Back to home page

EIC code displayed by LXR

 
 

    


Warning, /firebird/packages/firebird-ng/src/lib/provide-firebird.ts is written in an unsupported language. File is not indexed.

0001 /**
0002  * `provideFirebird()`: assembles the event display from Firebird's built-ins
0003  * and the application's features.
0004  */
0005 
0006 import { EnvironmentProviders, inject, provideAppInitializer } from '@angular/core';
0007 import {
0008   APP_FEATURE_OWNERS,
0009   AppFeatureInput,
0010   provideAppFeatures,
0011   resolveRegistry,
0012 } from '@dexvis/app-features';
0013 // The /model subpath (initial-bundle file): the core root re-exports the
0014 // painters, which pull three.js; the model imports none.
0015 import { registerEventPieceFactory } from '@dexvis/firebird-core/model';
0016 import type { EventPieceFactory } from '@dexvis/firebird-core';
0017 import { EVENT_PIECE_FACTORIES } from '@dexvis/firebird-ng/api';
0018 import { withFirebirdBuiltins } from './with-firebird-builtins';
0019 
0020 /**
0021  * Development-build warning: two packs ship different factory classes for
0022  * one piece type. Only the last one takes effect, which is rarely what both
0023  * packs intend. Replacing a built-in factory is no collision: the built-ins
0024  * are a pack of defaults, and `owners` has no entry for them.
0025  */
0026 function warnPieceTypeCollisions(factories: readonly EventPieceFactory[], owners: ReadonlyMap<unknown, readonly string[]>): void {
0027   const classesByType = new Map<string, Set<Function>>();
0028   for (const factory of factories) {
0029     const classes = classesByType.get(factory.type) ?? new Set<Function>();
0030     classes.add(factory.constructor);
0031     classesByType.set(factory.type, classes);
0032   }
0033   for (const [type, classes] of classesByType) {
0034     if (classes.size < 2) continue;
0035     const packs = new Set([...classes].flatMap(factoryClass => owners.get(factoryClass) ?? []));
0036     if (packs.size < 2) continue;
0037     const sources = [...classes]
0038       .filter(factoryClass => owners.has(factoryClass))
0039       .map(factoryClass => `${factoryClass.name} (${owners.get(factoryClass)!.join(', ')})`);
0040     // A piece factory feature has no id: dropping one of them means dropping its pack
0041     console.warn(`[Firebird] Piece type '${type}' has factories from several packs: ${sources.join(', ')}. ` +
0042       `The last one decodes it. To keep another one, change the order of the packs or drop a pack with withoutFeatures('<pack id>').`);
0043   }
0044 }
0045 
0046 /**
0047  * Assembles the Firebird event display: Firebird's built-ins
0048  * (`withFirebirdBuiltins()`), then the application's features.
0049  *
0050  * ```ts
0051  * export const appConfig: ApplicationConfig = {
0052  *   providers: [
0053  *     provideZonelessChangeDetection(),
0054  *     provideRouter(routes),
0055  *     provideHttpClient(withFetch()),
0056  *     provideFirebird(
0057  *       withMyExperiment(),
0058  *       withoutFeatures('firebird.navigation-cube'),
0059  *     ),
0060  *   ],
0061  * };
0062  * ```
0063  *
0064  * The built-ins are installed first, so registration order puts them ahead
0065  * of the application's features. To drop a part of them, pass
0066  * `withoutFeatures()` with the part's feature id (see
0067  * with-firebird-builtins.ts); to replace one, register under its id.
0068  *
0069  * Startup order inside the app initializers (after the initializers that
0070  * features contribute):
0071  * 1. Register DI-contributed event piece factories into the core registry
0072  *    (workers call core's `initPieceFactories()` explicitly instead; core stays DI-free).
0073  * 2. Apply feature-contributed config defaults.
0074  * 3. Load the server config (server tier of the config precedence).
0075  * 4. Parse URL query parameters: `config.*` session overrides and startup
0076  *    commands (`dex`, `geometry`, `event`, `cmd`). Commands are queued and run
0077  *    by the display page once the scene is ready.
0078  *
0079  * Steps 2-4 are `provideAppFeatures()` from `@dexvis/app-features`.
0080  */
0081 export function provideFirebird(...features: AppFeatureInput[]): EnvironmentProviders {
0082   return provideAppFeatures(
0083     withFirebirdBuiltins(),
0084     ...features,
0085     {
0086       kind: 'initializer',
0087       providers: [provideAppInitializer(() => {
0088         const factories = inject(EVENT_PIECE_FACTORIES, { optional: true }) ?? [];
0089         if (typeof ngDevMode !== 'undefined' && ngDevMode) {
0090           warnPieceTypeCollisions(factories, inject(APP_FEATURE_OWNERS, { optional: true }) ?? new Map());
0091         }
0092         for (const factory of resolveRegistry(factories, factory => factory.type)) {
0093           registerEventPieceFactory(factory);
0094         }
0095       })],
0096     },
0097   );
0098 }