@mirascript/mirascript 0.1.74 → 0.1.78

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 (75) hide show
  1. package/dist/{chunk-VI74OKFU.js → chunk-BITOQYYQ.js} +99 -89
  2. package/dist/chunk-BITOQYYQ.js.map +6 -0
  3. package/dist/{chunk-GONOUVUN.js → chunk-VNQQF2W7.js} +143 -58
  4. package/dist/chunk-VNQQF2W7.js.map +6 -0
  5. package/dist/compiler/emit/index.d.ts.map +1 -1
  6. package/dist/compiler/emit-script.d.ts.map +1 -1
  7. package/dist/compiler/worker.js +1 -1
  8. package/dist/helpers/convert/to-number.d.ts.map +1 -1
  9. package/dist/helpers/convert/to-string.d.ts +2 -0
  10. package/dist/helpers/convert/to-string.d.ts.map +1 -1
  11. package/dist/helpers/error.d.ts +1 -0
  12. package/dist/helpers/error.d.ts.map +1 -1
  13. package/dist/helpers/serialize.d.ts.map +1 -1
  14. package/dist/helpers/utils.d.ts +9 -0
  15. package/dist/helpers/utils.d.ts.map +1 -1
  16. package/dist/index.js +3 -3
  17. package/dist/index.js.map +1 -1
  18. package/dist/subtle.js +2 -2
  19. package/dist/vm/lib/global/debug.d.ts.map +1 -1
  20. package/dist/vm/lib/global/json.d.ts +3 -2
  21. package/dist/vm/lib/global/json.d.ts.map +1 -1
  22. package/dist/vm/lib/global/math/index.d.ts +2 -2
  23. package/dist/vm/lib/global/math/index.d.ts.map +1 -1
  24. package/dist/vm/lib/global/math/{gamma.d.ts → tgamma.d.ts} +1 -1
  25. package/dist/vm/lib/global/math/tgamma.d.ts.map +1 -0
  26. package/dist/vm/lib/global/math/{round.d.ts → to-int.d.ts} +1 -1
  27. package/dist/vm/lib/global/math/to-int.d.ts.map +1 -0
  28. package/dist/vm/lib/global/sequence/entries.d.ts +1 -1
  29. package/dist/vm/lib/global/sequence/entries.d.ts.map +1 -1
  30. package/dist/vm/lib/global/sequence/fold.d.ts +3 -0
  31. package/dist/vm/lib/global/sequence/fold.d.ts.map +1 -0
  32. package/dist/vm/lib/global/sequence/group.d.ts +3 -0
  33. package/dist/vm/lib/global/sequence/group.d.ts.map +1 -0
  34. package/dist/vm/lib/global/sequence/index.d.ts +2 -0
  35. package/dist/vm/lib/global/sequence/index.d.ts.map +1 -1
  36. package/dist/vm/lib/global/sequence/new.d.ts.map +1 -1
  37. package/dist/vm/lib/global/sequence/with.d.ts.map +1 -1
  38. package/dist/vm/lib/global/sequence/zip.d.ts +2 -2
  39. package/dist/vm/lib/global/sequence/zip.d.ts.map +1 -1
  40. package/dist/vm/lib/helpers.d.ts +2 -2
  41. package/dist/vm/lib/helpers.d.ts.map +1 -1
  42. package/dist/vm/operations/array-range.d.ts.map +1 -1
  43. package/dist/vm/operations/compound.d.ts.map +1 -1
  44. package/package.json +5 -5
  45. package/src/compiler/compile-fast.ts +1 -1
  46. package/src/compiler/emit/index.ts +0 -6
  47. package/src/compiler/emit-script.ts +1 -0
  48. package/src/helpers/convert/to-number.ts +5 -10
  49. package/src/helpers/convert/to-string.ts +3 -2
  50. package/src/helpers/error.ts +3 -1
  51. package/src/helpers/serialize.ts +4 -9
  52. package/src/helpers/types.ts +1 -1
  53. package/src/helpers/utils.ts +27 -0
  54. package/src/vm/lib/global/debug.ts +4 -8
  55. package/src/vm/lib/global/json.ts +21 -9
  56. package/src/vm/lib/global/math/index.ts +2 -2
  57. package/src/vm/lib/global/math/{gamma.ts → tgamma.ts} +8 -14
  58. package/src/vm/lib/global/sequence/entries.ts +6 -1
  59. package/src/vm/lib/global/sequence/fold.ts +30 -0
  60. package/src/vm/lib/global/sequence/group.ts +37 -0
  61. package/src/vm/lib/global/sequence/index.ts +2 -0
  62. package/src/vm/lib/global/sequence/map-filter.ts +2 -2
  63. package/src/vm/lib/global/sequence/new.ts +8 -2
  64. package/src/vm/lib/global/sequence/with.ts +7 -6
  65. package/src/vm/lib/global/sequence/zip.ts +21 -10
  66. package/src/vm/lib/helpers.ts +6 -6
  67. package/src/vm/lib/mod/matrix.ts +2 -2
  68. package/src/vm/operations/array-range.ts +10 -6
  69. package/src/vm/operations/compound.ts +13 -6
  70. package/src/vm/types/extern.ts +1 -1
  71. package/dist/chunk-GONOUVUN.js.map +0 -6
  72. package/dist/chunk-VI74OKFU.js.map +0 -6
  73. package/dist/vm/lib/global/math/gamma.d.ts.map +0 -1
  74. package/dist/vm/lib/global/math/round.d.ts.map +0 -1
  75. /package/src/vm/lib/global/math/{round.ts → to-int.ts} +0 -0
