ngx-blocks-studio 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,520 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import { Type, Injector, Signal, ComponentRef, ViewContainerRef } from '@angular/core';
3
+ import { CanActivateFn, RunGuardsAndResolvers } from '@angular/router';
4
+ import { z } from 'zod';
5
+
6
+ /**
7
+ * Registry entry type: component, service, or guard.
8
+ */
9
+ type RegistryEntryType = 'component' | 'service' | 'guard';
10
+ /**
11
+ * Metadata value stored per registry key.
12
+ */
13
+ type RegistryMetadataRecord = Record<string, unknown>;
14
+ interface AllRegistryMetadata {
15
+ components: Map<string, RegistryMetadataRecord>;
16
+ services: Map<string, RegistryMetadataRecord>;
17
+ guards: Map<string, RegistryMetadataRecord>;
18
+ }
19
+ /**
20
+ * Single source of truth for metadata across component, service, and guard registries.
21
+ * All registries delegate to this store so metadata can be queried uniformly
22
+ * and all metadata can be retrieved in one call.
23
+ */
24
+ declare class RegistryMetadataStore {
25
+ private static instance;
26
+ private entries;
27
+ private constructor();
28
+ static getInstance(): RegistryMetadataStore;
29
+ /**
30
+ * Set metadata for a registry key (component, service, or guard).
31
+ */
32
+ set(key: string, type: RegistryEntryType, data: RegistryMetadataRecord): void;
33
+ /**
34
+ * Get metadata for a key. Returns undefined if the key is not registered.
35
+ */
36
+ get(key: string): RegistryMetadataRecord | undefined;
37
+ /**
38
+ * Alias for get(); allows registries to expose getMetadata(key).
39
+ */
40
+ getMetadata(key: string): RegistryMetadataRecord | undefined;
41
+ /**
42
+ * Get all metadata for a given type (components or services).
43
+ */
44
+ getByType(type: RegistryEntryType): Map<string, RegistryMetadataRecord>;
45
+ /**
46
+ * Get all metadata for component, service, and guard registries in one call.
47
+ */
48
+ getAllMetadata(): AllRegistryMetadata;
49
+ /**
50
+ * Remove metadata for a key (e.g. when unregistering).
51
+ */
52
+ remove(key: string): boolean;
53
+ /**
54
+ * Check if metadata exists for a key.
55
+ */
56
+ has(key: string): boolean;
57
+ /**
58
+ * Clear all metadata (e.g. when clearing registries).
59
+ */
60
+ clear(): void;
61
+ }
62
+
63
+ type ComponentLoader = () => Promise<Type<any>>;
64
+ declare class ComponentRegistry {
65
+ private static instance;
66
+ private components;
67
+ private loadedComponents;
68
+ private readonly metadataStore;
69
+ private constructor();
70
+ static getInstance(): ComponentRegistry;
71
+ register(name: string, component: Type<any> | ComponentLoader, metadata?: RegistryMetadataRecord): void;
72
+ get(name: string): Promise<Type<any> | undefined>;
73
+ getSync(name: string): Type<any> | undefined;
74
+ has(name: string): boolean;
75
+ getAll(): Map<string, Type<any>>;
76
+ unregister(name: string): boolean;
77
+ clear(): void;
78
+ getMetadata(key: string): RegistryMetadataRecord | undefined;
79
+ getAllWithMetadata(): Map<string, {
80
+ component: Type<any>;
81
+ metadata?: RegistryMetadataRecord;
82
+ }>;
83
+ }
84
+
85
+ /**
86
+ * Guard type: functional guard or class-based guard type.
87
+ * Registered by name; resolved by RouteLoader from route config guards array.
88
+ */
89
+ type GuardOrType = CanActivateFn | Type<unknown>;
90
+ /** Loader for lazy-loaded guards. Must be a function with no parameters that returns Promise<GuardOrType>. */
91
+ type GuardLoader = () => Promise<GuardOrType>;
92
+ type GuardOrLoader = GuardOrType | GuardLoader;
93
+ declare class GuardRegistry {
94
+ private static instance;
95
+ private guards;
96
+ private loadedGuards;
97
+ private readonly metadataStore;
98
+ private constructor();
99
+ static getInstance(): GuardRegistry;
100
+ register(name: string, guard: GuardOrLoader, metadata?: RegistryMetadataRecord): void;
101
+ /**
102
+ * Resolve guard by name (async; runs loader if needed).
103
+ */
104
+ get(name: string): Promise<GuardOrType | undefined>;
105
+ /**
106
+ * Resolve guard synchronously. Returns undefined if the entry is a lazy loader not yet loaded.
107
+ */
108
+ getSync(name: string): GuardOrType | undefined;
109
+ has(name: string): boolean;
110
+ getMetadata(key: string): RegistryMetadataRecord | undefined;
111
+ getAllWithMetadata(): Map<string, {
112
+ guard: GuardOrType;
113
+ metadata?: RegistryMetadataRecord;
114
+ }>;
115
+ unregister(name: string): boolean;
116
+ clear(): void;
117
+ private isLoader;
118
+ }
119
+
120
+ type ServiceLoader = () => Promise<Type<any>>;
121
+ declare class ServiceRegistry {
122
+ private static instance;
123
+ private services;
124
+ private loadedServices;
125
+ private injector;
126
+ private readonly metadataStore;
127
+ private constructor();
128
+ static getInstance(): ServiceRegistry;
129
+ /**
130
+ * Set the injector to use for service resolution
131
+ */
132
+ setInjector(injector: Injector): void;
133
+ /**
134
+ * Register a service by name (supports lazy loading)
135
+ */
136
+ register(name: string, service: Type<any> | ServiceLoader, metadata?: RegistryMetadataRecord): void;
137
+ /**
138
+ * Get a service instance by name (supports lazy loading)
139
+ * Requires injector to be set first
140
+ */
141
+ get(name: string): Promise<any>;
142
+ /**
143
+ * Get a service instance synchronously (only works for already loaded services)
144
+ */
145
+ getSync(name: string): any;
146
+ /**
147
+ * Inject a service type using the injector
148
+ */
149
+ private injectService;
150
+ /**
151
+ * Get the service Type (class) by name (supports lazy loading).
152
+ * Use this to scope the provider to a child injector (e.g. "self" context).
153
+ */
154
+ getType(name: string): Promise<Type<any> | undefined>;
155
+ /**
156
+ * Get the service Type synchronously (only for already loaded services).
157
+ */
158
+ getTypeSync(name: string): Type<any> | undefined;
159
+ /**
160
+ * Check if a service is registered
161
+ */
162
+ has(name: string): boolean;
163
+ /**
164
+ * Get all registered service names
165
+ */
166
+ getAllNames(): string[];
167
+ /**
168
+ * Get metadata for a registered service by key.
169
+ */
170
+ getMetadata(key: string): RegistryMetadataRecord | undefined;
171
+ /**
172
+ * Unregister a service
173
+ */
174
+ unregister(name: string): boolean;
175
+ /**
176
+ * Clear all registered services
177
+ */
178
+ clear(): void;
179
+ }
180
+
181
+ /**
182
+ * Route configuration for the router.
183
+ * @param path - The path of the route.
184
+ * @param component - The component key to load for the route using the ComponentRegistry.
185
+ * @param title - The title of the route.
186
+ * @param canActivate - The guards keys to activate for the route using the GuardRegistry.
187
+ * @param canDeactivate - The guards keys to deactivate for the route using the GuardRegistry.
188
+ * @param canLoad - The guards keys to load for the route using the GuardRegistry.
189
+ * @param canMatch - The guards keys to match for the route using the GuardRegistry.
190
+ * @param pathMatch - The path match strategy for the route.
191
+ * @param outlet - The outlet of the route.
192
+ * @param canActivateChild - The guards keys to activate the children routes for the route using the GuardRegistry.
193
+ * @param runGuardsAndResolvers - The strategy to run guards and resolvers for the route.
194
+ * @param data - The data to pass to the route. It will be merged with the data from the route config file.
195
+ * @param children - Nested routes and optional defaultRedirect/catchAllRedirect for the child segment.
196
+ */
197
+ interface RouteConfig {
198
+ path: string;
199
+ component: string;
200
+ title?: string;
201
+ canActivate?: string[];
202
+ canDeactivate?: string[];
203
+ canLoad?: string[];
204
+ canMatch?: string[];
205
+ outlet?: string;
206
+ pathMatch?: 'full' | 'prefix';
207
+ canActivateChild?: string[];
208
+ runGuardsAndResolvers?: RunGuardsAndResolvers;
209
+ data?: Record<string, any>;
210
+ /** Child routes; can include defaultRedirect and catchAllRedirect for this segment. */
211
+ children?: RouteConfigs;
212
+ }
213
+ interface RouteConfigs {
214
+ routes: RouteConfig[];
215
+ /** Redirect path for empty route (path: ''). Omit to not add a default redirect. */
216
+ defaultRedirect?: string;
217
+ /** Redirect path for unknown routes (path: '**'). Omit to not add a catch-all. */
218
+ catchAllRedirect?: string;
219
+ }
220
+ declare class RouteLoader {
221
+ private router;
222
+ private http;
223
+ private componentRegistry;
224
+ private guardRegistry;
225
+ private readonly _routeConfigFile;
226
+ private readonly _configPath;
227
+ /** Currently loaded route config file, or null if not yet loaded. */
228
+ readonly routeConfigFile: _angular_core.Signal<RouteConfigs | null>;
229
+ /** Path from which the config was loaded. */
230
+ readonly configPath: _angular_core.Signal<string>;
231
+ /** Route config array from the loaded file. */
232
+ readonly routeConfig: _angular_core.Signal<RouteConfig[]>;
233
+ /**
234
+ * Load routes from a config object. Updates signals and resets the router.
235
+ */
236
+ loadRoutes(config: RouteConfigs): Promise<void>;
237
+ /**
238
+ * Fetch route config from a URL (HTTP GET), then load it. Sets configPath signal to the requested URL.
239
+ */
240
+ loadRoutesFromUrl(configPath: string): Promise<void>;
241
+ private updateRoutes;
242
+ private convertRouteConfig;
243
+ private resolveGuards;
244
+ private loadComponent;
245
+ private getGuard;
246
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<RouteLoader, never>;
247
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<RouteLoader>;
248
+ }
249
+
250
+ /**
251
+ * Service entry: root-scoped (string id) or self-scoped ({ id, scope: "self" }).
252
+ */
253
+ declare const ServiceEntrySchema: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
254
+ id: z.ZodString;
255
+ scope: z.ZodLiteral<"self">;
256
+ }, z.core.$strip>]>;
257
+ /**
258
+ * Output handler: empty (use directive-provided handler) or reference-based (call method on ref).
259
+ */
260
+ declare const OutputReferenceSchema: z.ZodObject<{
261
+ type: z.ZodLiteral<"reference">;
262
+ reference: z.ZodString;
263
+ method: z.ZodString;
264
+ params: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
265
+ then: z.ZodOptional<z.ZodArray<z.ZodObject<{
266
+ reference: z.ZodString;
267
+ method: z.ZodString;
268
+ params: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
269
+ }, z.core.$strip>>>;
270
+ onSuccess: z.ZodOptional<z.ZodObject<{
271
+ reference: z.ZodString;
272
+ method: z.ZodString;
273
+ params: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
274
+ }, z.core.$strip>>;
275
+ onError: z.ZodOptional<z.ZodObject<{
276
+ reference: z.ZodString;
277
+ method: z.ZodString;
278
+ params: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
279
+ }, z.core.$strip>>;
280
+ }, z.core.$strip>;
281
+ /**
282
+ * Block description: JSON-serializable descriptor for dynamic block loading.
283
+ * Refs in inputs use instance namespace: instance.FormState.firstName or UserForm.instance.FormState.firstName.
284
+ */
285
+ declare const BlockDescriptionSchema: z.ZodObject<{
286
+ component: z.ZodString;
287
+ id: z.ZodOptional<z.ZodString>;
288
+ services: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
289
+ id: z.ZodString;
290
+ scope: z.ZodLiteral<"self">;
291
+ }, z.core.$strip>]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
292
+ id: z.ZodString;
293
+ scope: z.ZodLiteral<"self">;
294
+ }, z.core.$strip>]>>]>>>;
295
+ inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
296
+ outputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodObject<{
297
+ type: z.ZodLiteral<"reference">;
298
+ reference: z.ZodString;
299
+ method: z.ZodString;
300
+ params: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
301
+ then: z.ZodOptional<z.ZodArray<z.ZodObject<{
302
+ reference: z.ZodString;
303
+ method: z.ZodString;
304
+ params: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
305
+ }, z.core.$strip>>>;
306
+ onSuccess: z.ZodOptional<z.ZodObject<{
307
+ reference: z.ZodString;
308
+ method: z.ZodString;
309
+ params: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
310
+ }, z.core.$strip>>;
311
+ onError: z.ZodOptional<z.ZodObject<{
312
+ reference: z.ZodString;
313
+ method: z.ZodString;
314
+ params: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
315
+ }, z.core.$strip>>;
316
+ }, z.core.$strip>]>>>;
317
+ }, z.core.$strip>;
318
+ type BlockDescription = z.infer<typeof BlockDescriptionSchema>;
319
+ type ServiceEntry = z.infer<typeof ServiceEntrySchema>;
320
+ type OutputReference = z.infer<typeof OutputReferenceSchema>;
321
+ /** Normalize services to array. */
322
+ declare function normalizeServices(services: BlockDescription['services']): ServiceEntry[];
323
+ declare function parseBlockDescription(data: unknown): BlockDescription;
324
+ declare function safeParseBlockDescription(data: unknown): ReturnType<typeof BlockDescriptionSchema.safeParse>;
325
+ declare function isOutputReference(value: unknown): value is OutputReference;
326
+ /**
327
+ * Reference to a registered block: { id: string } or { blockId: string, blockDefinition?: object }.
328
+ * When blockDefinition is provided, it is deep-merged onto the base definition so only
329
+ * specified properties override (e.g. inputs.model); other keys are preserved.
330
+ */
331
+ interface BlockReference {
332
+ id?: string;
333
+ blockId?: string;
334
+ blockDefinition?: Record<string, unknown>;
335
+ }
336
+ declare function isBlockReference(value: unknown): value is BlockReference;
337
+ /** @deprecated Use isBlockReference. Id-only is still supported as { id: string }. */
338
+ declare function isIdReference(value: unknown): value is {
339
+ id: string;
340
+ };
341
+ /**
342
+ * Deep-merge override onto base. Only keys present in override are changed; nested objects
343
+ * are merged recursively so e.g. override.inputs.model does not remove base.inputs.rows.
344
+ * Arrays and primitives in override replace the base value.
345
+ */
346
+ declare function deepMergeBlockDefinition(base: Record<string, unknown>, override: Record<string, unknown>): Record<string, unknown>;
347
+ /**
348
+ * Resolve a block reference to a full description using blockDefinitions.
349
+ * If blockDefinition is present, it is deep-merged onto the base; otherwise returns the base.
350
+ */
351
+ declare function resolveBlockReference(ref: BlockReference, blockDefinitions: Record<string, unknown>): Record<string, unknown>;
352
+
353
+ /**
354
+ * Global registry of block id → definition. Register block configs at app init
355
+ * so they can be used as templates anywhere (e.g. nested blocks that reference
356
+ * { id: 'AppNav' } resolve without passing blockDefinitions down).
357
+ * Per-call blockDefinitions (e.g. from route data) override global entries.
358
+ */
359
+ declare class BlockDefinitionsRegistry {
360
+ private static instance;
361
+ private readonly definitions;
362
+ private constructor();
363
+ static getInstance(): BlockDefinitionsRegistry;
364
+ /** Register a block template by id. Can be called before the block is needed. */
365
+ register(id: string, definition: Record<string, unknown>): void;
366
+ /** Get one definition by id. */
367
+ get(id: string): Record<string, unknown> | undefined;
368
+ /** Get all registered definitions (id → definition). Used to merge with per-call definitions. */
369
+ getAll(): Record<string, unknown>;
370
+ unregister(id: string): boolean;
371
+ }
372
+
373
+ /**
374
+ * Handle for a registered block: exposes instance (services/state by name) for ref resolution.
375
+ */
376
+ interface BlockInstanceHandle {
377
+ /** Instance: services and state by name (e.g. FormState, value). */
378
+ instance: Record<string, unknown>;
379
+ /** Optional cleanup when block is destroyed. */
380
+ destroy?: () => void;
381
+ }
382
+ /**
383
+ * Registry of block instances by (full) id within a tree.
384
+ * One registry per logical tree; duplicate id throws.
385
+ */
386
+ interface BlockRegistry {
387
+ register(id: string, handle: BlockInstanceHandle): void;
388
+ unregister(id: string): void;
389
+ get(id: string): BlockInstanceHandle | undefined;
390
+ has(id: string): boolean;
391
+ }
392
+ /**
393
+ * Default in-memory BlockRegistry.
394
+ */
395
+ declare class BlockRegistryImpl implements BlockRegistry {
396
+ private readonly map;
397
+ register(id: string, handle: BlockInstanceHandle): void;
398
+ unregister(id: string): void;
399
+ get(id: string): BlockInstanceHandle | undefined;
400
+ has(id: string): boolean;
401
+ }
402
+
403
+ /**
404
+ * Parse ref paths and detect {{ref}} (read-only) and [(ref)] (two-way) in strings.
405
+ */
406
+ interface ParsedRefPath {
407
+ blockId?: string;
408
+ instancePath: string;
409
+ pathParts: string[];
410
+ }
411
+ declare function parseRefPath(refPath: string): ParsedRefPath;
412
+ declare function extractReadonlyRefs(template: string): string[];
413
+ declare function isTwoWayRefString(value: unknown): value is string;
414
+ /**
415
+ * True when a string contains two-way ref delimiters `[(` or `)]` but is not a valid
416
+ * standalone two-way ref (exact form `[(refPath)]`). Mixing two-way with literals or {{ }} is invalid.
417
+ */
418
+ declare function isInvalidTwoWayMix(value: unknown): value is string;
419
+ /**
420
+ * One trim + one pass: classify string for two-way ref handling. Use instead of calling
421
+ * isInvalidTwoWayMix and isTwoWayRefString separately to avoid double trim/regex.
422
+ */
423
+ declare function classifyTwoWayString(value: unknown): 'two-way' | 'invalid-mix' | 'none';
424
+ declare function parseTwoWayRef(value: string): string | null;
425
+ declare function getRefPathFromReadonly(template: string, match: string): string;
426
+
427
+ interface ResolverContext {
428
+ registry: BlockRegistry;
429
+ /** Current block's full id (nearest block with id). */
430
+ currentBlockId?: string;
431
+ /** Current block's instance (services/state by name). */
432
+ currentInstance?: Record<string, unknown>;
433
+ }
434
+ /**
435
+ * Resolve a ref path to the target object and path.
436
+ * Path format: "instance.FormState.firstName" (context) or "UserForm.instance.FormState.firstName" (registry).
437
+ */
438
+ declare function resolveRefPath(refPath: string, ctx: ResolverContext): {
439
+ target: unknown;
440
+ path: string[];
441
+ } | null;
442
+ /**
443
+ * Get value at ref path (read-only). Returns undefined if not found.
444
+ */
445
+ declare function getRefValue(refPath: string, ctx: ResolverContext): unknown;
446
+ /**
447
+ * Set value at ref path (write). No-op if target is not writable.
448
+ */
449
+ declare function setRefValue(refPath: string, ctx: ResolverContext, value: unknown): void;
450
+ /**
451
+ * Build a computed signal for a template string with {{refPath}} placeholders.
452
+ */
453
+ declare function buildComputedForTemplate(template: string, refPaths: string[], ctx: ResolverContext): Signal<string>;
454
+
455
+ declare function resolveOutputReference(ref: OutputReference, eventValue: unknown, registry: BlockRegistry): (value: unknown) => void;
456
+ declare function createOutputHandler(outputValue: unknown, outputKey: string, registry: BlockRegistry, directiveHandlers?: Record<string, (value: unknown) => void>): (value: unknown) => void;
457
+
458
+ interface BlockLoadOptions {
459
+ outputHandlers?: Record<string, (value: unknown) => void>;
460
+ registry?: BlockRegistry;
461
+ /** Map of block id → full description; used when description is an id-only reference. */
462
+ blockDefinitions?: Record<string, unknown>;
463
+ }
464
+ interface BlockLoadResult {
465
+ componentRef: ComponentRef<unknown>;
466
+ destroy: () => void;
467
+ updateInputs: (description: unknown) => void;
468
+ }
469
+ declare class BlockLoaderService {
470
+ private readonly injector;
471
+ private readonly componentRegistry;
472
+ private readonly serviceRegistry;
473
+ load(description: unknown, viewContainerRef: ViewContainerRef, options?: BlockLoadOptions): Promise<BlockLoadResult>;
474
+ /** Resolve all service types in parallel (single batch for load). */
475
+ private getServiceTypes;
476
+ private buildChildInjectorFromTypes;
477
+ /** Set inputs and wire template/two-way effects. Single pass over inputs for large configs. */
478
+ private setInputs;
479
+ /** Replace all {{ refPath }} with resolved values. Uses parts array + join to avoid N string concats. */
480
+ private static readonly INTERPOLATE_MAX_PLACEHOLDERS;
481
+ private interpolateTemplate;
482
+ /**
483
+ * Resolve a single input value: resolve two-way refs, recurse into arrays/objects.
484
+ * Strings with {{ }} are left as-is so child blocks receive the template for reactive interpolation.
485
+ * Two-way refs inside nested block descriptors (object with "component" + "inputs") are left as-is
486
+ * so that when a child block is loaded it still sees value: '[(ref)]' and can wire two-way binding.
487
+ */
488
+ private resolveInputValue;
489
+ private wireOutputs;
490
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<BlockLoaderService, never>;
491
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<BlockLoaderService>;
492
+ }
493
+
494
+ declare class BlockDirective {
495
+ private readonly viewContainerRef;
496
+ private readonly loader;
497
+ private readonly destroyRef;
498
+ /** Full description, or { id } / { blockId, blockDefinition? } to reuse/override from blockDefinitions. */
499
+ readonly description: _angular_core.InputSignal<unknown>;
500
+ /** Handlers for component outputs; keys match descriptor.outputs. */
501
+ readonly outputHandlers: _angular_core.InputSignal<Record<string, (value: unknown) => void>>;
502
+ /** Registry for block instances by id; pass from root so nested blocks share it. */
503
+ readonly blockRegistry: _angular_core.InputSignal<BlockRegistry | null>;
504
+ /** Map id → full description; used when description is a block reference (id/blockId). */
505
+ readonly blockDefinitions: _angular_core.InputSignal<Record<string, unknown> | null>;
506
+ private loadResult;
507
+ private loadedComponent;
508
+ private loadedServicesKey;
509
+ private loadGeneration;
510
+ /** Avoid re-parsing when the same description reference is passed (e.g. stable signal). */
511
+ private lastDescRef;
512
+ private lastParsedData;
513
+ constructor();
514
+ private clear;
515
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<BlockDirective, never>;
516
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BlockDirective, "[block]", never, { "description": { "alias": "description"; "required": false; "isSignal": true; }; "outputHandlers": { "alias": "outputHandlers"; "required": false; "isSignal": true; }; "blockRegistry": { "alias": "blockRegistry"; "required": false; "isSignal": true; }; "blockDefinitions": { "alias": "blockDefinitions"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
517
+ }
518
+
519
+ export { BlockDefinitionsRegistry, BlockDescriptionSchema, BlockDirective, BlockLoaderService, BlockRegistryImpl, ComponentRegistry, GuardRegistry, RegistryMetadataStore, RouteLoader, ServiceRegistry, buildComputedForTemplate, classifyTwoWayString, createOutputHandler, deepMergeBlockDefinition, extractReadonlyRefs, getRefPathFromReadonly, getRefValue, isBlockReference, isIdReference, isInvalidTwoWayMix, isOutputReference, isTwoWayRefString, normalizeServices, parseBlockDescription, parseRefPath, parseTwoWayRef, resolveBlockReference, resolveOutputReference, resolveRefPath, safeParseBlockDescription, setRefValue };
520
+ export type { AllRegistryMetadata, BlockDescription, BlockInstanceHandle, BlockLoadOptions, BlockLoadResult, BlockReference, BlockRegistry, GuardLoader, GuardOrLoader, GuardOrType, OutputReference, ParsedRefPath, RegistryEntryType, RegistryMetadataRecord, ResolverContext, RouteConfig, ServiceEntry };