1- import type {
2- SeamHttp ,
3- SeamHttpOptionsWithClientSessionToken ,
4- } from '@seamapi/http/connect'
5- import { QueryClient , QueryClientProvider } from '@tanstack/react-query'
6- import {
7- createContext ,
8- type PropsWithChildren ,
9- useContext ,
10- useEffect ,
11- useMemo ,
12- } from 'react'
1+ import type { SeamHttp } from '@seamapi/http/connect'
2+ import type { QueryClient } from '@tanstack/react-query'
3+ import { createContext , type PropsWithChildren , useMemo } from 'react'
134
5+ import {
6+ SeamQueryProvider ,
7+ type SeamQueryProviderPropsWithClient ,
8+ type SeamQueryProviderPropsWithClientSessionToken ,
9+ type SeamQueryProviderPropsWithPublishableKey ,
10+ } from 'lib/seam/SeamQueryProvider.js'
1411import { useSeamFont } from 'lib/seam/use-seam-font.js'
1512import { useSeamStyles } from 'lib/seam/use-seam-styles.js'
1613import {
@@ -19,8 +16,6 @@ import {
1916 useUserTelemetry ,
2017} from 'lib/telemetry/index.js'
2118
22- import { useSeamClient } from './use-seam-client.js'
23-
2419declare global {
2520 // eslint-disable-next-line no-var
2621 var seam : SeamProviderProps | undefined
@@ -30,33 +25,28 @@ declare global {
3025 var seamTelemetryClient : TelemetryClient | undefined
3126}
3227
33- export interface SeamContext {
34- client : SeamHttp | null
35- clientOptions ?: SeamProviderClientOptions | undefined
36- publishableKey ?: string | undefined
37- userIdentifierKey ?: string | undefined
38- clientSessionToken ?: string | undefined
39- }
28+ // eslint-disable-next-line @typescript-eslint/no-empty-interface
29+ export interface SeamContext { }
4030
4131export type SeamProviderProps =
4232 | SeamProviderPropsWithClient
4333 | SeamProviderPropsWithPublishableKey
4434 | SeamProviderPropsWithClientSessionToken
4535
46- export interface SeamProviderPropsWithClient extends SeamProviderBaseProps {
47- client : SeamHttp
48- }
36+ export interface SeamProviderPropsWithClient
37+ extends SeamQueryProviderPropsWithClient ,
38+ SeamProviderBaseProps { }
4939
5040export interface SeamProviderPropsWithPublishableKey
5141 extends SeamProviderBaseProps ,
52- SeamProviderClientOptions {
42+ SeamQueryProviderPropsWithPublishableKey {
5343 publishableKey : string
5444 userIdentifierKey ?: string
5545}
5646
5747export interface SeamProviderPropsWithClientSessionToken
5848 extends SeamProviderBaseProps ,
59- SeamProviderClientOptions {
49+ SeamQueryProviderPropsWithClientSessionToken {
6050 clientSessionToken : string
6151}
6252
@@ -70,12 +60,6 @@ interface SeamProviderBaseProps extends PropsWithChildren {
7060 onSessionUpdate ?: ( client : SeamHttp ) => void
7161}
7262
73- type SeamClientOptions = SeamHttpOptionsWithClientSessionToken
74-
75- export type SeamProviderClientOptions = Pick < SeamClientOptions , 'endpoint' >
76-
77- const defaultQueryClient = new QueryClient ( )
78-
7963export const seamComponentsClassName = 'seam-components'
8064
8165export function SeamProvider ( {
@@ -84,198 +68,59 @@ export function SeamProvider({
8468 disableCssInjection = false ,
8569 disableFontInjection = false ,
8670 unminifiyCss = false ,
87- onSessionUpdate = ( ) => { } ,
88- queryClient,
8971 telemetryClient,
9072 ...props
9173} : SeamProviderProps ) : JSX . Element {
9274 useSeamStyles ( { disabled : disableCssInjection , unminified : unminifiyCss } )
9375 useSeamFont ( { disabled : disableFontInjection } )
9476
77+ const { Provider } = seamContext
78+
79+ const endpoint = 'endpoint' in props ? props . endpoint : undefined
9580 const value = useMemo ( ( ) => {
9681 const context = createSeamContextValue ( props )
97- if (
98- context . client == null &&
99- context . publishableKey == null &&
100- context . clientSessionToken == null
101- ) {
102- return defaultSeamContextValue
103- }
10482 return context
10583 } , [ props ] )
10684
107- if (
108- value . client == null &&
109- value . publishableKey == null &&
110- value . clientSessionToken == null
111- ) {
112- throw new Error (
113- `Must provide either a Seam client, clientSessionToken, or a publishableKey.`
114- )
115- }
116-
117- const { Provider } = seamContext
118-
119- const endpoint = 'endpoint' in props ? props . endpoint : undefined
120-
12185 return (
12286 < div className = { seamComponentsClassName } >
12387 < TelemetryProvider
12488 client = { telemetryClient ?? globalThis . seamTelemetryClient }
12589 disabled = { disableTelemetry }
12690 endpoint = { endpoint }
12791 >
128- < QueryClientProvider
129- client = {
130- queryClient ?? globalThis . seamQueryClient ?? defaultQueryClient
131- }
132- >
92+ < SeamQueryProvider { ...props } >
13393 < Provider value = { value } >
134- < Wrapper onSessionUpdate = { onSessionUpdate } > { children } </ Wrapper >
94+ < Telemetry > { children } </ Telemetry >
13595 </ Provider >
136- </ QueryClientProvider >
96+ </ SeamQueryProvider >
13797 </ TelemetryProvider >
13898 </ div >
13999 )
140100}
141101
142- function Wrapper ( {
143- onSessionUpdate,
144- children,
145- } : Required < Pick < SeamProviderProps , 'onSessionUpdate' > > &
146- PropsWithChildren ) : JSX . Element | null {
102+ function Telemetry ( { children } : PropsWithChildren ) : JSX . Element | null {
147103 useUserTelemetry ( )
148-
149- const { client } = useSeamClient ( )
150- useEffect ( ( ) => {
151- if ( client != null ) onSessionUpdate ( client )
152- } , [ onSessionUpdate , client ] )
153-
154104 return < > { children } </ >
155105}
156106
157107const createDefaultSeamContextValue = ( ) : SeamContext => {
158108 try {
159109 if ( globalThis . seam == null ) {
160- return { client : null }
110+ return { }
161111 }
162112 return createSeamContextValue ( globalThis . seam )
163113 } catch ( err ) {
164114 // eslint-disable-next-line no-console
165115 console . warn ( err )
166- return { client : null }
116+ return { }
167117 }
168118}
169119
170- const createSeamContextValue = ( options : SeamProviderProps ) : SeamContext => {
171- if ( isSeamProviderPropsWithClient ( options ) ) {
172- return options
173- }
174-
175- if ( isSeamProviderPropsWithClientSessionToken ( options ) ) {
176- const { clientSessionToken, ...clientOptions } = options
177- return {
178- clientSessionToken,
179- clientOptions,
180- client : null ,
181- }
182- }
183-
184- if ( isSeamProviderPropsWithPublishableKey ( options ) ) {
185- const { publishableKey, userIdentifierKey, ...clientOptions } = options
186- return {
187- publishableKey,
188- userIdentifierKey,
189- clientOptions,
190- client : null ,
191- }
192- }
193-
194- return { client : null }
120+ const createSeamContextValue = ( _options : SeamProviderProps ) : SeamContext => {
121+ return { }
195122}
196123
197124const defaultSeamContextValue = createDefaultSeamContextValue ( )
198125
199- export const seamContext = createContext < SeamContext > ( defaultSeamContextValue )
200-
201- export function useSeamContext ( ) : SeamContext {
202- return useContext ( seamContext )
203- }
204-
205- const isSeamProviderPropsWithClient = (
206- props : SeamProviderProps
207- ) : props is SeamProviderPropsWithClient => {
208- if ( ! ( 'client' in props ) ) return false
209-
210- const { client, ...otherProps } = props
211- if ( client == null ) return false
212-
213- const otherNonNullProps = Object . values ( otherProps ) . filter ( ( v ) => v != null )
214- if ( otherNonNullProps . length > 0 ) {
215- throw new InvalidSeamProviderProps (
216- `The client prop cannot be used with ${ otherNonNullProps . join ( ' or ' ) } .`
217- )
218- }
219-
220- return true
221- }
222-
223- const isSeamProviderPropsWithPublishableKey = (
224- props : SeamProviderProps
225- ) : props is SeamProviderPropsWithPublishableKey & SeamProviderClientOptions => {
226- if ( ! ( 'publishableKey' in props ) ) return false
227-
228- const { publishableKey } = props
229- if ( publishableKey == null ) return false
230-
231- if ( 'client' in props && props . client != null ) {
232- throw new InvalidSeamProviderProps (
233- 'The client prop cannot be used with the publishableKey prop.'
234- )
235- }
236-
237- if ( 'clientSessionToken' in props && props . clientSessionToken != null ) {
238- throw new InvalidSeamProviderProps (
239- 'The clientSessionToken prop cannot be used with the publishableKey prop.'
240- )
241- }
242-
243- return true
244- }
245-
246- const isSeamProviderPropsWithClientSessionToken = (
247- props : SeamProviderProps
248- ) : props is SeamProviderPropsWithClientSessionToken &
249- SeamProviderClientOptions => {
250- if ( ! ( 'clientSessionToken' in props ) ) return false
251-
252- const { clientSessionToken } = props
253- if ( clientSessionToken == null ) return false
254-
255- if ( 'client' in props && props . client != null ) {
256- throw new InvalidSeamProviderProps (
257- 'The client prop cannot be used with the clientSessionToken prop.'
258- )
259- }
260-
261- if ( 'publishableKey' in props && props . publishableKey != null ) {
262- throw new InvalidSeamProviderProps (
263- 'The publishableKey prop cannot be used with the clientSessionToken prop.'
264- )
265- }
266-
267- if ( 'userIdentifierKey' in props && props . userIdentifierKey != null ) {
268- throw new InvalidSeamProviderProps (
269- 'The userIdentifierKey prop cannot be used with the clientSessionToken prop.'
270- )
271- }
272-
273- return true
274- }
275-
276- class InvalidSeamProviderProps extends Error {
277- constructor ( message : string ) {
278- super ( `SeamProvider received invalid props: ${ message } ` )
279- this . name = this . constructor . name
280- }
281- }
126+ const seamContext = createContext < SeamContext > ( defaultSeamContextValue )
0 commit comments