[project] remove the unnecessary pkg underscore

This commit is contained in:
Revone 2023-11-02 11:57:20 +08:00
parent ca013f019f
commit f0777567f2
9 changed files with 316 additions and 273 deletions

9
package-lock.json generated
View file

@ -36,8 +36,7 @@
"ts-node": "^10.9.1",
"tsup": "^7.2.0",
"typedoc": "^0.25.1",
"typescript": "^5.2.2",
"underscore": "^1.13.6"
"typescript": "^5.2.2"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@ -9034,12 +9033,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/underscore": {
"version": "1.13.6",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
"integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==",
"dev": true
},
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",

View file

@ -84,8 +84,7 @@
"ts-node": "^10.9.1",
"tsup": "^7.2.0",
"typedoc": "^0.25.1",
"typescript": "^5.2.2",
"underscore": "^1.13.6"
"typescript": "^5.2.2"
},
"keywords": [
"data",

View file

@ -1,4 +1,4 @@
import {Deque} from "../../../../src";
import {Deque} from '../../../../src';
import * as Benchmark from 'benchmark';
export const suite = new Benchmark.Suite();
@ -16,4 +16,4 @@ suite
deque.push(i);
deque.shift();
}
})
});

View file

@ -1,4 +1,4 @@
import {Queue} from "../../../../src";
import {Queue} from '../../../../src';
import * as Benchmark from 'benchmark';
@ -17,4 +17,4 @@ suite
queue.push(i);
queue.shift();
}
})
});

View file

@ -2,15 +2,17 @@ import * as Benchmark from 'benchmark';
import * as path from 'path';
import * as fs from 'fs';
import * as fastGlob from 'fast-glob';
import {numberFix, render} from "./utils";
import {numberFix, render} from './utils';
const reportDistPath = 'benchmark';
const testDir = path.join(__dirname, 'data-structures');
const testFiles = fastGlob.sync(path.join(testDir, '**', '*.test.ts'));
const report: { [key: string]: any } = {};
const report: {[key: string]: any} = {};
let testFileCount = 0, suiteCount = 0, completedCount = 0;
let testFileCount = 0,
suiteCount = 0,
completedCount = 0;
testFiles.forEach((file: string) => {
testFileCount++;
console.log(`testing file ${file}`);
@ -24,28 +26,30 @@ testFiles.forEach((file: string) => {
console.log(event.target.toString());
});
suite.on('complete', function (this: Benchmark.Suite) {
completedCount++;
console.log('Fastest is ' + this.filter('fastest').map('name'));
report[testName] = this.map((test: Benchmark) => ({
'test name': test.name,
'time consumption (ms)': numberFix((test.times.period * 1000), 2),
'executions per second': numberFix(test.hz, 2),
'executed times': numberFix(test.count, 2),
'sample arithmetic mean (secs)': numberFix(test.stats.mean, 2),
'sample deviation': numberFix(test.stats.deviation, 2),
}));
suite
.on('complete', function (this: Benchmark.Suite) {
completedCount++;
console.log('Fastest is ' + this.filter('fastest').map('name'));
report[testName] = this.map((test: Benchmark) => ({
'test name': test.name,
'time consumption (ms)': numberFix(test.times.period * 1000, 2),
'executions per second': numberFix(test.hz, 2),
'executed times': numberFix(test.count, 2),
'sample arithmetic mean (secs)': numberFix(test.stats.mean, 2),
'sample deviation': numberFix(test.stats.deviation, 2)
}));
// report[testName] = this;
console.log(
`test file count: ${testFileCount}. suite count: ${suiteCount}. completed suite count: ${completedCount}`
);
if (completedCount === suiteCount) {
if (!fs.existsSync(reportDistPath)) fs.mkdirSync(reportDistPath, {recursive: true});
// report[testName] = this;
console.log(`test file count: ${testFileCount}. suite count: ${suiteCount}. completed suite count: ${completedCount}`)
if (completedCount === suiteCount) {
if (!fs.existsSync(reportDistPath)) fs.mkdirSync(reportDistPath, {recursive: true});
const filePath = path.join(reportDistPath, 'report.json');
const htmlFilePath = path.join(reportDistPath, 'report.html');
fs.writeFileSync(filePath, JSON.stringify(report, null, 2));
let html = `<!DOCTYPE html>
const filePath = path.join(reportDistPath, 'report.json');
const htmlFilePath = path.join(reportDistPath, 'report.html');
fs.writeFileSync(filePath, JSON.stringify(report, null, 2));
let html = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
@ -76,32 +80,32 @@ testFiles.forEach((file: string) => {
</style>
</head>
<body>
<div id="j2h">`
for (const r in report) {
if (report.hasOwnProperty(r)) {
html += render(report[r], {
'<>': 'table',
'html': [
{
'<>': 'tr',
'html': [
{'<>': 'td', 'html': '${name}'},
{'<>': 'td', 'html': '${periodMS}'},
{'<>': 'td', 'html': '${mean}'}
]
}
]
});
<div id="json-to-html">`;
for (const r in report) {
if (report.hasOwnProperty(r)) {
html += render(report[r], {
'<>': 'table',
html: [
{
'<>': 'tr',
html: [
{'<>': 'td', html: '${name}'},
{'<>': 'td', html: '${periodMS}'},
{'<>': 'td', html: '${mean}'}
]
}
]
});
}
}
}
html += `</div>
html += `</div>
</body>
</html>`;
fs.writeFileSync(htmlFilePath, html);
console.log('Performance test report file generated')
}
})
fs.writeFileSync(htmlFilePath, html);
console.log('Performance test report file generated');
}
})
.run({async: true});
}
});
});

