@fileverse-dev/formulajs 4.4.16 → 4.4.17-fix-sort-fn-2
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/lib/browser/formula.js +73 -34
- package/lib/browser/formula.min.js +2 -2
- package/lib/browser/formula.min.js.map +1 -1
- package/lib/cjs/index.cjs +71 -39
- package/lib/esm/index.mjs +71 -39
- package/package.json +1 -1
package/lib/cjs/index.cjs
CHANGED
|
@@ -1271,47 +1271,74 @@ function ROWS(array) {
|
|
|
1271
1271
|
* @returns
|
|
1272
1272
|
*/
|
|
1273
1273
|
function SORT(array, sort_index = 1, sort_order = 1, by_col = false) {
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1274
|
+
console.log("SORT function called with arguments:", { array, sort_index, sort_order, by_col });
|
|
1275
|
+
if (!array || !Array.isArray(array)) return na;
|
|
1276
|
+
if (array.length === 0) return 0;
|
|
1277
1277
|
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1278
|
+
let idx = parseNumber(sort_index);
|
|
1279
|
+
if (!idx || idx < 1) return value;
|
|
1280
|
+
idx = idx - 1;
|
|
1281
1281
|
|
|
1282
|
-
|
|
1283
|
-
if (
|
|
1284
|
-
return value
|
|
1285
|
-
}
|
|
1282
|
+
let order = parseNumber(sort_order);
|
|
1283
|
+
if (order !== 1 && order !== -1) return value;
|
|
1286
1284
|
|
|
1287
|
-
|
|
1288
|
-
if (
|
|
1289
|
-
|
|
1290
|
-
|
|
1285
|
+
const byCol = parseBool(by_col);
|
|
1286
|
+
if (typeof byCol !== "boolean") return name;
|
|
1287
|
+
|
|
1288
|
+
// Rectangularize then orient
|
|
1289
|
+
const matrix = fillMatrix(array);
|
|
1290
|
+
const working = byCol ? transpose(matrix) : matrix;
|
|
1291
1291
|
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
return name
|
|
1292
|
+
if (!working.length || !working[0] || idx >= working[0].length) {
|
|
1293
|
+
return value; // out of bounds
|
|
1295
1294
|
}
|
|
1296
1295
|
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
a = parseString(a[sort_index - 1]);
|
|
1300
|
-
b = parseString(b[sort_index - 1]);
|
|
1296
|
+
// Helpers (aiming for spreadsheet-ish behavior)
|
|
1297
|
+
const isBlank = (v) => v === "" || v === null || v === undefined;
|
|
1301
1298
|
|
|
1302
|
-
|
|
1303
|
-
|
|
1299
|
+
const cmp = (a, b) => {
|
|
1300
|
+
// Blanks last (ascending); we'll multiply by order later for descending.
|
|
1301
|
+
const aBlank = isBlank(a);
|
|
1302
|
+
const bBlank = isBlank(b);
|
|
1303
|
+
if (aBlank && bBlank) return 0;
|
|
1304
|
+
if (aBlank) return 1;
|
|
1305
|
+
if (bBlank) return -1;
|
|
1304
1306
|
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
+
// If both parse as finite numbers, compare numerically
|
|
1308
|
+
const na = parseNumber(a);
|
|
1309
|
+
const nb = parseNumber(b);
|
|
1310
|
+
const aNum = Number.isFinite(na);
|
|
1311
|
+
const bNum = Number.isFinite(nb);
|
|
1307
1312
|
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
+
if (aNum && bNum) {
|
|
1314
|
+
if (na < nb) return -1;
|
|
1315
|
+
if (na > nb) return 1;
|
|
1316
|
+
return 0;
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
// Fallback: case-insensitive string compare
|
|
1320
|
+
const sa = (parseString(a) ?? "").toString().toLowerCase();
|
|
1321
|
+
const sb = (parseString(b) ?? "").toString().toLowerCase();
|
|
1322
|
+
if (sa < sb) return -1;
|
|
1323
|
+
if (sa > sb) return 1;
|
|
1324
|
+
return 0;
|
|
1325
|
+
};
|
|
1326
|
+
|
|
1327
|
+
// Stable sort: decorate with original index
|
|
1328
|
+
const decorated = working.map((row, i) => ({ row, i }));
|
|
1329
|
+
|
|
1330
|
+
decorated.sort((A, B) => {
|
|
1331
|
+
const base = cmp(A.row[idx], B.row[idx]);
|
|
1332
|
+
if (base !== 0) return base * order;
|
|
1333
|
+
// stable tiebreaker: original order
|
|
1334
|
+
return A.i - B.i;
|
|
1335
|
+
});
|
|
1336
|
+
|
|
1337
|
+
const sorted = decorated.map((d) => d.row);
|
|
1338
|
+
return byCol ? transpose(sorted) : sorted;
|
|
1313
1339
|
}
|
|
1314
1340
|
|
|
1341
|
+
|
|
1315
1342
|
/**
|
|
1316
1343
|
* Returns the transpose of an array.
|
|
1317
1344
|
*
|
|
@@ -18586,17 +18613,22 @@ const SUPPORTED_TOKEN_NAMES = {
|
|
|
18586
18613
|
|
|
18587
18614
|
|
|
18588
18615
|
function formatNumber(raw, decimals) {
|
|
18589
|
-
|
|
18616
|
+
try {
|
|
18617
|
+
if(!decimals){
|
|
18618
|
+
return raw
|
|
18619
|
+
}
|
|
18620
|
+
const quorum = BigInt(raw);
|
|
18621
|
+
const divisor = 10 ** decimals;
|
|
18622
|
+
const normalized = Number(quorum) / divisor;
|
|
18623
|
+
|
|
18624
|
+
return new Intl.NumberFormat("en-US", {
|
|
18625
|
+
notation: "compact",
|
|
18626
|
+
maximumFractionDigits: 2,
|
|
18627
|
+
}).format(normalized);
|
|
18628
|
+
} catch (error) {
|
|
18629
|
+
console.log({error});
|
|
18590
18630
|
return raw
|
|
18591
18631
|
}
|
|
18592
|
-
const quorum = BigInt(raw);
|
|
18593
|
-
const divisor = 10 ** decimals;
|
|
18594
|
-
const normalized = Number(quorum) / divisor;
|
|
18595
|
-
|
|
18596
|
-
return new Intl.NumberFormat("en-US", {
|
|
18597
|
-
notation: "compact",
|
|
18598
|
-
maximumFractionDigits: 2,
|
|
18599
|
-
}).format(normalized);
|
|
18600
18632
|
}
|
|
18601
18633
|
|
|
18602
18634
|
let cachedChains = null;
|
package/lib/esm/index.mjs
CHANGED
|
@@ -1269,47 +1269,74 @@ function ROWS(array) {
|
|
|
1269
1269
|
* @returns
|
|
1270
1270
|
*/
|
|
1271
1271
|
function SORT(array, sort_index = 1, sort_order = 1, by_col = false) {
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1272
|
+
console.log("SORT function called with arguments:", { array, sort_index, sort_order, by_col });
|
|
1273
|
+
if (!array || !Array.isArray(array)) return na;
|
|
1274
|
+
if (array.length === 0) return 0;
|
|
1275
1275
|
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1276
|
+
let idx = parseNumber(sort_index);
|
|
1277
|
+
if (!idx || idx < 1) return value;
|
|
1278
|
+
idx = idx - 1;
|
|
1279
1279
|
|
|
1280
|
-
|
|
1281
|
-
if (
|
|
1282
|
-
return value
|
|
1283
|
-
}
|
|
1280
|
+
let order = parseNumber(sort_order);
|
|
1281
|
+
if (order !== 1 && order !== -1) return value;
|
|
1284
1282
|
|
|
1285
|
-
|
|
1286
|
-
if (
|
|
1287
|
-
|
|
1288
|
-
|
|
1283
|
+
const byCol = parseBool(by_col);
|
|
1284
|
+
if (typeof byCol !== "boolean") return name;
|
|
1285
|
+
|
|
1286
|
+
// Rectangularize then orient
|
|
1287
|
+
const matrix = fillMatrix(array);
|
|
1288
|
+
const working = byCol ? transpose(matrix) : matrix;
|
|
1289
1289
|
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
return name
|
|
1290
|
+
if (!working.length || !working[0] || idx >= working[0].length) {
|
|
1291
|
+
return value; // out of bounds
|
|
1293
1292
|
}
|
|
1294
1293
|
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
a = parseString(a[sort_index - 1]);
|
|
1298
|
-
b = parseString(b[sort_index - 1]);
|
|
1294
|
+
// Helpers (aiming for spreadsheet-ish behavior)
|
|
1295
|
+
const isBlank = (v) => v === "" || v === null || v === undefined;
|
|
1299
1296
|
|
|
1300
|
-
|
|
1301
|
-
|
|
1297
|
+
const cmp = (a, b) => {
|
|
1298
|
+
// Blanks last (ascending); we'll multiply by order later for descending.
|
|
1299
|
+
const aBlank = isBlank(a);
|
|
1300
|
+
const bBlank = isBlank(b);
|
|
1301
|
+
if (aBlank && bBlank) return 0;
|
|
1302
|
+
if (aBlank) return 1;
|
|
1303
|
+
if (bBlank) return -1;
|
|
1302
1304
|
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
+
// If both parse as finite numbers, compare numerically
|
|
1306
|
+
const na = parseNumber(a);
|
|
1307
|
+
const nb = parseNumber(b);
|
|
1308
|
+
const aNum = Number.isFinite(na);
|
|
1309
|
+
const bNum = Number.isFinite(nb);
|
|
1305
1310
|
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
+
if (aNum && bNum) {
|
|
1312
|
+
if (na < nb) return -1;
|
|
1313
|
+
if (na > nb) return 1;
|
|
1314
|
+
return 0;
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
// Fallback: case-insensitive string compare
|
|
1318
|
+
const sa = (parseString(a) ?? "").toString().toLowerCase();
|
|
1319
|
+
const sb = (parseString(b) ?? "").toString().toLowerCase();
|
|
1320
|
+
if (sa < sb) return -1;
|
|
1321
|
+
if (sa > sb) return 1;
|
|
1322
|
+
return 0;
|
|
1323
|
+
};
|
|
1324
|
+
|
|
1325
|
+
// Stable sort: decorate with original index
|
|
1326
|
+
const decorated = working.map((row, i) => ({ row, i }));
|
|
1327
|
+
|
|
1328
|
+
decorated.sort((A, B) => {
|
|
1329
|
+
const base = cmp(A.row[idx], B.row[idx]);
|
|
1330
|
+
if (base !== 0) return base * order;
|
|
1331
|
+
// stable tiebreaker: original order
|
|
1332
|
+
return A.i - B.i;
|
|
1333
|
+
});
|
|
1334
|
+
|
|
1335
|
+
const sorted = decorated.map((d) => d.row);
|
|
1336
|
+
return byCol ? transpose(sorted) : sorted;
|
|
1311
1337
|
}
|
|
1312
1338
|
|
|
1339
|
+
|
|
1313
1340
|
/**
|
|
1314
1341
|
* Returns the transpose of an array.
|
|
1315
1342
|
*
|
|
@@ -18584,17 +18611,22 @@ const SUPPORTED_TOKEN_NAMES = {
|
|
|
18584
18611
|
|
|
18585
18612
|
|
|
18586
18613
|
function formatNumber(raw, decimals) {
|
|
18587
|
-
|
|
18614
|
+
try {
|
|
18615
|
+
if(!decimals){
|
|
18616
|
+
return raw
|
|
18617
|
+
}
|
|
18618
|
+
const quorum = BigInt(raw);
|
|
18619
|
+
const divisor = 10 ** decimals;
|
|
18620
|
+
const normalized = Number(quorum) / divisor;
|
|
18621
|
+
|
|
18622
|
+
return new Intl.NumberFormat("en-US", {
|
|
18623
|
+
notation: "compact",
|
|
18624
|
+
maximumFractionDigits: 2,
|
|
18625
|
+
}).format(normalized);
|
|
18626
|
+
} catch (error) {
|
|
18627
|
+
console.log({error});
|
|
18588
18628
|
return raw
|
|
18589
18629
|
}
|
|
18590
|
-
const quorum = BigInt(raw);
|
|
18591
|
-
const divisor = 10 ** decimals;
|
|
18592
|
-
const normalized = Number(quorum) / divisor;
|
|
18593
|
-
|
|
18594
|
-
return new Intl.NumberFormat("en-US", {
|
|
18595
|
-
notation: "compact",
|
|
18596
|
-
maximumFractionDigits: 2,
|
|
18597
|
-
}).format(normalized);
|
|
18598
18630
|
}
|
|
18599
18631
|
|
|
18600
18632
|
let cachedChains = null;
|