Skip to content

Commit 9a4cacf

Browse files
committed
refactor(client): centralize connection credentials
1 parent 24ba9f4 commit 9a4cacf

2 files changed

Lines changed: 44 additions & 58 deletions

File tree

‎packages/devframe/src/client/connection.ts‎

Lines changed: 25 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -120,60 +120,44 @@ export function getDevframeConnection(): DevframeConnection | undefined {
120120
export async function setupDevframeConnection(
121121
options: SetupDevframeConnectionOptions = {},
122122
): Promise<DevframeConnection> {
123-
const isolateConnection = options.isolateConnection === true
124-
function resolveAuthToken(authToken: string | undefined): string | undefined {
125-
if (isolateConnection)
126-
return authToken
127-
return readStoredAuthToken(authToken)
128-
}
129-
function finishConnectionSetup(connection: DevframeConnection): DevframeConnection {
130-
if (!isolateConnection)
131-
storeConnection(connection)
132-
return connection
133-
}
134-
if (options.connection) {
135-
const connection = withAuthToken(
136-
options.connection,
137-
resolveAuthToken(
138-
options.authToken
139-
?? options.connection.authToken
140-
?? options.connection.connectionMeta.authToken,
141-
),
142-
)
143-
return finishConnectionSetup(connection)
144-
}
123+
const connection = await resolveDevframeConnection(options)
124+
const authToken = options.authToken ?? connection.authToken ?? connection.connectionMeta.authToken
125+
const resolvedConnection = withAuthToken(
126+
connection,
127+
options.isolateConnection ? authToken : readStoredAuthToken(authToken),
128+
)
129+
if (options.isolateConnection)
130+
return resolvedConnection
131+
132+
storeConnection(resolvedConnection)
133+
return resolvedConnection
134+
}
135+
136+
async function resolveDevframeConnection(
137+
options: SetupDevframeConnectionOptions,
138+
): Promise<DevframeConnection> {
139+
if (options.connection)
140+
return options.connection
145141

146142
const bases = Array.isArray(options.baseURL)
147143
? options.baseURL
148144
: [options.baseURL ?? './']
149145

150146
if (options.connectionMeta) {
151-
const connection: DevframeConnection = {
147+
return {
152148
connectionMeta: options.connectionMeta,
153149
/**
154150
* Preserve the established connectionMeta behavior: an explicitly
155151
* supplied descriptor resolves from the caller's explicit base.
156152
*/
157153
metaBaseUrl: resolveMetaBaseUrl(bases[0] ?? './'),
158-
authToken: resolveAuthToken(
159-
options.authToken ?? options.connectionMeta.authToken,
160-
),
154+
authToken: options.connectionMeta.authToken,
161155
}
162-
return finishConnectionSetup(connection)
163156
}
164157

165-
const existing = isolateConnection ? undefined : getDevframeConnection()
166-
if (existing) {
167-
const connection = withAuthToken(
168-
existing,
169-
resolveAuthToken(
170-
options.authToken
171-
?? existing.authToken
172-
?? existing.connectionMeta.authToken,
173-
),
174-
)
175-
return finishConnectionSetup(connection)
176-
}
158+
const existing = options.isolateConnection ? undefined : getDevframeConnection()
159+
if (existing)
160+
return existing
177161

178162
const errors: Error[] = []
179163
for (const base of bases) {
@@ -186,7 +170,7 @@ export async function setupDevframeConnection(
186170

187171
const connectionMeta = await response.json() as ConnectionMeta
188172
const loadedFrom = response.url || metaUrl
189-
const connection: DevframeConnection = {
173+
return {
190174
connectionMeta,
191175
/**
192176
* A served `baseUrl` re-points relative resolution (RPC dump shards,
@@ -196,11 +180,8 @@ export async function setupDevframeConnection(
196180
metaBaseUrl: connectionMeta.baseUrl
197181
? new URL(connectionMeta.baseUrl, loadedFrom).href
198182
: loadedFrom,
199-
authToken: resolveAuthToken(
200-
options.authToken ?? connectionMeta.authToken,
201-
),
183+
authToken: connectionMeta.authToken,
202184
}
203-
return finishConnectionSetup(connection)
204185
}
205186
catch (error) {
206187
errors.push(error as Error)

‎packages/devframe/src/client/rpc.ts‎

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -327,10 +327,20 @@ export function resolveClientTransport(
327327
throw new Error('[devframe] This server advertises no RPC transport (backend "none"), so there is nothing to connect to. Enable the WebSocket or SSE endpoint on the server, or use its static/MCP surfaces instead.')
328328
}
329329

330+
function createAuthChannel(isolateConnection = false): BroadcastChannel | undefined {
331+
if (isolateConnection)
332+
return undefined
333+
334+
try {
335+
/** Channel name kept for cross-tab interop with the Vite DevTools auth page. */
336+
return new BroadcastChannel('devframe-auth')
337+
}
338+
catch {}
339+
}
340+
330341
export async function getDevframeRpcClient(
331342
options: DevframeRpcClientOptions = {},
332343
): Promise<DevframeRpcClient> {
333-
const isolateConnection = options.isolateConnection === true
334344
// Default to a relative base: the SPA owns its mount path at runtime, so
335345
// connection meta and dump shards live alongside `index.html`. An embedded
336346
// surface inside a host page must pass an explicit `baseURL` - its
@@ -426,13 +436,13 @@ export async function getDevframeRpcClient(
426436
wsOptions: options.wsOptions,
427437
})
428438

429-
// Channel name kept for cross-tab interop with the Vite DevTools auth page.
430-
let authChannel: BroadcastChannel | undefined
431-
try {
432-
if (!isolateConnection)
433-
authChannel = new BroadcastChannel('devframe-auth')
439+
const authChannel = createAuthChannel(options.isolateConnection)
440+
441+
function updateAuthToken(token: string): void {
442+
connection = { ...connection, authToken: token }
443+
if (!options.isolateConnection)
444+
storeAuthToken(token)
434445
}
435-
catch {}
436446

437447
// Gate outbound calls behind the auth bootstrap below. Without it, a
438448
// caller's first RPC calls, fired the moment `connectDevframe()` resolves,
@@ -487,19 +497,14 @@ export async function getDevframeRpcClient(
487497
ensureTrusted: mode.ensureTrusted,
488498
requestTrust: mode.requestTrust,
489499
requestTrustWithToken: async (token: string) => {
490-
if (!isolateConnection)
491-
storeAuthToken(token)
492-
connection = { ...connection, authToken: token }
500+
updateAuthToken(token)
493501
return mode.requestTrustWithToken(token)
494502
},
495503
requestTrustWithCode: async (code: string) => {
496504
const token = await mode.requestTrustWithCode(code)
497505
if (!token)
498506
return false
499-
/** Shared mode also persists the issued token for sibling tabs. */
500-
if (!isolateConnection)
501-
storeAuthToken(token)
502-
connection = { ...connection, authToken: token }
507+
updateAuthToken(token)
503508
try {
504509
authChannel?.postMessage({ type: 'auth-update', authToken: token })
505510
}

0 commit comments

Comments
 (0)