frontend-app-api: move session reuse to prepare time
Remove the late-bound finalize session override so prepared apps accept reusable session state in one place. This keeps bootstrap and finalization semantics aligned and simplifies the prepared app API. Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> Made-with: Cursor
This commit is contained in:
@@ -941,32 +941,6 @@ describe('createSpecializedApp', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should reject finalize after selecting onFinalized', () => {
|
||||
const preparedApp = prepareSpecializedApp({
|
||||
features: [makeAppPlugin()],
|
||||
});
|
||||
|
||||
const unsubscribe = preparedApp.onFinalized(() => {});
|
||||
|
||||
expect(() => preparedApp.finalize()).toThrow(
|
||||
'prepareSpecializedApp only supports using either onFinalized() or finalize(), not both',
|
||||
);
|
||||
|
||||
unsubscribe();
|
||||
});
|
||||
|
||||
it('should reject onFinalized after selecting finalize', () => {
|
||||
const preparedApp = prepareSpecializedApp({
|
||||
features: [makeAppPlugin()],
|
||||
});
|
||||
|
||||
preparedApp.finalize();
|
||||
|
||||
expect(() => preparedApp.onFinalized(() => {})).toThrow(
|
||||
'prepareSpecializedApp only supports using either onFinalized() or finalize(), not both',
|
||||
);
|
||||
});
|
||||
|
||||
it('should synchronously finalize feature flag predicates without sign-in', async () => {
|
||||
const featureFlagsApi = {
|
||||
isActive: jest.fn((name: string) => name === 'test-flag'),
|
||||
|
||||
@@ -246,9 +246,7 @@ export type PrepareSpecializedAppOptions = {
|
||||
export type PreparedSpecializedApp = {
|
||||
getBootstrapApp(): BootstrapSpecializedApp;
|
||||
onFinalized(callback: (app: FinalizedSpecializedApp) => void): () => void;
|
||||
finalize(options?: {
|
||||
sessionState?: SpecializedAppSessionState;
|
||||
}): FinalizedSpecializedApp;
|
||||
finalize(): FinalizedSpecializedApp;
|
||||
};
|
||||
|
||||
// Internal options type, not exported in the public API
|
||||
@@ -591,25 +589,25 @@ export function prepareSpecializedApp(
|
||||
subscribed = false;
|
||||
};
|
||||
},
|
||||
finalize(finalizeOptions?: { sessionState?: SpecializedAppSessionState }) {
|
||||
finalize() {
|
||||
finalization.selectMode('finalize');
|
||||
if (finalized) {
|
||||
return finalized;
|
||||
}
|
||||
if (!finalizeOptions?.sessionState) {
|
||||
if (!providedSessionState) {
|
||||
// finalize() still depends on bootstrap classification and sign-in
|
||||
// discovery, so we make sure the bootstrap tree has been prepared first.
|
||||
// discovery unless a reusable session was supplied up front, so we make
|
||||
// sure the bootstrap tree has been prepared first.
|
||||
getBootstrapApp();
|
||||
}
|
||||
|
||||
// Direct finalization never waits for async session preparation. Callers
|
||||
// must either supply sessionState or invoke finalize() only when the
|
||||
// predicate context is already available synchronously.
|
||||
const finalizedSessionState =
|
||||
finalizeOptions?.sessionState ??
|
||||
(signInRuntime?.requiresSignIn
|
||||
? undefined
|
||||
: getSynchronousSessionState());
|
||||
// must either provide sessionState during prepareSpecializedApp() or
|
||||
// invoke finalize() only when the predicate context is already available
|
||||
// synchronously.
|
||||
const finalizedSessionState = signInRuntime?.requiresSignIn
|
||||
? undefined
|
||||
: getSynchronousSessionState();
|
||||
if (!finalizedSessionState) {
|
||||
if (signInRuntime?.requiresSignIn) {
|
||||
throw new Error(
|
||||
|
||||
Reference in New Issue
Block a user