From f6bb09989833698cb2cf6c5d8d27f25fdeebc84e Mon Sep 17 00:00:00 2001 From: Rhys Howell Date: Wed, 12 Feb 2025 13:02:45 -0500 Subject: [PATCH] chore(schema): move non-serializable services to services --- .../schema-toolbar/schema-toolbar.spec.tsx | 56 ++++++++----------- .../src/modules/schema-analysis.spec.ts | 4 +- .../src/modules/schema-analysis.ts | 7 +-- .../src/stores/schema-analysis-reducer.ts | 23 +++----- .../src/stores/schema-export-reducer.ts | 43 ++++++-------- packages/compass-schema/src/stores/store.ts | 17 +++++- 6 files changed, 67 insertions(+), 83 deletions(-) diff --git a/packages/compass-schema/src/components/schema-toolbar/schema-toolbar.spec.tsx b/packages/compass-schema/src/components/schema-toolbar/schema-toolbar.spec.tsx index 1e86ef32a5c..71c811aaff5 100644 --- a/packages/compass-schema/src/components/schema-toolbar/schema-toolbar.spec.tsx +++ b/packages/compass-schema/src/components/schema-toolbar/schema-toolbar.spec.tsx @@ -3,11 +3,7 @@ import React from 'react'; import { render, screen } from '@mongodb-js/testing-library-compass'; import { expect } from 'chai'; import sinon from 'sinon'; -import { - createSandboxFromDefaultPreferences, - type PreferencesAccess, -} from 'compass-preferences-model'; -import { PreferencesProvider } from 'compass-preferences-model/provider'; +import type { AllPreferences } from 'compass-preferences-model'; import { SchemaToolbar } from './schema-toolbar'; import QueryBarPlugin from '@mongodb-js/compass-query-bar'; import { @@ -35,33 +31,28 @@ const testErrorMessage = const exportSchemaTestId = 'open-schema-export-button'; describe('SchemaToolbar', function () { - let defaultPreferences: PreferencesAccess; - - before(async function () { - defaultPreferences = await createSandboxFromDefaultPreferences(); - }); - const renderSchemaToolbar = ( props: Partial> = {}, - preferences: PreferencesAccess = defaultPreferences + preferences: Partial = {} ) => { const queryBarProps = {}; render( - - - {}} - onResetClicked={() => {}} - sampleSize={10} - schemaResultId="123" - onExportSchemaClicked={() => {}} - {...props} - /> - - + + {}} + onResetClicked={() => {}} + sampleSize={10} + schemaResultId="123" + onExportSchemaClicked={() => {}} + {...props} + /> + , + { + preferences, + } ); }; @@ -125,17 +116,14 @@ describe('SchemaToolbar', function () { }); describe('when rendered with the enableExportSchema feature flag true', function () { - beforeEach(async function () { - const preferences = await createSandboxFromDefaultPreferences(); - await preferences.savePreferences({ - enableExportSchema: true, - }); - + beforeEach(function () { renderSchemaToolbar( { sampleSize: 100, }, - preferences + { + enableExportSchema: true, + } ); }); diff --git a/packages/compass-schema/src/modules/schema-analysis.spec.ts b/packages/compass-schema/src/modules/schema-analysis.spec.ts index b91ce702e1c..04b7b90d88e 100644 --- a/packages/compass-schema/src/modules/schema-analysis.spec.ts +++ b/packages/compass-schema/src/modules/schema-analysis.spec.ts @@ -196,7 +196,7 @@ describe('schema-analysis', function () { ); }); - it('returns null if is cancelled', async function () { + it('returns undefined if is cancelled', async function () { const dataService = { sample: () => Promise.reject(new Error('test error')), isCancelError: () => true, @@ -214,7 +214,7 @@ describe('schema-analysis', function () { dummyLogger ); - expect(result).to.equal(null); + expect(result).to.equal(undefined); }); it('throws if sample throws', async function () { diff --git a/packages/compass-schema/src/modules/schema-analysis.ts b/packages/compass-schema/src/modules/schema-analysis.ts index 0774f9a54b8..aaa5193979a 100644 --- a/packages/compass-schema/src/modules/schema-analysis.ts +++ b/packages/compass-schema/src/modules/schema-analysis.ts @@ -2,6 +2,7 @@ import type { AggregateOptions, Filter, Document } from 'mongodb'; import { analyzeDocuments } from 'mongodb-schema'; import type { Schema, + SchemaAccessor, ArraySchemaType, DocumentSchemaType, SchemaField, @@ -35,8 +36,6 @@ function promoteMongoErrorCode(err?: Error & { code?: unknown }) { return err; } -export type SchemaAccessor = Awaited>; - export const analyzeSchema = async ( dataService: DataService, abortSignal: AbortSignal, @@ -50,7 +49,7 @@ export const analyzeSchema = async ( | undefined, aggregateOptions: AggregateOptions, { log, mongoLogId, debug }: Logger -): Promise => { +): Promise => { try { log.info(mongoLogId(1001000089), 'Schema', 'Starting schema analysis', { ns, @@ -82,7 +81,7 @@ export const analyzeSchema = async ( }); if (dataService.isCancelError(err)) { debug('caught background operation terminated error', err); - return null; + return; } const error = promoteMongoErrorCode(err); diff --git a/packages/compass-schema/src/stores/schema-analysis-reducer.ts b/packages/compass-schema/src/stores/schema-analysis-reducer.ts index 21e7b74d469..37464b14ba3 100644 --- a/packages/compass-schema/src/stores/schema-analysis-reducer.ts +++ b/packages/compass-schema/src/stores/schema-analysis-reducer.ts @@ -14,7 +14,6 @@ import { addLayer, generateGeoQuery } from '../modules/geo'; import { analyzeSchema, calculateSchemaDepth, - type SchemaAccessor, schemaContainsGeoData, } from '../modules/schema-analysis'; import { capMaxTimeMSAtPreferenceLimit } from 'compass-preferences-model/provider'; @@ -33,7 +32,6 @@ export type SchemaAnalysisState = { analysisState: AnalysisState; errorMessage: string; schema: Schema | null; - schemaAccessor: SchemaAccessor | null; resultId: string; }; @@ -49,7 +47,6 @@ export type AnalysisStartedAction = { export type AnalysisFinishedAction = { type: SchemaAnalysisActions.analysisFinished; - schemaAccessor: SchemaAccessor | null; schema: Schema | null; }; @@ -73,7 +70,6 @@ export const schemaAnalysisReducer: Reducer = ( analysisState: ANALYSIS_STATE_ANALYZING, errorMessage: '', schema: null, - schemaAccessor: null, }; } @@ -89,7 +85,6 @@ export const schemaAnalysisReducer: Reducer = ( ? ANALYSIS_STATE_COMPLETE : ANALYSIS_STATE_INITIAL, schema: action.schema, - schemaAccessor: action.schemaAccessor, resultId: resultId(), }; } @@ -180,7 +175,6 @@ const getInitialState = (): SchemaAnalysisState => ({ analysisState: ANALYSIS_STATE_INITIAL, errorMessage: '', schema: null, - schemaAccessor: null, resultId: resultId(), }); @@ -222,9 +216,9 @@ export const geoLayersDeleted = ( }; export const stopAnalysis = (): SchemaThunkAction => { - return (dispatch, getState, { abortControllerRef }) => { - if (!abortControllerRef.current) return; - abortControllerRef.current?.abort(); + return (dispatch, getState, { analysisAbortControllerRef }) => { + if (!analysisAbortControllerRef.current) return; + analysisAbortControllerRef.current?.abort(); }; }; @@ -242,7 +236,8 @@ export const startAnalysis = (): SchemaThunkAction< dataService, logger, fieldStoreService, - abortControllerRef, + analysisAbortControllerRef, + schemaAccessorRef, namespace, geoLayersRef, connectionInfoRef, @@ -272,8 +267,8 @@ export const startAnalysis = (): SchemaThunkAction< maxTimeMS: capMaxTimeMSAtPreferenceLimit(preferences, query.maxTimeMS), }; - abortControllerRef.current = new AbortController(); - const abortSignal = abortControllerRef.current.signal; + analysisAbortControllerRef.current = new AbortController(); + const abortSignal = analysisAbortControllerRef.current.signal; try { debug('analysis started'); @@ -289,6 +284,7 @@ export const startAnalysis = (): SchemaThunkAction< driverOptions, logger ); + schemaAccessorRef.current = schemaAccessor; let schema: Schema | null = null; if (schemaAccessor) { schema = await schemaAccessor.getInternalSchema(); @@ -305,7 +301,6 @@ export const startAnalysis = (): SchemaThunkAction< dispatch({ type: SchemaAnalysisActions.analysisFinished, schema, - schemaAccessor, }); // track schema analyzed @@ -333,7 +328,7 @@ export const startAnalysis = (): SchemaThunkAction< error: err as Error, }); } finally { - abortControllerRef.current = undefined; + analysisAbortControllerRef.current = undefined; } }; }; diff --git a/packages/compass-schema/src/stores/schema-export-reducer.ts b/packages/compass-schema/src/stores/schema-export-reducer.ts index 7c8b4147d2c..ec86b19eac7 100644 --- a/packages/compass-schema/src/stores/schema-export-reducer.ts +++ b/packages/compass-schema/src/stores/schema-export-reducer.ts @@ -5,11 +5,11 @@ import type { InternalSchema, MongoDBJSONSchema, ExpandedJSONSchema, + SchemaAccessor, } from 'mongodb-schema'; import type { SchemaThunkAction } from './store'; import { isAction } from '../utils'; -import type { SchemaAccessor } from '../modules/schema-analysis'; export type SchemaFormat = | 'standardJSON' @@ -18,7 +18,6 @@ export type SchemaFormat = | 'legacyJSON'; export type ExportStatus = 'inprogress' | 'complete' | 'error'; export type SchemaExportState = { - abortController?: AbortController; isOpen: boolean; exportedSchema?: string; exportFormat: SchemaFormat; @@ -69,11 +68,8 @@ export const closeExportSchema = (): SchemaThunkAction< void, CloseExportSchemaAction > => { - return (dispatch, getState) => { - const { - schemaExport: { abortController }, - } = getState(); - abortController?.abort(); + return (dispatch, getState, { exportAbortControllerRef }) => { + exportAbortControllerRef.current?.abort(); return dispatch({ type: SchemaExportActions.closeExportSchema, @@ -87,7 +83,6 @@ export type CancelExportSchemaAction = { export type ChangeExportSchemaFormatStartedAction = { type: SchemaExportActions.changeExportSchemaFormatStarted; - abortController: AbortController; exportFormat: SchemaFormat; }; @@ -105,11 +100,8 @@ export const cancelExportSchema = (): SchemaThunkAction< void, CancelExportSchemaAction > => { - return (dispatch, getState) => { - const { - schemaExport: { abortController }, - } = getState(); - abortController?.abort(); + return (dispatch, getState, { exportAbortControllerRef }) => { + exportAbortControllerRef.current?.abort(); return dispatch({ type: SchemaExportActions.cancelExportSchema, @@ -157,19 +149,19 @@ export const changeExportSchemaFormat = ( | ChangeExportSchemaFormatErroredAction | ChangeExportSchemaFormatCompletedAction > => { - return async (dispatch, getState, { logger: { log } }) => { - const { - schemaExport: { abortController: existingAbortController }, - } = getState(); - + return async ( + dispatch, + getState, + { logger: { log }, exportAbortControllerRef, schemaAccessorRef } + ) => { // If we're already in progress we abort their current operation. - existingAbortController?.abort(); + exportAbortControllerRef.current?.abort(); - const abortController = new AbortController(); + exportAbortControllerRef.current = new AbortController(); + const abortSignal = exportAbortControllerRef.current.signal; dispatch({ type: SchemaExportActions.changeExportSchemaFormatStarted, - abortController, exportFormat, }); @@ -184,7 +176,7 @@ export const changeExportSchemaFormat = ( } ); - const schemaAccessor = getState().schemaAnalysis.schemaAccessor; + const schemaAccessor = schemaAccessorRef.current; if (!schemaAccessor) { throw new Error('No schema analysis available'); } @@ -192,10 +184,10 @@ export const changeExportSchemaFormat = ( exportedSchema = await getSchemaByFormat({ schemaAccessor, exportFormat, - signal: abortController.signal, + signal: abortSignal, }); } catch (err: any) { - if (abortController.signal.aborted) { + if (abortSignal.aborted) { return; } log.error( @@ -214,7 +206,7 @@ export const changeExportSchemaFormat = ( return; } - if (abortController.signal.aborted) { + if (abortSignal.aborted) { return; } @@ -271,7 +263,6 @@ export const schemaExportReducer: Reducer = ( ) { return { ...state, - abortController: action.abortController, exportStatus: 'inprogress', exportFormat: action.exportFormat, }; diff --git a/packages/compass-schema/src/stores/store.ts b/packages/compass-schema/src/stores/store.ts index d7efe6b7ab2..e9ffc3f03a4 100644 --- a/packages/compass-schema/src/stores/store.ts +++ b/packages/compass-schema/src/stores/store.ts @@ -17,6 +17,7 @@ import type { PreferencesAccess } from 'compass-preferences-model/provider'; import type { FieldStoreService } from '@mongodb-js/compass-field-store'; import type { QueryBarService } from '@mongodb-js/compass-query-bar'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; +import type { SchemaAccessor } from 'mongodb-schema'; import { schemaAnalysisReducer, handleSchemaShare, @@ -48,7 +49,9 @@ export const rootReducer = combineReducers({ export type RootState = ReturnType; export type SchemaExtraArgs = SchemaPluginServices & { - abortControllerRef: { current?: AbortController }; + analysisAbortControllerRef: { current?: AbortController }; + exportAbortControllerRef: { current?: AbortController }; + schemaAccessorRef: { current?: SchemaAccessor }; geoLayersRef: { current: Record }; namespace: string; }; @@ -97,7 +100,13 @@ export function configureStore( services: SchemaPluginServices, namespace: string ) { - const abortControllerRef = { + const analysisAbortControllerRef = { + current: undefined, + }; + const exportAbortControllerRef = { + current: undefined, + }; + const schemaAccessorRef = { current: undefined, }; const geoLayersRef: { current: Record } = { @@ -108,7 +117,9 @@ export function configureStore( applyMiddleware( thunk.withExtraArgument({ ...services, - abortControllerRef, + analysisAbortControllerRef, + exportAbortControllerRef, + schemaAccessorRef, geoLayersRef, namespace, })