View file

@ -1,2 +1,3 @@
export * from './json2html';
export * from './number';
export * from './number';
export * from './is';

View file

@ -0,0 +1,56 @@
export const isNumber = (value: any) => {
return typeof value === 'number';
};
export const isString = (value: any) => {
return typeof value === 'string';
};
export const isBoolean = (value: any) => {
return typeof value === 'boolean';
};
export const isDate = (value: any) => {
return value instanceof Date;
};
export const isNull = (value: any) => {
return value === null;
};
export const isUndefined = (value: any) => {
return typeof value === 'undefined';
};
export const isFunction = (value: any) => {
return typeof value === 'function';
};
export const isObject = (value: any) => {
return typeof value === 'object';
};
export const isArray = (value: any) => {
return Array.isArray(value);
};
export const isEqual = (objA: any, objB: any): boolean => {
if (objA === objB) {
return true;
}
if (typeof objA !== 'object' || typeof objB !== 'object' || objA === null || objB === null) {
return false;
}
const keysA = Object.keys(objA);
const keysB = Object.keys(objB);
if (keysA.length !== keysB.length) {
return false;
}
for (const key of keysA) {
if (!keysB.includes(key)) {
return false;
}
if (!isEqual(objA[key], objB[key])) {
return false;
}
}
return true;
};

View file

