ngx-blocks-studio 0.0.15 → 0.1.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.
- package/README.md +149 -10
- package/fesm2022/ngx-blocks-studio.mjs +1070 -262
- package/fesm2022/ngx-blocks-studio.mjs.map +1 -1
- package/package.json +15 -7
- package/types/ngx-blocks-studio.d.ts +248 -149
package/package.json
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ngx-blocks-studio",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/winghei/ngx-blocks-studio.git"
|
|
7
|
+
},
|
|
8
|
+
"bugs": {
|
|
9
|
+
"url": "https://github.com/winghei/ngx-blocks-studio/issues"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/winghei/ngx-blocks-studio#readme",
|
|
4
12
|
"peerDependencies": {
|
|
5
|
-
"@angular/common": "^
|
|
6
|
-
"@angular/core": "^
|
|
7
|
-
"@angular/router": "^
|
|
13
|
+
"@angular/common": "^22.0.0",
|
|
14
|
+
"@angular/core": "^22.0.0",
|
|
15
|
+
"@angular/router": "^22.0.0",
|
|
8
16
|
"rxjs": "^7.0.0"
|
|
9
17
|
},
|
|
10
18
|
"dependencies": {
|
|
11
|
-
"tslib": "^2.3.0"
|
|
12
|
-
"zod": "^4.0.0"
|
|
19
|
+
"tslib": "^2.3.0"
|
|
13
20
|
},
|
|
14
21
|
"sideEffects": false,
|
|
15
22
|
"module": "fesm2022/ngx-blocks-studio.mjs",
|
|
@@ -22,5 +29,6 @@
|
|
|
22
29
|
"types": "./types/ngx-blocks-studio.d.ts",
|
|
23
30
|
"default": "./fesm2022/ngx-blocks-studio.mjs"
|
|
24
31
|
}
|
|
25
|
-
}
|
|
32
|
+
},
|
|
33
|
+
"type": "module"
|
|
26
34
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
2
|
import { Type, Injector, Signal, ViewContainerRef, ComponentRef } from '@angular/core';
|
|
3
3
|
import { CanActivateFn, RunGuardsAndResolvers } from '@angular/router';
|
|
4
|
-
import { z } from 'zod';
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* Registry entry type: component, service, guard, directive, or block definition.
|
|
@@ -310,88 +309,157 @@ declare class RouteLoader {
|
|
|
310
309
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<RouteLoader>;
|
|
311
310
|
}
|
|
312
311
|
|
|
312
|
+
interface CurrentInstance {
|
|
313
|
+
model?: Signal<unknown>;
|
|
314
|
+
/**
|
|
315
|
+
* Services/state exposed by name for ref/expression resolution.
|
|
316
|
+
* (Kept separate from `model` to avoid alias collisions.)
|
|
317
|
+
*/
|
|
318
|
+
services: Record<string, unknown>;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Handle for a registered block: exposes instance (services/state by name) for ref resolution.
|
|
322
|
+
*/
|
|
323
|
+
interface BlockInstanceHandle {
|
|
324
|
+
/** Instance: services and state by name (e.g. FormState, value). */
|
|
325
|
+
instance: CurrentInstance;
|
|
326
|
+
/** Optional cleanup when block is destroyed. */
|
|
327
|
+
destroy?: () => void;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Registry of block instances by (full) id within a tree.
|
|
331
|
+
* One registry per logical tree; duplicate id throws.
|
|
332
|
+
*/
|
|
333
|
+
interface BlockRegistry {
|
|
334
|
+
register(id: string, handle: BlockInstanceHandle): void;
|
|
335
|
+
unregister(id: string): void;
|
|
336
|
+
get(id: string): BlockInstanceHandle | undefined;
|
|
337
|
+
/** True if id resolves in this registry or any parent (for refs). */
|
|
338
|
+
has(id: string): boolean;
|
|
339
|
+
/** True only if id is registered on this registry layer (not parent). Used before register. */
|
|
340
|
+
hasLocal(id: string): boolean;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Registry that chains lookups to a parent registry (lexical scoping).
|
|
344
|
+
* Registration/unregistration always happens on the local registry only.
|
|
345
|
+
*/
|
|
346
|
+
declare class ChainedBlockRegistry implements BlockRegistry {
|
|
347
|
+
private readonly local;
|
|
348
|
+
private readonly parent;
|
|
349
|
+
constructor(local: BlockRegistry, parent: BlockRegistry | null);
|
|
350
|
+
register(id: string, handle: BlockInstanceHandle): void;
|
|
351
|
+
unregister(id: string): void;
|
|
352
|
+
get(id: string): BlockInstanceHandle | undefined;
|
|
353
|
+
has(id: string): boolean;
|
|
354
|
+
hasLocal(id: string): boolean;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Default in-memory BlockRegistry.
|
|
358
|
+
*/
|
|
359
|
+
declare class BlockRegistryImpl implements BlockRegistry {
|
|
360
|
+
private readonly map;
|
|
361
|
+
register(id: string, handle: BlockInstanceHandle): void;
|
|
362
|
+
unregister(id: string): void;
|
|
363
|
+
get(id: string): BlockInstanceHandle | undefined;
|
|
364
|
+
has(id: string): boolean;
|
|
365
|
+
hasLocal(id: string): boolean;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
interface ScopedRegistryNode {
|
|
369
|
+
registry: BlockRegistry;
|
|
370
|
+
parentScopeKey: string | null;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Holds named block registries (e.g. `root` for a route outlet, scoped keys for list items/columns).
|
|
374
|
+
* This enables explicit cross-scope ref resolution like `ScopeKey/BlockId:model.title`.
|
|
375
|
+
*/
|
|
376
|
+
declare class BlockRegistryService {
|
|
377
|
+
readonly registry: Map<string, ScopedRegistryNode>;
|
|
378
|
+
setScopedRegistry(key: string, reg: BlockRegistry, parentScopeKey?: string | null): void;
|
|
379
|
+
removeScopedRegistry(key: string): void;
|
|
380
|
+
getRegistryForScope(scopeKey: string): BlockRegistry | null;
|
|
381
|
+
getParentScopeKey(scopeKey: string): string | null;
|
|
382
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BlockRegistryService, never>;
|
|
383
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<BlockRegistryService>;
|
|
384
|
+
}
|
|
385
|
+
|
|
313
386
|
/**
|
|
314
387
|
* Service entry: root-scoped (string id or { id, alias? } with no scope) or self-scoped ({ id, scope: "self", alias? }).
|
|
315
388
|
* When scope is omitted or undefined, the service is resolved from the root injector.
|
|
316
389
|
*/
|
|
317
|
-
|
|
318
|
-
id:
|
|
319
|
-
scope
|
|
320
|
-
alias
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
*
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
params
|
|
330
|
-
then
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
390
|
+
type ServiceEntry = string | {
|
|
391
|
+
id: string;
|
|
392
|
+
scope?: 'self';
|
|
393
|
+
alias?: string;
|
|
394
|
+
};
|
|
395
|
+
/**
|
|
396
|
+
* After the parent call succeeds, run `then` in order. Each step may nest `then` (runs after that step,
|
|
397
|
+
* before the next sibling). Step is a callable ref string (`Block:path.method`) or an object with `ref` plus options.
|
|
398
|
+
*/
|
|
399
|
+
type ThenChainStep = string | {
|
|
400
|
+
ref: string;
|
|
401
|
+
when?: unknown;
|
|
402
|
+
params?: unknown[] | Record<string, unknown>;
|
|
403
|
+
then?: ThenChainStep[];
|
|
404
|
+
};
|
|
405
|
+
interface OutputOnError {
|
|
406
|
+
ref: string;
|
|
407
|
+
when?: unknown;
|
|
408
|
+
params?: unknown[] | Record<string, unknown>;
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Object form when `params`, `when`, `then`, or `onError` are needed. `ref` is a full callable path
|
|
412
|
+
* (`Block:service.path.method` — last dot segment is the method name).
|
|
413
|
+
*/
|
|
414
|
+
interface OutputCallObject {
|
|
415
|
+
ref: string;
|
|
416
|
+
when?: unknown;
|
|
417
|
+
params?: unknown[] | Record<string, unknown>;
|
|
418
|
+
then?: ThenChainStep[];
|
|
419
|
+
onError?: OutputOnError;
|
|
420
|
+
}
|
|
421
|
+
type BlockOutputValue = string | OutputCallObject;
|
|
422
|
+
/** Raw block description input (optional fields may be omitted; defaults applied after validation). */
|
|
423
|
+
interface BlockInput {
|
|
424
|
+
component: string;
|
|
425
|
+
id?: string;
|
|
426
|
+
services?: ServiceEntry | ServiceEntry[];
|
|
427
|
+
directives?: string | string[];
|
|
428
|
+
inputs?: Record<string, unknown>;
|
|
429
|
+
outputs?: Record<string, BlockOutputValue>;
|
|
430
|
+
}
|
|
346
431
|
/**
|
|
347
432
|
* Block description: JSON-serializable descriptor for dynamic block loading.
|
|
348
433
|
* Refs in inputs: "model.info.title" (current block) or "BlockID:model.info.title" (block id + service/model + path).
|
|
349
434
|
*/
|
|
350
|
-
|
|
351
|
-
component:
|
|
352
|
-
id
|
|
353
|
-
services:
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
params: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
|
|
373
|
-
}, z.core.$strip>>>;
|
|
374
|
-
onSuccess: z.ZodOptional<z.ZodObject<{
|
|
375
|
-
reference: z.ZodString;
|
|
376
|
-
method: z.ZodString;
|
|
377
|
-
params: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
|
|
378
|
-
}, z.core.$strip>>;
|
|
379
|
-
onError: z.ZodOptional<z.ZodObject<{
|
|
380
|
-
reference: z.ZodString;
|
|
381
|
-
method: z.ZodString;
|
|
382
|
-
params: z.ZodOptional<z.ZodUnion<readonly [z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
|
|
383
|
-
}, z.core.$strip>>;
|
|
384
|
-
}, z.core.$strip>]>>>;
|
|
385
|
-
}, z.core.$strip>;
|
|
386
|
-
type BlockDescription = z.infer<typeof BlockDescriptionSchema>;
|
|
387
|
-
type BlockInput = z.input<typeof BlockDescriptionSchema>;
|
|
388
|
-
type ServiceEntry = z.infer<typeof ServiceEntrySchema>;
|
|
389
|
-
type OutputReference = z.infer<typeof OutputReferenceSchema>;
|
|
435
|
+
interface BlockDescription {
|
|
436
|
+
component: string;
|
|
437
|
+
id?: string;
|
|
438
|
+
services: ServiceEntry[];
|
|
439
|
+
directives: string | string[];
|
|
440
|
+
inputs?: Record<string, unknown>;
|
|
441
|
+
outputs?: Record<string, BlockOutputValue>;
|
|
442
|
+
}
|
|
443
|
+
type SafeParseBlockDescriptionResult = {
|
|
444
|
+
success: true;
|
|
445
|
+
data: BlockDescription;
|
|
446
|
+
} | {
|
|
447
|
+
success: false;
|
|
448
|
+
error: {
|
|
449
|
+
message: string;
|
|
450
|
+
};
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
declare function safeParseBlockDescription(data: unknown): SafeParseBlockDescriptionResult;
|
|
454
|
+
|
|
455
|
+
/** @deprecated Use OutputCallObject */
|
|
456
|
+
type OutputReference = OutputCallObject;
|
|
390
457
|
/** Normalize services to array. */
|
|
391
458
|
declare function normalizeServices(services: BlockDescription['services']): ServiceEntry[];
|
|
392
459
|
/** Normalize directives to array of directive ids. */
|
|
393
460
|
declare function normalizeDirectives(directives: BlockDescription['directives']): string[];
|
|
394
|
-
declare function
|
|
461
|
+
declare function isOutputCallObject(value: unknown): value is OutputCallObject;
|
|
462
|
+
/** @deprecated Use isOutputCallObject */
|
|
395
463
|
declare function isOutputReference(value: unknown): value is OutputReference;
|
|
396
464
|
/**
|
|
397
465
|
* Reference to a registered block: { blockId: string, blockDefinition?: object }.
|
|
@@ -425,44 +493,12 @@ declare function deepMergeBlockDefinition(base: Record<string, unknown>, overrid
|
|
|
425
493
|
*/
|
|
426
494
|
declare function resolveBlockReference(ref: BlockReference, blockDefinitions: Record<string, BlockDefinitionOrLoader> | null | undefined): Promise<Record<string, unknown>>;
|
|
427
495
|
|
|
428
|
-
interface CurrentInstance {
|
|
429
|
-
model?: Signal<unknown>;
|
|
430
|
-
[key: string]: unknown;
|
|
431
|
-
}
|
|
432
|
-
/**
|
|
433
|
-
* Handle for a registered block: exposes instance (services/state by name) for ref resolution.
|
|
434
|
-
*/
|
|
435
|
-
interface BlockInstanceHandle {
|
|
436
|
-
/** Instance: services and state by name (e.g. FormState, value). */
|
|
437
|
-
instance: CurrentInstance;
|
|
438
|
-
/** Optional cleanup when block is destroyed. */
|
|
439
|
-
destroy?: () => void;
|
|
440
|
-
}
|
|
441
|
-
/**
|
|
442
|
-
* Registry of block instances by (full) id within a tree.
|
|
443
|
-
* One registry per logical tree; duplicate id throws.
|
|
444
|
-
*/
|
|
445
|
-
interface BlockRegistry {
|
|
446
|
-
register(id: string, handle: BlockInstanceHandle): void;
|
|
447
|
-
unregister(id: string): void;
|
|
448
|
-
get(id: string): BlockInstanceHandle | undefined;
|
|
449
|
-
has(id: string): boolean;
|
|
450
|
-
}
|
|
451
|
-
/**
|
|
452
|
-
* Default in-memory BlockRegistry.
|
|
453
|
-
*/
|
|
454
|
-
declare class BlockRegistryImpl implements BlockRegistry {
|
|
455
|
-
private readonly map;
|
|
456
|
-
register(id: string, handle: BlockInstanceHandle): void;
|
|
457
|
-
unregister(id: string): void;
|
|
458
|
-
get(id: string): BlockInstanceHandle | undefined;
|
|
459
|
-
has(id: string): boolean;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
496
|
/**
|
|
463
497
|
* Parse ref paths and detect {{ref}} (read-only) and [(ref)] (two-way) in strings.
|
|
464
498
|
*/
|
|
465
499
|
interface ParsedRefPath {
|
|
500
|
+
/** Optional scope key prefix for cross-scope refs: `ScopeKey/BlockId:...` */
|
|
501
|
+
scopeKey?: string;
|
|
466
502
|
blockId?: string;
|
|
467
503
|
serviceOrModel: string;
|
|
468
504
|
pathParts: string[];
|
|
@@ -489,6 +525,8 @@ interface ResolverContext {
|
|
|
489
525
|
currentBlockId?: string;
|
|
490
526
|
/** Current block's instance (services/state by name). */
|
|
491
527
|
currentInstance?: CurrentInstance;
|
|
528
|
+
/** Optional scope-key → registry lookup for explicit `ScopeKey/BlockId:...` refs. */
|
|
529
|
+
getRegistryForScope?: (scopeKey: string) => BlockRegistry | null;
|
|
492
530
|
}
|
|
493
531
|
/**
|
|
494
532
|
* Resolve a ref path to the target object and path.
|
|
@@ -525,11 +563,98 @@ declare function setRefValue(refPath: string, ctx: ResolverContext, value: unkno
|
|
|
525
563
|
*/
|
|
526
564
|
declare function buildComputedForTemplate(template: string, refPaths: string[], ctx: ResolverContext): Signal<string>;
|
|
527
565
|
|
|
528
|
-
|
|
529
|
-
|
|
566
|
+
/** AST node types for flow template */
|
|
567
|
+
type FlowNode = {
|
|
568
|
+
type: 'text';
|
|
569
|
+
value: string;
|
|
570
|
+
} | {
|
|
571
|
+
type: 'ref';
|
|
572
|
+
refPath: string;
|
|
573
|
+
} | {
|
|
574
|
+
type: 'if';
|
|
575
|
+
refPath: string;
|
|
576
|
+
body: FlowNode[];
|
|
577
|
+
elseBody?: FlowNode[];
|
|
578
|
+
} | {
|
|
579
|
+
type: 'for';
|
|
580
|
+
itemVar: string;
|
|
581
|
+
refPath: string;
|
|
582
|
+
body: FlowNode[];
|
|
583
|
+
};
|
|
584
|
+
/** Scope for @for (e.g. item, $index) */
|
|
585
|
+
interface FlowScope {
|
|
586
|
+
[key: string]: unknown;
|
|
587
|
+
}
|
|
588
|
+
interface InterpretFlowOptions {
|
|
589
|
+
/**
|
|
590
|
+
* Called for each `text` node (e.g. to expand `{{ }}` inside flow bodies).
|
|
591
|
+
* Defaults to identity.
|
|
592
|
+
*/
|
|
593
|
+
interpolateText?: (segment: string) => string;
|
|
594
|
+
/**
|
|
595
|
+
* When set, `@if (…)` evaluates this instead of `resolveRefOrModel` (e.g. safe expressions + payload).
|
|
596
|
+
*/
|
|
597
|
+
resolveCondition?: (expression: string, scope: FlowScope) => unknown;
|
|
598
|
+
/**
|
|
599
|
+
* When false, `${…}` values are appended without HTML escaping (e.g. output handler params). Default true.
|
|
600
|
+
*/
|
|
601
|
+
escapeRefValues?: boolean;
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* Parses a flow template string into an AST.
|
|
605
|
+
* Supports: ${refPath}, @if (refPath) { ... }, @else { ... }, @for (item of refPath) { ... }
|
|
606
|
+
*/
|
|
607
|
+
declare function parseFlowTemplate(template: string): FlowNode[];
|
|
608
|
+
/** Collect all ref paths used in the AST (for reactivity). */
|
|
609
|
+
declare function collectRefPaths(nodes: FlowNode[]): Set<string>;
|
|
610
|
+
/**
|
|
611
|
+
* Same resolution rules as `interpolateTemplateMixed` for refs: named block ref, else current block `model` path.
|
|
612
|
+
*/
|
|
613
|
+
declare function resolveRefOrModel(refPath: string, ctx: ResolverContext): unknown;
|
|
614
|
+
/**
|
|
615
|
+
* Interprets the AST with the given resolver context and optional scope (e.g. item, $index).
|
|
616
|
+
* Escapes interpolated values for safe innerHTML.
|
|
617
|
+
*/
|
|
618
|
+
declare function interpretFlow(nodes: FlowNode[], ctx: ResolverContext, scope?: FlowScope, options?: InterpretFlowOptions): string;
|
|
619
|
+
/** True if the string uses flow syntax (not plain `{{ }}` only). */
|
|
620
|
+
declare function looksLikeFlowTemplate(s: string): boolean;
|
|
621
|
+
|
|
622
|
+
declare function resolveReferenceValue(ref: string, ctx: ResolverContext): unknown;
|
|
623
|
+
/**
|
|
624
|
+
* Safe expression evaluation (same as output `{{ }}` / `@if (...)` when used with this module).
|
|
625
|
+
* Falls back to `resolveReferenceValue` if parsing fails (treat whole string as a ref path).
|
|
626
|
+
*/
|
|
627
|
+
declare function evaluateExpression(expression: string, ctx: ResolverContext, payload: unknown): unknown;
|
|
628
|
+
/**
|
|
629
|
+
* Resolves only `{{ … }}` segments via `evaluateExpression`.
|
|
630
|
+
* Single full-string `{{ expr }}` preserves the evaluated type; mixed templates return a string.
|
|
631
|
+
*/
|
|
632
|
+
declare function resolveMustacheInterpolatedString(value: string, ctx: ResolverContext, payload: unknown): unknown;
|
|
633
|
+
declare function mustacheSegmentToString(segment: string, ctx: ResolverContext, payload: unknown): string;
|
|
634
|
+
interface ResolveTemplateStringOptions {
|
|
635
|
+
/**
|
|
636
|
+
* When true (default), `${…}` in flow output is HTML-escaped (block / innerHTML-friendly).
|
|
637
|
+
* Set false for plain strings (e.g. output handler method params).
|
|
638
|
+
*/
|
|
639
|
+
escapeFlowRefs?: boolean;
|
|
640
|
+
}
|
|
641
|
+
/**
|
|
642
|
+
* Unified template resolution: flow (`@if`, `@for`, `${}`) plus `{{ }}` in flow text segments.
|
|
643
|
+
* `@if` conditions use `evaluateExpression` (safe expressions + ref fallback).
|
|
644
|
+
*/
|
|
645
|
+
declare function resolveTemplateString(value: string, ctx: ResolverContext, payload?: unknown, options?: ResolveTemplateStringOptions): unknown;
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Split `Block:path.to.method` or `service.path.method` (current block) into ref path + method name.
|
|
649
|
+
* Last dot-separated segment after `:` is the method; before that is the ref path.
|
|
650
|
+
*/
|
|
651
|
+
declare function splitCallableRef(fullPath: string): {
|
|
652
|
+
refPath: string;
|
|
653
|
+
method: string;
|
|
654
|
+
} | null;
|
|
655
|
+
declare function createOutputHandler(outputValue: unknown, _outputKey: string, ctx: ResolverContext): (value: unknown) => void;
|
|
530
656
|
|
|
531
657
|
interface BlockLoadOptions {
|
|
532
|
-
outputHandlers?: Record<string, (value: unknown) => void>;
|
|
533
658
|
registry?: BlockRegistry;
|
|
534
659
|
/** Map of block id → full description or loader; used when description is a block reference. */
|
|
535
660
|
blockDefinitions?: Record<string, BlockDefinitionOrLoader>;
|
|
@@ -539,6 +664,7 @@ declare class BlockLoaderService {
|
|
|
539
664
|
private readonly componentRegistry;
|
|
540
665
|
private readonly directiveRegistry;
|
|
541
666
|
private readonly serviceRegistry;
|
|
667
|
+
private readonly blockRegistryService;
|
|
542
668
|
load(description: BlockInput | BlockReference, viewContainerRef: ViewContainerRef, model: Signal<unknown | undefined>, options?: BlockLoadOptions): Promise<ComponentRef<unknown>>;
|
|
543
669
|
private resolveServices;
|
|
544
670
|
private buildChildInjectorFromTypes;
|
|
@@ -548,6 +674,9 @@ declare class BlockLoaderService {
|
|
|
548
674
|
private getDirectiveTypes;
|
|
549
675
|
/** Resolve model from desc (interpolate ref if string) and set on blockInstance. */
|
|
550
676
|
private resolveContextModel;
|
|
677
|
+
private valueContainsTemplate;
|
|
678
|
+
private resolveNestedModelTemplates;
|
|
679
|
+
private withModelOverrideContext;
|
|
551
680
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BlockLoaderService, never>;
|
|
552
681
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<BlockLoaderService>;
|
|
553
682
|
}
|
|
@@ -557,55 +686,25 @@ declare class BlockDirective {
|
|
|
557
686
|
private readonly loader;
|
|
558
687
|
private readonly destroyRef;
|
|
559
688
|
/** Full description, or { id } / { blockId, blockDefinition? } to reuse/override from blockDefinitions. */
|
|
560
|
-
readonly description: _angular_core.InputSignal<
|
|
561
|
-
component: string;
|
|
562
|
-
id?: string | undefined;
|
|
563
|
-
services?: string | {
|
|
564
|
-
id: string;
|
|
565
|
-
scope?: "self" | undefined;
|
|
566
|
-
alias?: string | undefined;
|
|
567
|
-
} | (string | {
|
|
568
|
-
id: string;
|
|
569
|
-
scope?: "self" | undefined;
|
|
570
|
-
alias?: string | undefined;
|
|
571
|
-
})[] | undefined;
|
|
572
|
-
directives?: string | string[] | undefined;
|
|
573
|
-
inputs?: Record<string, unknown> | undefined;
|
|
574
|
-
outputs?: Record<string, Record<string, unknown> | {
|
|
575
|
-
type: "reference";
|
|
576
|
-
reference: string;
|
|
577
|
-
method: string;
|
|
578
|
-
params?: Record<string, unknown> | unknown[] | undefined;
|
|
579
|
-
then?: {
|
|
580
|
-
reference: string;
|
|
581
|
-
method: string;
|
|
582
|
-
params?: Record<string, unknown> | unknown[] | undefined;
|
|
583
|
-
}[] | undefined;
|
|
584
|
-
onSuccess?: {
|
|
585
|
-
reference: string;
|
|
586
|
-
method: string;
|
|
587
|
-
params?: Record<string, unknown> | unknown[] | undefined;
|
|
588
|
-
} | undefined;
|
|
589
|
-
onError?: {
|
|
590
|
-
reference: string;
|
|
591
|
-
method: string;
|
|
592
|
-
params?: Record<string, unknown> | unknown[] | undefined;
|
|
593
|
-
} | undefined;
|
|
594
|
-
}> | undefined;
|
|
595
|
-
} | BlockReference | null>;
|
|
596
|
-
/** Handlers for component outputs; keys match descriptor.outputs. */
|
|
597
|
-
readonly outputHandlers: _angular_core.InputSignal<Record<string, (value: unknown) => void>>;
|
|
689
|
+
readonly description: _angular_core.InputSignal<BlockInput | BlockReference | null>;
|
|
598
690
|
/** Registry for block instances by id; pass from root so nested blocks share it. */
|
|
599
691
|
readonly blockRegistry: _angular_core.InputSignal<BlockRegistry | null>;
|
|
600
692
|
/** Map id → full description or loader; used when description is a block reference (id/blockId). */
|
|
601
693
|
readonly blockDefinitions: _angular_core.InputSignal<Record<string, BlockDefinitionOrLoader> | null>;
|
|
602
694
|
/** Model for the block. */
|
|
603
695
|
readonly model: _angular_core.InputSignal<string | Record<string, unknown> | undefined>;
|
|
696
|
+
/**
|
|
697
|
+
* Forces a reload when this value changes, even if component/services are the same.
|
|
698
|
+
* Useful for "same component, different inputs" scenarios like tabs/switch blocks.
|
|
699
|
+
*/
|
|
700
|
+
readonly reloadKey: _angular_core.InputSignal<unknown>;
|
|
604
701
|
private loadResult;
|
|
605
702
|
private lastRegistry;
|
|
606
703
|
private lastId;
|
|
607
704
|
private loadedComponent;
|
|
608
705
|
private loadedServicesKey;
|
|
706
|
+
private loadedReloadKey;
|
|
707
|
+
private loadedDescKey;
|
|
609
708
|
private loadGeneration;
|
|
610
709
|
/** Invalidates in-flight block-reference resolution when the effect re-runs. */
|
|
611
710
|
private effectRunId;
|
|
@@ -615,8 +714,8 @@ declare class BlockDirective {
|
|
|
615
714
|
constructor();
|
|
616
715
|
private clear;
|
|
617
716
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<BlockDirective, never>;
|
|
618
|
-
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BlockDirective, "[block]", never, { "description": { "alias": "description"; "required": false; "isSignal": true; }; "
|
|
717
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<BlockDirective, "[block]", never, { "description": { "alias": "description"; "required": false; "isSignal": true; }; "blockRegistry": { "alias": "blockRegistry"; "required": false; "isSignal": true; }; "blockDefinitions": { "alias": "blockDefinitions"; "required": false; "isSignal": true; }; "model": { "alias": "model"; "required": false; "isSignal": true; }; "reloadKey": { "alias": "reloadKey"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
619
718
|
}
|
|
620
719
|
|
|
621
|
-
export { BlockDefinitionsRegistry,
|
|
622
|
-
export type { AllRegistryMetadata, BlockDefinitionLoader, BlockDefinitionOrLoader, BlockDescription, BlockInput, BlockInstanceHandle, BlockLoadOptions, BlockReference, BlockRegistry, CurrentInstance, GuardLoader, GuardOrLoader, GuardOrType, OutputReference, ParsedRefPath, RegistryEntryType, RegistryMetadataRecord, ResolverContext, RouteConfig, ServiceEntry };
|
|
720
|
+
export { BlockDefinitionsRegistry, BlockDirective, BlockLoaderService, BlockRegistryImpl, BlockRegistryService, ChainedBlockRegistry, ComponentRegistry, DirectiveRegistry, GuardRegistry, INTERPOLATE_MAX_PLACEHOLDERS, RegistryMetadataStore, RouteLoader, ServiceRegistry, buildComputedForTemplate, classifyTwoWayString, collectRefPaths, createOutputHandler, deepMergeBlockDefinition, evaluateExpression, extractReadonlyRefs, getRefPathFromReadonly, getRefSignal, getRefValue, getValueByPath, interpretFlow, isBlockDefinitionLoader, isBlockReference, isInvalidTwoWayMix, isOutputCallObject, isOutputReference, isTwoWayRefString, looksLikeFlowTemplate, mustacheSegmentToString, normalizeDirectives, normalizeServices, parseFlowTemplate, parseRefPath, parseTwoWayRef, refPathResolvesToSignal, resolveBlockReference, resolveMustacheInterpolatedString, resolveRefOrModel, resolveRefPath, resolveReferenceValue, resolveTemplateString, safeParseBlockDescription, setRefValue, splitCallableRef };
|
|
721
|
+
export type { AllRegistryMetadata, BlockDefinitionLoader, BlockDefinitionOrLoader, BlockDescription, BlockInput, BlockInstanceHandle, BlockLoadOptions, BlockOutputValue, BlockReference, BlockRegistry, CurrentInstance, FlowNode, FlowScope, GuardLoader, GuardOrLoader, GuardOrType, InterpretFlowOptions, OutputCallObject, OutputOnError, OutputReference, ParsedRefPath, RegistryEntryType, RegistryMetadataRecord, ResolveTemplateStringOptions, ResolverContext, RouteConfig, RouteConfigs, SafeParseBlockDescriptionResult, ScopedRegistryNode, ServiceEntry, ThenChainStep };
|