@actuarial-ts/core 0.10.0 → 0.12.0

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 (91) hide show
  1. package/README.md +9 -7
  2. package/dist/analysisRecipe.d.ts.map +1 -1
  3. package/dist/analysisRecipe.js +20 -1
  4. package/dist/analysisRecipe.js.map +1 -1
  5. package/dist/canonical.d.ts.map +1 -1
  6. package/dist/canonical.js +64 -5
  7. package/dist/canonical.js.map +1 -1
  8. package/dist/customizationContracts.d.ts +16 -1
  9. package/dist/customizationContracts.d.ts.map +1 -1
  10. package/dist/descriptiveStatistics.js +1 -1
  11. package/dist/descriptiveStatistics.js.map +1 -1
  12. package/dist/diagnosticAggregation.d.ts +26 -0
  13. package/dist/diagnosticAggregation.d.ts.map +1 -1
  14. package/dist/diagnosticAggregation.js +125 -11
  15. package/dist/diagnosticAggregation.js.map +1 -1
  16. package/dist/diagnosticAuditText.d.ts +11 -0
  17. package/dist/diagnosticAuditText.d.ts.map +1 -0
  18. package/dist/diagnosticAuditText.js +179 -0
  19. package/dist/diagnosticAuditText.js.map +1 -0
  20. package/dist/diagnosticFormulas.d.ts.map +1 -1
  21. package/dist/diagnosticFormulas.js +71 -12
  22. package/dist/diagnosticFormulas.js.map +1 -1
  23. package/dist/diagnosticFreeze.d.ts +15 -1
  24. package/dist/diagnosticFreeze.d.ts.map +1 -1
  25. package/dist/diagnosticFreeze.js +82 -31
  26. package/dist/diagnosticFreeze.js.map +1 -1
  27. package/dist/diagnosticKeys.d.ts +9 -0
  28. package/dist/diagnosticKeys.d.ts.map +1 -0
  29. package/dist/diagnosticKeys.js +20 -0
  30. package/dist/diagnosticKeys.js.map +1 -0
  31. package/dist/diagnosticOrdering.d.ts.map +1 -1
  32. package/dist/diagnosticOrdering.js +9 -2
  33. package/dist/diagnosticOrdering.js.map +1 -1
  34. package/dist/diagnosticPeriods.d.ts.map +1 -1
  35. package/dist/diagnosticPeriods.js +19 -1
  36. package/dist/diagnosticPeriods.js.map +1 -1
  37. package/dist/diagnosticPreparation.d.ts +19 -0
  38. package/dist/diagnosticPreparation.d.ts.map +1 -1
  39. package/dist/diagnosticPreparation.js +544 -231
  40. package/dist/diagnosticPreparation.js.map +1 -1
  41. package/dist/diagnosticReview.d.ts.map +1 -1
  42. package/dist/diagnosticReview.js +419 -186
  43. package/dist/diagnosticReview.js.map +1 -1
  44. package/dist/diagnosticReviewSources.d.ts +6 -1
  45. package/dist/diagnosticReviewSources.d.ts.map +1 -1
  46. package/dist/diagnosticReviewSources.js +59 -14
  47. package/dist/diagnosticReviewSources.js.map +1 -1
  48. package/dist/diagnosticReviewStore.d.ts.map +1 -1
  49. package/dist/diagnosticReviewStore.js +48 -7
  50. package/dist/diagnosticReviewStore.js.map +1 -1
  51. package/dist/diagnosticRunner.d.ts.map +1 -1
  52. package/dist/diagnosticRunner.js +112 -37
  53. package/dist/diagnosticRunner.js.map +1 -1
  54. package/dist/diagnosticRuntime.d.ts.map +1 -1
  55. package/dist/diagnosticRuntime.js +11 -1
  56. package/dist/diagnosticRuntime.js.map +1 -1
  57. package/dist/diagnosticSourceOrdering.d.ts +27 -0
  58. package/dist/diagnosticSourceOrdering.d.ts.map +1 -1
  59. package/dist/diagnosticSourceOrdering.js +98 -12
  60. package/dist/diagnosticSourceOrdering.js.map +1 -1
  61. package/dist/mack.d.ts.map +1 -1
  62. package/dist/mack.js +35 -0
  63. package/dist/mack.js.map +1 -1
  64. package/dist/types.d.ts +1 -1
  65. package/dist/types.d.ts.map +1 -1
  66. package/dist/types.js +1 -0
  67. package/dist/types.js.map +1 -1
  68. package/dist/version.d.ts +1 -1
  69. package/dist/version.js +1 -1
  70. package/package.json +1 -1
  71. package/src/analysisRecipe.ts +18 -1
  72. package/src/canonical.ts +63 -5
  73. package/src/customizationContracts.ts +12 -1
  74. package/src/descriptiveStatistics.ts +1 -1
  75. package/src/diagnosticAggregation.ts +173 -9
  76. package/src/diagnosticAuditText.ts +187 -0
  77. package/src/diagnosticFormulas.ts +77 -27
  78. package/src/diagnosticFreeze.ts +75 -30
  79. package/src/diagnosticKeys.ts +22 -0
  80. package/src/diagnosticOrdering.ts +9 -8
  81. package/src/diagnosticPeriods.ts +21 -1
  82. package/src/diagnosticPreparation.ts +624 -272
  83. package/src/diagnosticReview.ts +566 -268
  84. package/src/diagnosticReviewSources.ts +69 -18
  85. package/src/diagnosticReviewStore.ts +48 -6
  86. package/src/diagnosticRunner.ts +133 -54
  87. package/src/diagnosticRuntime.ts +11 -1
  88. package/src/diagnosticSourceOrdering.ts +115 -11
  89. package/src/mack.ts +41 -0
  90. package/src/types.ts +1 -0
  91. package/src/version.ts +1 -1
