From dd52b3ed4910059c1323ea0c3e037e38a14508af Mon Sep 17 00:00:00 2001 From: Felix Berman Date: Sun, 29 Aug 2021 12:51:24 +0300 Subject: [PATCH] Add API aspects - WIP --- src/API.ts | 13 ++++++++++++ src/appHost.ts | 35 ++++++++++++++++++++++++--------- src/interceptAnyObject.ts | 3 +-- test/interceptAnyObject.spec.ts | 3 ++- 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/API.ts b/src/API.ts index d499963f..4972f4e0 100644 --- a/src/API.ts +++ b/src/API.ts @@ -290,10 +290,23 @@ export interface APILayer { name: string } +export type FunctionInterceptor = (name: string, original: Function) => Function +export type PropertyInterceptor = (name: string, original: any) => any + +export interface APIAspect { + readonly name: string + readonly interceptFunction?: FunctionInterceptor + readonly interceptProperty?: PropertyInterceptor + readonly descendNestedLevel?: number +} + +export type APIAspectFactory = (apiKey: AnySlotKey, normalizedName: string) => APIAspect + export interface AppHostOptions { readonly logger?: HostLogger readonly monitoring: MonitoringOptions readonly layers?: APILayer[] | APILayer[][] + readonly apiAspects?: APIAspectFactory[] readonly disableLayersValidation?: boolean readonly disableCheckCircularDependencies?: boolean readonly enableStickyErrorBoundaries?: boolean diff --git a/src/appHost.ts b/src/appHost.ts index 25e03399..e86643c7 100644 --- a/src/appHost.ts +++ b/src/appHost.ts @@ -47,6 +47,7 @@ import { ConsoleHostLogger, createShellLogger } from './loggers' import { monitorAPI } from './monitorAPI' import { Graph, Tarjan } from './tarjanGraph' import { setupDebugInfo } from './repluggableAppDebug' +import { interceptAnyObject } from './interceptAnyObject' const isMultiArray = (v: T[] | T[][]): v is T[][] => _.every(v, _.isArray) const castMultiArray = (v: T[] | T[][]): T[][] => { @@ -881,14 +882,30 @@ miss: ${memoizedWithMissHit.miss} ) } + const applyAPIAspects = (inner: TAPI): TAPI => { + const normalizedName = normalizeApiName(slotKeyToName(key)) + + let result = monitorAPI(shell, options, normalizedName, api /*, trace, memoizedArr*/, apiOptions) + + const aspectFactories = options.apiAspects + + if (aspectFactories) { + for (const aspectFactory of aspectFactories) { + const aspect = aspectFactory(key, normalizedName) + result = interceptAnyObject( + result, + aspect.interceptFunction, + aspect.interceptProperty, + aspect.descendNestedLevel + ) + } + } + + return result + } + const api = factory() - const monitoredAPI = monitorAPI( - shell, - options, - normalizeApiName(slotKeyToName(key)), - api /*, trace, memoizedArr*/, - apiOptions - ) + const apiWithAspects = applyAPIAspects(api) const apiSlot = declareSlot(key) APILayers.set( @@ -900,7 +917,7 @@ miss: ${memoizedWithMissHit.miss} .value() : undefined ) - apiSlot.contribute(shell, monitoredAPI) + apiSlot.contribute(shell, apiWithAspects) readyAPIs.add(key) @@ -910,7 +927,7 @@ miss: ${memoizedWithMissHit.miss} setInstalledShellNames(_.difference(shellNames, _.map(unReadyEntryPointsStore.get(), 'name'))) } - return monitoredAPI + return apiWithAspects }, contributeState( diff --git a/src/interceptAnyObject.ts b/src/interceptAnyObject.ts index 7254cad9..5115417b 100644 --- a/src/interceptAnyObject.ts +++ b/src/interceptAnyObject.ts @@ -1,10 +1,9 @@ import _ from 'lodash' +import { FunctionInterceptor, PropertyInterceptor } from './API' export interface AnyObject { [key: string]: any } -export type FunctionInterceptor = (name: string, original: Function) => Function -export type PropertyInterceptor = (name: string, original: any) => any export function interceptAnyObject( inner: T, diff --git a/test/interceptAnyObject.spec.ts b/test/interceptAnyObject.spec.ts index f6b092d7..7d57224d 100644 --- a/test/interceptAnyObject.spec.ts +++ b/test/interceptAnyObject.spec.ts @@ -1,5 +1,6 @@ import _ from 'lodash' -import { interceptAnyObject, FunctionInterceptor, PropertyInterceptor } from '../src/interceptAnyObject' +import { FunctionInterceptor, PropertyInterceptor } from '../src/API' +import { interceptAnyObject } from '../src/interceptAnyObject' type LogSpy = jest.Mock