@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.
Files changed (59) hide show
  1. package/README.md +258 -0
  2. package/dist/cjs/client.d.ts +121 -0
  3. package/dist/cjs/client.d.ts.map +1 -0
  4. package/dist/cjs/client.js +483 -0
  5. package/dist/cjs/client.js.map +1 -0
  6. package/dist/cjs/context.d.ts +10 -0
  7. package/dist/cjs/context.d.ts.map +1 -0
  8. package/dist/cjs/context.js +14 -0
  9. package/dist/cjs/context.js.map +1 -0
  10. package/dist/cjs/hooks.d.ts +86 -0
  11. package/dist/cjs/hooks.d.ts.map +1 -0
  12. package/dist/cjs/hooks.js +186 -0
  13. package/dist/cjs/hooks.js.map +1 -0
  14. package/dist/cjs/index.d.ts +7 -0
  15. package/dist/cjs/index.d.ts.map +1 -0
  16. package/dist/cjs/index.js +23 -0
  17. package/dist/cjs/index.js.map +1 -0
  18. package/dist/cjs/local-evaluator.d.ts +12 -0
  19. package/dist/cjs/local-evaluator.d.ts.map +1 -0
  20. package/dist/cjs/local-evaluator.js +44 -0
  21. package/dist/cjs/local-evaluator.js.map +1 -0
  22. package/dist/cjs/package.json +1 -0
  23. package/dist/cjs/provider.d.ts +24 -0
  24. package/dist/cjs/provider.d.ts.map +1 -0
  25. package/dist/cjs/provider.js +97 -0
  26. package/dist/cjs/provider.js.map +1 -0
  27. package/dist/cjs/types.d.ts +163 -0
  28. package/dist/cjs/types.d.ts.map +1 -0
  29. package/dist/cjs/types.js +9 -0
  30. package/dist/cjs/types.js.map +1 -0
  31. package/dist/esm/client.d.ts +121 -0
  32. package/dist/esm/client.d.ts.map +1 -0
  33. package/dist/esm/client.js +479 -0
  34. package/dist/esm/client.js.map +1 -0
  35. package/dist/esm/context.d.ts +10 -0
  36. package/dist/esm/context.d.ts.map +1 -0
  37. package/dist/esm/context.js +11 -0
  38. package/dist/esm/context.js.map +1 -0
  39. package/dist/esm/hooks.d.ts +86 -0
  40. package/dist/esm/hooks.d.ts.map +1 -0
  41. package/dist/esm/hooks.js +178 -0
  42. package/dist/esm/hooks.js.map +1 -0
  43. package/dist/esm/index.d.ts +7 -0
  44. package/dist/esm/index.d.ts.map +1 -0
  45. package/dist/esm/index.js +10 -0
  46. package/dist/esm/index.js.map +1 -0
  47. package/dist/esm/local-evaluator.d.ts +12 -0
  48. package/dist/esm/local-evaluator.d.ts.map +1 -0
  49. package/dist/esm/local-evaluator.js +41 -0
  50. package/dist/esm/local-evaluator.js.map +1 -0
  51. package/dist/esm/provider.d.ts +24 -0
  52. package/dist/esm/provider.d.ts.map +1 -0
  53. package/dist/esm/provider.js +94 -0
  54. package/dist/esm/provider.js.map +1 -0
  55. package/dist/esm/types.d.ts +163 -0
  56. package/dist/esm/types.d.ts.map +1 -0
  57. package/dist/esm/types.js +8 -0
  58. package/dist/esm/types.js.map +1 -0
  59. package/package.json +58 -0
