@reekon-tools/boldr-utils 1.4.13 → 1.4.15
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.
- package/dist/formulas/evaluateFormula.js +107 -11
- package/dist/types/layout.d.ts +13 -12
- package/dist/types/layout.js +1 -0
- package/package.json +1 -1
|
@@ -41,13 +41,60 @@ export function evaluateFormula({ expression, mappings, valueMap, unit, formulas
|
|
|
41
41
|
if (scope) {
|
|
42
42
|
try {
|
|
43
43
|
const normalizedUnit = normalizeUnitForMathJS(unit);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
let compiled;
|
|
45
|
+
try {
|
|
46
|
+
compiled = compile(expression);
|
|
47
|
+
}
|
|
48
|
+
catch (compileErr) {
|
|
49
|
+
console.error(`Failed to compile formula expression`, compileErr);
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
let result;
|
|
53
|
+
try {
|
|
54
|
+
result = compiled.evaluate(scope);
|
|
55
|
+
}
|
|
56
|
+
catch (evalErr) {
|
|
57
|
+
// Handle divide by zero and other math errors
|
|
58
|
+
const errorMessage = evalErr instanceof Error ? evalErr.message : String(evalErr);
|
|
59
|
+
if (errorMessage.includes('divide') ||
|
|
60
|
+
errorMessage.includes('division') ||
|
|
61
|
+
errorMessage.includes('/') ||
|
|
62
|
+
errorMessage.includes('Division by zero') ||
|
|
63
|
+
errorMessage.includes('Cannot divide by zero')) {
|
|
64
|
+
console.error(`Division by zero in formula`, evalErr);
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
console.error(`Failed to evaluate formula`, evalErr);
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
// Check for invalid results (Infinity, NaN)
|
|
71
|
+
if (Number.isNaN(result)) {
|
|
72
|
+
console.error(`Formula result is NaN`);
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
if (!Number.isFinite(result)) {
|
|
76
|
+
console.error(`Formula result is Infinity`);
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
let asUnit;
|
|
80
|
+
try {
|
|
81
|
+
asUnit = mathUnit(result, normalizedUnit);
|
|
82
|
+
}
|
|
83
|
+
catch (unitErr) {
|
|
84
|
+
console.error(`Failed to convert result to unit`, unitErr);
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
47
87
|
if (!asUnit.equalBase(mathUnit('1 um'))) {
|
|
48
|
-
|
|
88
|
+
console.error(`Incompatible unit: ${asUnit.formatUnits()} is not compatible with ${normalizedUnit}`);
|
|
89
|
+
return null;
|
|
49
90
|
}
|
|
50
|
-
|
|
91
|
+
const finalResult = Math.round(asUnit.toNumber('um'));
|
|
92
|
+
// Check if final result is valid
|
|
93
|
+
if (!Number.isFinite(finalResult)) {
|
|
94
|
+
console.error(`Formula result is not a finite number`);
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
return finalResult;
|
|
51
98
|
}
|
|
52
99
|
catch (err) {
|
|
53
100
|
console.error(`Failed to evaluate formula`, err);
|
|
@@ -95,23 +142,72 @@ export function evaluateFormula({ expression, mappings, valueMap, unit, formulas
|
|
|
95
142
|
}
|
|
96
143
|
// Recursively evaluate the referenced formula
|
|
97
144
|
const nestedResult = evaluateNestedFormula(referencedFormula.id, referencedFormula.expression, referencedFormula.variableToColumnMap);
|
|
98
|
-
// Convert result to current unit
|
|
99
|
-
|
|
145
|
+
// Convert result to current unit with error handling
|
|
146
|
+
let resultInUnit;
|
|
147
|
+
try {
|
|
148
|
+
resultInUnit = mathUnit(nestedResult, 'um').toNumber(normalizedUnit);
|
|
149
|
+
}
|
|
150
|
+
catch (unitErr) {
|
|
151
|
+
throw new Error(`Failed to convert nested formula result to unit: ${unitErr instanceof Error ? unitErr.message : 'Unknown error'}`);
|
|
152
|
+
}
|
|
100
153
|
scope[variable] = resultInUnit;
|
|
101
154
|
}
|
|
102
155
|
}
|
|
103
|
-
// Evaluate the formula expression
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
156
|
+
// Evaluate the formula expression with error handling for math errors
|
|
157
|
+
let compiled;
|
|
158
|
+
try {
|
|
159
|
+
compiled = compile(currentExpression);
|
|
160
|
+
}
|
|
161
|
+
catch (compileErr) {
|
|
162
|
+
throw new Error(`Failed to compile formula expression: ${compileErr instanceof Error ? compileErr.message : 'Unknown error'}`);
|
|
163
|
+
}
|
|
164
|
+
let result;
|
|
165
|
+
try {
|
|
166
|
+
result = compiled.evaluate(scope);
|
|
167
|
+
}
|
|
168
|
+
catch (evalErr) {
|
|
169
|
+
// Handle divide by zero and other math errors
|
|
170
|
+
const errorMessage = evalErr instanceof Error ? evalErr.message : String(evalErr);
|
|
171
|
+
if (errorMessage.includes('divide') ||
|
|
172
|
+
errorMessage.includes('division') ||
|
|
173
|
+
errorMessage.includes('/') ||
|
|
174
|
+
errorMessage.includes('Division by zero') ||
|
|
175
|
+
errorMessage.includes('Cannot divide by zero')) {
|
|
176
|
+
throw new Error(`Division by zero in formula: ${formulaId}`);
|
|
177
|
+
}
|
|
178
|
+
// Re-throw other evaluation errors
|
|
179
|
+
throw new Error(`Failed to evaluate formula: ${errorMessage}`);
|
|
180
|
+
}
|
|
181
|
+
// Check for invalid results (Infinity, NaN)
|
|
182
|
+
if (Number.isNaN(result)) {
|
|
183
|
+
throw new Error(`Formula result is NaN: ${formulaId}`);
|
|
184
|
+
}
|
|
185
|
+
if (!Number.isFinite(result)) {
|
|
186
|
+
throw new Error(`Formula result is Infinity: ${formulaId}`);
|
|
187
|
+
}
|
|
188
|
+
let asUnit;
|
|
189
|
+
try {
|
|
190
|
+
asUnit = mathUnit(result, normalizedUnit);
|
|
191
|
+
}
|
|
192
|
+
catch (unitErr) {
|
|
193
|
+
throw new Error(`Failed to convert result to unit: ${unitErr instanceof Error ? unitErr.message : 'Unknown error'}`);
|
|
194
|
+
}
|
|
107
195
|
if (!asUnit.equalBase(mathUnit('1 um'))) {
|
|
108
196
|
throw new Error(`Incompatible unit: ${asUnit.formatUnits()} is not compatible with ${normalizedUnit}`);
|
|
109
197
|
}
|
|
110
198
|
const finalResult = Math.round(asUnit.toNumber('um'));
|
|
199
|
+
// Check if final result is valid
|
|
200
|
+
if (!Number.isFinite(finalResult)) {
|
|
201
|
+
throw new Error(`Formula result is not a finite number: ${formulaId}`);
|
|
202
|
+
}
|
|
111
203
|
// Cache the result
|
|
112
204
|
cache.set(cacheKey, finalResult);
|
|
113
205
|
return finalResult;
|
|
114
206
|
}
|
|
207
|
+
catch (err) {
|
|
208
|
+
// Re-throw the error so it can be caught by the outer try-catch
|
|
209
|
+
throw err;
|
|
210
|
+
}
|
|
115
211
|
finally {
|
|
116
212
|
evaluationStack.delete(formulaId);
|
|
117
213
|
}
|
package/dist/types/layout.d.ts
CHANGED
|
@@ -32,24 +32,25 @@ export interface Face {
|
|
|
32
32
|
measurementIds?: string[];
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
+
export interface BackgroundImage {
|
|
36
|
+
id: string;
|
|
37
|
+
fileId: string;
|
|
38
|
+
opacity: number;
|
|
39
|
+
centerWorld: {
|
|
40
|
+
x: number;
|
|
41
|
+
y: number;
|
|
42
|
+
};
|
|
43
|
+
pixelSizeWorld: number;
|
|
44
|
+
widthPx: number;
|
|
45
|
+
heightPx: number;
|
|
46
|
+
rotationRad: number;
|
|
47
|
+
}
|
|
35
48
|
export interface Layout {
|
|
36
49
|
id: string;
|
|
37
50
|
name?: string;
|
|
38
51
|
points: Record<string, Point>;
|
|
39
52
|
edges: Record<string, Edge>;
|
|
40
53
|
faces: Record<string, Face>;
|
|
41
|
-
backgroundImage?: {
|
|
42
|
-
fileId: string;
|
|
43
|
-
opacity: number;
|
|
44
|
-
centerWorld: {
|
|
45
|
-
x: number;
|
|
46
|
-
y: number;
|
|
47
|
-
};
|
|
48
|
-
pixelSizeWorld: number;
|
|
49
|
-
widthPx: number;
|
|
50
|
-
heightPx: number;
|
|
51
|
-
rotationRad: number;
|
|
52
|
-
};
|
|
53
54
|
metadata?: {
|
|
54
55
|
projectId?: string;
|
|
55
56
|
jobId?: string;
|
package/dist/types/layout.js
CHANGED