@stll/calculations 0.1.2 → 0.1.3

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 (2) hide show
  1. package/dist/index.js +37 -16
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -124,9 +124,17 @@ const classify = (values) => {
124
124
  reason: "non-numeric"
125
125
  };
126
126
  case "number":
127
+ if (!Number.isFinite(value.value)) return {
128
+ type: "unsupported",
129
+ reason: "non-numeric"
130
+ };
127
131
  numbers.push(value.value);
128
132
  break;
129
133
  case "money": {
134
+ if (!Number.isFinite(value.amountCents)) return {
135
+ type: "unsupported",
136
+ reason: "non-numeric"
137
+ };
130
138
  const bucket = buckets.get(value.currency);
131
139
  if (bucket) bucket.push(value.amountCents);
132
140
  else buckets.set(value.currency, [value.amountCents]);
@@ -179,14 +187,18 @@ const reduceNumeric = (kind, values) => {
179
187
  kind,
180
188
  reason: classified.reason
181
189
  };
182
- case "numbers": return {
183
- type: "number",
184
- kind,
185
- value: REDUCERS[kind](classified.values)
186
- };
190
+ case "numbers": return finiteNumberResult(kind, REDUCERS[kind](classified.values));
187
191
  case "money": {
188
192
  const totals = new MoneyTotals();
189
- for (const [currency, amounts] of classified.buckets) totals.add(currency, cents(Math.round(REDUCERS[kind](amounts))));
193
+ for (const [currency, amounts] of classified.buckets) {
194
+ const reduced = REDUCERS[kind](amounts);
195
+ if (!Number.isFinite(reduced)) return {
196
+ type: "unsupported",
197
+ kind,
198
+ reason: "non-numeric"
199
+ };
200
+ totals.add(currency, cents(Math.round(reduced)));
201
+ }
190
202
  return {
191
203
  type: "money",
192
204
  kind,
@@ -196,6 +208,15 @@ const reduceNumeric = (kind, values) => {
196
208
  default: return panic(`Unhandled classified: ${String(classified)}`);
197
209
  }
198
210
  };
211
+ const finiteNumberResult = (kind, value) => Number.isFinite(value) ? {
212
+ type: "number",
213
+ kind,
214
+ value
215
+ } : {
216
+ type: "unsupported",
217
+ kind,
218
+ reason: "non-numeric"
219
+ };
199
220
  /**
200
221
  * The column's total as a share of the view's total.
201
222
  *
@@ -240,25 +261,25 @@ const singleTotal = (values) => {
240
261
  type: "unsupported",
241
262
  reason: classified.reason
242
263
  };
243
- case "numbers": return {
244
- type: "total",
245
- value: REDUCERS.sum(classified.values),
246
- unit: "number"
247
- };
264
+ case "numbers": return finiteTotal(REDUCERS.sum(classified.values), "number");
248
265
  case "money": {
249
266
  if (classified.buckets.size > 1) return {
250
267
  type: "unsupported",
251
268
  reason: "mixed-units"
252
269
  };
253
270
  const [currency, amounts] = [...classified.buckets.entries()].at(0) ?? ["", []];
254
- return {
255
- type: "total",
256
- value: REDUCERS.sum(amounts),
257
- unit: currency
258
- };
271
+ return finiteTotal(REDUCERS.sum(amounts), currency);
259
272
  }
260
273
  default: return panic(`Unhandled classified: ${String(classified)}`);
261
274
  }
262
275
  };
276
+ const finiteTotal = (value, unit) => Number.isFinite(value) ? {
277
+ type: "total",
278
+ value,
279
+ unit
280
+ } : {
281
+ type: "unsupported",
282
+ reason: "non-numeric"
283
+ };
263
284
  //#endregion
264
285
  export { CALCULATION_KINDS, NUMERIC_CALCULATION_KINDS, isNumericCalculationKind, runCalculation };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stll/calculations",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Typed, unit-safe reducers for workspace column calculations.",
5
5
  "keywords": [
6
6
  "calculations",
@@ -40,21 +40,21 @@
40
40
  "pack:dry-run": "bun pm pack --dry-run",
41
41
  "test": "bun test src",
42
42
  "test:property": "bun test --preload @stll/property-testing/preload $(grep -rlE 'fc\\.assert|assertProperty' src)",
43
- "typecheck": "bun ../../packages/scripts/src/tsc-native.ts --noEmit",
43
+ "typecheck": "bun check --no-pretty --all --project=tsconfig.json",
44
44
  "lint": "cd ../.. && bun --bun oxlint -c oxlint.config.ts --report-unused-disable-directives-severity=error --type-aware --type-check packages/calculations",
45
45
  "lint:fix": "cd ../.. && bun --bun oxlint -c oxlint.config.ts --type-aware --fix packages/calculations",
46
46
  "format": "bun ../../scripts/run-oxfmt.ts .",
47
47
  "prepack": "bun run build"
48
48
  },
49
49
  "dependencies": {
50
- "@stll/money": "^0.3.0",
50
+ "@stll/money": "^0.3.1",
51
51
  "better-result": "3.0.1"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@stll/property-testing": "0.0.0",
55
55
  "@stll/typescript-config": "0.0.0",
56
- "bun-types": "1.4.2",
57
- "fast-check": "^4.10.1",
56
+ "bun-types": "1.4.3",
57
+ "fast-check": "^4.10.2",
58
58
  "tsdown": "0.23.0"
59
59
  },
60
60
  "main": "./dist/index.js",