piral-ng
Version:
Plugin for integrating Angular components in Piral.
150 lines • 5.89 kB
JavaScript
import { __decorate, __metadata, __param } from "tslib";
import { BrowserModule } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
import { ComponentFactoryResolver, CUSTOM_ELEMENTS_SCHEMA, Inject, NgModule, NgZone, } from '@angular/core';
import { PIRAL, PROPS } from './injection';
import { teardown } from './startup';
import { RoutingService } from './RoutingService';
import { findComponents, getAnnotations } from './utils';
import { piralName, propsName } from './constants';
import { SharedModule } from '../common';
const availableModules = [];
function instantiateModule(moduleDef, piral) {
var BootstrapModule_1;
const { module, components } = moduleDef;
const imports = [BrowserModule, SharedModule, module];
const props = { current: undefined };
const createProxy = () => new Proxy(props.current, {
get(_, name) {
return props.current[name];
},
});
const providers = [
RoutingService,
{ provide: propsName, useFactory: createProxy, deps: [] },
{ provide: PROPS, useFactory: createProxy, deps: [] },
{ provide: piralName, useFactory: () => piral, deps: [] },
{ provide: PIRAL, useFactory: () => piral, deps: [] },
];
let BootstrapModule = BootstrapModule_1 = class BootstrapModule {
constructor(resolver, zone, routing, flags) {
this.resolver = resolver;
this.zone = zone;
this.routing = routing;
this.flags = flags;
this.refs = [];
}
ngDoBootstrap(appRef) {
this.appRef = appRef;
}
attach(component, node, $props) {
const factory = this.resolver.resolveComponentFactory(component);
props.current = $props.value;
if (factory) {
const ref = this.zone.run(() => this.appRef.bootstrap(factory, node));
const name = ref.componentType?.ɵcmp?.inputs?.Props;
if (typeof name === 'string' || Array.isArray(name)) {
const sub = $props.subscribe((props) => {
if (typeof ref.setInput === 'function') {
// Here we don't care about the aliased name etc.
ref.setInput('Props', props);
}
else if (typeof name === 'string') {
// Legacy mode - just set it directly and trigger CD
ref.instance[name] = props;
ref.changeDetectorRef?.detectChanges();
}
});
ref.onDestroy(() => sub.unsubscribe());
}
this.refs.push([component, node, ref]);
}
}
detach(component, node) {
for (let i = this.refs.length; i--;) {
const [sourceComponent, sourceNode, ref] = this.refs[i];
if (sourceComponent === component && sourceNode === node) {
ref.destroy();
this.refs.splice(i, 1);
}
}
if (!this.flags?.keepAlive && this.refs.length === 0) {
teardown(BootstrapModule_1);
}
}
};
BootstrapModule = BootstrapModule_1 = __decorate([
NgModule({
imports,
// @ts-ignore
entryComponents: components,
providers,
}),
__param(3, Inject('NgFlags')),
__metadata("design:paramtypes", [ComponentFactoryResolver,
NgZone,
RoutingService, Object])
], BootstrapModule);
return BootstrapModule;
}
export function activateModuleInstance(moduleDef, piral) {
if (!moduleDef.active) {
moduleDef.active = instantiateModule(moduleDef, piral);
}
return [moduleDef.active, moduleDef.opts, moduleDef.flags];
}
export function getModuleInstance(component, standalone, piral) {
const [moduleDef] = availableModules.filter((m) => m.components.includes(component));
if (moduleDef) {
return activateModuleInstance(moduleDef, piral);
}
if (process.env.NODE_ENV === 'development') {
if (!standalone) {
console.warn('Component not found in all defined Angular modules. Make sure to define (using `defineNgModule`) a module with your component(s) referenced in the exports section of the `@NgModule` decorator.', component, piral.meta);
}
}
return undefined;
}
export function createModuleInstance(component, standalone, piral) {
const declarations = standalone ? [] : [component];
const importsDef = standalone ? [CommonModule, component] : [CommonModule];
const exportsDef = [component];
const schemasDef = [CUSTOM_ELEMENTS_SCHEMA];
let Module = class Module {
};
Module = __decorate([
NgModule({
declarations,
imports: importsDef,
exports: exportsDef,
schemas: schemasDef,
})
], Module);
defineModule(Module);
return getModuleInstance(component, standalone, piral);
}
export function findModule(module) {
return availableModules.find((m) => m.module === module);
}
export function defineModule(module, opts = undefined, flags = undefined) {
const [annotation] = getAnnotations(module);
if (annotation) {
availableModules.push({
active: undefined,
components: findComponents(annotation.exports),
module,
flags,
opts,
});
}
else if (typeof module === 'function') {
const state = {
current: undefined,
};
return (selector) => ({
component: { selector, module, opts, flags, state },
type: 'ng',
});
}
}
//# sourceMappingURL=module.js.map