@@ -1,19 +1,31 @@
1
- import { isVmExtern, isVmModule } from '../../types/index.js';
1
+ import { isVmExtern, isVmModule, type VmValue } from '../../types/index.js';
2
2
  import { expectString, required, rethrowError, VmLib } from '../helpers.js';
3
3
  const { parse, stringify } = JSON;
4
4
 
5
5
  export const to_json = VmLib(
6
6
  (data) => {
7
7
  required('data', data, null);
8
- if (isVmExtern(data) || isVmModule(data)) {
9
- try {
10
- return stringify(data.value) ?? null;
11
- } catch (ex) {
12
- rethrowError('Failed to convert extern to JSON', ex, '{}');
13
- }
14
- }
15
8
  if (typeof data == 'function') return null;
16
- return stringify(data);
9
+ return stringify(data, (key, value: VmValue) => {
10
+ if (typeof value == 'function') {
11
+ return undefined;
12
+ }
13
+ if (isVmModule(value)) {
14
+ return value.value as JSONValue;
15
+ }
16
+ if (isVmExtern(value)) {
17
+ const extern = value.value;
18
+ if ('toJSON' in extern && typeof extern.toJSON == 'function') {
19
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
20
+ return extern.toJSON() as JSONValue;
21
+ }
22
+ if (typeof extern == 'function') {
23
+ return undefined;
24
+ }
25
+ return extern as JSONValue;
26
+ }
27
+ return value as JSONValue;
28
+ });
17
29
  },
18
30
  {
19
31
  summary: '将数据转换为 JSON 字符串',
@@ -26,5 +26,5 @@ export const random = VmLib(() => _random(), {
26
26
  export * from './arr.js';
27
27
  export * from './const.js';
28
28
  export * from './unary.js';
29
- export * from './round.js';
30
- export { gamma, factorial } from './gamma.js';
29
+ export * from './to-int.js';
30
+ export { gamma, factorial } from './tgamma.js';
@@ -81,22 +81,16 @@ function sinpi(x: number): number {
81
81
  const N = 12;
82
82
 
83
83
  // static const double g = 6.024680040776729583740234375;
84
- const GMHALF = 5.524_680_040_776_729_583_740_234_375 as const;
84
+ const GMHALF = 5.524680040776729583740234375 as const;
85
85
 
86
86
  const SNUM = [
87
- 23_531_376_880.410_759_688_572_007_674_451_636_754_734_846_804_94,
88
- 42_919_803_642.649_098_768_957_899_047_001_988_850_926_355_848_959,
89
- 35_711_959_237.355_668_049_440_185_451_547_166_705_960_488_635_843,
90
- 17_921_034_426.037_209_699_919_755_754_458_931_112_671_403_265_39,
91
- 6_039_542_586.352_028_005_064_291_644_307_297_921_069_938_842_070_8,
92
- 1_439_720_407.311_721_673_663_223_072_794_912_393_971_548_578_677_2,
93
- 248_874_557.862_054_156_511_460_386_413_229_423_216_321_251_278_01,
94
- 31_426_415.585_400_194_380_614_231_628_318_205_362_874_684_987_64,
95
- 2_876_370.628_935_372_441_225_409_051_620_849_613_599_114_537_876_8,
96
- 186_056.265_395_223_495_040_294_989_716_045_699_282_207_842_363_28,
97
- 8071.672_002_365_816_210_638_002_902_272_250_613_821_851_632_502_4,
98
- 210.824_277_751_579_345_872_509_733_920_713_362_711_669_695_802_91,
99
- 2.506_628_274_631_000_270_164_908_177_133_837_338_626_431_079_340_8,
87
+ 23_531_376_880.41075968857200767445163675473484680494, 42_919_803_642.649098768957899047001988850926355848959,
88
+ 35_711_959_237.355668049440185451547166705960488635843, 17_921_034_426.03720969991975575445893111267140326539,
89
+ 6_039_542_586.3520280050642916443072979210699388420708, 1_439_720_407.3117216736632230727949123939715485786772,
90
+ 248_874_557.86205415651146038641322942321632125127801, 31_426_415.58540019438061423162831820536287468498764,
91
+ 2_876_370.6289353724412254090516208496135991145378768, 186_056.26539522349504029498971604569928220784236328,
92
+ 8071.6720023658162106380029022722506138218516325024, 210.82427775157934587250973392071336271166969580291,
93
+ 2.5066282746310002701649081771338373386264310793408,
100
94
  ] as const;
101
95
 
102
96
  const SDEN = [
@@ -56,8 +56,13 @@ export const entries = VmLib(
56
56
  arr.push({ 0: i, 1: data[i] ?? null });
57
57
  }
58
58
  return arr;
59
+ } else {
60
+ const arr: Array<{ 0: string; 1: VmConst }> = [];
61
+ for (const [key, value] of _entries(data)) {
62
+ arr.push({ 0: key, 1: value ?? null });
63
+ }
64
+ return arr;
59
65
  }
60
- return _entries(data).map(([key, value]) => ({ 0: key, 1: value ?? null }));
61
66
  },
62
67
  {
63
68
  summary: '返回数组或记录的键值对列表',
@@ -0,0 +1,30 @@
1
+ import { $Call } from '../../../operations/index.js';
2
+ import type { VmValue } from '../../../types/index.js';
3
+ import { VmLib, expectCallable, expectConst, iterate, required } from '../../helpers.js';
4
+
5
+ export const fold = VmLib(
6
+ (data, initial, f) => {
7
+ required('initial', initial, null);
8
+ expectConst('data', data, null);
9
+ expectCallable('f', f, data);
10
+
11
+ let acc: VmValue = initial;
12
+ iterate(data, (value, index, data) => {
13
+ acc = $Call(f, [acc, value, index, data]);
14
+ });
15
+ return acc;
16
+ },
17
+ {
18
+ summary: '对数组或记录中的每个元素应用函数,并返回累积结果',
19
+ params: {
20
+ data: { type: 'array | record', description: '要折叠的数组或记录' },
21
+ initial: { type: 'any', description: '初始累积值' },
22
+ f: {
23
+ type: 'fn(acc: type(initial), value: any, key: number | string, input: type(data)) -> type(initial)',
24
+ description: '应用于每个元素的函数',
25
+ },
26
+ },
27
+ returns: { type: 'type(initial)' },
28
+ examples: ['fold([1, 2, 3], 0, fn (acc, x) { acc + x }) // 6'],
29
+ },
30
+ );
@@ -0,0 +1,37 @@
1
+ import { toString } from '../../../../helpers/convert/to-string.js';
2
+ import { fromEntries } from '../../../../helpers/utils.js';
3
+ import { $Call } from '../../../operations/call.js';
4
+ import type { VmConst } from '../../../types/index.js';
5
+ import { VmLib, expectArray, expectCallable } from '../../helpers.js';
6
+
7
+ export const group_by = VmLib(
8
+ (data, key) => {
9
+ expectArray('data', data, null);
10
+ expectCallable('key', key, data);
11
+ const result = new Map<string, VmConst[]>();
12
+ const len = data.length;
13
+ for (let i = 0; i < len; i++) {
14
+ const v = data[i] ?? null;
15
+ const k = toString($Call(key, [v, i, data]), undefined);
16
+ let arr = result.get(k);
17
+ if (!arr) {
18
+ arr = [];
19
+ result.set(k, arr);
20
+ }
21
+ arr.push(v);
22
+ }
23
+ return fromEntries(result);
24
+ },
25
+ {
26
+ summary: '根据指定的键函数对数组进行分组',
27
+ params: {
28
+ data: { type: 'array', description: '要分组的数组' },
29
+ key: {
30
+ type: 'fn(value: any, index: number, arr: type(data)) -> string',
31
+ description: '用于生成分组键的函数',
32
+ },
33
+ },
34
+ returns: { type: 'record' },
35
+ examples: ['group_by([1, 2, 3, 4], fn { it % 2 }) // ("0": [2, 4], "1": [1, 3])'],
36
+ },
37
+ );
@@ -11,3 +11,5 @@ export * from './sort.js';
11
11
  export * from './unique.js';
12
12
  export * from './repeat.js';
13
13
  export * from './new.js';
14
+ export * from './fold.js';
15
+ export * from './group.js';
@@ -1,7 +1,7 @@
1
1
  import { toBoolean } from '../../../../helpers/convert/to-boolean.js';
2
2
  import { $Call } from '../../../operations/index.js';
3
3
  import { isVmConst, type VmAny, type VmValue } from '../../../types/index.js';
4
- import { VmLib, expectCallable, expectConst, map as mapImpl } from '../../helpers.js';
4
+ import { VmLib, expectCallable, expectConst, iterate } from '../../helpers.js';
5
5
 
6
6
  export * from './with.js';
7
7
  export * from './entries.js';
@@ -16,7 +16,7 @@ function mapImplWrapped(
16
16
  ): VmValue {
17
17
  expectConst('data', data, null);
18
18
  expectCallable(fnName, fn, data);
19
- return mapImpl(data, (value, index, data) => {
19
+ return iterate(data, (value, index, data) => {
20
20
  const ret = mapper(fn, value, index, data);
21
21
  if (ret === undefined || isVmConst(ret)) return ret;
22
22
  return null;
@@ -1,7 +1,13 @@
1
1
  import type { VmArray, VmConst, VmRecord } from '../../../types/index.js';
2
2
  import { toString } from '../../../../helpers/convert/to-string.js';
3
3
  import { VM_ARRAY_MAX_LENGTH } from '../../../../helpers/constants.js';
4
- import { keys as _keys, values as _values, entries as _entries, PositiveInfinity } from '../../../../helpers/utils.js';
4
+ import {
5
+ keys as _keys,
6
+ values as _values,
7
+ entries as _entries,
8
+ PositiveInfinity,
9
+ setRecord,
10
+ } from '../../../../helpers/utils.js';
5
11
  import { $Call, $El, $Get } from '../../../operations/index.js';
6
12
  import { VmLib, expectCallable, expectIntegerRange } from '../../helpers.js';
7
13
 
@@ -15,7 +21,7 @@ export const new_record = VmLib(
15
21
  if (entry == null) continue;
16
22
  const key = $Get(entry, 0);
17
23
  const value = $El($Get(entry, 1));
18
- result[toString(key)] = value;
24
+ setRecord(result, toString(key), value);
19
25
  }
20
26
  return result;
21
27
  },
@@ -1,16 +1,17 @@
1
1
  import { VM_ARRAY_MAX_LENGTH } from '../../../../helpers/constants.js';
2
2
  import { toNumber, toString } from '../../../../helpers/convert/index.js';
3
3
  import { isVmArray, isVmRecord } from '../../../../helpers/types.js';
4
- import { isArray, isInteger, isNaN, NotNumber } from '../../../../helpers/utils.js';
4
+ import { isArray, isInteger, isFinite, NotNumber, setRecord, getRecord } from '../../../../helpers/utils.js';
5
5
  import { $El } from '../../../operations/helpers.js';
6
6
  import type { VmArray, VmConst, VmValue } from '../../../types/index.js';
7
7
  import { VmLib, expectArrayOrRecord, expectConst, throwError } from '../../helpers.js';
8
8
 
9
9
  const arrIndex = (index: NonNullable<VmConst>): number => {
10
- const idx = Math.trunc(toNumber(index, NotNumber));
11
- if (isNaN(idx) || idx < 0) {
10
+ const num = toNumber(index, NotNumber);
11
+ if (!isFinite(num) || num < 0) {
12
12
  throwError('Array index must be a non-negative integer', index);
13
13
  }
14
+ const idx = Math.trunc(num);
14
15
  if (idx >= VM_ARRAY_MAX_LENGTH) {
15
16
  throwError(`Array index exceeds maximum limit of ${VM_ARRAY_MAX_LENGTH}`, index);
16
17
  }
@@ -45,7 +46,7 @@ const withInner = (obj: VmConst | undefined, key: VmArray, keyIndex: number, val
45
46
  result[index] = withInner(result[index], key, keyIndex + 1, value);
46
47
  } else {
47
48
  const prop = toString(k, undefined);
48
- result[prop] = withInner(result[prop], key, keyIndex + 1, value);
49
+ setRecord(result, prop, withInner(result[prop], key, keyIndex + 1, value));
49
50
  }
50
51
  return result;
51
52
  };
@@ -109,12 +110,12 @@ const _with = VmLib(
109
110
  if (isVmArray(key)) {
110
111
  const firstKey = key[0]!;
111
112
  prop = toString(firstKey, undefined);
112
- val = withInner(result[prop], key, 1, value);
113
+ val = withInner(getRecord(result, prop), key, 1, value);
113
114
  } else {
114
115
  prop = toString(key, undefined);
115
116
  val = value;
116
117
  }
117
- result[prop] = val;
118
+ setRecord(result, prop, val);
118
119
  }
119
120
  return result;
120
121
  }
@@ -1,12 +1,13 @@
1
1
  import { display } from '../../../../helpers/serialize.js';
2
+ import { setRecord } from '../../../../helpers/utils.js';
2
3
  import { Cp } from '../../../checkpoint.js';
3
- import { isVmArray, type VmConst, type VmArray } from '../../../types/index.js';
4
+ import { isVmArray, type VmConst, type VmArray, type VmRecord } from '../../../types/index.js';
4
5
  import { VmLib, throwError } from '../../helpers.js';
5
6
  import { entries } from './entries.js';
6
7
 
7
8
  export const zip = VmLib(
8
9
  (data) => {
9
- const ets = entries(data);
10
+ const ets = entries(data) as Array<{ 0: string | number; 1: VmArray }>;
10
11
  let length = 0;
11
12
  for (const { 0: key, 1: arr } of ets) {
12
13
  if (!isVmArray(arr)) {
@@ -15,15 +16,25 @@ export const zip = VmLib(
15
16
  length = Math.max(length, arr.length);
16
17
  }
17
18
  if (length === 0) return [];
18
- const result: Array<Record<number | string, VmConst>> = [];
19
- const isArr = isVmArray(data);
20
- for (let i = 0; i < length; i++) {
21
- Cp();
22
- const obj: Record<number | string, VmConst> = isArr ? ([] as Record<number, VmConst>) : {};
23
- for (const { 0: key, 1: arr } of ets) {
24
- obj[key] = (arr as VmArray)[i] ?? null;
19
+ const result: Array<VmArray | VmRecord> = [];
20
+ if (isVmArray(data)) {
21
+ for (let i = 0; i < length; i++) {
22
+ Cp();
23
+ const obj: VmConst[] = [];
24
+ for (const { 0: key, 1: arr } of ets) {
25
+ obj[key as number] = arr[i] ?? null;
26
+ }
27
+ result.push(obj);
28
+ }
29
+ } else {
30
+ for (let i = 0; i < length; i++) {
31
+ Cp();
32
+ const obj: Record<string, VmConst> = {};
33
+ for (const { 0: key, 1: arr } of ets) {
34
+ setRecord(obj, key as string, arr[i]);
35
+ }
36
+ result.push(obj);
25
37
  }
26
- result.push(obj);
27
38
  }
28
39
  return result;
29
40
  },
@@ -1,5 +1,5 @@
1
1
  import { VM_ARRAY_MAX_LENGTH } from '../../helpers/constants.js';
2
- import { isNaN, NotNumber, entries, fromEntries, isSafeInteger, isFinite } from '../../helpers/utils.js';
2
+ import { NotNumber, entries, fromEntries, isSafeInteger, isFinite } from '../../helpers/utils.js';
3
3
  import { toBoolean, toNumber, toString } from '../../helpers/convert/index.js';
4
4
  import { display } from '../../helpers/serialize.js';
5
5
  import { isVmArray, isVmFunction, isVmPrimitive, isVmConst, isVmCallable, isVmRecord } from '../../helpers/types.js';
@@ -229,7 +229,7 @@ export function getNumbers(args: readonly VmAny[]): number[] {
229
229
 
230
230
  /** 将值转为数组长度 */
231
231
  export function arrayLen(len: number | null | undefined): number {
232
- if (len == null || isNaN(len) || len <= -1) {
232
+ if (len == null || !isFinite(len) || len <= -1) {
233
233
  throwError('Array length must be a non-negative integer', null);
234
234
  }
235
235
  len = Math.trunc(len);
@@ -240,10 +240,10 @@ export function arrayLen(len: number | null | undefined): number {
240
240
  }
241
241
 
242
242
  /** 应用映射函数 */
243
- export function map(
244
- data: VmConst,
243
+ export function iterate<T extends VmConst>(
244
+ data: T,
245
245
  /** 返回 `undefined` 表示跳过该元素 */
246
- mapper: (value: VmConst, index: number | string | null, data: VmConst) => VmConst | undefined,
246
+ mapper: (value: VmConst, index: number | string | null, data: T) => VmConst | undefined,
247
247
  ): VmConst {
248
248
  if (isVmPrimitive(data)) {
249
249
  return mapper(data, null, data) ?? null;
@@ -260,7 +260,7 @@ export function map(
260
260
  return result;
261
261
  } else {
262
262
  const e: Array<[string, VmConst]> = [];
263
- for (const [key, value] of entries(data)) {
263
+ for (const [key, value] of entries<string, VmConst | undefined>(data)) {
264
264
  Cp();
265
265
  const ret = mapper(value ?? null, key, data);
266
266
  if (ret === undefined) continue;
@@ -12,7 +12,7 @@ import {
12
12
  throwError,
13
13
  getNumbers,
14
14
  arrayLen,
15
- map,
15
+ iterate,
16
16
  expectInteger,
17
17
  } from '../helpers.js';
18
18
 
@@ -370,7 +370,7 @@ export const invert = VmLib(
370
370
  expectConst('a', a, null);
371
371
  const [rows, cols] = sizeImpl(a);
372
372
  if (rows == null) return 1 / num(a); // 标量取倒数
373
- if (cols == null) return map(a, (v) => 1 / num(v)); // 向量按元素取倒数
373
+ if (cols == null) return iterate(a, (v) => 1 / num(v)); // 向量按元素取倒数
374
374
 
375
375
  if (rows !== cols) throwError(`Matrix must be square`, a);
376
376
  const m = a as VmConst[][];
@@ -16,10 +16,12 @@ export const $ArrayRange = (start: VmAny, end: VmAny): VmArray => {
16
16
  const s = $ToNumber(start);
17
17
  const e = $ToNumber(end);
18
18
  if (isEmptyRange(s, e)) return [];
19
- assertArrayLength(e - s + 1);
19
+ const n = Math.floor(e - s + 1);
20
+ assertArrayLength(n);
20
21
  const arr = [];
21
- for (let i = s; i <= e; i++) {
22
- arr.push(i);
22
+ arr.length = n;
23
+ for (let i = 0; i < n; i++) {
24
+ arr[i] = s + i;
23
25
  }
24
26
  return arr;
25
27
  };
@@ -28,10 +30,12 @@ export const $ArrayRangeExclusive = (start: VmAny, end: VmAny): VmArray => {
28
30
  const s = $ToNumber(start);
29
31
  const e = $ToNumber(end);
30
32
  if (isEmptyRange(s, e)) return [];
31
- assertArrayLength(e - s);
33
+ const n = Math.ceil(e - s);
34
+ assertArrayLength(n);
32
35
  const arr = [];
33
- for (let i = s; i < e; i++) {
34
- arr.push(i);
36
+ arr.length = n;
37
+ for (let i = 0; i < n; i++) {
38
+ arr[i] = s + i;
35
39
  }
36
40
  return arr;
37
41
  };
@@ -1,5 +1,14 @@
1
1
  import { VmError } from '../../helpers/error.js';
2
- import { hasOwnEnumerable, NotNumber, keys, create, isFinite, keysLength } from '../../helpers/utils.js';
2
+ import {
3
+ hasOwnEnumerable,
4
+ NotNumber,
5
+ keys,
6
+ create,
7
+ isFinite,
8
+ keysLength,
9
+ getRecord,
10
+ setRecord,
11
+ } from '../../helpers/utils.js';
3
12
  import { toNumber, toString } from '../../helpers/convert/index.js';
4
13
  import { display } from '../../helpers/serialize.js';
5
14
  import {
@@ -63,8 +72,7 @@ export const $Omit = (value: VmAny, omitted: ReadonlyArray<number | string>): Vm
63
72
  const omittedSet = new Set(omitted.map($ToString));
64
73
  for (const key of valueKeys) {
65
74
  if (!omittedSet.has(key)) {
66
- /* c8 ignore next */
67
- result[key] = value[key] ?? null;
75
+ setRecord(result, key, value[key]);
68
76
  }
69
77
  }
70
78
  return result;
@@ -78,7 +86,7 @@ export const $Pick = (value: VmAny, picked: ReadonlyArray<number | string>): VmR
78
86
  for (const key of picked) {
79
87
  const k = $ToString(key);
80
88
  if (hasOwnEnumerable(value, k)) {
81
- result[k] = value[k] ?? null;
89
+ setRecord(result, k, value[k]);
82
90
  }
83
91
  }
84
92
  return result;
@@ -114,8 +122,7 @@ export const $Get = (obj: VmAny, key: VmAny): VmValue => {
114
122
  }
115
123
  return obj.get(pk) ?? null;
116
124
  }
117
- if (!hasOwnEnumerable(obj, pk)) return null;
118
- return $El(obj[pk] ?? null);
125
+ return $El(getRecord(obj, pk) ?? null);
119
126
  };
120
127
  /** 设置字段 */
121
128
  export const $Set = (obj: VmAny, key: VmAny, value: VmAny): void => {
@@ -140,7 +140,7 @@ export class VmExtern<const T extends object = object> extends VmWrapper<T> {
140
140
  override toString(useBraces: boolean): string {
141
141
  // eslint-disable-next-line @typescript-eslint/unbound-method
142
142
  const { toString } = this.value;
143
- if (typeof toString != 'function' || toString === ObjectToString || toString === FunctionToString) {
143
+ if (typeof toString !== 'function' || toString === ObjectToString || toString === FunctionToString) {
144
144
  // When the toString method is not overridden or invalid, provide a better default representation
145
145
  return super.toString(useBraces);
146
146
  }