Skip to content

Commit

Permalink
feat: add getExtensions method to extend zoid component instance (#468)
Browse files Browse the repository at this point in the history
  • Loading branch information
ravishekhar authored Dec 19, 2024
1 parent b2c8a19 commit 44d2d24
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 35 deletions.
4 changes: 2 additions & 2 deletions src/child/child.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ export type ChildComponent<P, X> = {|
init: () => ZalgoPromise<void>,
|};

export function childComponent<P, X, C>(
options: NormalizedComponentOptionsType<P, X, C>
export function childComponent<P, X, C, ExtType>(
options: NormalizedComponentOptionsType<P, X, C, ExtType>
): ChildComponent<P, X> {
const { tag, propsDef, autoResize, allowedParentDomains } = options;

Expand Down
75 changes: 51 additions & 24 deletions src/component/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {

import { childComponent, type ChildComponent } from "../child";
import {
type ParentComponent,
type RenderOptionsType,
type ParentHelpers,
parentComponent,
Expand Down Expand Up @@ -106,9 +107,10 @@ export type ExportsDefinition<X> =
| ExportsConfigDefinition
| ExportsMapperDefinition<X>;

export type ComponentOptionsType<P, X, C> = {|
export type ComponentOptionsType<P, X, C, ExtType> = {|
tag: string,

getExtensions?: (parent: ParentComponent<P, X>) => ExtType,
url: string | (({| props: PropsType<P> |}) => string),
domain?: DomainMatcher,
bridgeUrl?: string,
Expand Down Expand Up @@ -155,10 +157,11 @@ type AutoResizeType = {|
element?: string,
|};

export type NormalizedComponentOptionsType<P, X, C> = {|
export type NormalizedComponentOptionsType<P, X, C, ExtType> = {|
tag: string,
name: string,

getExtensions: (parent: ParentComponent<P, X>) => ExtType,
url: string | (({| props: PropsType<P> |}) => string),
domain: ?DomainMatcher,
bridgeUrl: ?string,
Expand Down Expand Up @@ -192,12 +195,13 @@ export type NormalizedComponentOptionsType<P, X, C> = {|
exports: ExportsMapperDefinition<X>,
|};

export type ZoidComponentInstance<P, X = void, C = void> = {|
export type ZoidComponentInstance<P, X = void, C = void, ExtType = void> = {|
...ExtType,
...ParentHelpers<P>,
...X,
...C,
isEligible: () => boolean,
clone: () => ZoidComponentInstance<P, X, C>,
clone: () => ZoidComponentInstance<P, X, C, ExtType>,
render: (
container?: ContainerReferenceType,
context?: $Values<typeof CONTEXT>
Expand All @@ -210,14 +214,14 @@ export type ZoidComponentInstance<P, X = void, C = void> = {|
|};

// eslint-disable-next-line flowtype/require-exact-type
export type ZoidComponent<P, X = void, C = void> = {
(props?: PropsInputType<P> | void): ZoidComponentInstance<P, X, C>,
export type ZoidComponent<P, X = void, C = void, ExtType = void> = {
(props?: PropsInputType<P> | void): ZoidComponentInstance<P, X, C, ExtType>,
// eslint-disable-next-line no-undef
driver: <T>(string, mixed) => T,
isChild: () => boolean,
xprops?: PropsType<P>,
canRenderTo: (CrossDomainWindowType) => ZalgoPromise<boolean>,
instances: $ReadOnlyArray<ZoidComponentInstance<P, X, C>>,
instances: $ReadOnlyArray<ZoidComponentInstance<P, X, C, ExtType>>,
};

const getDefaultAttributes = (): AttributesType => {
Expand All @@ -240,15 +244,26 @@ const getDefaultDimensions = (): CssDimensionsType => {
return {};
};

function normalizeOptions<P, X, C>(
options: ComponentOptionsType<P, X, C>
): NormalizedComponentOptionsType<P, X, C> {
function getDefaultGetExtensions<P, X, ExtType>(): (
parent: ParentComponent<P, X>
) => ExtType {
return function getExtensions(): ExtType {
// $FlowFixMe
const ext: ExtType = {};
return ext;
};
}

function normalizeOptions<P, X, C, ExtType>(
options: ComponentOptionsType<P, X, C, ExtType>
): NormalizedComponentOptionsType<P, X, C, ExtType> {
const {
tag,
url,
domain,
bridgeUrl,
props = {},
getExtensions = getDefaultGetExtensions<P, X, ExtType>(),
dimensions = getDefaultDimensions(),
autoResize = getDefaultAutoResize(),
allowedParentDomains = WILDCARD,
Expand Down Expand Up @@ -329,31 +344,42 @@ function normalizeOptions<P, X, C>(
eligible,
children,
exports: xports,
getExtensions,
};
}

let cleanInstances = cleanup();
const cleanZoid = cleanup();

export type Component<P, X, C> = {|
init: (props?: PropsInputType<P> | void) => ZoidComponentInstance<P, X, C>,
instances: $ReadOnlyArray<ZoidComponentInstance<P, X, C>>,
export type Component<P, X, C, ExtType> = {|
init: (
props?: PropsInputType<P> | void
) => ZoidComponentInstance<P, X, C, ExtType>,
instances: $ReadOnlyArray<ZoidComponentInstance<P, X, C, ExtType>>,
driver: (string, mixed) => mixed,
isChild: () => boolean,
canRenderTo: (CrossDomainWindowType) => ZalgoPromise<boolean>,
registerChild: () => ?ChildComponent<P, X>,
|};

export function component<P, X, C>(
opts: ComponentOptionsType<P, X, C>
): Component<P, X, C> {
export function component<P, X, C, ExtType>(
opts: ComponentOptionsType<P, X, C, ExtType>
): Component<P, X, C, ExtType> {
if (__DEBUG__) {
validateOptions(opts);
}

const options = normalizeOptions(opts);

const { name, tag, defaultContext, propsDef, eligible, children } = options;
const {
name,
tag,
defaultContext,
propsDef,
eligible,
children,
getExtensions,
} = options;

const global = getGlobal(window);
const driverCache = {};
Expand Down Expand Up @@ -471,7 +497,7 @@ export function component<P, X, C>(

const init = (
inputProps?: PropsInputType<P> | void
): ZoidComponentInstance<P, X, C> => {
): ZoidComponentInstance<P, X, C, ExtType> => {
// eslint-disable-next-line prefer-const
let instance;

Expand Down Expand Up @@ -590,6 +616,7 @@ export function component<P, X, C>(
};

instance = {
...getExtensions(parent),
...parent.getExports(),
...parent.getHelpers(),
...getChildren(),
Expand Down Expand Up @@ -663,15 +690,15 @@ export type ComponentDriverType<P, L, D, X, C> = {|
export type ZoidProps<P> = PropsType<P>;

// eslint-disable-next-line no-undef
export type CreateZoidComponent = <P, X, C>(
export type CreateZoidComponent = <P, X, C, ExtType>(
// eslint-disable-next-line no-undef
options: ComponentOptionsType<P, X, C>
options: ComponentOptionsType<P, X, C, ExtType>
// eslint-disable-next-line no-undef
) => ZoidComponent<P, X, C>;
) => ZoidComponent<P, X, C, ExtType>;

export const create: CreateZoidComponent = <P, X, C>(
options: ComponentOptionsType<P, X, C>
): ZoidComponent<P, X, C> => {
export const create: CreateZoidComponent = <P, X, C, ExtType>(
options: ComponentOptionsType<P, X, C, ExtType>
): ZoidComponent<P, X, C, ExtType> => {
setupPostRobot();

const comp = component(options);
Expand Down
8 changes: 4 additions & 4 deletions src/component/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { CONTEXT, PROP_TYPE } from "../constants";

import type { ComponentOptionsType } from "./index";

function validatepropsDefinitions<P, X, C>(
options: ComponentOptionsType<P, X, C>
function validatepropsDefinitions<P, X, C, ExtType>(
options: ComponentOptionsType<P, X, C, ExtType>
) {
if (options.props && !(typeof options.props === "object")) {
throw new Error(`Expected options.props to be an object`);
Expand Down Expand Up @@ -49,8 +49,8 @@ function validatepropsDefinitions<P, X, C>(
}

// eslint-disable-next-line complexity
export function validateOptions<P, X, C>(
options: ?ComponentOptionsType<P, X, C>
export function validateOptions<P, X, C, ExtType>(
options: ?ComponentOptionsType<P, X, C, ExtType>
) {
// eslint-ignore-line

Expand Down
10 changes: 5 additions & 5 deletions src/parent/parent.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ type RenderOptions = {|
rerender: Rerender,
|};

type ParentComponent<P, X> = {|
export type ParentComponent<P, X> = {|
init: () => void,
render: (RenderOptions) => ZalgoPromise<void>,
getProps: () => PropsType<P>,
Expand All @@ -271,19 +271,19 @@ const getDefaultOverrides = <P>(): ParentDelegateOverrides<P> => {
return {};
};

type ParentOptions<P, X, C> = {|
type ParentOptions<P, X, C, ExtType> = {|
uid: string,
options: NormalizedComponentOptionsType<P, X, C>,
options: NormalizedComponentOptionsType<P, X, C, ExtType>,
overrides?: ParentDelegateOverrides<P>,
parentWin?: CrossDomainWindowType,
|};

export function parentComponent<P, X, C>({
export function parentComponent<P, X, C, ExtType>({
uid,
options,
overrides = getDefaultOverrides(),
parentWin = window,
}: ParentOptions<P, X, C>): ParentComponent<P, X> {
}: ParentOptions<P, X, C, ExtType>): ParentComponent<P, X> {
const {
propsDef,
containerTemplate,
Expand Down
Loading

0 comments on commit 44d2d24

Please sign in to comment.