@fgv/ts-res 5.0.0-4 → 5.0.0-6
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 +69 -3
- package/lib/packlets/resources/common.d.ts +12 -0
- package/lib/packlets/resources/common.d.ts.map +1 -1
- package/lib/packlets/resources/common.js.map +1 -1
- package/lib/packlets/resources/resourceManagerBuilder.d.ts +40 -3
- package/lib/packlets/resources/resourceManagerBuilder.d.ts.map +1 -1
- package/lib/packlets/resources/resourceManagerBuilder.js +186 -8
- package/lib/packlets/resources/resourceManagerBuilder.js.map +1 -1
- package/lib/packlets/runtime/cacheListener.d.ts +9 -0
- package/lib/packlets/runtime/cacheListener.d.ts.map +1 -1
- package/lib/packlets/runtime/cacheListener.js +6 -0
- package/lib/packlets/runtime/cacheListener.js.map +1 -1
- package/lib/packlets/runtime/cacheMetrics.d.ts +6 -0
- package/lib/packlets/runtime/cacheMetrics.d.ts.map +1 -1
- package/lib/packlets/runtime/cacheMetrics.js +11 -0
- package/lib/packlets/runtime/cacheMetrics.js.map +1 -1
- package/lib/packlets/runtime/resourceResolver.js +15 -11
- package/lib/packlets/runtime/resourceResolver.js.map +1 -1
- package/package.json +12 -12
package/dist/ts-res.d.ts
CHANGED
|
@@ -4333,6 +4333,19 @@ declare interface IResourceManagerBuilderCreateParams {
|
|
|
4333
4333
|
resourceTypes: ReadOnlyResourceTypeCollector;
|
|
4334
4334
|
}
|
|
4335
4335
|
|
|
4336
|
+
/**
|
|
4337
|
+
* Options for ResourceManagerBuilder clone operations.
|
|
4338
|
+
* Extends IDeclarationOptions to include support for applying edits when cloning.
|
|
4339
|
+
* @public
|
|
4340
|
+
*/
|
|
4341
|
+
declare interface IResourceManagerCloneOptions extends IResourceDeclarationOptions {
|
|
4342
|
+
/**
|
|
4343
|
+
* Optional array of loose condition declarations to be applied as edits during the clone operation.
|
|
4344
|
+
* These conditions can modify or extend the resource candidates in the cloned manager.
|
|
4345
|
+
*/
|
|
4346
|
+
readonly candidates?: ReadonlyArray<ResourceJson.Json.ILooseResourceCandidateDecl>;
|
|
4347
|
+
}
|
|
4348
|
+
|
|
4336
4349
|
/**
|
|
4337
4350
|
* A listener for {@link Runtime.ResourceResolver | ResourceResolver} cache activity.
|
|
4338
4351
|
* @public
|
|
@@ -4356,6 +4369,11 @@ declare interface IResourceResolverCacheListener {
|
|
|
4356
4369
|
* @param index - The index of the cache that had an error.
|
|
4357
4370
|
*/
|
|
4358
4371
|
onCacheError(cache: ResourceResolverCacheType, index: number): void;
|
|
4372
|
+
/**
|
|
4373
|
+
* Called when a context error occurs.
|
|
4374
|
+
* @param error - The error that occurred.
|
|
4375
|
+
*/
|
|
4376
|
+
onContextError(qualifier: string, error: string): void;
|
|
4359
4377
|
/**
|
|
4360
4378
|
* Called when a cache is cleared.
|
|
4361
4379
|
* @param cache - The type of cache that was cleared.
|
|
@@ -5545,6 +5563,10 @@ declare class NoOpResourceResolverCacheListener implements IResourceResolverCach
|
|
|
5545
5563
|
* {@inheritDoc Runtime.IResourceResolverCacheListener.onCacheError}
|
|
5546
5564
|
*/
|
|
5547
5565
|
onCacheError(cache: ResourceResolverCacheType, index: number): void;
|
|
5566
|
+
/**
|
|
5567
|
+
* {@inheritDoc Runtime.IResourceResolverCacheListener.onContextError}
|
|
5568
|
+
*/
|
|
5569
|
+
onContextError(qualifier: string, error: string): void;
|
|
5548
5570
|
/**
|
|
5549
5571
|
* {@inheritDoc Runtime.IResourceResolverCacheListener.onCacheClear}
|
|
5550
5572
|
*/
|
|
@@ -7046,11 +7068,48 @@ declare class ResourceManagerBuilder implements IResourceManager {
|
|
|
7046
7068
|
* Creates a filtered clone of this ResourceManagerBuilder using the specified context.
|
|
7047
7069
|
* This is a convenience method that creates a new ResourceManagerBuilder with the same
|
|
7048
7070
|
* configuration but filtered to include only candidates that match the provided context.
|
|
7049
|
-
*
|
|
7071
|
+
* If candidates are provided for editing, they will be applied with collision detection.
|
|
7072
|
+
* @param options - Options for the cloning operation, including the strongly-typed filterForContext property and optional candidates for edits.
|
|
7050
7073
|
* @returns A Result containing the new filtered ResourceManagerBuilder.
|
|
7051
7074
|
* @public
|
|
7052
7075
|
*/
|
|
7053
|
-
clone(options?:
|
|
7076
|
+
clone(options?: IResourceManagerCloneOptions): Result<ResourceManagerBuilder>;
|
|
7077
|
+
/**
|
|
7078
|
+
* Creates a resource ID keyed map from an array of loose resource candidate declarations.
|
|
7079
|
+
* This enables efficient detection of edit collisions by grouping candidates by their target resource.
|
|
7080
|
+
* @param candidates - Array of loose resource candidate declarations to organize
|
|
7081
|
+
* @returns A Result containing a Map where keys are validated ResourceIds and values are arrays of candidates for that resource
|
|
7082
|
+
* @internal
|
|
7083
|
+
*/
|
|
7084
|
+
private static _createCandidatesByResourceMap;
|
|
7085
|
+
/**
|
|
7086
|
+
* Generates a proper ConditionSet token for collision detection using the existing ConditionSet.getKeyForDecl method.
|
|
7087
|
+
* @param conditionSet - The condition set to generate a token for
|
|
7088
|
+
* @param conditionCollector - The condition collector needed for validation context
|
|
7089
|
+
* @returns A Result containing the ConditionSet token if successful, or failure if validation fails
|
|
7090
|
+
* @internal
|
|
7091
|
+
*/
|
|
7092
|
+
private static _getConditionSetToken;
|
|
7093
|
+
/**
|
|
7094
|
+
* Applies candidate edits to a resource declaration, handling collisions using condition set tokens.
|
|
7095
|
+
* If there's no collision, adds the candidate. If there's a collision, replaces the original candidate with the edit.
|
|
7096
|
+
* @param resourceDecl - The original resource declaration to potentially modify
|
|
7097
|
+
* @param candidatesByResource - Map of resource IDs to arrays of candidate edits
|
|
7098
|
+
* @param conditionCollector - The condition collector needed for generating condition tokens
|
|
7099
|
+
* @returns A Result containing the resource declaration to use (original or modified)
|
|
7100
|
+
* @internal
|
|
7101
|
+
*/
|
|
7102
|
+
private static _applyEditsToResourceDeclaration;
|
|
7103
|
+
/**
|
|
7104
|
+
* Creates a new resource declaration from an array of candidate declarations.
|
|
7105
|
+
* This is used when cloning to create new resources that don't exist in the original manager.
|
|
7106
|
+
* @param resourceId - The validated resource ID for the new resource
|
|
7107
|
+
* @param candidates - Array of loose candidate declarations for the new resource
|
|
7108
|
+
* @param conditionCollector - The condition collector for validation context
|
|
7109
|
+
* @returns A Result containing the new resource declaration if successful, or failure if validation fails
|
|
7110
|
+
* @internal
|
|
7111
|
+
*/
|
|
7112
|
+
private static _createResourceDeclFromCandidates;
|
|
7054
7113
|
}
|
|
7055
7114
|
|
|
7056
7115
|
/**
|
|
@@ -7233,6 +7292,8 @@ declare type ResourceResolverCacheActivity = 'hit' | 'miss' | 'error' | 'clear';
|
|
|
7233
7292
|
*/
|
|
7234
7293
|
declare class ResourceResolverCacheMetricsListener<TM extends ICacheMetrics> implements IResourceResolverCacheListener {
|
|
7235
7294
|
private readonly _metrics;
|
|
7295
|
+
private _contextErrors;
|
|
7296
|
+
get numContextErrors(): number;
|
|
7236
7297
|
constructor(factory: () => TM);
|
|
7237
7298
|
constructor(metrics: OverallCacheMetrics<TM>);
|
|
7238
7299
|
/**
|
|
@@ -7252,6 +7313,10 @@ declare class ResourceResolverCacheMetricsListener<TM extends ICacheMetrics> imp
|
|
|
7252
7313
|
* {@inheritDoc Runtime.IResourceResolverCacheListener.onCacheError}
|
|
7253
7314
|
*/
|
|
7254
7315
|
onCacheError(cache: ResourceResolverCacheType, index: number): void;
|
|
7316
|
+
/**
|
|
7317
|
+
* {@inheritDoc Runtime.IResourceResolverCacheListener.onContextError}
|
|
7318
|
+
*/
|
|
7319
|
+
onContextError(qualifier: string, error: string): void;
|
|
7255
7320
|
/**
|
|
7256
7321
|
* {@inheritDoc Runtime.IResourceResolverCacheListener.onCacheClear}
|
|
7257
7322
|
*/
|
|
@@ -7286,7 +7351,8 @@ declare namespace Resources {
|
|
|
7286
7351
|
ResourceManagerBuilderResultDetail,
|
|
7287
7352
|
ResourceManagerBuilder,
|
|
7288
7353
|
IResourceDeclarationOptions,
|
|
7289
|
-
ICompiledResourceOptionsWithFilter
|
|
7354
|
+
ICompiledResourceOptionsWithFilter,
|
|
7355
|
+
IResourceManagerCloneOptions
|
|
7290
7356
|
}
|
|
7291
7357
|
}
|
|
7292
7358
|
export { Resources }
|
|
@@ -57,4 +57,16 @@ export interface ICompiledResourceOptionsWithFilter extends ResourceJson.Compile
|
|
|
57
57
|
*/
|
|
58
58
|
filterForContext?: IValidatedContextDecl;
|
|
59
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Options for ResourceManagerBuilder clone operations.
|
|
62
|
+
* Extends IDeclarationOptions to include support for applying edits when cloning.
|
|
63
|
+
* @public
|
|
64
|
+
*/
|
|
65
|
+
export interface IResourceManagerCloneOptions extends IResourceDeclarationOptions {
|
|
66
|
+
/**
|
|
67
|
+
* Optional array of loose condition declarations to be applied as edits during the clone operation.
|
|
68
|
+
* These conditions can modify or extend the resource candidates in the cloned manager.
|
|
69
|
+
*/
|
|
70
|
+
readonly candidates?: ReadonlyArray<ResourceJson.Json.ILooseResourceCandidateDecl>;
|
|
71
|
+
}
|
|
60
72
|
//# sourceMappingURL=common.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/packlets/resources/common.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,YAAY,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,2BAA4B,SAAQ,YAAY,CAAC,OAAO,CAAC,mBAAmB;IAC3F;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;IAEzC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;GAKG;AACH,MAAM,WAAW,kCAAmC,SAAQ,YAAY,CAAC,QAAQ,CAAC,wBAAwB;IACxG;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;CAC1C"}
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/packlets/resources/common.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,YAAY,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,2BAA4B,SAAQ,YAAY,CAAC,OAAO,CAAC,mBAAmB;IAC3F;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;IAEzC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;GAKG;AACH,MAAM,WAAW,kCAAmC,SAAQ,YAAY,CAAC,QAAQ,CAAC,wBAAwB;IACxG;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;CAC1C;AAED;;;;GAIG;AACH,MAAM,WAAW,4BAA6B,SAAQ,2BAA2B;IAC/E;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,YAAY,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;CACpF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/packlets/resources/common.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport * as ResourceJson from '../resource-json';\nimport { IValidatedContextDecl } from '../context';\n\n/**\n * Options for resource declaration operations with strongly-typed context filtering.\n * Extends the base IDeclarationOptions with proper type safety for context filtering.\n *\n * @example\n * ```typescript\n * // Preferred Result pattern with onSuccess chaining\n * resourceManager.validateContext({ language: 'en' })\n * .onSuccess((validatedContext) => {\n * return resourceManager.clone({ filterForContext: validatedContext });\n * })\n * .onSuccess((clonedManager) => {\n * return clonedManager.getResourceCollectionDecl();\n * })\n * .onFailure((error) => {\n * console.error('Failed to create filtered clone:', error);\n * });\n * ```\n * @public\n */\nexport interface IResourceDeclarationOptions extends ResourceJson.Helpers.IDeclarationOptions {\n /**\n * If provided, filters resource candidates to only include those that can match the\n * specified validated context. This provides strongly-typed context filtering.\n *\n * Use resourceManager.validateContext() to create a validated context from an IContextDecl.\n */\n filterForContext?: IValidatedContextDecl;\n\n /**\n * If true, reduces the qualifiers of the resource candidates by removing qualifiers that are made\n * irrelevant by the filterForContext.\n * @defaultValue false\n */\n reduceQualifiers?: boolean;\n\n /**\n * Whether to include metadata in compiled outputs.\n * Metadata includes human-readable information like semantic keys\n * that can be useful for debugging or tooling.\n * @defaultValue false\n */\n includeMetadata?: boolean;\n}\n\n/**\n * Extended compiled resource options that includes context filtering capabilities.\n * This interface combines the standard compilation options with strongly-typed\n * context filtering for resource candidates.\n * @public\n */\nexport interface ICompiledResourceOptionsWithFilter extends ResourceJson.Compiled.ICompiledResourceOptions {\n /**\n * If provided, filters resource candidates to only include those that can match the\n * specified validated context. This provides strongly-typed context filtering.\n *\n * Use resourceManager.validateContext() to create a validated context from an IContextDecl.\n */\n filterForContext?: IValidatedContextDecl;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/packlets/resources/common.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport * as ResourceJson from '../resource-json';\nimport { IValidatedContextDecl } from '../context';\n\n/**\n * Options for resource declaration operations with strongly-typed context filtering.\n * Extends the base IDeclarationOptions with proper type safety for context filtering.\n *\n * @example\n * ```typescript\n * // Preferred Result pattern with onSuccess chaining\n * resourceManager.validateContext({ language: 'en' })\n * .onSuccess((validatedContext) => {\n * return resourceManager.clone({ filterForContext: validatedContext });\n * })\n * .onSuccess((clonedManager) => {\n * return clonedManager.getResourceCollectionDecl();\n * })\n * .onFailure((error) => {\n * console.error('Failed to create filtered clone:', error);\n * });\n * ```\n * @public\n */\nexport interface IResourceDeclarationOptions extends ResourceJson.Helpers.IDeclarationOptions {\n /**\n * If provided, filters resource candidates to only include those that can match the\n * specified validated context. This provides strongly-typed context filtering.\n *\n * Use resourceManager.validateContext() to create a validated context from an IContextDecl.\n */\n filterForContext?: IValidatedContextDecl;\n\n /**\n * If true, reduces the qualifiers of the resource candidates by removing qualifiers that are made\n * irrelevant by the filterForContext.\n * @defaultValue false\n */\n reduceQualifiers?: boolean;\n\n /**\n * Whether to include metadata in compiled outputs.\n * Metadata includes human-readable information like semantic keys\n * that can be useful for debugging or tooling.\n * @defaultValue false\n */\n includeMetadata?: boolean;\n}\n\n/**\n * Extended compiled resource options that includes context filtering capabilities.\n * This interface combines the standard compilation options with strongly-typed\n * context filtering for resource candidates.\n * @public\n */\nexport interface ICompiledResourceOptionsWithFilter extends ResourceJson.Compiled.ICompiledResourceOptions {\n /**\n * If provided, filters resource candidates to only include those that can match the\n * specified validated context. This provides strongly-typed context filtering.\n *\n * Use resourceManager.validateContext() to create a validated context from an IContextDecl.\n */\n filterForContext?: IValidatedContextDecl;\n}\n\n/**\n * Options for ResourceManagerBuilder clone operations.\n * Extends IDeclarationOptions to include support for applying edits when cloning.\n * @public\n */\nexport interface IResourceManagerCloneOptions extends IResourceDeclarationOptions {\n /**\n * Optional array of loose condition declarations to be applied as edits during the clone operation.\n * These conditions can modify or extend the resource candidates in the cloned manager.\n */\n readonly candidates?: ReadonlyArray<ResourceJson.Json.ILooseResourceCandidateDecl>;\n}\n"]}
|
|
@@ -8,7 +8,7 @@ import { IResourceManager } from '../runtime';
|
|
|
8
8
|
import { ResourceBuilder, ResourceBuilderResultDetail } from './resourceBuilder';
|
|
9
9
|
import { Resource } from './resource';
|
|
10
10
|
import { ResourceCandidate } from './resourceCandidate';
|
|
11
|
-
import { IResourceDeclarationOptions } from './common';
|
|
11
|
+
import { IResourceDeclarationOptions, IResourceManagerCloneOptions } from './common';
|
|
12
12
|
import * as ResourceJson from '../resource-json';
|
|
13
13
|
import * as Context from '../context';
|
|
14
14
|
/**
|
|
@@ -211,10 +211,47 @@ export declare class ResourceManagerBuilder implements IResourceManager {
|
|
|
211
211
|
* Creates a filtered clone of this ResourceManagerBuilder using the specified context.
|
|
212
212
|
* This is a convenience method that creates a new ResourceManagerBuilder with the same
|
|
213
213
|
* configuration but filtered to include only candidates that match the provided context.
|
|
214
|
-
*
|
|
214
|
+
* If candidates are provided for editing, they will be applied with collision detection.
|
|
215
|
+
* @param options - Options for the cloning operation, including the strongly-typed filterForContext property and optional candidates for edits.
|
|
215
216
|
* @returns A Result containing the new filtered ResourceManagerBuilder.
|
|
216
217
|
* @public
|
|
217
218
|
*/
|
|
218
|
-
clone(options?:
|
|
219
|
+
clone(options?: IResourceManagerCloneOptions): Result<ResourceManagerBuilder>;
|
|
220
|
+
/**
|
|
221
|
+
* Creates a resource ID keyed map from an array of loose resource candidate declarations.
|
|
222
|
+
* This enables efficient detection of edit collisions by grouping candidates by their target resource.
|
|
223
|
+
* @param candidates - Array of loose resource candidate declarations to organize
|
|
224
|
+
* @returns A Result containing a Map where keys are validated ResourceIds and values are arrays of candidates for that resource
|
|
225
|
+
* @internal
|
|
226
|
+
*/
|
|
227
|
+
private static _createCandidatesByResourceMap;
|
|
228
|
+
/**
|
|
229
|
+
* Generates a proper ConditionSet token for collision detection using the existing ConditionSet.getKeyForDecl method.
|
|
230
|
+
* @param conditionSet - The condition set to generate a token for
|
|
231
|
+
* @param conditionCollector - The condition collector needed for validation context
|
|
232
|
+
* @returns A Result containing the ConditionSet token if successful, or failure if validation fails
|
|
233
|
+
* @internal
|
|
234
|
+
*/
|
|
235
|
+
private static _getConditionSetToken;
|
|
236
|
+
/**
|
|
237
|
+
* Applies candidate edits to a resource declaration, handling collisions using condition set tokens.
|
|
238
|
+
* If there's no collision, adds the candidate. If there's a collision, replaces the original candidate with the edit.
|
|
239
|
+
* @param resourceDecl - The original resource declaration to potentially modify
|
|
240
|
+
* @param candidatesByResource - Map of resource IDs to arrays of candidate edits
|
|
241
|
+
* @param conditionCollector - The condition collector needed for generating condition tokens
|
|
242
|
+
* @returns A Result containing the resource declaration to use (original or modified)
|
|
243
|
+
* @internal
|
|
244
|
+
*/
|
|
245
|
+
private static _applyEditsToResourceDeclaration;
|
|
246
|
+
/**
|
|
247
|
+
* Creates a new resource declaration from an array of candidate declarations.
|
|
248
|
+
* This is used when cloning to create new resources that don't exist in the original manager.
|
|
249
|
+
* @param resourceId - The validated resource ID for the new resource
|
|
250
|
+
* @param candidates - Array of loose candidate declarations for the new resource
|
|
251
|
+
* @param conditionCollector - The condition collector for validation context
|
|
252
|
+
* @returns A Result containing the new resource declaration if successful, or failure if validation fails
|
|
253
|
+
* @internal
|
|
254
|
+
*/
|
|
255
|
+
private static _createResourceDeclFromCandidates;
|
|
219
256
|
}
|
|
220
257
|
//# sourceMappingURL=resourceManagerBuilder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resourceManagerBuilder.d.ts","sourceRoot":"","sources":["../../../src/packlets/resources/resourceManagerBuilder.ts"],"names":[],"mappings":"AAsBA,OAAO,EAEL,WAAW,EACX,cAAc,EAMd,MAAM,EAGN,mBAAmB,EACpB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,kBAAkB,
|
|
1
|
+
{"version":3,"file":"resourceManagerBuilder.d.ts","sourceRoot":"","sources":["../../../src/packlets/resources/resourceManagerBuilder.ts"],"names":[],"mappings":"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"}
|
|
@@ -422,7 +422,8 @@ class ResourceManagerBuilder {
|
|
|
422
422
|
* Creates a filtered clone of this ResourceManagerBuilder using the specified context.
|
|
423
423
|
* This is a convenience method that creates a new ResourceManagerBuilder with the same
|
|
424
424
|
* configuration but filtered to include only candidates that match the provided context.
|
|
425
|
-
*
|
|
425
|
+
* If candidates are provided for editing, they will be applied with collision detection.
|
|
426
|
+
* @param options - Options for the cloning operation, including the strongly-typed filterForContext property and optional candidates for edits.
|
|
426
427
|
* @returns A Result containing the new filtered ResourceManagerBuilder.
|
|
427
428
|
* @public
|
|
428
429
|
*/
|
|
@@ -433,19 +434,196 @@ class ResourceManagerBuilder {
|
|
|
433
434
|
qualifiers: this.qualifiers,
|
|
434
435
|
resourceTypes: this.resourceTypes
|
|
435
436
|
}).onSuccess((newManager) => {
|
|
436
|
-
//
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
437
|
+
// Check if we have candidates to apply as edits
|
|
438
|
+
const editCandidates = (options === null || options === void 0 ? void 0 : options.candidates) || [];
|
|
439
|
+
const candidatesByResourceResult = editCandidates.length > 0
|
|
440
|
+
? ResourceManagerBuilder._createCandidatesByResourceMap(editCandidates)
|
|
441
|
+
: (0, ts_utils_1.succeed)(new Map());
|
|
442
|
+
return candidatesByResourceResult.onSuccess((candidatesByResource) => {
|
|
443
|
+
// Track which resource IDs have been processed from the original collection
|
|
444
|
+
const processedResourceIds = new Set();
|
|
445
|
+
// Add each resource from the filtered collection to the new manager
|
|
446
|
+
if (collection.resources) {
|
|
447
|
+
for (const resourceDecl of collection.resources) {
|
|
448
|
+
processedResourceIds.add(resourceDecl.id);
|
|
449
|
+
// Apply edits if there are candidates for this resource
|
|
450
|
+
const editedDeclResult = ResourceManagerBuilder._applyEditsToResourceDeclaration(resourceDecl, candidatesByResource, this._conditions);
|
|
451
|
+
if (editedDeclResult.isFailure()) {
|
|
452
|
+
return (0, ts_utils_1.fail)(`${resourceDecl.id}: Failed to apply edits: ${editedDeclResult.message}`);
|
|
453
|
+
}
|
|
454
|
+
const addResult = newManager.addResource(editedDeclResult.value);
|
|
455
|
+
if (addResult.isFailure()) {
|
|
456
|
+
return (0, ts_utils_1.fail)(`${resourceDecl.id}: Failed to add resource to cloned manager: ${addResult.message}`);
|
|
457
|
+
}
|
|
442
458
|
}
|
|
443
459
|
}
|
|
460
|
+
// Handle any remaining candidates that target new resources not in the original collection
|
|
461
|
+
const errors = new ts_utils_1.MessageAggregator();
|
|
462
|
+
for (const [resourceId, candidates] of candidatesByResource) {
|
|
463
|
+
if (!processedResourceIds.has(resourceId)) {
|
|
464
|
+
// Create a new resource declaration for candidates targeting a new resource ID
|
|
465
|
+
ResourceManagerBuilder._createResourceDeclFromCandidates(resourceId, candidates, this._conditions)
|
|
466
|
+
.withErrorFormat((e) => `${resourceId}: Failed to create new resource from candidates: ${e}`)
|
|
467
|
+
.onSuccess((newResourceDecl) => {
|
|
468
|
+
return newManager
|
|
469
|
+
.addResource(newResourceDecl)
|
|
470
|
+
.withErrorFormat((e) => `${resourceId}: Failed to add new resource to cloned manager: ${e}`);
|
|
471
|
+
})
|
|
472
|
+
.aggregateError(errors);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
return errors.returnOrReport((0, ts_utils_1.succeed)(newManager));
|
|
476
|
+
});
|
|
477
|
+
});
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Creates a resource ID keyed map from an array of loose resource candidate declarations.
|
|
482
|
+
* This enables efficient detection of edit collisions by grouping candidates by their target resource.
|
|
483
|
+
* @param candidates - Array of loose resource candidate declarations to organize
|
|
484
|
+
* @returns A Result containing a Map where keys are validated ResourceIds and values are arrays of candidates for that resource
|
|
485
|
+
* @internal
|
|
486
|
+
*/
|
|
487
|
+
static _createCandidatesByResourceMap(candidates) {
|
|
488
|
+
const candidatesByResource = new Map();
|
|
489
|
+
for (const candidate of candidates) {
|
|
490
|
+
const { value: resourceId, message } = common_1.Validate.toResourceId(candidate.id);
|
|
491
|
+
if (message !== undefined) {
|
|
492
|
+
return (0, ts_utils_1.fail)(`Invalid resource ID "${candidate.id}": ${message}`);
|
|
493
|
+
}
|
|
494
|
+
const existingCandidates = candidatesByResource.get(resourceId);
|
|
495
|
+
if (existingCandidates) {
|
|
496
|
+
existingCandidates.push(candidate);
|
|
497
|
+
}
|
|
498
|
+
else {
|
|
499
|
+
candidatesByResource.set(resourceId, [candidate]);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
return (0, ts_utils_1.succeed)(candidatesByResource);
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Generates a proper ConditionSet token for collision detection using the existing ConditionSet.getKeyForDecl method.
|
|
506
|
+
* @param conditionSet - The condition set to generate a token for
|
|
507
|
+
* @param conditionCollector - The condition collector needed for validation context
|
|
508
|
+
* @returns A Result containing the ConditionSet token if successful, or failure if validation fails
|
|
509
|
+
* @internal
|
|
510
|
+
*/
|
|
511
|
+
static _getConditionSetToken(conditionSet, conditionCollector) {
|
|
512
|
+
if (!conditionSet) {
|
|
513
|
+
return (0, ts_utils_1.succeed)(conditions_1.ConditionSet.UnconditionalKey);
|
|
514
|
+
}
|
|
515
|
+
// Convert ConditionSetDecl to IConditionSetDecl format
|
|
516
|
+
let conditionSetDecl;
|
|
517
|
+
if (Array.isArray(conditionSet)) {
|
|
518
|
+
// ConditionSetDeclAsArray: array of ILooseConditionDecl
|
|
519
|
+
conditionSetDecl = { conditions: conditionSet };
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
// ConditionSetDeclAsRecord: Record<string, string | IChildConditionDecl>
|
|
523
|
+
const conditions = Object.entries(conditionSet).map(([qualifierName, value]) => {
|
|
524
|
+
if (typeof value === 'string') {
|
|
525
|
+
return { qualifierName, value };
|
|
526
|
+
}
|
|
527
|
+
else {
|
|
528
|
+
return Object.assign({ qualifierName }, value);
|
|
444
529
|
}
|
|
445
|
-
return (0, ts_utils_1.succeed)(newManager);
|
|
446
530
|
});
|
|
531
|
+
conditionSetDecl = { conditions };
|
|
532
|
+
}
|
|
533
|
+
// Validate and convert to IValidatedConditionSetDecl
|
|
534
|
+
return conditions_1.Convert.validatedConditionSetDecl
|
|
535
|
+
.convert(conditionSetDecl, { conditions: conditionCollector })
|
|
536
|
+
.onSuccess((validatedDecl) => {
|
|
537
|
+
// Use proper ConditionSet.getKeyForDecl method to generate the token
|
|
538
|
+
return conditions_1.ConditionSet.getKeyForDecl(validatedDecl);
|
|
447
539
|
});
|
|
448
540
|
}
|
|
541
|
+
/**
|
|
542
|
+
* Applies candidate edits to a resource declaration, handling collisions using condition set tokens.
|
|
543
|
+
* If there's no collision, adds the candidate. If there's a collision, replaces the original candidate with the edit.
|
|
544
|
+
* @param resourceDecl - The original resource declaration to potentially modify
|
|
545
|
+
* @param candidatesByResource - Map of resource IDs to arrays of candidate edits
|
|
546
|
+
* @param conditionCollector - The condition collector needed for generating condition tokens
|
|
547
|
+
* @returns A Result containing the resource declaration to use (original or modified)
|
|
548
|
+
* @internal
|
|
549
|
+
*/
|
|
550
|
+
static _applyEditsToResourceDeclaration(resourceDecl, candidatesByResource, conditionCollector) {
|
|
551
|
+
const { value: resourceId, message } = common_1.Validate.toResourceId(resourceDecl.id);
|
|
552
|
+
if (message !== undefined) {
|
|
553
|
+
return (0, ts_utils_1.fail)(`Invalid resource ID "${resourceDecl.id}": ${message}`);
|
|
554
|
+
}
|
|
555
|
+
const editCandidates = candidatesByResource.get(resourceId);
|
|
556
|
+
if (!editCandidates || editCandidates.length === 0) {
|
|
557
|
+
return (0, ts_utils_1.succeed)(resourceDecl);
|
|
558
|
+
}
|
|
559
|
+
// Use Map approach: apply original candidates first, then replace with edits on collision
|
|
560
|
+
const candidatesByConditionKey = new Map();
|
|
561
|
+
// First, add all original candidates keyed by their condition set token
|
|
562
|
+
for (const candidate of resourceDecl.candidates || []) {
|
|
563
|
+
const conditionTokenResult = ResourceManagerBuilder._getConditionSetToken(candidate.conditions, conditionCollector);
|
|
564
|
+
if (conditionTokenResult.isFailure()) {
|
|
565
|
+
return (0, ts_utils_1.fail)(`Failed to generate condition token for original candidate: ${conditionTokenResult.message}`);
|
|
566
|
+
}
|
|
567
|
+
candidatesByConditionKey.set(conditionTokenResult.value, candidate);
|
|
568
|
+
}
|
|
569
|
+
// Then, apply edits (this replaces any colliding original candidates)
|
|
570
|
+
// Convert edit candidates (which have ids) to child candidates (without ids) for merging
|
|
571
|
+
for (const editCandidate of editCandidates) {
|
|
572
|
+
const conditionTokenResult = ResourceManagerBuilder._getConditionSetToken(editCandidate.conditions, conditionCollector);
|
|
573
|
+
if (conditionTokenResult.isFailure()) {
|
|
574
|
+
return (0, ts_utils_1.fail)(`Failed to generate condition token for edit candidate: ${conditionTokenResult.message}`);
|
|
575
|
+
}
|
|
576
|
+
const childCandidate = {
|
|
577
|
+
json: editCandidate.json,
|
|
578
|
+
conditions: editCandidate.conditions,
|
|
579
|
+
isPartial: editCandidate.isPartial,
|
|
580
|
+
mergeMethod: editCandidate.mergeMethod
|
|
581
|
+
};
|
|
582
|
+
candidatesByConditionKey.set(conditionTokenResult.value, childCandidate);
|
|
583
|
+
}
|
|
584
|
+
// Extract the final merged candidate list
|
|
585
|
+
const mergedCandidates = Array.from(candidatesByConditionKey.values());
|
|
586
|
+
const modifiedDecl = Object.assign(Object.assign({}, resourceDecl), { candidates: mergedCandidates });
|
|
587
|
+
return (0, ts_utils_1.succeed)(modifiedDecl);
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Creates a new resource declaration from an array of candidate declarations.
|
|
591
|
+
* This is used when cloning to create new resources that don't exist in the original manager.
|
|
592
|
+
* @param resourceId - The validated resource ID for the new resource
|
|
593
|
+
* @param candidates - Array of loose candidate declarations for the new resource
|
|
594
|
+
* @param conditionCollector - The condition collector for validation context
|
|
595
|
+
* @returns A Result containing the new resource declaration if successful, or failure if validation fails
|
|
596
|
+
* @internal
|
|
597
|
+
*/
|
|
598
|
+
static _createResourceDeclFromCandidates(resourceId, candidates, conditionCollector) {
|
|
599
|
+
// Convert candidate declarations to child candidate declarations
|
|
600
|
+
const childCandidates = [];
|
|
601
|
+
// Ensure we have candidates
|
|
602
|
+
if (candidates.length === 0) {
|
|
603
|
+
return (0, ts_utils_1.fail)('Cannot create resource declaration from empty candidates array');
|
|
604
|
+
}
|
|
605
|
+
// Extract resourceTypeName from the first candidate (all candidates for the same resource should have the same type)
|
|
606
|
+
const resourceTypeName = candidates[0].resourceTypeName;
|
|
607
|
+
if (!resourceTypeName) {
|
|
608
|
+
return (0, ts_utils_1.fail)('resourceTypeName is required for new resource candidates');
|
|
609
|
+
}
|
|
610
|
+
for (const candidate of candidates) {
|
|
611
|
+
const childCandidate = {
|
|
612
|
+
json: candidate.json,
|
|
613
|
+
conditions: candidate.conditions,
|
|
614
|
+
isPartial: candidate.isPartial,
|
|
615
|
+
mergeMethod: candidate.mergeMethod
|
|
616
|
+
};
|
|
617
|
+
childCandidates.push(childCandidate);
|
|
618
|
+
}
|
|
619
|
+
// Create the new resource declaration
|
|
620
|
+
const newResourceDecl = {
|
|
621
|
+
id: resourceId,
|
|
622
|
+
candidates: childCandidates,
|
|
623
|
+
resourceTypeName
|
|
624
|
+
};
|
|
625
|
+
return (0, ts_utils_1.succeed)(newResourceDecl);
|
|
626
|
+
}
|
|
449
627
|
}
|
|
450
628
|
exports.ResourceManagerBuilder = ResourceManagerBuilder;
|
|
451
629
|
//# sourceMappingURL=resourceManagerBuilder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resourceManagerBuilder.js","sourceRoot":"","sources":["../../../src/packlets/resources/resourceManagerBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport {\n captureResult,\n Collections,\n DetailedResult,\n fail,\n failWithDetail,\n Hash,\n mapResults,\n MessageAggregator,\n Result,\n succeed,\n succeedWithDetail,\n ValidatingResultMap\n} from '@fgv/ts-utils';\nimport {\n ConditionCollector,\n ConditionSetCollector,\n ReadOnlyConditionCollector,\n ReadOnlyConditionSetCollector\n} from '../conditions';\nimport { AbstractDecisionCollector, ReadOnlyAbstractDecisionCollector } from '../decisions';\nimport { IReadOnlyQualifierCollector } from '../qualifiers';\nimport { ReadOnlyResourceTypeCollector } from '../resource-types';\nimport { Convert, ResourceId, Validate } from '../common';\nimport { IResourceManager } from '../runtime';\nimport { ResourceBuilder, ResourceBuilderResultDetail } from './resourceBuilder';\nimport { Resource } from './resource';\nimport { ResourceCandidate } from './resourceCandidate';\nimport { IResourceDeclarationOptions } from './common';\nimport * as ResourceJson from '../resource-json';\nimport * as Context from '../context';\n\n/**\n * Interface for parameters to the {@link Resources.ResourceManagerBuilder.create | ResourceManagerBuilder create method}.\n * @public\n */\nexport interface IResourceManagerBuilderCreateParams {\n qualifiers: IReadOnlyQualifierCollector;\n resourceTypes: ReadOnlyResourceTypeCollector;\n}\n\n/**\n * Error details that can be returned by a {@link Resources.ResourceManagerBuilder | ResourceManagerBuilder}.\n * @public\n */\nexport type ResourceManagerBuilderResultDetail =\n | Collections.ResultMapResultDetail\n | ResourceBuilderResultDetail;\n\n/**\n * Builder for a collection of {@link Resources.Resource | resources}. Collects\n * {@link Resources.ResourceCandidate | candidates} for each resource into a\n * {@link Resources.ResourceBuilder | ResourceBuilder} per resource, validates them against each other,\n * and builds a collection of {@link Resources.Resource | resources} once all candidates are collected.\n * @public\n */\nexport class ResourceManagerBuilder implements IResourceManager {\n public readonly qualifiers: IReadOnlyQualifierCollector;\n public readonly resourceTypes: ReadOnlyResourceTypeCollector;\n\n protected readonly _conditions: ConditionCollector;\n protected readonly _conditionSets: ConditionSetCollector;\n protected readonly _decisions: AbstractDecisionCollector;\n protected readonly _resources: ValidatingResultMap<ResourceId, ResourceBuilder>;\n public readonly _builtResources: ValidatingResultMap<ResourceId, Resource>;\n\n protected _built: boolean;\n\n /**\n * A {@link Conditions.ConditionCollector | ConditionCollector} which\n * contains the {@link Conditions.Condition | conditions} used so far by\n * the {@link Resources.ResourceCandidate | resource candidates} in this manager.\n */\n public get conditions(): ReadOnlyConditionCollector {\n return this._conditions;\n }\n\n /**\n * A {@link Conditions.ConditionSetCollector | ConditionSetCollector} which\n * contains the {@link Conditions.ConditionSet | condition sets} used so far by\n * the {@link Resources.ResourceCandidate | resource candidates} in this manager.\n */\n public get conditionSets(): ReadOnlyConditionSetCollector {\n return this._conditionSets;\n }\n\n /**\n * A {@link Decisions.AbstractDecisionCollector | AbstractDecisionCollector} which\n * contains the {@link Decisions.Decision | abstract decisions} used so far by\n * the {@link Resources.ResourceCandidate | resource candidates} in this manager.\n */\n public get decisions(): ReadOnlyAbstractDecisionCollector {\n return this._decisions;\n }\n\n /**\n * A read-only map of {@link Resources.ResourceBuilder | resource builders} used by the manager.\n */\n public get resources(): Collections.IReadOnlyValidatingResultMap<ResourceId, ResourceBuilder> {\n return this._resources;\n }\n\n /**\n * The number of {@link Resources.Resource | resources} contained by the manager.\n */\n public get size(): number {\n return this._resources.size;\n }\n\n /**\n * {@inheritdoc Runtime.IResourceManager.numResources}\n */\n public get numResources(): number {\n return this._resources.size;\n }\n\n /**\n * The number of candidates in this resource manager.\n */\n protected _numCandidates?: number;\n\n /**\n * {@inheritdoc Runtime.IResourceManager.numCandidates}\n */\n public get numCandidates(): number {\n if (this._numCandidates === undefined) {\n this._numCandidates = this.getAllCandidates().length;\n }\n return this._numCandidates;\n }\n\n /**\n * {@inheritdoc Runtime.IResourceManager.builtResources}\n */\n public get builtResources(): Collections.IReadOnlyValidatingResultMap<ResourceId, Resource> {\n return this._performBuild().orThrow();\n }\n\n /**\n * Constructor for a {@link Resources.ResourceManagerBuilder | ResourceManagerBuilder} object.\n * @param params - Parameters to create a new {@link Resources.ResourceManagerBuilder | ResourceManagerBuilder}.\n * @public\n */\n protected constructor(params: IResourceManagerBuilderCreateParams) {\n this.qualifiers = params.qualifiers;\n this.resourceTypes = params.resourceTypes;\n this._conditions = ConditionCollector.create({ qualifiers: params.qualifiers }).orThrow();\n this._conditionSets = ConditionSetCollector.create({ conditions: this._conditions }).orThrow();\n this._decisions = AbstractDecisionCollector.create({ conditionSets: this._conditionSets }).orThrow();\n this._resources = new ValidatingResultMap({\n converters: new Collections.KeyValueConverters<ResourceId, ResourceBuilder>({\n key: Convert.resourceId,\n /* c8 ignore next 2 - defense in depth against internal error */\n value: (from: unknown) =>\n from instanceof ResourceBuilder ? succeed(from) : fail('not a resource builder')\n })\n });\n this._builtResources = new ValidatingResultMap({\n converters: new Collections.KeyValueConverters<ResourceId, Resource>({\n key: Convert.resourceId,\n /* c8 ignore next 1 - defense in depth against internal error */\n value: (from: unknown) => (from instanceof Resource ? succeed(from) : fail('not a resource'))\n })\n });\n this._built = false;\n }\n\n /**\n * Creates a new {@link Resources.ResourceManagerBuilder | ResourceManagerBuilder} object.\n * @param params - Parameters to create a new {@link Resources.ResourceManagerBuilder | ResourceManagerBuilder}.\n * @returns `Success` with the new {@link Resources.ResourceManagerBuilder | ResourceManagerBuilder} object if successful,\n * or `Failure` with an error message if not.\n * @public\n */\n public static create(params: IResourceManagerBuilderCreateParams): Result<ResourceManagerBuilder> {\n return captureResult(() => new ResourceManagerBuilder(params));\n }\n\n /**\n * Given a {@link ResourceJson.Json.ILooseResourceCandidateDecl | resource candidate declaration}, builds and adds\n * a {@link Resources.ResourceCandidate | candidate} to the manager.\n * @param candidate - The {@link Resources.ResourceCandidate | candidate} to add.\n * @returns `Success` with the candidate if successful, or `Failure` with an error message if not.\n * @public\n */\n public addLooseCandidate(\n decl: ResourceJson.Json.ILooseResourceCandidateDecl\n ): DetailedResult<ResourceCandidate, ResourceBuilderResultDetail> {\n const { value: id, message } = Validate.toResourceId(decl.id);\n if (message !== undefined) {\n return failWithDetail(`${id}: invalid id - ${message}`, 'failure');\n }\n\n const builderResult = this._resources.getOrAdd(id, () =>\n ResourceBuilder.create({\n id,\n resourceTypes: this.resourceTypes,\n conditionSets: this._conditionSets,\n decisions: this._decisions\n })\n );\n /* c8 ignore next 6 - defense in depth against internal error */\n if (builderResult.isFailure()) {\n return failWithDetail(\n `${id}: unable to get or add resource\\n${builderResult.message}`,\n builderResult.detail\n );\n }\n return builderResult.value.addLooseCandidate(decl).onSuccess((c, d) => {\n this._builtResources.delete(id);\n this._built = false;\n this._numCandidates = undefined;\n return succeedWithDetail(c, d);\n });\n }\n\n public addResource(\n decl: ResourceJson.Json.ILooseResourceDecl\n ): DetailedResult<ResourceBuilder, ResourceBuilderResultDetail> {\n const { value: id, message } = Validate.toResourceId(decl.id);\n if (message !== undefined) {\n return failWithDetail(`${id}: invalid id - ${message}`, 'failure');\n }\n\n const {\n value: builder,\n message: getOrAddMessage,\n detail\n } = this._resources.getOrAdd(id, () =>\n ResourceBuilder.create({\n id,\n typeName: decl.resourceTypeName,\n resourceTypes: this.resourceTypes,\n conditionSets: this._conditionSets,\n decisions: this._decisions\n })\n );\n /* c8 ignore next 3 - defense in depth against internal error */\n if (getOrAddMessage !== undefined) {\n return failWithDetail(`${id}: unable to get or add resource\\n${getOrAddMessage}`, detail);\n }\n\n if (detail === 'exists') {\n const { message } = builder.setResourceType(decl.resourceTypeName);\n if (message !== undefined) {\n return failWithDetail(`${id}: unable to set resource type\\n${message}`, 'type-mismatch');\n }\n }\n\n const candidates = decl.candidates ?? [];\n return mapResults(candidates.map((c) => builder.addChildCandidate(c)))\n .onSuccess(() => {\n return succeed(builder);\n })\n .withDetail('failure', detail);\n }\n\n /**\n * Gets a read-only array of all {@link Resources.ResourceBuilder | resource builders} present in the manager.\n * @returns `Success` with the {@link Resources.ResourceBuilder | resource builder} if successful,\n * or `Failure` with an error message if not.\n */\n public getAllResources(): ReadonlyArray<ResourceBuilder> {\n return Array.from(this._resources.values()).sort((a, b) => a.id.localeCompare(b.id));\n }\n\n /**\n * Gets a read-only array of all {@link Resources.ResourceCandidate | resource candidates} present in the manager.\n */\n public getAllCandidates(): ReadonlyArray<ResourceCandidate> {\n return this.getAllResources().flatMap((r) => r.candidates);\n }\n\n /**\n * Gets an individual {@link Resources.Resource | built resource} from the manager.\n * @param id - The {@link ResourceId | id} of the resource to get.\n * @returns `Success` with the resource if successful, or `Failure` with an error message if not.\n * @public\n */\n public getBuiltResource(id: string): Result<Resource> {\n return this._resources.validating\n .get(id)\n .onSuccess((builder) => this._builtResources.validating.getOrAdd(id, () => builder.build()));\n }\n\n /**\n * Validates a context declaration against the qualifiers managed by this resource manager.\n * @param context - The context declaration to validate\n * @returns Success with the validated context if successful, Failure otherwise\n * @public\n */\n /* c8 ignore next 5 - functional code path tested but coverage intermittently missed */\n public validateContext(context: Context.IContextDecl): Result<Context.IValidatedContextDecl> {\n return Context.Convert.validatedContextDecl.convert(context, {\n qualifiers: this.qualifiers\n });\n }\n\n /**\n * Gets a read-only array of all {@link Resources.Resource | built resources} in the manager.\n * @returns `Success` with an array of resources if successful, or `Failure` with an error message if not.\n * @public\n */\n public getAllBuiltResources(): Result<ReadonlyArray<Resource>> {\n return this.build().onSuccess((manager) =>\n succeed(Array.from(manager._builtResources.values()).sort((a, b) => a.id.localeCompare(b.id)))\n );\n }\n\n /**\n * Gets a read-only array of all {@link Resources.Resource | built resources} in the manager.\n * @returns `Success` with an array of resources if successful, or `Failure` with an error message if not.\n * @public\n */\n public getAllBuiltCandidates(): Result<ReadonlyArray<ResourceCandidate>> {\n return this.getAllBuiltResources().onSuccess((built) => succeed(built.flatMap((r) => r.candidates)));\n }\n\n /**\n * Internal helper method that performs the actual building of resources.\n * @returns `Success` with the built resources if all resources were built successfully, `Failure` otherwise.\n * @internal\n */\n public _performBuild(): Result<Collections.IReadOnlyValidatingResultMap<ResourceId, Resource>> {\n if (this._built) {\n return succeed(this._builtResources);\n }\n\n const errors: MessageAggregator = new MessageAggregator();\n this._resources.forEach((r, id) => {\n this._builtResources.getOrAdd(id, () => r.build()).aggregateError(errors);\n });\n /* c8 ignore next 3 - defense in depth against internal error */\n if (errors.hasMessages) {\n return fail(`build failed: ${errors.toString()}`);\n }\n this._built = true;\n return succeed(this._builtResources);\n }\n\n /**\n * Builds the {@link Resources.Resource | resources} from the collected {@link Resources.ResourceCandidate | candidates}.\n * @returns `Success` with the {@link Resources.ResourceManagerBuilder | ResourceManagerBuilder} object if successful,\n * or `Failure` with an error message if not.\n * @public\n */\n public build(): Result<this> {\n return this._performBuild().onSuccess(() => succeed(this));\n }\n\n /**\n * Gets a read-only array of all {@link Resources.ResourceCandidate | resource candidates} that can match the supplied context.\n * @param context - The {@link Context.IValidatedContextDecl | context} to match against.\n * @param options - {@link Context.IContextMatchOptions | options} for the context match.\n * @returns A read-only array of {@link Resources.ResourceCandidate | candidates} that can match the context.\n * @public\n */\n public getCandidatesForContext(\n context: Context.IValidatedContextDecl,\n options?: Context.IContextMatchOptions\n ): ReadonlyArray<ResourceCandidate> {\n return this.getAllCandidates().filter((candidate) => candidate.canMatchPartialContext(context, options));\n }\n\n /**\n * Gets a read-only array of all {@link Resources.ResourceBuilder | resource builders} that have at least one candidate\n * that can match the supplied context.\n * @param context - The {@link Context.IValidatedContextDecl | context} to match against.\n * @param options - {@link Context.IContextMatchOptions | options} for the context match.\n * @returns A read-only array of {@link Resources.ResourceBuilder | resource builders} with matching candidates.\n * @public\n */\n public getResourcesForContext(\n context: Context.IValidatedContextDecl,\n options?: Context.IContextMatchOptions\n ): ReadonlyArray<ResourceBuilder> {\n return this.getAllResources().filter(\n (resource) => resource.getCandidatesForContext(context, options).length > 0\n );\n }\n\n /**\n * Gets a read-only array of all {@link Resources.ResourceCandidate | built resource candidates} that can match the supplied context.\n * @param context - The {@link Context.IValidatedContextDecl | context} to match against.\n * @param options - {@link Context.IContextMatchOptions | options} for the context match.\n * @returns `Success` with an array of {@link Resources.ResourceCandidate | candidates} if successful, or `Failure` with an error message if not.\n * @public\n */\n public getBuiltCandidatesForContext(\n context: Context.IValidatedContextDecl,\n options?: Context.IContextMatchOptions\n ): Result<ReadonlyArray<ResourceCandidate>> {\n return this.getAllBuiltCandidates().onSuccess((candidates) =>\n succeed(candidates.filter((candidate) => candidate.canMatchPartialContext(context, options)))\n );\n }\n\n /**\n * Gets a read-only array of all {@link Resources.Resource | built resources} that have at least one candidate\n * that can match the supplied context.\n * @param context - The {@link Context.IValidatedContextDecl | context} to match against.\n * @param options - {@link Context.IContextMatchOptions | options} for the context match.\n * @returns `Success` with an array of {@link Resources.Resource | resources} if successful, or `Failure` with an error message if not.\n * @public\n */\n public getBuiltResourcesForContext(\n context: Context.IValidatedContextDecl,\n options?: Context.IContextMatchOptions\n ): Result<ReadonlyArray<Resource>> {\n return this.getAllBuiltResources().onSuccess((resources) =>\n succeed(resources.filter((resource) => resource.getCandidatesForContext(context, options).length > 0))\n );\n }\n\n /**\n * Gets a compiled resource collection from the current state of the resource manager builder.\n * This method generates an optimized, index-based representation of all resources, conditions,\n * and decisions that can be used for serialization or efficient runtime processing.\n * @param options - Optional compilation options controlling the output format.\n * @returns Success with the compiled resource collection if successful, Failure otherwise.\n * @public\n */\n public getCompiledResourceCollection(\n options?: ResourceJson.Compiled.ICompiledResourceOptions\n ): Result<ResourceJson.Compiled.ICompiledResourceCollection> {\n // Build resources first to ensure all data is available\n const buildResult = this._performBuild();\n if (buildResult.isFailure()) {\n return fail(`Failed to build resources: ${buildResult.message}`);\n }\n\n // Generate compiled data from internal collections using the new toCompiled methods\n // Note: All objects have a defined index property due to the collector pattern - indices are assigned during collection building\n const compiledData = {\n qualifierTypes: Array.from(this.qualifiers.qualifierTypes.values()).map((qt) => ({\n name: qt.name\n })),\n qualifiers: Array.from(this.qualifiers.values()).map((q) => ({\n name: q.name,\n type: q.type.index!,\n defaultPriority: q.defaultPriority\n })),\n resourceTypes: Array.from(this.resourceTypes.values()).map((rt) => ({\n name: rt.key\n })),\n conditions: Array.from(this._conditions.values()).map((c) => c.toCompiled(options)),\n conditionSets: Array.from(this._conditionSets.values()).map((cs) => cs.toCompiled(options)),\n decisions: Array.from(this._decisions.values()).map((d) => d.toCompiled(options)),\n resources: Array.from(this._builtResources.values()).map((r) => r.toCompiled(options))\n };\n\n // Apply validation through the converter\n return ResourceJson.Compiled.Convert.compiledResourceCollection.convert(compiledData);\n }\n\n /**\n * Gets a resource collection declaration containing all built resources in a flat array structure.\n * This method returns all built resources as an {@link ResourceJson.Normalized.IResourceCollectionDecl | IResourceCollectionDecl}\n * that can be used for serialization, export, or re-import. Resources are sorted by ID for consistent ordering.\n * @param options - Optional {@link Resources.IResourceDeclarationOptions | declaration options} controlling the output format.\n * If `options.normalized` is `true`, applies hash-based normalization for additional consistency guarantees.\n * @returns Success with the resource collection declaration if successful, Failure otherwise.\n * @public\n */\n public getResourceCollectionDecl(\n options?: IResourceDeclarationOptions\n ): Result<ResourceJson.Normalized.IResourceCollectionDecl> {\n return this._performBuild().onSuccess(() => {\n // Get all built resources and convert to loose resource declarations\n const resources = Array.from(this._builtResources.values()).map((resource) =>\n resource.toLooseResourceDecl(options)\n );\n\n // Sort resources by ID for consistent ordering\n resources.sort((a, b) => a.id.localeCompare(b.id));\n\n // Create the collection declaration structure\n const collectionData = {\n resources\n };\n\n // Convert and validate using the normalized converter\n return ResourceJson.Convert.resourceCollectionDecl\n .convert(collectionData)\n .onSuccess((compiledCollection) => {\n // Apply hash-based normalization only if requested\n if (options?.normalized === true) {\n const normalizer = new Hash.Crc32Normalizer();\n return normalizer\n .normalize(compiledCollection)\n .withErrorFormat((e) => `Failed to normalize resource collection: ${e}`);\n }\n return succeed(compiledCollection);\n });\n });\n }\n\n /**\n * Creates a filtered clone of this ResourceManagerBuilder using the specified context.\n * This is a convenience method that creates a new ResourceManagerBuilder with the same\n * configuration but filtered to include only candidates that match the provided context.\n * @param options - Options for the cloning operation, including the strongly-typed filterForContext property.\n * @returns A Result containing the new filtered ResourceManagerBuilder.\n * @public\n */\n /* c8 ignore next 21 - functional code path tested but coverage intermittently missed */\n public clone(options?: IResourceDeclarationOptions): Result<ResourceManagerBuilder> {\n return this.getResourceCollectionDecl(options).onSuccess((collection) => {\n return ResourceManagerBuilder.create({\n qualifiers: this.qualifiers,\n resourceTypes: this.resourceTypes\n }).onSuccess((newManager) => {\n // Add each resource from the filtered collection to the new manager\n if (collection.resources) {\n for (const resourceDecl of collection.resources) {\n const addResult = newManager.addResource(resourceDecl);\n if (addResult.isFailure()) {\n return fail(\n `${resourceDecl.id}: Failed to add resource to cloned manager: ${addResult.message}`\n );\n }\n }\n }\n return succeed(newManager);\n });\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"resourceManagerBuilder.js","sourceRoot":"","sources":["../../../src/packlets/resources/resourceManagerBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport {\n captureResult,\n Collections,\n DetailedResult,\n fail,\n failWithDetail,\n Hash,\n mapResults,\n MessageAggregator,\n Result,\n succeed,\n succeedWithDetail,\n ValidatingResultMap\n} from '@fgv/ts-utils';\nimport {\n ConditionCollector,\n ConditionSet,\n ConditionSetCollector,\n ReadOnlyConditionCollector,\n ReadOnlyConditionSetCollector,\n Convert as ConditionsConvert\n} from '../conditions';\nimport { AbstractDecisionCollector, ReadOnlyAbstractDecisionCollector } from '../decisions';\nimport { IReadOnlyQualifierCollector } from '../qualifiers';\nimport { ReadOnlyResourceTypeCollector } from '../resource-types';\nimport { Convert, ResourceId, Validate } from '../common';\nimport { IResourceManager } from '../runtime';\nimport { ResourceBuilder, ResourceBuilderResultDetail } from './resourceBuilder';\nimport { Resource } from './resource';\nimport { ResourceCandidate } from './resourceCandidate';\nimport { IResourceDeclarationOptions, IResourceManagerCloneOptions } from './common';\nimport * as ResourceJson from '../resource-json';\nimport * as Context from '../context';\n\n/**\n * Interface for parameters to the {@link Resources.ResourceManagerBuilder.create | ResourceManagerBuilder create method}.\n * @public\n */\nexport interface IResourceManagerBuilderCreateParams {\n qualifiers: IReadOnlyQualifierCollector;\n resourceTypes: ReadOnlyResourceTypeCollector;\n}\n\n/**\n * Error details that can be returned by a {@link Resources.ResourceManagerBuilder | ResourceManagerBuilder}.\n * @public\n */\nexport type ResourceManagerBuilderResultDetail =\n | Collections.ResultMapResultDetail\n | ResourceBuilderResultDetail;\n\n/**\n * Builder for a collection of {@link Resources.Resource | resources}. Collects\n * {@link Resources.ResourceCandidate | candidates} for each resource into a\n * {@link Resources.ResourceBuilder | ResourceBuilder} per resource, validates them against each other,\n * and builds a collection of {@link Resources.Resource | resources} once all candidates are collected.\n * @public\n */\nexport class ResourceManagerBuilder implements IResourceManager {\n public readonly qualifiers: IReadOnlyQualifierCollector;\n public readonly resourceTypes: ReadOnlyResourceTypeCollector;\n\n protected readonly _conditions: ConditionCollector;\n protected readonly _conditionSets: ConditionSetCollector;\n protected readonly _decisions: AbstractDecisionCollector;\n protected readonly _resources: ValidatingResultMap<ResourceId, ResourceBuilder>;\n public readonly _builtResources: ValidatingResultMap<ResourceId, Resource>;\n\n protected _built: boolean;\n\n /**\n * A {@link Conditions.ConditionCollector | ConditionCollector} which\n * contains the {@link Conditions.Condition | conditions} used so far by\n * the {@link Resources.ResourceCandidate | resource candidates} in this manager.\n */\n public get conditions(): ReadOnlyConditionCollector {\n return this._conditions;\n }\n\n /**\n * A {@link Conditions.ConditionSetCollector | ConditionSetCollector} which\n * contains the {@link Conditions.ConditionSet | condition sets} used so far by\n * the {@link Resources.ResourceCandidate | resource candidates} in this manager.\n */\n public get conditionSets(): ReadOnlyConditionSetCollector {\n return this._conditionSets;\n }\n\n /**\n * A {@link Decisions.AbstractDecisionCollector | AbstractDecisionCollector} which\n * contains the {@link Decisions.Decision | abstract decisions} used so far by\n * the {@link Resources.ResourceCandidate | resource candidates} in this manager.\n */\n public get decisions(): ReadOnlyAbstractDecisionCollector {\n return this._decisions;\n }\n\n /**\n * A read-only map of {@link Resources.ResourceBuilder | resource builders} used by the manager.\n */\n public get resources(): Collections.IReadOnlyValidatingResultMap<ResourceId, ResourceBuilder> {\n return this._resources;\n }\n\n /**\n * The number of {@link Resources.Resource | resources} contained by the manager.\n */\n public get size(): number {\n return this._resources.size;\n }\n\n /**\n * {@inheritdoc Runtime.IResourceManager.numResources}\n */\n public get numResources(): number {\n return this._resources.size;\n }\n\n /**\n * The number of candidates in this resource manager.\n */\n protected _numCandidates?: number;\n\n /**\n * {@inheritdoc Runtime.IResourceManager.numCandidates}\n */\n public get numCandidates(): number {\n if (this._numCandidates === undefined) {\n this._numCandidates = this.getAllCandidates().length;\n }\n return this._numCandidates;\n }\n\n /**\n * {@inheritdoc Runtime.IResourceManager.builtResources}\n */\n public get builtResources(): Collections.IReadOnlyValidatingResultMap<ResourceId, Resource> {\n return this._performBuild().orThrow();\n }\n\n /**\n * Constructor for a {@link Resources.ResourceManagerBuilder | ResourceManagerBuilder} object.\n * @param params - Parameters to create a new {@link Resources.ResourceManagerBuilder | ResourceManagerBuilder}.\n * @public\n */\n protected constructor(params: IResourceManagerBuilderCreateParams) {\n this.qualifiers = params.qualifiers;\n this.resourceTypes = params.resourceTypes;\n this._conditions = ConditionCollector.create({ qualifiers: params.qualifiers }).orThrow();\n this._conditionSets = ConditionSetCollector.create({ conditions: this._conditions }).orThrow();\n this._decisions = AbstractDecisionCollector.create({ conditionSets: this._conditionSets }).orThrow();\n this._resources = new ValidatingResultMap({\n converters: new Collections.KeyValueConverters<ResourceId, ResourceBuilder>({\n key: Convert.resourceId,\n /* c8 ignore next 2 - defense in depth against internal error */\n value: (from: unknown) =>\n from instanceof ResourceBuilder ? succeed(from) : fail('not a resource builder')\n })\n });\n this._builtResources = new ValidatingResultMap({\n converters: new Collections.KeyValueConverters<ResourceId, Resource>({\n key: Convert.resourceId,\n /* c8 ignore next 1 - defense in depth against internal error */\n value: (from: unknown) => (from instanceof Resource ? succeed(from) : fail('not a resource'))\n })\n });\n this._built = false;\n }\n\n /**\n * Creates a new {@link Resources.ResourceManagerBuilder | ResourceManagerBuilder} object.\n * @param params - Parameters to create a new {@link Resources.ResourceManagerBuilder | ResourceManagerBuilder}.\n * @returns `Success` with the new {@link Resources.ResourceManagerBuilder | ResourceManagerBuilder} object if successful,\n * or `Failure` with an error message if not.\n * @public\n */\n public static create(params: IResourceManagerBuilderCreateParams): Result<ResourceManagerBuilder> {\n return captureResult(() => new ResourceManagerBuilder(params));\n }\n\n /**\n * Given a {@link ResourceJson.Json.ILooseResourceCandidateDecl | resource candidate declaration}, builds and adds\n * a {@link Resources.ResourceCandidate | candidate} to the manager.\n * @param candidate - The {@link Resources.ResourceCandidate | candidate} to add.\n * @returns `Success` with the candidate if successful, or `Failure` with an error message if not.\n * @public\n */\n public addLooseCandidate(\n decl: ResourceJson.Json.ILooseResourceCandidateDecl\n ): DetailedResult<ResourceCandidate, ResourceBuilderResultDetail> {\n const { value: id, message } = Validate.toResourceId(decl.id);\n if (message !== undefined) {\n return failWithDetail(`${id}: invalid id - ${message}`, 'failure');\n }\n\n const builderResult = this._resources.getOrAdd(id, () =>\n ResourceBuilder.create({\n id,\n resourceTypes: this.resourceTypes,\n conditionSets: this._conditionSets,\n decisions: this._decisions\n })\n );\n /* c8 ignore next 6 - defense in depth against internal error */\n if (builderResult.isFailure()) {\n return failWithDetail(\n `${id}: unable to get or add resource\\n${builderResult.message}`,\n builderResult.detail\n );\n }\n return builderResult.value.addLooseCandidate(decl).onSuccess((c, d) => {\n this._builtResources.delete(id);\n this._built = false;\n this._numCandidates = undefined;\n return succeedWithDetail(c, d);\n });\n }\n\n public addResource(\n decl: ResourceJson.Json.ILooseResourceDecl\n ): DetailedResult<ResourceBuilder, ResourceBuilderResultDetail> {\n const { value: id, message } = Validate.toResourceId(decl.id);\n if (message !== undefined) {\n return failWithDetail(`${id}: invalid id - ${message}`, 'failure');\n }\n\n const {\n value: builder,\n message: getOrAddMessage,\n detail\n } = this._resources.getOrAdd(id, () =>\n ResourceBuilder.create({\n id,\n typeName: decl.resourceTypeName,\n resourceTypes: this.resourceTypes,\n conditionSets: this._conditionSets,\n decisions: this._decisions\n })\n );\n /* c8 ignore next 3 - defense in depth against internal error */\n if (getOrAddMessage !== undefined) {\n return failWithDetail(`${id}: unable to get or add resource\\n${getOrAddMessage}`, detail);\n }\n\n if (detail === 'exists') {\n const { message } = builder.setResourceType(decl.resourceTypeName);\n if (message !== undefined) {\n return failWithDetail(`${id}: unable to set resource type\\n${message}`, 'type-mismatch');\n }\n }\n\n const candidates = decl.candidates ?? [];\n return mapResults(candidates.map((c) => builder.addChildCandidate(c)))\n .onSuccess(() => {\n return succeed(builder);\n })\n .withDetail('failure', detail);\n }\n\n /**\n * Gets a read-only array of all {@link Resources.ResourceBuilder | resource builders} present in the manager.\n * @returns `Success` with the {@link Resources.ResourceBuilder | resource builder} if successful,\n * or `Failure` with an error message if not.\n */\n public getAllResources(): ReadonlyArray<ResourceBuilder> {\n return Array.from(this._resources.values()).sort((a, b) => a.id.localeCompare(b.id));\n }\n\n /**\n * Gets a read-only array of all {@link Resources.ResourceCandidate | resource candidates} present in the manager.\n */\n public getAllCandidates(): ReadonlyArray<ResourceCandidate> {\n return this.getAllResources().flatMap((r) => r.candidates);\n }\n\n /**\n * Gets an individual {@link Resources.Resource | built resource} from the manager.\n * @param id - The {@link ResourceId | id} of the resource to get.\n * @returns `Success` with the resource if successful, or `Failure` with an error message if not.\n * @public\n */\n public getBuiltResource(id: string): Result<Resource> {\n return this._resources.validating\n .get(id)\n .onSuccess((builder) => this._builtResources.validating.getOrAdd(id, () => builder.build()));\n }\n\n /**\n * Validates a context declaration against the qualifiers managed by this resource manager.\n * @param context - The context declaration to validate\n * @returns Success with the validated context if successful, Failure otherwise\n * @public\n */\n /* c8 ignore next 5 - functional code path tested but coverage intermittently missed */\n public validateContext(context: Context.IContextDecl): Result<Context.IValidatedContextDecl> {\n return Context.Convert.validatedContextDecl.convert(context, {\n qualifiers: this.qualifiers\n });\n }\n\n /**\n * Gets a read-only array of all {@link Resources.Resource | built resources} in the manager.\n * @returns `Success` with an array of resources if successful, or `Failure` with an error message if not.\n * @public\n */\n public getAllBuiltResources(): Result<ReadonlyArray<Resource>> {\n return this.build().onSuccess((manager) =>\n succeed(Array.from(manager._builtResources.values()).sort((a, b) => a.id.localeCompare(b.id)))\n );\n }\n\n /**\n * Gets a read-only array of all {@link Resources.Resource | built resources} in the manager.\n * @returns `Success` with an array of resources if successful, or `Failure` with an error message if not.\n * @public\n */\n public getAllBuiltCandidates(): Result<ReadonlyArray<ResourceCandidate>> {\n return this.getAllBuiltResources().onSuccess((built) => succeed(built.flatMap((r) => r.candidates)));\n }\n\n /**\n * Internal helper method that performs the actual building of resources.\n * @returns `Success` with the built resources if all resources were built successfully, `Failure` otherwise.\n * @internal\n */\n public _performBuild(): Result<Collections.IReadOnlyValidatingResultMap<ResourceId, Resource>> {\n if (this._built) {\n return succeed(this._builtResources);\n }\n\n const errors: MessageAggregator = new MessageAggregator();\n this._resources.forEach((r, id) => {\n this._builtResources.getOrAdd(id, () => r.build()).aggregateError(errors);\n });\n /* c8 ignore next 3 - defense in depth against internal error */\n if (errors.hasMessages) {\n return fail(`build failed: ${errors.toString()}`);\n }\n this._built = true;\n return succeed(this._builtResources);\n }\n\n /**\n * Builds the {@link Resources.Resource | resources} from the collected {@link Resources.ResourceCandidate | candidates}.\n * @returns `Success` with the {@link Resources.ResourceManagerBuilder | ResourceManagerBuilder} object if successful,\n * or `Failure` with an error message if not.\n * @public\n */\n public build(): Result<this> {\n return this._performBuild().onSuccess(() => succeed(this));\n }\n\n /**\n * Gets a read-only array of all {@link Resources.ResourceCandidate | resource candidates} that can match the supplied context.\n * @param context - The {@link Context.IValidatedContextDecl | context} to match against.\n * @param options - {@link Context.IContextMatchOptions | options} for the context match.\n * @returns A read-only array of {@link Resources.ResourceCandidate | candidates} that can match the context.\n * @public\n */\n public getCandidatesForContext(\n context: Context.IValidatedContextDecl,\n options?: Context.IContextMatchOptions\n ): ReadonlyArray<ResourceCandidate> {\n return this.getAllCandidates().filter((candidate) => candidate.canMatchPartialContext(context, options));\n }\n\n /**\n * Gets a read-only array of all {@link Resources.ResourceBuilder | resource builders} that have at least one candidate\n * that can match the supplied context.\n * @param context - The {@link Context.IValidatedContextDecl | context} to match against.\n * @param options - {@link Context.IContextMatchOptions | options} for the context match.\n * @returns A read-only array of {@link Resources.ResourceBuilder | resource builders} with matching candidates.\n * @public\n */\n public getResourcesForContext(\n context: Context.IValidatedContextDecl,\n options?: Context.IContextMatchOptions\n ): ReadonlyArray<ResourceBuilder> {\n return this.getAllResources().filter(\n (resource) => resource.getCandidatesForContext(context, options).length > 0\n );\n }\n\n /**\n * Gets a read-only array of all {@link Resources.ResourceCandidate | built resource candidates} that can match the supplied context.\n * @param context - The {@link Context.IValidatedContextDecl | context} to match against.\n * @param options - {@link Context.IContextMatchOptions | options} for the context match.\n * @returns `Success` with an array of {@link Resources.ResourceCandidate | candidates} if successful, or `Failure` with an error message if not.\n * @public\n */\n public getBuiltCandidatesForContext(\n context: Context.IValidatedContextDecl,\n options?: Context.IContextMatchOptions\n ): Result<ReadonlyArray<ResourceCandidate>> {\n return this.getAllBuiltCandidates().onSuccess((candidates) =>\n succeed(candidates.filter((candidate) => candidate.canMatchPartialContext(context, options)))\n );\n }\n\n /**\n * Gets a read-only array of all {@link Resources.Resource | built resources} that have at least one candidate\n * that can match the supplied context.\n * @param context - The {@link Context.IValidatedContextDecl | context} to match against.\n * @param options - {@link Context.IContextMatchOptions | options} for the context match.\n * @returns `Success` with an array of {@link Resources.Resource | resources} if successful, or `Failure` with an error message if not.\n * @public\n */\n public getBuiltResourcesForContext(\n context: Context.IValidatedContextDecl,\n options?: Context.IContextMatchOptions\n ): Result<ReadonlyArray<Resource>> {\n return this.getAllBuiltResources().onSuccess((resources) =>\n succeed(resources.filter((resource) => resource.getCandidatesForContext(context, options).length > 0))\n );\n }\n\n /**\n * Gets a compiled resource collection from the current state of the resource manager builder.\n * This method generates an optimized, index-based representation of all resources, conditions,\n * and decisions that can be used for serialization or efficient runtime processing.\n * @param options - Optional compilation options controlling the output format.\n * @returns Success with the compiled resource collection if successful, Failure otherwise.\n * @public\n */\n public getCompiledResourceCollection(\n options?: ResourceJson.Compiled.ICompiledResourceOptions\n ): Result<ResourceJson.Compiled.ICompiledResourceCollection> {\n // Build resources first to ensure all data is available\n const buildResult = this._performBuild();\n if (buildResult.isFailure()) {\n return fail(`Failed to build resources: ${buildResult.message}`);\n }\n\n // Generate compiled data from internal collections using the new toCompiled methods\n // Note: All objects have a defined index property due to the collector pattern - indices are assigned during collection building\n const compiledData = {\n qualifierTypes: Array.from(this.qualifiers.qualifierTypes.values()).map((qt) => ({\n name: qt.name\n })),\n qualifiers: Array.from(this.qualifiers.values()).map((q) => ({\n name: q.name,\n type: q.type.index!,\n defaultPriority: q.defaultPriority\n })),\n resourceTypes: Array.from(this.resourceTypes.values()).map((rt) => ({\n name: rt.key\n })),\n conditions: Array.from(this._conditions.values()).map((c) => c.toCompiled(options)),\n conditionSets: Array.from(this._conditionSets.values()).map((cs) => cs.toCompiled(options)),\n decisions: Array.from(this._decisions.values()).map((d) => d.toCompiled(options)),\n resources: Array.from(this._builtResources.values()).map((r) => r.toCompiled(options))\n };\n\n // Apply validation through the converter\n return ResourceJson.Compiled.Convert.compiledResourceCollection.convert(compiledData);\n }\n\n /**\n * Gets a resource collection declaration containing all built resources in a flat array structure.\n * This method returns all built resources as an {@link ResourceJson.Normalized.IResourceCollectionDecl | IResourceCollectionDecl}\n * that can be used for serialization, export, or re-import. Resources are sorted by ID for consistent ordering.\n * @param options - Optional {@link Resources.IResourceDeclarationOptions | declaration options} controlling the output format.\n * If `options.normalized` is `true`, applies hash-based normalization for additional consistency guarantees.\n * @returns Success with the resource collection declaration if successful, Failure otherwise.\n * @public\n */\n public getResourceCollectionDecl(\n options?: IResourceDeclarationOptions\n ): Result<ResourceJson.Normalized.IResourceCollectionDecl> {\n return this._performBuild().onSuccess(() => {\n // Get all built resources and convert to loose resource declarations\n const resources = Array.from(this._builtResources.values()).map((resource) =>\n resource.toLooseResourceDecl(options)\n );\n\n // Sort resources by ID for consistent ordering\n resources.sort((a, b) => a.id.localeCompare(b.id));\n\n // Create the collection declaration structure\n const collectionData = {\n resources\n };\n\n // Convert and validate using the normalized converter\n return ResourceJson.Convert.resourceCollectionDecl\n .convert(collectionData)\n .onSuccess((compiledCollection) => {\n // Apply hash-based normalization only if requested\n if (options?.normalized === true) {\n const normalizer = new Hash.Crc32Normalizer();\n return normalizer\n .normalize(compiledCollection)\n .withErrorFormat((e) => `Failed to normalize resource collection: ${e}`);\n }\n return succeed(compiledCollection);\n });\n });\n }\n\n /**\n * Creates a filtered clone of this ResourceManagerBuilder using the specified context.\n * This is a convenience method that creates a new ResourceManagerBuilder with the same\n * configuration but filtered to include only candidates that match the provided context.\n * If candidates are provided for editing, they will be applied with collision detection.\n * @param options - Options for the cloning operation, including the strongly-typed filterForContext property and optional candidates for edits.\n * @returns A Result containing the new filtered ResourceManagerBuilder.\n * @public\n */\n /* c8 ignore next 21 - functional code path tested but coverage intermittently missed */\n public clone(options?: IResourceManagerCloneOptions): Result<ResourceManagerBuilder> {\n return this.getResourceCollectionDecl(options).onSuccess((collection) => {\n return ResourceManagerBuilder.create({\n qualifiers: this.qualifiers,\n resourceTypes: this.resourceTypes\n }).onSuccess((newManager) => {\n // Check if we have candidates to apply as edits\n const editCandidates = options?.candidates || [];\n const candidatesByResourceResult =\n editCandidates.length > 0\n ? ResourceManagerBuilder._createCandidatesByResourceMap(editCandidates)\n : succeed(new Map());\n\n return candidatesByResourceResult.onSuccess((candidatesByResource) => {\n // Track which resource IDs have been processed from the original collection\n const processedResourceIds = new Set<ResourceId>();\n\n // Add each resource from the filtered collection to the new manager\n if (collection.resources) {\n for (const resourceDecl of collection.resources) {\n processedResourceIds.add(resourceDecl.id as ResourceId);\n\n // Apply edits if there are candidates for this resource\n const editedDeclResult = ResourceManagerBuilder._applyEditsToResourceDeclaration(\n resourceDecl,\n candidatesByResource,\n this._conditions\n );\n\n if (editedDeclResult.isFailure()) {\n return fail(`${resourceDecl.id}: Failed to apply edits: ${editedDeclResult.message}`);\n }\n\n const addResult = newManager.addResource(editedDeclResult.value);\n if (addResult.isFailure()) {\n return fail(\n `${resourceDecl.id}: Failed to add resource to cloned manager: ${addResult.message}`\n );\n }\n }\n }\n\n // Handle any remaining candidates that target new resources not in the original collection\n const errors = new MessageAggregator();\n for (const [resourceId, candidates] of candidatesByResource) {\n if (!processedResourceIds.has(resourceId)) {\n // Create a new resource declaration for candidates targeting a new resource ID\n ResourceManagerBuilder._createResourceDeclFromCandidates(\n resourceId,\n candidates,\n this._conditions\n )\n .withErrorFormat((e) => `${resourceId}: Failed to create new resource from candidates: ${e}`)\n .onSuccess((newResourceDecl) => {\n return newManager\n .addResource(newResourceDecl)\n .withErrorFormat(\n (e) => `${resourceId}: Failed to add new resource to cloned manager: ${e}`\n );\n })\n .aggregateError(errors);\n }\n }\n\n return errors.returnOrReport(succeed(newManager));\n });\n });\n });\n }\n\n /**\n * Creates a resource ID keyed map from an array of loose resource candidate declarations.\n * This enables efficient detection of edit collisions by grouping candidates by their target resource.\n * @param candidates - Array of loose resource candidate declarations to organize\n * @returns A Result containing a Map where keys are validated ResourceIds and values are arrays of candidates for that resource\n * @internal\n */\n private static _createCandidatesByResourceMap(\n candidates: ReadonlyArray<ResourceJson.Json.ILooseResourceCandidateDecl>\n ): Result<Map<ResourceId, ResourceJson.Json.ILooseResourceCandidateDecl[]>> {\n const candidatesByResource = new Map<ResourceId, ResourceJson.Json.ILooseResourceCandidateDecl[]>();\n\n for (const candidate of candidates) {\n const { value: resourceId, message } = Validate.toResourceId(candidate.id);\n if (message !== undefined) {\n return fail(`Invalid resource ID \"${candidate.id}\": ${message}`);\n }\n\n const existingCandidates = candidatesByResource.get(resourceId);\n if (existingCandidates) {\n existingCandidates.push(candidate);\n } else {\n candidatesByResource.set(resourceId, [candidate]);\n }\n }\n\n return succeed(candidatesByResource);\n }\n\n /**\n * Generates a proper ConditionSet token for collision detection using the existing ConditionSet.getKeyForDecl method.\n * @param conditionSet - The condition set to generate a token for\n * @param conditionCollector - The condition collector needed for validation context\n * @returns A Result containing the ConditionSet token if successful, or failure if validation fails\n * @internal\n */\n private static _getConditionSetToken(\n conditionSet: ResourceJson.Json.ConditionSetDecl | undefined,\n conditionCollector: ConditionCollector\n ): Result<string> {\n if (!conditionSet) {\n return succeed(ConditionSet.UnconditionalKey);\n }\n\n // Convert ConditionSetDecl to IConditionSetDecl format\n let conditionSetDecl: { conditions: ResourceJson.Json.ILooseConditionDecl[] };\n\n if (Array.isArray(conditionSet)) {\n // ConditionSetDeclAsArray: array of ILooseConditionDecl\n conditionSetDecl = { conditions: conditionSet };\n } else {\n // ConditionSetDeclAsRecord: Record<string, string | IChildConditionDecl>\n const conditions = Object.entries(conditionSet).map(([qualifierName, value]) => {\n if (typeof value === 'string') {\n return { qualifierName, value };\n } else {\n return { qualifierName, ...value };\n }\n });\n conditionSetDecl = { conditions };\n }\n\n // Validate and convert to IValidatedConditionSetDecl\n return ConditionsConvert.validatedConditionSetDecl\n .convert(conditionSetDecl, { conditions: conditionCollector })\n .onSuccess((validatedDecl) => {\n // Use proper ConditionSet.getKeyForDecl method to generate the token\n return ConditionSet.getKeyForDecl(validatedDecl);\n });\n }\n\n /**\n * Applies candidate edits to a resource declaration, handling collisions using condition set tokens.\n * If there's no collision, adds the candidate. If there's a collision, replaces the original candidate with the edit.\n * @param resourceDecl - The original resource declaration to potentially modify\n * @param candidatesByResource - Map of resource IDs to arrays of candidate edits\n * @param conditionCollector - The condition collector needed for generating condition tokens\n * @returns A Result containing the resource declaration to use (original or modified)\n * @internal\n */\n private static _applyEditsToResourceDeclaration(\n resourceDecl: ResourceJson.Json.ILooseResourceDecl,\n candidatesByResource: Map<ResourceId, ResourceJson.Json.ILooseResourceCandidateDecl[]>,\n conditionCollector: ConditionCollector\n ): Result<ResourceJson.Json.ILooseResourceDecl> {\n const { value: resourceId, message } = Validate.toResourceId(resourceDecl.id);\n if (message !== undefined) {\n return fail(`Invalid resource ID \"${resourceDecl.id}\": ${message}`);\n }\n\n const editCandidates = candidatesByResource.get(resourceId);\n if (!editCandidates || editCandidates.length === 0) {\n return succeed(resourceDecl);\n }\n\n // Use Map approach: apply original candidates first, then replace with edits on collision\n const candidatesByConditionKey = new Map<string, ResourceJson.Json.IChildResourceCandidateDecl>();\n\n // First, add all original candidates keyed by their condition set token\n for (const candidate of resourceDecl.candidates || []) {\n const conditionTokenResult = ResourceManagerBuilder._getConditionSetToken(\n candidate.conditions,\n conditionCollector\n );\n if (conditionTokenResult.isFailure()) {\n return fail(\n `Failed to generate condition token for original candidate: ${conditionTokenResult.message}`\n );\n }\n candidatesByConditionKey.set(conditionTokenResult.value, candidate);\n }\n\n // Then, apply edits (this replaces any colliding original candidates)\n // Convert edit candidates (which have ids) to child candidates (without ids) for merging\n for (const editCandidate of editCandidates) {\n const conditionTokenResult = ResourceManagerBuilder._getConditionSetToken(\n editCandidate.conditions,\n conditionCollector\n );\n if (conditionTokenResult.isFailure()) {\n return fail(`Failed to generate condition token for edit candidate: ${conditionTokenResult.message}`);\n }\n\n const childCandidate: ResourceJson.Json.IChildResourceCandidateDecl = {\n json: editCandidate.json,\n conditions: editCandidate.conditions,\n isPartial: editCandidate.isPartial,\n mergeMethod: editCandidate.mergeMethod\n };\n candidatesByConditionKey.set(conditionTokenResult.value, childCandidate);\n }\n\n // Extract the final merged candidate list\n const mergedCandidates = Array.from(candidatesByConditionKey.values());\n\n const modifiedDecl: ResourceJson.Json.ILooseResourceDecl = {\n ...resourceDecl,\n candidates: mergedCandidates\n };\n\n return succeed(modifiedDecl);\n }\n\n /**\n * Creates a new resource declaration from an array of candidate declarations.\n * This is used when cloning to create new resources that don't exist in the original manager.\n * @param resourceId - The validated resource ID for the new resource\n * @param candidates - Array of loose candidate declarations for the new resource\n * @param conditionCollector - The condition collector for validation context\n * @returns A Result containing the new resource declaration if successful, or failure if validation fails\n * @internal\n */\n private static _createResourceDeclFromCandidates(\n resourceId: ResourceId,\n candidates: ResourceJson.Json.ILooseResourceCandidateDecl[],\n conditionCollector: ConditionCollector\n ): Result<ResourceJson.Json.ILooseResourceDecl> {\n // Convert candidate declarations to child candidate declarations\n const childCandidates: ResourceJson.Json.IChildResourceCandidateDecl[] = [];\n\n // Ensure we have candidates\n if (candidates.length === 0) {\n return fail('Cannot create resource declaration from empty candidates array');\n }\n\n // Extract resourceTypeName from the first candidate (all candidates for the same resource should have the same type)\n const resourceTypeName = candidates[0].resourceTypeName;\n if (!resourceTypeName) {\n return fail('resourceTypeName is required for new resource candidates');\n }\n\n for (const candidate of candidates) {\n const childCandidate: ResourceJson.Json.IChildResourceCandidateDecl = {\n json: candidate.json,\n conditions: candidate.conditions,\n isPartial: candidate.isPartial,\n mergeMethod: candidate.mergeMethod\n };\n childCandidates.push(childCandidate);\n }\n\n // Create the new resource declaration\n const newResourceDecl: ResourceJson.Json.ILooseResourceDecl = {\n id: resourceId,\n candidates: childCandidates,\n resourceTypeName\n };\n\n return succeed(newResourceDecl);\n }\n}\n"]}
|
|
@@ -31,6 +31,11 @@ export interface IResourceResolverCacheListener {
|
|
|
31
31
|
* @param index - The index of the cache that had an error.
|
|
32
32
|
*/
|
|
33
33
|
onCacheError(cache: ResourceResolverCacheType, index: number): void;
|
|
34
|
+
/**
|
|
35
|
+
* Called when a context error occurs.
|
|
36
|
+
* @param error - The error that occurred.
|
|
37
|
+
*/
|
|
38
|
+
onContextError(qualifier: string, error: string): void;
|
|
34
39
|
/**
|
|
35
40
|
* Called when a cache is cleared.
|
|
36
41
|
* @param cache - The type of cache that was cleared.
|
|
@@ -54,6 +59,10 @@ export declare class NoOpResourceResolverCacheListener implements IResourceResol
|
|
|
54
59
|
* {@inheritDoc Runtime.IResourceResolverCacheListener.onCacheError}
|
|
55
60
|
*/
|
|
56
61
|
onCacheError(cache: ResourceResolverCacheType, index: number): void;
|
|
62
|
+
/**
|
|
63
|
+
* {@inheritDoc Runtime.IResourceResolverCacheListener.onContextError}
|
|
64
|
+
*/
|
|
65
|
+
onContextError(qualifier: string, error: string): void;
|
|
57
66
|
/**
|
|
58
67
|
* {@inheritDoc Runtime.IResourceResolverCacheListener.onCacheClear}
|
|
59
68
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cacheListener.d.ts","sourceRoot":"","sources":["../../../src/packlets/runtime/cacheListener.ts"],"names":[],"mappings":"AAsBA;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG,WAAW,GAAG,cAAc,GAAG,UAAU,CAAC;AAElF;;;GAGG;AACH,MAAM,MAAM,6BAA6B,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAE/E;;;GAGG;AACH,MAAM,WAAW,8BAA8B;IAC7C;;;;OAIG;IACH,UAAU,CAAC,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAElE;;;;OAIG;IACH,WAAW,CAAC,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnE;;;;OAIG;IACH,YAAY,CAAC,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAEpE;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,yBAAyB,GAAG,IAAI,CAAC;CACtD;AAED;;;GAGG;AACH,qBAAa,iCAAkC,YAAW,8BAA8B;IACtF;;OAEG;IACI,UAAU,CAAC,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIxE;;OAEG;IACI,WAAW,CAAC,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIzE;;OAEG;IACI,YAAY,CAAC,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAI1E;;OAEG;IACI,YAAY,CAAC,KAAK,EAAE,yBAAyB,GAAG,IAAI;CAG5D"}
|
|
1
|
+
{"version":3,"file":"cacheListener.d.ts","sourceRoot":"","sources":["../../../src/packlets/runtime/cacheListener.ts"],"names":[],"mappings":"AAsBA;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG,WAAW,GAAG,cAAc,GAAG,UAAU,CAAC;AAElF;;;GAGG;AACH,MAAM,MAAM,6BAA6B,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAE/E;;;GAGG;AACH,MAAM,WAAW,8BAA8B;IAC7C;;;;OAIG;IACH,UAAU,CAAC,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAElE;;;;OAIG;IACH,WAAW,CAAC,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAEnE;;;;OAIG;IACH,YAAY,CAAC,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAEpE;;;OAGG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvD;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,yBAAyB,GAAG,IAAI,CAAC;CACtD;AAED;;;GAGG;AACH,qBAAa,iCAAkC,YAAW,8BAA8B;IACtF;;OAEG;IACI,UAAU,CAAC,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIxE;;OAEG;IACI,WAAW,CAAC,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIzE;;OAEG;IACI,YAAY,CAAC,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAI1E;;OAEG;IACI,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAI7D;;OAEG;IACI,YAAY,CAAC,KAAK,EAAE,yBAAyB,GAAG,IAAI;CAG5D"}
|
|
@@ -45,6 +45,12 @@ class NoOpResourceResolverCacheListener {
|
|
|
45
45
|
onCacheError(cache, index) {
|
|
46
46
|
// no-op
|
|
47
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* {@inheritDoc Runtime.IResourceResolverCacheListener.onContextError}
|
|
50
|
+
*/
|
|
51
|
+
onContextError(qualifier, error) {
|
|
52
|
+
// no-op
|
|
53
|
+
}
|
|
48
54
|
/**
|
|
49
55
|
* {@inheritDoc Runtime.IResourceResolverCacheListener.onCacheClear}
|
|
50
56
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cacheListener.js","sourceRoot":"","sources":["../../../src/packlets/runtime/cacheListener.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;
|
|
1
|
+
{"version":3,"file":"cacheListener.js","sourceRoot":"","sources":["../../../src/packlets/runtime/cacheListener.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AAqDH;;;GAGG;AACH,MAAa,iCAAiC;IAC5C;;OAEG;IACI,UAAU,CAAC,KAAgC,EAAE,KAAa;QAC/D,QAAQ;IACV,CAAC;IAED;;OAEG;IACI,WAAW,CAAC,KAAgC,EAAE,KAAa;QAChE,QAAQ;IACV,CAAC;IAED;;OAEG;IACI,YAAY,CAAC,KAAgC,EAAE,KAAa;QACjE,QAAQ;IACV,CAAC;IAED;;OAEG;IACI,cAAc,CAAC,SAAiB,EAAE,KAAa;QACpD,QAAQ;IACV,CAAC;IAED;;OAEG;IACI,YAAY,CAAC,KAAgC;QAClD,QAAQ;IACV,CAAC;CACF;AAnCD,8EAmCC","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n/**\n * Type indicating which {@link Runtime.ResourceResolver | ResourceResolver} cache is affected.\n * @public\n */\nexport type ResourceResolverCacheType = 'condition' | 'conditionSet' | 'decision';\n\n/**\n * Type indicating the action performed on a {@link Runtime.ResourceResolver | ResourceResolver} cache.\n * @public\n */\nexport type ResourceResolverCacheActivity = 'hit' | 'miss' | 'error' | 'clear';\n\n/**\n * A listener for {@link Runtime.ResourceResolver | ResourceResolver} cache activity.\n * @public\n */\nexport interface IResourceResolverCacheListener {\n /**\n * Called when a cache hit occurs.\n * @param cache - The type of cache that was hit.\n * @param index - The index of the cache that was hit.\n */\n onCacheHit(cache: ResourceResolverCacheType, index: number): void;\n\n /**\n * Called when a cache miss occurs.\n * @param cache - The type of cache that was missed.\n * @param index - The index of the cache that was missed.\n */\n onCacheMiss(cache: ResourceResolverCacheType, index: number): void;\n\n /**\n * Called when a cache error occurs.\n * @param cache - The type of cache that had an error.\n * @param index - The index of the cache that had an error.\n */\n onCacheError(cache: ResourceResolverCacheType, index: number): void;\n\n /**\n * Called when a context error occurs.\n * @param error - The error that occurred.\n */\n onContextError(qualifier: string, error: string): void;\n\n /**\n * Called when a cache is cleared.\n * @param cache - The type of cache that was cleared.\n */\n onCacheClear(cache: ResourceResolverCacheType): void;\n}\n\n/**\n * A no-op implementation of {@link Runtime.IResourceResolverCacheListener}.\n * @public\n */\nexport class NoOpResourceResolverCacheListener implements IResourceResolverCacheListener {\n /**\n * {@inheritDoc Runtime.IResourceResolverCacheListener.onCacheHit}\n */\n public onCacheHit(cache: ResourceResolverCacheType, index: number): void {\n // no-op\n }\n\n /**\n * {@inheritDoc Runtime.IResourceResolverCacheListener.onCacheMiss}\n */\n public onCacheMiss(cache: ResourceResolverCacheType, index: number): void {\n // no-op\n }\n\n /**\n * {@inheritDoc Runtime.IResourceResolverCacheListener.onCacheError}\n */\n public onCacheError(cache: ResourceResolverCacheType, index: number): void {\n // no-op\n }\n\n /**\n * {@inheritDoc Runtime.IResourceResolverCacheListener.onContextError}\n */\n public onContextError(qualifier: string, error: string): void {\n // no-op\n }\n\n /**\n * {@inheritDoc Runtime.IResourceResolverCacheListener.onCacheClear}\n */\n public onCacheClear(cache: ResourceResolverCacheType): void {\n // no-op\n }\n}\n"]}
|
|
@@ -51,6 +51,8 @@ export type OverallCacheMetrics<TM extends ICacheMetrics = ICacheMetrics> = Reco
|
|
|
51
51
|
*/
|
|
52
52
|
export declare class ResourceResolverCacheMetricsListener<TM extends ICacheMetrics> implements IResourceResolverCacheListener {
|
|
53
53
|
private readonly _metrics;
|
|
54
|
+
private _contextErrors;
|
|
55
|
+
get numContextErrors(): number;
|
|
54
56
|
constructor(factory: () => TM);
|
|
55
57
|
constructor(metrics: OverallCacheMetrics<TM>);
|
|
56
58
|
/**
|
|
@@ -70,6 +72,10 @@ export declare class ResourceResolverCacheMetricsListener<TM extends ICacheMetri
|
|
|
70
72
|
* {@inheritDoc Runtime.IResourceResolverCacheListener.onCacheError}
|
|
71
73
|
*/
|
|
72
74
|
onCacheError(cache: ResourceResolverCacheType, index: number): void;
|
|
75
|
+
/**
|
|
76
|
+
* {@inheritDoc Runtime.IResourceResolverCacheListener.onContextError}
|
|
77
|
+
*/
|
|
78
|
+
onContextError(qualifier: string, error: string): void;
|
|
73
79
|
/**
|
|
74
80
|
* {@inheritDoc Runtime.IResourceResolverCacheListener.onCacheClear}
|
|
75
81
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cacheMetrics.d.ts","sourceRoot":"","sources":["../../../src/packlets/runtime/cacheMetrics.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,8BAA8B,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAE5F;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,IAAI,IAAI,CAAC;IAChB,KAAK,IAAI,IAAI,CAAC;CACf;AAED;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,aAAa;IACzD,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,OAAO,CAAa;;IASrB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI5B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI7B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI9B,OAAO,IAAI,IAAI;IAOtB,IAAW,IAAI,IAAI,MAAM,CAExB;IAED,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED,IAAW,aAAa,IAAI,MAAM,CAEjC;IAED,IAAW,OAAO,IAAI,MAAM,CAE3B;IAED,IAAW,SAAS,IAAI,MAAM,CAE7B;IAEM,KAAK,IAAI,IAAI;CAMrB;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,CAAC,EAAE,SAAS,aAAa,GAAG,aAAa,IAAI,MAAM,CAChF,yBAAyB,EACzB,EAAE,CACH,CAAC;AAEF;;;;GAIG;AACH,qBAAa,oCAAoC,CAAC,EAAE,SAAS,aAAa,CACxE,YAAW,8BAA8B;IAEzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;
|
|
1
|
+
{"version":3,"file":"cacheMetrics.d.ts","sourceRoot":"","sources":["../../../src/packlets/runtime/cacheMetrics.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,8BAA8B,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAE5F;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,IAAI,IAAI,CAAC;IAChB,KAAK,IAAI,IAAI,CAAC;CACf;AAED;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,aAAa;IACzD,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,OAAO,CAAa;;IASrB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI5B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI7B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI9B,OAAO,IAAI,IAAI;IAOtB,IAAW,IAAI,IAAI,MAAM,CAExB;IAED,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED,IAAW,aAAa,IAAI,MAAM,CAEjC;IAED,IAAW,OAAO,IAAI,MAAM,CAE3B;IAED,IAAW,SAAS,IAAI,MAAM,CAE7B;IAEM,KAAK,IAAI,IAAI;CAMrB;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,CAAC,EAAE,SAAS,aAAa,GAAG,aAAa,IAAI,MAAM,CAChF,yBAAyB,EACzB,EAAE,CACH,CAAC;AAEF;;;;GAIG;AACH,qBAAa,oCAAoC,CAAC,EAAE,SAAS,aAAa,CACxE,YAAW,8BAA8B;IAEzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IACnD,OAAO,CAAC,cAAc,CAAS;IAE/B,IAAW,gBAAgB,IAAI,MAAM,CAEpC;gBAEkB,OAAO,EAAE,MAAM,EAAE;gBACjB,OAAO,EAAE,mBAAmB,CAAC,EAAE,CAAC;IAcnD;;;OAGG;IACH,IAAW,OAAO,IAAI,QAAQ,CAAC,mBAAmB,CAAC,CAElD;IAED;;OAEG;IACI,UAAU,CAAC,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIxE;;OAEG;IACI,WAAW,CAAC,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIzE;;OAEG;IACI,YAAY,CAAC,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAI1E;;OAEG;IACI,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAI7D;;OAEG;IACI,YAAY,CAAC,KAAK,EAAE,yBAAyB,GAAG,IAAI;IAI3D;;OAEG;IACI,KAAK,IAAI,IAAI;CAMrB"}
|
|
@@ -87,6 +87,9 @@ exports.AggregateCacheMetrics = AggregateCacheMetrics;
|
|
|
87
87
|
* @public
|
|
88
88
|
*/
|
|
89
89
|
class ResourceResolverCacheMetricsListener {
|
|
90
|
+
get numContextErrors() {
|
|
91
|
+
return this._contextErrors;
|
|
92
|
+
}
|
|
90
93
|
constructor(factoryOrMetrics) {
|
|
91
94
|
if (typeof factoryOrMetrics === 'function') {
|
|
92
95
|
this._metrics = {
|
|
@@ -98,6 +101,7 @@ class ResourceResolverCacheMetricsListener {
|
|
|
98
101
|
else {
|
|
99
102
|
this._metrics = factoryOrMetrics;
|
|
100
103
|
}
|
|
104
|
+
this._contextErrors = 0;
|
|
101
105
|
}
|
|
102
106
|
/**
|
|
103
107
|
* Get the metrics for all cache types.
|
|
@@ -124,6 +128,12 @@ class ResourceResolverCacheMetricsListener {
|
|
|
124
128
|
onCacheError(cache, index) {
|
|
125
129
|
this._metrics[cache].onError(index);
|
|
126
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* {@inheritDoc Runtime.IResourceResolverCacheListener.onContextError}
|
|
133
|
+
*/
|
|
134
|
+
onContextError(qualifier, error) {
|
|
135
|
+
this._contextErrors++;
|
|
136
|
+
}
|
|
127
137
|
/**
|
|
128
138
|
* {@inheritDoc Runtime.IResourceResolverCacheListener.onCacheClear}
|
|
129
139
|
*/
|
|
@@ -137,6 +147,7 @@ class ResourceResolverCacheMetricsListener {
|
|
|
137
147
|
this._metrics.condition.reset();
|
|
138
148
|
this._metrics.conditionSet.reset();
|
|
139
149
|
this._metrics.decision.reset();
|
|
150
|
+
this._contextErrors = 0;
|
|
140
151
|
}
|
|
141
152
|
}
|
|
142
153
|
exports.ResourceResolverCacheMetricsListener = ResourceResolverCacheMetricsListener;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cacheMetrics.js","sourceRoot":"","sources":["../../../src/packlets/runtime/cacheMetrics.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AAsBH;;;GAGG;AACH,MAAa,qBAAqB;IAMhC;QALQ,UAAK,GAAW,CAAC,CAAC;QAClB,YAAO,GAAW,CAAC,CAAC;QACpB,YAAO,GAAW,CAAC,CAAC;QACpB,YAAO,GAAW,CAAC,CAAC;QAG1B,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACf,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;IACnB,CAAC;IAEM,KAAK,CAAC,OAAe;QAC1B,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;IAEM,MAAM,CAAC,OAAe;QAC3B,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAEM,OAAO,CAAC,OAAe;QAC5B,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAEM,OAAO;QACZ,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACf,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED,IAAW,IAAI;QACb,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,IAAW,aAAa;QACtB,OAAO,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAClD,CAAC;IAED,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED,IAAW,SAAS;QAClB,OAAO,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,CAAC;IAEM,KAAK;QACV,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACf,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC;IACnB,CAAC;CACF;AAlED,sDAkEC;AAWD;;;;GAIG;AACH,MAAa,oCAAoC;
|
|
1
|
+
{"version":3,"file":"cacheMetrics.js","sourceRoot":"","sources":["../../../src/packlets/runtime/cacheMetrics.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { IResourceResolverCacheListener, ResourceResolverCacheType } from './cacheListener';\n\n/**\n * Cache metrics interface for tracking cache performance.\n * @public\n */\nexport interface ICacheMetrics {\n hits: number;\n misses: number;\n errors: number;\n clears: number;\n totalAccesses: number;\n hitRate: number;\n onHit(index: number): void;\n onMiss(index: number): void;\n onError(index: number): void;\n onClear(): void;\n reset(): void;\n}\n\n/**\n * Aggregate cache metrics for a specific cache type.\n * @public\n */\nexport class AggregateCacheMetrics implements ICacheMetrics {\n private _hits: number = 0;\n private _misses: number = 0;\n private _errors: number = 0;\n private _clears: number = 0;\n\n public constructor() {\n this._hits = 0;\n this._misses = 0;\n this._errors = 0;\n this._clears = 0;\n }\n\n public onHit(__index: number): void {\n this._hits++;\n }\n\n public onMiss(__index: number): void {\n this._misses++;\n }\n\n public onError(__index: number): void {\n this._errors++;\n }\n\n public onClear(): void {\n this._hits = 0;\n this._misses = 0;\n this._errors = 0;\n this._clears++;\n }\n\n public get hits(): number {\n return this._hits;\n }\n\n public get misses(): number {\n return this._misses;\n }\n\n public get errors(): number {\n return this._errors;\n }\n\n public get clears(): number {\n return this._clears;\n }\n\n public get totalAccesses(): number {\n return this._hits + this._misses + this._errors;\n }\n\n public get hitRate(): number {\n return this.totalAccesses > 0 ? (this._hits / this.totalAccesses) * 100 : 0;\n }\n\n public get errorRate(): number {\n return this.totalAccesses > 0 ? (this._errors / this.totalAccesses) * 100 : 0;\n }\n\n public reset(): void {\n this._hits = 0;\n this._misses = 0;\n this._errors = 0;\n this._clears = 0;\n }\n}\n\n/**\n * Overall cache metrics across all cache types.\n * @public\n */\nexport type OverallCacheMetrics<TM extends ICacheMetrics = ICacheMetrics> = Record<\n ResourceResolverCacheType,\n TM\n>;\n\n/**\n * A metrics implementation of {@link Runtime.IResourceResolverCacheListener} that tracks\n * hit counts and rates across all cache types.\n * @public\n */\nexport class ResourceResolverCacheMetricsListener<TM extends ICacheMetrics>\n implements IResourceResolverCacheListener\n{\n private readonly _metrics: OverallCacheMetrics<TM>;\n private _contextErrors: number;\n\n public get numContextErrors(): number {\n return this._contextErrors;\n }\n\n public constructor(factory: () => TM);\n public constructor(metrics: OverallCacheMetrics<TM>);\n public constructor(factoryOrMetrics: OverallCacheMetrics<TM> | (() => TM)) {\n if (typeof factoryOrMetrics === 'function') {\n this._metrics = {\n condition: factoryOrMetrics(),\n conditionSet: factoryOrMetrics(),\n decision: factoryOrMetrics()\n };\n } else {\n this._metrics = factoryOrMetrics;\n }\n this._contextErrors = 0;\n }\n\n /**\n * Get the metrics for all cache types.\n * @returns The metrics for all cache types.\n */\n public get metrics(): Readonly<OverallCacheMetrics> {\n return this._metrics;\n }\n\n /**\n * {@inheritDoc Runtime.IResourceResolverCacheListener.onCacheHit}\n */\n public onCacheHit(cache: ResourceResolverCacheType, index: number): void {\n this._metrics[cache].onHit(index);\n }\n\n /**\n * {@inheritDoc Runtime.IResourceResolverCacheListener.onCacheMiss}\n */\n public onCacheMiss(cache: ResourceResolverCacheType, index: number): void {\n this._metrics[cache].onMiss(index);\n }\n\n /**\n * {@inheritDoc Runtime.IResourceResolverCacheListener.onCacheError}\n */\n public onCacheError(cache: ResourceResolverCacheType, index: number): void {\n this._metrics[cache].onError(index);\n }\n\n /**\n * {@inheritDoc Runtime.IResourceResolverCacheListener.onContextError}\n */\n public onContextError(qualifier: string, error: string): void {\n this._contextErrors++;\n }\n\n /**\n * {@inheritDoc Runtime.IResourceResolverCacheListener.onCacheClear}\n */\n public onCacheClear(cache: ResourceResolverCacheType): void {\n this._metrics[cache].onClear();\n }\n\n /**\n * Reset all metrics to zero.\n */\n public reset(): void {\n this._metrics.condition.reset();\n this._metrics.conditionSet.reset();\n this._metrics.decision.reset();\n this._contextErrors = 0;\n }\n}\n"]}
|
|
@@ -94,7 +94,7 @@ class ResourceResolver {
|
|
|
94
94
|
* @public
|
|
95
95
|
*/
|
|
96
96
|
resolveCondition(condition) {
|
|
97
|
-
var _a, _b, _c
|
|
97
|
+
var _a, _b, _c;
|
|
98
98
|
// Get the condition's index for cache lookup
|
|
99
99
|
const conditionIndex = condition.index;
|
|
100
100
|
if (conditionIndex === undefined) {
|
|
@@ -107,16 +107,20 @@ class ResourceResolver {
|
|
|
107
107
|
return (0, ts_utils_1.succeed)(cachedResult);
|
|
108
108
|
}
|
|
109
109
|
// Resolve the condition by getting qualifier value and evaluating with qualifier type
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
110
|
+
const score = this.contextQualifierProvider
|
|
111
|
+
.get(condition.qualifier)
|
|
112
|
+
.onSuccess((qualifierValue) => {
|
|
113
|
+
// Evaluate the condition using the qualifier type's matching logic
|
|
114
|
+
return (0, ts_utils_1.succeed)(condition.qualifier.type.matches(condition.value, qualifierValue, condition.operator));
|
|
115
|
+
})
|
|
116
|
+
.onFailure((err) => {
|
|
117
|
+
var _a;
|
|
118
|
+
(_a = this._listener) === null || _a === void 0 ? void 0 : _a.onContextError(condition.qualifier.name, err);
|
|
119
|
+
return (0, ts_utils_1.fail)(err);
|
|
120
|
+
})
|
|
121
|
+
.orDefault(common_1.NoMatch);
|
|
118
122
|
const priority = condition.priority;
|
|
119
|
-
const scoreAsDefault = (
|
|
123
|
+
const scoreAsDefault = (_b = condition.scoreAsDefault) !== null && _b !== void 0 ? _b : common_1.NoMatch;
|
|
120
124
|
const matchResult = score > common_1.NoMatch
|
|
121
125
|
? { score, priority, matchType: 'match' }
|
|
122
126
|
: scoreAsDefault > common_1.NoMatch
|
|
@@ -124,7 +128,7 @@ class ResourceResolver {
|
|
|
124
128
|
: { score: common_1.NoMatch, priority, matchType: 'noMatch' };
|
|
125
129
|
// Cache the resolved value for future O(1) lookup
|
|
126
130
|
this._conditionCache[conditionIndex] = matchResult;
|
|
127
|
-
(
|
|
131
|
+
(_c = this._listener) === null || _c === void 0 ? void 0 : _c.onCacheMiss('condition', conditionIndex);
|
|
128
132
|
return (0, ts_utils_1.succeed)(matchResult);
|
|
129
133
|
}
|
|
130
134
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resourceResolver.js","sourceRoot":"","sources":["../../../src/packlets/runtime/resourceResolver.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Result, captureResult, fail, succeed } from '@fgv/ts-utils';\nimport { JsonValue, JsonObject, isJsonObject } from '@fgv/ts-json-base';\nimport { JsonEditor } from '@fgv/ts-json';\nimport { NoMatch } from '../common';\nimport { Condition, ConditionSet } from '../conditions';\nimport { AbstractDecision } from '../decisions';\nimport { ReadOnlyQualifierTypeCollector } from '../qualifier-types';\nimport { IContextQualifierProvider } from './context';\nimport { IResourceManager, IResource, IResourceCandidate } from './iResourceManager';\nimport {\n ConditionMatchType,\n ConditionSetResolutionResult,\n IConditionMatchResult\n} from './conditionSetResolutionResult';\nimport { IResourceResolverCacheListener } from './cacheListener';\n\n/**\n * Represents the cached result of resolving a decision.\n * Contains either a failure indicator or a list of instance indices for matching condition sets,\n * ordered by condition set priority.\n * @public\n */\nexport type DecisionResolutionResult =\n | { success: false }\n | { success: true; instanceIndices: ReadonlyArray<number>; defaultInstanceIndices: ReadonlyArray<number> };\n\n/**\n * Parameters for creating a {@link Runtime.ResourceResolver | ResourceResolver}.\n * @public\n */\nexport interface IResourceResolverCreateParams {\n /**\n * The {@link Runtime.IResourceManager | resource manager} that defines the resources available\n * and provides access to qualifiers and conditions.\n */\n resourceManager: IResourceManager;\n\n /**\n * The {@link QualifierTypes.ReadOnlyQualifierTypeCollector | readonly qualifier type collector}\n * that provides qualifier implementations for condition evaluation.\n */\n qualifierTypes: ReadOnlyQualifierTypeCollector;\n\n /**\n * The {@link Runtime.Context.IContextQualifierProvider | context qualifier provider} that resolves\n * qualifier values for the current context.\n */\n contextQualifierProvider: IContextQualifierProvider;\n\n /**\n * An optional listener for {@link Runtime.ResourceResolver | ResourceResolver} cache activity.\n */\n listener?: IResourceResolverCacheListener;\n}\n\n/**\n * High-performance runtime resource resolver with O(1) condition caching.\n * Resolves resources for a given context by evaluating conditions against qualifier values\n * and caching results for optimal performance.\n * @public\n */\nexport class ResourceResolver {\n /**\n * The resource manager that defines available resources and provides condition access.\n */\n public readonly resourceManager: IResourceManager;\n\n /**\n * The readonly qualifier type collector that provides qualifier implementations.\n */\n public readonly qualifierTypes: ReadOnlyQualifierTypeCollector;\n\n /**\n * The context qualifier provider that resolves qualifier values.\n */\n public readonly contextQualifierProvider: IContextQualifierProvider;\n\n /**\n * The cache array for resolved conditions, indexed by condition index for O(1) lookup.\n * Each entry stores the resolved {@link Runtime.IConditionMatchResult | condition match result} for\n * the corresponding condition.\n */\n public get conditionCache(): ReadonlyArray<IConditionMatchResult | undefined> {\n return this._conditionCache;\n }\n\n /**\n * The cache array for resolved condition sets, indexed by condition set index for O(1) lookup.\n * Each entry stores the resolved ConditionSetResolutionResult for the corresponding condition set.\n */\n public get conditionSetCache(): ReadonlyArray<ConditionSetResolutionResult | undefined> {\n return this._conditionSetCache;\n }\n\n /**\n * The cache array for resolved decisions, indexed by decision index for O(1) lookup.\n * Each entry stores the resolved DecisionResolutionResult for the corresponding decision.\n */\n public get decisionCache(): ReadonlyArray<DecisionResolutionResult | undefined> {\n return this._decisionCache;\n }\n\n /**\n * Cache array for resolved conditions, indexed by condition index for O(1) lookup.\n * Each entry stores the resolved QualifierMatchScore for the corresponding condition.\n */\n private readonly _conditionCache: Array<IConditionMatchResult | undefined>;\n\n /**\n * Cache array for resolved condition sets, indexed by condition set index for O(1) lookup.\n * Each entry stores the resolved ConditionSetResolutionResult for the corresponding condition set.\n */\n private readonly _conditionSetCache: Array<ConditionSetResolutionResult | undefined>;\n\n /**\n * Cache array for resolved decisions, indexed by decision index for O(1) lookup.\n * Each entry stores the resolved DecisionResolutionResult for the corresponding decision.\n */\n private readonly _decisionCache: Array<DecisionResolutionResult | undefined>;\n\n /**\n * The listener for {@link Runtime.ResourceResolver | ResourceResolver} cache activity.\n */\n private readonly _listener?: IResourceResolverCacheListener;\n\n /**\n * Constructor for a {@link Runtime.ResourceResolver | ResourceResolver} object.\n * @param params - {@link Runtime.IResourceResolverCreateParams | Parameters} used to create the resolver.\n */\n protected constructor(params: IResourceResolverCreateParams) {\n this.resourceManager = params.resourceManager;\n this.qualifierTypes = params.qualifierTypes;\n this.contextQualifierProvider = params.contextQualifierProvider;\n\n // Initialize condition cache array with size matching the condition collector\n const conditionCollectorSize = this.resourceManager.conditions.size;\n this._conditionCache = new Array<IConditionMatchResult | undefined>(conditionCollectorSize);\n\n // Initialize condition set cache array with size matching the condition set collector\n const conditionSetCollectorSize = this.resourceManager.conditionSets.size;\n this._conditionSetCache = new Array<ConditionSetResolutionResult | undefined>(conditionSetCollectorSize);\n\n // Initialize decision cache array with size matching the decision collector\n const decisionCollectorSize = this.resourceManager.decisions.size;\n this._decisionCache = new Array<DecisionResolutionResult | undefined>(decisionCollectorSize);\n\n this._listener = params.listener;\n }\n\n /**\n * Creates a new {@link Runtime.ResourceResolver | ResourceResolver} object.\n * @param params - {@link Runtime.IResourceResolverCreateParams | Parameters} used to create the resolver.\n * @returns `Success` with the new {@link Runtime.ResourceResolver | ResourceResolver} object if successful,\n * or `Failure` with an error message if not.\n * @public\n */\n public static create(params: IResourceResolverCreateParams): Result<ResourceResolver> {\n return captureResult(() => new ResourceResolver(params));\n }\n\n /**\n * Resolves a condition by evaluating it against the current context.\n * Uses O(1) caching based on the condition's globally unique sequential index.\n * @param condition - The {@link Conditions.Condition | condition} to resolve.\n * @returns `Success` with the {@link QualifierMatchScore | match score} if successful,\n * or `Failure` with an error message if the condition cannot be resolved.\n * @public\n */\n public resolveCondition(condition: Condition): Result<IConditionMatchResult> {\n // Get the condition's index for cache lookup\n const conditionIndex = condition.index;\n if (conditionIndex === undefined) {\n return fail(`Condition \"${condition.key}\" does not have a valid index`);\n }\n\n // Check cache first for O(1) lookup\n const cachedResult = this._conditionCache[conditionIndex];\n if (cachedResult !== undefined) {\n this._listener?.onCacheHit('condition', conditionIndex);\n return succeed(cachedResult);\n }\n\n // Resolve the condition by getting qualifier value and evaluating with qualifier type\n const qualifierValueResult = this.contextQualifierProvider.get(condition.qualifier);\n if (qualifierValueResult.isFailure()) {\n this._listener?.onCacheError('condition', conditionIndex);\n return fail(\n `Failed to get qualifier value for \"${condition.qualifier.name}\": ${qualifierValueResult.message}`\n );\n }\n\n const qualifierValue = qualifierValueResult.value;\n\n // Evaluate the condition using the qualifier type's matching logic\n const score = condition.qualifier.type.matches(condition.value, qualifierValue, condition.operator);\n const priority = condition.priority;\n const scoreAsDefault = condition.scoreAsDefault ?? NoMatch;\n const matchResult: IConditionMatchResult =\n score > NoMatch\n ? { score, priority, matchType: 'match' }\n : scoreAsDefault > NoMatch\n ? { score: scoreAsDefault, priority, matchType: 'matchAsDefault' }\n : { score: NoMatch, priority, matchType: 'noMatch' };\n\n // Cache the resolved value for future O(1) lookup\n this._conditionCache[conditionIndex] = matchResult;\n this._listener?.onCacheMiss('condition', conditionIndex);\n\n return succeed(matchResult);\n }\n\n /**\n * Resolves a condition set by evaluating all its constituent conditions against the current context.\n * Uses O(1) caching based on the condition set's globally unique sequential index.\n * @param conditionSet - The {@link Conditions.ConditionSet | condition set} to resolve.\n * @returns `Success` with the {@link Runtime.ConditionSetResolutionResult | resolution result} if successful,\n * or `Failure` with an error message if the condition set cannot be resolved.\n * @public\n */\n public resolveConditionSet(conditionSet: ConditionSet): Result<ConditionSetResolutionResult> {\n // Get the condition set's index for cache lookup\n const conditionSetIndex = conditionSet.index;\n if (conditionSetIndex === undefined) {\n return fail(`ConditionSet \"${conditionSet.key}\" does not have a valid index`);\n }\n\n // Check cache first for O(1) lookup\n const cachedResult = this._conditionSetCache[conditionSetIndex];\n if (cachedResult !== undefined) {\n this._listener?.onCacheHit('conditionSet', conditionSetIndex);\n return succeed(cachedResult);\n }\n\n // Resolve all conditions in the condition set\n const conditions: Array<IConditionMatchResult> = [];\n let matchType: ConditionMatchType = 'match';\n\n for (const condition of conditionSet.conditions) {\n const { value: conditionResult, message: conditionMessage } = this.resolveCondition(condition);\n\n if (conditionMessage !== undefined) {\n /* c8 ignore next 2 - defensive coding: extreme internal error scenario not reachable in normal operation */\n this._listener?.onCacheError('conditionSet', conditionSetIndex);\n return fail(`Failed to resolve condition \"${condition.key}\": ${conditionMessage}`);\n }\n\n conditions.push(conditionResult);\n\n if (conditionResult.matchType === 'noMatch') {\n // Cache the failure result\n return ConditionSetResolutionResult.create('noMatch', conditions)\n .onSuccess((result) => {\n this._conditionSetCache[conditionSetIndex] = result;\n this._listener?.onCacheMiss('conditionSet', conditionSetIndex);\n return succeed(result);\n })\n .onFailure((err) => {\n /* c8 ignore next 4 - defensive coding: extreme internal error scenario not reachable in normal operation */\n this._conditionSetCache[conditionSetIndex] = undefined;\n this._listener?.onCacheError('conditionSet', conditionSetIndex);\n return fail(`${conditionSetIndex}: error creating condition set resolution result: ${err}`);\n });\n }\n\n if (conditionResult.matchType === 'matchAsDefault') {\n matchType = 'matchAsDefault';\n }\n }\n\n // Cache the successful result\n return ConditionSetResolutionResult.create(matchType, conditions)\n .onSuccess((result) => {\n this._conditionSetCache[conditionSetIndex] = result;\n this._listener?.onCacheMiss('conditionSet', conditionSetIndex);\n return succeed(result);\n })\n .onFailure((err) => {\n /* c8 ignore next 4 - defensive coding: extreme internal error scenario not reachable in normal operation */\n this._conditionSetCache[conditionSetIndex] = undefined;\n this._listener?.onCacheError('conditionSet', conditionSetIndex);\n return fail(`${conditionSetIndex}: error creating condition set resolution result: ${err}`);\n });\n }\n\n /**\n * Resolves a decision by evaluating all its constituent condition sets against the current context.\n * Uses O(1) caching based on the decision's globally unique sequential index.\n * @param decision - The {@link Decisions.AbstractDecision | abstract decision} to resolve.\n * @returns `Success` with the {@link Runtime.DecisionResolutionResult | resolution result} if successful,\n * or `Failure` with an error message if the decision cannot be resolved.\n * @public\n */\n public resolveDecision(decision: AbstractDecision): Result<DecisionResolutionResult> {\n // Get the decision's index for cache lookup\n const decisionIndex = decision.index;\n if (decisionIndex === undefined) {\n return fail(`Decision \"${decision.key}\" does not have a valid index`);\n }\n\n // Check cache first for O(1) lookup\n const cachedResult = this._decisionCache[decisionIndex];\n if (cachedResult !== undefined) {\n this._listener?.onCacheHit('decision', decisionIndex);\n return succeed(cachedResult);\n }\n\n // Resolve all condition sets in the decision\n const matchingInstanceResults: Array<{ index: number; result: ConditionSetResolutionResult }> = [];\n const matchingDefaultInstanceResults: Array<{ index: number; result: ConditionSetResolutionResult }> = [];\n\n for (let instanceIndex = 0; instanceIndex < decision.candidates.length; instanceIndex++) {\n const candidate = decision.candidates[instanceIndex];\n const conditionSetResult = this.resolveConditionSet(candidate.conditionSet);\n\n if (conditionSetResult.isFailure()) {\n /* c8 ignore next 2 - defensive coding: extreme internal error scenario not reachable in normal operation */\n this._listener?.onCacheError('decision', decisionIndex);\n return fail(`${decision.key}: Failed to resolve condition set\": ${conditionSetResult.message}`);\n }\n\n const resolution = conditionSetResult.value;\n\n // Only include condition sets that match\n if (resolution.matchType === 'match') {\n matchingInstanceResults.push({\n index: instanceIndex,\n result: resolution\n });\n } else if (resolution.matchType === 'matchAsDefault') {\n matchingDefaultInstanceResults.push({\n index: instanceIndex,\n result: resolution\n });\n }\n // If condition set doesn't match, we simply skip it and continue (don't fail the decision)\n }\n\n // Sort by condition set resolution priority using the proper comparison logic\n matchingInstanceResults.sort((a, b) => ConditionSetResolutionResult.compare(a.result, b.result));\n matchingDefaultInstanceResults.sort((a, b) => ConditionSetResolutionResult.compare(a.result, b.result));\n\n // Extract just the instance indices in priority order\n const instanceIndices = matchingInstanceResults.map((item) => item.index);\n const defaultInstanceIndices = matchingDefaultInstanceResults.map((item) => item.index);\n\n // Cache the successful result\n const successResult: DecisionResolutionResult = {\n success: true,\n instanceIndices,\n defaultInstanceIndices\n };\n this._decisionCache[decisionIndex] = successResult;\n this._listener?.onCacheMiss('decision', decisionIndex);\n\n return succeed(successResult);\n }\n\n /**\n * Resolves a resource by finding the best matching candidate.\n * Uses the resource's associated decision to determine the best match based on the current context.\n * @param resource - The {@link Resources.Resource | resource} to resolve.\n * @returns `Success` with the best matching candidate if successful,\n * or `Failure` with an error message if no candidates match or resolution fails.\n * @public\n */\n public resolveResource(resource: IResource): Result<IResourceCandidate> {\n // Get the abstract decision from the resource's concrete decision\n const abstractDecision = resource.decision.baseDecision;\n\n // Resolve the decision to get candidate indices in priority order\n const decisionResult = this.resolveDecision(abstractDecision);\n /* c8 ignore next 3 - defense in depth almost impossible to hit */\n if (decisionResult.isFailure()) {\n return fail(`Failed to resolve decision for resource \"${resource.id}\": ${decisionResult.message}`);\n }\n\n const resolution = decisionResult.value;\n\n // Check if any candidates matched (regular or default)\n if (\n !resolution.success ||\n (resolution.instanceIndices.length === 0 && resolution.defaultInstanceIndices.length === 0)\n ) {\n return fail(`No matching candidates found for resource \"${resource.id}\"`);\n }\n\n // Prefer regular matches over default matches\n const candidateIndex =\n resolution.instanceIndices.length > 0\n ? resolution.instanceIndices[0] // Best regular match\n : resolution.defaultInstanceIndices[0]; // Best default match\n\n if (candidateIndex >= resource.candidates.length) {\n return fail(`Invalid candidate index ${candidateIndex} for resource \"${resource.id}\"`);\n }\n\n const bestCandidate = resource.candidates[candidateIndex];\n return succeed(bestCandidate);\n }\n\n /**\n * Resolves all matching resource candidates in priority order.\n * Uses the resource's associated decision to determine all matching candidates based on the current context.\n * @param resource - The {@link Resources.Resource | resource} to resolve.\n * @returns `Success` with an array of all matching candidates in priority order if successful,\n * or `Failure` with an error message if no candidates match or resolution fails.\n * @public\n */\n public resolveAllResourceCandidates(resource: IResource): Result<ReadonlyArray<IResourceCandidate>> {\n // Get the abstract decision from the resource's concrete decision\n const abstractDecision = resource.decision.baseDecision;\n\n // Resolve the decision to get candidate indices in priority order\n const decisionResult = this.resolveDecision(abstractDecision);\n /* c8 ignore next 3 - defense in depth almost impossible to hit */\n if (decisionResult.isFailure()) {\n return fail(`Failed to resolve decision for resource \"${resource.id}\": ${decisionResult.message}`);\n }\n\n const resolution = decisionResult.value;\n\n // Check if any candidates matched (regular or default)\n if (\n !resolution.success ||\n (resolution.instanceIndices.length === 0 && resolution.defaultInstanceIndices.length === 0)\n ) {\n return fail(`No matching candidates found for resource \"${resource.id}\"`);\n }\n\n // Get all matching candidates: regular matches first, then default matches\n const candidates: IResourceCandidate[] = [];\n\n // Add all regular matches first (already sorted by priority)\n for (const candidateIndex of resolution.instanceIndices) {\n if (candidateIndex >= resource.candidates.length) {\n return fail(`Invalid candidate index ${candidateIndex} for resource \"${resource.id}\"`);\n }\n const candidate = resource.candidates[candidateIndex];\n candidates.push(candidate);\n }\n\n // Add all default matches after regular matches (already sorted by priority)\n for (const candidateIndex of resolution.defaultInstanceIndices) {\n /* c8 ignore next 3 - defensive coding: extreme internal error scenario not reachable in normal operation */\n if (candidateIndex >= resource.candidates.length) {\n return fail(`Invalid candidate index ${candidateIndex} for resource \"${resource.id}\"`);\n }\n const candidate = resource.candidates[candidateIndex];\n candidates.push(candidate);\n }\n\n return succeed(candidates);\n }\n\n /**\n * Resolves a resource to a composed value by merging matching candidates according to their merge methods.\n * Starting from the highest priority candidates, finds the first \"full\" candidate and merges all higher\n * priority \"partial\" candidates into it in ascending order of priority.\n * @param resource - The {@link Resources.Resource | resource} to resolve.\n * @returns `Success` with the composed JsonValue if successful,\n * or `Failure` with an error message if no candidates match or resolution fails.\n * @public\n */\n public resolveComposedResourceValue(resource: IResource): Result<JsonValue> {\n return this.resolveAllResourceCandidates(resource).onSuccess((candidates) => {\n /* c8 ignore next 3 - defense in depth should never occur */\n if (candidates.length === 0) {\n return fail(`${resource.id}: No matching candidates found.`);\n }\n\n // Find the first full candidate and collect all partial candidates above it\n let fullCandidateIndex = -1;\n const partialCandidates: IResourceCandidate[] = [];\n\n for (let i = 0; i < candidates.length; i++) {\n const candidate = candidates[i];\n if (!candidate.isPartial) {\n // Found the first full candidate\n fullCandidateIndex = i;\n break;\n } else {\n // Collect partial candidates (these are in ascending priority order)\n partialCandidates.unshift(candidate);\n }\n }\n\n // If no full candidate found, use the last candidate as the base\n const baseCandidateIndex = fullCandidateIndex >= 0 ? fullCandidateIndex : candidates.length - 1;\n const baseCandidate = candidates[baseCandidateIndex];\n\n // If there are no partial candidates to merge, return the base candidate's value\n if (partialCandidates.length === 0) {\n return succeed(baseCandidate.json);\n }\n\n const allCandidates = [\n baseCandidate.json,\n ...partialCandidates.map((candidate) => candidate.json)\n ].filter((v): v is JsonObject => isJsonObject(v));\n\n /* c8 ignore next 3 - defensive check: non-object values in resource candidates should be prevented at validation time */\n if (allCandidates.length !== partialCandidates.length + 1) {\n return fail(`${resource.id}: Unable to compose non-object candidate values.`);\n }\n\n // Create JsonEditor with array replacement behavior for resource composition\n const editor = JsonEditor.create({\n merge: {\n arrayMergeBehavior: 'replace'\n }\n }).orThrow(); // Should never fail with valid options\n\n return editor\n .mergeObjectsInPlace({}, allCandidates)\n .withErrorFormat((err) => `${resource.id}: Composition failed: ${err}`);\n });\n }\n\n /**\n * Clears all caches (condition, condition set, and decision), forcing all cached items\n * to be re-evaluated on next access. This should be called when the context changes and cached\n * results are no longer valid.\n * @public\n */\n public clearConditionCache(): void {\n this._conditionCache.fill(undefined);\n this._conditionSetCache.fill(undefined);\n this._decisionCache.fill(undefined);\n\n this._listener?.onCacheClear('condition');\n this._listener?.onCacheClear('conditionSet');\n this._listener?.onCacheClear('decision');\n }\n\n /**\n * Gets the current size of the condition cache array.\n * @returns The size of the condition cache array.\n * @public\n */\n public get conditionCacheSize(): number {\n return this._conditionCache.length;\n }\n\n /**\n * Gets the current size of the condition set cache array.\n * @returns The size of the condition set cache array.\n * @public\n */\n public get conditionSetCacheSize(): number {\n return this._conditionSetCache.length;\n }\n\n /**\n * Gets the current size of the decision cache array.\n * @returns The size of the decision cache array.\n * @public\n */\n public get decisionCacheSize(): number {\n return this._decisionCache.length;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"resourceResolver.js","sourceRoot":"","sources":["../../../src/packlets/runtime/resourceResolver.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Result, captureResult, fail, succeed } from '@fgv/ts-utils';\nimport { JsonValue, JsonObject, isJsonObject } from '@fgv/ts-json-base';\nimport { JsonEditor } from '@fgv/ts-json';\nimport { NoMatch } from '../common';\nimport { Condition, ConditionSet } from '../conditions';\nimport { AbstractDecision } from '../decisions';\nimport { ReadOnlyQualifierTypeCollector } from '../qualifier-types';\nimport { IContextQualifierProvider } from './context';\nimport { IResourceManager, IResource, IResourceCandidate } from './iResourceManager';\nimport {\n ConditionMatchType,\n ConditionSetResolutionResult,\n IConditionMatchResult\n} from './conditionSetResolutionResult';\nimport { IResourceResolverCacheListener } from './cacheListener';\n\n/**\n * Represents the cached result of resolving a decision.\n * Contains either a failure indicator or a list of instance indices for matching condition sets,\n * ordered by condition set priority.\n * @public\n */\nexport type DecisionResolutionResult =\n | { success: false }\n | { success: true; instanceIndices: ReadonlyArray<number>; defaultInstanceIndices: ReadonlyArray<number> };\n\n/**\n * Parameters for creating a {@link Runtime.ResourceResolver | ResourceResolver}.\n * @public\n */\nexport interface IResourceResolverCreateParams {\n /**\n * The {@link Runtime.IResourceManager | resource manager} that defines the resources available\n * and provides access to qualifiers and conditions.\n */\n resourceManager: IResourceManager;\n\n /**\n * The {@link QualifierTypes.ReadOnlyQualifierTypeCollector | readonly qualifier type collector}\n * that provides qualifier implementations for condition evaluation.\n */\n qualifierTypes: ReadOnlyQualifierTypeCollector;\n\n /**\n * The {@link Runtime.Context.IContextQualifierProvider | context qualifier provider} that resolves\n * qualifier values for the current context.\n */\n contextQualifierProvider: IContextQualifierProvider;\n\n /**\n * An optional listener for {@link Runtime.ResourceResolver | ResourceResolver} cache activity.\n */\n listener?: IResourceResolverCacheListener;\n}\n\n/**\n * High-performance runtime resource resolver with O(1) condition caching.\n * Resolves resources for a given context by evaluating conditions against qualifier values\n * and caching results for optimal performance.\n * @public\n */\nexport class ResourceResolver {\n /**\n * The resource manager that defines available resources and provides condition access.\n */\n public readonly resourceManager: IResourceManager;\n\n /**\n * The readonly qualifier type collector that provides qualifier implementations.\n */\n public readonly qualifierTypes: ReadOnlyQualifierTypeCollector;\n\n /**\n * The context qualifier provider that resolves qualifier values.\n */\n public readonly contextQualifierProvider: IContextQualifierProvider;\n\n /**\n * The cache array for resolved conditions, indexed by condition index for O(1) lookup.\n * Each entry stores the resolved {@link Runtime.IConditionMatchResult | condition match result} for\n * the corresponding condition.\n */\n public get conditionCache(): ReadonlyArray<IConditionMatchResult | undefined> {\n return this._conditionCache;\n }\n\n /**\n * The cache array for resolved condition sets, indexed by condition set index for O(1) lookup.\n * Each entry stores the resolved ConditionSetResolutionResult for the corresponding condition set.\n */\n public get conditionSetCache(): ReadonlyArray<ConditionSetResolutionResult | undefined> {\n return this._conditionSetCache;\n }\n\n /**\n * The cache array for resolved decisions, indexed by decision index for O(1) lookup.\n * Each entry stores the resolved DecisionResolutionResult for the corresponding decision.\n */\n public get decisionCache(): ReadonlyArray<DecisionResolutionResult | undefined> {\n return this._decisionCache;\n }\n\n /**\n * Cache array for resolved conditions, indexed by condition index for O(1) lookup.\n * Each entry stores the resolved QualifierMatchScore for the corresponding condition.\n */\n private readonly _conditionCache: Array<IConditionMatchResult | undefined>;\n\n /**\n * Cache array for resolved condition sets, indexed by condition set index for O(1) lookup.\n * Each entry stores the resolved ConditionSetResolutionResult for the corresponding condition set.\n */\n private readonly _conditionSetCache: Array<ConditionSetResolutionResult | undefined>;\n\n /**\n * Cache array for resolved decisions, indexed by decision index for O(1) lookup.\n * Each entry stores the resolved DecisionResolutionResult for the corresponding decision.\n */\n private readonly _decisionCache: Array<DecisionResolutionResult | undefined>;\n\n /**\n * The listener for {@link Runtime.ResourceResolver | ResourceResolver} cache activity.\n */\n private readonly _listener?: IResourceResolverCacheListener;\n\n /**\n * Constructor for a {@link Runtime.ResourceResolver | ResourceResolver} object.\n * @param params - {@link Runtime.IResourceResolverCreateParams | Parameters} used to create the resolver.\n */\n protected constructor(params: IResourceResolverCreateParams) {\n this.resourceManager = params.resourceManager;\n this.qualifierTypes = params.qualifierTypes;\n this.contextQualifierProvider = params.contextQualifierProvider;\n\n // Initialize condition cache array with size matching the condition collector\n const conditionCollectorSize = this.resourceManager.conditions.size;\n this._conditionCache = new Array<IConditionMatchResult | undefined>(conditionCollectorSize);\n\n // Initialize condition set cache array with size matching the condition set collector\n const conditionSetCollectorSize = this.resourceManager.conditionSets.size;\n this._conditionSetCache = new Array<ConditionSetResolutionResult | undefined>(conditionSetCollectorSize);\n\n // Initialize decision cache array with size matching the decision collector\n const decisionCollectorSize = this.resourceManager.decisions.size;\n this._decisionCache = new Array<DecisionResolutionResult | undefined>(decisionCollectorSize);\n\n this._listener = params.listener;\n }\n\n /**\n * Creates a new {@link Runtime.ResourceResolver | ResourceResolver} object.\n * @param params - {@link Runtime.IResourceResolverCreateParams | Parameters} used to create the resolver.\n * @returns `Success` with the new {@link Runtime.ResourceResolver | ResourceResolver} object if successful,\n * or `Failure` with an error message if not.\n * @public\n */\n public static create(params: IResourceResolverCreateParams): Result<ResourceResolver> {\n return captureResult(() => new ResourceResolver(params));\n }\n\n /**\n * Resolves a condition by evaluating it against the current context.\n * Uses O(1) caching based on the condition's globally unique sequential index.\n * @param condition - The {@link Conditions.Condition | condition} to resolve.\n * @returns `Success` with the {@link QualifierMatchScore | match score} if successful,\n * or `Failure` with an error message if the condition cannot be resolved.\n * @public\n */\n public resolveCondition(condition: Condition): Result<IConditionMatchResult> {\n // Get the condition's index for cache lookup\n const conditionIndex = condition.index;\n if (conditionIndex === undefined) {\n return fail(`Condition \"${condition.key}\" does not have a valid index`);\n }\n\n // Check cache first for O(1) lookup\n const cachedResult = this._conditionCache[conditionIndex];\n if (cachedResult !== undefined) {\n this._listener?.onCacheHit('condition', conditionIndex);\n return succeed(cachedResult);\n }\n\n // Resolve the condition by getting qualifier value and evaluating with qualifier type\n const score = this.contextQualifierProvider\n .get(condition.qualifier)\n .onSuccess((qualifierValue) => {\n // Evaluate the condition using the qualifier type's matching logic\n return succeed(condition.qualifier.type.matches(condition.value, qualifierValue, condition.operator));\n })\n .onFailure((err) => {\n this._listener?.onContextError(condition.qualifier.name, err);\n return fail(err);\n })\n .orDefault(NoMatch);\n\n const priority = condition.priority;\n const scoreAsDefault = condition.scoreAsDefault ?? NoMatch;\n const matchResult: IConditionMatchResult =\n score > NoMatch\n ? { score, priority, matchType: 'match' }\n : scoreAsDefault > NoMatch\n ? { score: scoreAsDefault, priority, matchType: 'matchAsDefault' }\n : { score: NoMatch, priority, matchType: 'noMatch' };\n\n // Cache the resolved value for future O(1) lookup\n this._conditionCache[conditionIndex] = matchResult;\n this._listener?.onCacheMiss('condition', conditionIndex);\n\n return succeed(matchResult);\n }\n\n /**\n * Resolves a condition set by evaluating all its constituent conditions against the current context.\n * Uses O(1) caching based on the condition set's globally unique sequential index.\n * @param conditionSet - The {@link Conditions.ConditionSet | condition set} to resolve.\n * @returns `Success` with the {@link Runtime.ConditionSetResolutionResult | resolution result} if successful,\n * or `Failure` with an error message if the condition set cannot be resolved.\n * @public\n */\n public resolveConditionSet(conditionSet: ConditionSet): Result<ConditionSetResolutionResult> {\n // Get the condition set's index for cache lookup\n const conditionSetIndex = conditionSet.index;\n if (conditionSetIndex === undefined) {\n return fail(`ConditionSet \"${conditionSet.key}\" does not have a valid index`);\n }\n\n // Check cache first for O(1) lookup\n const cachedResult = this._conditionSetCache[conditionSetIndex];\n if (cachedResult !== undefined) {\n this._listener?.onCacheHit('conditionSet', conditionSetIndex);\n return succeed(cachedResult);\n }\n\n // Resolve all conditions in the condition set\n const conditions: Array<IConditionMatchResult> = [];\n let matchType: ConditionMatchType = 'match';\n\n for (const condition of conditionSet.conditions) {\n const { value: conditionResult, message: conditionMessage } = this.resolveCondition(condition);\n\n if (conditionMessage !== undefined) {\n /* c8 ignore next 2 - defensive coding: extreme internal error scenario not reachable in normal operation */\n this._listener?.onCacheError('conditionSet', conditionSetIndex);\n return fail(`Failed to resolve condition \"${condition.key}\": ${conditionMessage}`);\n }\n\n conditions.push(conditionResult);\n\n if (conditionResult.matchType === 'noMatch') {\n // Cache the failure result\n return ConditionSetResolutionResult.create('noMatch', conditions)\n .onSuccess((result) => {\n this._conditionSetCache[conditionSetIndex] = result;\n this._listener?.onCacheMiss('conditionSet', conditionSetIndex);\n return succeed(result);\n })\n .onFailure((err) => {\n /* c8 ignore next 4 - defensive coding: extreme internal error scenario not reachable in normal operation */\n this._conditionSetCache[conditionSetIndex] = undefined;\n this._listener?.onCacheError('conditionSet', conditionSetIndex);\n return fail(`${conditionSetIndex}: error creating condition set resolution result: ${err}`);\n });\n }\n\n if (conditionResult.matchType === 'matchAsDefault') {\n matchType = 'matchAsDefault';\n }\n }\n\n // Cache the successful result\n return ConditionSetResolutionResult.create(matchType, conditions)\n .onSuccess((result) => {\n this._conditionSetCache[conditionSetIndex] = result;\n this._listener?.onCacheMiss('conditionSet', conditionSetIndex);\n return succeed(result);\n })\n .onFailure((err) => {\n /* c8 ignore next 4 - defensive coding: extreme internal error scenario not reachable in normal operation */\n this._conditionSetCache[conditionSetIndex] = undefined;\n this._listener?.onCacheError('conditionSet', conditionSetIndex);\n return fail(`${conditionSetIndex}: error creating condition set resolution result: ${err}`);\n });\n }\n\n /**\n * Resolves a decision by evaluating all its constituent condition sets against the current context.\n * Uses O(1) caching based on the decision's globally unique sequential index.\n * @param decision - The {@link Decisions.AbstractDecision | abstract decision} to resolve.\n * @returns `Success` with the {@link Runtime.DecisionResolutionResult | resolution result} if successful,\n * or `Failure` with an error message if the decision cannot be resolved.\n * @public\n */\n public resolveDecision(decision: AbstractDecision): Result<DecisionResolutionResult> {\n // Get the decision's index for cache lookup\n const decisionIndex = decision.index;\n if (decisionIndex === undefined) {\n return fail(`Decision \"${decision.key}\" does not have a valid index`);\n }\n\n // Check cache first for O(1) lookup\n const cachedResult = this._decisionCache[decisionIndex];\n if (cachedResult !== undefined) {\n this._listener?.onCacheHit('decision', decisionIndex);\n return succeed(cachedResult);\n }\n\n // Resolve all condition sets in the decision\n const matchingInstanceResults: Array<{ index: number; result: ConditionSetResolutionResult }> = [];\n const matchingDefaultInstanceResults: Array<{ index: number; result: ConditionSetResolutionResult }> = [];\n\n for (let instanceIndex = 0; instanceIndex < decision.candidates.length; instanceIndex++) {\n const candidate = decision.candidates[instanceIndex];\n const conditionSetResult = this.resolveConditionSet(candidate.conditionSet);\n\n if (conditionSetResult.isFailure()) {\n /* c8 ignore next 2 - defensive coding: extreme internal error scenario not reachable in normal operation */\n this._listener?.onCacheError('decision', decisionIndex);\n return fail(`${decision.key}: Failed to resolve condition set\": ${conditionSetResult.message}`);\n }\n\n const resolution = conditionSetResult.value;\n\n // Only include condition sets that match\n if (resolution.matchType === 'match') {\n matchingInstanceResults.push({\n index: instanceIndex,\n result: resolution\n });\n } else if (resolution.matchType === 'matchAsDefault') {\n matchingDefaultInstanceResults.push({\n index: instanceIndex,\n result: resolution\n });\n }\n // If condition set doesn't match, we simply skip it and continue (don't fail the decision)\n }\n\n // Sort by condition set resolution priority using the proper comparison logic\n matchingInstanceResults.sort((a, b) => ConditionSetResolutionResult.compare(a.result, b.result));\n matchingDefaultInstanceResults.sort((a, b) => ConditionSetResolutionResult.compare(a.result, b.result));\n\n // Extract just the instance indices in priority order\n const instanceIndices = matchingInstanceResults.map((item) => item.index);\n const defaultInstanceIndices = matchingDefaultInstanceResults.map((item) => item.index);\n\n // Cache the successful result\n const successResult: DecisionResolutionResult = {\n success: true,\n instanceIndices,\n defaultInstanceIndices\n };\n this._decisionCache[decisionIndex] = successResult;\n this._listener?.onCacheMiss('decision', decisionIndex);\n\n return succeed(successResult);\n }\n\n /**\n * Resolves a resource by finding the best matching candidate.\n * Uses the resource's associated decision to determine the best match based on the current context.\n * @param resource - The {@link Resources.Resource | resource} to resolve.\n * @returns `Success` with the best matching candidate if successful,\n * or `Failure` with an error message if no candidates match or resolution fails.\n * @public\n */\n public resolveResource(resource: IResource): Result<IResourceCandidate> {\n // Get the abstract decision from the resource's concrete decision\n const abstractDecision = resource.decision.baseDecision;\n\n // Resolve the decision to get candidate indices in priority order\n const decisionResult = this.resolveDecision(abstractDecision);\n /* c8 ignore next 3 - defense in depth almost impossible to hit */\n if (decisionResult.isFailure()) {\n return fail(`Failed to resolve decision for resource \"${resource.id}\": ${decisionResult.message}`);\n }\n\n const resolution = decisionResult.value;\n\n // Check if any candidates matched (regular or default)\n if (\n !resolution.success ||\n (resolution.instanceIndices.length === 0 && resolution.defaultInstanceIndices.length === 0)\n ) {\n return fail(`No matching candidates found for resource \"${resource.id}\"`);\n }\n\n // Prefer regular matches over default matches\n const candidateIndex =\n resolution.instanceIndices.length > 0\n ? resolution.instanceIndices[0] // Best regular match\n : resolution.defaultInstanceIndices[0]; // Best default match\n\n if (candidateIndex >= resource.candidates.length) {\n return fail(`Invalid candidate index ${candidateIndex} for resource \"${resource.id}\"`);\n }\n\n const bestCandidate = resource.candidates[candidateIndex];\n return succeed(bestCandidate);\n }\n\n /**\n * Resolves all matching resource candidates in priority order.\n * Uses the resource's associated decision to determine all matching candidates based on the current context.\n * @param resource - The {@link Resources.Resource | resource} to resolve.\n * @returns `Success` with an array of all matching candidates in priority order if successful,\n * or `Failure` with an error message if no candidates match or resolution fails.\n * @public\n */\n public resolveAllResourceCandidates(resource: IResource): Result<ReadonlyArray<IResourceCandidate>> {\n // Get the abstract decision from the resource's concrete decision\n const abstractDecision = resource.decision.baseDecision;\n\n // Resolve the decision to get candidate indices in priority order\n const decisionResult = this.resolveDecision(abstractDecision);\n /* c8 ignore next 3 - defense in depth almost impossible to hit */\n if (decisionResult.isFailure()) {\n return fail(`Failed to resolve decision for resource \"${resource.id}\": ${decisionResult.message}`);\n }\n\n const resolution = decisionResult.value;\n\n // Check if any candidates matched (regular or default)\n if (\n !resolution.success ||\n (resolution.instanceIndices.length === 0 && resolution.defaultInstanceIndices.length === 0)\n ) {\n return fail(`No matching candidates found for resource \"${resource.id}\"`);\n }\n\n // Get all matching candidates: regular matches first, then default matches\n const candidates: IResourceCandidate[] = [];\n\n // Add all regular matches first (already sorted by priority)\n for (const candidateIndex of resolution.instanceIndices) {\n if (candidateIndex >= resource.candidates.length) {\n return fail(`Invalid candidate index ${candidateIndex} for resource \"${resource.id}\"`);\n }\n const candidate = resource.candidates[candidateIndex];\n candidates.push(candidate);\n }\n\n // Add all default matches after regular matches (already sorted by priority)\n for (const candidateIndex of resolution.defaultInstanceIndices) {\n /* c8 ignore next 3 - defensive coding: extreme internal error scenario not reachable in normal operation */\n if (candidateIndex >= resource.candidates.length) {\n return fail(`Invalid candidate index ${candidateIndex} for resource \"${resource.id}\"`);\n }\n const candidate = resource.candidates[candidateIndex];\n candidates.push(candidate);\n }\n\n return succeed(candidates);\n }\n\n /**\n * Resolves a resource to a composed value by merging matching candidates according to their merge methods.\n * Starting from the highest priority candidates, finds the first \"full\" candidate and merges all higher\n * priority \"partial\" candidates into it in ascending order of priority.\n * @param resource - The {@link Resources.Resource | resource} to resolve.\n * @returns `Success` with the composed JsonValue if successful,\n * or `Failure` with an error message if no candidates match or resolution fails.\n * @public\n */\n public resolveComposedResourceValue(resource: IResource): Result<JsonValue> {\n return this.resolveAllResourceCandidates(resource).onSuccess((candidates) => {\n /* c8 ignore next 3 - defense in depth should never occur */\n if (candidates.length === 0) {\n return fail(`${resource.id}: No matching candidates found.`);\n }\n\n // Find the first full candidate and collect all partial candidates above it\n let fullCandidateIndex = -1;\n const partialCandidates: IResourceCandidate[] = [];\n\n for (let i = 0; i < candidates.length; i++) {\n const candidate = candidates[i];\n if (!candidate.isPartial) {\n // Found the first full candidate\n fullCandidateIndex = i;\n break;\n } else {\n // Collect partial candidates (these are in ascending priority order)\n partialCandidates.unshift(candidate);\n }\n }\n\n // If no full candidate found, use the last candidate as the base\n const baseCandidateIndex = fullCandidateIndex >= 0 ? fullCandidateIndex : candidates.length - 1;\n const baseCandidate = candidates[baseCandidateIndex];\n\n // If there are no partial candidates to merge, return the base candidate's value\n if (partialCandidates.length === 0) {\n return succeed(baseCandidate.json);\n }\n\n const allCandidates = [\n baseCandidate.json,\n ...partialCandidates.map((candidate) => candidate.json)\n ].filter((v): v is JsonObject => isJsonObject(v));\n\n /* c8 ignore next 3 - defensive check: non-object values in resource candidates should be prevented at validation time */\n if (allCandidates.length !== partialCandidates.length + 1) {\n return fail(`${resource.id}: Unable to compose non-object candidate values.`);\n }\n\n // Create JsonEditor with array replacement behavior for resource composition\n const editor = JsonEditor.create({\n merge: {\n arrayMergeBehavior: 'replace'\n }\n }).orThrow(); // Should never fail with valid options\n\n return editor\n .mergeObjectsInPlace({}, allCandidates)\n .withErrorFormat((err) => `${resource.id}: Composition failed: ${err}`);\n });\n }\n\n /**\n * Clears all caches (condition, condition set, and decision), forcing all cached items\n * to be re-evaluated on next access. This should be called when the context changes and cached\n * results are no longer valid.\n * @public\n */\n public clearConditionCache(): void {\n this._conditionCache.fill(undefined);\n this._conditionSetCache.fill(undefined);\n this._decisionCache.fill(undefined);\n\n this._listener?.onCacheClear('condition');\n this._listener?.onCacheClear('conditionSet');\n this._listener?.onCacheClear('decision');\n }\n\n /**\n * Gets the current size of the condition cache array.\n * @returns The size of the condition cache array.\n * @public\n */\n public get conditionCacheSize(): number {\n return this._conditionCache.length;\n }\n\n /**\n * Gets the current size of the condition set cache array.\n * @returns The size of the condition set cache array.\n * @public\n */\n public get conditionSetCacheSize(): number {\n return this._conditionSetCache.length;\n }\n\n /**\n * Gets the current size of the decision cache array.\n * @returns The size of the decision cache array.\n * @public\n */\n public get decisionCacheSize(): number {\n return this._decisionCache.length;\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fgv/ts-res",
|
|
3
|
-
"version": "5.0.0-
|
|
3
|
+
"version": "5.0.0-6",
|
|
4
4
|
"description": "Multi-dimensional Resource Runtime",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "dist/ts-res.d.ts",
|
|
@@ -44,22 +44,22 @@
|
|
|
44
44
|
"@rushstack/heft-node-rig": "~2.9.0",
|
|
45
45
|
"@types/heft-jest": "1.0.6",
|
|
46
46
|
"eslint-plugin-tsdoc": "~0.4.0",
|
|
47
|
-
"@fgv/ts-utils": "5.0.0-
|
|
48
|
-
"@fgv/ts-
|
|
49
|
-
"@fgv/ts-
|
|
50
|
-
"@fgv/ts-json-base": "5.0.0-
|
|
51
|
-
"@fgv/ts-
|
|
52
|
-
"@fgv/ts-
|
|
47
|
+
"@fgv/ts-utils-jest": "5.0.0-6",
|
|
48
|
+
"@fgv/ts-extras": "5.0.0-6",
|
|
49
|
+
"@fgv/ts-utils": "5.0.0-6",
|
|
50
|
+
"@fgv/ts-json-base": "5.0.0-6",
|
|
51
|
+
"@fgv/ts-bcp47": "5.0.0-6",
|
|
52
|
+
"@fgv/ts-json": "5.0.0-6"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"luxon": "^3.6.1"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"@fgv/ts-utils": "5.0.0-
|
|
59
|
-
"@fgv/ts-extras": "5.0.0-
|
|
60
|
-
"@fgv/ts-
|
|
61
|
-
"@fgv/ts-
|
|
62
|
-
"@fgv/ts-json
|
|
58
|
+
"@fgv/ts-utils": "5.0.0-6",
|
|
59
|
+
"@fgv/ts-extras": "5.0.0-6",
|
|
60
|
+
"@fgv/ts-json-base": "5.0.0-6",
|
|
61
|
+
"@fgv/ts-bcp47": "5.0.0-6",
|
|
62
|
+
"@fgv/ts-json": "5.0.0-6"
|
|
63
63
|
},
|
|
64
64
|
"scripts": {
|
|
65
65
|
"build": "heft build --clean",
|