Description

Defines the configuration for a function that generates a FactoryProvider for native objects.

Extends

FactoryGeneratorConfig

import { FactoryProvider  } from '@angular/core';
import { UniversalService } from '@bespunky/angular-zen/universal';

import { GoogleMapsApiService   } from '../../api/google-maps-api.service';
import { Native                 } from '../types/abstraction';
import { FactoryGeneratorConfig } from './common';
import { NativeInstance         } from './tokens';

type NativeFactory<TNative  extends Native> = (...deps: any[]) => TNative;

/**
 * Creates the factory that will be used in the provider created by `createNativeFactoryProvider`.
 * See `createNativeFactoryProvider` for more details.
 *
 * @template TNative The type of native object generated by the factory.
 * @param {NativeFactory<TNative>} produceNative The function that will create the native object. Receives the dependencies specified in `deps` when configuring the generator.
 * @returns A factory that receives the `GoogleMapsApiService`, `UniversalService`, and any additional dependencies, then returns a new native object on browsers and `null` on non-browsers.
 */
function createNativeFactory<TNative extends Native>(produceNative: NativeFactory<TNative>)
{
    // Called by Angular's Dependency Injector
    return (api: GoogleMapsApiService, universal: UniversalService, ...deps: any[]) =>
    {
        // TODO: Test with Angular Universal app and see if this doesn't break the chain of contained directives
        if (!universal.isPlatformBrowser) return null;

        return api.runOutsideAngular(() => produceNative(...deps));
    };
}

/**
 * Defines the configuration for a function that generates a `FactoryProvider` for native objects.
 *
 * @export
 * @interface NativeFactoryGeneratorConfig
 * @extends {FactoryGeneratorConfig<Native>}
 */
export interface NativeFactoryGeneratorConfig extends FactoryGeneratorConfig<Native> { }

/**
 * Applies default values for undefined values in the config object.
 *
 * @export
 * @param {NativeFactoryGeneratorConfig} config The optional config.
 * @returns {Required<NativeFactoryGeneratorConfig>} The filled config.
 */
export function configNativeFactoryProviderGeneratorDefaults(config: NativeFactoryGeneratorConfig): Required<NativeFactoryGeneratorConfig>
{
    return {
        token: config.token || NativeInstance,
        deps : config.deps  || []
    };
}

/**
 * Creates a factory provider for the a natve object injection token.
 * The factory runs the specified function and passes the specified dependencies to it.
 * The function will be run outside Angular.
 *
 * By default, the generator will create the factory provider for the `NativeInstance` token.
 * To change this behavior, specify the appropriate token in the config argument.
 * 
 * Note: The factory will detect non-browser platforms and return `null` instead of calling the function.
 *  
 * @export
 * @template TNative The type of native object generated by the factory.
 * @param {NativeFactory<TNative>} produceNative The function that will create the native object. Receives the dependencies specified in `deps`.
 * @param {NativeFactoryGeneratorConfig} [config={}] (Optional) A configuration object for the generator.
 * @returns {FactoryProvider} A `FactoryProvider` object for the specified token.
 */
export function createNativeFactoryProvider<TNative extends Native>(produceNative: NativeFactory<TNative>, config: NativeFactoryGeneratorConfig = {}): FactoryProvider
{
    const { token, deps } = configNativeFactoryProviderGeneratorDefaults(config);

    return {
        provide   : token,
        useFactory: createNativeFactory(produceNative),
        deps      : [GoogleMapsApiService, UniversalService, ...deps]
    };
}

results matching ""

    No results matching ""