dsh-math-calculator 2.1.0 → 2.2.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.
- package/CHANGELOG.md +951 -0
- package/README.md +64 -50
- package/dsh.plugin.json +2 -2
- package/lib/__wtest.txt +1 -0
- package/lib/awareness.js +69 -20
- package/lib/format.js +522 -13
- package/lib/formula-library-em.js +428 -0
- package/lib/formulas.js +28 -1
- package/lib/guards.js +653 -0
- package/lib/help.js +509 -0
- package/lib/index.js +1367 -212
- package/lib/ops/shared.js +547 -6
- package/lib/ops/units-op.js +116 -10
- package/lib/ops/workspace-op.js +10 -0
- package/lib/playbook.js +32 -7
- package/lib/types/format.d.ts +31 -1
- package/lib/types/formula-library-em.d.ts +28 -0
- package/lib/types/formulas.d.ts +2 -0
- package/lib/types/guards.d.ts +255 -0
- package/lib/types/help.d.ts +70 -0
- package/lib/types/index.d.ts +34 -1
- package/lib/types/ops/shared.d.ts +87 -3
- package/lib/types/playbook.d.ts +28 -0
- package/lib/types/units-data.d.ts +253 -0
- package/lib/types/units.d.ts +54 -4
- package/lib/types/workspace.d.ts +50 -0
- package/lib/units-data.js +1037 -0
- package/lib/units.js +82 -117
- package/lib/workspace.js +54 -0
- package/package.json +1 -1
- package/src/awareness.ts +69 -20
- package/src/format.ts +520 -12
- package/src/formula-library-em.ts +435 -0
- package/src/formulas.ts +35 -4
- package/src/guards.ts +673 -0
- package/src/help.ts +543 -0
- package/src/index.ts +1502 -213
- package/src/ops/shared.ts +589 -9
- package/src/ops/units-op.ts +125 -9
- package/src/ops/workspace-op.ts +10 -0
- package/src/playbook.ts +32 -7
- package/src/units-data.ts +1128 -0
- package/src/units.ts +149 -130
- package/src/workspace.ts +65 -0
package/lib/types/index.d.ts
CHANGED
|
@@ -60,10 +60,43 @@ export interface MathResult {
|
|
|
60
60
|
* 提示属于「给人/模型看的说明」,走这个字段即可。
|
|
61
61
|
*/
|
|
62
62
|
notice?: string;
|
|
63
|
+
/**
|
|
64
|
+
* 批量模式:「部分成功」——本批有失败条目,但也有成功结果可用。
|
|
65
|
+
*
|
|
66
|
+
* 为什么要单独一个字段:`ok` 是布尔,说不了「废了几条、还剩几条」。
|
|
67
|
+
* 没有它,调用方只能二选一:整批当废(浪费成功条目)或整批当可用(把失败当成功)。
|
|
68
|
+
*/
|
|
69
|
+
partial?: boolean;
|
|
70
|
+
/** 批量模式:失败条目数。 */
|
|
71
|
+
failed?: number;
|
|
72
|
+
/** 批量模式:成功条目数。 */
|
|
73
|
+
succeeded?: number;
|
|
63
74
|
}
|
|
64
75
|
/** 更新检测器配置。 */
|
|
65
76
|
export declare function configureDetector(config: Partial<DetectorConfig>): Partial<DetectorConfig>;
|
|
66
|
-
/**
|
|
77
|
+
/**
|
|
78
|
+
* 取本次调用中被跳过的非法变量键(组装提示用)。
|
|
79
|
+
*
|
|
80
|
+
* @returns 被跳过的键与原因
|
|
81
|
+
*/
|
|
82
|
+
export declare function takeSkippedVariableKeys(): Array<{
|
|
83
|
+
name: string;
|
|
84
|
+
reason: string;
|
|
85
|
+
}>;
|
|
86
|
+
/**
|
|
87
|
+
* 清理被跳过的变量键记录(每次工具调用开头)。
|
|
88
|
+
*/
|
|
89
|
+
export declare function resetSkippedVariableKeys(): void;
|
|
90
|
+
/**
|
|
91
|
+
* 工具主入口:永不抛异常。
|
|
92
|
+
*
|
|
93
|
+
* 所有失败都转成 `{ ok:false, error:{ type, message, hint } }`,
|
|
94
|
+
* 因为宿主侧把抛异常当成「工具坏了」,而这里的失败几乎都是**输入问题**,
|
|
95
|
+
* 调用方按 hint 改一下就能过。
|
|
96
|
+
*
|
|
97
|
+
* @param rawArguments - 宿主传进来的参数对象(可能是任意形态,这里先做白名单校验)
|
|
98
|
+
* @returns 永远是一个 MathResult,不会 throw
|
|
99
|
+
*/
|
|
67
100
|
export declare function runMathTool(rawArguments: unknown): MathResult;
|
|
68
101
|
/**
|
|
69
102
|
* 数学计算工具(`math_execute`)。
|
|
@@ -75,12 +75,32 @@ export interface MathArgs {
|
|
|
75
75
|
* 一次算多条,省掉多次工具往返的开销。每条独立报错,
|
|
76
76
|
* 不会因为一条失败就中断整批。
|
|
77
77
|
*
|
|
78
|
-
*
|
|
78
|
+
* 两种条目形态:
|
|
79
|
+
* - 字符串:`['1/7','2^0.5']`
|
|
80
|
+
* - 带标签对象:`[{label:'储耗比-中值', expr:'139e8/152e4'}]`
|
|
81
|
+
*
|
|
82
|
+
* ## 为什么要 label
|
|
83
|
+
*
|
|
84
|
+
* 实测反馈:同一批算两个口径时(`['139e8/1743500','139e8/152e4']` → 7972 / 9144),
|
|
85
|
+
* 输出里**只有顺序号区分**,后续引用要回翻表达式原文 —— 报告里「一次差点引错」。
|
|
86
|
+
* 单批十几条时,纯靠位置对齐的心智负担很大。
|
|
79
87
|
*
|
|
80
88
|
* 为什么值得:每次工具调用都有固定开销(往返 + 结果文本进入上下文),
|
|
81
89
|
* 算 5 条就多付 5 次。批量把 5 次往返压成 1 次。
|
|
82
90
|
*/
|
|
83
|
-
expressions?: string
|
|
91
|
+
expressions?: Array<string | {
|
|
92
|
+
label?: string;
|
|
93
|
+
expr?: string;
|
|
94
|
+
}>;
|
|
95
|
+
/**
|
|
96
|
+
* 精简输出(operation=evaluate 的批量模式):只回「表达式 = 结果」。
|
|
97
|
+
*
|
|
98
|
+
* 去掉标题与「成功 N,失败 M」统计行。实测反馈:
|
|
99
|
+
* 批量 8—14 条时这些固定行本身也是开销,报告估算全程 terse 可省 40%+ 输出 token。
|
|
100
|
+
*
|
|
101
|
+
* 失败信息**不省**:省掉会让调用方以为全成功了。
|
|
102
|
+
*/
|
|
103
|
+
terse?: boolean;
|
|
84
104
|
data?: number[];
|
|
85
105
|
dataY?: number[];
|
|
86
106
|
distribution?: string;
|
|
@@ -144,6 +164,13 @@ export interface MathArgs {
|
|
|
144
164
|
workspaceVariables?: {
|
|
145
165
|
[key: string]: number;
|
|
146
166
|
};
|
|
167
|
+
/**
|
|
168
|
+
* 工作区开关:命名变量是否参与计算(默认关闭)。
|
|
169
|
+
*
|
|
170
|
+
* 打开后,缓存键会把变量内容算进去(否则改了变量会命中旧缓存);
|
|
171
|
+
* 关闭时行为与未引入该功能时完全一致。
|
|
172
|
+
*/
|
|
173
|
+
useWorkspaceVariables?: boolean;
|
|
147
174
|
/** operation=feasibility:待校验的设定(约束 id → 值)。 */
|
|
148
175
|
claims?: {
|
|
149
176
|
[constraintId: string]: number;
|
|
@@ -156,6 +183,13 @@ export interface MathArgs {
|
|
|
156
183
|
layer?: string;
|
|
157
184
|
/** 单位缩放因子,检测「单位重定义陷阱」,如 { mass: 2 }。 */
|
|
158
185
|
unitScales?: Record<string, number>;
|
|
186
|
+
/**
|
|
187
|
+
* 列单位清单时展开哪一维(`"length"` / `"长度"` 等)。
|
|
188
|
+
*
|
|
189
|
+
* 单位表收到近三百条后,全量展开一次是一万七千多字符;
|
|
190
|
+
* 默认只给各量纲的计数与样例,点名才展开。这与 help 的「用到时才读」一致。
|
|
191
|
+
*/
|
|
192
|
+
unitScale?: string;
|
|
159
193
|
/** 敏感性分析的基线值。 */
|
|
160
194
|
sensitivityBase?: number;
|
|
161
195
|
/** 敏感性分析的幂次(结果 = 输入^幂)。 */
|
|
@@ -297,6 +331,13 @@ export interface MathArgs {
|
|
|
297
331
|
costWithPipeline?: boolean;
|
|
298
332
|
/** 提示注入档位: off / brief / full(传了就切换并返回当前值)。 */
|
|
299
333
|
promptMode?: string;
|
|
334
|
+
/**
|
|
335
|
+
* operation=help 时要取哪一节。省略则返回目录。
|
|
336
|
+
*
|
|
337
|
+
* 分节是为了让「每次调用只付用到的那一节」—— 旧版是一整块 5900 字符全量摊平,
|
|
338
|
+
* 算一条 1/3 也要读 3039 字符的 world 字段表。详见 `src/help.ts`。
|
|
339
|
+
*/
|
|
340
|
+
helpTopic?: string;
|
|
300
341
|
/** operation=formula-table 的动作: list / show / override / remove / add / disable / enable / reset */
|
|
301
342
|
tableAction?: string;
|
|
302
343
|
/** 目标公式 id。 */
|
|
@@ -372,8 +413,11 @@ export declare class CalcError extends Error {
|
|
|
372
413
|
* 安全:删除 import / createUnit,防止表达式注入任意 JS 或改写单位表。
|
|
373
414
|
* **不能**删 typed/parse/evaluate —— derivative/simplify 依赖它们。
|
|
374
415
|
* 自定义函数(rank/nsolve…)在删除 import **之前**注册,顺序不能反。
|
|
416
|
+
*
|
|
417
|
+
* 单位注入(`injectUnitTable`)同理:也在删除 createUnit **之前**做,
|
|
418
|
+
* 注入完方法即被删除,所以表达式求值仍然拿不到它。
|
|
375
419
|
*/
|
|
376
|
-
export declare function buildMath(numberMode: 'BigNumber' | 'number', precision: number): any;
|
|
420
|
+
export declare function buildMath(numberMode: 'BigNumber' | 'number' | 'Fraction', precision: number): any;
|
|
377
421
|
/**
|
|
378
422
|
* 取 BigNumber 引擎(按 precision 缓存)。
|
|
379
423
|
*
|
|
@@ -388,6 +432,26 @@ export declare function bignum(precision: number): any;
|
|
|
388
432
|
* 用 BigNumber 只会更慢且没有意义。
|
|
389
433
|
*/
|
|
390
434
|
export declare function fast(): any;
|
|
435
|
+
/**
|
|
436
|
+
* 取**有理数**引擎(Fraction 模式)。
|
|
437
|
+
*
|
|
438
|
+
* ## 为什么需要它
|
|
439
|
+
*
|
|
440
|
+
* 定积分要按 Newton-Leibniz 代入上下限。用 BigNumber 引擎会出这种事:
|
|
441
|
+
*
|
|
442
|
+
* 原函数 1/3·x³,在 x=3 处
|
|
443
|
+
* BigNumber → 8.99999999999999999999999999999999999999…
|
|
444
|
+
* Fraction → 9
|
|
445
|
+
*
|
|
446
|
+
* 因为 BigNumber 的 `1/3` 是**截断的小数**,乘 27 后回不到整数。
|
|
447
|
+
* 而 Fraction 保留精确分数,代入后能约分成整数 —— 结果 9 就是 9。
|
|
448
|
+
*
|
|
449
|
+
* 三角函数等无理性结果 Fraction 会退化成浮点,这是可接受的:
|
|
450
|
+
* 那些结果本来就不是有理数。
|
|
451
|
+
*
|
|
452
|
+
* @returns mathjs 实例(Fraction 模式)
|
|
453
|
+
*/
|
|
454
|
+
export declare function rational(): any;
|
|
391
455
|
/**
|
|
392
456
|
* 规范化输入:换行转语句分隔符、去多余分号、引号内原样保留。
|
|
393
457
|
*
|
|
@@ -395,6 +459,26 @@ export declare function fast(): any;
|
|
|
395
459
|
* 换行会被 mathjs 当成语句结束而报错。
|
|
396
460
|
*/
|
|
397
461
|
export declare function normalizeSource(input: string): string;
|
|
462
|
+
/**
|
|
463
|
+
* 把中文单位与中文量级词展开成 mathjs 能解析的形态。
|
|
464
|
+
*
|
|
465
|
+
* ## 两次展开,顺序有讲究
|
|
466
|
+
*
|
|
467
|
+
* 1. **量级词**(万/亿/万亿)→ 纯乘数括号,如 `(2.66 * 1e8)`
|
|
468
|
+
* 2. **中文单位**(里/丈/亩/斤/吨)→ `(450 * 1e8) * 1000 kg`
|
|
469
|
+
*
|
|
470
|
+
* 顺序反了会漏:`450 亿吨` 先走单位展开时,「亿吨」不在单位表里,
|
|
471
|
+
* 原样留下;先展开量级词得到 `(450 * 1e8)吨`,再让单位展开处理「吨」才对。
|
|
472
|
+
*
|
|
473
|
+
* ## 为什么走文本变换而不是注册进 mathjs
|
|
474
|
+
*
|
|
475
|
+
* `buildMath` 里刻意删掉了 `createUnit`(表达式求值不允许往引擎注入任意定义)。
|
|
476
|
+
* 放开这个边界来支持中文单位,代价远大于收益。
|
|
477
|
+
*
|
|
478
|
+
* @param source - 已做过基础归一化的表达式
|
|
479
|
+
* @returns 中文单位与量级词已展开的表达式
|
|
480
|
+
*/
|
|
481
|
+
export declare function normalizeChineseUnits(source: string): string;
|
|
398
482
|
/**
|
|
399
483
|
* 设置本次调用的显示精度(在工具入口调用)。
|
|
400
484
|
*
|
package/lib/types/playbook.d.ts
CHANGED
|
@@ -90,6 +90,34 @@ export declare function buildPlaybook(state: {
|
|
|
90
90
|
* @param state - 工作区状态
|
|
91
91
|
* @returns 精简提示词
|
|
92
92
|
*/
|
|
93
|
+
/**
|
|
94
|
+
* brief 档的指令集(每轮都随注入下发,**每个字都在付费**)。
|
|
95
|
+
*
|
|
96
|
+
* ## 字数按「使用频率 × 重要程度」分配
|
|
97
|
+
*
|
|
98
|
+
* 曾经的问题是比例失调:整段 817 字符里,「世界推演」占了 360(44%),
|
|
99
|
+
* 而它只对做架空世界设定那类会话有用 —— 算术、单位换算、统计这些
|
|
100
|
+
* **高频场景完全用不到**,却要为它每轮付 360 字符。
|
|
101
|
+
*
|
|
102
|
+
* 现在按三档分配:
|
|
103
|
+
*
|
|
104
|
+
* | 内容 | 频率 | 重要度 | 字数 |
|
|
105
|
+
* |---|---|---|---|
|
|
106
|
+
* | 行为约束(必须调用 / 不要心算) | 每轮 | 极高 | ~40 |
|
|
107
|
+
* | 该用哪个 operation(最常问) | 极高 | 高 | ~70 |
|
|
108
|
+
* | 可信度标签怎么读 | 中 | 极高 | ~60 |
|
|
109
|
+
* | 精度两层 | 中 | 高 | ~50 |
|
|
110
|
+
* | 世界推演分工(低频,压到极限) | 低 | 中 | ~80 |
|
|
111
|
+
*
|
|
112
|
+
* ## 顺手修掉两处自相矛盾
|
|
113
|
+
*
|
|
114
|
+
* 原第 5 条说「输出默认全精度(几十位小数)」、第 6 条说「默认 8 位小数」——
|
|
115
|
+
* 两条并列下发,模型读到的是互相冲突的指令。**8 位才是现状**(2.1.0 起),
|
|
116
|
+
* 「全精度」那句是过时表述,已删。
|
|
117
|
+
*
|
|
118
|
+
* @param state - 工作区状态(改过的常数、自创量)
|
|
119
|
+
* @returns 指令集文本
|
|
120
|
+
*/
|
|
93
121
|
export declare function buildBriefPlaybook(state: {
|
|
94
122
|
changedConstants?: string[];
|
|
95
123
|
customConstants?: number;
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 度量单位数据:古今中外,尽量收全。
|
|
3
|
+
*
|
|
4
|
+
* ## 公制中转
|
|
5
|
+
*
|
|
6
|
+
* 每个单位都只声明「它等于多少**该量纲的公制基准单位**」(`factor`),
|
|
7
|
+
* 换算于是变成 `value × 源factor ÷ 目标factor` 两步,任何两个单位都能互通。
|
|
8
|
+
* 这样加一个单位只需一行数据,不需要和已有单位两两配对(那是 O(n²) 的维护地狱)。
|
|
9
|
+
*
|
|
10
|
+
* 基准单位见 `units.ts` 的 `BASE_UNIT`:长度 m、质量 kg、时间 s、面积 m²、
|
|
11
|
+
* 体积 m³、能量 J、功率 W、温度 K、速度 m/s、压强 Pa,以及本模块新增量纲各自的基准。
|
|
12
|
+
*
|
|
13
|
+
* ## 为什么收这么多
|
|
14
|
+
*
|
|
15
|
+
* 作者写「这堵墙高三丈」「追了三十里地」「秤上三斤二两」时,
|
|
16
|
+
* 换算系数全靠脑记 —— 记错一次就是一次事故(实测反馈里有 3~4 次因为这个中断重算)。
|
|
17
|
+
* 收进表里,就把「记错数」变成「打错名」,后者一眼就能看出来。
|
|
18
|
+
*
|
|
19
|
+
* ## 收录原则
|
|
20
|
+
*
|
|
21
|
+
* · **不收需要上下文才能定的**(「一箭之地」「一盏茶工夫」)—— 猜就是错
|
|
22
|
+
* · **同一名字在不同体系有歧义时,收常用那个并在 note 里标明另一体系**
|
|
23
|
+
* (加仑、担、石、马力都是这样)
|
|
24
|
+
* · **历史单位标朝代/年代**——尺、斤、里的数值历代不同,这是事实,不是精度问题
|
|
25
|
+
*
|
|
26
|
+
* @module dsh-math-calculator/units-data
|
|
27
|
+
*/
|
|
28
|
+
import type { Dimension, UnitDef } from './units.js';
|
|
29
|
+
/**
|
|
30
|
+
* SI 词头(十进制),从最大到最小。
|
|
31
|
+
*
|
|
32
|
+
* 用于批量生成 `km`/`cm`/`mm` 这类前缀单位,避免手写几十行同构数据。
|
|
33
|
+
*/
|
|
34
|
+
export declare const SI_PREFIXES: Array<[string, number]>;
|
|
35
|
+
/**
|
|
36
|
+
* 用 SI 词头批量生成一组单位。
|
|
37
|
+
*
|
|
38
|
+
* @param base - 词头后面的单位符号(如 `'m'` → `km`/`cm`/`mm`)
|
|
39
|
+
* @param dimension - 量纲
|
|
40
|
+
* @param baseFactor - 该单位本身的公制等值(如 `'t'` 的 1000 kg)
|
|
41
|
+
* @param aliasPrefix - 中文名前缀(如 `'千'\,`'厘'`),省略则不给中文别名
|
|
42
|
+
* @returns 单位定义数组(含词头为 1 的那个基础单位)
|
|
43
|
+
*/
|
|
44
|
+
/**
|
|
45
|
+
* 长度。
|
|
46
|
+
*
|
|
47
|
+
* 基准 m。收录:SI(含词头)、中国历代市制与古制、英制/美制、航海、
|
|
48
|
+
* 天文、日/俄/印等地域单位、微观与专业单位。
|
|
49
|
+
*/
|
|
50
|
+
export declare const LENGTH_UNITS: UnitDef[];
|
|
51
|
+
/**
|
|
52
|
+
* 质量。
|
|
53
|
+
*
|
|
54
|
+
* 基准 kg。中国市制与古制、英制三套吨、金衡、药衡、日/俄等。
|
|
55
|
+
*/
|
|
56
|
+
export declare const MASS_UNITS: UnitDef[];
|
|
57
|
+
/**
|
|
58
|
+
* 时间。
|
|
59
|
+
*
|
|
60
|
+
* 基准 s。含中国古制(刻/时辰/更/炷香)、佛家/道家时间、地质年代、天文周期。
|
|
61
|
+
*/
|
|
62
|
+
export declare const TIME_UNITS: UnitDef[];
|
|
63
|
+
/**
|
|
64
|
+
* 面积。
|
|
65
|
+
*
|
|
66
|
+
* 基准 m²。中国市制亩/顷(各地亩不同)、英制 acre/rood、日本町/反步。
|
|
67
|
+
*/
|
|
68
|
+
export declare const AREA_UNITS: UnitDef[];
|
|
69
|
+
/**
|
|
70
|
+
* 体积。
|
|
71
|
+
*
|
|
72
|
+
* 基准 m³。中国市制(斗/升/石)、英制美制(加仑三种!)、
|
|
73
|
+
* 烹饪量(杯/勺/茶匙)、酒桶、日本(合/升/石)。
|
|
74
|
+
*
|
|
75
|
+
* ⚠ 体积是歧义最多的量纲:加仑(美/英差 20%)、盎司(液量/常衡)、
|
|
76
|
+
* 夸脱、品脱都分英美两制。表里默认收**美制**并在 note 标明英制差异。
|
|
77
|
+
*/
|
|
78
|
+
export declare const VOLUME_UNITS: UnitDef[];
|
|
79
|
+
/**
|
|
80
|
+
* 能量。
|
|
81
|
+
*
|
|
82
|
+
* 基准 J。含营养学卡路里、英制 BTU/therm、化石燃料(吨油当量/吨煤当量)、
|
|
83
|
+
* 火药与核武当量、以及家常能源计量(度、方气)。
|
|
84
|
+
*/
|
|
85
|
+
export declare const ENERGY_UNITS: UnitDef[];
|
|
86
|
+
/**
|
|
87
|
+
* 功率。
|
|
88
|
+
*
|
|
89
|
+
* 基准 W。含马力两套(英制 745.7 / 公制 735)、制冷吨、
|
|
90
|
+
* 人力畜力(写古代题材最需要)、以及天体量级(太阳光度)。
|
|
91
|
+
*/
|
|
92
|
+
export declare const POWER_UNITS: UnitDef[];
|
|
93
|
+
/**
|
|
94
|
+
* 温度、速度、压强,以及本模块新增的几个量纲。
|
|
95
|
+
*
|
|
96
|
+
* ## 温度为什么特殊
|
|
97
|
+
*
|
|
98
|
+
* 温度是**仿射**变换(`K = °C + 273.15`),不是比例。
|
|
99
|
+
* 表里的 `factor` 只表示「每 1 单位等于多少 K 的**间隔**」,
|
|
100
|
+
* 实际换算由 `units.ts` 的 `convert()` 用专门分支处理偏移。
|
|
101
|
+
* 只收三种有偏移的温标 + 一种无偏移的(K)。列氏/兰氏也收了,方便历史文本。
|
|
102
|
+
*/
|
|
103
|
+
export declare const TEMPERATURE_UNITS: UnitDef[];
|
|
104
|
+
/**
|
|
105
|
+
* 速度。
|
|
106
|
+
*
|
|
107
|
+
* 基准 m/s。含航海(节)、航空(马赫两套基准)、
|
|
108
|
+
* 古代表述(「日行百里」拆成速度)、以及天体量级。
|
|
109
|
+
*/
|
|
110
|
+
export declare const SPEED_UNITS: UnitDef[];
|
|
111
|
+
/**
|
|
112
|
+
* 压强。
|
|
113
|
+
*
|
|
114
|
+
* 基准 Pa。含工程(psi/bar)、气象(hPa/atm)、医学(mmHg)、真空(Torr)、
|
|
115
|
+
* 以及水柱/汞柱高度这类「用液柱高表示压强」的写法。
|
|
116
|
+
*/
|
|
117
|
+
export declare const PRESSURE_UNITS: UnitDef[];
|
|
118
|
+
/**
|
|
119
|
+
* 本模块新增的量纲。
|
|
120
|
+
*
|
|
121
|
+
* 原表只有 10 个量纲(长/质/时/面/体/能/功/温/速/压)。写小说时还会撞上:
|
|
122
|
+
* 数据量(「这段代码多大」)、角度(「转三十度」)、力(「拉弓要多少牛」)、
|
|
123
|
+
* 频率(「一秒几次」)。
|
|
124
|
+
*
|
|
125
|
+
* 这些量纲的**基准单位也是公制 SI**,所以「公制中转」对它们同样成立。
|
|
126
|
+
*/
|
|
127
|
+
/** 数据量(十进制与二进制两套并存,差 2.4%~7%,是企业价目表最常见的坑)。 */
|
|
128
|
+
export declare const DATA_UNITS: UnitDef[];
|
|
129
|
+
/** 平面角。基准 rad(弧度)。 */
|
|
130
|
+
export declare const ANGLE_UNITS: UnitDef[];
|
|
131
|
+
/** 力。基准 N。 */
|
|
132
|
+
export declare const FORCE_UNITS: UnitDef[];
|
|
133
|
+
/** 频率(次要但常用)。基准 Hz。 */
|
|
134
|
+
export declare const FREQUENCY_UNITS: UnitDef[];
|
|
135
|
+
/**
|
|
136
|
+
* 用 SI 词头批量生成一组单位。
|
|
137
|
+
*
|
|
138
|
+
* 便于将来按需生成(当前表内的前缀单位已直接列在数据里,避免运行期拼装开销)。
|
|
139
|
+
*
|
|
140
|
+
* @param base - 词头后面的单位符号(如 'm' → km/cm/mm)
|
|
141
|
+
* @param dimension - 量纲
|
|
142
|
+
* @param baseFactor - 该单位本身的公制等值(如 't' 的 1000 kg)
|
|
143
|
+
* @returns 单位定义数组
|
|
144
|
+
*/
|
|
145
|
+
export declare function withPrefixes(base: string, dimension: Dimension, baseFactor: number): UnitDef[];
|
|
146
|
+
/**
|
|
147
|
+
* 全部单位:公制(含 SI 词头)、中国市制与古制、英制与美制、航海、天文、
|
|
148
|
+
* 日本、俄国、印度、古希腊罗马,以及数据量 / 角度 / 力 / 频率。
|
|
149
|
+
*
|
|
150
|
+
* 每个条目只声明「等于多少**公制基准单位**」,因此任意两者都能互换 ——
|
|
151
|
+
* 这就是「公制做换算中转」的实现方式。
|
|
152
|
+
*/
|
|
153
|
+
/**
|
|
154
|
+
* 中国古制与市制的细分单位。
|
|
155
|
+
*
|
|
156
|
+
* ## 为什么这么多条
|
|
157
|
+
*
|
|
158
|
+
* 中文里长度、重量、容量三套都是**十进制细分**(尺寸分厘毫丝忽),
|
|
159
|
+
* 而且历代数值不同。写小说时「一厘银」「三忽」这类说法会出现,
|
|
160
|
+
* 但换算系数从来没人记得住 —— 这正是该收进表的理由。
|
|
161
|
+
*
|
|
162
|
+
* ⚠ 历代数值差异极大,表内统一用**市制(1929 年定制)**为基准,
|
|
163
|
+
* 古制差异写在 note 里;要精确到某朝代用 `customUnits` 覆盖。
|
|
164
|
+
*/
|
|
165
|
+
export declare const CHINA_EXTRA_UNITS: UnitDef[];
|
|
166
|
+
/**
|
|
167
|
+
* 欧洲列强的传统单位(工业革命前后,写蒸汽朋克/历史题材的刚需)。
|
|
168
|
+
*
|
|
169
|
+
* ## 为什么这些必须收
|
|
170
|
+
*
|
|
171
|
+
* 公制是 1795 年法国才立、1875 年才国际化的。在此之前**每个国家各有一套**,
|
|
172
|
+
* 而且同一国不同行业还不一样(例如英国有常衡/金衡/药衡三套重量)。
|
|
173
|
+
*
|
|
174
|
+
* 写 1700—1900 年的故事时,人物说的「一普特面粉」「三十维尔斯特」是真的,
|
|
175
|
+
* 换算系数却没人记得住。这些数值来自当时的官方定义或学界通行近似。
|
|
176
|
+
*/
|
|
177
|
+
/** 俄制(沙俄,16—20 世纪初)。 */
|
|
178
|
+
export declare const RUSSIA_UNITS: UnitDef[];
|
|
179
|
+
/** 德制(普鲁士/各邦,1872 年统一前)。 */
|
|
180
|
+
export declare const GERMANY_UNITS: UnitDef[];
|
|
181
|
+
/** 法制(公制诞生地,但旧制 au 1795 前仍在使用)。 */
|
|
182
|
+
export declare const FRANCE_UNITS: UnitDef[];
|
|
183
|
+
/** 西班牙/葡萄牙/意大利/荷兰/北欧。 */
|
|
184
|
+
export declare const OTHER_EUROPE_UNITS: UnitDef[];
|
|
185
|
+
/**
|
|
186
|
+
* 东亚、南亚、西亚的传统单位。
|
|
187
|
+
*
|
|
188
|
+
* 日本是用户明确点名的:尺贯法(shakkan-hō)自成一套,且与中国市制
|
|
189
|
+
* 同字不同值(日尺 30.3 cm vs 市尺 32 cm,日斤 600 g vs 市斤 500 g)。
|
|
190
|
+
* 写日式题材(武士、町人、和风奇幻)时这些是刚需。
|
|
191
|
+
*/
|
|
192
|
+
/** 日本尺贯法(1891 年法定,沿用至公制化)。 */
|
|
193
|
+
export declare const JAPAN_UNITS: UnitDef[];
|
|
194
|
+
/** 印度(莫卧儿与英属时期)。 */
|
|
195
|
+
export declare const INDIA_UNITS: UnitDef[];
|
|
196
|
+
/** 阿拉伯/奥斯曼/波斯。 */
|
|
197
|
+
export declare const ARABIA_UNITS: UnitDef[];
|
|
198
|
+
/** 东南亚与其它。 */
|
|
199
|
+
export declare const SEA_OTHER_UNITS: UnitDef[];
|
|
200
|
+
/**
|
|
201
|
+
* 全部单位:公制(含 SI 词头)、中国市制与历代、日本尺贯法、
|
|
202
|
+
* 俄/德/法/西/葡/意/荷/北欧传统单位、印度/阿拉伯/奥斯曼、
|
|
203
|
+
* 英美制、航海与天文,以及数据量/角度/力/频率。
|
|
204
|
+
*
|
|
205
|
+
* 每个条目只声明「等于多少**公制基准单位**」,因此任意两者都能互换 ——
|
|
206
|
+
* 这就是「公制做换算中转」的实现方式。
|
|
207
|
+
*
|
|
208
|
+
* 条数见 `ALL_UNITS.length`(当前 429:度量衡 398 + 科学 31)。
|
|
209
|
+
*/
|
|
210
|
+
/**
|
|
211
|
+
* 电学、光学、化学与核物理的 SI 单位(补齐量纲断层)。
|
|
212
|
+
*
|
|
213
|
+
* ## 为什么必须补这一批
|
|
214
|
+
*
|
|
215
|
+
* 原来的单位表只有 4 个 SI 基本单位(m / kg / s / K),缺安培、摩尔、坎德拉 ——
|
|
216
|
+
* 于是**整个电学、光学、化学、核物理领域无法换算**:
|
|
217
|
+
* 写「十二伏电池」「三毫居里放射源」「0.5 戈瑞剂量」时工具一律不认识。
|
|
218
|
+
*
|
|
219
|
+
* 这一批把 7 个 SI 基本单位补全,并把 22 个具名导出单位落地,
|
|
220
|
+
* 连带 18 个新量纲(电流/电荷/电压/电容/电阻/电导/磁通/磁通密度/电感/
|
|
221
|
+
* 立体角/发光强度/光通量/照度/物质的量/活度/吸收剂量/剂量当量/催化活度)。
|
|
222
|
+
*
|
|
223
|
+
* ## 溯源
|
|
224
|
+
*
|
|
225
|
+
* 全部按 BIPM《SI Brochure》第 9 版(2019)Table 2/3/5。
|
|
226
|
+
* 非 SI 单位(Ci、rad、U、gauss)按 NIST SP 811 与 ISO 80000 系列。
|
|
227
|
+
*
|
|
228
|
+
* ## 一处同名冲突
|
|
229
|
+
*
|
|
230
|
+
* 辐射吸收剂量的 `rad` 与平面角弧度 `rad` 同名(插件已收弧度)。
|
|
231
|
+
* 辐射那条主名用 `rad_dose`,别名写 `rad (dose)` —— 两个都是正式写法,
|
|
232
|
+
* 但主名不能撞,否则查表时永远命中弧度。
|
|
233
|
+
*/
|
|
234
|
+
export declare const SI_ELECTRO_OPTICAL_UNITS: UnitDef[];
|
|
235
|
+
/**
|
|
236
|
+
* 全部单位:公制(含 SI 词头)、中国市制与历代、日本尺贯法、
|
|
237
|
+
* 俄/德/法/西/葡/意/荷/北欧传统单位、印度/阿拉伯/奥斯曼、
|
|
238
|
+
* 英美制、航海与天文、电学/光学/化学/核物理的 SI 单位,
|
|
239
|
+
* 以及数据量/角度/力/频率。
|
|
240
|
+
*
|
|
241
|
+
* 每个条目只声明「等于多少**公制基准单位**」,因此任意两者都能互换 ——
|
|
242
|
+
* 这就是「公制做换算中转」的实现方式。
|
|
243
|
+
*
|
|
244
|
+
* 条数见 `ALL_UNITS.length`:462 条 / 32 个量纲
|
|
245
|
+
* (度量衡与科学两类,见 `UnitDef.category`)。
|
|
246
|
+
*/
|
|
247
|
+
export declare const ALL_UNITS: UnitDef[];
|
|
248
|
+
/** 各量纲的基准(公制中转点)。换算永远「先乘到基准、再除以目标」。 */
|
|
249
|
+
export declare const DIMENSION_BASE: Record<Dimension, string>;
|
|
250
|
+
/** 量纲的中文名。 */
|
|
251
|
+
export declare const DIMENSION_LABEL: Record<Dimension, string>;
|
|
252
|
+
/** 量纲排列顺序(列单位时分组的顺序)。 */
|
|
253
|
+
export declare const DIMENSION_ORDER: Dimension[];
|
package/lib/types/units.d.ts
CHANGED
|
@@ -35,6 +35,31 @@
|
|
|
35
35
|
* @module dsh-math-calculator/units
|
|
36
36
|
*/
|
|
37
37
|
/** 一个单位。 */
|
|
38
|
+
/**
|
|
39
|
+
* 单位的**用途分类**。
|
|
40
|
+
*
|
|
41
|
+
* ## 为什么要分
|
|
42
|
+
*
|
|
43
|
+
* 这两类的使用场景完全不同,混在一张表里会让列表变得没法读:
|
|
44
|
+
*
|
|
45
|
+
* | 分类 | 例子 | 谁会用 |
|
|
46
|
+
* |---|---|---|
|
|
47
|
+
* | `measure`(度量衡) | 里、斤、斗、俄尺、日尺、加仑、英亩 | 写小说、算账、历史考据 |
|
|
48
|
+
* | `science`(科学) | eV、里德伯、靶恩、玻尔半径、amu、erg、slug | 物理/化学/天文计算 |
|
|
49
|
+
*
|
|
50
|
+
* 一个作者问「三丈是多少米」,不该在 422 条里跟「玻尔半径」挤在一起找;
|
|
51
|
+
* 反过来,算原子结合能的人也不关心「日尺」。分开列,两边都清爽。
|
|
52
|
+
*
|
|
53
|
+
* ## 判据
|
|
54
|
+
*
|
|
55
|
+
* · **度量衡**:日常生活、贸易、历史、工程里**人真的会说出口**的量
|
|
56
|
+
* · **科学**:只在专业计算里出现,日常语境说了没人懂(「这块地 3 靶恩」是笑话)
|
|
57
|
+
*
|
|
58
|
+
* 边界情况按「作者会不会在正文里写它」判:`psi` 会(工程题材),
|
|
59
|
+
* 所以算度量衡;`hartree` 不会(原子物理单位),算科学。
|
|
60
|
+
*/
|
|
61
|
+
export type UnitCategory = 'measure' | 'science';
|
|
62
|
+
/** 一个单位。 */
|
|
38
63
|
export interface UnitDef {
|
|
39
64
|
/** 单位名(作者会写的写法)。 */
|
|
40
65
|
name: string;
|
|
@@ -44,21 +69,46 @@ export interface UnitDef {
|
|
|
44
69
|
dimension: Dimension;
|
|
45
70
|
/** 换算到该量纲基准单位的系数(基准单位见 BASE_UNIT)。 */
|
|
46
71
|
factor: number;
|
|
72
|
+
/**
|
|
73
|
+
* 用途分类,默认 `measure`(度量衡)。
|
|
74
|
+
*
|
|
75
|
+
* 省略时按度量衡处理 —— 表里绝大多数是这一类,
|
|
76
|
+
* 只给科学单位显式标 `science`,比逐条标更不容易漏。
|
|
77
|
+
*/
|
|
78
|
+
category?: UnitCategory;
|
|
47
79
|
/** 说明(什么时候用、有什么坑)。 */
|
|
48
80
|
note?: string;
|
|
49
81
|
}
|
|
50
|
-
/**
|
|
51
|
-
|
|
52
|
-
|
|
82
|
+
/**
|
|
83
|
+
* 支持的量纲。
|
|
84
|
+
*
|
|
85
|
+
* 分两层:**物理量纲**(长/质/时/面/体/能/功/温/速/压)与**扩展量纲**
|
|
86
|
+
* (数据量/角度/力/频率)—— 后者是写小说时同样会撞上的(「这段代码多大」
|
|
87
|
+
* 「转三十度」「拉弓要多少牛」),它们各自的公制基准也定义在 units-data。
|
|
88
|
+
*/
|
|
89
|
+
export type Dimension = 'length' | 'mass' | 'time' | 'area' | 'volume' | 'energy' | 'power' | 'temperature' | 'speed' | 'pressure' | 'data' | 'angle' | 'force' | 'frequency' | 'current' | 'charge' | 'voltage' | 'capacitance' | 'resistance' | 'conductance' | 'magnetic_flux' | 'magnetic_flux_density' | 'inductance' | 'solid_angle' | 'luminous_intensity' | 'luminous_flux' | 'illuminance' | 'amount_of_substance' | 'activity' | 'absorbed_dose' | 'dose_equivalent' | 'catalytic_activity';
|
|
90
|
+
/**
|
|
91
|
+
* 每个量纲的基准单位(factor = 1 的那个)—— 即「公制中转点」。
|
|
92
|
+
*
|
|
93
|
+
* 定义在 `units-data.ts`,这里再导出,保持旧的导入路径可用。
|
|
94
|
+
*/
|
|
95
|
+
import { DIMENSION_LABEL, DIMENSION_ORDER } from './units-data.js';
|
|
96
|
+
/** 每个量纲的基准单位 —— 即「公制中转点」。 */
|
|
53
97
|
export declare const BASE_UNIT: Record<Dimension, string>;
|
|
54
98
|
/** 量纲的中文名。 */
|
|
55
|
-
export
|
|
99
|
+
export { DIMENSION_LABEL, DIMENSION_ORDER };
|
|
56
100
|
/**
|
|
57
101
|
* 内置单位表。
|
|
58
102
|
*
|
|
59
103
|
* ⚠️ 中文古制的换算**历朝不同**,这里用最常见的近似值并在 note 里标注。
|
|
60
104
|
* 作者若需要精确到某个朝代,用 `customUnits` 覆盖。
|
|
61
105
|
*/
|
|
106
|
+
/**
|
|
107
|
+
* 内置单位表 —— 从 `units-data.ts` 导入(那里按体系分节,便于查阅与扩充)。
|
|
108
|
+
*
|
|
109
|
+
* 现在是 **288 条**:公制(含 SI 词头)、中国市制与古制、英制与美制、
|
|
110
|
+
* 航海、天文、日本、俄国、印度、古希腊罗马,外加数据量/角度/力/频率。
|
|
111
|
+
*/
|
|
62
112
|
export declare const UNITS: UnitDef[];
|
|
63
113
|
/**
|
|
64
114
|
* 按名字查单位(含别名)。
|
package/lib/types/workspace.d.ts
CHANGED
|
@@ -74,6 +74,19 @@ export interface WorkspaceData {
|
|
|
74
74
|
* 未设置时沿用计算精度(即完整输出,旧行为)。
|
|
75
75
|
*/
|
|
76
76
|
displayPrecision?: number;
|
|
77
|
+
/**
|
|
78
|
+
* 是否让 `variables` 里的命名变量**参与计算**。
|
|
79
|
+
*
|
|
80
|
+
* ## 为什么默认关闭
|
|
81
|
+
*
|
|
82
|
+
* 打开后,同一个调用在不同工作区状态下会给出不同结果 ——
|
|
83
|
+
* 那会削弱「同输入同输出」,而后者是本项目做 hash 复现与回归对比的基础。
|
|
84
|
+
* 所以这是一个**显式的、逐工作区的**选择,不默认生效。
|
|
85
|
+
*
|
|
86
|
+
* 关闭时 `variables` 仍然照常存着(能 show、能 remove),
|
|
87
|
+
* 只是不参与计算 —— 与未引入这个功能时的行为完全一致。
|
|
88
|
+
*/
|
|
89
|
+
useWorkspaceVariables?: boolean;
|
|
77
90
|
/** 创建时间。 */
|
|
78
91
|
createdAt: string;
|
|
79
92
|
/** 最后修改时间。 */
|
|
@@ -336,4 +349,41 @@ export declare function bindHostWorkspace(rawId: unknown, rawTitle: unknown, mak
|
|
|
336
349
|
* @param name - 工作区名;省略用当前活动工作区
|
|
337
350
|
* @returns 显示有效位数;未设置返回 undefined
|
|
338
351
|
*/
|
|
352
|
+
/**
|
|
353
|
+
* 读出当前工作区里登记的命名变量(`variables` 字段)。
|
|
354
|
+
*
|
|
355
|
+
* ## 这个函数为什么存在
|
|
356
|
+
*
|
|
357
|
+
* 工作区的 `variables` 字段、写入路径(`action2:"set"` + `workspaceVariables`)、
|
|
358
|
+
* 删除路径(`remove-variable`)、显示(`show`)**都已经有了**,
|
|
359
|
+
* 唯独**读取路径缺**——存进去的变量在计算里根本用不到。
|
|
360
|
+
*
|
|
361
|
+
* 实测:
|
|
362
|
+
*
|
|
363
|
+
* ```
|
|
364
|
+
* {action2:"set", workspaceVariables:{BTU_LB:1260000}} → 变量 2 个 ✓ 存住了
|
|
365
|
+
* {expression:"BTU_LB/1000"} → Undefined symbol ✗ 用不了
|
|
366
|
+
* ```
|
|
367
|
+
*
|
|
368
|
+
* 也就是说这是「能删不能加、加了用不了」的半成品,不是需要从头设计的新能力。
|
|
369
|
+
*
|
|
370
|
+
* ## 失败时返回空对象,不抛异常
|
|
371
|
+
*
|
|
372
|
+
* 读工作区失败(文件损坏、目录不可写)不该让一次正常计算失败。
|
|
373
|
+
* 但**空对象与「真的没有变量」无法区分**,所以缓存指纹那边
|
|
374
|
+
* 不能只靠这个函数的返回值 —— 见 `index.ts` 里的 `workspaceVariablesFingerprint`。
|
|
375
|
+
*
|
|
376
|
+
* @param name - 工作区名;省略则用当前工作区
|
|
377
|
+
* @returns 变量字典(数字形态);读不到时为空对象
|
|
378
|
+
*/
|
|
379
|
+
export declare function workspaceVariablesOf(name?: string): Record<string, number>;
|
|
380
|
+
/**
|
|
381
|
+
* 读当前工作区固化的**显示**精度(小数点后几位)。
|
|
382
|
+
*
|
|
383
|
+
* 未设或读到 0 时返回 undefined,调用方据此回落默认值。
|
|
384
|
+
* 语义与「本次调用传入的 displayPrecision」一致:都是小数点后位数。
|
|
385
|
+
*
|
|
386
|
+
* @param name - 工作区名;省略则用当前工作区
|
|
387
|
+
* @returns 显示位数;未设或读不到返回 undefined
|
|
388
|
+
*/
|
|
339
389
|
export declare function displayPrecisionOf(name?: string): number | undefined;
|