@ -1,43 +1,38 @@
import * as _ from "underscore";
import * as _ from './is';
function toggleJS(options?: { plainHtml?: boolean }): string {
function toggleJS(options?: {plainHtml?: boolean}): string {
if (options?.plainHtml) {
return "";
return '';
} else {
return "onclick=\"j2h.toggleVisibility(this);return false\"";
return 'onclick="json-to-html.toggleVisibility(this);return false"';
}
}
function makeLabelDiv(
options: any,
level: number,
keyname: string | number,
datatype?: string
): string {
if (typeof keyname === "number") {
return `<div class='index'><span class='j2h-label'>${keyname}&nbsp;</span></div>`;
} else if (typeof keyname === "string") {
if (datatype === "array") {
function makeLabelDiv(options: any, level: number, keyname: string | number, datatype?: string): string {
if (typeof keyname === 'number') {
return `<div class='index'><span class='json-to-html-label'>${keyname}&nbsp;</span></div>`;
} else if (typeof keyname === 'string') {
if (datatype === 'array') {
return `<div class='collapsible level${level}' ${toggleJS(
options
)}><span class='j2h-label'>${keyname}</span></div>`;
} else if (datatype === "object") {
)}><span class='json-to-html-label'>${keyname}</span></div>`;
} else if (datatype === 'object') {
return `<div class='attribute collapsible level${level}' ${toggleJS(
options
)}><span class='j2h-label'>${keyname}:</span></div>`;
)}><span class='json-to-html-label'>${keyname}:</span></div>`;
} else {
return `<div class='leaf level${level}'><span class='j2h-label'>${keyname}:</span></div>`;
return `<div class='leaf level${level}'><span class='json-to-html-label'>${keyname}:</span></div>`;
}
} else {
return "";
return '';
}
}
function getContentClass(keyname: string | number): string {
if (typeof keyname === "string") {
return "content";
if (typeof keyname === 'string') {
return 'content';
} else {
return "";
return '';
}
}
@ -63,7 +58,7 @@ function isLeafValue(val: any): boolean {
_.isDate(val) ||
_.isNull(val) ||
_.isUndefined(val) ||
_.isNaN(val) ||
isNaN(val) ||
_.isFunction(val) ||
!isPlainObject(val)
);
@ -89,12 +84,12 @@ function isTable(arr: any[]): boolean {
if (arr.length === 0 || !_.isObject(arr[0])) {
return false;
} else {
let nonCompliant = _.detect(arr, (row) => !isLeafObject(row));
let nonCompliant = arr.find(row => !isLeafObject(row));
if (nonCompliant) {
return false;
} else {
const cols = _.keys(arr[0]);
nonCompliant = _.detect(arr, (row: object) => !_.isEqual(cols, _.keys(row)));
const cols = Object.keys(arr[0]);
nonCompliant = arr.find((row: object) => !_.isEqual(cols, Object.keys(row)));
if (nonCompliant) {
return false;
} else {
@ -106,65 +101,61 @@ function isTable(arr: any[]): boolean {
function drawTable(arr: any[]): string {
function drawRow(headers: string[], rowObj: any): string {
return (
"<td>" +
headers.map((header) => rowObj[header]).join("</td><td>") +
"</td>"
);
return '<td>' + headers.map(header => rowObj[header]).join('</td><td>') + '</td>';
}
const cols = _.keys(arr[0]);
const content = arr.map((rowObj) => drawRow(cols, rowObj));
const headingHtml = "<tr><th>" + cols.join("</th><th>") + "</th></tr>";
const contentHtml = "<tr>" + content.join("</tr><tr>") + "</tr>";
return "<table>" + headingHtml + contentHtml + "</table>";
const cols = Object.keys(arr[0]);
const content = arr.map(rowObj => drawRow(cols, rowObj));
const headingHtml = '<tr><th>' + cols.join('</th><th>') + '</th></tr>';
const contentHtml = '<tr>' + content.join('</tr><tr>') + '</tr>';
return '<table>' + headingHtml + contentHtml + '</table>';
}
function _render(
name: string,
data: any,
options: any,
level: number,
altrow: number
): string {
function _render(name: string, data: any, options: any, level: number, altrow: number): string {
const contentClass = getContentClass(name);
if (_.isArray(data)) {
const title = makeLabelDiv(options, level, `${name} (${data.length})`, "array");
const title = makeLabelDiv(options, level, `${name} (${data.length})`, 'array');
let subs: string;
if (isTable(data)) {
subs = drawTable(data);
} else {
subs = "<div class='altRows'>" + data
.map((val: any, idx: number) => _render(idx.toString(), val, options, level + 1, idx % 2))
.join("</div><div class='altRows'>") + "</div>";
subs =
"<div class='altRows'>" +
data
.map((val: any, idx: number) => _render(idx.toString(), val, options, level + 1, idx % 2))
.join("</div><div class='altRows'>") +
'</div>';
}
return `<div class="j2h-collapse clearfix ${altrow}">
return `<div class="json-to-html-collapse clearfix ${altrow}">
${title}
<div class="${contentClass}">${subs}</div>
</div>`;
} else if (isLeafValue(data)) {
const title = makeLabelDiv(options, level, name);
if (_.isFunction(data)) {
return `${title}<span class='j2h-value'>&nbsp;&nbsp;-function() can't _render-</span>`;
return `${title}<span class='json-to-html-value'>&nbsp;&nbsp;-function() can't _render-</span>`;
} else if (!isPlainObject(data)) {
if (_.isFunction(data.toString)) {
return `${title}<span class='j2h-value'>&nbsp;&nbsp;${data.toString()}</span>`;
return `${title}<span class='json-to-html-value'>&nbsp;&nbsp;${data.toString()}</span>`;
} else {
return `${title}<span class='j2h-value'>&nbsp;&nbsp;-instance object, can't render-</span>`;
return `${title}<span class='json-to-html-value'>&nbsp;&nbsp;-instance object, can't render-</span>`;
}
} else {
return `${title}<span class='j2h-value'>&nbsp;&nbsp;${data}</span>`;
return `${title}<span class='json-to-html-value'>&nbsp;&nbsp;${data}</span>`;
}
} else {
const title = makeLabelDiv(options, level, name, "object");
const title = makeLabelDiv(options, level, name, 'object');
let count = 0;
const subs = "<div>" + Object.entries(data)
.map(([key, val]) => _render(key, val, options, level + 1, count++ % 2))
.join("</div><div>") + "</div>";
const inner = `<div class="j2h-expand clearfix ${altrow}">
const subs =
'<div>' +
Object.entries(data)
.map(([key, val]) => _render(key, val, options, level + 1, count++ % 2))
.join('</div><div>') +
'</div>';
const inner = `<div class="json-to-html-expand clearfix ${altrow}">
${title}
<div class="${contentClass}">${subs}</div>
</div>`;
return `${level === 0 ? '<div id=\'j2h\'>' : ''}
return `${level === 0 ? "<div id='json-to-html'>" : ''}
${inner}
${level === 0 ? '</div>' : ''}`;
}
@ -175,155 +166,155 @@ export function render(json: any, options: any): string {
return `${_render('', json, options, 0, 0)}`;
}
const head = `<style>
#j2h table {
border-collapse: collapse;
}
#j2h th {
color: #888;
}
#j2h table,th, td {
border: 1px solid #DDD;
padding: 10px 5px;
}
#j2h th, td {
text-align: center;
}
#j2h .content {
padding-left: 30px;
font-family: Arial;
}
#j2h .index {
font-size: 100%;
color: #999;
float: left;
}
#j2h .clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
#j2h .j2h-label {
font-family: Helvetica Neue;
color: #333;
}
#j2h .j2h-value {
font-family: Arial;
color: #777;
}
#j2h .collapsible > .j2h-label:hover {
text-decoration: underline;
}
#j2h .collapsible > .j2h-label {
color: #15C;
}
#j2h .j2h-collapse > div.content {
display: none;
}
#j2h .j2h-collapse > .j2h-label {
font-weight: bold;
}
#j2h .j2h-expand > div > .j2h-label, #j2h .j2h-collapse > div > .j2h-label {
background-repeat: no-repeat;
background-position: left;
padding-left: 25px;
margin: 5px 0px 5px 15px;
display: inline-block;
}
#j2h .j2h-expand > div > .j2h-label {
width: 30px;
height: 30px;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><polygon points="50,10 10,90 90,90" fill="blue" /></svg>');
background-size: cover;
background-position: center;
}
#j2h .j2h-collapse > div > .j2h-label {
width: 30px;
height: 30px;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><polygon points="50,10 10,90 90,90" fill="blue" /></svg>');
background-size: cover;
background-position: center;
}
#j2h .j2h-collapse > span.collapsible:before {
border-radius: 2px;
border-color: #A44;
border-style: solid;
border-width: 1px;
color: #A44;
content: '+';
display: inline-block;
line-height: 7px;
margin: 0 2px;
overflow: hidden;
padding: 1px;
font-size: 11px;
}
#j2h .j2h-expand > span.collapsible:before {
border: none;
color: #A44;
content: '-';
display: inline-block;
line-height: 7px;
margin: 4px;
overflow: hidden;
padding: 1px;
font-size: 11px;
}
#j2h.level0 {
font-size: 25px;
}
#j2h .level1 {
font-size: 22px;
}
#j2h .leaf {
color: #666;
display: inline;
}
#j2h .altRows:nth-child(odd) { background-color:#ddd; }
#j2h .altRows:nth-child(even) { background-color:#fff; }
#j2h tr:nth-child(odd) { background-color:#eee; }
#j2h tr:nth-child(even) { background-color:#fff; }
</style>
<script type="text/javascript">
j2h = {
toggleVisibility: function(el, name) {
j2h.toggleClass(el.parentElement,'j2h-collapse j2h-expand');
},
classRe: function(name) {
return new RegExp('(?:^|\\s)'+name+'(?!\\S)');
},
addClass: function(el, name) {
el.className += " "+name;
},
removeClass: function(el, name) {
var re = j2h.classRe(name);
el.className = el.className.replace(j2h.classRe(name) , '' )
},
hasClass: function(el, name) {
var re = j2h.classRe(name);
return j2h.classRe(name).exec(el.className);
},
toggleClass: function(el, name) {
var names = name.split(/\s+/);
for (n in names) {
if (j2h.hasClass(el, names[n])) {
j2h.removeClass(el, names[n]);
} else {
j2h.addClass(el, names[n]);
}
}
}
};
</script>`;
// const head = `<style>
// #json-to-html table {
// border-collapse: collapse;
// }
// #json-to-html th {
// color: #888;
// }
// #json-to-html table,th, td {
// border: 1px solid #DDD;
// padding: 10px 5px;
// }
// #json-to-html th, td {
// text-align: center;
// }
// #json-to-html .content {
// padding-left: 30px;
// font-family: Arial;
// }
//
// #json-to-html .index {
// font-size: 100%;
// color: #999;
// float: left;
// }
// #json-to-html .clearfix:after {
// content: ".";
// display: block;
// height: 0;
// clear: both;
// visibility: hidden;
// }
// #json-to-html .json-to-html-label {
// font-family: Helvetica Neue;
// color: #333;
// }
// #json-to-html .json-to-html-value {
// font-family: Arial;
// color: #777;
// }
// #json-to-html .collapsible > .json-to-html-label:hover {
// text-decoration: underline;
// }
// #json-to-html .collapsible > .json-to-html-label {
// color: #15C;
// }
// #json-to-html .json-to-html-collapse > div.content {
// display: none;
// }
// #json-to-html .json-to-html-collapse > .json-to-html-label {
// font-weight: bold;
// }
//
// #json-to-html .json-to-html-expand > div > .json-to-html-label, #json-to-html .json-to-html-collapse > div > .json-to-html-label {
// background-repeat: no-repeat;
// background-position: left;
// padding-left: 25px;
// margin: 5px 0px 5px 15px;
// display: inline-block;
// }
//
// #json-to-html .json-to-html-expand > div > .json-to-html-label {
// width: 30px;
// height: 30px;
// background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><polygon points="50,10 10,90 90,90" fill="blue" /></svg>');
// background-size: cover;
// background-position: center;
// }
//
// #json-to-html .json-to-html-collapse > div > .json-to-html-label {
// width: 30px;
// height: 30px;
// background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><polygon points="50,10 10,90 90,90" fill="blue" /></svg>');
// background-size: cover;
// background-position: center;
// }
//
// #json-to-html .json-to-html-collapse > span.collapsible:before {
// border-radius: 2px;
// border-color: #A44;
// border-style: solid;
// border-width: 1px;
// color: #A44;
// content: '+';
// display: inline-block;
// line-height: 7px;
// margin: 0 2px;
// overflow: hidden;
// padding: 1px;
// font-size: 11px;
// }
//
// #json-to-html .json-to-html-expand > span.collapsible:before {
// border: none;
// color: #A44;
// content: '-';
// display: inline-block;
// line-height: 7px;
// margin: 4px;
// overflow: hidden;
// padding: 1px;
// font-size: 11px;
// }
//
// #json-to-html.level0 {
// font-size: 25px;
// }
// #json-to-html .level1 {
// font-size: 22px;
// }
//
// #json-to-html .leaf {
// color: #666;
// display: inline;
// }
//
// #json-to-html .altRows:nth-child(odd) { background-color:#ddd; }
// #json-to-html .altRows:nth-child(even) { background-color:#fff; }
//
// #json-to-html tr:nth-child(odd) { background-color:#eee; }
// #json-to-html tr:nth-child(even) { background-color:#fff; }
// </style>
// <script type="text/javascript">
// json-to-html = {
// toggleVisibility: function(el, name) {
// json-to-html.toggleClass(el.parentElement,'json-to-html-collapse json-to-html-expand');
// },
// classRe: function(name) {
// return new RegExp('(?:^|\\s)'+name+'(?!\\S)');
// },
// addClass: function(el, name) {
// el.className += " "+name;
// },
// removeClass: function(el, name) {
// var re = json-to-html.classRe(name);
// el.className = el.className.replace(json-to-html.classRe(name) , '' )
// },
// hasClass: function(el, name) {
// var re = json-to-html.classRe(name);
// return json-to-html.classRe(name).exec(el.className);
// },
// toggleClass: function(el, name) {
// var names = name.split(/\s+/);
// for (n in names) {
// if (json-to-html.hasClass(el, names[n])) {
// json-to-html.removeClass(el, names[n]);
// } else {
// json-to-html.addClass(el, names[n]);
// }
// }
// }
// };
// </script>`;

View file

@ -1,5 +1,4 @@
export function numberFix(number: number, decimalPlaces: number): string {
if (number > 10000 || number < 0.001) {
const [mantissa, exponent] = number.toExponential().split('e');
const formattedMantissa = Number(mantissa).toFixed(decimalPlaces);
@ -7,4 +6,4 @@ export function numberFix(number: number, decimalPlaces: number): string {
} else {
return number.toFixed(decimalPlaces);
}
}
}