@supashiphq/react-sdk 0.7.7

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.
@@ -0,0 +1,260 @@
1
+ import { FeaturesWithFallbacks, FeatureValue, FeatureContext, Features as Features$1, SupaClientConfig, SupaToolbarPluginConfig, SupaClient } from '@supashiphq/javascript-sdk';
2
+ export { FeatureContext, FeatureValue, FeaturesWithFallbacks, SupaPlugin, SupaClientConfig as SupaProviderConfig, SupaToolbarPluginConfig, SupaToolbarPosition } from '@supashiphq/javascript-sdk';
3
+ import React, { ReactNode } from 'react';
4
+
5
+ type QueryStatus = 'idle' | 'loading' | 'success' | 'error';
6
+ interface BaseQueryState<TData = unknown, TError = Error> {
7
+ status: QueryStatus;
8
+ data: TData | undefined;
9
+ error: TError | null;
10
+ isLoading: boolean;
11
+ isSuccess: boolean;
12
+ isError: boolean;
13
+ isIdle: boolean;
14
+ isFetching: boolean;
15
+ dataUpdatedAt: number;
16
+ }
17
+ interface QueryState<TData = unknown, TError = Error> extends BaseQueryState<TData, TError> {
18
+ refetch: () => Promise<void>;
19
+ }
20
+ declare function getInitialQueryState<TData, TError>(initialData?: TData, enabled?: boolean): BaseQueryState<TData, TError>;
21
+ interface UseQueryOptions<TData = unknown, TError = Error> {
22
+ enabled?: boolean;
23
+ retry?: number | boolean;
24
+ retryDelay?: number;
25
+ staleTime?: number;
26
+ cacheTime?: number;
27
+ refetchOnWindowFocus?: boolean;
28
+ initialData?: TData;
29
+ onSuccess?: (data: TData) => void;
30
+ onError?: (error: TError) => void;
31
+ onSettled?: (data: TData | undefined, error: TError | null) => void;
32
+ }
33
+ type QueryKey = unknown[];
34
+ declare class QueryCache {
35
+ private cache;
36
+ private timers;
37
+ private observers;
38
+ getQuery(queryKey: string): unknown;
39
+ isStale(queryKey: string, staleTime: number): boolean;
40
+ setQuery(queryKey: string, data: unknown, cacheTime?: number): void;
41
+ subscribe(queryKey: string, callback: () => void): () => void;
42
+ private notifyObservers;
43
+ invalidateQuery(queryKey: string): void;
44
+ invalidateQueries(queryKeyPrefix: string): void;
45
+ clear(): void;
46
+ }
47
+ declare const queryCache: QueryCache;
48
+ declare class QueryClient {
49
+ private cache;
50
+ constructor(cache?: QueryCache);
51
+ /**
52
+ * Invalidates a specific query by its query key
53
+ * This will remove it from cache and trigger refetch in all components using this query
54
+ */
55
+ invalidateQueries(queryKey: QueryKey): void;
56
+ /**
57
+ * Invalidates all queries matching a partial query key
58
+ * For example, invalidateQueriesByPrefix(['feature']) will invalidate all feature queries
59
+ */
60
+ invalidateQueriesByPrefix(queryKeyPrefix: QueryKey): void;
61
+ /**
62
+ * Clears all queries from the cache
63
+ */
64
+ clear(): void;
65
+ }
66
+ declare function useQueryClient(): QueryClient;
67
+ declare function useQuery<TData = unknown, TError = Error>(queryKey: QueryKey, queryFn: () => Promise<TData>, options?: UseQueryOptions<TData, TError>): QueryState<TData, TError>;
68
+
69
+ /**
70
+ * Helper type to infer feature types from your feature config for module augmentation.
71
+ *
72
+ * ⚠️ Remember: Define features with `satisfies FeaturesWithFallbacks`, not type annotation
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * import { FeaturesWithFallbacks, InferFeatures } from '@supashiphq/react-sdk'
77
+ *
78
+ * // ✅ Use satisfies to preserve literal types
79
+ * export const FEATURE_FLAGS = {
80
+ * 'dark-mode': false,
81
+ * 'ui-config': { variant: 'a' as const }
82
+ * } satisfies FeaturesWithFallbacks
83
+ *
84
+ * declare module '@supashiphq/react-sdk' {
85
+ * interface Features extends InferFeatures<typeof FEATURE_FLAGS> {}
86
+ * }
87
+ * ```
88
+ */
89
+ type InferFeatures<T extends FeaturesWithFallbacks> = {
90
+ [K in keyof T]: T[K];
91
+ };
92
+ /**
93
+ * Interface to be augmented by users for type-safe feature flags.
94
+ * Use InferFeatures helper to enable type-safe feature access.
95
+ *
96
+ * @example
97
+ * ```ts
98
+ * // lib/features.ts
99
+ * import { FeaturesWithFallbacks, InferFeatures } from '@supashiphq/react-sdk'
100
+ *
101
+ * export const FEATURE_FLAGS = {
102
+ * 'dark-mode': false,
103
+ * 'ui-config': {
104
+ * variant: 'a' as const,
105
+ * showWelcome: true,
106
+ * },
107
+ * } satisfies FeaturesWithFallbacks
108
+ *
109
+ * declare module '@supashiphq/react-sdk' {
110
+ * interface Features extends InferFeatures<typeof FEATURE_FLAGS> {}
111
+ * }
112
+ * ```
113
+ */
114
+ interface Features {
115
+ }
116
+ /**
117
+ * Return type for useFeature hook with proper typing based on feature key
118
+ */
119
+ type TypedFeatures = keyof Features extends never ? {
120
+ [key: string]: Omit<QueryState<FeatureValue | null>, 'data'> & {
121
+ feature: FeatureValue | null;
122
+ };
123
+ } : {
124
+ [K in keyof Features]: Omit<QueryState<Features[K]>, 'data'> & {
125
+ feature: Features[K];
126
+ };
127
+ };
128
+ type FeatureKey = keyof Features extends never ? string : keyof Features;
129
+ interface UseFeatureOptions {
130
+ context?: FeatureContext;
131
+ shouldFetch?: boolean;
132
+ }
133
+ interface UseFeaturesOptions {
134
+ context?: FeatureContext;
135
+ shouldFetch?: boolean;
136
+ }
137
+
138
+ interface UseFeatureResult<T extends FeatureValue> extends Omit<QueryState<T | null>, 'data'> {
139
+ feature: T | null;
140
+ }
141
+ interface UseFeaturesResult<T extends Record<string, FeatureValue>> extends Omit<QueryState<T>, 'data'> {
142
+ features: T;
143
+ }
144
+ /**
145
+ * Returns the state of a given feature for the current context.
146
+ *
147
+ * @example
148
+ * ```ts
149
+ * function MyComponent() {
150
+ * const { feature, isLoading } = useFeature('my-feature')
151
+ * if (isLoading) return <div>Loading...</div>
152
+ * return <div>Feature value: {String(feature)}</div>
153
+ * }
154
+ * ```
155
+ *
156
+ * @remarks
157
+ * For type-safe feature flags, augment the Features interface:
158
+ * ```ts
159
+ * declare module '@supashiphq/react-sdk' {
160
+ * interface Features {
161
+ * 'my-feature': { value: 'variant-a' | 'variant-b' }
162
+ * 'dark-mode': { value: boolean }
163
+ * }
164
+ * }
165
+ *
166
+ * // Now get full type safety:
167
+ * const { feature } = useFeature('my-feature')
168
+ * // feature is typed as 'variant-a' | 'variant-b'
169
+ * ```
170
+ */
171
+ declare function useFeature<TKey extends FeatureKey>(key: TKey, options?: {
172
+ context?: FeatureContext;
173
+ shouldFetch?: boolean;
174
+ }): TypedFeatures[TKey];
175
+ /**
176
+ * Extract feature value type from Features interface
177
+ */
178
+ type ExtractFeatureValue<T> = T extends {
179
+ value: infer V;
180
+ } ? V : FeatureValue;
181
+ /**
182
+ * Returns the state of multiple features for the current context.
183
+ *
184
+ * @example
185
+ * ```ts
186
+ * function MyComponent() {
187
+ * const { features, isLoading } = useFeatures(['feature-a', 'feature-b'])
188
+ * if (isLoading) return <div>Loading...</div>
189
+ * return <div>Feature A: {String(features['feature-a'])}</div>
190
+ * }
191
+ * ```
192
+ */
193
+ declare function useFeatures<TKeys extends readonly FeatureKey[]>(featureNames: TKeys, options?: {
194
+ context?: FeatureContext;
195
+ shouldFetch?: boolean;
196
+ }): UseFeaturesResult<{
197
+ [K in TKeys[number]]: K extends keyof Features ? ExtractFeatureValue<Features[K]> : FeatureValue | null;
198
+ }>;
199
+
200
+ interface SupaContextValue<TFeatures extends Features$1<Record<string, FeatureValue>>> {
201
+ client: SupaClient<TFeatures>;
202
+ updateContext: (context: FeatureContext, mergeWithExisting?: boolean) => void;
203
+ getContext: () => FeatureContext | undefined;
204
+ }
205
+ interface SupaProviderProps<TFeatures extends Features$1<Record<string, FeatureValue>>> {
206
+ config: Omit<SupaClientConfig, 'plugins' | 'toolbar'> & {
207
+ features: TFeatures;
208
+ };
209
+ toolbar?: SupaToolbarPluginConfig | boolean;
210
+ children: ReactNode;
211
+ }
212
+ declare function SupaProvider<TFeatures extends Features$1<Record<string, FeatureValue>>>({ config, toolbar, children, }: SupaProviderProps<TFeatures>): React.JSX.Element;
213
+ declare function useClient<TFeatures extends Features$1<Record<string, FeatureValue>>>(): SupaClient<TFeatures>;
214
+ /**
215
+ * Hook to update the context dynamically
216
+ * Useful when context depends on authentication or other async operations
217
+ */
218
+ declare function useFeatureContext(): Omit<SupaContextValue<any>, 'client'>;
219
+
220
+ interface SupaFeatureProps {
221
+ /**
222
+ * The feature flag key to evaluate
223
+ */
224
+ feature: FeatureKey;
225
+ /**
226
+ * Context for feature evaluation
227
+ */
228
+ context?: FeatureContext;
229
+ /**
230
+ * Whether to fetch the feature (default: true)
231
+ */
232
+ shouldFetch?: boolean;
233
+ /**
234
+ * Variations object mapping feature values/keys to JSX elements
235
+ */
236
+ variations: Record<string, ReactNode>;
237
+ /**
238
+ * Key in variations object to use for loading state
239
+ */
240
+ loading?: string;
241
+ }
242
+ /**
243
+ * SupaFeature component that conditionally renders variations based on feature flag values.
244
+ * Uses the default value defined in the client configuration.
245
+ *
246
+ * @example
247
+ * ```tsx
248
+ * <SupaFeature
249
+ * feature="new-header"
250
+ * variations={{
251
+ * "true": <NewHeader />,
252
+ * "false": <OldHeader />,
253
+ * loading: <HeaderSkeleton />
254
+ * }}
255
+ * />
256
+ * ```
257
+ */
258
+ declare function SupaFeature({ feature, context, shouldFetch, variations, loading, }: SupaFeatureProps): React.JSX.Element | null;
259
+
260
+ export { type BaseQueryState, type FeatureKey, type Features, type InferFeatures, QueryClient, type QueryKey, type QueryState, type QueryStatus, SupaFeature, type SupaFeatureProps, SupaProvider, type TypedFeatures, type UseFeatureOptions, type UseFeatureResult, type UseFeaturesOptions, type UseFeaturesResult, type UseQueryOptions, getInitialQueryState, queryCache, useClient, useFeature, useFeatureContext, useFeatures, useQuery, useQueryClient };
@@ -0,0 +1,260 @@
1
+ import { FeaturesWithFallbacks, FeatureValue, FeatureContext, Features as Features$1, SupaClientConfig, SupaToolbarPluginConfig, SupaClient } from '@supashiphq/javascript-sdk';
2
+ export { FeatureContext, FeatureValue, FeaturesWithFallbacks, SupaPlugin, SupaClientConfig as SupaProviderConfig, SupaToolbarPluginConfig, SupaToolbarPosition } from '@supashiphq/javascript-sdk';
3
+ import React, { ReactNode } from 'react';
4
+
5
+ type QueryStatus = 'idle' | 'loading' | 'success' | 'error';
6
+ interface BaseQueryState<TData = unknown, TError = Error> {
7
+ status: QueryStatus;
8
+ data: TData | undefined;
9
+ error: TError | null;
10
+ isLoading: boolean;
11
+ isSuccess: boolean;
12
+ isError: boolean;
13
+ isIdle: boolean;
14
+ isFetching: boolean;
15
+ dataUpdatedAt: number;
16
+ }
17
+ interface QueryState<TData = unknown, TError = Error> extends BaseQueryState<TData, TError> {
18
+ refetch: () => Promise<void>;
19
+ }
20
+ declare function getInitialQueryState<TData, TError>(initialData?: TData, enabled?: boolean): BaseQueryState<TData, TError>;
21
+ interface UseQueryOptions<TData = unknown, TError = Error> {
22
+ enabled?: boolean;
23
+ retry?: number | boolean;
24
+ retryDelay?: number;
25
+ staleTime?: number;
26
+ cacheTime?: number;
27
+ refetchOnWindowFocus?: boolean;
28
+ initialData?: TData;
29
+ onSuccess?: (data: TData) => void;
30
+ onError?: (error: TError) => void;
31
+ onSettled?: (data: TData | undefined, error: TError | null) => void;
32
+ }
33
+ type QueryKey = unknown[];
34
+ declare class QueryCache {
35
+ private cache;
36
+ private timers;
37
+ private observers;
38
+ getQuery(queryKey: string): unknown;
39
+ isStale(queryKey: string, staleTime: number): boolean;
40
+ setQuery(queryKey: string, data: unknown, cacheTime?: number): void;
41
+ subscribe(queryKey: string, callback: () => void): () => void;
42
+ private notifyObservers;
43
+ invalidateQuery(queryKey: string): void;
44
+ invalidateQueries(queryKeyPrefix: string): void;
45
+ clear(): void;
46
+ }
47
+ declare const queryCache: QueryCache;
48
+ declare class QueryClient {
49
+ private cache;
50
+ constructor(cache?: QueryCache);
51
+ /**
52
+ * Invalidates a specific query by its query key
53
+ * This will remove it from cache and trigger refetch in all components using this query
54
+ */
55
+ invalidateQueries(queryKey: QueryKey): void;
56
+ /**
57
+ * Invalidates all queries matching a partial query key
58
+ * For example, invalidateQueriesByPrefix(['feature']) will invalidate all feature queries
59
+ */
60
+ invalidateQueriesByPrefix(queryKeyPrefix: QueryKey): void;
61
+ /**
62
+ * Clears all queries from the cache
63
+ */
64
+ clear(): void;
65
+ }
66
+ declare function useQueryClient(): QueryClient;
67
+ declare function useQuery<TData = unknown, TError = Error>(queryKey: QueryKey, queryFn: () => Promise<TData>, options?: UseQueryOptions<TData, TError>): QueryState<TData, TError>;
68
+
69
+ /**
70
+ * Helper type to infer feature types from your feature config for module augmentation.
71
+ *
72
+ * ⚠️ Remember: Define features with `satisfies FeaturesWithFallbacks`, not type annotation
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * import { FeaturesWithFallbacks, InferFeatures } from '@supashiphq/react-sdk'
77
+ *
78
+ * // ✅ Use satisfies to preserve literal types
79
+ * export const FEATURE_FLAGS = {
80
+ * 'dark-mode': false,
81
+ * 'ui-config': { variant: 'a' as const }
82
+ * } satisfies FeaturesWithFallbacks
83
+ *
84
+ * declare module '@supashiphq/react-sdk' {
85
+ * interface Features extends InferFeatures<typeof FEATURE_FLAGS> {}
86
+ * }
87
+ * ```
88
+ */
89
+ type InferFeatures<T extends FeaturesWithFallbacks> = {
90
+ [K in keyof T]: T[K];
91
+ };
92
+ /**
93
+ * Interface to be augmented by users for type-safe feature flags.
94
+ * Use InferFeatures helper to enable type-safe feature access.
95
+ *
96
+ * @example
97
+ * ```ts
98
+ * // lib/features.ts
99
+ * import { FeaturesWithFallbacks, InferFeatures } from '@supashiphq/react-sdk'
100
+ *
101
+ * export const FEATURE_FLAGS = {
102
+ * 'dark-mode': false,
103
+ * 'ui-config': {
104
+ * variant: 'a' as const,
105
+ * showWelcome: true,
106
+ * },
107
+ * } satisfies FeaturesWithFallbacks
108
+ *
109
+ * declare module '@supashiphq/react-sdk' {
110
+ * interface Features extends InferFeatures<typeof FEATURE_FLAGS> {}
111
+ * }
112
+ * ```
113
+ */
114
+ interface Features {
115
+ }
116
+ /**
117
+ * Return type for useFeature hook with proper typing based on feature key
118
+ */
119
+ type TypedFeatures = keyof Features extends never ? {
120
+ [key: string]: Omit<QueryState<FeatureValue | null>, 'data'> & {
121
+ feature: FeatureValue | null;
122
+ };
123
+ } : {
124
+ [K in keyof Features]: Omit<QueryState<Features[K]>, 'data'> & {
125
+ feature: Features[K];
126
+ };
127
+ };
128
+ type FeatureKey = keyof Features extends never ? string : keyof Features;
129
+ interface UseFeatureOptions {
130
+ context?: FeatureContext;
131
+ shouldFetch?: boolean;
132
+ }
133
+ interface UseFeaturesOptions {
134
+ context?: FeatureContext;
135
+ shouldFetch?: boolean;
136
+ }
137
+
138
+ interface UseFeatureResult<T extends FeatureValue> extends Omit<QueryState<T | null>, 'data'> {
139
+ feature: T | null;
140
+ }
141
+ interface UseFeaturesResult<T extends Record<string, FeatureValue>> extends Omit<QueryState<T>, 'data'> {
142
+ features: T;
143
+ }
144
+ /**
145
+ * Returns the state of a given feature for the current context.
146
+ *
147
+ * @example
148
+ * ```ts
149
+ * function MyComponent() {
150
+ * const { feature, isLoading } = useFeature('my-feature')
151
+ * if (isLoading) return <div>Loading...</div>
152
+ * return <div>Feature value: {String(feature)}</div>
153
+ * }
154
+ * ```
155
+ *
156
+ * @remarks
157
+ * For type-safe feature flags, augment the Features interface:
158
+ * ```ts
159
+ * declare module '@supashiphq/react-sdk' {
160
+ * interface Features {
161
+ * 'my-feature': { value: 'variant-a' | 'variant-b' }
162
+ * 'dark-mode': { value: boolean }
163
+ * }
164
+ * }
165
+ *
166
+ * // Now get full type safety:
167
+ * const { feature } = useFeature('my-feature')
168
+ * // feature is typed as 'variant-a' | 'variant-b'
169
+ * ```
170
+ */
171
+ declare function useFeature<TKey extends FeatureKey>(key: TKey, options?: {
172
+ context?: FeatureContext;
173
+ shouldFetch?: boolean;
174
+ }): TypedFeatures[TKey];
175
+ /**
176
+ * Extract feature value type from Features interface
177
+ */
178
+ type ExtractFeatureValue<T> = T extends {
179
+ value: infer V;
180
+ } ? V : FeatureValue;
181
+ /**
182
+ * Returns the state of multiple features for the current context.
183
+ *
184
+ * @example
185
+ * ```ts
186
+ * function MyComponent() {
187
+ * const { features, isLoading } = useFeatures(['feature-a', 'feature-b'])
188
+ * if (isLoading) return <div>Loading...</div>
189
+ * return <div>Feature A: {String(features['feature-a'])}</div>
190
+ * }
191
+ * ```
192
+ */
193
+ declare function useFeatures<TKeys extends readonly FeatureKey[]>(featureNames: TKeys, options?: {
194
+ context?: FeatureContext;
195
+ shouldFetch?: boolean;
196
+ }): UseFeaturesResult<{
197
+ [K in TKeys[number]]: K extends keyof Features ? ExtractFeatureValue<Features[K]> : FeatureValue | null;
198
+ }>;
199
+
200
+ interface SupaContextValue<TFeatures extends Features$1<Record<string, FeatureValue>>> {
201
+ client: SupaClient<TFeatures>;
202
+ updateContext: (context: FeatureContext, mergeWithExisting?: boolean) => void;
203
+ getContext: () => FeatureContext | undefined;
204
+ }
205
+ interface SupaProviderProps<TFeatures extends Features$1<Record<string, FeatureValue>>> {
206
+ config: Omit<SupaClientConfig, 'plugins' | 'toolbar'> & {
207
+ features: TFeatures;
208
+ };
209
+ toolbar?: SupaToolbarPluginConfig | boolean;
210
+ children: ReactNode;
211
+ }
212
+ declare function SupaProvider<TFeatures extends Features$1<Record<string, FeatureValue>>>({ config, toolbar, children, }: SupaProviderProps<TFeatures>): React.JSX.Element;
213
+ declare function useClient<TFeatures extends Features$1<Record<string, FeatureValue>>>(): SupaClient<TFeatures>;
214
+ /**
215
+ * Hook to update the context dynamically
216
+ * Useful when context depends on authentication or other async operations
217
+ */
218
+ declare function useFeatureContext(): Omit<SupaContextValue<any>, 'client'>;
219
+
220
+ interface SupaFeatureProps {
221
+ /**
222
+ * The feature flag key to evaluate
223
+ */
224
+ feature: FeatureKey;
225
+ /**
226
+ * Context for feature evaluation
227
+ */
228
+ context?: FeatureContext;
229
+ /**
230
+ * Whether to fetch the feature (default: true)
231
+ */
232
+ shouldFetch?: boolean;
233
+ /**
234
+ * Variations object mapping feature values/keys to JSX elements
235
+ */
236
+ variations: Record<string, ReactNode>;
237
+ /**
238
+ * Key in variations object to use for loading state
239
+ */
240
+ loading?: string;
241
+ }
242
+ /**
243
+ * SupaFeature component that conditionally renders variations based on feature flag values.
244
+ * Uses the default value defined in the client configuration.
245
+ *
246
+ * @example
247
+ * ```tsx
248
+ * <SupaFeature
249
+ * feature="new-header"
250
+ * variations={{
251
+ * "true": <NewHeader />,
252
+ * "false": <OldHeader />,
253
+ * loading: <HeaderSkeleton />
254
+ * }}
255
+ * />
256
+ * ```
257
+ */
258
+ declare function SupaFeature({ feature, context, shouldFetch, variations, loading, }: SupaFeatureProps): React.JSX.Element | null;
259
+
260
+ export { type BaseQueryState, type FeatureKey, type Features, type InferFeatures, QueryClient, type QueryKey, type QueryState, type QueryStatus, SupaFeature, type SupaFeatureProps, SupaProvider, type TypedFeatures, type UseFeatureOptions, type UseFeatureResult, type UseFeaturesOptions, type UseFeaturesResult, type UseQueryOptions, getInitialQueryState, queryCache, useClient, useFeature, useFeatureContext, useFeatures, useQuery, useQueryClient };