@@ -22,19 +22,21 @@ export interface Session {
2222 salt : Uint8Array ;
2323}
2424
25+ type SessionData = Pick < Session , "identity" | "nonce" | "salt" > ;
26+
2527type SessionStore = Readable < Session > & {
2628 init : ( params : {
2729 canisterId : Principal ;
2830 agentOptions : HttpAgentOptions ;
2931 } ) => Promise < void > ;
30- reset : ( ) => Promise < void > ;
32+ reset : ( ) => void ;
3133} ;
3234
3335const STORAGE_KEY = "ii-session" ;
3436
3537const internalStore = writable < Session | undefined > ( ) ;
3638
37- const create = async ( ) => {
39+ const createSession = async ( ) : Promise < SessionData > => {
3840 const identity = await ECDSAKeyIdentity . generate ( {
3941 extractable : true ,
4042 } ) ;
@@ -59,7 +61,7 @@ const create = async () => {
5961 } ;
6062} ;
6163
62- const read = async ( ) => {
64+ const readSession = async ( ) : Promise < SessionData | undefined > => {
6365 const item = sessionStorage . getItem ( STORAGE_KEY ) ;
6466 if ( isNullish ( item ) ) {
6567 return undefined ;
@@ -91,9 +93,24 @@ const read = async () => {
9193 } ;
9294} ;
9395
96+ let preCreatedSession : SessionData ;
97+ const nextSession = ( ) : SessionData => {
98+ const session = preCreatedSession ! ;
99+ void ( async ( ) => {
100+ // Pre-create the next session in the background to make reset synchronous
101+ preCreatedSession = await createSession ( ) ;
102+ } ) ( ) ;
103+ return session ;
104+ } ;
105+
94106export const sessionStore : SessionStore = {
95107 init : async ( { canisterId, agentOptions } ) => {
96- const { identity, nonce, salt } = ( await read ( ) ) ?? ( await create ( ) ) ;
108+ // Try to read an existing session from sessionStorage,
109+ // if it doesn't exist or is expired create a new one.
110+ const { identity, nonce, salt } =
111+ ( await readSession ( ) ) ?? ( await createSession ( ) ) ;
112+ // Pre-create the next session for synchronous reset later on.
113+ void nextSession ( ) ;
97114 const agent = HttpAgent . createSync ( { ...agentOptions , identity } ) ;
98115 // Fetch subnet keys to speed up queries during authentication,
99116 // this avoids having to fetch them later on user interaction.
@@ -110,8 +127,8 @@ export const sessionStore: SessionStore = {
110127 }
111128 return session ;
112129 } ) . subscribe ,
113- reset : async ( ) => {
114- const { identity, nonce, salt } = await create ( ) ;
130+ reset : ( ) => {
131+ const { identity, nonce, salt } = nextSession ( ) ;
115132 internalStore . update ( ( session ) => {
116133 if ( isNullish ( session ) ) {
117134 throw new Error ( "Not initialized" ) ;
0 commit comments