@higher.archi/boe 1.0.21 → 1.0.22

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 (34) hide show
  1. package/dist/core/types/rule.d.ts +1 -1
  2. package/dist/core/types/rule.d.ts.map +1 -1
  3. package/dist/engines/ranking/compiler.d.ts +12 -0
  4. package/dist/engines/ranking/compiler.d.ts.map +1 -0
  5. package/dist/engines/ranking/compiler.js +163 -0
  6. package/dist/engines/ranking/compiler.js.map +1 -0
  7. package/dist/engines/ranking/engine.d.ts +48 -0
  8. package/dist/engines/ranking/engine.d.ts.map +1 -0
  9. package/dist/engines/ranking/engine.js +89 -0
  10. package/dist/engines/ranking/engine.js.map +1 -0
  11. package/dist/engines/ranking/index.d.ts +9 -0
  12. package/dist/engines/ranking/index.d.ts.map +1 -0
  13. package/dist/engines/ranking/index.js +23 -0
  14. package/dist/engines/ranking/index.js.map +1 -0
  15. package/dist/engines/ranking/strategy.d.ts +21 -0
  16. package/dist/engines/ranking/strategy.d.ts.map +1 -0
  17. package/dist/engines/ranking/strategy.js +250 -0
  18. package/dist/engines/ranking/strategy.js.map +1 -0
  19. package/dist/engines/ranking/types.d.ts +142 -0
  20. package/dist/engines/ranking/types.d.ts.map +1 -0
  21. package/dist/engines/ranking/types.js +46 -0
  22. package/dist/engines/ranking/types.js.map +1 -0
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +12 -1
  26. package/dist/index.js.map +1 -1
  27. package/package.json +1 -1
  28. package/src/core/types/rule.ts +1 -1
  29. package/src/engines/ranking/compiler.ts +194 -0
  30. package/src/engines/ranking/engine.ts +120 -0
  31. package/src/engines/ranking/index.ts +46 -0
  32. package/src/engines/ranking/strategy.ts +333 -0
  33. package/src/engines/ranking/types.ts +231 -0
  34. package/src/index.ts +36 -0
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Ranking Engine Types
3
+ *
4
+ * Comparative scoring engine that ranks N entities relative to each other.
5
+ * Supports score-based ranking, Elo ratings, and head-to-head pairwise comparison.
6
+ */
7
+
8
+ import type {
9
+ CompiledScoringRuleSet,
10
+ ScoringOptions,
11
+ ScoringTierMatch,
12
+ TierDefinition
13
+ } from '../scoring/types';
14
+ import type { SemanticPriority } from '../utility/types';
15
+
16
+ // ========================================
17
+ // Semantic Types
18
+ // ========================================
19
+
20
+ /** Ranking algorithm to use */
21
+ export type RankingStrategy = 'score' | 'elo' | 'head-to-head';
22
+
23
+ /** Sort direction for rankings */
24
+ export type RankingDirection = 'highest-first' | 'lowest-first';
25
+
26
+ /** Human-readable percentile bracket */
27
+ export type PercentileLabel =
28
+ | 'top-1%'
29
+ | 'top-5%'
30
+ | 'top-10%'
31
+ | 'top-25%'
32
+ | 'top-50%'
33
+ | 'bottom-half';
34
+
35
+ /** Rank movement since previous ranking */
36
+ export type Movement = 'climbed' | 'steady' | 'dropped';
37
+
38
+ /** Elo K-factor presets controlling rating volatility */
39
+ export type KFactorPreset = 'volatile' | 'standard' | 'stable';
40
+
41
+ export const K_FACTOR_VALUES: Record<KFactorPreset, number> = {
42
+ 'volatile': 32, // New entities, fast adjustment
43
+ 'standard': 16, // Default
44
+ 'stable': 8 // Established entities, slow drift
45
+ };
46
+
47
+ export function isKFactorPreset(value: unknown): value is KFactorPreset {
48
+ return typeof value === 'string' && value in K_FACTOR_VALUES;
49
+ }
50
+
51
+ // ========================================
52
+ // Resolver Functions
53
+ // ========================================
54
+
55
+ /** Map a percentile (0-100) to a semantic label */
56
+ export function resolvePercentileLabel(percentile: number): PercentileLabel {
57
+ if (percentile >= 99) return 'top-1%';
58
+ if (percentile >= 95) return 'top-5%';
59
+ if (percentile >= 90) return 'top-10%';
60
+ if (percentile >= 75) return 'top-25%';
61
+ if (percentile >= 50) return 'top-50%';
62
+ return 'bottom-half';
63
+ }
64
+
65
+ /** Map rank change to a semantic movement label */
66
+ export function resolveMovement(previousRank: number, currentRank: number): Movement {
67
+ if (currentRank < previousRank) return 'climbed'; // lower rank number = better
68
+ if (currentRank > previousRank) return 'dropped';
69
+ return 'steady';
70
+ }
71
+
72
+ // ========================================
73
+ // Criterion Types (Head-to-Head)
74
+ // ========================================
75
+
76
+ /** A dimension for pairwise comparison */
77
+ export type RankingCriterion = {
78
+ id: string;
79
+ name?: string;
80
+ weight: number | SemanticPriority; // 'critical', 'high', 'medium', 'low'
81
+ direction: RankingDirection;
82
+ };
83
+
84
+ /** Compiled criterion with resolved numeric weight */
85
+ export type CompiledRankingCriterion = {
86
+ id: string;
87
+ name?: string;
88
+ weight: number; // normalized to sum to 1.0
89
+ direction: RankingDirection;
90
+ };
91
+
92
+ // ========================================
93
+ // Strategy-Specific Config Types
94
+ // ========================================
95
+
96
+ export type ScoreRankingConfig<T extends TierDefinition = TierDefinition> = {
97
+ direction?: RankingDirection; // default: 'highest-first'
98
+ tiers?: T[];
99
+ };
100
+
101
+ export type EloConfig = {
102
+ initialRating?: number; // default: 1500
103
+ kFactor?: KFactorPreset | number; // default: 'standard'
104
+ direction?: RankingDirection;
105
+ };
106
+
107
+ export type HeadToHeadConfig = {
108
+ direction?: RankingDirection;
109
+ };
110
+
111
+ // ========================================
112
+ // Source RuleSet Types (Discriminated Union)
113
+ // ========================================
114
+
115
+ type RankingRuleSetBase = {
116
+ id: string;
117
+ name?: string;
118
+ mode: 'ranking';
119
+ };
120
+
121
+ /** Score strategy: point at a scoring ruleset, rank entities by totalScore */
122
+ export type ScoreRankingRuleSet<T extends TierDefinition = TierDefinition> = RankingRuleSetBase & {
123
+ strategy: 'score';
124
+ scoringRuleset: CompiledScoringRuleSet<T>;
125
+ scoringOptions?: ScoringOptions;
126
+ entityType: string;
127
+ config?: ScoreRankingConfig<T>;
128
+ };
129
+
130
+ /** Elo strategy: process match history, compute ratings */
131
+ export type EloRankingRuleSet = RankingRuleSetBase & {
132
+ strategy: 'elo';
133
+ entityType: string;
134
+ matchType?: string; // default: 'MatchResult'
135
+ config?: EloConfig;
136
+ };
137
+
138
+ /** Head-to-head strategy: pairwise comparison on weighted criteria */
139
+ export type HeadToHeadRankingRuleSet = RankingRuleSetBase & {
140
+ strategy: 'head-to-head';
141
+ entityType: string;
142
+ criteria: RankingCriterion[];
143
+ config?: HeadToHeadConfig;
144
+ };
145
+
146
+ export type RankingRuleSet<T extends TierDefinition = TierDefinition> =
147
+ | ScoreRankingRuleSet<T>
148
+ | EloRankingRuleSet
149
+ | HeadToHeadRankingRuleSet;
150
+
151
+ // ========================================
152
+ // Compiled RuleSet Types
153
+ // ========================================
154
+
155
+ type CompiledRankingRuleSetBase = {
156
+ id: string;
157
+ name?: string;
158
+ mode: 'ranking';
159
+ };
160
+
161
+ export type CompiledScoreRankingRuleSet<T extends TierDefinition = TierDefinition> = CompiledRankingRuleSetBase & {
162
+ strategy: 'score';
163
+ scoringRuleset: CompiledScoringRuleSet<T>;
164
+ scoringOptions?: ScoringOptions;
165
+ entityType: string;
166
+ config: {
167
+ direction: RankingDirection;
168
+ tiers?: T[];
169
+ };
170
+ };
171
+
172
+ export type CompiledEloRankingRuleSet = CompiledRankingRuleSetBase & {
173
+ strategy: 'elo';
174
+ entityType: string;
175
+ matchType: string;
176
+ config: {
177
+ initialRating: number;
178
+ kFactor: number;
179
+ direction: RankingDirection;
180
+ };
181
+ };
182
+
183
+ export type CompiledHeadToHeadRankingRuleSet = CompiledRankingRuleSetBase & {
184
+ strategy: 'head-to-head';
185
+ entityType: string;
186
+ criteria: CompiledRankingCriterion[];
187
+ config: {
188
+ direction: RankingDirection;
189
+ };
190
+ };
191
+
192
+ export type CompiledRankingRuleSet<T extends TierDefinition = TierDefinition> =
193
+ | CompiledScoreRankingRuleSet<T>
194
+ | CompiledEloRankingRuleSet
195
+ | CompiledHeadToHeadRankingRuleSet;
196
+
197
+ // ========================================
198
+ // Runtime Types
199
+ // ========================================
200
+
201
+ /** Previous ranking for movement tracking */
202
+ export type PreviousRanking = {
203
+ entityId: string;
204
+ rank: number;
205
+ };
206
+
207
+ /** Runtime options */
208
+ export type RankingOptions = {
209
+ previousRankings?: PreviousRanking[];
210
+ onRank?: (entity: RankedEntity) => void;
211
+ };
212
+
213
+ /** Per-entity result */
214
+ export type RankedEntity<T extends TierDefinition = TierDefinition> = {
215
+ entityId: string;
216
+ rank: number; // 1-based
217
+ score: number;
218
+ percentile: number; // 0-100
219
+ percentileLabel: PercentileLabel;
220
+ tier?: ScoringTierMatch<T>;
221
+ movement?: Movement; // only when previousRankings provided
222
+ delta?: number; // rank positions changed (positive = climbed)
223
+ };
224
+
225
+ /** Full ranking result */
226
+ export type RankingResult<T extends TierDefinition = TierDefinition> = {
227
+ rankings: RankedEntity<T>[];
228
+ totalEntities: number;
229
+ strategy: RankingStrategy;
230
+ executionTimeMs: number;
231
+ };
package/src/index.ts CHANGED
@@ -409,6 +409,42 @@ export type {
409
409
  ExpertMemberConfig, ScoringMemberConfig
410
410
  } from './engines/ensemble';
