@fgv/ts-res 5.0.1-0 → 5.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/dist/ts-res.d.ts +211 -0
- package/lib/packlets/common/resources.d.ts +4 -0
- package/lib/packlets/resources/deltaGenerator.d.ts +189 -0
- package/lib/packlets/resources/deltaGenerator.js +344 -0
- package/lib/packlets/resources/index.d.ts +1 -0
- package/lib/packlets/resources/index.js +1 -0
- package/lib/packlets/resources/resourceManagerBuilder.d.ts +4 -0
- package/lib/packlets/resources/resourceManagerBuilder.js +6 -0
- package/lib/packlets/runtime/compiledResourceCollection.d.ts +4 -0
- package/lib/packlets/runtime/compiledResourceCollection.js +6 -0
- package/lib/packlets/runtime/iResourceManager.d.ts +4 -0
- package/lib/packlets/runtime/resourceResolver.d.ts +5 -1
- package/lib/packlets/runtime/resourceResolver.js +6 -0
- package/package.json +7 -7
package/dist/ts-res.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { IReadOnlyResultMap } from '@fgv/ts-utils';
|
|
|
10
10
|
import { JsonCompatible } from '@fgv/ts-json-base';
|
|
11
11
|
import { JsonObject } from '@fgv/ts-json-base';
|
|
12
12
|
import { JsonValue } from '@fgv/ts-json-base';
|
|
13
|
+
import { Logging } from '@fgv/ts-utils';
|
|
13
14
|
import { ObjectConverter } from '@fgv/ts-utils';
|
|
14
15
|
import { Result } from '@fgv/ts-utils';
|
|
15
16
|
import { ResultMap } from '@fgv/ts-utils';
|
|
@@ -995,6 +996,10 @@ declare class CompiledResourceCollection implements IResourceManager<IResource>
|
|
|
995
996
|
* contains the {@link Qualifiers.Qualifier | qualifiers} used in this collection.
|
|
996
997
|
*/
|
|
997
998
|
get qualifiers(): IReadOnlyQualifierCollector;
|
|
999
|
+
/**
|
|
1000
|
+
* The resource IDs contained in this compiled resource collection.
|
|
1001
|
+
*/
|
|
1002
|
+
get resourceIds(): ReadonlyArray<ResourceId>;
|
|
998
1003
|
/**
|
|
999
1004
|
* A {@link ResourceTypes.ResourceTypeCollector | ResourceTypeCollector} which
|
|
1000
1005
|
* contains the {@link ResourceTypes.ResourceType | resource types} used in this collection.
|
|
@@ -2552,6 +2557,150 @@ declare const DefaultResourceTypes: ReadonlyArray<ResourceTypes.Config.IResource
|
|
|
2552
2557
|
*/
|
|
2553
2558
|
declare const DefaultSystemConfiguration: ISystemConfiguration;
|
|
2554
2559
|
|
|
2560
|
+
/**
|
|
2561
|
+
* Class for generating resource deltas between baseline and delta resolvers.
|
|
2562
|
+
* Creates partial/augment candidates for updated resources and full/replace candidates for new resources.
|
|
2563
|
+
* Uses Diff.jsonThreeWayDiff for efficient delta computation.
|
|
2564
|
+
* @public
|
|
2565
|
+
*/
|
|
2566
|
+
declare class DeltaGenerator {
|
|
2567
|
+
/**
|
|
2568
|
+
* The baseline resource resolver to compare against.
|
|
2569
|
+
* @internal
|
|
2570
|
+
*/
|
|
2571
|
+
private readonly _baselineResolver;
|
|
2572
|
+
/**
|
|
2573
|
+
* The delta resource resolver containing changes.
|
|
2574
|
+
* @internal
|
|
2575
|
+
*/
|
|
2576
|
+
private readonly _deltaResolver;
|
|
2577
|
+
/**
|
|
2578
|
+
* The resource manager to clone and update.
|
|
2579
|
+
* @internal
|
|
2580
|
+
*/
|
|
2581
|
+
private readonly _resourceManager;
|
|
2582
|
+
/**
|
|
2583
|
+
* Logger for status and error reporting.
|
|
2584
|
+
* @internal
|
|
2585
|
+
*/
|
|
2586
|
+
private readonly _logger;
|
|
2587
|
+
/**
|
|
2588
|
+
* Constructor for a {@link Resources.DeltaGenerator | DeltaGenerator} object.
|
|
2589
|
+
* @param params - Parameters to create a new {@link Resources.DeltaGenerator | DeltaGenerator}.
|
|
2590
|
+
* @internal
|
|
2591
|
+
*/
|
|
2592
|
+
protected constructor(params: IDeltaGeneratorParams);
|
|
2593
|
+
/**
|
|
2594
|
+
* Creates a new {@link Resources.DeltaGenerator | DeltaGenerator} object.
|
|
2595
|
+
* @param params - Parameters to create a new {@link Resources.DeltaGenerator | DeltaGenerator}.
|
|
2596
|
+
* @returns `Success` with the new {@link Resources.DeltaGenerator | DeltaGenerator} object if successful,
|
|
2597
|
+
* or `Failure` with an error message if not.
|
|
2598
|
+
* @public
|
|
2599
|
+
*/
|
|
2600
|
+
static create(params: IDeltaGeneratorParams): Result<DeltaGenerator>;
|
|
2601
|
+
/**
|
|
2602
|
+
* Generates deltas between baseline and delta resolvers.
|
|
2603
|
+
* Creates a cloned resource manager with partial/augment candidates for updates
|
|
2604
|
+
* and full/replace candidates for new resources.
|
|
2605
|
+
*
|
|
2606
|
+
* @param options - Options controlling delta generation behavior.
|
|
2607
|
+
* @returns `Success` with the updated resource manager if successful,
|
|
2608
|
+
* or `Failure` with an error message if not.
|
|
2609
|
+
* @public
|
|
2610
|
+
*/
|
|
2611
|
+
generate(options?: IDeltaGeneratorOptions): Result<ResourceManagerBuilder>;
|
|
2612
|
+
/**
|
|
2613
|
+
* Validates the provided context declaration.
|
|
2614
|
+
* @param context - The context declaration to validate.
|
|
2615
|
+
* @returns `Success` with the validated context if successful, `Failure` otherwise.
|
|
2616
|
+
* @internal
|
|
2617
|
+
*/
|
|
2618
|
+
private _validateContext;
|
|
2619
|
+
/**
|
|
2620
|
+
* Enumerates target resource IDs for delta generation.
|
|
2621
|
+
* If specific resource IDs are provided, uses those. Otherwise, discovers all resources
|
|
2622
|
+
* from both the baseline resource manager and the delta resolver to ensure comprehensive
|
|
2623
|
+
* coverage of all potential resources.
|
|
2624
|
+
*
|
|
2625
|
+
* @param requestedIds - Optional array of specific resource IDs to target.
|
|
2626
|
+
* @param context - The validated context to use for resource discovery.
|
|
2627
|
+
* @returns `Success` with array of resource IDs if successful, `Failure` otherwise.
|
|
2628
|
+
* @internal
|
|
2629
|
+
*/
|
|
2630
|
+
private _enumerateTargetResources;
|
|
2631
|
+
/**
|
|
2632
|
+
* Discovers all unique resource IDs from both baseline and delta resolvers.
|
|
2633
|
+
* Creates a union of resource IDs from the baseline resource manager and delta resolver
|
|
2634
|
+
* to ensure comprehensive coverage of all resources.
|
|
2635
|
+
*
|
|
2636
|
+
* @returns `Success` with array of unique resource IDs if successful, `Failure` otherwise.
|
|
2637
|
+
* @internal
|
|
2638
|
+
*/
|
|
2639
|
+
private _discoverAllResourceIds;
|
|
2640
|
+
/**
|
|
2641
|
+
* Creates a clone of the resource manager for delta operations.
|
|
2642
|
+
* @returns `Success` with the cloned resource manager if successful, `Failure` otherwise.
|
|
2643
|
+
* @internal
|
|
2644
|
+
*/
|
|
2645
|
+
private _cloneResourceManager;
|
|
2646
|
+
/**
|
|
2647
|
+
* Generates deltas for the specified resources and adds them to the cloned manager.
|
|
2648
|
+
*
|
|
2649
|
+
* @param clonedManager - The cloned resource manager to update.
|
|
2650
|
+
* @param resourceIds - Array of resource IDs to process.
|
|
2651
|
+
* @param context - The context to use for resource resolution.
|
|
2652
|
+
* @param skipUnchanged - Whether to skip resources that haven't changed.
|
|
2653
|
+
* @returns `Success` with the updated manager if successful, `Failure` otherwise.
|
|
2654
|
+
* @internal
|
|
2655
|
+
*/
|
|
2656
|
+
private _generateDeltas;
|
|
2657
|
+
/**
|
|
2658
|
+
* Generates a delta for a single resource and adds appropriate candidates to the manager.
|
|
2659
|
+
*
|
|
2660
|
+
* @param manager - The resource manager to update.
|
|
2661
|
+
* @param resourceId - The resource ID to process.
|
|
2662
|
+
* @param context - The context to use for resource resolution.
|
|
2663
|
+
* @param skipUnchanged - Whether to skip resources that haven't changed.
|
|
2664
|
+
* @returns `Success` with the resource delta result if successful, `Failure` otherwise.
|
|
2665
|
+
* @internal
|
|
2666
|
+
*/
|
|
2667
|
+
private _generateResourceDelta;
|
|
2668
|
+
/**
|
|
2669
|
+
* Checks if two JSON values are identical.
|
|
2670
|
+
* @param value1 - First value to compare.
|
|
2671
|
+
* @param value2 - Second value to compare.
|
|
2672
|
+
* @returns True if values are identical, false otherwise.
|
|
2673
|
+
* @internal
|
|
2674
|
+
*/
|
|
2675
|
+
private _areValuesIdentical;
|
|
2676
|
+
/**
|
|
2677
|
+
* Creates a new resource candidate for a newly discovered resource.
|
|
2678
|
+
* Uses full/replace merge method since this is a completely new resource.
|
|
2679
|
+
*
|
|
2680
|
+
* @param manager - The resource manager to update.
|
|
2681
|
+
* @param resourceId - The resource ID for the new resource.
|
|
2682
|
+
* @param value - The resolved value for the new resource.
|
|
2683
|
+
* @param context - The context used for resolution.
|
|
2684
|
+
* @returns `Success` if the candidate was added successfully, `Failure` otherwise.
|
|
2685
|
+
* @internal
|
|
2686
|
+
*/
|
|
2687
|
+
private _createNewResourceCandidate;
|
|
2688
|
+
/**
|
|
2689
|
+
* Creates a delta candidate for an updated resource.
|
|
2690
|
+
* Computes the difference between baseline and delta values and creates
|
|
2691
|
+
* a partial/augment candidate with only the changed properties.
|
|
2692
|
+
*
|
|
2693
|
+
* @param manager - The resource manager to update.
|
|
2694
|
+
* @param resourceId - The resource ID for the updated resource.
|
|
2695
|
+
* @param baselineValue - The baseline resolved value.
|
|
2696
|
+
* @param deltaValue - The delta resolved value.
|
|
2697
|
+
* @param context - The context used for resolution.
|
|
2698
|
+
* @returns `Success` if the candidate was added successfully, `Failure` otherwise.
|
|
2699
|
+
* @internal
|
|
2700
|
+
*/
|
|
2701
|
+
private _createDeltaCandidate;
|
|
2702
|
+
}
|
|
2703
|
+
|
|
2555
2704
|
/**
|
|
2556
2705
|
* Type for handling empty branch nodes during tree composition.
|
|
2557
2706
|
* The handler receives the branch node, names of failed children, and the resolver for recovery attempts.
|
|
@@ -3813,6 +3962,49 @@ declare interface IDeclarationOptions {
|
|
|
3813
3962
|
normalized?: boolean;
|
|
3814
3963
|
}
|
|
3815
3964
|
|
|
3965
|
+
/**
|
|
3966
|
+
* Interface for options controlling delta generation behavior.
|
|
3967
|
+
* @public
|
|
3968
|
+
*/
|
|
3969
|
+
declare interface IDeltaGeneratorOptions {
|
|
3970
|
+
/**
|
|
3971
|
+
* Context to use when resolving resources. If not provided, uses empty context.
|
|
3972
|
+
*/
|
|
3973
|
+
context?: Context.IContextDecl;
|
|
3974
|
+
/**
|
|
3975
|
+
* Array of specific resource IDs to include in delta generation.
|
|
3976
|
+
* If not provided, generates deltas for all resources in the delta resolver.
|
|
3977
|
+
*/
|
|
3978
|
+
resourceIds?: ReadonlyArray<string>;
|
|
3979
|
+
/**
|
|
3980
|
+
* Whether to skip resources that haven't changed. Default: true.
|
|
3981
|
+
*/
|
|
3982
|
+
skipUnchanged?: boolean;
|
|
3983
|
+
}
|
|
3984
|
+
|
|
3985
|
+
/**
|
|
3986
|
+
* Interface for parameters to create a {@link Resources.DeltaGenerator | DeltaGenerator}.
|
|
3987
|
+
* @public
|
|
3988
|
+
*/
|
|
3989
|
+
declare interface IDeltaGeneratorParams {
|
|
3990
|
+
/**
|
|
3991
|
+
* The baseline resource resolver to compare against.
|
|
3992
|
+
*/
|
|
3993
|
+
baselineResolver: IResourceResolver;
|
|
3994
|
+
/**
|
|
3995
|
+
* The delta resource resolver containing changes.
|
|
3996
|
+
*/
|
|
3997
|
+
deltaResolver: IResourceResolver;
|
|
3998
|
+
/**
|
|
3999
|
+
* The resource manager to clone and update.
|
|
4000
|
+
*/
|
|
4001
|
+
resourceManager: ResourceManagerBuilder;
|
|
4002
|
+
/**
|
|
4003
|
+
* Optional logger for status and error reporting.
|
|
4004
|
+
*/
|
|
4005
|
+
logger?: Logging.ILogger;
|
|
4006
|
+
}
|
|
4007
|
+
|
|
3816
4008
|
/**
|
|
3817
4009
|
* @internal
|
|
3818
4010
|
*/
|
|
@@ -5266,6 +5458,10 @@ export declare interface IResourceManager<TR extends IResource = IResource> {
|
|
|
5266
5458
|
* The number of resources in this resource manager.
|
|
5267
5459
|
*/
|
|
5268
5460
|
readonly numResources: number;
|
|
5461
|
+
/**
|
|
5462
|
+
* The resource IDs that this resource manager can resolve.
|
|
5463
|
+
*/
|
|
5464
|
+
readonly resourceIds: ReadonlyArray<ResourceId>;
|
|
5269
5465
|
/**
|
|
5270
5466
|
* The number of candidates in this resource manager.
|
|
5271
5467
|
*/
|
|
@@ -5317,6 +5513,10 @@ declare interface IResourceManagerCloneOptions extends IResourceDeclarationOptio
|
|
|
5317
5513
|
* @public
|
|
5318
5514
|
*/
|
|
5319
5515
|
export declare interface IResourceResolver {
|
|
5516
|
+
/**
|
|
5517
|
+
* The resource IDs that this resolver can resolve.
|
|
5518
|
+
*/
|
|
5519
|
+
readonly resourceIds: ReadonlyArray<ResourceId>;
|
|
5320
5520
|
/**
|
|
5321
5521
|
* Resolves a resource to a composed value by merging matching candidates according to their merge methods.
|
|
5322
5522
|
* Starting from the highest priority candidates, finds the first "full" candidate and merges all higher
|
|
@@ -8457,6 +8657,10 @@ export declare class ResourceManagerBuilder implements IResourceManager<Resource
|
|
|
8457
8657
|
* the {@link Resources.ResourceCandidate | resource candidates} in this manager.
|
|
8458
8658
|
*/
|
|
8459
8659
|
get conditions(): ReadOnlyConditionCollector;
|
|
8660
|
+
/**
|
|
8661
|
+
* The resource IDs that this resource manager can resolve.
|
|
8662
|
+
*/
|
|
8663
|
+
get resourceIds(): ReadonlyArray<ResourceId>;
|
|
8460
8664
|
/**
|
|
8461
8665
|
* A {@link Conditions.ConditionSetCollector | ConditionSetCollector} which
|
|
8462
8666
|
* contains the {@link Conditions.ConditionSet | condition sets} used so far by
|
|
@@ -8805,6 +9009,10 @@ export declare class ResourceResolver implements IResourceResolver {
|
|
|
8805
9009
|
* The readonly qualifier collector that provides qualifier implementations.
|
|
8806
9010
|
*/
|
|
8807
9011
|
get qualifiers(): IReadOnlyQualifierCollector;
|
|
9012
|
+
/**
|
|
9013
|
+
* The resource IDs that this resolver can resolve.
|
|
9014
|
+
*/
|
|
9015
|
+
get resourceIds(): ReadonlyArray<ResourceId>;
|
|
8808
9016
|
/**
|
|
8809
9017
|
* The cache array for resolved conditions, indexed by condition index for O(1) lookup.
|
|
8810
9018
|
* Each entry stores the resolved {@link Runtime.IConditionMatchResult | condition match result} for
|
|
@@ -9032,6 +9240,9 @@ declare namespace Resources {
|
|
|
9032
9240
|
CandidateValue,
|
|
9033
9241
|
ICandidateValueCollectorCreateParams,
|
|
9034
9242
|
CandidateValueCollector,
|
|
9243
|
+
IDeltaGeneratorParams,
|
|
9244
|
+
IDeltaGeneratorOptions,
|
|
9245
|
+
DeltaGenerator,
|
|
9035
9246
|
IResourceCandidateCreateParams,
|
|
9036
9247
|
ICandidateDeclOptions,
|
|
9037
9248
|
ResourceCandidate,
|
|
@@ -66,6 +66,10 @@ export type CandidateValueKey = Brand<string, 'CandidateValueKey'>;
|
|
|
66
66
|
* @public
|
|
67
67
|
*/
|
|
68
68
|
export interface IResourceResolver {
|
|
69
|
+
/**
|
|
70
|
+
* The resource IDs that this resolver can resolve.
|
|
71
|
+
*/
|
|
72
|
+
readonly resourceIds: ReadonlyArray<ResourceId>;
|
|
69
73
|
/**
|
|
70
74
|
* Resolves a resource to a composed value by merging matching candidates according to their merge methods.
|
|
71
75
|
* Starting from the highest priority candidates, finds the first "full" candidate and merges all higher
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { Logging, Result } from '@fgv/ts-utils';
|
|
2
|
+
import { IResourceResolver } from '../common';
|
|
3
|
+
import { ResourceManagerBuilder } from './resourceManagerBuilder';
|
|
4
|
+
import * as Context from '../context';
|
|
5
|
+
/**
|
|
6
|
+
* Interface for parameters to create a {@link Resources.DeltaGenerator | DeltaGenerator}.
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export interface IDeltaGeneratorParams {
|
|
10
|
+
/**
|
|
11
|
+
* The baseline resource resolver to compare against.
|
|
12
|
+
*/
|
|
13
|
+
baselineResolver: IResourceResolver;
|
|
14
|
+
/**
|
|
15
|
+
* The delta resource resolver containing changes.
|
|
16
|
+
*/
|
|
17
|
+
deltaResolver: IResourceResolver;
|
|
18
|
+
/**
|
|
19
|
+
* The resource manager to clone and update.
|
|
20
|
+
*/
|
|
21
|
+
resourceManager: ResourceManagerBuilder;
|
|
22
|
+
/**
|
|
23
|
+
* Optional logger for status and error reporting.
|
|
24
|
+
*/
|
|
25
|
+
logger?: Logging.ILogger;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Interface for options controlling delta generation behavior.
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
export interface IDeltaGeneratorOptions {
|
|
32
|
+
/**
|
|
33
|
+
* Context to use when resolving resources. If not provided, uses empty context.
|
|
34
|
+
*/
|
|
35
|
+
context?: Context.IContextDecl;
|
|
36
|
+
/**
|
|
37
|
+
* Array of specific resource IDs to include in delta generation.
|
|
38
|
+
* If not provided, generates deltas for all resources in the delta resolver.
|
|
39
|
+
*/
|
|
40
|
+
resourceIds?: ReadonlyArray<string>;
|
|
41
|
+
/**
|
|
42
|
+
* Whether to skip resources that haven't changed. Default: true.
|
|
43
|
+
*/
|
|
44
|
+
skipUnchanged?: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Class for generating resource deltas between baseline and delta resolvers.
|
|
48
|
+
* Creates partial/augment candidates for updated resources and full/replace candidates for new resources.
|
|
49
|
+
* Uses Diff.jsonThreeWayDiff for efficient delta computation.
|
|
50
|
+
* @public
|
|
51
|
+
*/
|
|
52
|
+
export declare class DeltaGenerator {
|
|
53
|
+
/**
|
|
54
|
+
* The baseline resource resolver to compare against.
|
|
55
|
+
* @internal
|
|
56
|
+
*/
|
|
57
|
+
private readonly _baselineResolver;
|
|
58
|
+
/**
|
|
59
|
+
* The delta resource resolver containing changes.
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
private readonly _deltaResolver;
|
|
63
|
+
/**
|
|
64
|
+
* The resource manager to clone and update.
|
|
65
|
+
* @internal
|
|
66
|
+
*/
|
|
67
|
+
private readonly _resourceManager;
|
|
68
|
+
/**
|
|
69
|
+
* Logger for status and error reporting.
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
72
|
+
private readonly _logger;
|
|
73
|
+
/**
|
|
74
|
+
* Constructor for a {@link Resources.DeltaGenerator | DeltaGenerator} object.
|
|
75
|
+
* @param params - Parameters to create a new {@link Resources.DeltaGenerator | DeltaGenerator}.
|
|
76
|
+
* @internal
|
|
77
|
+
*/
|
|
78
|
+
protected constructor(params: IDeltaGeneratorParams);
|
|
79
|
+
/**
|
|
80
|
+
* Creates a new {@link Resources.DeltaGenerator | DeltaGenerator} object.
|
|
81
|
+
* @param params - Parameters to create a new {@link Resources.DeltaGenerator | DeltaGenerator}.
|
|
82
|
+
* @returns `Success` with the new {@link Resources.DeltaGenerator | DeltaGenerator} object if successful,
|
|
83
|
+
* or `Failure` with an error message if not.
|
|
84
|
+
* @public
|
|
85
|
+
*/
|
|
86
|
+
static create(params: IDeltaGeneratorParams): Result<DeltaGenerator>;
|
|
87
|
+
/**
|
|
88
|
+
* Generates deltas between baseline and delta resolvers.
|
|
89
|
+
* Creates a cloned resource manager with partial/augment candidates for updates
|
|
90
|
+
* and full/replace candidates for new resources.
|
|
91
|
+
*
|
|
92
|
+
* @param options - Options controlling delta generation behavior.
|
|
93
|
+
* @returns `Success` with the updated resource manager if successful,
|
|
94
|
+
* or `Failure` with an error message if not.
|
|
95
|
+
* @public
|
|
96
|
+
*/
|
|
97
|
+
generate(options?: IDeltaGeneratorOptions): Result<ResourceManagerBuilder>;
|
|
98
|
+
/**
|
|
99
|
+
* Validates the provided context declaration.
|
|
100
|
+
* @param context - The context declaration to validate.
|
|
101
|
+
* @returns `Success` with the validated context if successful, `Failure` otherwise.
|
|
102
|
+
* @internal
|
|
103
|
+
*/
|
|
104
|
+
private _validateContext;
|
|
105
|
+
/**
|
|
106
|
+
* Enumerates target resource IDs for delta generation.
|
|
107
|
+
* If specific resource IDs are provided, uses those. Otherwise, discovers all resources
|
|
108
|
+
* from both the baseline resource manager and the delta resolver to ensure comprehensive
|
|
109
|
+
* coverage of all potential resources.
|
|
110
|
+
*
|
|
111
|
+
* @param requestedIds - Optional array of specific resource IDs to target.
|
|
112
|
+
* @param context - The validated context to use for resource discovery.
|
|
113
|
+
* @returns `Success` with array of resource IDs if successful, `Failure` otherwise.
|
|
114
|
+
* @internal
|
|
115
|
+
*/
|
|
116
|
+
private _enumerateTargetResources;
|
|
117
|
+
/**
|
|
118
|
+
* Discovers all unique resource IDs from both baseline and delta resolvers.
|
|
119
|
+
* Creates a union of resource IDs from the baseline resource manager and delta resolver
|
|
120
|
+
* to ensure comprehensive coverage of all resources.
|
|
121
|
+
*
|
|
122
|
+
* @returns `Success` with array of unique resource IDs if successful, `Failure` otherwise.
|
|
123
|
+
* @internal
|
|
124
|
+
*/
|
|
125
|
+
private _discoverAllResourceIds;
|
|
126
|
+
/**
|
|
127
|
+
* Creates a clone of the resource manager for delta operations.
|
|
128
|
+
* @returns `Success` with the cloned resource manager if successful, `Failure` otherwise.
|
|
129
|
+
* @internal
|
|
130
|
+
*/
|
|
131
|
+
private _cloneResourceManager;
|
|
132
|
+
/**
|
|
133
|
+
* Generates deltas for the specified resources and adds them to the cloned manager.
|
|
134
|
+
*
|
|
135
|
+
* @param clonedManager - The cloned resource manager to update.
|
|
136
|
+
* @param resourceIds - Array of resource IDs to process.
|
|
137
|
+
* @param context - The context to use for resource resolution.
|
|
138
|
+
* @param skipUnchanged - Whether to skip resources that haven't changed.
|
|
139
|
+
* @returns `Success` with the updated manager if successful, `Failure` otherwise.
|
|
140
|
+
* @internal
|
|
141
|
+
*/
|
|
142
|
+
private _generateDeltas;
|
|
143
|
+
/**
|
|
144
|
+
* Generates a delta for a single resource and adds appropriate candidates to the manager.
|
|
145
|
+
*
|
|
146
|
+
* @param manager - The resource manager to update.
|
|
147
|
+
* @param resourceId - The resource ID to process.
|
|
148
|
+
* @param context - The context to use for resource resolution.
|
|
149
|
+
* @param skipUnchanged - Whether to skip resources that haven't changed.
|
|
150
|
+
* @returns `Success` with the resource delta result if successful, `Failure` otherwise.
|
|
151
|
+
* @internal
|
|
152
|
+
*/
|
|
153
|
+
private _generateResourceDelta;
|
|
154
|
+
/**
|
|
155
|
+
* Checks if two JSON values are identical.
|
|
156
|
+
* @param value1 - First value to compare.
|
|
157
|
+
* @param value2 - Second value to compare.
|
|
158
|
+
* @returns True if values are identical, false otherwise.
|
|
159
|
+
* @internal
|
|
160
|
+
*/
|
|
161
|
+
private _areValuesIdentical;
|
|
162
|
+
/**
|
|
163
|
+
* Creates a new resource candidate for a newly discovered resource.
|
|
164
|
+
* Uses full/replace merge method since this is a completely new resource.
|
|
165
|
+
*
|
|
166
|
+
* @param manager - The resource manager to update.
|
|
167
|
+
* @param resourceId - The resource ID for the new resource.
|
|
168
|
+
* @param value - The resolved value for the new resource.
|
|
169
|
+
* @param context - The context used for resolution.
|
|
170
|
+
* @returns `Success` if the candidate was added successfully, `Failure` otherwise.
|
|
171
|
+
* @internal
|
|
172
|
+
*/
|
|
173
|
+
private _createNewResourceCandidate;
|
|
174
|
+
/**
|
|
175
|
+
* Creates a delta candidate for an updated resource.
|
|
176
|
+
* Computes the difference between baseline and delta values and creates
|
|
177
|
+
* a partial/augment candidate with only the changed properties.
|
|
178
|
+
*
|
|
179
|
+
* @param manager - The resource manager to update.
|
|
180
|
+
* @param resourceId - The resource ID for the updated resource.
|
|
181
|
+
* @param baselineValue - The baseline resolved value.
|
|
182
|
+
* @param deltaValue - The delta resolved value.
|
|
183
|
+
* @param context - The context used for resolution.
|
|
184
|
+
* @returns `Success` if the candidate was added successfully, `Failure` otherwise.
|
|
185
|
+
* @internal
|
|
186
|
+
*/
|
|
187
|
+
private _createDeltaCandidate;
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=deltaGenerator.d.ts.map
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025 Erik Fortune
|
|
4
|
+
*
|
|
5
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
* in the Software without restriction, including without limitation the rights
|
|
8
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
* furnished to do so, subject to the following conditions:
|
|
11
|
+
*
|
|
12
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
* copies or substantial portions of the Software.
|
|
14
|
+
*
|
|
15
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
* SOFTWARE.
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.DeltaGenerator = void 0;
|
|
25
|
+
const ts_utils_1 = require("@fgv/ts-utils");
|
|
26
|
+
const ts_json_base_1 = require("@fgv/ts-json-base");
|
|
27
|
+
const ts_json_1 = require("@fgv/ts-json");
|
|
28
|
+
/**
|
|
29
|
+
* Class for generating resource deltas between baseline and delta resolvers.
|
|
30
|
+
* Creates partial/augment candidates for updated resources and full/replace candidates for new resources.
|
|
31
|
+
* Uses Diff.jsonThreeWayDiff for efficient delta computation.
|
|
32
|
+
* @public
|
|
33
|
+
*/
|
|
34
|
+
class DeltaGenerator {
|
|
35
|
+
/**
|
|
36
|
+
* Constructor for a {@link Resources.DeltaGenerator | DeltaGenerator} object.
|
|
37
|
+
* @param params - Parameters to create a new {@link Resources.DeltaGenerator | DeltaGenerator}.
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
40
|
+
constructor(params) {
|
|
41
|
+
var _a;
|
|
42
|
+
this._baselineResolver = params.baselineResolver;
|
|
43
|
+
this._deltaResolver = params.deltaResolver;
|
|
44
|
+
this._resourceManager = params.resourceManager;
|
|
45
|
+
this._logger = (_a = params.logger) !== null && _a !== void 0 ? _a : new ts_utils_1.Logging.NoOpLogger();
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Creates a new {@link Resources.DeltaGenerator | DeltaGenerator} object.
|
|
49
|
+
* @param params - Parameters to create a new {@link Resources.DeltaGenerator | DeltaGenerator}.
|
|
50
|
+
* @returns `Success` with the new {@link Resources.DeltaGenerator | DeltaGenerator} object if successful,
|
|
51
|
+
* or `Failure` with an error message if not.
|
|
52
|
+
* @public
|
|
53
|
+
*/
|
|
54
|
+
static create(params) {
|
|
55
|
+
return (0, ts_utils_1.captureResult)(() => new DeltaGenerator(params));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Generates deltas between baseline and delta resolvers.
|
|
59
|
+
* Creates a cloned resource manager with partial/augment candidates for updates
|
|
60
|
+
* and full/replace candidates for new resources.
|
|
61
|
+
*
|
|
62
|
+
* @param options - Options controlling delta generation behavior.
|
|
63
|
+
* @returns `Success` with the updated resource manager if successful,
|
|
64
|
+
* or `Failure` with an error message if not.
|
|
65
|
+
* @public
|
|
66
|
+
*/
|
|
67
|
+
generate(options) {
|
|
68
|
+
var _a, _b;
|
|
69
|
+
this._logger.info('Starting delta generation');
|
|
70
|
+
const context = (_a = options === null || options === void 0 ? void 0 : options.context) !== null && _a !== void 0 ? _a : {};
|
|
71
|
+
const skipUnchanged = (_b = options === null || options === void 0 ? void 0 : options.skipUnchanged) !== null && _b !== void 0 ? _b : true;
|
|
72
|
+
return this._validateContext(context)
|
|
73
|
+
.onSuccess((validatedContext) => this._enumerateTargetResources(options === null || options === void 0 ? void 0 : options.resourceIds, validatedContext))
|
|
74
|
+
.onSuccess((resourceIds) => {
|
|
75
|
+
return this._cloneResourceManager()
|
|
76
|
+
.onSuccess((clonedManager) => this._generateDeltas(clonedManager, resourceIds, context, skipUnchanged))
|
|
77
|
+
.onSuccess((manager) => {
|
|
78
|
+
this._logger.info(`Delta generation completed successfully with ${manager.size} resources`);
|
|
79
|
+
return (0, ts_utils_1.succeed)(manager);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Validates the provided context declaration.
|
|
85
|
+
* @param context - The context declaration to validate.
|
|
86
|
+
* @returns `Success` with the validated context if successful, `Failure` otherwise.
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
89
|
+
_validateContext(context) {
|
|
90
|
+
return this._resourceManager.validateContext(context);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Enumerates target resource IDs for delta generation.
|
|
94
|
+
* If specific resource IDs are provided, uses those. Otherwise, discovers all resources
|
|
95
|
+
* from both the baseline resource manager and the delta resolver to ensure comprehensive
|
|
96
|
+
* coverage of all potential resources.
|
|
97
|
+
*
|
|
98
|
+
* @param requestedIds - Optional array of specific resource IDs to target.
|
|
99
|
+
* @param context - The validated context to use for resource discovery.
|
|
100
|
+
* @returns `Success` with array of resource IDs if successful, `Failure` otherwise.
|
|
101
|
+
* @internal
|
|
102
|
+
*/
|
|
103
|
+
_enumerateTargetResources(requestedIds, context) {
|
|
104
|
+
if (requestedIds && requestedIds.length > 0) {
|
|
105
|
+
this._logger.info(`Using ${requestedIds.length} specified resource IDs`);
|
|
106
|
+
// Validate the requested IDs
|
|
107
|
+
const validatedIds = [];
|
|
108
|
+
const errors = new ts_utils_1.MessageAggregator();
|
|
109
|
+
for (const id of requestedIds) {
|
|
110
|
+
const validationResult = this._resourceManager.getBuiltResource(id);
|
|
111
|
+
if (validationResult.isSuccess()) {
|
|
112
|
+
validatedIds.push(id);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
errors.addMessage(`Invalid resource ID "${id}": ${validationResult.message}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (errors.hasMessages) {
|
|
119
|
+
return (0, ts_utils_1.fail)(errors.toString());
|
|
120
|
+
}
|
|
121
|
+
return (0, ts_utils_1.succeed)(validatedIds);
|
|
122
|
+
}
|
|
123
|
+
// Discover resources from both baseline and delta resolvers to ensure comprehensive coverage
|
|
124
|
+
this._logger.info('Discovering resources from both baseline and delta resolvers');
|
|
125
|
+
return this._discoverAllResourceIds().onSuccess((allResourceIds) => {
|
|
126
|
+
this._logger.info(`Discovered ${allResourceIds.length} unique resources across both resolvers`);
|
|
127
|
+
return (0, ts_utils_1.succeed)(allResourceIds);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Discovers all unique resource IDs from both baseline and delta resolvers.
|
|
132
|
+
* Creates a union of resource IDs from the baseline resource manager and delta resolver
|
|
133
|
+
* to ensure comprehensive coverage of all resources.
|
|
134
|
+
*
|
|
135
|
+
* @returns `Success` with array of unique resource IDs if successful, `Failure` otherwise.
|
|
136
|
+
* @internal
|
|
137
|
+
*/
|
|
138
|
+
_discoverAllResourceIds() {
|
|
139
|
+
// Get resource IDs from baseline resource manager
|
|
140
|
+
return this._resourceManager.getAllBuiltResources().onSuccess((baselineResources) => {
|
|
141
|
+
const baselineResourceIds = baselineResources.map((r) => r.id);
|
|
142
|
+
this._logger.detail(`Found ${baselineResourceIds.length} resources in baseline`);
|
|
143
|
+
// Get resource IDs from delta resolver using the public interface
|
|
144
|
+
const deltaResourceIds = this._deltaResolver.resourceIds;
|
|
145
|
+
this._logger.detail(`Found ${deltaResourceIds.length} resources in delta`);
|
|
146
|
+
// Create a union of resource IDs from both sources
|
|
147
|
+
const allResourceIds = new Set();
|
|
148
|
+
// Add baseline resource IDs
|
|
149
|
+
baselineResourceIds.forEach((id) => {
|
|
150
|
+
allResourceIds.add(id);
|
|
151
|
+
});
|
|
152
|
+
// Add delta resource IDs
|
|
153
|
+
deltaResourceIds.forEach((id) => {
|
|
154
|
+
allResourceIds.add(id);
|
|
155
|
+
});
|
|
156
|
+
const uniqueResourceIds = Array.from(allResourceIds);
|
|
157
|
+
this._logger.detail(`Created union of ${uniqueResourceIds.length} unique resource IDs`);
|
|
158
|
+
return (0, ts_utils_1.succeed)(uniqueResourceIds);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Creates a clone of the resource manager for delta operations.
|
|
163
|
+
* @returns `Success` with the cloned resource manager if successful, `Failure` otherwise.
|
|
164
|
+
* @internal
|
|
165
|
+
*/
|
|
166
|
+
_cloneResourceManager() {
|
|
167
|
+
this._logger.info('Cloning resource manager');
|
|
168
|
+
return this._resourceManager.clone();
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Generates deltas for the specified resources and adds them to the cloned manager.
|
|
172
|
+
*
|
|
173
|
+
* @param clonedManager - The cloned resource manager to update.
|
|
174
|
+
* @param resourceIds - Array of resource IDs to process.
|
|
175
|
+
* @param context - The context to use for resource resolution.
|
|
176
|
+
* @param skipUnchanged - Whether to skip resources that haven't changed.
|
|
177
|
+
* @returns `Success` with the updated manager if successful, `Failure` otherwise.
|
|
178
|
+
* @internal
|
|
179
|
+
*/
|
|
180
|
+
_generateDeltas(clonedManager, resourceIds, context, skipUnchanged) {
|
|
181
|
+
this._logger.info(`Generating deltas for ${resourceIds.length} resources`);
|
|
182
|
+
const errors = new ts_utils_1.MessageAggregator();
|
|
183
|
+
let processedCount = 0;
|
|
184
|
+
let changedCount = 0;
|
|
185
|
+
let newCount = 0;
|
|
186
|
+
let skippedCount = 0;
|
|
187
|
+
for (const resourceId of resourceIds) {
|
|
188
|
+
this._logger.detail(`Processing resource: ${resourceId}`);
|
|
189
|
+
const result = this._generateResourceDelta(clonedManager, resourceId, context, skipUnchanged);
|
|
190
|
+
if (result.isFailure()) {
|
|
191
|
+
errors.addMessage(`${resourceId}: ${result.message}`);
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
processedCount++;
|
|
195
|
+
// Track statistics based on result
|
|
196
|
+
const deltaResult = result.value;
|
|
197
|
+
if (deltaResult.type === 'skipped') {
|
|
198
|
+
skippedCount++;
|
|
199
|
+
}
|
|
200
|
+
else if (deltaResult.type === 'new') {
|
|
201
|
+
newCount++;
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
changedCount++;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
this._logger.info(`Processed ${processedCount} resources: ${changedCount} updated, ${newCount} new, ${skippedCount} skipped`);
|
|
208
|
+
if (errors.hasMessages) {
|
|
209
|
+
return (0, ts_utils_1.fail)(`Delta generation failed with errors:\n${errors.toString()}`);
|
|
210
|
+
}
|
|
211
|
+
return (0, ts_utils_1.succeed)(clonedManager);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Generates a delta for a single resource and adds appropriate candidates to the manager.
|
|
215
|
+
*
|
|
216
|
+
* @param manager - The resource manager to update.
|
|
217
|
+
* @param resourceId - The resource ID to process.
|
|
218
|
+
* @param context - The context to use for resource resolution.
|
|
219
|
+
* @param skipUnchanged - Whether to skip resources that haven't changed.
|
|
220
|
+
* @returns `Success` with the resource delta result if successful, `Failure` otherwise.
|
|
221
|
+
* @internal
|
|
222
|
+
*/
|
|
223
|
+
_generateResourceDelta(manager, resourceId, context, skipUnchanged) {
|
|
224
|
+
// Resolve values from both resolvers
|
|
225
|
+
const baselineResult = this._baselineResolver.resolveComposedResourceValue(resourceId);
|
|
226
|
+
const deltaResult = this._deltaResolver.resolveComposedResourceValue(resourceId);
|
|
227
|
+
const baselineExists = baselineResult.isSuccess();
|
|
228
|
+
const deltaExists = deltaResult.isSuccess();
|
|
229
|
+
if (deltaExists && !baselineExists) {
|
|
230
|
+
// New resource - exists in delta but not in baseline
|
|
231
|
+
this._logger.detail(`${resourceId}: New resource detected (exists in delta only)`);
|
|
232
|
+
return this._createNewResourceCandidate(manager, resourceId, deltaResult.value, context).onSuccess(() => (0, ts_utils_1.succeed)({ type: 'new', resourceId }));
|
|
233
|
+
}
|
|
234
|
+
if (baselineExists && !deltaExists) {
|
|
235
|
+
// Baseline-only resource - exists in baseline but not in delta (potential deletion)
|
|
236
|
+
// For now, skip these resources since delete merge method is not yet implemented
|
|
237
|
+
// TODO: When 'delete' merge method is available, create deletion candidates here
|
|
238
|
+
this._logger.detail(`${resourceId}: Baseline-only resource detected, skipping (delete merge method not yet implemented)`);
|
|
239
|
+
return (0, ts_utils_1.succeed)({ type: 'skipped', resourceId });
|
|
240
|
+
}
|
|
241
|
+
if (!baselineExists && !deltaExists) {
|
|
242
|
+
// Resource doesn't exist in either resolver - this shouldn't happen due to enumeration logic
|
|
243
|
+
return (0, ts_utils_1.fail)(`Resource ${resourceId} not found in either baseline or delta resolvers`);
|
|
244
|
+
}
|
|
245
|
+
// Both resolvers have the resource - check for changes
|
|
246
|
+
// At this point, both results are successful so values are guaranteed to exist
|
|
247
|
+
const baselineValue = baselineResult.value; // Safe: baselineExists is true
|
|
248
|
+
const deltaValue = deltaResult.value; // Safe: deltaExists is true
|
|
249
|
+
// Check if values are identical
|
|
250
|
+
if (skipUnchanged && this._areValuesIdentical(baselineValue, deltaValue)) {
|
|
251
|
+
this._logger.detail(`${resourceId}: No changes detected, skipping`);
|
|
252
|
+
return (0, ts_utils_1.succeed)({ type: 'skipped', resourceId });
|
|
253
|
+
}
|
|
254
|
+
// Updated resource - compute delta and create partial/augment candidate
|
|
255
|
+
this._logger.detail(`${resourceId}: Changes detected, computing delta`);
|
|
256
|
+
return this._createDeltaCandidate(manager, resourceId, baselineValue, deltaValue, context).onSuccess(() => (0, ts_utils_1.succeed)({ type: 'updated', resourceId }));
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Checks if two JSON values are identical.
|
|
260
|
+
* @param value1 - First value to compare.
|
|
261
|
+
* @param value2 - Second value to compare.
|
|
262
|
+
* @returns True if values are identical, false otherwise.
|
|
263
|
+
* @internal
|
|
264
|
+
*/
|
|
265
|
+
_areValuesIdentical(value1, value2) {
|
|
266
|
+
return JSON.stringify(value1) === JSON.stringify(value2);
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Creates a new resource candidate for a newly discovered resource.
|
|
270
|
+
* Uses full/replace merge method since this is a completely new resource.
|
|
271
|
+
*
|
|
272
|
+
* @param manager - The resource manager to update.
|
|
273
|
+
* @param resourceId - The resource ID for the new resource.
|
|
274
|
+
* @param value - The resolved value for the new resource.
|
|
275
|
+
* @param context - The context used for resolution.
|
|
276
|
+
* @returns `Success` if the candidate was added successfully, `Failure` otherwise.
|
|
277
|
+
* @internal
|
|
278
|
+
*/
|
|
279
|
+
_createNewResourceCandidate(manager, resourceId, value, context) {
|
|
280
|
+
if (!(0, ts_json_base_1.isJsonObject)(value)) {
|
|
281
|
+
return (0, ts_utils_1.fail)(`Resource value must be a JSON object, got ${typeof value}`);
|
|
282
|
+
}
|
|
283
|
+
const candidateDecl = {
|
|
284
|
+
id: resourceId,
|
|
285
|
+
json: value,
|
|
286
|
+
conditions: Object.keys(context).length > 0 ? context : undefined,
|
|
287
|
+
isPartial: false,
|
|
288
|
+
mergeMethod: 'replace',
|
|
289
|
+
resourceTypeName: 'json' // Use 'json' resource type for new JSON resources
|
|
290
|
+
};
|
|
291
|
+
const result = manager.addLooseCandidate(candidateDecl);
|
|
292
|
+
if (result.isFailure()) {
|
|
293
|
+
return (0, ts_utils_1.fail)(result.message);
|
|
294
|
+
}
|
|
295
|
+
return (0, ts_utils_1.succeed)(undefined);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Creates a delta candidate for an updated resource.
|
|
299
|
+
* Computes the difference between baseline and delta values and creates
|
|
300
|
+
* a partial/augment candidate with only the changed properties.
|
|
301
|
+
*
|
|
302
|
+
* @param manager - The resource manager to update.
|
|
303
|
+
* @param resourceId - The resource ID for the updated resource.
|
|
304
|
+
* @param baselineValue - The baseline resolved value.
|
|
305
|
+
* @param deltaValue - The delta resolved value.
|
|
306
|
+
* @param context - The context used for resolution.
|
|
307
|
+
* @returns `Success` if the candidate was added successfully, `Failure` otherwise.
|
|
308
|
+
* @internal
|
|
309
|
+
*/
|
|
310
|
+
_createDeltaCandidate(manager, resourceId, baselineValue, deltaValue, context) {
|
|
311
|
+
// Compute three-way diff to get only the changed properties
|
|
312
|
+
return ts_json_1.Diff.jsonThreeWayDiff(baselineValue, deltaValue).onSuccess((diff) => {
|
|
313
|
+
if (diff.identical) {
|
|
314
|
+
// This shouldn't happen if we checked for identity earlier, but be defensive
|
|
315
|
+
this._logger.warn(`${resourceId}: Diff reports identical values, skipping`);
|
|
316
|
+
return (0, ts_utils_1.succeed)(undefined);
|
|
317
|
+
}
|
|
318
|
+
// Use onlyInB (second object) which contains new/changed properties
|
|
319
|
+
const deltaChanges = diff.onlyInB;
|
|
320
|
+
if (!(0, ts_json_base_1.isJsonObject)(deltaChanges)) {
|
|
321
|
+
return (0, ts_utils_1.fail)(`Delta changes must be a JSON object, got ${typeof deltaChanges}`);
|
|
322
|
+
}
|
|
323
|
+
// TODO: Handle deletions using 'augment' merge method with null values
|
|
324
|
+
// Note: The 'delete' merge type is not yet implemented in ts-res, so we use 'augment'
|
|
325
|
+
// with null values for deletion semantics (as used in ts-res-ui-components).
|
|
326
|
+
// When the 'delete' merge type is available, this should be updated to use it.
|
|
327
|
+
const candidateDecl = {
|
|
328
|
+
id: resourceId,
|
|
329
|
+
json: deltaChanges,
|
|
330
|
+
conditions: Object.keys(context).length > 0 ? context : undefined,
|
|
331
|
+
isPartial: true,
|
|
332
|
+
mergeMethod: 'augment',
|
|
333
|
+
resourceTypeName: undefined // Will be inferred by the manager
|
|
334
|
+
};
|
|
335
|
+
const result = manager.addLooseCandidate(candidateDecl);
|
|
336
|
+
if (result.isFailure()) {
|
|
337
|
+
return (0, ts_utils_1.fail)(result.message);
|
|
338
|
+
}
|
|
339
|
+
return (0, ts_utils_1.succeed)(undefined);
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
exports.DeltaGenerator = DeltaGenerator;
|
|
344
|
+
//# sourceMappingURL=deltaGenerator.js.map
|
|
@@ -38,6 +38,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
38
38
|
__exportStar(require("./candidateReducer"), exports);
|
|
39
39
|
__exportStar(require("./candidateValue"), exports);
|
|
40
40
|
__exportStar(require("./candidateValueCollector"), exports);
|
|
41
|
+
__exportStar(require("./deltaGenerator"), exports);
|
|
41
42
|
__exportStar(require("./resourceCandidate"), exports);
|
|
42
43
|
__exportStar(require("./resource"), exports);
|
|
43
44
|
__exportStar(require("./resourceBuilder"), exports);
|
|
@@ -93,6 +93,10 @@ export declare class ResourceManagerBuilder implements IResourceManager<Resource
|
|
|
93
93
|
* the {@link Resources.ResourceCandidate | resource candidates} in this manager.
|
|
94
94
|
*/
|
|
95
95
|
get conditions(): ReadOnlyConditionCollector;
|
|
96
|
+
/**
|
|
97
|
+
* The resource IDs that this resource manager can resolve.
|
|
98
|
+
*/
|
|
99
|
+
get resourceIds(): ReadonlyArray<ResourceId>;
|
|
96
100
|
/**
|
|
97
101
|
* A {@link Conditions.ConditionSetCollector | ConditionSetCollector} which
|
|
98
102
|
* contains the {@link Conditions.ConditionSet | condition sets} used so far by
|
|
@@ -91,6 +91,12 @@ class ResourceManagerBuilder {
|
|
|
91
91
|
get conditions() {
|
|
92
92
|
return this._conditions;
|
|
93
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* The resource IDs that this resource manager can resolve.
|
|
96
|
+
*/
|
|
97
|
+
get resourceIds() {
|
|
98
|
+
return Array.from(this._resources.keys()).sort();
|
|
99
|
+
}
|
|
94
100
|
/**
|
|
95
101
|
* A {@link Conditions.ConditionSetCollector | ConditionSetCollector} which
|
|
96
102
|
* contains the {@link Conditions.ConditionSet | condition sets} used so far by
|
|
@@ -54,6 +54,10 @@ export declare class CompiledResourceCollection implements IResourceManager<IRes
|
|
|
54
54
|
* contains the {@link Qualifiers.Qualifier | qualifiers} used in this collection.
|
|
55
55
|
*/
|
|
56
56
|
get qualifiers(): IReadOnlyQualifierCollector;
|
|
57
|
+
/**
|
|
58
|
+
* The resource IDs contained in this compiled resource collection.
|
|
59
|
+
*/
|
|
60
|
+
get resourceIds(): ReadonlyArray<ResourceId>;
|
|
57
61
|
/**
|
|
58
62
|
* A {@link ResourceTypes.ResourceTypeCollector | ResourceTypeCollector} which
|
|
59
63
|
* contains the {@link ResourceTypes.ResourceType | resource types} used in this collection.
|
|
@@ -88,6 +88,12 @@ class CompiledResourceCollection {
|
|
|
88
88
|
get qualifiers() {
|
|
89
89
|
return this._qualifiers;
|
|
90
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* The resource IDs contained in this compiled resource collection.
|
|
93
|
+
*/
|
|
94
|
+
get resourceIds() {
|
|
95
|
+
return Array.from(this._builtResources.keys()).sort();
|
|
96
|
+
}
|
|
91
97
|
/**
|
|
92
98
|
* A {@link ResourceTypes.ResourceTypeCollector | ResourceTypeCollector} which
|
|
93
99
|
* contains the {@link ResourceTypes.ResourceType | resource types} used in this collection.
|
|
@@ -82,6 +82,10 @@ export interface IResourceManager<TR extends IResource = IResource> {
|
|
|
82
82
|
* The number of resources in this resource manager.
|
|
83
83
|
*/
|
|
84
84
|
readonly numResources: number;
|
|
85
|
+
/**
|
|
86
|
+
* The resource IDs that this resource manager can resolve.
|
|
87
|
+
*/
|
|
88
|
+
readonly resourceIds: ReadonlyArray<ResourceId>;
|
|
85
89
|
/**
|
|
86
90
|
* The number of candidates in this resource manager.
|
|
87
91
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Result } from '@fgv/ts-utils';
|
|
2
2
|
import { JsonValue } from '@fgv/ts-json-base';
|
|
3
|
-
import { IResourceResolver } from '../common';
|
|
3
|
+
import { IResourceResolver, ResourceId } from '../common';
|
|
4
4
|
import { Condition, ConditionSet } from '../conditions';
|
|
5
5
|
import { AbstractDecision } from '../decisions';
|
|
6
6
|
import { ReadOnlyQualifierTypeCollector } from '../qualifier-types';
|
|
@@ -91,6 +91,10 @@ export declare class ResourceResolver implements IResourceResolver {
|
|
|
91
91
|
* The readonly qualifier collector that provides qualifier implementations.
|
|
92
92
|
*/
|
|
93
93
|
get qualifiers(): IReadOnlyQualifierCollector;
|
|
94
|
+
/**
|
|
95
|
+
* The resource IDs that this resolver can resolve.
|
|
96
|
+
*/
|
|
97
|
+
get resourceIds(): ReadonlyArray<ResourceId>;
|
|
94
98
|
/**
|
|
95
99
|
* The cache array for resolved conditions, indexed by condition index for O(1) lookup.
|
|
96
100
|
* Each entry stores the resolved {@link Runtime.IConditionMatchResult | condition match result} for
|
|
@@ -41,6 +41,12 @@ class ResourceResolver {
|
|
|
41
41
|
get qualifiers() {
|
|
42
42
|
return this.contextQualifierProvider.qualifiers;
|
|
43
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* The resource IDs that this resolver can resolve.
|
|
46
|
+
*/
|
|
47
|
+
get resourceIds() {
|
|
48
|
+
return this.resourceManager.resourceIds;
|
|
49
|
+
}
|
|
44
50
|
/**
|
|
45
51
|
* The cache array for resolved conditions, indexed by condition index for O(1) lookup.
|
|
46
52
|
* Each entry stores the resolved {@link Runtime.IConditionMatchResult | condition match result} for
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fgv/ts-res",
|
|
3
|
-
"version": "5.0.1-
|
|
3
|
+
"version": "5.0.1-1",
|
|
4
4
|
"description": "Multi-dimensional Resource Runtime",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "dist/ts-res.d.ts",
|
|
@@ -44,16 +44,16 @@
|
|
|
44
44
|
"@rushstack/heft-node-rig": "2.9.5",
|
|
45
45
|
"@types/heft-jest": "1.0.6",
|
|
46
46
|
"eslint-plugin-tsdoc": "~0.4.0",
|
|
47
|
-
"@fgv/ts-utils-jest": "5.0.1-
|
|
48
|
-
"@fgv/ts-extras": "5.0.1-
|
|
47
|
+
"@fgv/ts-utils-jest": "5.0.1-1",
|
|
48
|
+
"@fgv/ts-extras": "5.0.1-1"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"luxon": "^3.7.2",
|
|
52
52
|
"fflate": "~0.8.2",
|
|
53
|
-
"@fgv/ts-
|
|
54
|
-
"@fgv/ts-
|
|
55
|
-
"@fgv/ts-
|
|
56
|
-
"@fgv/ts-
|
|
53
|
+
"@fgv/ts-utils": "5.0.1-1",
|
|
54
|
+
"@fgv/ts-json-base": "5.0.1-1",
|
|
55
|
+
"@fgv/ts-json": "5.0.1-1",
|
|
56
|
+
"@fgv/ts-bcp47": "5.0.1-1"
|
|
57
57
|
},
|
|
58
58
|
"scripts": {
|
|
59
59
|
"build": "heft build --clean",
|