@fgv/ts-res 5.0.0-5 → 5.0.0-7

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.
Files changed (33) hide show
  1. package/dist/ts-res.d.ts +136 -42
  2. package/lib/index.d.ts +8 -2
  3. package/lib/index.d.ts.map +1 -1
  4. package/lib/index.js +18 -2
  5. package/lib/index.js.map +1 -1
  6. package/lib/packlets/common/resources.d.ts +8 -0
  7. package/lib/packlets/common/resources.d.ts.map +1 -1
  8. package/lib/packlets/common/resources.js.map +1 -1
  9. package/lib/packlets/resource-types/jsonResourceType.d.ts +4 -4
  10. package/lib/packlets/resource-types/jsonResourceType.d.ts.map +1 -1
  11. package/lib/packlets/resource-types/jsonResourceType.js +1 -1
  12. package/lib/packlets/resource-types/jsonResourceType.js.map +1 -1
  13. package/lib/packlets/resource-types/resourceType.d.ts +16 -7
  14. package/lib/packlets/resource-types/resourceType.d.ts.map +1 -1
  15. package/lib/packlets/resource-types/resourceType.js.map +1 -1
  16. package/lib/packlets/resources/common.d.ts +12 -0
  17. package/lib/packlets/resources/common.d.ts.map +1 -1
  18. package/lib/packlets/resources/common.js.map +1 -1
  19. package/lib/packlets/resources/resourceManagerBuilder.d.ts +50 -3
  20. package/lib/packlets/resources/resourceManagerBuilder.d.ts.map +1 -1
  21. package/lib/packlets/resources/resourceManagerBuilder.js +203 -8
  22. package/lib/packlets/resources/resourceManagerBuilder.js.map +1 -1
  23. package/lib/packlets/runtime/cacheListener.d.ts +9 -0
  24. package/lib/packlets/runtime/cacheListener.d.ts.map +1 -1
  25. package/lib/packlets/runtime/cacheListener.js +6 -0
  26. package/lib/packlets/runtime/cacheListener.js.map +1 -1
  27. package/lib/packlets/runtime/cacheMetrics.d.ts +6 -0
  28. package/lib/packlets/runtime/cacheMetrics.d.ts.map +1 -1
  29. package/lib/packlets/runtime/cacheMetrics.js +11 -0
  30. package/lib/packlets/runtime/cacheMetrics.js.map +1 -1
  31. package/lib/packlets/runtime/resourceResolver.js +15 -11
  32. package/lib/packlets/runtime/resourceResolver.js.map +1 -1
  33. package/package.json +12 -12
@@ -1,6 +1,6 @@
1
1
  import { JsonValue } from '@fgv/ts-json-base';
2
2
  import { ICollectible, Result } from '@fgv/ts-utils';
3
- import { ResourceTypeIndex, ResourceTypeName, ResourceValueMergeMethod, ResourceId } from '../common';
3
+ import { CandidateCompleteness, ResourceTypeIndex, ResourceTypeName, ResourceValueMergeMethod, ResourceId } from '../common';
4
4
  /**
5
5
  * Parameters used to validate a {@link ResourceJson.Json.ILooseResourceCandidateDecl | resource candidate declaration}.
6
6
  * @public
@@ -56,30 +56,39 @@ export declare abstract class ResourceType<T = unknown> implements ICollectible<
56
56
  /**
57
57
  * Validates a JSON value for use as a partial resource instance value.
58
58
  * @param json - The JSON value to validate.
59
- * @param isPartial - `true` indicates that the value is expected to be partial.
59
+ * @param completeness - Describes {@link CandidateCompleteness | how complete} the candidate value is.
60
60
  * @returns `Success` with the strongly-typed partial resource value if the JSON is valid,
61
61
  * `Failure` with an error message otherwise.
62
62
  * @public
63
63
  */
64
- abstract validate(json: JsonValue, isPartial: true): Result<Partial<T>>;
64
+ abstract validate(json: JsonValue, completeness: CandidateCompleteness): Result<Partial<T>>;
65
65
  /**
66
66
  * Validates a JSON value for use as a complete resource instance value.
67
67
  * @param json - The JSON value to validate.
68
- * @param isPartial - `false` indicates that the value is expected to be complete.
68
+ * @param completeness - Describes {@link CandidateCompleteness | how complete} the candidate value is.
69
69
  * @returns `Success` with the strongly-typed resource value if the JSON is valid,
70
70
  * `Failure` with an error message otherwise.
71
71
  * @public
72
72
  */
73
- abstract validate(json: JsonValue, isPartial: false): Result<T>;
73
+ abstract validate(json: JsonValue, completeness: 'full'): Result<T>;
74
+ /**
75
+ * Validates a JSON value for use as a partial resource instance value.
76
+ * @param json - The JSON value to validate.
77
+ * @param completeness - Describes {@link CandidateCompleteness | how complete} the candidate value is.
78
+ * @returns `Success` with the strongly-typed partial resource value if the JSON is valid,
79
+ * `Failure` with an error message otherwise.
80
+ * @public
81
+ */
82
+ abstract validate(json: JsonValue, completeness: 'partial'): Result<Partial<T>>;
74
83
  /**
75
84
  * Validates a JSON value for use as a full or partial resource instance value.
76
85
  * @param json - The JSON value to validate.
77
- * @param isPartial - Indicates whether the value is expected to be partial.
86
+ * @param completeness - Describes {@link CandidateCompleteness | how complete} the candidate value is.
78
87
  * @returns `Success` with the strongly-typed full or partial resource value if
79
88
  * the JSON is valid, `Failure` with an error message otherwise.
80
89
  * @public
81
90
  */
