Skip to content

Commit

Permalink
Merge pull request #32 from rambler-digital-solutions/types
Browse files Browse the repository at this point in the history
fix types
  • Loading branch information
andrepolischuk authored Jun 25, 2024
2 parents 0088f61 + c3d173a commit 85812ef
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 48 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"domready": "^1.0.8",
"lodash.debounce": "^4.0.8",
"lodash.throttle": "^4.1.1",
"magic-transport": "^3.0.0"
"magic-transport": "^3.0.1"
},
"devDependencies": {
"@commitlint/cli": "^19.0.3",
Expand Down
32 changes: 23 additions & 9 deletions src/iframe/consumer.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,30 @@
import type BaseEventEmitter from 'events'
import {Consumer} from 'magic-transport'
import type {Size, Promisify} from '../types'
import type {IFrameProviderAPI} from './provider'
import {IFrameResizer} from './consumer-resizer'

/**
* Configuration of the consumer inside an iframe
*/
export interface IFrameConsumerConfig {
/** Widget initialization function, should render the application */
initialize(): void
initialize(this: IFrameConsumer): void
/** Factory that exports a facade available externally to the widget user */
externalize?(): void
externalize?(this: IFrameConsumer): void
/** Factory that exports a facade available to the widget */
externalizeAsConsumer?(): void
externalizeAsConsumer?(this: IFrameConsumer): void
}

/**
* Consumer facade available to the widget
*/
export interface IFrameConsumerAPI extends Record<string, any> {
initialize(this: IFrameConsumer): void
externalizedProps: Record<string, any>
getSize(): Size
watchSize(): void
resize(): void
}

/**
Expand All @@ -19,9 +33,9 @@ export interface IFrameConsumerConfig {
export class IFrameConsumer {
public id: string
public resizer: IFrameResizer
public transport: Consumer<any, any>
public consumer: Record<string, any>
public provider?: Record<string, any>
public transport: Consumer<IFrameProviderAPI, IFrameConsumerAPI>
public consumer: BaseEventEmitter & IFrameConsumerAPI
public provider!: Promisify<BaseEventEmitter & IFrameProviderAPI>

private config: IFrameConsumerConfig
private properties: Record<string, any>
Expand All @@ -38,7 +52,7 @@ export class IFrameConsumer {
*/
public constructor(
config: IFrameConsumerConfig,
properties: Record<string, any>
properties?: Record<string, any>
) {
this.id = this.parseId()
this.config = config
Expand All @@ -56,7 +70,7 @@ export class IFrameConsumer {
}
}

this.transport = new Consumer({
this.transport = new Consumer<IFrameProviderAPI, IFrameConsumerAPI>({
id: this.id,
parentOrigin: '*',
...this.externalizeAsConsumer()
Expand Down Expand Up @@ -110,7 +124,7 @@ export class IFrameConsumer {
*/
export function registerIFrame(
config: IFrameConsumerConfig,
properties: Record<string, any>
properties?: Record<string, any>
) {
return new IFrameConsumer(config, properties)
}
27 changes: 19 additions & 8 deletions src/iframe/provider.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type BaseEventEmitter from 'events'
import {Provider} from 'magic-transport'
import {
removeFromDOM,
Expand All @@ -7,25 +8,35 @@ import {
} from '../utils/dom'
import {getVisibleArea, type VisibleArea} from '../utils/dom/viewport'
import {EventEmitter} from '../utils/event-emitter'
import type {Callback, Debounce, Size} from '../types'
import type {Widget} from '../widget'
import type {ContentElement} from '../layouts/content-element'
import type {Callback, Debounce, Size, Promisify} from '../types'
import type {Widget, WidgetProviderAPI} from '../widget'
import type {IFrameConsumerAPI} from './consumer'
import {Resizer} from './provider-resizer'

/**
* Provider facade available in the iframe
*/
export interface IFrameProviderAPI extends WidgetProviderAPI {
resize(): void
setSize(size: Size): void
}

/**
* Wrapper over an iframe
*
* @event viewportChange Event when the viewport of the element changes
* @event destroy Termination of the provider
*/
export class IFrameProvider extends EventEmitter {
export class IFrameProvider extends EventEmitter implements ContentElement {
public id: string
public url: string
public resizer?: Resizer
public transport?: Provider<any, any>
public consumer?: Record<string, any>
public provider?: Record<string, any>
public transport?: Provider<IFrameProviderAPI, IFrameConsumerAPI>
public consumer?: Promisify<BaseEventEmitter & IFrameConsumerAPI>
public provider?: BaseEventEmitter & IFrameProviderAPI
public element!: HTMLIFrameElement

private element!: HTMLIFrameElement
private widget: Widget
private viewportManager?: ViewportManager
private consumerOrigin: string
Expand Down Expand Up @@ -85,7 +96,7 @@ export class IFrameProvider extends EventEmitter {
* Initialization of the iframe provider
*/
public async initialize() {
this.transport = new Provider<any, any>({
this.transport = new Provider<IFrameProviderAPI, IFrameConsumerAPI>({
id: this.id,
childOrigin: this.consumerOrigin,
...this.widget.externalizeAsProvider(),
Expand Down
9 changes: 7 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ export type {
ContainerElement,
EnterViewportOptions
} from './container'
export type {Widget, WidgetConfig, ExternalizedWidget} from './widget'
export type {Widget, WidgetConfig, WidgetAPI} from './widget'
export type {Debounce, Callback} from './types'
export {createMediator, Mediator, type MediatorConfig} from './mediator'
export {
createMediator,
Mediator,
type MediatorConfig,
type MediatorAPI
} from './mediator'
2 changes: 1 addition & 1 deletion src/layouts/content-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Content element
*/
export abstract class ContentElement {
protected abstract element: HTMLElement
public abstract element: HTMLElement

public abstract getElement(): HTMLElement
}
25 changes: 19 additions & 6 deletions src/mediator.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import domready from 'domready'
import {randomId} from './utils/random-id'
import {mutationEvents} from './utils/dom'
import {EventEmitter} from './utils/event-emitter'
import {EventEmitter, type EventEmitterAPI} from './utils/event-emitter'
import {Container} from './container'
import {Widget, type WidgetConfig, type ExternalizedWidget} from './widget'
import {Widget, type WidgetConfig, type WidgetAPI} from './widget'

/**
* Mediator configuration
Expand All @@ -12,11 +12,24 @@ export interface MediatorConfig {
/** Prefix for data-attributes */
prefix: string
/** Initialization function */
initialize(): void
initialize?(this: Mediator): void
/** Factory that exports a facade available in an iframe */
externalizeAsProvider?(this: Mediator): Record<string, any>
}

/**
* Mediator facade available to the widget and inside an iframe
*/
export interface MediatorAPI extends EventEmitterAPI, Record<string, any> {
buildWidget(
name: string,
containerElement: HTMLElement | string,
params?: Record<string, any>
): Promise<WidgetAPI>
buildWidget(name: string, params?: Record<string, any>): Promise<WidgetAPI>
initializeDOMElements(): void
}

/**
* Mediator - a widget factory
*/
Expand Down Expand Up @@ -154,7 +167,7 @@ export class Mediator extends EventEmitter {
name: string,
containerElement: HTMLElement | string,
params?: Record<string, any>
): Promise<ExternalizedWidget>
): Promise<WidgetAPI>

/**
* Create a widget and place it on the page
Expand All @@ -165,13 +178,13 @@ export class Mediator extends EventEmitter {
public buildWidget(
name: string,
params?: Record<string, any>
): Promise<ExternalizedWidget>
): Promise<WidgetAPI>

public buildWidget(
name: string,
containerElement?: HTMLElement | string | Record<string, any>,
params?: Record<string, any>
): Promise<ExternalizedWidget> {
): Promise<WidgetAPI> {
if (!this.widgets[name]) {
throw new Error(`Widget '${name}' does not exists`)
}
Expand Down
12 changes: 12 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,15 @@ export interface Size {
width: number
height: number
}

type ArgumentTypes<F extends () => any> = F extends (...args: infer A) => any
? A
: never

export type Promisify<T> = {
[K in keyof T]: T[K] extends (...args: any[]) => any
? (...args: ArgumentTypes<T[K]>) => Promise<ReturnType<T[K]>>
: T[K] extends object
? Promisify<T[K]>
: T[K]
}
10 changes: 5 additions & 5 deletions src/utils/event-emitter.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import BaseEventEmitter from 'events'

interface ExternalizeEmitterParams {
interface EventEmitterAPIParams {
withEmit?: boolean
}

export type ExternalizedEmitter = Pick<
EventEmitter,
export type EventEmitterAPI = Pick<
BaseEventEmitter,
'on' | 'once' | 'removeListener' | 'emit'
>

Expand All @@ -16,8 +16,8 @@ export class EventEmitter extends BaseEventEmitter {
}

public externalizeEmitter(
params: ExternalizeEmitterParams = {}
): ExternalizedEmitter {
params: EventEmitterAPIParams = {}
): EventEmitterAPI {
const methods: (keyof EventEmitter)[] = ['on', 'once', 'removeListener']

if (params.withEmit) {
Expand Down
41 changes: 29 additions & 12 deletions src/widget.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
import {IFrameProvider} from './iframe/provider'
import {EventEmitter, type ExternalizedEmitter} from './utils/event-emitter'
import {EventEmitter, type EventEmitterAPI} from './utils/event-emitter'
import {scrollByElementTo} from './utils/dom'
import {VisibleArea} from './utils/dom/viewport'
import type {Debounce, Callback} from './types'
import type {Mediator} from './mediator'
import type {Mediator, MediatorAPI} from './mediator'
import type {Container, EnterViewportOptions} from './container'
import {BaseLayout} from './layouts/base-layout'

/**
* Widget facade available to the user
*/
export interface ExternalizedWidget extends ExternalizedEmitter {
export interface WidgetAPI extends EventEmitterAPI, Record<string, any> {
params: Record<string, any>
destroy(): void
}

/**
* Widget facade available in the iframe
*/
export interface WidgetProviderAPI
extends EventEmitterAPI,
Record<string, any> {
url: string
mediator: MediatorAPI
params: Record<string, any>
destroy(): void
subscribeVisibleAreaChange(callback: Callback): void
getVisibleArea(): VisibleArea
scrollTo(top: number, duration: number): void
resize(): void
}

/**
* Widget configuration
*/
Expand Down Expand Up @@ -48,18 +65,18 @@ export class Widget extends EventEmitter {
public name: string

/** Widget configuration */
private config: WidgetConfig
public config: WidgetConfig

/** Widget properties */
private properties: Record<string, any>
public properties: Record<string, any>

/** External parameters for the widget */
private params: Record<string, any>
public params: Record<string, any>

private mediator: Mediator
private layout?: BaseLayout
private container?: Container
private iframe?: IFrameProvider
public mediator: Mediator
public layout?: BaseLayout
public container!: Container
public iframe?: IFrameProvider
private destroyed = false

/**
Expand Down Expand Up @@ -236,7 +253,7 @@ export class Widget extends EventEmitter {
this.container?.removeListener('destroy', this.destroy)
}

private getIFrameVisibleArea() {
return this.iframe?.getVisibleArea()
private getIFrameVisibleArea(): VisibleArea {
return this.iframe?.getVisibleArea() as VisibleArea
}
}
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6064,10 +6064,10 @@ lunr@^2.3.9:
resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1"
integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==

magic-transport@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/magic-transport/-/magic-transport-3.0.0.tgz#eedde85cc4d1f5fa71850f4eabda42922ed846e9"
integrity sha512-hwzrW8k0byUgQ0hoJgicjHyzIEnw0To1rjazDQOZsDho/Zv61HjqbwS68hK+bj5wHA7DL3UV9JWjdSrPtHSjRQ==
magic-transport@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/magic-transport/-/magic-transport-3.0.1.tgz#2434819ac9556686b561573c6924ca03908cfe7c"
integrity sha512-yNt9+l4VIYhlWIcHcWX8g6V6DoH6KRIDGcarILpZnVQreLr5635sN+Wxna0tO08dTbAOE1EFE/+mael35PC1fg==
dependencies:
dot-prop "^3.0.0"

Expand Down

0 comments on commit 85812ef

Please sign in to comment.