@@ -0,0 +1,22 @@
1
+ import { canonicalJson } from "./canonical.js";
2
+
3
+ /**
4
+ * `canonicalJson` for a flat array of JSON scalars through the native
5
+ * serializer. Arrays keep their order and each finite number, string, boolean
6
+ * and null has exactly one canonical rendering, so the text is byte-identical
7
+ * to `canonicalJson(values)`. Any other element defers to `canonicalJson`,
8
+ * including its errors, so callers keep the same contract on every input.
9
+ */
10
+ export function canonicalScalarArrayJson(values: readonly unknown[]): string {
11
+ for (const value of values) {
12
+ if (
13
+ typeof value === "string" ||
14
+ typeof value === "boolean" ||
15
+ value === null ||
16
+ (typeof value === "number" && Number.isFinite(value))
17
+ )
18
+ continue;
19
+ return canonicalJson(values);
20
+ }
21
+ return JSON.stringify(values);
22
+ }
@@ -77,15 +77,17 @@ export function compareDiagnosticFindings(
77
77
  );
78
78
  }
79
79
 
80
+ // Tuple comparisons are written out field by field: the section 15 order of two
81
+ // equal-length tuples is exactly the first non-zero field comparison, and this
82
+ // avoids allocating two arrays for every comparison inside large sorts.
80
83
  export function compareDiagnosticContributions(
81
84
  left: DiagnosticMeasureContribution,
82
85
  right: DiagnosticMeasureContribution,
83
86
  ): number {
84
87
  return (
85
- compareDiagnosticIdentityValues(
86
- [left.sourceId, left.status, left.deduplicated],
87
- [right.sourceId, right.status, right.deduplicated],
88
- ) ||
88
+ compareDiagnosticIdentityValues(left.sourceId, right.sourceId) ||
89
+ compareDiagnosticIdentityValues(left.status, right.status) ||
90
+ compareDiagnosticIdentityValues(left.deduplicated, right.deduplicated) ||
89
91
  compareSources(left.sources, right.sources) ||
90
92
  compareDiagnosticIdentityValues(left, right)
91
93
  );
@@ -96,10 +98,9 @@ export function compareDiagnosticBlockers(
96
98
  right: DiagnosticStructuralBlocker,
97
99
  ): number {
98
100
  return (
99
- compareDiagnosticIdentityValues(
100
- [left.code, left.message, left.sourceIds],
101
- [right.code, right.message, right.sourceIds],
102
- ) ||
101
+ compareDiagnosticIdentityValues(left.code, right.code) ||
102
+ compareDiagnosticIdentityValues(left.message, right.message) ||
103
+ compareDiagnosticIdentityValues(left.sourceIds, right.sourceIds) ||
103
104
  compareSources(left.sources, right.sources) ||
104
105
  compareDiagnosticIdentityValues(left.finding, right.finding)
105
106
  );
@@ -14,11 +14,28 @@ export interface DiagnosticNormalizedPeriod {
14
14
  readonly coordinate: number;
15
15
  }
16
16
 
17
+ // Labels repeat across every row, cell and query of a definition, and each
18
+ // normalized period is an immutable value. Cache per axis object and side,
19
+ // bounded so adversarial label streams cannot grow the tables without limit.
20
+ const MAX_MEMOIZED_LABELS = 100_000;
21
+ const normalizedByAxis = new WeakMap<
22
+ DiagnosticPeriodAxis,
23
+ Record<DiagnosticPeriodSide, Map<string, DiagnosticNormalizedPeriod>>
24
+ >();
25
+
17
26
  function normalizeWithAxis(
18
27
  axis: DiagnosticPeriodAxis,
19
28
  side: DiagnosticPeriodSide,
20
29
  label: string,
21
30
  ): DiagnosticNormalizedPeriod {
31
+ let tables = normalizedByAxis.get(axis);
32
+ if (!tables) {
33
+ tables = { origin: new Map(), valuation: new Map() };
34
+ normalizedByAxis.set(axis, tables);
35
+ }
36
+ const table = tables[side];
37
+ const cached = table.get(label);
38
+ if (cached !== undefined) return cached;
22
39
  const normalized = normalizeDiagnosticPeriodWithAxis(axis, side, label);
23
40
  if (!normalized)
24
41
  throw new DiagnosticValidationError([
@@ -32,7 +49,10 @@ function normalizeWithAxis(
32
49
  : `Unknown ordered-axis ${side} label ${JSON.stringify(label)}`,
33
50
  },
34
51
  ]);
35
- return Object.freeze(normalized);
52
+ const frozen = Object.freeze(normalized);
53
+ if (table.size >= MAX_MEMOIZED_LABELS) table.clear();
54
+ table.set(label, frozen);
55
+ return frozen;
36
56
  }
37
57
 
38
58
  export function normalizeDiagnosticPeriod(