82
- abstract validate(json: JsonValue, isPartial?: boolean): Result<T | Partial<T>>;
91
+ abstract validate(json: JsonValue, completeness?: CandidateCompleteness): Result<T | Partial<T>>;
83
92
  /**
84
93
  * Sets the index for this resource type. Once set, the index cannot be changed.
85
94
  */
@@ -1 +1 @@
1
- {"version":3,"file":"resourceType.d.ts","sourceRoot":"","sources":["../../../src/packlets/resource-types/resourceType.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAe,YAAY,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAGL,iBAAiB,EACjB,gBAAgB,EAChB,wBAAwB,EACxB,UAAU,EACX,MAAM,WAAW,CAAC;AAEnB;;;GAGG;AACH,MAAM,WAAW,sCAAsC;IACrD;;;OAGG;IACH,EAAE,EAAE,UAAU,CAAC;IAEf;;;OAGG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,IAAI,EAAE,SAAS,CAAC;IAEhB;;;OAGG;IACH,WAAW,EAAE,wBAAwB,CAAC;CACvC;AAED;;;;;GAKG;AACH,8BAAsB,YAAY,CAAC,CAAC,GAAG,OAAO,CAAE,YAAW,YAAY,CAAC,gBAAgB,EAAE,iBAAiB,CAAC;IAC1G,OAAO,CAAC,YAAY,CAA+D;IACnF;;OAEG;IACH,IAAW,GAAG,IAAI,gBAAgB,CAEjC;IAED;;OAEG;IACH,IAAW,KAAK,IAAI,iBAAiB,GAAG,SAAS,CAEhD;IAED,SAAS,aAAa,GAAG,EAAE,gBAAgB,EAAE,KAAK,CAAC,EAAE,MAAM;IAS3D;;;;;;;OAOG;aACa,mBAAmB,CAAC,KAAK,EAAE,sCAAsC,GAAG,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE1G;;;;;;;OAOG;aACa,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAE9E;;;;;;;OAOG;aACa,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC;IAEtE;;;;;;;OAOG;aACa,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAEtF;;OAEG;IACI,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,iBAAiB,CAAC;CAG1D"}
1
+ {"version":3,"file":"resourceType.d.ts","sourceRoot":"","sources":["../../../src/packlets/resource-types/resourceType.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAe,YAAY,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EACL,qBAAqB,EAGrB,iBAAiB,EACjB,gBAAgB,EAChB,wBAAwB,EACxB,UAAU,EACX,MAAM,WAAW,CAAC;AAEnB;;;GAGG;AACH,MAAM,WAAW,sCAAsC;IACrD;;;OAGG;IACH,EAAE,EAAE,UAAU,CAAC;IAEf;;;OAGG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,IAAI,EAAE,SAAS,CAAC;IAEhB;;;OAGG;IACH,WAAW,EAAE,wBAAwB,CAAC;CACvC;AAED;;;;;GAKG;AACH,8BAAsB,YAAY,CAAC,CAAC,GAAG,OAAO,CAAE,YAAW,YAAY,CAAC,gBAAgB,EAAE,iBAAiB,CAAC;IAC1G,OAAO,CAAC,YAAY,CAA+D;IACnF;;OAEG;IACH,IAAW,GAAG,IAAI,gBAAgB,CAEjC;IAED;;OAEG;IACH,IAAW,KAAK,IAAI,iBAAiB,GAAG,SAAS,CAEhD;IAED,SAAS,aAAa,GAAG,EAAE,gBAAgB,EAAE,KAAK,CAAC,EAAE,MAAM;IAS3D;;;;;;;OAOG;aACa,mBAAmB,CAAC,KAAK,EAAE,sCAAsC,GAAG,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE1G;;;;;;;OAOG;aACa,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,qBAAqB,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAElG;;;;;;;OAOG;aACa,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;IAE1E;;;;;;;OAOG;aACa,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAEtF;;;;;;;OAOG;aACa,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAEvG;;OAEG;IACI,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,iBAAiB,CAAC;CAG1D"}
@@ -1 +1 @@
1
- {"version":3,"file":"resourceType.js","sourceRoot":"","sources":["../../../src/packlets/resource-types/resourceType.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AAGH,4CAAkE;AAClE,sCAOmB;AAgCnB;;;;;GAKG;AACH,MAAsB,YAAY;IAEhC;;OAEG;IACH,IAAW,GAAG;QACZ,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,IAAW,KAAK;QACd,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;IACjC,CAAC;IAED,YAAsB,GAAqB,EAAE,KAAc;QACzD,IAAI,CAAC,YAAY,GAAG,IAAI,sBAAW,CAAC,WAAW,CAAsC;YACnF,GAAG;YACH,qDAAqD;YACrD,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,iBAAQ,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS;YACtF,cAAc,EAAE,gBAAa,CAAC,iBAAiB;SAChD,CAAC,CAAC;IACL,CAAC;IA0CD;;OAEG;IACI,QAAQ,CAAC,KAAa;QAC3B,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;CACF;AAvED,oCAuEC","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 { JsonValue } from '@fgv/ts-json-base';\nimport { Collections, ICollectible, Result } from '@fgv/ts-utils';\nimport {\n Convert as CommonConvert,\n Validate,\n ResourceTypeIndex,\n ResourceTypeName,\n ResourceValueMergeMethod,\n ResourceId\n} from '../common';\n\n/**\n * Parameters used to validate a {@link ResourceJson.Json.ILooseResourceCandidateDecl | resource candidate declaration}.\n * @public\n */\nexport interface IResourceCandidateValidationProperties {\n /**\n * {@inheritdoc ResourceJson.Json.ILooseResourceCandidateDecl.id}\n * @public\n */\n id: ResourceId;\n\n /**\n * {@inheritdoc ResourceJson.Json.ILooseResourceCandidateDecl.isPartial}\n * @public\n */\n isPartial: boolean;\n\n /**\n * {@inheritdoc ResourceJson.Json.ILooseResourceCandidateDecl.json}\n * @public\n */\n json: JsonValue;\n\n /**\n * {@inheritdoc ResourceJson.Json.ILooseResourceCandidateDecl.mergeMethod}\n * @public\n */\n mergeMethod: ResourceValueMergeMethod;\n}\n\n/**\n * Abstract base class for resource types which are responsible for\n * validating and converting JSON values into the appropriate strongly-typed\n * resource value.\n * @public\n */\nexport abstract class ResourceType<T = unknown> implements ICollectible<ResourceTypeName, ResourceTypeIndex> {\n private _collectible: Collections.Collectible<ResourceTypeName, ResourceTypeIndex>;\n /**\n * The key for this resource type.\n */\n public get key(): ResourceTypeName {\n return this._collectible.key;\n }\n\n /**\n * The index for this resource type.\n */\n public get index(): ResourceTypeIndex | undefined {\n return this._collectible.index;\n }\n\n protected constructor(key: ResourceTypeName, index?: number) {\n this._collectible = new Collections.Collectible<ResourceTypeName, ResourceTypeIndex>({\n key,\n /* c8 ignore next 1 - coverage having a rough time */\n index: index !== undefined ? Validate.toResourceTypeIndex(index).orThrow() : undefined,\n indexConverter: CommonConvert.resourceTypeIndex\n });\n }\n\n /**\n * Validates properties of a {@link ResourceJson.Json.ILooseResourceCandidateDecl | resource candidate declaration} for\n * a resource instance value.\n * @param props - The {@link ResourceTypes.IResourceCandidateValidationProperties | properties } to validate.\n * @returns `Success` with the strongly-typed resource value if the JSON and merge method\n * are valid, `Failure` with an error message otherwise.\n * @public\n */\n public abstract validateDeclaration(props: IResourceCandidateValidationProperties): Result<T | Partial<T>>;\n\n /**\n * Validates a JSON value for use as a partial resource instance value.\n * @param json - The JSON value to validate.\n * @param isPartial - `true` indicates that the value is expected to be partial.\n * @returns `Success` with the strongly-typed partial resource value if the JSON is valid,\n * `Failure` with an error message otherwise.\n * @public\n */\n public abstract validate(json: JsonValue, isPartial: true): Result<Partial<T>>;\n\n /**\n * Validates a JSON value for use as a complete resource instance value.\n * @param json - The JSON value to validate.\n * @param isPartial - `false` indicates that the value is expected to be complete.\n * @returns `Success` with the strongly-typed resource value if the JSON is valid,\n * `Failure` with an error message otherwise.\n * @public\n */\n public abstract validate(json: JsonValue, isPartial: false): Result<T>;\n\n /**\n * Validates a JSON value for use as a full or partial resource instance value.\n * @param json - The JSON value to validate.\n * @param isPartial - Indicates whether the value is expected to be partial.\n * @returns `Success` with the strongly-typed full or partial resource value if\n * the JSON is valid, `Failure` with an error message otherwise.\n * @public\n */\n public abstract validate(json: JsonValue, isPartial?: boolean): Result<T | Partial<T>>;\n\n /**\n * Sets the index for this resource type. Once set, the index cannot be changed.\n */\n public setIndex(index: number): Result<ResourceTypeIndex> {\n return this._collectible.setIndex(index);\n }\n}\n"]}
1
+ {"version":3,"file":"resourceType.js","sourceRoot":"","sources":["../../../src/packlets/resource-types/resourceType.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AAGH,4CAAkE;AAClE,sCAQmB;AAgCnB;;;;;GAKG;AACH,MAAsB,YAAY;IAEhC;;OAEG;IACH,IAAW,GAAG;QACZ,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,IAAW,KAAK;QACd,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;IACjC,CAAC;IAED,YAAsB,GAAqB,EAAE,KAAc;QACzD,IAAI,CAAC,YAAY,GAAG,IAAI,sBAAW,CAAC,WAAW,CAAsC;YACnF,GAAG;YACH,qDAAqD;YACrD,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,iBAAQ,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS;YACtF,cAAc,EAAE,gBAAa,CAAC,iBAAiB;SAChD,CAAC,CAAC;IACL,CAAC;IAoDD;;OAEG;IACI,QAAQ,CAAC,KAAa;QAC3B,OAAO,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;CACF;AAjFD,oCAiFC","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 { JsonValue } from '@fgv/ts-json-base';\nimport { Collections, ICollectible, Result } from '@fgv/ts-utils';\nimport {\n CandidateCompleteness,\n Convert as CommonConvert,\n Validate,\n ResourceTypeIndex,\n ResourceTypeName,\n ResourceValueMergeMethod,\n ResourceId\n} from '../common';\n\n/**\n * Parameters used to validate a {@link ResourceJson.Json.ILooseResourceCandidateDecl | resource candidate declaration}.\n * @public\n */\nexport interface IResourceCandidateValidationProperties {\n /**\n * {@inheritdoc ResourceJson.Json.ILooseResourceCandidateDecl.id}\n * @public\n */\n id: ResourceId;\n\n /**\n * {@inheritdoc ResourceJson.Json.ILooseResourceCandidateDecl.isPartial}\n * @public\n */\n isPartial: boolean;\n\n /**\n * {@inheritdoc ResourceJson.Json.ILooseResourceCandidateDecl.json}\n * @public\n */\n json: JsonValue;\n\n /**\n * {@inheritdoc ResourceJson.Json.ILooseResourceCandidateDecl.mergeMethod}\n * @public\n */\n mergeMethod: ResourceValueMergeMethod;\n}\n\n/**\n * Abstract base class for resource types which are responsible for\n * validating and converting JSON values into the appropriate strongly-typed\n * resource value.\n * @public\n */\nexport abstract class ResourceType<T = unknown> implements ICollectible<ResourceTypeName, ResourceTypeIndex> {\n private _collectible: Collections.Collectible<ResourceTypeName, ResourceTypeIndex>;\n /**\n * The key for this resource type.\n */\n public get key(): ResourceTypeName {\n return this._collectible.key;\n }\n\n /**\n * The index for this resource type.\n */\n public get index(): ResourceTypeIndex | undefined {\n return this._collectible.index;\n }\n\n protected constructor(key: ResourceTypeName, index?: number) {\n this._collectible = new Collections.Collectible<ResourceTypeName, ResourceTypeIndex>({\n key,\n /* c8 ignore next 1 - coverage having a rough time */\n index: index !== undefined ? Validate.toResourceTypeIndex(index).orThrow() : undefined,\n indexConverter: CommonConvert.resourceTypeIndex\n });\n }\n\n /**\n * Validates properties of a {@link ResourceJson.Json.ILooseResourceCandidateDecl | resource candidate declaration} for\n * a resource instance value.\n * @param props - The {@link ResourceTypes.IResourceCandidateValidationProperties | properties } to validate.\n * @returns `Success` with the strongly-typed resource value if the JSON and merge method\n * are valid, `Failure` with an error message otherwise.\n * @public\n */\n public abstract validateDeclaration(props: IResourceCandidateValidationProperties): Result<T | Partial<T>>;\n\n /**\n * Validates a JSON value for use as a partial resource instance value.\n * @param json - The JSON value to validate.\n * @param completeness - Describes {@link CandidateCompleteness | how complete} the candidate value is.\n * @returns `Success` with the strongly-typed partial resource value if the JSON is valid,\n * `Failure` with an error message otherwise.\n * @public\n */\n public abstract validate(json: JsonValue, completeness: CandidateCompleteness): Result<Partial<T>>;\n\n /**\n * Validates a JSON value for use as a complete resource instance value.\n * @param json - The JSON value to validate.\n * @param completeness - Describes {@link CandidateCompleteness | how complete} the candidate value is.\n * @returns `Success` with the strongly-typed resource value if the JSON is valid,\n * `Failure` with an error message otherwise.\n * @public\n */\n public abstract validate(json: JsonValue, completeness: 'full'): Result<T>;\n\n /**\n * Validates a JSON value for use as a partial resource instance value.\n * @param json - The JSON value to validate.\n * @param completeness - Describes {@link CandidateCompleteness | how complete} the candidate value is.\n * @returns `Success` with the strongly-typed partial resource value if the JSON is valid,\n * `Failure` with an error message otherwise.\n * @public\n */\n public abstract validate(json: JsonValue, completeness: 'partial'): Result<Partial<T>>;\n\n /**\n * Validates a JSON value for use as a full or partial resource instance value.\n * @param json - The JSON value to validate.\n * @param completeness - Describes {@link CandidateCompleteness | how complete} the candidate value is.\n * @returns `Success` with the strongly-typed full or partial resource value if\n * the JSON is valid, `Failure` with an error message otherwise.\n * @public\n */\n public abstract validate(json: JsonValue, completeness?: CandidateCompleteness): Result<T | Partial<T>>;\n\n /**\n * Sets the index for this resource type. Once set, the index cannot be changed.\n */\n public setIndex(index: number): Result<ResourceTypeIndex> {\n return this._collectible.setIndex(index);\n }\n}\n"]}
@@ -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,9 +8,10 @@ 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
+ import * as Config from '../config';
14
15
  /**
15
16
  * Interface for parameters to the {@link Resources.ResourceManagerBuilder.create | ResourceManagerBuilder create method}.
16
17
  * @public
@@ -96,6 +97,15 @@ export declare class ResourceManagerBuilder implements IResourceManager {
96
97
  * @public
97
98
  */
98
99
  static create(params: IResourceManagerBuilderCreateParams): Result<ResourceManagerBuilder>;
100
+ /**
101
+ * Creates a new {@link Resources.ResourceManagerBuilder | ResourceManagerBuilder} object from a predefined system configuration.
102
+ * @param name - The name of the predefined system configuration to use.
103
+ * @param qualifierDefaultValues - Optional default values for qualifiers.
104
+ * @returns `Success` with the new {@link Resources.ResourceManagerBuilder | ResourceManagerBuilder} object if successful,
105
+ * or `Failure` with an error message if not.
106
+ * @public
107
+ */
108
+ static createPredefined(name: Config.PredefinedSystemConfiguration, qualifierDefaultValues?: Config.ISystemConfigurationInitParams['qualifierDefaultValues']): Result<ResourceManagerBuilder>;
99
109
  /**
100
110
  * Given a {@link ResourceJson.Json.ILooseResourceCandidateDecl | resource candidate declaration}, builds and adds
101
111
  * a {@link Resources.ResourceCandidate | candidate} to the manager.
@@ -211,10 +221,47 @@ export declare class ResourceManagerBuilder implements IResourceManager {
211
221
  * Creates a filtered clone of this ResourceManagerBuilder using the specified context.
212
222
  * This is a convenience method that creates a new ResourceManagerBuilder with the same
213
223
  * configuration but filtered to include only candidates that match the provided context.
214
- * @param options - Options for the cloning operation, including the strongly-typed filterForContext property.
224
+ * If candidates are provided for editing, they will be applied with collision detection.
225
+ * @param options - Options for the cloning operation, including the strongly-typed filterForContext property and optional candidates for edits.
215
226
  * @returns A Result containing the new filtered ResourceManagerBuilder.
216
227
  * @public
217
228
  */
218
- clone(options?: IResourceDeclarationOptions): Result<ResourceManagerBuilder>;
229
+ clone(options?: IResourceManagerCloneOptions): Result<ResourceManagerBuilder>;
230
+ /**
231
+ * Creates a resource ID keyed map from an array of loose resource candidate declarations.
232
+ * This enables efficient detection of edit collisions by grouping candidates by their target resource.
233
+ * @param candidates - Array of loose resource candidate declarations to organize
234
+ * @returns A Result containing a Map where keys are validated ResourceIds and values are arrays of candidates for that resource
235
+ * @internal
236
+ */
237
+ private static _createCandidatesByResourceMap;
238
+ /**
239
+ * Generates a proper ConditionSet token for collision detection using the existing ConditionSet.getKeyForDecl method.
240
+ * @param conditionSet - The condition set to generate a token for
241
+ * @param conditionCollector - The condition collector needed for validation context
242
+ * @returns A Result containing the ConditionSet token if successful, or failure if validation fails
243
+ * @internal
244
+ */
245
+ private static _getConditionSetToken;
246
+ /**
247
+ * Applies candidate edits to a resource declaration, handling collisions using condition set tokens.
248
+ * If there's no collision, adds the candidate. If there's a collision, replaces the original candidate with the edit.
249
+ * @param resourceDecl - The original resource declaration to potentially modify
250
+ * @param candidatesByResource - Map of resource IDs to arrays of candidate edits
251
+ * @param conditionCollector - The condition collector needed for generating condition tokens
252
+ * @returns A Result containing the resource declaration to use (original or modified)
253
+ * @internal
254
+ */
255
+ private static _applyEditsToResourceDeclaration;
256
+ /**
257
+ * Creates a new resource declaration from an array of candidate declarations.
258
+ * This is used when cloning to create new resources that don't exist in the original manager.
259
+ * @param resourceId - The validated resource ID for the new resource
260
+ * @param candidates - Array of loose candidate declarations for the new resource
261
+ * @param conditionCollector - The condition collector for validation context
262
+ * @returns A Result containing the new resource declaration if successful, or failure if validation fails
263
+ * @internal
264
+ */
265
+ private static _createResourceDeclFromCandidates;
219
266
  }
220
267
  //# 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,EAClB,qBAAqB,EACrB,0BAA0B,EAC1B,6BAA6B,EAC9B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,yBAAyB,EAAE,iCAAiC,EAAE,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAW,UAAU,EAAY,MAAM,WAAW,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,KAAK,YAAY,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,OAAO,MAAM,YAAY,CAAC;AAEtC;;;GAGG;AACH,MAAM,WAAW,mCAAmC;IAClD,UAAU,EAAE,2BAA2B,CAAC;IACxC,aAAa,EAAE,6BAA6B,CAAC;CAC9C;AAED;;;GAGG;AACH,MAAM,MAAM,kCAAkC,GAC1C,WAAW,CAAC,qBAAqB,GACjC,2BAA2B,CAAC;AAEhC;;;;;;GAMG;AACH,qBAAa,sBAAuB,YAAW,gBAAgB;IAC7D,SAAgB,UAAU,EAAE,2BAA2B,CAAC;IACxD,SAAgB,aAAa,EAAE,6BAA6B,CAAC;IAE7D,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,kBAAkB,CAAC;IACnD,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,qBAAqB,CAAC;IACzD,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,yBAAyB,CAAC;IACzD,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,mBAAmB,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IAChF,SAAgB,eAAe,EAAE,mBAAmB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAE3E,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC;IAE1B;;;;OAIG;IACH,IAAW,UAAU,IAAI,0BAA0B,CAElD;IAED;;;;OAIG;IACH,IAAW,aAAa,IAAI,6BAA6B,CAExD;IAED;;;;OAIG;IACH,IAAW,SAAS,IAAI,iCAAiC,CAExD;IAED;;OAEG;IACH,IAAW,SAAS,IAAI,WAAW,CAAC,4BAA4B,CAAC,UAAU,EAAE,eAAe,CAAC,CAE5F;IAED;;OAEG;IACH,IAAW,IAAI,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,IAAW,YAAY,IAAI,MAAM,CAEhC;IAED;;OAEG;IACH,SAAS,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAElC;;OAEG;IACH,IAAW,aAAa,IAAI,MAAM,CAKjC;IAED;;OAEG;IACH,IAAW,cAAc,IAAI,WAAW,CAAC,4BAA4B,CAAC,UAAU,EAAE,QAAQ,CAAC,CAE1F;IAED;;;;OAIG;IACH,SAAS,aAAa,MAAM,EAAE,mCAAmC;IAwBjE;;;;;;OAMG;WACW,MAAM,CAAC,MAAM,EAAE,mCAAmC,GAAG,MAAM,CAAC,sBAAsB,CAAC;IAIjG;;;;;;OAMG;IACI,iBAAiB,CACtB,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,2BAA2B,GAClD,cAAc,CAAC,iBAAiB,EAAE,2BAA2B,CAAC;IA6B1D,WAAW,CAChB,IAAI,EAAE,YAAY,CAAC,IAAI,CAAC,kBAAkB,GACzC,cAAc,CAAC,eAAe,EAAE,2BAA2B,CAAC;IAuC/D;;;;OAIG;IACI,eAAe,IAAI,aAAa,CAAC,eAAe,CAAC;IAIxD;;OAEG;IACI,gBAAgB,IAAI,aAAa,CAAC,iBAAiB,CAAC;IAI3D;;;;;OAKG;IACI,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC;IAMrD;;;;;OAKG;IAEI,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,qBAAqB,CAAC;IAM5F;;;;OAIG;IACI,oBAAoB,IAAI,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAM9D;;;;OAIG;IACI,qBAAqB,IAAI,MAAM,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAIxE;;;;OAIG;IACI,aAAa,IAAI,MAAM,CAAC,WAAW,CAAC,4BAA4B,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAiB9F;;;;;OAKG;IACI,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC;IAI5B;;;;;;OAMG;IACI,uBAAuB,CAC5B,OAAO,EAAE,OAAO,CAAC,qBAAqB,EACtC,OAAO,CAAC,EAAE,OAAO,CAAC,oBAAoB,GACrC,aAAa,CAAC,iBAAiB,CAAC;IAInC;;;;;;;OAOG;IACI,sBAAsB,CAC3B,OAAO,EAAE,OAAO,CAAC,qBAAqB,EACtC,OAAO,CAAC,EAAE,OAAO,CAAC,oBAAoB,GACrC,aAAa,CAAC,eAAe,CAAC;IAMjC;;;;;;OAMG;IACI,4BAA4B,CACjC,OAAO,EAAE,OAAO,CAAC,qBAAqB,EACtC,OAAO,CAAC,EAAE,OAAO,CAAC,oBAAoB,GACrC,MAAM,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAM3C;;;;;;;OAOG;IACI,2BAA2B,CAChC,OAAO,EAAE,OAAO,CAAC,qBAAqB,EACtC,OAAO,CAAC,EAAE,OAAO,CAAC,oBAAoB,GACrC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAMlC;;;;;;;OAOG;IACI,6BAA6B,CAClC,OAAO,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,wBAAwB,GACvD,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,2BAA2B,CAAC;IA+B5D;;;;;;;;OAQG;IACI,yBAAyB,CAC9B,OAAO,CAAC,EAAE,2BAA2B,GACpC,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,uBAAuB,CAAC;IA+B1D;;;;;;;OAOG;IAEI,KAAK,CAAC,OAAO,CAAC,EAAE,2BAA2B,GAAG,MAAM,CAAC,sBAAsB,CAAC;CAqBpF"}
1
+ {"version":3,"file":"resourceManagerBuilder.d.ts","sourceRoot":"","sources":["../../../src/packlets/resources/resourceManagerBuilder.ts"],"names":[],"mappings":"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"}
@@ -63,6 +63,7 @@ const resourceBuilder_1 = require("./resourceBuilder");
63
63
  const resource_1 = require("./resource");
64
64
  const ResourceJson = __importStar(require("../resource-json"));
65
65
  const Context = __importStar(require("../context"));
66
+ const Config = __importStar(require("../config"));
66
67
  /**
67
68
  * Builder for a collection of {@link Resources.Resource | resources}. Collects
68
69
  * {@link Resources.ResourceCandidate | candidates} for each resource into a
@@ -165,6 +166,22 @@ class ResourceManagerBuilder {
165
166
  static create(params) {
166
167
  return (0, ts_utils_1.captureResult)(() => new ResourceManagerBuilder(params));
167
168
  }
169
+ /**
170
+ * Creates a new {@link Resources.ResourceManagerBuilder | ResourceManagerBuilder} object from a predefined system configuration.
171
+ * @param name - The name of the predefined system configuration to use.
172
+ * @param qualifierDefaultValues - Optional default values for qualifiers.
173
+ * @returns `Success` with the new {@link Resources.ResourceManagerBuilder | ResourceManagerBuilder} object if successful,
174
+ * or `Failure` with an error message if not.
175
+ * @public
176
+ */
177
+ static createPredefined(name, qualifierDefaultValues) {
178
+ return Config.getPredefinedSystemConfiguration(name, qualifierDefaultValues ? { qualifierDefaultValues } : undefined).onSuccess((systemConfig) => {
179
+ return ResourceManagerBuilder.create({
180
+ qualifiers: systemConfig.qualifiers,
181
+ resourceTypes: systemConfig.resourceTypes
182
+ });
183
+ });
184
+ }
168
185
  /**
169
186
  * Given a {@link ResourceJson.Json.ILooseResourceCandidateDecl | resource candidate declaration}, builds and adds
170
187
  * a {@link Resources.ResourceCandidate | candidate} to the manager.
@@ -422,7 +439,8 @@ class ResourceManagerBuilder {
422
439
  * Creates a filtered clone of this ResourceManagerBuilder using the specified context.
423
440
  * This is a convenience method that creates a new ResourceManagerBuilder with the same
424
441
  * configuration but filtered to include only candidates that match the provided context.
425
- * @param options - Options for the cloning operation, including the strongly-typed filterForContext property.
442
+ * If candidates are provided for editing, they will be applied with collision detection.
443
+ * @param options - Options for the cloning operation, including the strongly-typed filterForContext property and optional candidates for edits.
426
444
  * @returns A Result containing the new filtered ResourceManagerBuilder.
427
445
  * @public
428
446
  */
@@ -433,19 +451,196 @@ class ResourceManagerBuilder {
433
451
  qualifiers: this.qualifiers,
434
452
  resourceTypes: this.resourceTypes
435
453
  }).onSuccess((newManager) => {
436
- // Add each resource from the filtered collection to the new manager
437
- if (collection.resources) {
438
- for (const resourceDecl of collection.resources) {
439
- const addResult = newManager.addResource(resourceDecl);
440
- if (addResult.isFailure()) {
441
- return (0, ts_utils_1.fail)(`${resourceDecl.id}: Failed to add resource to cloned manager: ${addResult.message}`);
454
+ // Check if we have candidates to apply as edits
455
+ const editCandidates = (options === null || options === void 0 ? void 0 : options.candidates) || [];
456
+ const candidatesByResourceResult = editCandidates.length > 0
457
+ ? ResourceManagerBuilder._createCandidatesByResourceMap(editCandidates)
458
+ : (0, ts_utils_1.succeed)(new Map());
459
+ return candidatesByResourceResult.onSuccess((candidatesByResource) => {
460
+ // Track which resource IDs have been processed from the original collection
461
+ const processedResourceIds = new Set();
462
+ // Add each resource from the filtered collection to the new manager
463
+ if (collection.resources) {
464
+ for (const resourceDecl of collection.resources) {
465
+ processedResourceIds.add(resourceDecl.id);
466
+ // Apply edits if there are candidates for this resource
467
+ const editedDeclResult = ResourceManagerBuilder._applyEditsToResourceDeclaration(resourceDecl, candidatesByResource, this._conditions);
468
+ if (editedDeclResult.isFailure()) {
469
+ return (0, ts_utils_1.fail)(`${resourceDecl.id}: Failed to apply edits: ${editedDeclResult.message}`);
470
+ }
471
+ const addResult = newManager.addResource(editedDeclResult.value);
472
+ if (addResult.isFailure()) {
473
+ return (0, ts_utils_1.fail)(`${resourceDecl.id}: Failed to add resource to cloned manager: ${addResult.message}`);
474
+ }
475
+ }
476
+ }
477
+ // Handle any remaining candidates that target new resources not in the original collection
478
+ const errors = new ts_utils_1.MessageAggregator();
479
+ for (const [resourceId, candidates] of candidatesByResource) {
480
+ if (!processedResourceIds.has(resourceId)) {
481
+ // Create a new resource declaration for candidates targeting a new resource ID
482
+ ResourceManagerBuilder._createResourceDeclFromCandidates(resourceId, candidates, this._conditions)
483
+ .withErrorFormat((e) => `${resourceId}: Failed to create new resource from candidates: ${e}`)
484
+ .onSuccess((newResourceDecl) => {
485
+ return newManager
486
+ .addResource(newResourceDecl)
487
+ .withErrorFormat((e) => `${resourceId}: Failed to add new resource to cloned manager: ${e}`);
488
+ })
489
+ .aggregateError(errors);
442
490
  }
443
491
  }
492
+ return errors.returnOrReport((0, ts_utils_1.succeed)(newManager));
493
+ });
494
+ });
495
+ });
496
+ }
497
+ /**
498
+ * Creates a resource ID keyed map from an array of loose resource candidate declarations.
499
+ * This enables efficient detection of edit collisions by grouping candidates by their target resource.
500
+ * @param candidates - Array of loose resource candidate declarations to organize
501
+ * @returns A Result containing a Map where keys are validated ResourceIds and values are arrays of candidates for that resource
502
+ * @internal
503
+ */
504
+ static _createCandidatesByResourceMap(candidates) {
505
+ const candidatesByResource = new Map();
506
+ for (const candidate of candidates) {
507
+ const { value: resourceId, message } = common_1.Validate.toResourceId(candidate.id);
508
+ if (message !== undefined) {
509
+ return (0, ts_utils_1.fail)(`Invalid resource ID "${candidate.id}": ${message}`);
510
+ }
511
+ const existingCandidates = candidatesByResource.get(resourceId);
512
+ if (existingCandidates) {
513
+ existingCandidates.push(candidate);
514
+ }
515
+ else {
516
+ candidatesByResource.set(resourceId, [candidate]);
517
+ }
518
+ }
519
+ return (0, ts_utils_1.succeed)(candidatesByResource);
520
+ }
521
+ /**
522
+ * Generates a proper ConditionSet token for collision detection using the existing ConditionSet.getKeyForDecl method.
523
+ * @param conditionSet - The condition set to generate a token for
524
+ * @param conditionCollector - The condition collector needed for validation context
525
+ * @returns A Result containing the ConditionSet token if successful, or failure if validation fails
526
+ * @internal
527
+ */
528
+ static _getConditionSetToken(conditionSet, conditionCollector) {
529
+ if (!conditionSet) {
530
+ return (0, ts_utils_1.succeed)(conditions_1.ConditionSet.UnconditionalKey);
531
+ }
532
+ // Convert ConditionSetDecl to IConditionSetDecl format
533
+ let conditionSetDecl;
534
+ if (Array.isArray(conditionSet)) {
535
+ // ConditionSetDeclAsArray: array of ILooseConditionDecl
536
+ conditionSetDecl = { conditions: conditionSet };
537
+ }
538
+ else {
539
+ // ConditionSetDeclAsRecord: Record<string, string | IChildConditionDecl>
540
+ const conditions = Object.entries(conditionSet).map(([qualifierName, value]) => {
541
+ if (typeof value === 'string') {
542
+ return { qualifierName, value };
543
+ }
544
+ else {
545
+ return Object.assign({ qualifierName }, value);
444
546
  }
445
- return (0, ts_utils_1.succeed)(newManager);
446
547
  });
548
+ conditionSetDecl = { conditions };
549
+ }
550
+ // Validate and convert to IValidatedConditionSetDecl
551
+ return conditions_1.Convert.validatedConditionSetDecl
552
+ .convert(conditionSetDecl, { conditions: conditionCollector })
553
+ .onSuccess((validatedDecl) => {
554
+ // Use proper ConditionSet.getKeyForDecl method to generate the token
555
+ return conditions_1.ConditionSet.getKeyForDecl(validatedDecl);
447
556
  });
448
557
  }
