@stytch/react 0.0.3-0 → 0.3.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 CHANGED
@@ -9,7 +9,7 @@ With `npm`
9
9
 
10
10
  ## Documentation
11
11
 
12
- For full documentation please refer to Stytch's javascript SDK documentation on https://stytch.com/docs/sdks.
12
+ For full documentation please refer to Stytch's javascript SDK documentation at https://stytch.com/docs/sdks.
13
13
 
14
14
  ## Example Usage
15
15
 
@@ -54,7 +54,11 @@ const App = () => {
54
54
 
55
55
  return (
56
56
  <div id="login">
57
- <Stytch config={stytchProps.loginOrSignupView} styles={stytchProps.style} callbacks={stytchProps.callbacks} />
57
+ <StytchLogin
58
+ config={stytchProps.loginOrSignupView}
59
+ styles={stytchProps.style}
60
+ callbacks={stytchProps.callbacks}
61
+ />
58
62
  </div>
59
63
  );
60
64
  };
@@ -63,3 +67,90 @@ const App = () => {
63
67
  ## Typescript Support
64
68
 
65
69
  There are built in typescript definitions in the npm package.
70
+
71
+ ## Migrating from @stytch/stytch-react
72
+
73
+ If you are migrating from [@stytch/stytch-react](https://www.npmjs.com/package/@stytch/stytch-react), follow the steps below:
74
+
75
+ ### Step 1: Install the new libraries
76
+
77
+ - The core SDK is now bundled in its own module - [@stytch/vanilla-js](https://www.npmjs.com/package/@stytch/vanilla-js)
78
+ - We now have a library specifically for React bindings - [@stytch/react](https://www.npmjs.com/package/@stytch/react)
79
+
80
+ ```shell
81
+ # NPM
82
+ npm install @stytch/vanilla-js @stytch/react
83
+ # Yarn
84
+ yarn add @stytch/vanilla-js @stytch/react
85
+ ```
86
+
87
+ ### Step 2: Remove the old SDK
88
+
89
+ - Remove the `@styth/stytch-react` package
90
+ - If you are explicitly loading the `stytch.js` script in the document header, remove it. It isn't needed anymore.
91
+
92
+ ```shell
93
+ # NPM
94
+ npm rm @stytch/stytch-react
95
+ # Yarn
96
+ yarn remove @stytch/stytch-react
97
+ ```
98
+
99
+ ### Step 3: Initialize the client in your Application Root
100
+
101
+ - Determine if you need the Headless or UI client. If you plan to use the `<StytchLogin />` component in your application then you should use the the UI client. Otherwise use the Headless client to minimize application bundle size.
102
+ - To create the Stytch Headless client, use `StytchHeadlessClient` from `@stytch/vanilla-js/headless`
103
+ - To create the Stytch UI client, use `StytchUIClient` from `@stytch/vanilla-js`
104
+ - Pass it into `<StytchProvider />` component from `@stytch/react`
105
+
106
+ ```jsx
107
+ import React from 'react';
108
+ import { StytchProvider } from '@stytch/react';
109
+ import { StytchHeadlessClient } from '@stytch/vanilla-js/headless';
110
+ // Or alternately
111
+ // import { StytchUIClient } from '@stytch/vanilla-js';
112
+
113
+ const stytch = new StytchHeadlessClient(process.env.REACT_APP_STYTCH_PUBLIC_TOKEN);
114
+
115
+ function WrappedApp() {
116
+ return (
117
+ <StytchProvider stytch={stytch}>
118
+ <App />
119
+ </StytchProvider>
120
+ );
121
+ }
122
+
123
+ export default WrappedApp;
124
+ ```
125
+
126
+ ### Step 4: Update calls to `useStytchUser` , `useStytchSession`, and `useStytchLazy`
127
+
128
+ - `useStytchUser` and `useStytchSession` hooks now return envelope objects - `{ user, isCached }` and `{ session, isCached }` respectively.
129
+ - On first render the SDK will read user/session out of persistent storage, and serve them with `isCached: true` - at this point you’re reading the stale-while-revalidating value
130
+ - The SDK will make network requests to pull the most up-to-date user and session objects, and serve them with `isCached: false`
131
+ - `useStytchLazy` is no longer required - you may always call `useStytch` now
132
+
133
+ ```jsx
134
+ import React, { useEffect } from 'react';
135
+ import { useStytchUser } from '@stytch/react';
136
+
137
+ export default function Profile() {
138
+ const router = useRouter();
139
+ const { user, isCached } = useStytchUser();
140
+
141
+ return (
142
+ <Layout>
143
+ <h1>Your {isCached ? 'Cached' : null} Profile</h1>
144
+ <pre>{JSON.stringify(user, null, 2)}</pre>
145
+ </Layout>
146
+ );
147
+ }
148
+ ```
149
+
150
+ ### Step 5: UI Naming Changes
151
+
152
+ We've made a number of small changes to our naming conventions to make the API cleaner and easier to understand.
153
+
154
+ - The `<Stytch />` login component is now called `<StytchLogin />`
155
+ - The `OAuthProvidersTypes` enum is now called `OAuthProviders`
156
+ - The `SDKProductTypes` enum is now called `Products`
package/dist/index.d.ts CHANGED
@@ -1,35 +1,208 @@
1
1
  /// <reference types="react" />
2
- import { Callbacks, Config, StyleConfig, User, Session, StytchUIClient } from "@stytch/vanilla-js";
2
+ // We need to import the StytchUIClient type to give the TSDoc parser a hint as to where it is from
3
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
4
+ import { Callbacks, StytchLoginConfig, StyleConfig, User, Session, StytchUIClient } from "@stytch/vanilla-js";
3
5
  import React from "react";
4
6
  import { ReactNode } from "react";
5
7
  import { StytchHeadlessClient } from "@stytch/vanilla-js/headless";
8
+ interface StytchProps {
9
+ /**
10
+ * A {@link StytchLoginConfig} object. Add products and product-specific config to this object to change the login methods shown.
11
+ *
12
+ * @example
13
+ * {
14
+ * products: ['crypto', 'otps']
15
+ * }
16
+ *
17
+ * @example
18
+ * {
19
+ * products: ['emailMagicLinks'>]
20
+ * emailMagicLinksOptions: {
21
+ * loginRedirectURL: 'https://example.com/authenticate',
22
+ * signupRedirectURL: 'https://example.com/authenticate',
23
+ * }
24
+ * }
25
+ *
26
+ * @example
27
+ * {
28
+ * products: ['oauth'>]
29
+ * oauthOptions: {
30
+ * providers: [
31
+ * { type: 'google', one_tap: true, position: 'embedded' },
32
+ * { type: 'microsoft' },
33
+ * { type: 'apple' },
34
+ * { type: 'facebook' },
35
+ * ],
36
+ * }
37
+ * }
38
+ */
39
+ config: StytchLoginConfig;
40
+ /**
41
+ * An optional {@link StyleConfig} to customize the look and feel of the screen.
42
+ *
43
+ * @example
44
+ * {
45
+ * fontFamily: 'Arial, Helvetica, sans-serif',
46
+ * width: '360px',
47
+ * primaryColor: '#19303D',
48
+ * }
49
+ */
50
+ styles?: StyleConfig;
51
+ /**
52
+ * An optional {@link Callbacks} object.
53
+ *
54
+ * @example
55
+ * {
56
+ * onError: ({message}) => {
57
+ * console.error('Stytch login screen error', message)
58
+ * }
59
+ * }
60
+ *
61
+ * @example
62
+ * {
63
+ * onEvent: ({type, data}) => {
64
+ * if(type === StytchEventType.CryptoWalletAuthenticate) {
65
+ * console.log('Logged in with crypto wallet', data);
66
+ * }
67
+ * }
68
+ * }
69
+ */
70
+ callbacks?: Callbacks;
71
+ }
6
72
  /**
7
- * Stytch JS React Component
73
+ * The Stytch Login Screen component.
74
+ * This component can only be used with a {@link StytchUIClient} client constructor
75
+ * passed into the {@link StytchProvider}
8
76
  *
9
- * [Documentation](https://stytch.com/docs/javascript-sdk)
77
+ * See the {@link https://stytch.com/docs/sdks/javascript-sdk online reference}
78
+ * and {@link https://storybook.stytch.com interactive examples} for more.
79
+ *
80
+ * @example
81
+ * <StytchLogin
82
+ * config={{
83
+ * products: ['emailMagicLinks', 'oauth'],
84
+ * emailMagicLinksOptions: {
85
+ * loginRedirectURL: 'https://example.com/authenticate',
86
+ * signupRedirectURL: 'https://example.com/authenticate',
87
+ * },
88
+ * oauthOptions: {
89
+ * providers: [{ type: OAuthProviders.Google }, { type: OAuthProviders.Microsoft }],
90
+ * },
91
+ * }}
92
+ * styles={{
93
+ * fontFamily: '"Helvetica New", Helvetica, sans-serif',
94
+ * primaryColor: '#0577CA',
95
+ * width: '321px',
96
+ * }}
97
+ * callbacks={{
98
+ * onEvent: (event) => console.log(event)
99
+ * }}
100
+ * />
101
+ * @param props {@link StytchProps}
102
+ */
103
+ declare const StytchLogin: ({ config, styles, callbacks }: StytchProps) => JSX.Element;
104
+ interface StytchResetPasswordProps extends StytchProps {
105
+ passwordResetToken: string;
106
+ }
107
+ /**
108
+ * The Stytch Reset Password component.
109
+ * This component can only be used with a {@link StytchUIClient} client constructor
110
+ * passed into the {@link StytchProvider}
111
+ *
112
+ * See the {@link https://stytch.com/docs/sdks/javascript-sdk online reference}
113
+ * and {@link https://storybook.stytch.com interactive examples} for more.
114
+ *
115
+ * @example
116
+ * TODO
117
+ */
118
+ declare const StytchPasswordReset: ({ config, styles, callbacks, passwordResetToken }: StytchResetPasswordProps) => JSX.Element;
119
+ /**
120
+ * The Stytch Client object passed in to <StytchProvider /> in your application root.
121
+ * Either a StytchUIClient or StytchHeadlessClient.
10
122
  */
11
- declare const Stytch: ({ config, styles, callbacks }: {
12
- config: Config;
13
- styles: StyleConfig;
14
- callbacks?: Callbacks | undefined;
15
- }) => JSX.Element | null;
16
123
  type StytchClient = StytchUIClient | StytchHeadlessClient;
17
- declare const useStytchUser: () => User | null;
18
- declare const useStytchSession: () => Session | null;
124
+ type SWRUser = {
125
+ /**
126
+ * Either the active {@link User} object, or null if the user is not logged in.
127
+ */
128
+ user: User | null;
129
+ /**
130
+ * If true, indicates that the value returned is from the application cache and a state refresh is in progress.
131
+ */
132
+ fromCache: boolean;
133
+ };
134
+ type SWRSession = {
135
+ /**
136
+ * Either the active {@link Session} object, or null if the user is not logged in.
137
+ */
138
+ session: Session | null;
139
+ /**
140
+ * If true, indicates that the value returned is from the application cache and a state refresh is in progress.
141
+ */
142
+ fromCache: boolean;
143
+ };
144
+ /**
145
+ * Returns the active User.
146
+ * Check the fromCache property to determine if the user data is from persistent storage.
147
+ * @example
148
+ * const {user} = useStytchUser();
149
+ * return (<h1>Welcome, {user.name.first_name}</h1>);
150
+ * @returns A {@link SWRUser}
151
+ */
152
+ declare const useStytchUser: () => SWRUser;
153
+ /**
154
+ * Returns the active user's Stytch session.
155
+ * @example
156
+ * const {session} = useStytchSession();
157
+ * useEffect(() => {
158
+ * if (!session) {
159
+ * router.replace('/login')
160
+ * }
161
+ * }, [session]);
162
+ * @returns A {@link SWRSession}
163
+ */
164
+ declare const useStytchSession: () => SWRSession;
165
+ /**
166
+ * Returns the Stytch client stored in the Stytch context.
167
+ *
168
+ * @example
169
+ * const stytch = useStytch();
170
+ * useEffect(() => {
171
+ * stytch.magicLinks.authenticate('...')
172
+ * }, [stytch]);
173
+ */
19
174
  declare const useStytch: () => StytchClient;
20
175
  declare const withStytch: <T extends object>(Component: React.ComponentType<T & {
21
176
  stytch: StytchClient;
22
177
  }>) => React.ComponentType<T>;
23
178
  declare const withStytchUser: <T extends object>(Component: React.ComponentType<T & {
24
179
  stytchUser: User | null;
180
+ stytchUserIsFromCache: boolean;
25
181
  }>) => React.ComponentType<T>;
26
182
  declare const withStytchSession: <T extends object>(Component: React.ComponentType<T & {
27
183
  stytchSession: Session | null;
184
+ stytchSessionIsFromCache: boolean;
28
185
  }>) => React.ComponentType<T>;
29
186
  type StytchProviderProps = {
187
+ /**
188
+ * A Stytch client instance, either a {@link StytchUIClient} or {@link StytchHeadlessClient}
189
+ */
30
190
  stytch: StytchClient;
31
191
  children?: ReactNode;
32
192
  };
193
+ /**
194
+ * The Stytch Context Provider.
195
+ * Wrap your application with this component in the root file in order to use Stytch everywhere in your app.
196
+ * @example
197
+ * const stytch = new StytchHeadlessClient('public-token-<find yours in the stytch dashboard>')
198
+ *
199
+ * ReactDOM.render(
200
+ * <StytchProvider stytch={stytch}>
201
+ * <App />
202
+ * </StytchProvider>,
203
+ * document.getElementById('root'),
204
+ * )
205
+ */
33
206
  declare const StytchProvider: ({ stytch, children }: StytchProviderProps) => JSX.Element;
34
- export { Stytch, StytchProvider, useStytch, useStytchSession, useStytchUser, withStytch, withStytchSession, withStytchUser };
207
+ export { StytchLogin, StytchPasswordReset, StytchProvider, useStytch, useStytchSession, useStytchUser, withStytch, withStytchSession, withStytchUser };
35
208
  export type { StytchProviderProps };
@@ -1,35 +1,208 @@
1
1
  /// <reference types="react" />
2
- import { Callbacks, Config, StyleConfig, User, Session, StytchUIClient } from "@stytch/vanilla-js";
2
+ // We need to import the StytchUIClient type to give the TSDoc parser a hint as to where it is from
3
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
4
+ import { Callbacks, StytchLoginConfig, StyleConfig, User, Session, StytchUIClient } from "@stytch/vanilla-js";
3
5
  import React from "react";
4
6
  import { ReactNode } from "react";
5
7
  import { StytchHeadlessClient } from "@stytch/vanilla-js/headless";
8
+ interface StytchProps {
9
+ /**
10
+ * A {@link StytchLoginConfig} object. Add products and product-specific config to this object to change the login methods shown.
11
+ *
12
+ * @example
13
+ * {
14
+ * products: ['crypto', 'otps']
15
+ * }
16
+ *
17
+ * @example
18
+ * {
19
+ * products: ['emailMagicLinks'>]
20
+ * emailMagicLinksOptions: {
21
+ * loginRedirectURL: 'https://example.com/authenticate',
22
+ * signupRedirectURL: 'https://example.com/authenticate',
23
+ * }
24
+ * }
25
+ *
26
+ * @example
27
+ * {
28
+ * products: ['oauth'>]
29
+ * oauthOptions: {
30
+ * providers: [
31
+ * { type: 'google', one_tap: true, position: 'embedded' },
32
+ * { type: 'microsoft' },
33
+ * { type: 'apple' },
34
+ * { type: 'facebook' },
35
+ * ],
36
+ * }
37
+ * }
38
+ */
39
+ config: StytchLoginConfig;
40
+ /**
41
+ * An optional {@link StyleConfig} to customize the look and feel of the screen.
42
+ *
43
+ * @example
44
+ * {
45
+ * fontFamily: 'Arial, Helvetica, sans-serif',
46
+ * width: '360px',
47
+ * primaryColor: '#19303D',
48
+ * }
49
+ */
50
+ styles?: StyleConfig;
51
+ /**
52
+ * An optional {@link Callbacks} object.
53
+ *
54
+ * @example
55
+ * {
56
+ * onError: ({message}) => {
57
+ * console.error('Stytch login screen error', message)
58
+ * }
59
+ * }
60
+ *
61
+ * @example
62
+ * {
63
+ * onEvent: ({type, data}) => {
64
+ * if(type === StytchEventType.CryptoWalletAuthenticate) {
65
+ * console.log('Logged in with crypto wallet', data);
66
+ * }
67
+ * }
68
+ * }
69
+ */
70
+ callbacks?: Callbacks;
71
+ }
6
72
  /**
7
- * Stytch JS React Component
73
+ * The Stytch Login Screen component.
74
+ * This component can only be used with a {@link StytchUIClient} client constructor
75
+ * passed into the {@link StytchProvider}
8
76
  *
9
- * [Documentation](https://stytch.com/docs/javascript-sdk)
77
+ * See the {@link https://stytch.com/docs/sdks/javascript-sdk online reference}
78
+ * and {@link https://storybook.stytch.com interactive examples} for more.
79
+ *
80
+ * @example
81
+ * <StytchLogin
82
+ * config={{
83
+ * products: ['emailMagicLinks', 'oauth'],
84
+ * emailMagicLinksOptions: {
85
+ * loginRedirectURL: 'https://example.com/authenticate',
86
+ * signupRedirectURL: 'https://example.com/authenticate',
87
+ * },
88
+ * oauthOptions: {
89
+ * providers: [{ type: OAuthProviders.Google }, { type: OAuthProviders.Microsoft }],
90
+ * },
91
+ * }}
92
+ * styles={{
93
+ * fontFamily: '"Helvetica New", Helvetica, sans-serif',
94
+ * primaryColor: '#0577CA',
95
+ * width: '321px',
96
+ * }}
97
+ * callbacks={{
98
+ * onEvent: (event) => console.log(event)
99
+ * }}
100
+ * />
101
+ * @param props {@link StytchProps}
102
+ */
103
+ declare const StytchLogin: ({ config, styles, callbacks }: StytchProps) => JSX.Element;
104
+ interface StytchResetPasswordProps extends StytchProps {
105
+ passwordResetToken: string;
106
+ }
107
+ /**
108
+ * The Stytch Reset Password component.
109
+ * This component can only be used with a {@link StytchUIClient} client constructor
110
+ * passed into the {@link StytchProvider}
111
+ *
112
+ * See the {@link https://stytch.com/docs/sdks/javascript-sdk online reference}
113
+ * and {@link https://storybook.stytch.com interactive examples} for more.
114
+ *
115
+ * @example
116
+ * TODO
117
+ */
118
+ declare const StytchPasswordReset: ({ config, styles, callbacks, passwordResetToken }: StytchResetPasswordProps) => JSX.Element;
119
+ /**
120
+ * The Stytch Client object passed in to <StytchProvider /> in your application root.
121
+ * Either a StytchUIClient or StytchHeadlessClient.
10
122
  */
11
- declare const Stytch: ({ config, styles, callbacks }: {
12
- config: Config;
13
- styles: StyleConfig;
14
- callbacks?: Callbacks | undefined;
15
- }) => JSX.Element | null;
16
123
  type StytchClient = StytchUIClient | StytchHeadlessClient;
17
- declare const useStytchUser: () => User | null;
18
- declare const useStytchSession: () => Session | null;
124
+ type SWRUser = {
125
+ /**
126
+ * Either the active {@link User} object, or null if the user is not logged in.
127
+ */
128
+ user: User | null;
129
+ /**
130
+ * If true, indicates that the value returned is from the application cache and a state refresh is in progress.
131
+ */
132
+ fromCache: boolean;
133
+ };
134
+ type SWRSession = {
135
+ /**
136
+ * Either the active {@link Session} object, or null if the user is not logged in.
137
+ */
138
+ session: Session | null;
139
+ /**
140
+ * If true, indicates that the value returned is from the application cache and a state refresh is in progress.
141
+ */
142
+ fromCache: boolean;
143
+ };
144
+ /**
145
+ * Returns the active User.
146
+ * Check the fromCache property to determine if the user data is from persistent storage.
147
+ * @example
148
+ * const {user} = useStytchUser();
149
+ * return (<h1>Welcome, {user.name.first_name}</h1>);
150
+ * @returns A {@link SWRUser}
151
+ */
152
+ declare const useStytchUser: () => SWRUser;
153
+ /**
154
+ * Returns the active user's Stytch session.
155
+ * @example
156
+ * const {session} = useStytchSession();
157
+ * useEffect(() => {
158
+ * if (!session) {
159
+ * router.replace('/login')
160
+ * }
161
+ * }, [session]);
162
+ * @returns A {@link SWRSession}
163
+ */
164
+ declare const useStytchSession: () => SWRSession;
165
+ /**
166
+ * Returns the Stytch client stored in the Stytch context.
167
+ *
168
+ * @example
169
+ * const stytch = useStytch();
170
+ * useEffect(() => {
171
+ * stytch.magicLinks.authenticate('...')
172
+ * }, [stytch]);
173
+ */
19
174
  declare const useStytch: () => StytchClient;
20
175
  declare const withStytch: <T extends object>(Component: React.ComponentType<T & {
21
176
  stytch: StytchClient;
22
177
  }>) => React.ComponentType<T>;
23
178
  declare const withStytchUser: <T extends object>(Component: React.ComponentType<T & {
24
179
  stytchUser: User | null;
180
+ stytchUserIsFromCache: boolean;
25
181
  }>) => React.ComponentType<T>;
26
182
  declare const withStytchSession: <T extends object>(Component: React.ComponentType<T & {
27
183
  stytchSession: Session | null;
184
+ stytchSessionIsFromCache: boolean;
28
185
  }>) => React.ComponentType<T>;
29
186
  type StytchProviderProps = {
187
+ /**
188
+ * A Stytch client instance, either a {@link StytchUIClient} or {@link StytchHeadlessClient}
189
+ */
30
190
  stytch: StytchClient;
31
191
  children?: ReactNode;
32
192
  };
193
+ /**
194
+ * The Stytch Context Provider.
195
+ * Wrap your application with this component in the root file in order to use Stytch everywhere in your app.
196
+ * @example
197
+ * const stytch = new StytchHeadlessClient('public-token-<find yours in the stytch dashboard>')
198
+ *
199
+ * ReactDOM.render(
200
+ * <StytchProvider stytch={stytch}>
201
+ * <App />
202
+ * </StytchProvider>,
203
+ * document.getElementById('root'),
204
+ * )
205
+ */
33
206
  declare const StytchProvider: ({ stytch, children }: StytchProviderProps) => JSX.Element;
34
- export { Stytch, StytchProvider, useStytch, useStytchSession, useStytchUser, withStytch, withStytchSession, withStytchUser };
207
+ export { StytchLogin, StytchPasswordReset, StytchProvider, useStytch, useStytchSession, useStytchUser, withStytch, withStytchSession, withStytchUser };
35
208
  export type { StytchProviderProps };
package/dist/index.esm.js CHANGED
@@ -1,5 +1,4 @@
1
- import * as React from 'react';
2
- import React__default, { useRef, useState, useEffect, useCallback, createContext, useContext, useMemo } from 'react';
1
+ import React, { useRef, useState, useEffect, useCallback, createContext, useContext, useMemo, useLayoutEffect } from 'react';
3
2
 
4
3
  const noProviderError = (item) => `${item} can only be used inside <StytchProvider>.`;
5
4
  const providerMustBeUniqueError = 'You cannot render a <StytchProvider> inside another <StytchProvider>.';
@@ -34,21 +33,57 @@ const useAsyncState = (initialState) => {
34
33
  return [state, setStateAction];
35
34
  };
36
35
 
36
+ const initialUser = {
37
+ user: null,
38
+ fromCache: false,
39
+ };
40
+ const initialSession = {
41
+ session: null,
42
+ fromCache: false,
43
+ };
37
44
  const StytchContext = createContext({ isMounted: false });
38
- const StytchUserContext = createContext(null);
39
- const StytchSessionContext = createContext(null);
45
+ const StytchUserContext = createContext(initialUser);
46
+ const StytchSessionContext = createContext(initialSession);
40
47
  const useIsMounted__INTERNAL = () => useContext(StytchContext).isMounted;
41
48
  const isUIClient = (client) => {
42
- return client.mount !== undefined;
49
+ return client.mountLogin !== undefined;
43
50
  };
51
+ /**
52
+ * Returns the active User.
53
+ * Check the fromCache property to determine if the user data is from persistent storage.
54
+ * @example
55
+ * const {user} = useStytchUser();
56
+ * return (<h1>Welcome, {user.name.first_name}</h1>);
57
+ * @returns A {@link SWRUser}
58
+ */
44
59
  const useStytchUser = () => {
45
60
  invariant(useIsMounted__INTERNAL(), noProviderError('useStytchUser'));
46
61
  return useContext(StytchUserContext);
47
62
  };
63
+ /**
64
+ * Returns the active user's Stytch session.
65
+ * @example
66
+ * const {session} = useStytchSession();
67
+ * useEffect(() => {
68
+ * if (!session) {
69
+ * router.replace('/login')
70
+ * }
71
+ * }, [session]);
72
+ * @returns A {@link SWRSession}
73
+ */
48
74
  const useStytchSession = () => {
49
75
  invariant(useIsMounted__INTERNAL(), noProviderError('useStytchSession'));
50
76
  return useContext(StytchSessionContext);
51
77
  };
78
+ /**
79
+ * Returns the Stytch client stored in the Stytch context.
80
+ *
81
+ * @example
82
+ * const stytch = useStytch();
83
+ * useEffect(() => {
84
+ * stytch.magicLinks.authenticate('...')
85
+ * }, [stytch]);
86
+ */
52
87
  const useStytch = () => {
53
88
  const ctx = useContext(StytchContext);
54
89
  invariant(ctx.isMounted, noProviderError('useStytch'));
@@ -57,7 +92,7 @@ const useStytch = () => {
57
92
  const withStytch = (Component) => {
58
93
  const WithStytch = (props) => {
59
94
  invariant(useIsMounted__INTERNAL(), noProviderError('withStytch'));
60
- return React__default.createElement(Component, { ...props, stytch: useStytch() });
95
+ return React.createElement(Component, Object.assign({}, props, { stytch: useStytch() }));
61
96
  };
62
97
  WithStytch.displayName = `withStytch(${Component.displayName || Component.name || 'Component'})`;
63
98
  return WithStytch;
@@ -65,7 +100,8 @@ const withStytch = (Component) => {
65
100
  const withStytchUser = (Component) => {
66
101
  const WithStytchUser = (props) => {
67
102
  invariant(useIsMounted__INTERNAL(), noProviderError('withStytchUser'));
68
- return React__default.createElement(Component, { ...props, stytchUser: useStytchUser() });
103
+ const { user, fromCache } = useStytchUser();
104
+ return React.createElement(Component, Object.assign({}, props, { stytchUser: user, stytchUserIsFromCache: fromCache }));
69
105
  };
70
106
  WithStytchUser.displayName = `withStytchUser(${Component.displayName || Component.name || 'Component'})`;
71
107
  return WithStytchUser;
@@ -73,65 +109,150 @@ const withStytchUser = (Component) => {
73
109
  const withStytchSession = (Component) => {
74
110
  const WithStytchSession = (props) => {
75
111
  invariant(useIsMounted__INTERNAL(), noProviderError('withStytchSession'));
76
- return React__default.createElement(Component, { ...props, stytchSession: useStytchSession() });
112
+ const { session, fromCache } = useStytchSession();
113
+ return React.createElement(Component, Object.assign({}, props, { stytchSession: session, stytchSessionIsFromCache: fromCache }));
77
114
  };
78
115
  WithStytchSession.displayName = `withStytchSession(${Component.displayName || Component.name || 'Component'})`;
79
116
  return WithStytchSession;
80
117
  };
118
+ /**
119
+ * The Stytch Context Provider.
120
+ * Wrap your application with this component in the root file in order to use Stytch everywhere in your app.
121
+ * @example
122
+ * const stytch = new StytchHeadlessClient('public-token-<find yours in the stytch dashboard>')
123
+ *
124
+ * ReactDOM.render(
125
+ * <StytchProvider stytch={stytch}>
126
+ * <App />
127
+ * </StytchProvider>,
128
+ * document.getElementById('root'),
129
+ * )
130
+ */
81
131
  const StytchProvider = ({ stytch, children }) => {
82
132
  invariant(!useIsMounted__INTERNAL(), providerMustBeUniqueError);
83
133
  invariant(typeof window !== 'undefined', noSSRError);
84
134
  const ctx = useMemo(() => ({ client: stytch, isMounted: true }), [stytch]);
85
- const [user, setUser] = useAsyncState(stytch.user.getSync());
86
- const [session, setSession] = useAsyncState(stytch.session.getSync());
135
+ const [user, setUser] = useAsyncState({
136
+ user: stytch.user.getSync(),
137
+ fromCache: true,
138
+ });
139
+ const [session, setSession] = useAsyncState({
140
+ session: stytch.session.getSync(),
141
+ fromCache: true,
142
+ });
87
143
  useEffect(() => {
88
- const unsubscribeUser = stytch.user.onChange((user) => setUser(user));
89
- const unsubscribeSession = stytch.session.onChange((session) => setSession(session));
144
+ const unsubscribeUser = stytch.user.onChange((user) => setUser({
145
+ user,
146
+ fromCache: false,
147
+ }));
148
+ const unsubscribeSession = stytch.session.onChange((session) => setSession({
149
+ session,
150
+ fromCache: false,
151
+ }));
90
152
  return () => {
91
153
  unsubscribeUser();
92
154
  unsubscribeSession();
93
155
  };
94
156
  }, [stytch, setUser, setSession]);
95
- return (React__default.createElement(StytchContext.Provider, { value: ctx },
96
- React__default.createElement(StytchUserContext.Provider, { value: session && user },
97
- React__default.createElement(StytchSessionContext.Provider, { value: user && session }, children))));
157
+ const finalSess = !!session.session === !!user.user ? session : initialSession;
158
+ const finalUser = !!session.session === !!user.user ? user : initialUser;
159
+ return (React.createElement(StytchContext.Provider, { value: ctx },
160
+ React.createElement(StytchUserContext.Provider, { value: finalUser },
161
+ React.createElement(StytchSessionContext.Provider, { value: finalSess }, children))));
98
162
  };
99
163
 
100
164
  /**
101
- * Returns a unique element ID.
102
- * Intended to only be used client-side - this will cause HTML mismatch issues in SSR!
103
- * cf: https://github.com/vercel/next.js/issues/7322#issuecomment-968858477
104
- */
105
- const useUniqueElementId = () => {
106
- return React.useMemo(() => {
107
- const randId = Math.floor(Math.random() * 1e6);
108
- return `stytch-magic-link-${randId}`;
109
- }, []);
110
- };
111
- /**
112
- * Stytch JS React Component
165
+ * The Stytch Login Screen component.
166
+ * This component can only be used with a {@link StytchUIClient} client constructor
167
+ * passed into the {@link StytchProvider}
113
168
  *
114
- * [Documentation](https://stytch.com/docs/javascript-sdk)
169
+ * See the {@link https://stytch.com/docs/sdks/javascript-sdk online reference}
170
+ * and {@link https://storybook.stytch.com interactive examples} for more.
171
+ *
172
+ * @example
173
+ * <StytchLogin
174
+ * config={{
175
+ * products: ['emailMagicLinks', 'oauth'],
176
+ * emailMagicLinksOptions: {
177
+ * loginRedirectURL: 'https://example.com/authenticate',
178
+ * signupRedirectURL: 'https://example.com/authenticate',
179
+ * },
180
+ * oauthOptions: {
181
+ * providers: [{ type: OAuthProviders.Google }, { type: OAuthProviders.Microsoft }],
182
+ * },
183
+ * }}
184
+ * styles={{
185
+ * fontFamily: '"Helvetica New", Helvetica, sans-serif',
186
+ * primaryColor: '#0577CA',
187
+ * width: '321px',
188
+ * }}
189
+ * callbacks={{
190
+ * onEvent: (event) => console.log(event)
191
+ * }}
192
+ * />
193
+ * @param props {@link StytchProps}
115
194
  */
116
- const Stytch = ({ config, styles, callbacks, }) => {
117
- invariant(useIsMounted__INTERNAL(), noProviderError('<Stytch />'));
195
+ const StytchLogin = ({ config, styles, callbacks }) => {
196
+ invariant(useIsMounted__INTERNAL(), noProviderError('<StytchLogin />'));
118
197
  const stytchClient = useStytch();
119
- const elementId = useUniqueElementId();
120
- React.useEffect(() => {
121
- if (!elementId) {
122
- return;
123
- }
198
+ const containerEl = useRef(null);
199
+ useLayoutEffect(() => {
124
200
  if (!isUIClient(stytchClient)) {
125
201
  throw Error(noHeadlessClientError);
126
202
  }
127
- stytchClient.mount({
203
+ if (!containerEl.current) {
204
+ return;
205
+ }
206
+ if (!containerEl.current.id) {
207
+ const randId = Math.floor(Math.random() * 1e6);
208
+ containerEl.current.id = `stytch-magic-link-${randId}`;
209
+ }
210
+ stytchClient.mountLogin({
128
211
  config,
129
212
  callbacks,
130
- elementId: `#${elementId}`,
213
+ elementId: `#${containerEl.current.id}`,
131
214
  styles,
132
215
  });
133
- }, [elementId, stytchClient]);
134
- return elementId ? React.createElement("div", { id: elementId }) : null;
216
+ }, [stytchClient, config, styles, callbacks]);
217
+ return React.createElement("div", { ref: containerEl });
218
+ };
219
+ /**
220
+ * The Stytch Reset Password component.
221
+ * This component can only be used with a {@link StytchUIClient} client constructor
222
+ * passed into the {@link StytchProvider}
223
+ *
224
+ * See the {@link https://stytch.com/docs/sdks/javascript-sdk online reference}
225
+ * and {@link https://storybook.stytch.com interactive examples} for more.
226
+ *
227
+ * @example
228
+ * TODO
229
+ */
230
+ const StytchPasswordReset = ({ config, styles, callbacks, passwordResetToken }) => {
231
+ invariant(useIsMounted__INTERNAL(), noProviderError('<StytchResetPassword />'));
232
+ const stytchClient = useStytch();
233
+ const containerEl = useRef(null);
234
+ useLayoutEffect(() => {
235
+ if (!isUIClient(stytchClient)) {
236
+ throw Error(noHeadlessClientError);
237
+ }
238
+ if (!containerEl.current) {
239
+ return;
240
+ }
241
+ if (!containerEl.current.id) {
242
+ const randId = Math.floor(Math.random() * 1e6);
243
+ containerEl.current.id = `stytch-reset-password-${randId}`;
244
+ }
245
+ if (passwordResetToken) {
246
+ stytchClient.mountResetPassword({
247
+ config,
248
+ callbacks,
249
+ elementId: `#${containerEl.current.id}`,
250
+ styles,
251
+ passwordResetToken,
252
+ });
253
+ }
254
+ }, [stytchClient, config, styles, callbacks, passwordResetToken]);
255
+ return React.createElement("div", { ref: containerEl });
135
256
  };
136
257
 
137
- export { Stytch, StytchProvider, useStytch, useStytchSession, useStytchUser, withStytch, withStytchSession, withStytchUser };
258
+ export { StytchLogin, StytchPasswordReset, StytchProvider, useStytch, useStytchSession, useStytchUser, withStytch, withStytchSession, withStytchUser };
package/dist/index.js CHANGED
@@ -6,26 +6,7 @@ var React = require('react');
6
6
 
7
7
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
8
 
9
- function _interopNamespace(e) {
10
- if (e && e.__esModule) return e;
11
- var n = Object.create(null);
12
- if (e) {
13
- Object.keys(e).forEach(function (k) {
14
- if (k !== 'default') {
15
- var d = Object.getOwnPropertyDescriptor(e, k);
16
- Object.defineProperty(n, k, d.get ? d : {
17
- enumerable: true,
18
- get: function () { return e[k]; }
19
- });
20
- }
21
- });
22
- }
23
- n["default"] = e;
24
- return Object.freeze(n);
25
- }
26
-
27
9
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
28
- var React__namespace = /*#__PURE__*/_interopNamespace(React);
29
10
 
30
11
  const noProviderError = (item) => `${item} can only be used inside <StytchProvider>.`;
31
12
  const providerMustBeUniqueError = 'You cannot render a <StytchProvider> inside another <StytchProvider>.';
@@ -60,21 +41,57 @@ const useAsyncState = (initialState) => {
60
41
  return [state, setStateAction];
61
42
  };
62
43
 
44
+ const initialUser = {
45
+ user: null,
46
+ fromCache: false,
47
+ };
48
+ const initialSession = {
49
+ session: null,
50
+ fromCache: false,
51
+ };
63
52
  const StytchContext = React.createContext({ isMounted: false });
64
- const StytchUserContext = React.createContext(null);
65
- const StytchSessionContext = React.createContext(null);
53
+ const StytchUserContext = React.createContext(initialUser);
54
+ const StytchSessionContext = React.createContext(initialSession);
66
55
  const useIsMounted__INTERNAL = () => React.useContext(StytchContext).isMounted;
67
56
  const isUIClient = (client) => {
68
- return client.mount !== undefined;
57
+ return client.mountLogin !== undefined;
69
58
  };
59
+ /**
60
+ * Returns the active User.
61
+ * Check the fromCache property to determine if the user data is from persistent storage.
62
+ * @example
63
+ * const {user} = useStytchUser();
64
+ * return (<h1>Welcome, {user.name.first_name}</h1>);
65
+ * @returns A {@link SWRUser}
66
+ */
70
67
  const useStytchUser = () => {
71
68
  invariant(useIsMounted__INTERNAL(), noProviderError('useStytchUser'));
72
69
  return React.useContext(StytchUserContext);
73
70
  };
71
+ /**
72
+ * Returns the active user's Stytch session.
73
+ * @example
74
+ * const {session} = useStytchSession();
75
+ * useEffect(() => {
76
+ * if (!session) {
77
+ * router.replace('/login')
78
+ * }
79
+ * }, [session]);
80
+ * @returns A {@link SWRSession}
81
+ */
74
82
  const useStytchSession = () => {
75
83
  invariant(useIsMounted__INTERNAL(), noProviderError('useStytchSession'));
76
84
  return React.useContext(StytchSessionContext);
77
85
  };
86
+ /**
87
+ * Returns the Stytch client stored in the Stytch context.
88
+ *
89
+ * @example
90
+ * const stytch = useStytch();
91
+ * useEffect(() => {
92
+ * stytch.magicLinks.authenticate('...')
93
+ * }, [stytch]);
94
+ */
78
95
  const useStytch = () => {
79
96
  const ctx = React.useContext(StytchContext);
80
97
  invariant(ctx.isMounted, noProviderError('useStytch'));
@@ -83,7 +100,7 @@ const useStytch = () => {
83
100
  const withStytch = (Component) => {
84
101
  const WithStytch = (props) => {
85
102
  invariant(useIsMounted__INTERNAL(), noProviderError('withStytch'));
86
- return React__default["default"].createElement(Component, { ...props, stytch: useStytch() });
103
+ return React__default["default"].createElement(Component, Object.assign({}, props, { stytch: useStytch() }));
87
104
  };
88
105
  WithStytch.displayName = `withStytch(${Component.displayName || Component.name || 'Component'})`;
89
106
  return WithStytch;
@@ -91,7 +108,8 @@ const withStytch = (Component) => {
91
108
  const withStytchUser = (Component) => {
92
109
  const WithStytchUser = (props) => {
93
110
  invariant(useIsMounted__INTERNAL(), noProviderError('withStytchUser'));
94
- return React__default["default"].createElement(Component, { ...props, stytchUser: useStytchUser() });
111
+ const { user, fromCache } = useStytchUser();
112
+ return React__default["default"].createElement(Component, Object.assign({}, props, { stytchUser: user, stytchUserIsFromCache: fromCache }));
95
113
  };
96
114
  WithStytchUser.displayName = `withStytchUser(${Component.displayName || Component.name || 'Component'})`;
97
115
  return WithStytchUser;
@@ -99,68 +117,154 @@ const withStytchUser = (Component) => {
99
117
  const withStytchSession = (Component) => {
100
118
  const WithStytchSession = (props) => {
101
119
  invariant(useIsMounted__INTERNAL(), noProviderError('withStytchSession'));
102
- return React__default["default"].createElement(Component, { ...props, stytchSession: useStytchSession() });
120
+ const { session, fromCache } = useStytchSession();
121
+ return React__default["default"].createElement(Component, Object.assign({}, props, { stytchSession: session, stytchSessionIsFromCache: fromCache }));
103
122
  };
104
123
  WithStytchSession.displayName = `withStytchSession(${Component.displayName || Component.name || 'Component'})`;
105
124
  return WithStytchSession;
106
125
  };
126
+ /**
127
+ * The Stytch Context Provider.
128
+ * Wrap your application with this component in the root file in order to use Stytch everywhere in your app.
129
+ * @example
130
+ * const stytch = new StytchHeadlessClient('public-token-<find yours in the stytch dashboard>')
131
+ *
132
+ * ReactDOM.render(
133
+ * <StytchProvider stytch={stytch}>
134
+ * <App />
135
+ * </StytchProvider>,
136
+ * document.getElementById('root'),
137
+ * )
138
+ */
107
139
  const StytchProvider = ({ stytch, children }) => {
108
140
  invariant(!useIsMounted__INTERNAL(), providerMustBeUniqueError);
109
141
  invariant(typeof window !== 'undefined', noSSRError);
110
142
  const ctx = React.useMemo(() => ({ client: stytch, isMounted: true }), [stytch]);
111
- const [user, setUser] = useAsyncState(stytch.user.getSync());
112
- const [session, setSession] = useAsyncState(stytch.session.getSync());
143
+ const [user, setUser] = useAsyncState({
144
+ user: stytch.user.getSync(),
145
+ fromCache: true,
146
+ });
147
+ const [session, setSession] = useAsyncState({
148
+ session: stytch.session.getSync(),
149
+ fromCache: true,
150
+ });
113
151
  React.useEffect(() => {
114
- const unsubscribeUser = stytch.user.onChange((user) => setUser(user));
115
- const unsubscribeSession = stytch.session.onChange((session) => setSession(session));
152
+ const unsubscribeUser = stytch.user.onChange((user) => setUser({
153
+ user,
154
+ fromCache: false,
155
+ }));
156
+ const unsubscribeSession = stytch.session.onChange((session) => setSession({
157
+ session,
158
+ fromCache: false,
159
+ }));
116
160
  return () => {
117
161
  unsubscribeUser();
118
162
  unsubscribeSession();
119
163
  };
120
164
  }, [stytch, setUser, setSession]);
165
+ const finalSess = !!session.session === !!user.user ? session : initialSession;
166
+ const finalUser = !!session.session === !!user.user ? user : initialUser;
121
167
  return (React__default["default"].createElement(StytchContext.Provider, { value: ctx },
122
- React__default["default"].createElement(StytchUserContext.Provider, { value: session && user },
123
- React__default["default"].createElement(StytchSessionContext.Provider, { value: user && session }, children))));
168
+ React__default["default"].createElement(StytchUserContext.Provider, { value: finalUser },
169
+ React__default["default"].createElement(StytchSessionContext.Provider, { value: finalSess }, children))));
124
170
  };
125
171
 
126
172
  /**
127
- * Returns a unique element ID.
128
- * Intended to only be used client-side - this will cause HTML mismatch issues in SSR!
129
- * cf: https://github.com/vercel/next.js/issues/7322#issuecomment-968858477
130
- */
131
- const useUniqueElementId = () => {
132
- return React__namespace.useMemo(() => {
133
- const randId = Math.floor(Math.random() * 1e6);
134
- return `stytch-magic-link-${randId}`;
135
- }, []);
136
- };
137
- /**
138
- * Stytch JS React Component
173
+ * The Stytch Login Screen component.
174
+ * This component can only be used with a {@link StytchUIClient} client constructor
175
+ * passed into the {@link StytchProvider}
176
+ *
177
+ * See the {@link https://stytch.com/docs/sdks/javascript-sdk online reference}
178
+ * and {@link https://storybook.stytch.com interactive examples} for more.
139
179
  *
140
- * [Documentation](https://stytch.com/docs/javascript-sdk)
180
+ * @example
181
+ * <StytchLogin
182
+ * config={{
183
+ * products: ['emailMagicLinks', 'oauth'],
184
+ * emailMagicLinksOptions: {
185
+ * loginRedirectURL: 'https://example.com/authenticate',
186
+ * signupRedirectURL: 'https://example.com/authenticate',
187
+ * },
188
+ * oauthOptions: {
189
+ * providers: [{ type: OAuthProviders.Google }, { type: OAuthProviders.Microsoft }],
190
+ * },
191
+ * }}
192
+ * styles={{
193
+ * fontFamily: '"Helvetica New", Helvetica, sans-serif',
194
+ * primaryColor: '#0577CA',
195
+ * width: '321px',
196
+ * }}
197
+ * callbacks={{
198
+ * onEvent: (event) => console.log(event)
199
+ * }}
200
+ * />
201
+ * @param props {@link StytchProps}
141
202
  */
142
- const Stytch = ({ config, styles, callbacks, }) => {
143
- invariant(useIsMounted__INTERNAL(), noProviderError('<Stytch />'));
203
+ const StytchLogin = ({ config, styles, callbacks }) => {
204
+ invariant(useIsMounted__INTERNAL(), noProviderError('<StytchLogin />'));
144
205
  const stytchClient = useStytch();
145
- const elementId = useUniqueElementId();
146
- React__namespace.useEffect(() => {
147
- if (!elementId) {
148
- return;
149
- }
206
+ const containerEl = React.useRef(null);
207
+ React.useLayoutEffect(() => {
150
208
  if (!isUIClient(stytchClient)) {
151
209
  throw Error(noHeadlessClientError);
152
210
  }
153
- stytchClient.mount({
211
+ if (!containerEl.current) {
212
+ return;
213
+ }
214
+ if (!containerEl.current.id) {
215
+ const randId = Math.floor(Math.random() * 1e6);
216
+ containerEl.current.id = `stytch-magic-link-${randId}`;
217
+ }
218
+ stytchClient.mountLogin({
154
219
  config,
155
220
  callbacks,
156
- elementId: `#${elementId}`,
221
+ elementId: `#${containerEl.current.id}`,
157
222
  styles,
158
223
  });
159
- }, [elementId, stytchClient]);
160
- return elementId ? React__namespace.createElement("div", { id: elementId }) : null;
224
+ }, [stytchClient, config, styles, callbacks]);
225
+ return React__default["default"].createElement("div", { ref: containerEl });
226
+ };
227
+ /**
228
+ * The Stytch Reset Password component.
229
+ * This component can only be used with a {@link StytchUIClient} client constructor
230
+ * passed into the {@link StytchProvider}
231
+ *
232
+ * See the {@link https://stytch.com/docs/sdks/javascript-sdk online reference}
233
+ * and {@link https://storybook.stytch.com interactive examples} for more.
234
+ *
235
+ * @example
236
+ * TODO
237
+ */
238
+ const StytchPasswordReset = ({ config, styles, callbacks, passwordResetToken }) => {
239
+ invariant(useIsMounted__INTERNAL(), noProviderError('<StytchResetPassword />'));
240
+ const stytchClient = useStytch();
241
+ const containerEl = React.useRef(null);
242
+ React.useLayoutEffect(() => {
243
+ if (!isUIClient(stytchClient)) {
244
+ throw Error(noHeadlessClientError);
245
+ }
246
+ if (!containerEl.current) {
247
+ return;
248
+ }
249
+ if (!containerEl.current.id) {
250
+ const randId = Math.floor(Math.random() * 1e6);
251
+ containerEl.current.id = `stytch-reset-password-${randId}`;
252
+ }
253
+ if (passwordResetToken) {
254
+ stytchClient.mountResetPassword({
255
+ config,
256
+ callbacks,
257
+ elementId: `#${containerEl.current.id}`,
258
+ styles,
259
+ passwordResetToken,
260
+ });
261
+ }
262
+ }, [stytchClient, config, styles, callbacks, passwordResetToken]);
263
+ return React__default["default"].createElement("div", { ref: containerEl });
161
264
  };
162
265
 
163
- exports.Stytch = Stytch;
266
+ exports.StytchLogin = StytchLogin;
267
+ exports.StytchPasswordReset = StytchPasswordReset;
164
268
  exports.StytchProvider = StytchProvider;
165
269
  exports.useStytch = useStytch;
166
270
  exports.useStytchSession = useStytchSession;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stytch/react",
3
- "version": "0.0.3-0",
3
+ "version": "0.3.0",
4
4
  "description": "Stytch's official React Library",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.esm.js",
@@ -12,22 +12,33 @@
12
12
  "build": "npm run clean && npm run compile",
13
13
  "clean": "rm -rf ./dist",
14
14
  "compile": "rollup -c",
15
- "dev": "tsc -p tsconfig.build.json --watch",
15
+ "dev": "rollup -c -w",
16
16
  "test": "jest"
17
17
  },
18
18
  "license": "MIT",
19
+ "homepage": "https://stytch.com/docs/sdks/javascript-sdk",
19
20
  "author": "Stytch",
21
+ "keywords": [
22
+ "stytch",
23
+ "react",
24
+ "nextjs",
25
+ "typescript",
26
+ "auth",
27
+ "authentication",
28
+ "session",
29
+ "jwt",
30
+ "user"
31
+ ],
20
32
  "devDependencies": {
21
33
  "@babel/runtime": "^7.18.6",
22
- "@stytch/vanilla-js": "0.0.2-0",
34
+ "@stytch/vanilla-js": "0.3.0",
23
35
  "eslint-config-custom": "0.0.0",
24
36
  "rollup": "^2.56.3",
25
- "typescript": "^4.5.3"
37
+ "typescript": "4.7.4"
26
38
  },
27
39
  "peerDependencies": {
28
- "@stytch/vanilla-js": "^0.0.2-0",
40
+ "@stytch/vanilla-js": "^0.3.0",
29
41
  "react": ">= 17.0.2",
30
42
  "react-dom": ">= 17.0.2"
31
- },
32
- "stableVersion": "0.0.2"
33
- }
43
+ }
44
+ }