@shaxpir/duiduidui-models 1.9.25 → 1.9.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,60 @@
1
+ import { Conditions } from '../models/Condition';
2
+ /**
3
+ * Represents a difficulty range with guaranteed min (defaults to 0).
4
+ * Used for intersecting pool difficulty ranges with Collection constraints.
5
+ */
6
+ export interface DifficultyRange {
7
+ min: number;
8
+ max: number | undefined;
9
+ }
10
+ /**
11
+ * Extracts difficulty constraints from Conditions.
12
+ *
13
+ * Checks the 'all' section for difficulty conditions since that's where
14
+ * Collection-level constraints are placed (they must all be satisfied).
15
+ *
16
+ * Exploits the invariant that difficulty and skill level are always >= 0,
17
+ * so min defaults to 0 when not specified.
18
+ *
19
+ * @param conditions - The conditions to search
20
+ * @returns DifficultyRange if a difficulty condition is found, null otherwise
21
+ */
22
+ export declare function extractDifficultyConstraints(conditions?: Conditions): DifficultyRange | null;
23
+ /**
24
+ * Result of intersecting difficulty ranges.
25
+ */
26
+ export interface DifficultyRangeIntersection {
27
+ /** The effective minimum difficulty to use */
28
+ min: number;
29
+ /** The effective maximum difficulty to use */
30
+ max: number;
31
+ /** True if a valid intersection was found, false if fell back to Collection range */
32
+ usedIntersection: boolean;
33
+ /** True if Collection had a difficulty constraint */
34
+ hadCollectionConstraint: boolean;
35
+ }
36
+ /**
37
+ * Calculates the intersection of a pool's difficulty range with Collection constraints.
38
+ *
39
+ * If no intersection exists (ranges are disjoint), returns the Collection's range
40
+ * since the Collection constraints take precedence over skill-based calculations.
41
+ *
42
+ * @param poolMin - The pool's calculated minimum difficulty
43
+ * @param poolMax - The pool's calculated maximum difficulty
44
+ * @param collectionRange - The Collection's difficulty constraints (if any)
45
+ * @returns The effective range to use for queries, plus metadata
46
+ */
47
+ export declare function intersectDifficultyRanges(poolMin: number, poolMax: number, collectionRange: DifficultyRange | null): DifficultyRangeIntersection;
48
+ /**
49
+ * Checks if a difficulty value falls within a range.
50
+ *
51
+ * Useful for in-memory filtering in strategies that don't use database queries
52
+ * (ReinforcementPoolStrategy, StalePoolStrategy, DecompositionPoolStrategy).
53
+ *
54
+ * Uses half-open interval semantics: min is inclusive (>=), max is exclusive (<).
55
+ *
56
+ * @param difficulty - The difficulty value to check
57
+ * @param range - The range to check against (null means no constraint)
58
+ * @returns true if difficulty is within range or no range specified
59
+ */
60
+ export declare function isWithinDifficultyRange(difficulty: number, range: DifficultyRange | null): boolean;
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractDifficultyConstraints = extractDifficultyConstraints;
4
+ exports.intersectDifficultyRanges = intersectDifficultyRanges;
5
+ exports.isWithinDifficultyRange = isWithinDifficultyRange;
6
+ /**
7
+ * Extracts difficulty constraints from Conditions.
8
+ *
9
+ * Checks the 'all' section for difficulty conditions since that's where
10
+ * Collection-level constraints are placed (they must all be satisfied).
11
+ *
12
+ * Exploits the invariant that difficulty and skill level are always >= 0,
13
+ * so min defaults to 0 when not specified.
14
+ *
15
+ * @param conditions - The conditions to search
16
+ * @returns DifficultyRange if a difficulty condition is found, null otherwise
17
+ */
18
+ function extractDifficultyConstraints(conditions) {
19
+ if (!conditions?.all)
20
+ return null;
21
+ for (const condition of conditions.all) {
22
+ if (condition.type === 'difficulty') {
23
+ const diffCondition = condition;
24
+ return {
25
+ min: diffCondition.min ?? 0,
26
+ max: diffCondition.max
27
+ };
28
+ }
29
+ }
30
+ return null;
31
+ }
32
+ /**
33
+ * Calculates the intersection of a pool's difficulty range with Collection constraints.
34
+ *
35
+ * If no intersection exists (ranges are disjoint), returns the Collection's range
36
+ * since the Collection constraints take precedence over skill-based calculations.
37
+ *
38
+ * @param poolMin - The pool's calculated minimum difficulty
39
+ * @param poolMax - The pool's calculated maximum difficulty
40
+ * @param collectionRange - The Collection's difficulty constraints (if any)
41
+ * @returns The effective range to use for queries, plus metadata
42
+ */
43
+ function intersectDifficultyRanges(poolMin, poolMax, collectionRange) {
44
+ // No Collection constraint - use pool's range as-is
45
+ if (!collectionRange) {
46
+ return {
47
+ min: poolMin,
48
+ max: poolMax,
49
+ usedIntersection: true,
50
+ hadCollectionConstraint: false
51
+ };
52
+ }
53
+ // Calculate intersection
54
+ const intersectMin = Math.max(poolMin, collectionRange.min);
55
+ const intersectMax = collectionRange.max !== undefined
56
+ ? Math.min(poolMax, collectionRange.max)
57
+ : poolMax; // No upper bound on Collection, use pool's max
58
+ // Check if intersection is valid (non-empty range)
59
+ if (intersectMin < intersectMax) {
60
+ return {
61
+ min: intersectMin,
62
+ max: intersectMax,
63
+ usedIntersection: true,
64
+ hadCollectionConstraint: true
65
+ };
66
+ }
67
+ // No valid intersection - fall back to Collection's range
68
+ return {
69
+ min: collectionRange.min,
70
+ max: collectionRange.max ?? poolMax, // Use pool max if Collection has no upper bound
71
+ usedIntersection: false,
72
+ hadCollectionConstraint: true
73
+ };
74
+ }
75
+ /**
76
+ * Checks if a difficulty value falls within a range.
77
+ *
78
+ * Useful for in-memory filtering in strategies that don't use database queries
79
+ * (ReinforcementPoolStrategy, StalePoolStrategy, DecompositionPoolStrategy).
80
+ *
81
+ * Uses half-open interval semantics: min is inclusive (>=), max is exclusive (<).
82
+ *
83
+ * @param difficulty - The difficulty value to check
84
+ * @param range - The range to check against (null means no constraint)
85
+ * @returns true if difficulty is within range or no range specified
86
+ */
87
+ function isWithinDifficultyRange(difficulty, range) {
88
+ if (!range)
89
+ return true;
90
+ if (difficulty < range.min)
91
+ return false;
92
+ if (range.max !== undefined && difficulty >= range.max)
93
+ return false;
94
+ return true;
95
+ }
@@ -1,6 +1,7 @@
1
1
  export * from './AvatarUri';
2
2
  export * from './ConditionMatcher';
3
3
  export * from './Database';
4
+ export * from './DifficultyRange';
4
5
  export * from './Encryption';
5
6
  export * from './Logging';
6
7
  export * from './SenseRankEncoder';
@@ -18,6 +18,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
18
18
  __exportStar(require("./AvatarUri"), exports);
19
19
  __exportStar(require("./ConditionMatcher"), exports);
20
20
  __exportStar(require("./Database"), exports);
21
+ __exportStar(require("./DifficultyRange"), exports);
21
22
  __exportStar(require("./Encryption"), exports);
22
23
  __exportStar(require("./Logging"), exports);
23
24
  __exportStar(require("./SenseRankEncoder"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shaxpir/duiduidui-models",
3
- "version": "1.9.25",
3
+ "version": "1.9.26",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/shaxpir/duiduidui-models"