558
+ /**
559
+ * Applies candidate edits to a resource declaration, handling collisions using condition set tokens.
560
+ * If there's no collision, adds the candidate. If there's a collision, replaces the original candidate with the edit.
561
+ * @param resourceDecl - The original resource declaration to potentially modify
562
+ * @param candidatesByResource - Map of resource IDs to arrays of candidate edits
563
+ * @param conditionCollector - The condition collector needed for generating condition tokens
564
+ * @returns A Result containing the resource declaration to use (original or modified)
565
+ * @internal
566
+ */
567
+ static _applyEditsToResourceDeclaration(resourceDecl, candidatesByResource, conditionCollector) {
568
+ const { value: resourceId, message } = common_1.Validate.toResourceId(resourceDecl.id);
569
+ if (message !== undefined) {
570
+ return (0, ts_utils_1.fail)(`Invalid resource ID "${resourceDecl.id}": ${message}`);
571
+ }
572
+ const editCandidates = candidatesByResource.get(resourceId);
573
+ if (!editCandidates || editCandidates.length === 0) {
574
+ return (0, ts_utils_1.succeed)(resourceDecl);
575
+ }
576
+ // Use Map approach: apply original candidates first, then replace with edits on collision
577
+ const candidatesByConditionKey = new Map();
578
+ // First, add all original candidates keyed by their condition set token
579
+ for (const candidate of resourceDecl.candidates || []) {
580
+ const conditionTokenResult = ResourceManagerBuilder._getConditionSetToken(candidate.conditions, conditionCollector);
581
+ if (conditionTokenResult.isFailure()) {
582
+ return (0, ts_utils_1.fail)(`Failed to generate condition token for original candidate: ${conditionTokenResult.message}`);
583
+ }
584
+ candidatesByConditionKey.set(conditionTokenResult.value, candidate);
585
+ }
586
+ // Then, apply edits (this replaces any colliding original candidates)
587
+ // Convert edit candidates (which have ids) to child candidates (without ids) for merging
588
+ for (const editCandidate of editCandidates) {
589
+ const conditionTokenResult = ResourceManagerBuilder._getConditionSetToken(editCandidate.conditions, conditionCollector);
590
+ if (conditionTokenResult.isFailure()) {
591
+ return (0, ts_utils_1.fail)(`Failed to generate condition token for edit candidate: ${conditionTokenResult.message}`);
592
+ }
593
+ const childCandidate = {
594
+ json: editCandidate.json,
595
+ conditions: editCandidate.conditions,
596
+ isPartial: editCandidate.isPartial,
597
+ mergeMethod: editCandidate.mergeMethod
598
+ };
599
+ candidatesByConditionKey.set(conditionTokenResult.value, childCandidate);
600
+ }
601
+ // Extract the final merged candidate list
602
+ const mergedCandidates = Array.from(candidatesByConditionKey.values());
603
+ const modifiedDecl = Object.assign(Object.assign({}, resourceDecl), { candidates: mergedCandidates });
604
+ return (0, ts_utils_1.succeed)(modifiedDecl);
605
+ }
606
+ /**
607
+ * Creates a new resource declaration from an array of candidate declarations.
608
+ * This is used when cloning to create new resources that don't exist in the original manager.
609
+ * @param resourceId - The validated resource ID for the new resource
610
+ * @param candidates - Array of loose candidate declarations for the new resource
611
+ * @param conditionCollector - The condition collector for validation context
612
+ * @returns A Result containing the new resource declaration if successful, or failure if validation fails
613
+ * @internal
614
+ */
615
+ static _createResourceDeclFromCandidates(resourceId, candidates, conditionCollector) {
616
+ // Convert candidate declarations to child candidate declarations
617
+ const childCandidates = [];
618
+ // Ensure we have candidates
619
+ if (candidates.length === 0) {
620
+ return (0, ts_utils_1.fail)('Cannot create resource declaration from empty candidates array');
621
+ }
622
+ // Extract resourceTypeName from the first candidate (all candidates for the same resource should have the same type)
623
+ const resourceTypeName = candidates[0].resourceTypeName;
624
+ if (!resourceTypeName) {
625
+ return (0, ts_utils_1.fail)('resourceTypeName is required for new resource candidates');
626
+ }
627
+ for (const candidate of candidates) {
628
+ const childCandidate = {
629
+ json: candidate.json,
630
+ conditions: candidate.conditions,
631
+ isPartial: candidate.isPartial,
632
+ mergeMethod: candidate.mergeMethod
633
+ };
634
+ childCandidates.push(childCandidate);
635
+ }
636
+ // Create the new resource declaration
637
+ const newResourceDecl = {
638
+ id: resourceId,
639
+ candidates: childCandidates,
640
+ resourceTypeName
641
+ };
642
+ return (0, ts_utils_1.succeed)(newResourceDecl);
643
+ }
449
644
  }
450
645
  exports.ResourceManagerBuilder = ResourceManagerBuilder;
451
646
  //# sourceMappingURL=resourceManagerBuilder.js.map