frontend-app-api: separate prepared app finalization modes
Make prepared apps choose either onFinalized or finalize so the async and direct finalization flows can no longer be mixed on the same instance. Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> Made-with: Cursor
This commit is contained in:
@@ -941,6 +941,32 @@ 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'),
|
||||
|
||||
@@ -151,6 +151,8 @@ type FinalizationState = {
|
||||
reject(error: unknown): void;
|
||||
};
|
||||
|
||||
type FinalizationMode = 'onFinalized' | 'finalize';
|
||||
|
||||
type InternalSpecializedAppSessionState = {
|
||||
apis: ApiHolder;
|
||||
identityApi?: IdentityApi;
|
||||
@@ -374,6 +376,7 @@ export function prepareSpecializedApp(
|
||||
let bootstrapApp: BootstrapSpecializedApp | undefined;
|
||||
let bootstrapError: Error | undefined;
|
||||
let finalizationState: FinalizationState | undefined;
|
||||
let finalizationMode: FinalizationMode | undefined;
|
||||
|
||||
function updateIdentityApiTarget(identityApi?: IdentityApi) {
|
||||
if (!identityApi) {
|
||||
@@ -541,6 +544,16 @@ export function prepareSpecializedApp(
|
||||
return finalization.promise;
|
||||
}
|
||||
|
||||
function selectFinalizationMode(mode: FinalizationMode) {
|
||||
if (finalizationMode && finalizationMode !== mode) {
|
||||
throw new Error(
|
||||
`prepareSpecializedApp only supports using either onFinalized() or finalize(), not both`,
|
||||
);
|
||||
}
|
||||
|
||||
finalizationMode = mode;
|
||||
}
|
||||
|
||||
function getBootstrapApp() {
|
||||
if (bootstrapApp) {
|
||||
return bootstrapApp;
|
||||
@@ -596,6 +609,7 @@ export function prepareSpecializedApp(
|
||||
return {
|
||||
getBootstrapApp,
|
||||
onFinalized(callback) {
|
||||
selectFinalizationMode('onFinalized');
|
||||
getBootstrapApp();
|
||||
|
||||
let subscribed = true;
|
||||
@@ -628,6 +642,7 @@ export function prepareSpecializedApp(
|
||||
};
|
||||
},
|
||||
finalize(finalizeOptions?: { sessionState?: SpecializedAppSessionState }) {
|
||||
selectFinalizationMode('finalize');
|
||||
if (finalized) {
|
||||
return finalized;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user