@@ -0,0 +1,86 @@
1
+ import type { DeploySentryClient } from './client';
2
+ import type { Flag, FlagCategory, FlagDetail } from './types';
3
+ /**
4
+ * Return the raw {@link DeploySentryClient} instance.
5
+ *
6
+ * Useful for advanced use-cases such as manual re-identification or
7
+ * subscribing to change events outside of React's lifecycle.
8
+ *
9
+ * @throws If called outside of a `<DeploySentryProvider>`.
10
+ */
11
+ export declare function useDeploySentry(): DeploySentryClient;
12
+ /**
13
+ * Evaluate a feature flag and return its resolved value.
14
+ *
15
+ * The component re-renders whenever the flag value changes (via SSE).
16
+ *
17
+ * @param key - The unique flag key.
18
+ * @param defaultValue - Value returned while the flag is loading or if the
19
+ * key does not exist.
20
+ * @returns The resolved flag value, or `defaultValue`.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * const showBanner = useFlag('show-banner', false);
25
+ * ```
26
+ */
27
+ export declare function useFlag<T = unknown>(key: string, defaultValue: T): T;
28
+ /**
29
+ * Return detailed evaluation information for a single flag.
30
+ *
31
+ * Includes the resolved value, enabled state, full metadata, and a
32
+ * `loading` indicator that is `true` until the initial fetch completes.
33
+ *
34
+ * @param key - The unique flag key.
35
+ *
36
+ * @example
37
+ * ```tsx
38
+ * const { value, enabled, metadata, loading } = useFlagDetail('new-checkout');
39
+ * ```
40
+ */
41
+ export declare function useFlagDetail<T = unknown>(key: string): FlagDetail<T>;
42
+ /**
43
+ * Return all flags that belong to the given category.
44
+ *
45
+ * The result is referentially stable across renders as long as the
46
+ * underlying flag data has not changed.
47
+ *
48
+ * @param category - One of the predefined {@link FlagCategory} values.
49
+ *
50
+ * @example
51
+ * ```tsx
52
+ * const experiments = useFlagsByCategory('experiment');
53
+ * ```
54
+ */
55
+ export declare function useFlagsByCategory(category: FlagCategory): Flag[];
56
+ /**
57
+ * Return the dispatch function for the given operation name.
58
+ *
59
+ * Reads the client from context and calls {@link DeploySentryClient.dispatch},
60
+ * which selects the appropriate handler based on currently enabled flags.
61
+ *
62
+ * @param operation - The name of the registered operation.
63
+ * @returns The resolved handler function.
64
+ *
65
+ * @throws If no handlers are registered for the operation.
66
+ *
67
+ * @example
68
+ * ```tsx
69
+ * const checkout = useDispatch<() => void>('checkout');
70
+ * checkout();
71
+ * ```
72
+ */
73
+ export declare function useDispatch<T extends (...args: any[]) => any>(operation: string): T;
74
+ /**
75
+ * Return all non-permanent flags whose `expiresAt` date is in the past.
76
+ *
77
+ * This is useful for building admin dashboards that surface stale flags
78
+ * that should be cleaned up.
79
+ *
80
+ * @example
81
+ * ```tsx
82
+ * const expired = useExpiredFlags();
83
+ * ```
84
+ */
85
+ export declare function useExpiredFlags(): Flag[];
86
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/hooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEnD,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAgB,MAAM,SAAS,CAAC;AAqD5E;;;;;;;GAOG;AACH,wBAAgB,eAAe,IAAI,kBAAkB,CAEpD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,GAAG,CAAC,CAQpE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CA+BrE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,EAAE,CAQjE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,SAAS,EAAE,MAAM,GAAG,CAAC,CAGnF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,IAAI,IAAI,EAAE,CAWxC"}
@@ -0,0 +1,178 @@
1
+ import { useCallback, useContext, useMemo, useSyncExternalStore } from 'react';
2
+ import { DeploySentryContext } from './context';
3
+ // ---------------------------------------------------------------------------
4
+ // Helpers
5
+ // ---------------------------------------------------------------------------
6
+ const EMPTY_FLAGS = [];
7
+ const DEFAULT_METADATA = {
8
+ category: 'feature',
9
+ purpose: '',
10
+ owners: [],
11
+ isPermanent: false,
12
+ expiresAt: undefined,
13
+ tags: [],
14
+ };
15
+ function useClient() {
16
+ const client = useContext(DeploySentryContext);
17
+ if (!client) {
18
+ throw new Error('DeploySentry hooks must be used within a <DeploySentryProvider>. ' +
19
+ 'Wrap your component tree with the provider before calling any hook.');
20
+ }
21
+ return client;
22
+ }
23
+ /**
24
+ * Subscribe to the client's flag store via `useSyncExternalStore`.
25
+ *
26
+ * Every flag-change notification from the client (initial fetch or SSE
27
+ * update) will trigger a synchronous re-render of any component that
28
+ * consumes this hook.
29
+ */
30
+ function useFlagSnapshot(client) {
31
+ const subscribe = useCallback((onStoreChange) => client.subscribe(onStoreChange), [client]);
32
+ const getSnapshot = useCallback(() => client.getAllFlags(), [client]);
33
+ // For SSR, return an empty array. Flags are fetched client-side.
34
+ const getServerSnapshot = useCallback(() => EMPTY_FLAGS, []);
35
+ return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
36
+ }
37
+ // ---------------------------------------------------------------------------
38
+ // Public hooks
39
+ // ---------------------------------------------------------------------------
40
+ /**
41
+ * Return the raw {@link DeploySentryClient} instance.
42
+ *
43
+ * Useful for advanced use-cases such as manual re-identification or
44
+ * subscribing to change events outside of React's lifecycle.
45
+ *
46
+ * @throws If called outside of a `<DeploySentryProvider>`.
47
+ */
48
+ export function useDeploySentry() {
49
+ return useClient();
50
+ }
51
+ /**
52
+ * Evaluate a feature flag and return its resolved value.
53
+ *
54
+ * The component re-renders whenever the flag value changes (via SSE).
55
+ *
56
+ * @param key - The unique flag key.
57
+ * @param defaultValue - Value returned while the flag is loading or if the
58
+ * key does not exist.
59
+ * @returns The resolved flag value, or `defaultValue`.
60
+ *
61
+ * @example
62
+ * ```tsx
63
+ * const showBanner = useFlag('show-banner', false);
64
+ * ```
65
+ */
66
+ export function useFlag(key, defaultValue) {
67
+ const client = useClient();
68
+ // Subscribe to the store so we re-render on updates.
69
+ useFlagSnapshot(client);
70
+ const flag = client.getFlag(key);
71
+ if (!flag)
72
+ return defaultValue;
73
+ return (flag.enabled ? flag.value : defaultValue);
74
+ }
75
+ /**
76
+ * Return detailed evaluation information for a single flag.
77
+ *
78
+ * Includes the resolved value, enabled state, full metadata, and a
79
+ * `loading` indicator that is `true` until the initial fetch completes.
80
+ *
81
+ * @param key - The unique flag key.
82
+ *
83
+ * @example
84
+ * ```tsx
85
+ * const { value, enabled, metadata, loading } = useFlagDetail('new-checkout');
86
+ * ```
87
+ */
88
+ export function useFlagDetail(key) {
89
+ const client = useClient();
90
+ useFlagSnapshot(client);
91
+ const flag = client.getFlag(key);
92
+ const loading = !client.isInitialised;
93
+ if (!flag) {
94
+ return {
95
+ value: undefined,
96
+ enabled: false,
97
+ metadata: DEFAULT_METADATA,
98
+ loading,
99
+ };
100
+ }
101
+ const metadata = {
102
+ category: flag.category,
103
+ purpose: flag.purpose,
104
+ owners: flag.owners,
105
+ isPermanent: flag.isPermanent,
106
+ expiresAt: flag.expiresAt,
107
+ tags: flag.tags,
108
+ };
109
+ return {
110
+ value: flag.value,
111
+ enabled: flag.enabled,
112
+ metadata,
113
+ loading,
114
+ };
115
+ }
116
+ /**
117
+ * Return all flags that belong to the given category.
118
+ *
119
+ * The result is referentially stable across renders as long as the
120
+ * underlying flag data has not changed.
121
+ *
122
+ * @param category - One of the predefined {@link FlagCategory} values.
123
+ *
124
+ * @example
125
+ * ```tsx
126
+ * const experiments = useFlagsByCategory('experiment');
127
+ * ```
128
+ */
129
+ export function useFlagsByCategory(category) {
130
+ const client = useClient();
131
+ const allFlags = useFlagSnapshot(client);
132
+ return useMemo(() => allFlags.filter((f) => f.category === category), [allFlags, category]);
133
+ }
134
+ /**
135
+ * Return the dispatch function for the given operation name.
136
+ *
137
+ * Reads the client from context and calls {@link DeploySentryClient.dispatch},
138
+ * which selects the appropriate handler based on currently enabled flags.
139
+ *
140
+ * @param operation - The name of the registered operation.
141
+ * @returns The resolved handler function.
142
+ *
143
+ * @throws If no handlers are registered for the operation.
144
+ *
145
+ * @example
146
+ * ```tsx
147
+ * const checkout = useDispatch<() => void>('checkout');
148
+ * checkout();
149
+ * ```
150
+ */
151
+ export function useDispatch(operation) {
152
+ const client = useDeploySentry();
153
+ return client.dispatch(operation);
154
+ }
155
+ /**
156
+ * Return all non-permanent flags whose `expiresAt` date is in the past.
157
+ *
158
+ * This is useful for building admin dashboards that surface stale flags
159
+ * that should be cleaned up.
160
+ *
161
+ * @example
162
+ * ```tsx
163
+ * const expired = useExpiredFlags();
164
+ * ```
165
+ */
166
+ export function useExpiredFlags() {
167
+ const client = useClient();
168
+ const allFlags = useFlagSnapshot(client);
169
+ return useMemo(() => {
170
+ const now = Date.now();
171
+ return allFlags.filter((f) => {
172
+ if (f.isPermanent || !f.expiresAt)
173
+ return false;
174
+ return new Date(f.expiresAt).getTime() <= now;
175
+ });
176
+ }, [allFlags]);
177
+ }
178
+ //# 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,10 @@
1
+ // Context & Provider
2
+ export { DeploySentryContext } from './context';
3
+ export { DeploySentryProvider } from './provider';
4
+ // Hooks
5
+ export { useDeploySentry, useDispatch, useExpiredFlags, useFlag, useFlagDetail, useFlagsByCategory, } from './hooks';
6
+ // Client (advanced usage)
7
+ export { DeploySentryClient } from './client';
8
+ // Local evaluation (file/flagData mode)
9
+ export { evaluateLocal } from './local-evaluator';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,qBAAqB;AACrB,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAElD,QAAQ;AACR,OAAO,EACL,eAAe,EACf,WAAW,EACX,eAAe,EACf,OAAO,EACP,aAAa,EACb,kBAAkB,GACnB,MAAM,SAAS,CAAC;AAEjB,0BAA0B;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAE9C,wCAAwC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC"}
@@ -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,41 @@
1
+ /**
2
+ * Evaluate a flag locally using pre-loaded config data.
3
+ *
4
+ * This mirrors the Node SDK's local evaluator so that file/flagData mode
5
+ * produces consistent results across SDKs.
6
+ */
7
+ export function evaluateLocal(config, environment, key, context) {
8
+ const flag = config.flags.find((f) => f.key === key);
9
+ if (!flag)
10
+ return { value: '', reason: 'flag_not_found' };
11
+ const envState = flag.environments[environment];
12
+ if (!envState || !envState.enabled)
13
+ return { value: flag.default_value, reason: 'env_disabled' };
14
+ if (flag.rules && context) {
15
+ const sorted = [...flag.rules].sort((a, b) => a.priority - b.priority);
16
+ for (const rule of sorted) {
17
+ if (!rule.environments[environment])
18
+ continue;
19
+ if (matchRule(rule, context))
20
+ return { value: rule.value, reason: 'rule_match' };
21
+ }
22
+ }
23
+ return { value: envState.value || flag.default_value, reason: 'default' };
24
+ }
25
+ function matchRule(rule, context) {
26
+ const val = context.attributes?.[rule.attribute] ?? '';
27
+ const targets = rule.target_values ?? [];
28
+ switch (rule.operator) {
29
+ case 'equals': return targets.length > 0 && val === targets[0];
30
+ case 'not_equals': return targets.length > 0 && val !== targets[0];
31
+ case 'in': return targets.includes(val);
32
+ case 'not_in': return !targets.includes(val);
33
+ case 'contains': return targets.length > 0 && val.includes(targets[0]);
34
+ case 'starts_with': return targets.length > 0 && val.startsWith(targets[0]);
35
+ case 'ends_with': return targets.length > 0 && val.endsWith(targets[0]);
36
+ case 'greater_than': return targets.length > 0 && parseFloat(val) > parseFloat(targets[0]);
37
+ case 'less_than': return targets.length > 0 && parseFloat(val) < parseFloat(targets[0]);
38
+ default: return false;
39
+ }
40
+ }
41
+ //# 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,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,94 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useRef, useState } from 'react';
3
+ import { DeploySentryClient } from './client';
4
+ import { DeploySentryContext } from './context';
5
+ /**
6
+ * Provides the DeploySentry client to all descendant components.
7
+ *
8
+ * The provider creates a {@link DeploySentryClient} on mount, fetches the
9
+ * initial flag set, opens an SSE connection for real-time updates, and tears
10
+ * everything down on unmount.
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * <DeploySentryProvider
15
+ * apiKey="ds_live_abc123"
16
+ * baseURL="https://api.dr-sentry.com"
17
+ * environment="production"
18
+ * project="my-app"
19
+ * user={{ id: 'user-42' }}
20
+ * >
21
+ * <App />
22
+ * </DeploySentryProvider>
23
+ * ```
24
+ */
25
+ export function DeploySentryProvider({ apiKey, baseURL, environment, project, application, user, sessionId, mode, flagData, children, }) {
26
+ const [client, setClient] = useState(null);
27
+ const [, setError] = useState(null);
28
+ // Keep a ref so the effect cleanup always targets the right instance.
29
+ const clientRef = useRef(null);
30
+ // Memoise the configuration identity so we only recreate the client when
31
+ // the connection parameters change, not on every render.
32
+ const configKey = useMemo(() => JSON.stringify({ apiKey, baseURL, environment, project, application, sessionId, mode }), [apiKey, baseURL, environment, project, application, sessionId, mode]);
33
+ useEffect(() => {
34
+ const instance = new DeploySentryClient({
35
+ apiKey,
36
+ baseURL,
37
+ environment,
38
+ project,
39
+ application,
40
+ user,
41
+ sessionId,
42
+ mode,
43
+ flagConfig: flagData,
44
+ });
45
+ clientRef.current = instance;
46
+ instance
47
+ .init()
48
+ .then(() => {
49
+ // Guard against the effect having been cleaned up before init resolved.
50
+ if (clientRef.current === instance) {
51
+ setClient(instance);
52
+ setError(null);
53
+ }
54
+ })
55
+ .catch((err) => {
56
+ if (clientRef.current === instance) {
57
+ setError(err instanceof Error
58
+ ? err
59
+ : new Error(String(err)));
60
+ // Still expose the client so hooks can return defaults gracefully.
61
+ setClient(instance);
62
+ }
63
+ });
64
+ return () => {
65
+ clientRef.current = null;
66
+ instance.destroy();
67
+ };
68
+ // eslint-disable-next-line react-hooks/exhaustive-deps
69
+ }, [configKey]);
70
+ // When the user context changes (but connection params stay the same),
71
+ // re-identify on the existing client rather than tearing it down.
72
+ const userKey = useMemo(() => JSON.stringify(user), [user]);
73
+ useEffect(() => {
74
+ if (!client)
75
+ return;
76
+ // The initial identify already happened inside init(), so we skip the
77
+ // first call by comparing refs.
78
+ client.identify(user).catch(() => {
79
+ // Swallow identify errors. The client will keep the previous state.
80
+ });
81
+ // eslint-disable-next-line react-hooks/exhaustive-deps
82
+ }, [userKey, client]);
83
+ // Delay rendering children until the client exists. Hooks like
84
+ // `useFlag` throw synchronously when the context value is null, which
85
+ // crashes the whole subtree on the first render — before `init()` has
86
+ // even had a chance to run. Gating children behind the client's
87
+ // readiness keeps the external API (a throwing hook that enforces
88
+ // provider presence) while preventing that race.
89
+ if (!client) {
90
+ return _jsx(DeploySentryContext.Provider, { value: null, children: null });
91
+ }
92
+ return (_jsx(DeploySentryContext.Provider, { value: client, children: children }));
93
+ }
94
+ //# 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