@reekon-tools/boldr-utils 1.16.0 → 1.17.1
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/annotation/canvas/elements/BackgroundSvg.js +26 -1
- package/dist/canvas/AnnotationCanvas.d.ts +11 -0
- package/dist/canvas/AnnotationCanvas.js +10 -0
- package/dist/canvas/AnnotationCanvas.native.d.ts +8 -0
- package/dist/canvas/AnnotationCanvas.native.js +6 -0
- package/dist/canvas/AnnotationCanvasInner.d.ts +39 -0
- package/dist/canvas/AnnotationCanvasInner.js +219 -0
- package/dist/canvas/AnnotationCanvasInner.native.d.ts +35 -0
- package/dist/canvas/AnnotationCanvasInner.native.js +138 -0
- package/dist/canvas/AnnotationCanvasSkia.d.ts +27 -0
- package/dist/canvas/AnnotationCanvasSkia.js +20 -0
- package/dist/canvas/Tool.d.ts +38 -0
- package/dist/canvas/Tool.js +1 -0
- package/dist/canvas/elements/BackgroundImageElement.d.ts +9 -0
- package/dist/canvas/elements/BackgroundImageElement.js +37 -0
- package/dist/canvas/elements/MeasurementStampElement.d.ts +13 -0
- package/dist/canvas/elements/MeasurementStampElement.js +30 -0
- package/dist/canvas/elements/ShapeElement.d.ts +7 -0
- package/dist/canvas/elements/ShapeElement.js +62 -0
- package/dist/canvas/elements/StrokeElement.d.ts +7 -0
- package/dist/canvas/elements/StrokeElement.js +18 -0
- package/dist/canvas/measurementPicker.d.ts +10 -0
- package/dist/canvas/measurementPicker.js +1 -0
- package/dist/canvas/measurementStampOverlay.d.ts +11 -0
- package/dist/canvas/measurementStampOverlay.js +1 -0
- package/dist/canvas/pointerAdapter.d.ts +3 -0
- package/dist/canvas/pointerAdapter.js +19 -0
- package/dist/canvas/stampLayout.d.ts +5 -0
- package/dist/canvas/stampLayout.js +14 -0
- package/dist/canvas/tools/measurementStampTool.d.ts +9 -0
- package/dist/canvas/tools/measurementStampTool.js +37 -0
- package/dist/canvas/tools/panTool.d.ts +5 -0
- package/dist/canvas/tools/panTool.js +25 -0
- package/dist/canvas/tools/penTool.d.ts +13 -0
- package/dist/canvas/tools/penTool.js +68 -0
- package/dist/canvas/tools/selectTool.d.ts +2 -0
- package/dist/canvas/tools/selectTool.js +182 -0
- package/dist/canvas/useAnnotationCanvasState.d.ts +54 -0
- package/dist/canvas/useAnnotationCanvasState.js +210 -0
- package/dist/canvas/viewport.d.ts +16 -0
- package/dist/canvas/viewport.js +54 -0
- package/dist/data/AnnotationDataContext.d.ts +8 -0
- package/dist/data/AnnotationDataContext.js +11 -0
- package/dist/data/AnnotationDataProvider.d.ts +65 -0
- package/dist/data/AnnotationDataProvider.js +4 -0
- package/dist/data/InMemoryAnnotationProvider.d.ts +30 -0
- package/dist/data/InMemoryAnnotationProvider.js +197 -0
- package/dist/data/canvasPersistence.d.ts +3 -0
- package/dist/data/canvasPersistence.js +26 -0
- package/dist/data/hooks/useAnnotationCanvasDoc.d.ts +33 -0
- package/dist/data/hooks/useAnnotationCanvasDoc.js +314 -0
- package/dist/data/hooks/useAnnotationDoc.d.ts +7 -0
- package/dist/data/hooks/useAnnotationDoc.js +33 -0
- package/dist/data/hooks/useAnnotationList.d.ts +7 -0
- package/dist/data/hooks/useAnnotationList.js +26 -0
- package/dist/data/hooks/useAnnotationMutations.d.ts +9 -0
- package/dist/data/hooks/useAnnotationMutations.js +11 -0
- package/dist/export/buildJobCsv.js +91 -17
- package/dist/export/config.d.ts +1 -1
- package/dist/export/config.js +10 -1
- package/dist/exports.d.ts +2 -0
- package/dist/exports.js +2 -0
- package/dist/hooks/useParseMeasurement.d.ts +4 -0
- package/dist/hooks/useParseMeasurement.js +14 -0
- package/dist/server.d.ts +16 -0
- package/dist/server.js +21 -0
- package/dist/utils/evaluateFormula.d.ts +20 -0
- package/dist/utils/evaluateFormula.js +31 -0
- package/dist/utils/measurementKind.d.ts +22 -0
- package/dist/utils/measurementKind.js +22 -0
- package/dist/utils/measurementSort.d.ts +2 -0
- package/dist/utils/measurementSort.js +45 -0
- package/package.json +6 -1
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { evaluateFormula, createFormulaScope, createEnhancedFormulaScope, clearFormulaCache, type EnhancedMapping, type FormulaDefinition, type FormulaEvaluationOptions, } from './formulas/evaluateFormula.js';
|
|
2
|
+
export { calculateFormula } from './formulas/calculateFormula.js';
|
|
3
|
+
export { convertMicrometers } from './utils/micrometersToUnit.js';
|
|
4
|
+
export { parseMeasurement } from './utils/parseMeasurement.js';
|
|
5
|
+
export * from './types/firestore.js';
|
|
6
|
+
export * from './types/layout.js';
|
|
7
|
+
export * from './types/annotation.js';
|
|
8
|
+
export { getToleranceColor, getToleranceSecondaryColor, calculateDeviationPercentage, isWithinTolerance, generateToleranceGradient, createDefaultToleranceThresholds, DEFAULT_TOLERANCE_COLORS, DEFAULT_TOLERANCE_SECONDARY_COLORS, type ToleranceThreshold, type ToleranceConfig, } from './utils/tolerance.js';
|
|
9
|
+
export { DEFAULT_GROUP_INDEX, isDefaultGroup, findDefaultGroup, isFormGroupCompleted, } from './utils/groups.js';
|
|
10
|
+
export { ALL_EXPORT_CATEGORIES, ALL_EXPORT_MEASUREMENT_DATA_FIELDS, ALL_EXPORT_OBJECT_TYPES, DEFAULT_EXPORT_CONFIG, EXPORT_EVERYTHING_CONFIG, normalizeExportConfig, type ExportCategory, type ExportConfig, type ExportImageFormat, type ExportMeasurementDataField, type ExportMeasurementFilter, type ExportObjectType, } from './export/config.js';
|
|
11
|
+
export { classifyFileForExport } from './export/objectKinds.js';
|
|
12
|
+
export { buildJobCsv, escapeCSVField, hyperlinkCell, type BuildJobCsvInput, type ExportObjectRow, type ExportScope, } from './export/buildJobCsv.js';
|
|
13
|
+
export { desktopBaseUrlForFirebaseProject, desktopFileEditorUrl, type DesktopLinkContext, } from './export/desktopLinks.js';
|
|
14
|
+
export { numberToLetterIndex, formGroupInputLabel, listGroupMeasurementLabel, } from './utils/indexLabels.js';
|
|
15
|
+
export { toSelectedValues, formatSelectedValues, toStoredValue, } from './utils/selectValues.js';
|
|
16
|
+
export * from './calculator/index.js';
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Server-safe entry point (package export "./server"). Node consumers —
|
|
2
|
+
// boldr-api, Cloud Functions, scripts — import from here instead of the
|
|
3
|
+
// root barrel, whose module graph statically pulls in `react` and
|
|
4
|
+
// `@shopify/react-native-skia`. Only modules with no React/Skia anywhere
|
|
5
|
+
// in their import graph may be re-exported from this file.
|
|
6
|
+
export { evaluateFormula, createFormulaScope, createEnhancedFormulaScope, clearFormulaCache, } from './formulas/evaluateFormula.js';
|
|
7
|
+
export { calculateFormula } from './formulas/calculateFormula.js';
|
|
8
|
+
export { convertMicrometers } from './utils/micrometersToUnit.js';
|
|
9
|
+
export { parseMeasurement } from './utils/parseMeasurement.js';
|
|
10
|
+
export * from './types/firestore.js';
|
|
11
|
+
export * from './types/layout.js';
|
|
12
|
+
export * from './types/annotation.js';
|
|
13
|
+
export { getToleranceColor, getToleranceSecondaryColor, calculateDeviationPercentage, isWithinTolerance, generateToleranceGradient, createDefaultToleranceThresholds, DEFAULT_TOLERANCE_COLORS, DEFAULT_TOLERANCE_SECONDARY_COLORS, } from './utils/tolerance.js';
|
|
14
|
+
export { DEFAULT_GROUP_INDEX, isDefaultGroup, findDefaultGroup, isFormGroupCompleted, } from './utils/groups.js';
|
|
15
|
+
export { ALL_EXPORT_CATEGORIES, ALL_EXPORT_MEASUREMENT_DATA_FIELDS, ALL_EXPORT_OBJECT_TYPES, DEFAULT_EXPORT_CONFIG, EXPORT_EVERYTHING_CONFIG, normalizeExportConfig, } from './export/config.js';
|
|
16
|
+
export { classifyFileForExport } from './export/objectKinds.js';
|
|
17
|
+
export { buildJobCsv, escapeCSVField, hyperlinkCell, } from './export/buildJobCsv.js';
|
|
18
|
+
export { desktopBaseUrlForFirebaseProject, desktopFileEditorUrl, } from './export/desktopLinks.js';
|
|
19
|
+
export { numberToLetterIndex, formGroupInputLabel, listGroupMeasurementLabel, } from './utils/indexLabels.js';
|
|
20
|
+
export { toSelectedValues, formatSelectedValues, toStoredValue, } from './utils/selectValues.js';
|
|
21
|
+
export * from './calculator/index.js';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
type MeasurementMap = Map<string, {
|
|
2
|
+
id: string;
|
|
3
|
+
value: number;
|
|
4
|
+
}[]>;
|
|
5
|
+
interface FormulaEvaluationOptions {
|
|
6
|
+
expression: string;
|
|
7
|
+
mappings: Record<string, string>;
|
|
8
|
+
group: {
|
|
9
|
+
id: string;
|
|
10
|
+
columns: Map<string, any>;
|
|
11
|
+
};
|
|
12
|
+
columns: {
|
|
13
|
+
id: string;
|
|
14
|
+
type: string;
|
|
15
|
+
}[];
|
|
16
|
+
measurementMap: MeasurementMap;
|
|
17
|
+
defaultUnit?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function evaluateFormula({ expression, mappings, group, columns, measurementMap, defaultUnit, }: FormulaEvaluationOptions): number | string;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { create, all } from 'mathjs';
|
|
2
|
+
const math = create(all);
|
|
3
|
+
export function evaluateFormula({ expression, mappings, group, columns, measurementMap, defaultUnit = 'um', }) {
|
|
4
|
+
const scope = {};
|
|
5
|
+
for (const [variable, columnId] of Object.entries(mappings)) {
|
|
6
|
+
const rawValue = group.columns.get(columnId);
|
|
7
|
+
const columnDef = columns.find((c) => c.id === columnId);
|
|
8
|
+
if (columnDef?.type === 'Measurement') {
|
|
9
|
+
const groupMeasurements = measurementMap.get(group.id) || [];
|
|
10
|
+
const measurement = groupMeasurements.find((m) => m.id === rawValue);
|
|
11
|
+
if (measurement?.value !== undefined) {
|
|
12
|
+
scope[variable] = math.unit(measurement.value, defaultUnit);
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const parsedValue = typeof rawValue === 'number' ? rawValue : parseFloat(rawValue || '');
|
|
17
|
+
scope[variable] = isNaN(parsedValue) ? 0 : parsedValue;
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const compiled = math.compile(expression);
|
|
21
|
+
const result = compiled.evaluate(scope);
|
|
22
|
+
if (math.typeOf(result) === 'Unit') {
|
|
23
|
+
return result.toNumber(defaultUnit);
|
|
24
|
+
}
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
console.error(`Formula evaluation failed:`, err);
|
|
29
|
+
return 'Error';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { MeasurementType } from '../types/firestore.js';
|
|
2
|
+
/**
|
|
3
|
+
* Angle and Number are BARE SCALARS: `value` is stored exactly as entered
|
|
4
|
+
* (signed degrees / a unitless decimal) and must never go through the
|
|
5
|
+
* micrometer parser or formatter. Only Length is micrometers — including a
|
|
6
|
+
* legacy doc with no `type` at all, which predates the field.
|
|
7
|
+
*
|
|
8
|
+
* These exist because the shorthand for "is this a length" was
|
|
9
|
+
* `type !== MeasurementType.Angle`. That read correctly while the enum had two
|
|
10
|
+
* members and became wrong the moment it gained a third: a unitless `25` fell
|
|
11
|
+
* into the length branch and rendered as `0 in`. Prefer these over an inline
|
|
12
|
+
* comparison so the next member added is a one-file change.
|
|
13
|
+
*/
|
|
14
|
+
export declare const isLengthMeasurement: (type?: MeasurementType) => boolean;
|
|
15
|
+
/** Angle or Number — a value shown as-is, with no unit conversion. */
|
|
16
|
+
export declare const isScalarMeasurement: (type?: MeasurementType) => boolean;
|
|
17
|
+
/**
|
|
18
|
+
* The unit mark shown alongside a scalar value. Numbers are unitless by
|
|
19
|
+
* definition, so this is empty for them — callers must not substitute the
|
|
20
|
+
* user's selected unit.
|
|
21
|
+
*/
|
|
22
|
+
export declare const scalarValueSuffix: (type?: MeasurementType) => string;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { MeasurementType } from '../types/firestore.js';
|
|
2
|
+
/**
|
|
3
|
+
* Angle and Number are BARE SCALARS: `value` is stored exactly as entered
|
|
4
|
+
* (signed degrees / a unitless decimal) and must never go through the
|
|
5
|
+
* micrometer parser or formatter. Only Length is micrometers — including a
|
|
6
|
+
* legacy doc with no `type` at all, which predates the field.
|
|
7
|
+
*
|
|
8
|
+
* These exist because the shorthand for "is this a length" was
|
|
9
|
+
* `type !== MeasurementType.Angle`. That read correctly while the enum had two
|
|
10
|
+
* members and became wrong the moment it gained a third: a unitless `25` fell
|
|
11
|
+
* into the length branch and rendered as `0 in`. Prefer these over an inline
|
|
12
|
+
* comparison so the next member added is a one-file change.
|
|
13
|
+
*/
|
|
14
|
+
export const isLengthMeasurement = (type) => (type ?? MeasurementType.Length) === MeasurementType.Length;
|
|
15
|
+
/** Angle or Number — a value shown as-is, with no unit conversion. */
|
|
16
|
+
export const isScalarMeasurement = (type) => !isLengthMeasurement(type);
|
|
17
|
+
/**
|
|
18
|
+
* The unit mark shown alongside a scalar value. Numbers are unitless by
|
|
19
|
+
* definition, so this is empty for them — callers must not substitute the
|
|
20
|
+
* user's selected unit.
|
|
21
|
+
*/
|
|
22
|
+
export const scalarValueSuffix = (type) => type === MeasurementType.Angle ? '°' : '';
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Firestore Timestamp doesn't support relational comparison operators, which
|
|
2
|
+
// silently degrades sort comparators to insertion order. The shared model
|
|
3
|
+
// types createdAt as Date, but both apps deliver Timestamps at runtime — read
|
|
4
|
+
// via the methods Timestamps actually expose.
|
|
5
|
+
const createdAtMillis = (createdAt) => {
|
|
6
|
+
if (createdAt == null)
|
|
7
|
+
return 0;
|
|
8
|
+
if (createdAt instanceof Date)
|
|
9
|
+
return createdAt.getTime();
|
|
10
|
+
const ts = createdAt;
|
|
11
|
+
if (typeof ts.toMillis === 'function')
|
|
12
|
+
return ts.toMillis();
|
|
13
|
+
if (typeof ts.seconds === 'number') {
|
|
14
|
+
return ts.seconds * 1000 + Math.floor((ts.nanoseconds ?? 0) / 1e6);
|
|
15
|
+
}
|
|
16
|
+
return 0;
|
|
17
|
+
};
|
|
18
|
+
// Canonical display order for a LIST group's measurements, shared by
|
|
19
|
+
// rock-desktop and rock-pro-app so cards, tables and exports all agree:
|
|
20
|
+
// incomplete first, then by capture time. Callers that hide completed
|
|
21
|
+
// measurements filter at render time — completed entries sort to the tail, so
|
|
22
|
+
// the visible positional indexes are unaffected either way.
|
|
23
|
+
export const sortMeasurementsByCompleted = (groupMeasurements) => {
|
|
24
|
+
return [...groupMeasurements].sort((a, b) => {
|
|
25
|
+
const isCompletedA = a.isCompleted === true;
|
|
26
|
+
const isCompletedB = b.isCompleted === true;
|
|
27
|
+
if (isCompletedA !== isCompletedB)
|
|
28
|
+
return isCompletedA ? 1 : -1;
|
|
29
|
+
const ms = createdAtMillis(a.createdAt) - createdAtMillis(b.createdAt);
|
|
30
|
+
if (ms !== 0)
|
|
31
|
+
return ms;
|
|
32
|
+
// Synced floods collapse createdAt into a millisecond-wide window and
|
|
33
|
+
// legacy data has identical timestamps for whole batches. Device capture
|
|
34
|
+
// sequence is the right tiebreaker — it's monotonic per device session.
|
|
35
|
+
const aNum = a.deviceMeasurementNumber;
|
|
36
|
+
const bNum = b.deviceMeasurementNumber;
|
|
37
|
+
if (aNum != null && bNum != null)
|
|
38
|
+
return aNum - bNum;
|
|
39
|
+
if (aNum != null)
|
|
40
|
+
return -1;
|
|
41
|
+
if (bNum != null)
|
|
42
|
+
return 1;
|
|
43
|
+
return 0;
|
|
44
|
+
});
|
|
45
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reekon-tools/boldr-utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.1",
|
|
4
4
|
"description": "Shared utilities for formulas and measurement conversion used in Reekon apps",
|
|
5
5
|
"author": "REEKON Tools",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,6 +24,11 @@
|
|
|
24
24
|
"import": "./dist/theme/colors.js",
|
|
25
25
|
"default": "./dist/theme/colors.js"
|
|
26
26
|
},
|
|
27
|
+
"./server": {
|
|
28
|
+
"types": "./dist/server.d.ts",
|
|
29
|
+
"import": "./dist/server.js",
|
|
30
|
+
"default": "./dist/server.js"
|
|
31
|
+
},
|
|
27
32
|
"./package.json": "./package.json"
|
|
28
33
|
},
|
|
29
34
|
"scripts": {
|