Add SSE for metadata and plug front components (#17998)
Create the necessary tooling to listen to metadata events and plug it to the front components. Now we have a hot reload like experience when we edit a component in an app. ## Backend - Split `EventWithQueryIds` into `ObjectRecordEventWithQueryIds` and `MetadataEventWithQueryIds` - Publish metadata event batches to active SSE streams in `MetadataEventsToDbListener` ## Frontend - Create a metadata event dispatching pipeline: SSE metadata events are grouped by metadata name, transformed into `MetadataOperationBrowserEventDetail` objects, and dispatched as browser `CustomEvents` - Add `useListenToMetadataOperationBrowserEvent` hook for consuming metadata operation events filtered by metadata name and operation type - Rename `useListenToObjectRecordEventsForQuery` to `useListenToEventsForQuery`, now accepting both `RecordGqlOperationSignature` and `MetadataGqlOperationSignature` - Implement `useOnFrontComponentUpdated` which subscribes to front component metadata events and updates the Apollo cache when the component is modified - Add `builtComponentChecksum` to the front component query and appends it to the component URL for browser cache invalidation
This commit is contained in:
+2
@@ -10,6 +10,7 @@ import { FrontComponentResolver } from 'src/engine/metadata-modules/front-compon
|
||||
import { FrontComponentService } from 'src/engine/metadata-modules/front-component/front-component.service';
|
||||
import { FrontComponentGraphqlApiExceptionInterceptor } from 'src/engine/metadata-modules/front-component/interceptors/front-component-graphql-api-exception.interceptor';
|
||||
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
|
||||
import { SubscriptionsModule } from 'src/engine/subscriptions/subscriptions.module';
|
||||
import { WorkspaceMigrationGraphqlApiExceptionInterceptor } from 'src/engine/workspace-manager/workspace-migration/interceptors/workspace-migration-graphql-api-exception.interceptor';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
|
||||
@@ -21,6 +22,7 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace
|
||||
TokenModule,
|
||||
PermissionsModule,
|
||||
FlatFrontComponentModule,
|
||||
SubscriptionsModule,
|
||||
],
|
||||
controllers: [FrontComponentController],
|
||||
providers: [
|
||||
|
||||
+16
-8
@@ -129,10 +129,14 @@ export class FrontComponentService {
|
||||
},
|
||||
);
|
||||
|
||||
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityId: flatFrontComponentToCreate.id,
|
||||
flatEntityMaps: recomputedFlatFrontComponentMaps,
|
||||
});
|
||||
const createdFlatFrontComponent = findFlatEntityByIdInFlatEntityMapsOrThrow(
|
||||
{
|
||||
flatEntityId: flatFrontComponentToCreate.id,
|
||||
flatEntityMaps: recomputedFlatFrontComponentMaps,
|
||||
},
|
||||
);
|
||||
|
||||
return createdFlatFrontComponent;
|
||||
}
|
||||
|
||||
async updateOne({
|
||||
@@ -200,10 +204,14 @@ export class FrontComponentService {
|
||||
},
|
||||
);
|
||||
|
||||
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||
flatEntityId: id,
|
||||
flatEntityMaps: recomputedFlatFrontComponentMaps,
|
||||
});
|
||||
const updatedFlatFrontComponent = findFlatEntityByIdInFlatEntityMapsOrThrow(
|
||||
{
|
||||
flatEntityId: id,
|
||||
flatEntityMaps: recomputedFlatFrontComponentMaps,
|
||||
},
|
||||
);
|
||||
|
||||
return updatedFlatFrontComponent;
|
||||
}
|
||||
|
||||
async destroyOne({
|
||||
|
||||
Reference in New Issue
Block a user