411
411
 
412
+ // Ranking
413
+ export {
414
+ RankingEngine,
415
+ RankingExecutor,
416
+ compileRankingRuleSet,
417
+ rankingStrategy,
418
+ K_FACTOR_VALUES,
419
+ isKFactorPreset,
420
+ resolvePercentileLabel,
421
+ resolveMovement
422
+ } from './engines/ranking';
423
+ export type {
424
+ RankingStrategy,
425
+ RankingDirection,
426
+ PercentileLabel,
427
+ Movement,
428
+ KFactorPreset,
429
+ RankingCriterion,
430
+ CompiledRankingCriterion,
431
+ ScoreRankingConfig,
432
+ EloConfig,
433
+ HeadToHeadConfig,
434
+ ScoreRankingRuleSet,
435
+ EloRankingRuleSet,
436
+ HeadToHeadRankingRuleSet,
437
+ RankingRuleSet,
438
+ CompiledScoreRankingRuleSet,
439
+ CompiledEloRankingRuleSet,
440
+ CompiledHeadToHeadRankingRuleSet,
441
+ CompiledRankingRuleSet,
442
+ PreviousRanking,
443
+ RankingOptions,
444
+ RankedEntity,
445
+ RankingResult
446
+ } from './engines/ranking';
447
+
412
448
  // ========================================
413
449
  // Utility Functions (from old modules, re-exported for convenience)
414
450
  // ========================================