xshell 0.0.9 → 0.0.13

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/server.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["server.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer as create_server } from 'http'\nimport type { Server as HttpServer, IncomingHttpHeaders } from 'http'\n\nimport zlib from 'zlib'\n\n// --- 3-rd party\nimport invoke from 'lodash/invoke'\nimport qs from 'qs'\n\n\n// --- Koa & Koa Middleware\nimport Koa from 'koa'\nimport type { Context, Next } from 'koa'\n\nimport KoaCors from '@koa/cors'\nimport KoaCompress from 'koa-compress'\nimport { userAgent as KoaUserAgent } from 'koa-useragent'\n\n\ndeclare module 'koa' {\n interface Request {\n _path: string\n body: any\n }\n \n interface Context {\n compress: boolean\n }\n}\n\n// --- My Lib\nimport { request as _request } from './net'\nimport { stream_to_buffer, delay, log_section, inspect } from './utils'\n\n\ndeclare module 'http' {\n interface IncomingMessage {\n tunnel?: boolean\n id?: string\n body?: Buffer\n }\n \n interface ServerResponse {\n body?: Buffer\n }\n}\n\ninterface Message {\n id: string\n headers: IncomingHttpHeaders\n body: {\n buffer: Buffer\n }\n}\n\n// ------------ CONSTs\nexport const LOCALHOST_IPS = new Set(['127.0.0.1', '::ffff:127.0.0.1', '::1'])\nexport const ROUTER_IP = '192.168.1.1'\nexport const PHONE_IP = '192.168.1.113'\nexport const KNOWN_IPS = new Set([...LOCALHOST_IPS, ROUTER_IP, PHONE_IP])\n\n\n// ------------ MyServer\nexport const server = {\n app: null as Koa,\n \n handler: null as ReturnType<Koa['callback']>,\n \n server_80: null as HttpServer,\n \n \n /** start http server and listen */\n async start () {\n let app = new Koa()\n app.on('error', (error, ctx) => {\n console.error(error)\n console.log(ctx)\n })\n \n app.use(this.entry.bind(this))\n \n app.use(KoaCompress({\n br: {\n // https://nodejs.org/api/zlib.html#zlib_class_brotlioptions\n params: {\n [zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT,\n [zlib.constants.BROTLI_PARAM_QUALITY]: 6 // default 11 (maximized compression), may lead to news/get generated 14MB JSON taking 24s\n },\n },\n threshold: 512\n }))\n \n app.use(KoaCors({ credentials: true }))\n app.use(KoaUserAgent)\n \n app.use(this.router.bind(this))\n \n this.app = app\n \n await this.listen()\n },\n \n \n async listen () {\n this.handler = this.app.callback()\n this.server_80 = create_server(this.handler)\n \n await Promise.all([\n new Promise<void>( resolve => { this.server_80.listen(8421, resolve) }),\n ])\n },\n \n \n stop () {\n this.server_80.close()\n },\n \n \n async entry (ctx: Context, next: Next) {\n const { req: { tunnel, id }, res } = ctx\n let { req, request } = ctx\n \n if (!tunnel) {\n const buf = await stream_to_buffer(req)\n if (buf.length)\n req.body = buf\n }\n \n // ------------ parse req.body to request.body\n if (req.body)\n if (ctx.is('application/json') || ctx.is('text/plain'))\n request.body = JSON.parse(req.body.toString())\n else if (ctx.is('application/x-www-form-urlencoded'))\n request.body = qs.parse(req.body.toString())\n else if (ctx.is('multipart/form-data')) {\n throw new Error('multipart/form-data is not supported')\n } else\n request.body = req.body\n \n \n // ------------ parse request.ip\n request.ip = (request.headers['x-real-ip'] as string || request.ip).replace(/^::ffff:/, '')\n \n \n // ------------ next\n await next()\n // ------------ post processing\n },\n \n \n \n async router (ctx: Context, next: Next) {\n let { request, response } = ctx\n request.path\n request._path = decodeURIComponent(request.path)\n Object.defineProperty(request, 'path', {\n value: request._path,\n configurable: true,\n enumerable: true,\n writable: true\n })\n \n const { path } = request\n \n // ------------ RPC\n if (path === '/api/rpc') {\n await this.rpc(ctx)\n return\n }\n \n \n // ------------ log\n this.logger(ctx)\n \n await next?.()\n },\n \n \n /** args are array http://127.0.0.1/repl/rpc?func=to_json&args=aaa&args=bbb \n should use POST when arg is number, otherwise type will be string \n queries:\n - func: function name\n - args?: `[]` args array\n - async?: `false` don't wait\n - ignore?: `false` don't serialize result into response\n */\n async rpc (ctx: Context) {\n const { request: { query, body }, response } = ctx\n \n let { func, args = [], ignore = false, async: _async = false }: { func: string, args: any[] | string, ignore: boolean | string, async: boolean | string } = { ...query, ...body }\n \n if (!func) throw new Error('rpc no func')\n \n if (!Array.isArray(args))\n args = [args]\n \n // ?async=1 or ?async=0 or ?async=false\n if (typeof ignore === 'string')\n ignore = ignore.to_bool()\n \n if (typeof _async === 'string')\n _async = _async.to_bool()\n \n try {\n const presult = invoke(global, func, ...args)\n \n if (_async) {\n response.body = ''\n return\n }\n \n const result = await presult\n \n if (ignore) {\n response.body = ''\n return\n }\n \n response.body = JSON.stringify(result) || ''\n } catch (error) {\n response.status = 500\n response.body = error\n throw error\n }\n },\n \n \n logger (ctx: Context) {\n const { request } = ctx\n const { query, body, path, method, req: { httpVersion, tunnel }, ip } = request\n \n const known = KNOWN_IPS.has(ip)\n const ua = ctx.userAgent\n \n let s = ''\n \n // --- time\n s += new Date().to_time_str() + ' '\n \n \n let t: string\n // --- IP 50\n if (known)\n if (LOCALHOST_IPS.has(ip))\n t = ''\n else if (ip === ROUTER_IP)\n t = 'Router'.grey\n else if (ip === PHONE_IP)\n t = 'Phone'\n else\n t = ip\n else\n t = ip\n \n s += t.pad(50) + ' '\n \n \n // --- UA\n t = ''\n if (!known) {\n if (ua.isMobile)\n t += ' Mobile'.magenta\n if (ua.isBot)\n t += ' Robot'.blue\n if (ua.isDesktop)\n t += ' Desktop'\n if (ua.platform !== 'unknown' && !ua.os.startsWith('Windows'))\n t += '/' + ua.platform\n if (ua.os !== 'unknown' && ua.platform !== 'Android')\n t += '/' + ua.os\n if (ua.browser !== 'unknown')\n t += '/' + ua.browser\n if (ua.version !== 'unknown')\n t += '/' + ua.version\n }\n s += t.pad(50) + ' '\n \n \n // --- Tunnel/HTTP version\n s += tunnel ? \n ('Tunnel/' + httpVersion).pad(10).cyan\n :\n ('HTTP/' + httpVersion).pad(10)\n \n s += ' '\n \n \n // --- Method 8\n if (method === 'GET')\n t = method\n else\n t = method.red\n \n s += t.pad(8)\n \n \n // --- Path 60\n if (path.toLowerCase() !== request._path.toLowerCase())\n t = request._path.blue + ' → ' + path\n else\n if (!path.includes('.'))\n t = path.yellow\n else\n t = path\n \n s += t.pad(60) + ' '\n \n \n // --- Query\n if (query && Object.keys(query).length) {\n t = ` ${inspect(query, { compact: true }).replace('[Object: null prototype] ', '')}`\n if ((s + t).width > global.WIDTH)\n s += '\\n'\n s += t\n }\n \n \n // --- Body\n if (body && Object.keys(body).length)\n s += '\\n' + inspect(body).replace('[Object: null prototype] ', '')\n \n \n console.log(s)\n },\n}\n\n\nexport default server\n\nexport type Server = typeof server\n"]}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["server.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer as http_create_server } from 'http'\nimport type { Server as HttpServer, IncomingHttpHeaders } from 'http'\n\nimport zlib from 'zlib'\n\n// --- 3rd party\nimport invoke from 'lodash/invoke'\nimport qs from 'qs'\n\n\n// --- koa & koa middleware\nimport Koa from 'koa'\nimport type { Context, Next } from 'koa'\n\nimport KoaCors from '@koa/cors'\nimport KoaCompress from 'koa-compress'\nimport { userAgent as KoaUserAgent } from 'koa-useragent'\nimport type { UserAgentContext } from 'koa-useragent'\n\n\ndeclare module 'koa' {\n interface Request {\n _path: string\n body: any\n }\n \n interface Context {\n compress: boolean\n userAgent: UserAgentContext['userAgent'] & { isWechat: boolean }\n }\n}\n\n// --- my libs\nimport { request as _request } from './net'\nimport { stream_to_buffer, inspect } from './utils'\nimport { output_width } from './utils'\n\n\ndeclare module 'http' {\n interface IncomingMessage {\n tunnel?: boolean\n id?: string\n body?: Buffer\n }\n \n interface ServerResponse {\n body?: Buffer\n }\n}\n\ninterface Message {\n id: string\n headers: IncomingHttpHeaders\n body: {\n buffer: Buffer\n }\n}\n\n// ------------ my server\nexport const server = {\n app: null as Koa,\n \n handler: null as ReturnType<Koa['callback']>,\n \n server_80: null as HttpServer,\n \n \n /** start http server and listen */\n async start () {\n // --- init koa app\n let app = new Koa()\n \n app.on('error', (error, ctx) => {\n console.error(error)\n console.log(ctx)\n })\n \n app.use(\n this.entry.bind(this)\n )\n \n app.use(KoaCompress({\n br: {\n // https://nodejs.org/api/zlib.html#zlib_class_brotlioptions\n params: {\n [zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT,\n [zlib.constants.BROTLI_PARAM_QUALITY]: 6 // default 11 (maximized compression), may lead to news/get generated 14mb json taking 24s\n },\n },\n threshold: 512\n }))\n \n app.use(\n KoaCors({ credentials: true })\n )\n app.use(KoaUserAgent)\n \n app.use(this.router.bind(this))\n \n this.app = app\n \n this.handler = this.app.callback()\n \n this.server_80 = http_create_server(this.handler)\n \n await new Promise<void>(resolve => {\n this.server_80.listen(8421, resolve)\n })\n },\n \n \n stop () {\n this.server_80.close()\n },\n \n \n async entry (ctx: Context, next: Next) {\n let { response } = ctx\n \n await this.parse(ctx)\n \n // ------------ next\n try {\n await next()\n } catch (error) {\n if (error.status !== 404)\n console.error(error)\n response.status = error.status || 500\n response.body = inspect(error, { colors: false })\n response.type = 'text/plain'\n }\n },\n \n \n /** \n parse req.body to request.body \n process request.ip\n */\n async parse (ctx: Context) {\n const {\n request,\n req,\n req: { tunnel },\n } = ctx\n \n if (!tunnel) {\n const buf = await stream_to_buffer(req)\n if (buf.length)\n req.body = buf\n }\n \n // --- parse request.ip\n request.ip = (request.headers['x-real-ip'] as string || request.ip).replace(/^::ffff:/, '')\n \n \n // --- parse body\n if (!req.body) return\n \n if (ctx.is('application/json') || ctx.is('text/plain'))\n request.body = JSON.parse(req.body.toString())\n else if (ctx.is('application/x-www-form-urlencoded'))\n request.body = qs.parse(req.body.toString())\n else if (ctx.is('multipart/form-data')) {\n throw new Error('multipart/form-data is not supported')\n } else\n request.body = req.body\n },\n \n \n async router (ctx: Context, next: Next) {\n let { request } = ctx\n const _path = request._path = decodeURIComponent(request.path)\n Object.defineProperty(request, 'path', {\n value: _path,\n configurable: true,\n enumerable: true,\n writable: true\n })\n \n const { path } = request\n \n // ------------ /repl/rpc\n if (path === '/api/rpc') {\n await this.rpc(ctx)\n return\n }\n \n \n // ------------ log\n this.logger(ctx)\n \n // ------------ repl_router hook\n if (await global.repl_router?.(ctx))\n return\n \n await next?.()\n },\n \n \n /** args are array http://localhost/repl/rpc?func=to_json&args=aaa&args=bbb \n should use POST when arg is number, otherwise type will be string \n queries:\n - func: function name\n - args?: `[]` args array\n - ignore?: `false` don't serialize result into response\n - async?: `false` don't wait\n */\n async rpc (ctx: Context) {\n const { request: { query, body }, response } = ctx\n \n let { func, args = [], ignore = false, async: _async = false }: { func: string, args: any[] | string, ignore: boolean | string, async: boolean | string } = { ...query, ...body }\n \n if (!func) {\n let error = new Error('rpc no func')\n ;(error as any).status = 400\n throw error\n }\n \n if (!Array.isArray(args))\n args = [args]\n \n // ?async=1 or ?async=0 or ?async=false\n if (typeof ignore === 'string')\n ignore = ignore.to_bool()\n \n if (typeof _async === 'string')\n _async = _async.to_bool()\n \n try {\n const presult = invoke(global, func, ...args)\n \n if (_async) {\n response.body = ''\n return\n }\n \n const result = await presult\n \n if (ignore) {\n response.body = ''\n return\n }\n \n response.body = JSON.stringify(result) || ''\n } catch (error) {\n error.status = 500\n throw error\n }\n },\n \n \n logger (ctx: Context) {\n const { request } = ctx\n const {\n query, \n body, \n path, _path, \n protocol,\n host,\n req: { httpVersion: http_version },\n ip,\n } = request\n \n let { method } = request\n \n const ua = ctx.userAgent\n \n \n let s = ''\n \n // --- time\n s += `${new Date().to_time_str()} `\n \n \n // --- ip\n s += (ip || '').pad(40) + ' '\n \n \n // --- ua\n s += (() => {\n let t = ''\n if (ua.isMobile)\n t += 'mobile'\n if (ua.isDesktop)\n t += 'desktop'\n if (ua.isBot)\n t += `${ t ? ' ' : '' }${'robot'.blue}`\n if (ua.platform !== 'unknown' && !ua.os.startsWith('Windows'))\n t += '/' + ua.platform.toLowerCase().replace('apple mac', 'mac')\n if (ua.os !== 'unknown' && ua.platform !== 'Android')\n t += '/' + ua.os.toLowerCase()\n if (ua.browser !== 'unknown')\n t += '/' + ua.browser.toLowerCase()\n if (ua.isWechat)\n t += '/weixin'\n if (ua.version !== 'unknown')\n t += '/' + ua.version.split('.').slice(0, 2).join('.')\n return t\n })().pad(40) + ' '\n \n \n // --- https/2.0\n // if (req.tunnel) `tunnel/${http_version}`.pad(10).cyan\n s += `${`${protocol.pad(5)}/${http_version}`.pad(10)} `\n \n \n // --- method\n method = method.toLowerCase()\n s += method === 'get' ? method.pad(10) : method.pad(10).yellow\n \n \n // --- host\n s += `${host.pad(20)} `\n \n \n // --- path\n s += (() => {\n if (path.toLowerCase() !== _path.toLowerCase())\n return `${_path.blue} → ${path}`\n if (!path.includes('.'))\n return path.yellow\n return path\n })()\n \n \n // --- query\n if (Object.keys(query).length) {\n let t = inspect(query, { compact: true })\n .replace('[Object: null prototype] ', '')\n \n if (t.endsWith('\\n'))\n t = t.slice(0, -1)\n \n s += (s + t).width > output_width ? '\\n' : ' '\n \n s += t\n }\n \n \n // --- body\n if (body && Object.keys(body).length)\n s += '\\n' + inspect(body).replace('[Object: null prototype] ', '')\n \n \n // --- print log\n console.log(s)\n },\n}\n\n\nexport default server\n\nexport type Server = typeof server\n"]}
package/tsconfig.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "compilerOptions": {
3
- // --- Module
3
+ // --- module
4
4
  "module": "CommonJS", // none, CommonJS, amd, system, umd, es6, es2015, ESNext
5
5
  "moduleResolution": "Node",
6
6
  "allowSyntheticDefaultImports": true,
@@ -8,7 +8,7 @@
8
8
  "resolveJsonModule": true,
9
9
  "isolatedModules": true,
10
10
 
11
- // --- Build
11
+ // --- build
12
12
  "target": "ES2019",
13
13
  "allowJs": false,
14
14
  "checkJs": false,
@@ -16,22 +16,23 @@
16
16
  "newLine": "lf",
17
17
  "lib": ["ESNext", "DOM"],
18
18
  "importHelpers": true,
19
+ // "watch": false
19
20
  "incremental": true,
20
21
  "tsBuildInfoFile": "./node_modules/.tsbuildinfo",
21
22
 
22
23
 
23
- // --- Emit
24
+ // --- emit
24
25
  "declaration": true,
25
26
  "emitDeclarationOnly": false,
26
27
  "noEmitOnError": false,
27
28
  "listEmittedFiles": true,
28
29
 
29
- // --- Source Maps
30
+ // --- source maps
30
31
  "sourceMap": true,
31
32
  "inlineSourceMap": false,
32
33
  "inlineSources": true,
33
34
 
34
- // --- Features
35
+ // --- features
35
36
  "experimentalDecorators": true,
36
37
  "emitDecoratorMetadata": true,
37
38
  "preserveSymlinks": true,
@@ -41,7 +42,7 @@
41
42
  "forceConsistentCasingInFileNames": true,
42
43
 
43
44
 
44
- // --- Type Checking
45
+ // --- type checking
45
46
  "strict": false,
46
47
  "alwaysStrict": false,
47
48
  "noImplicitAny": false,
@@ -51,6 +52,17 @@
51
52
  "noUnusedLocals": false,
52
53
  "noUnusedParameters": false,
53
54
  "skipLibCheck": true,
55
+ },
56
+
57
+ "watchOptions": {
58
+ "excludeDirectories": [
59
+ "**/node_modules",
60
+ ],
61
+
62
+ "watchFile": "useFsEvents",
63
+ "watchDirectory": "useFsEvents",
64
+
65
+ "fallbackPolling": "dynamicPriority"
54
66
  }
55
67
  }
56
68
 
package/ufs.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ /// <reference types="node" />
2
+ import type fs from 'fs';
3
+ import './prototype.js';
4
+ declare type FS = typeof fs;
5
+ export interface UFS extends FS {
6
+ }
7
+ export declare class UFS {
8
+ fss: FS[];
9
+ constructor(fss: any[]);
10
+ use(fs: any): this;
11
+ existsSync(path: string): boolean;
12
+ readdir(...args: any[]): any;
13
+ readdirSync(...args: any[]): unknown[];
14
+ createReadStream(path: string, options?: any): any;
15
+ createWriteStream(path: string, options?: any): any;
16
+ static sync_method_wrapper(this: UFS, method: string, ...args: any[]): any;
17
+ static async_method_wrapper(this: UFS, method: string, ...args: any[]): any;
18
+ }
19
+ export declare let ufs: UFS;
20
+ export declare function set_ufs(_ufs: UFS): void;
21
+ export default UFS;
package/ufs.js ADDED
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.set_ufs = exports.ufs = exports.UFS = void 0;
4
+ const lists_js_1 = require("fs-monkey/lib/util/lists.js");
5
+ require("./prototype.js");
6
+ class UFS {
7
+ constructor(fss) {
8
+ this.fss = fss || [];
9
+ const overriden_methods = Object.getOwnPropertyNames(UFS.prototype);
10
+ const filter_out_overriden_methods = (method) => !overriden_methods.includes(method);
11
+ lists_js_1.fsSyncMethods.filter(filter_out_overriden_methods).forEach(method => {
12
+ this[method] = UFS.sync_method_wrapper.bind(this, method);
13
+ }, this);
14
+ lists_js_1.fsAsyncMethods.filter(filter_out_overriden_methods).forEach(method => {
15
+ this[method] = UFS.async_method_wrapper.bind(this, method);
16
+ }, this);
17
+ }
18
+ use(fs) {
19
+ this.fss = [fs, ...this.fss];
20
+ return this;
21
+ }
22
+ existsSync(path) {
23
+ for (let fs of this.fss)
24
+ if (fs.existsSync(path))
25
+ return true;
26
+ return false;
27
+ }
28
+ readdir(...args) {
29
+ const method = 'readdir';
30
+ let callback = args.last;
31
+ if (typeof callback !== 'function')
32
+ callback = null;
33
+ else
34
+ args.pop();
35
+ let files = new Set();
36
+ const iterate = (i, error) => {
37
+ if (i >= this.fss.length)
38
+ return callback === null || callback === void 0 ? void 0 : callback(error, [...files].sort());
39
+ const fs = this.fss[i];
40
+ if (!fs[method])
41
+ return iterate(i + 1, new Error(`fs no method: ${method}, args: ${args}`));
42
+ fs[method](...args, (fsError, _files) => {
43
+ if (!fsError) {
44
+ files = new Set([...files, ..._files]);
45
+ return iterate(i + 1, null);
46
+ }
47
+ fsError.prev = error;
48
+ return iterate(i + 1, fsError);
49
+ });
50
+ };
51
+ return iterate(0, null);
52
+ }
53
+ readdirSync(...args) {
54
+ const method = 'readdirSync';
55
+ let last_error = null;
56
+ let files = new Set();
57
+ this.fss.forEach(fs => {
58
+ try {
59
+ if (!fs[method])
60
+ throw new Error(`fs no method: ${method}, args: ${args}`);
61
+ files = new Set([...files, ...fs[method].apply(fs, args)]);
62
+ }
63
+ catch (error) {
64
+ error.prev = last_error;
65
+ last_error = error;
66
+ }
67
+ });
68
+ if (last_error)
69
+ throw last_error;
70
+ return [...files].sort();
71
+ }
72
+ createReadStream(path, options) {
73
+ let last_error = null;
74
+ for (let fs of this.fss)
75
+ try {
76
+ if (!fs.createReadStream)
77
+ throw new Error('method not supported: "createReadStream"');
78
+ if (!fs.existsSync)
79
+ throw new Error('method not supported: "existsSync"');
80
+ if (!fs.existsSync(path))
81
+ throw new Error(`文件不存在:${path}`);
82
+ const read_stream = fs.createReadStream.apply(fs, arguments);
83
+ if (!read_stream)
84
+ throw new Error('no valid read stream');
85
+ return read_stream;
86
+ }
87
+ catch (error) {
88
+ error.prev = last_error;
89
+ last_error = error;
90
+ }
91
+ throw last_error;
92
+ }
93
+ createWriteStream(path, options) {
94
+ let last_error = null;
95
+ for (let fs of this.fss)
96
+ try {
97
+ if (!fs.createWriteStream)
98
+ throw new Error('Method not supported: "createWriteStream"');
99
+ fs.statSync(path);
100
+ const write_stream = fs.createWriteStream.apply(fs, arguments);
101
+ if (!write_stream)
102
+ throw new Error('no valid write stream');
103
+ return write_stream;
104
+ }
105
+ catch (error) {
106
+ error.prev = last_error;
107
+ last_error = error;
108
+ }
109
+ throw last_error;
110
+ }
111
+ static sync_method_wrapper(method, ...args) {
112
+ let last_error = null;
113
+ for (let fs of this.fss)
114
+ try {
115
+ if (!fs[method])
116
+ throw new Error(`fs no method: ${method}, args: ${args}`);
117
+ return fs[method].apply(fs, args);
118
+ }
119
+ catch (error) {
120
+ error.prev = last_error;
121
+ last_error = error;
122
+ }
123
+ throw last_error;
124
+ }
125
+ static async_method_wrapper(method, ...args) {
126
+ let callback = args.last;
127
+ if (typeof callback !== 'function')
128
+ callback = null;
129
+ else
130
+ args.pop();
131
+ const iterate = (i, error) => {
132
+ if (i >= this.fss.length)
133
+ return callback === null || callback === void 0 ? void 0 : callback(error);
134
+ const fs = this.fss[i];
135
+ if (!fs[method])
136
+ return iterate(i + 1, new Error(`fs no method: ${method}, args: ${args}`));
137
+ return fs[method](...args, (fs_error, ...results) => {
138
+ if (!fs_error)
139
+ return callback === null || callback === void 0 ? void 0 : callback.call(fs, null, ...results);
140
+ fs_error.prev = error;
141
+ return iterate(i + 1, fs_error);
142
+ });
143
+ };
144
+ return iterate(0, null);
145
+ }
146
+ }
147
+ exports.UFS = UFS;
148
+ function set_ufs(_ufs) {
149
+ exports.ufs = _ufs;
150
+ }
151
+ exports.set_ufs = set_ufs;
152
+ exports.default = UFS;
153
+ //# sourceMappingURL=ufs.js.map
package/ufs.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ufs.js","sourceRoot":"","sources":["ufs.ts"],"names":[],"mappings":"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","sourcesContent":["import { fsAsyncMethods as fs_async_methods, fsSyncMethods as fs_sync_methods } from 'fs-monkey/lib/util/lists.js'\n\nimport type fs from 'fs'\n\n\nimport './prototype.js'\n\n\ntype FS = typeof fs\n\n// @ts-ignore\nexport interface UFS extends FS { }\n\nexport class UFS {\n fss: FS[]\n \n constructor (fss: any[]) {\n this.fss = fss || []\n \n const overriden_methods = Object.getOwnPropertyNames(UFS.prototype)\n \n const filter_out_overriden_methods = (method: string) => \n !overriden_methods.includes(method)\n \n fs_sync_methods.filter(filter_out_overriden_methods).forEach( method => {\n this[method] = UFS.sync_method_wrapper.bind(this, method)\n }, this)\n \n fs_async_methods.filter(filter_out_overriden_methods).forEach( method => {\n this[method] = UFS.async_method_wrapper.bind(this, method)\n }, this)\n }\n \n \n use (fs: any) {\n this.fss = [fs, ...this.fss]\n return this\n }\n \n \n existsSync (path: string) {\n for (let fs of this.fss)\n if (fs.existsSync(path)) return true\n return false\n }\n \n \n readdir (...args) {\n const method = 'readdir'\n \n let callback = args.last\n \n if (typeof callback !== 'function')\n callback = null\n else\n args.pop()\n \n let files = new Set()\n \n const iterate = (i: number, error: Error) => {\n if (i >= this.fss.length) return callback?.(error, [...files].sort())\n \n const fs = this.fss[i]\n \n if (!fs[method]) return iterate(i+1, new Error(`fs no method: ${method}, args: ${args}`))\n \n fs[method as string](...args, (fsError: Error & { prev: Error }, _files: string[]) => {\n if (!fsError) {\n files = new Set([...files, ..._files])\n return iterate(i+1, null)\n }\n fsError.prev = error\n return iterate(i+1, fsError)\n })\n }\n \n return iterate(0, null)\n }\n \n \n readdirSync (...args) {\n const method = 'readdirSync'\n \n let last_error = null\n let files = new Set()\n \n this.fss.forEach( fs => {\n try {\n if (!fs[method]) throw new Error(`fs no method: ${method}, args: ${args}`)\n \n files = new Set([...files, ...fs[method].apply(fs, args)])\n } catch (error) {\n error.prev = last_error\n last_error = error\n }\n })\n \n if (last_error) throw last_error\n \n return [...files].sort()\n }\n \n \n createReadStream (path: string, options?: any) {\n let last_error = null\n \n for (let fs of this.fss)\n try {\n if (!fs.createReadStream) throw new Error('method not supported: \"createReadStream\"')\n if (!fs.existsSync) throw new Error('method not supported: \"existsSync\"')\n if (!fs.existsSync(path)) throw new Error(`文件不存在:${path}`)\n const read_stream = fs.createReadStream.apply(fs, arguments)\n if (!read_stream) throw new Error('no valid read stream')\n return read_stream\n } catch (error) {\n error.prev = last_error\n last_error = error\n }\n \n throw last_error\n }\n \n \n createWriteStream (path: string, options?: any) {\n let last_error = null\n \n for (let fs of this.fss)\n try {\n if (!fs.createWriteStream) throw new Error('Method not supported: \"createWriteStream\"')\n fs.statSync(path)\n const write_stream = fs.createWriteStream.apply(fs, arguments)\n if (!write_stream) throw new Error('no valid write stream')\n return write_stream\n } catch (error) {\n error.prev = last_error\n last_error = error\n }\n \n \n throw last_error\n }\n \n \n static sync_method_wrapper (this: UFS, method: string, ...args: any[]) {\n let last_error: Error = null\n for (let fs of this.fss)\n try {\n if (!fs[method]) throw new Error(`fs no method: ${method}, args: ${args}`)\n return fs[method].apply(fs, args)\n } catch (error) {\n error.prev = last_error\n last_error = error\n }\n throw last_error\n }\n \n \n static async_method_wrapper (this: UFS, method: string, ...args: any[]) {\n let callback = args.last\n \n if (typeof callback !== 'function')\n callback = null\n else\n args.pop()\n \n const iterate = (i: number, error: Error) => {\n if (i >= this.fss.length) return callback?.(error)\n \n const fs = this.fss[i]\n \n if (!fs[method]) return iterate(i+1, new Error(`fs no method: ${method}, args: ${args}`))\n \n return fs[method](...args, (fs_error: Error & { prev: Error }, ...results: any[]) => {\n if (!fs_error) return callback?.call(fs, null, ...results)\n fs_error.prev = error\n return iterate(i+1, fs_error)\n })\n }\n \n return iterate(0, null)\n }\n}\n\nexport let ufs: UFS\n\nexport function set_ufs (_ufs: UFS) {\n ufs = _ufs\n}\n\nexport default UFS\n"]}
package/utils.d.ts CHANGED
@@ -1,20 +1,26 @@
1
1
  /// <reference types="node" />
2
2
  import { Readable } from 'stream';
3
3
  import util from 'util';
4
- export declare function assert(shoud_be_true_expr: any): never | void;
4
+ import './prototype';
5
+ export declare const output_width = 230;
5
6
  export declare function dedent(templ: TemplateStringsArray | string, ...values: any[]): string;
6
- export declare function unique(iterable: any[] | Set<any>): any[];
7
+ /** unique iterable or array (by selector)
8
+ - selector?: 可以是 key (string) 或 (obj: any) => any
9
+ */
10
+ export declare function unique<T>(iterable: T[] | Iterable<T>, selector?: string | ((obj: T) => any)): any[];
11
+ /** sort keys in object and returns new object */
7
12
  export declare function sort_keys<T>(obj: T): T;
8
- export declare function log_module_loaded(id: string): void;
9
- export declare function log_section(message: string, { timestamp, time, color, left_width, full_width }?: {
10
- timestamp?: boolean;
11
- time?: boolean | Date;
13
+ /** string compare in lexicographic order */
14
+ export declare function strcmp(l: string, r: string): 0 | 1 | -1;
15
+ /** 拼接 TypedArrays 生成一个完整的 Uint8Array */
16
+ export declare function concat(views: ArrayBufferView[]): Uint8Array;
17
+ export declare function typed_array_to_buffer(view: ArrayBufferView): Buffer;
18
+ export declare function log_section(message: string, { time, timestamp, color, }?: {
19
+ time?: boolean;
20
+ timestamp?: boolean | Date;
12
21
  color?: 'green' | 'red' | 'yellow';
13
- left_width?: number;
14
- full_width?: number;
15
22
  }): void;
16
- /** '─' === '\u2500' */
17
- export declare function log_line(width?: number): void;
23
+ export declare function log_line(): void;
18
24
  export declare function delay(milliseconds: number): Promise<unknown>;
19
25
  export declare function has_chinese(str: string): boolean;
20
26
  export declare function escape_line_feed(str: string): string;
@@ -30,3 +36,4 @@ export declare namespace inspect {
30
36
  const custom: typeof util.inspect.custom;
31
37
  }
32
38
  export declare function stream_to_buffer(stream: Readable): Promise<Buffer>;
39
+ export declare function stream_to_lines(stream: Readable): AsyncGenerator<string, void, unknown>;
package/utils.js CHANGED
@@ -1,38 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.stream_to_buffer = exports.inspect = exports.escape_line_feed = exports.has_chinese = exports.delay = exports.log_line = exports.log_section = exports.log_module_loaded = exports.sort_keys = exports.unique = exports.dedent = exports.assert = void 0;
3
+ exports.stream_to_lines = exports.stream_to_buffer = exports.inspect = exports.escape_line_feed = exports.has_chinese = exports.delay = exports.log_line = exports.log_section = exports.typed_array_to_buffer = exports.concat = exports.strcmp = exports.sort_keys = exports.unique = exports.dedent = exports.output_width = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const upath_1 = tslib_1.__importDefault(require("upath"));
6
- const util_1 = tslib_1.__importDefault(require("util"));
7
- const omit_1 = tslib_1.__importDefault(require("lodash/omit"));
8
- const sortBy_1 = tslib_1.__importDefault(require("lodash/sortBy"));
9
- const prototype_1 = require("./prototype");
10
- function assert(shoud_be_true_expr) {
11
- if (!shoud_be_true_expr) {
12
- debugger;
13
- throw new Error(`Assertion Failed: ${inspect(shoud_be_true_expr)}`);
14
- }
15
- }
16
- exports.assert = assert;
5
+ const util_1 = (0, tslib_1.__importDefault)(require("util"));
6
+ const omit_1 = (0, tslib_1.__importDefault)(require("lodash/omit"));
7
+ require("./prototype");
8
+ exports.output_width = 230;
17
9
  function dedent(templ, ...values) {
18
10
  let strings = Array.from(typeof templ === 'string' ? [templ] : templ.raw);
19
- // 1. Remove trailing whitespace.
11
+ // 1. remove trailing whitespace
20
12
  strings[strings.length - 1] = strings[strings.length - 1].replace(/\r?\n([\t ]*)$/, '');
21
- // 2. Find all line breaks to determine the highest common indentation level.
22
- const indentLengths = strings.reduce((arr, str) => {
13
+ // 2. find all line breaks to determine the highest common indentation level
14
+ const indent_lengths = strings.reduce((arr, str) => {
23
15
  const matches = str.match(/\n[\t ]+/g);
24
16
  if (matches)
25
17
  return arr.concat(matches.map(match => match.length - 1));
26
18
  return arr;
27
19
  }, []);
28
- // 3. Remove the common indentation from all strings.
29
- if (indentLengths.length) {
30
- const pattern = new RegExp(`\n[\t ]{${Math.min(...indentLengths)}}`, 'g');
20
+ // 3. remove the common indentation from all strings
21
+ if (indent_lengths.length) {
22
+ const pattern = new RegExp(`\n[\t ]{${Math.min(...indent_lengths)}}`, 'g');
31
23
  strings = strings.map(str => str.replace(pattern, '\n'));
32
24
  }
33
- // 4. Remove leading whitespace.
25
+ // 4. remove leading whitespace
34
26
  strings[0] = strings[0].replace(/^\r?\n/, '');
35
- // 5. Perform interpolation.
27
+ // 5. perform interpolation
36
28
  let string = strings[0];
37
29
  values.forEach((value, i) => {
38
30
  string += value + strings[i + 1];
@@ -41,40 +33,76 @@ function dedent(templ, ...values) {
41
33
  return string;
42
34
  }
43
35
  exports.dedent = dedent;
44
- function unique(iterable) {
45
- return [...new Set(iterable)];
36
+ /** unique iterable or array (by selector)
37
+ - selector?: 可以是 key (string) 或 (obj: any) => any
38
+ */
39
+ function unique(iterable, selector) {
40
+ if (!selector)
41
+ return [...new Set(iterable)];
42
+ let map = new Map();
43
+ if (typeof selector === 'string')
44
+ for (const x of iterable)
45
+ map.set(x[selector], x);
46
+ else
47
+ for (const x of iterable)
48
+ map.set(selector(x), x);
49
+ return [...map.values()];
46
50
  }
47
51
  exports.unique = unique;
52
+ /** sort keys in object and returns new object */
48
53
  function sort_keys(obj) {
49
- return Object.fromEntries(sortBy_1.default(Object.entries(obj), ([key,]) => key));
54
+ return Object.fromEntries(Object.entries(obj)
55
+ .sort(([key_l], [key_r]) => strcmp(key_l, key_r)));
50
56
  }
51
57
  exports.sort_keys = sort_keys;
52
- // ------------------------------------ Log: module loaded, section, line
53
- function log_module_loaded(id) {
54
- const fname = upath_1.default.basename(id).replace(/\.(coffee|ts)$/, '');
55
- console.log(`${fname}${' '.repeat(20 - fname.length)}loaded`);
58
+ /** string compare in lexicographic order */
59
+ function strcmp(l, r) {
60
+ if (l === r)
61
+ return 0;
62
+ if (l < r)
63
+ return -1;
64
+ return 1;
65
+ }
66
+ exports.strcmp = strcmp;
67
+ /** 拼接 TypedArrays 生成一个完整的 Uint8Array */
68
+ function concat(views) {
69
+ let length = 0;
70
+ for (const v of views)
71
+ length += v.byteLength;
72
+ let buf = new Uint8Array(length);
73
+ let offset = 0;
74
+ for (const v of views) {
75
+ const uint8view = new Uint8Array(v.buffer, v.byteOffset, v.byteLength);
76
+ buf.set(uint8view, offset);
77
+ offset += uint8view.byteLength;
78
+ }
79
+ return buf;
56
80
  }
57
- exports.log_module_loaded = log_module_loaded;
58
- function log_section(message, { timestamp = false, time = false, color = undefined, left_width = 30, full_width = 110 } = {}) {
81
+ exports.concat = concat;
82
+ function typed_array_to_buffer(view) {
83
+ return Buffer.from(view.buffer, view.byteOffset, view.byteLength);
84
+ }
85
+ exports.typed_array_to_buffer = typed_array_to_buffer;
86
+ // ------------------------------------ log: module loaded, section, line
87
+ function log_section(message, { time = false, timestamp = false, color = undefined, } = {}) {
59
88
  const stime = (() => {
60
- if (timestamp)
61
- return ` [${String(new Date().getTime() - global.started_at.getTime()).pad(4, { position: 'left' })} ms]`;
62
89
  if (time)
63
- if (typeof time === 'object')
64
- return ` [${time.to_str()}]`;
90
+ return `[${String(new Date().getTime() - global.started_at.getTime()).pad(4, { position: 'left' })} ms]`;
91
+ if (timestamp)
92
+ if (typeof timestamp === 'object')
93
+ return `[${timestamp.to_str()}]`;
65
94
  else
66
- return ` [${new Date().to_str()}]`;
95
+ return `[${new Date().to_str()}]`;
67
96
  return '';
68
97
  })();
69
- message = `${'-'.repeat(left_width)}${stime} ${message} `.pad(full_width, { character: '-' });
98
+ message = `${stime.pad(20)}${message}`;
70
99
  if (color)
71
- message = prototype_1.colors[color](message);
100
+ message = message[color];
72
101
  console.log(message);
73
102
  }
74
103
  exports.log_section = log_section;
75
- /** '─' === '\u2500' */
76
- function log_line(width = global.WIDTH || 240) {
77
- console.log('─'.repeat(width / 2));
104
+ function log_line() {
105
+ console.log('---');
78
106
  }
79
107
  exports.log_line = log_line;
80
108
  async function delay(milliseconds) {
@@ -83,7 +111,7 @@ async function delay(milliseconds) {
83
111
  });
84
112
  }
85
113
  exports.delay = delay;
86
- // ------------ Text
114
+ // ------------ text
87
115
  function has_chinese(str) {
88
116
  return /[\u4E00-\u9FA5]/.test(str);
89
117
  }
@@ -98,10 +126,8 @@ exports.escape_line_feed = escape_line_feed;
98
126
  */
99
127
  function inspect(obj, options = {}) {
100
128
  if (options.omit)
101
- obj = omit_1.default(obj, [inspect.custom, ...(options.omit || [])]);
129
+ obj = (0, omit_1.default)(obj, [inspect.custom, ...(options.omit || [])]);
102
130
  let text = util_1.default.inspect(obj, options);
103
- if (obj && typeof obj === 'object')
104
- text = text.split_lines().indent2to4().join_lines();
105
131
  if (!('limit' in options))
106
132
  options.limit = 10000;
107
133
  if (options.limit && text.length > options.limit)
@@ -121,4 +147,21 @@ async function stream_to_buffer(stream) {
121
147
  return Buffer.concat(chunks);
122
148
  }
123
149
  exports.stream_to_buffer = stream_to_buffer;
150
+ async function* stream_to_lines(stream) {
151
+ let buf = '';
152
+ for await (const chunk of stream) {
153
+ let i = 0, j = 0;
154
+ for (; (i = chunk.indexOf('\n', j)) >= 0;) {
155
+ let line = chunk.slice(j, i);
156
+ if (buf) {
157
+ line = buf + line;
158
+ buf = '';
159
+ }
160
+ j = i + 1;
161
+ yield line;
162
+ }
163
+ buf = chunk.slice(j);
164
+ }
165
+ }
166
+ exports.stream_to_lines = stream_to_lines;
124
167
  //# sourceMappingURL=utils.js.map
package/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { Readable } from 'stream'\n\nimport path from 'upath'\nimport util from 'util'\nimport omit from 'lodash/omit'\nimport sort_by from 'lodash/sortBy'\n\nimport { colors } from './prototype'\n\n\nexport function assert (shoud_be_true_expr: any): never | void {\n if (!shoud_be_true_expr) {\n debugger\n throw new Error(`Assertion Failed: ${inspect(shoud_be_true_expr)}`)\n }\n}\n\n\nexport function dedent (\n templ: TemplateStringsArray | string,\n ...values: any[]\n): string {\n let strings = Array.from(typeof templ === 'string' ? [templ] : templ.raw)\n \n // 1. Remove trailing whitespace.\n strings[strings.length - 1] = strings[strings.length - 1].replace(\n /\\r?\\n([\\t ]*)$/,\n '',\n )\n \n // 2. Find all line breaks to determine the highest common indentation level.\n const indentLengths = strings.reduce<number[]>(\n (arr, str) => {\n const matches = str.match(/\\n[\\t ]+/g)\n if (matches) \n return arr.concat(matches.map(match => match.length - 1))\n \n return arr\n },\n [],\n )\n \n // 3. Remove the common indentation from all strings.\n if (indentLengths.length) {\n const pattern = new RegExp(`\\n[\\t ]{${Math.min(...indentLengths)}}`, 'g')\n \n strings = strings.map(str => str.replace(pattern, '\\n'))\n }\n \n // 4. Remove leading whitespace.\n strings[0] = strings[0].replace(/^\\r?\\n/, '')\n \n // 5. Perform interpolation.\n let string = strings[0]\n \n values.forEach((value, i) => {\n string += value + strings[i + 1]\n })\n \n string += '\\n'\n \n return string\n}\n\n\nexport function unique (iterable: any[] | Set<any>) {\n return [... new Set(iterable)]\n}\n\n\nexport function sort_keys <T> (obj: T) {\n return Object.fromEntries(\n sort_by(\n Object.entries(obj),\n ([key, ]) => key\n )\n ) as T\n}\n\n\n// ------------------------------------ Log: module loaded, section, line\nexport function log_module_loaded (id: string) {\n const fname = path.basename(id).replace(/\\.(coffee|ts)$/, '')\n console.log(`${ fname }${ ' '.repeat(20 - fname.length) }loaded`)\n}\n\n\nexport function log_section (\n message: string, \n {\n timestamp = false,\n time = false,\n color = undefined,\n left_width = 30,\n full_width = 110\n }: {\n timestamp?: boolean\n time?: boolean | Date\n color?: 'green' | 'red' | 'yellow'\n left_width?: number\n full_width?: number\n } = { }\n) {\n const stime = (() => {\n if (timestamp)\n return ` [${String(new Date().getTime() - global.started_at.getTime()).pad(4, { position: 'left' })} ms]`\n if (time)\n if (typeof time === 'object')\n return ` [${time.to_str()}]`\n else\n return ` [${new Date().to_str()}]`\n return ''\n })()\n \n message = `${'-'.repeat(left_width)}${stime} ${message} `.pad(full_width, { character: '-' })\n \n if (color)\n message = colors[color](message)\n \n console.log(message)\n}\n\n\n/** '─' === '\\u2500' */\nexport function log_line (width: number = global.WIDTH || 240) {\n console.log('─'.repeat(width / 2))\n}\n\n\nexport async function delay (milliseconds: number) {\n return new Promise( resolve => {\n setTimeout(resolve, milliseconds)\n })\n}\n\n\n// ------------ Text\nexport function has_chinese (str: string) {\n return /[\\u4E00-\\u9FA5]/.test(str)\n}\n\n\nexport function escape_line_feed (str: string) {\n return str.replace(/\\n/g, '\\\\n')\n}\n\n/** util.inspect(obj) \n - options\n - limit?: `10000`\n*/\nexport function inspect (\n obj: any, \n options: util.InspectOptions & {\n limit?: number\n omit?: string[]\n } = { }\n) {\n if (options.omit)\n obj = omit(obj, [inspect.custom, ...(options.omit || [])])\n \n let text = util.inspect(obj, options)\n \n if (obj && typeof obj === 'object')\n text = text.split_lines().indent2to4().join_lines()\n\n if (!('limit' in options))\n options.limit = 10000\n if (options.limit && text.length > options.limit)\n return `${text.slice(0, options.limit)}……'\\u001b[39m\\n`\n else\n return text\n}\n\nexport namespace inspect {\n export const custom: typeof util.inspect.custom = util.inspect.custom\n}\n\n\n// ------------------------------------ Steam\nexport async function stream_to_buffer (stream: Readable) {\n let chunks = [ ]\n for await (const chunk of stream)\n chunks.push(chunk)\n return Buffer.concat(chunks)\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { Readable } from 'stream'\n\nimport util from 'util'\nimport omit from 'lodash/omit'\n\nimport './prototype'\n\nexport const output_width = 230\n\n\nexport function dedent (\n templ: TemplateStringsArray | string,\n ...values: any[]\n): string {\n let strings = Array.from(typeof templ === 'string' ? [templ] : templ.raw)\n \n // 1. remove trailing whitespace\n strings[strings.length - 1] = strings[strings.length - 1].replace(\n /\\r?\\n([\\t ]*)$/,\n '',\n )\n \n // 2. find all line breaks to determine the highest common indentation level\n const indent_lengths = strings.reduce<number[]>(\n (arr, str) => {\n const matches = str.match(/\\n[\\t ]+/g)\n if (matches) \n return arr.concat(matches.map(match => match.length - 1))\n \n return arr\n },\n [],\n )\n \n // 3. remove the common indentation from all strings\n if (indent_lengths.length) {\n const pattern = new RegExp(`\\n[\\t ]{${Math.min(...indent_lengths)}}`, 'g')\n \n strings = strings.map(str => str.replace(pattern, '\\n'))\n }\n \n // 4. remove leading whitespace\n strings[0] = strings[0].replace(/^\\r?\\n/, '')\n \n // 5. perform interpolation\n let string = strings[0]\n \n values.forEach((value, i) => {\n string += value + strings[i + 1]\n })\n \n string += '\\n'\n \n return string\n}\n\n\n/** unique iterable or array (by selector) \n - selector?: 可以是 key (string) 或 (obj: any) => any\n*/\nexport function unique <T> (iterable: T[] | Iterable<T>, selector?: string | ((obj: T) => any)) {\n if (!selector)\n return [...new Set(iterable)]\n \n let map = new Map()\n if (typeof selector === 'string')\n for (const x of iterable)\n map.set(x[selector], x)\n else\n for (const x of iterable)\n map.set(\n selector(x),\n x\n )\n \n return [...map.values()]\n}\n\n\n/** sort keys in object and returns new object */\nexport function sort_keys <T> (obj: T) {\n return Object.fromEntries(\n Object.entries(obj)\n .sort(([key_l], [key_r]) => \n strcmp(key_l, key_r))\n ) as T\n}\n\n\n/** string compare in lexicographic order */\nexport function strcmp (l: string, r: string) {\n if (l === r) return 0\n if (l < r) return -1\n return 1\n}\n\n\n/** 拼接 TypedArrays 生成一个完整的 Uint8Array */\nexport function concat (views: ArrayBufferView[]) {\n let length = 0\n for (const v of views)\n length += v.byteLength\n \n let buf = new Uint8Array(length)\n let offset = 0\n for (const v of views) {\n const uint8view = new Uint8Array(v.buffer, v.byteOffset, v.byteLength)\n buf.set(uint8view, offset)\n offset += uint8view.byteLength\n }\n \n return buf\n}\n\n\nexport function typed_array_to_buffer (view: ArrayBufferView) {\n return Buffer.from(\n view.buffer,\n view.byteOffset,\n view.byteLength\n )\n}\n\n\n// ------------------------------------ log: module loaded, section, line\nexport function log_section (\n message: string, \n {\n time = false,\n timestamp = false,\n color = undefined,\n }: {\n time?: boolean\n timestamp?: boolean | Date\n color?: 'green' | 'red' | 'yellow'\n } = { }\n) {\n const stime = (() => {\n if (time)\n return `[${String(new Date().getTime() - global.started_at.getTime()).pad(4, { position: 'left' })} ms]`\n if (timestamp)\n if (typeof timestamp === 'object')\n return `[${timestamp.to_str()}]`\n else\n return `[${new Date().to_str()}]`\n return ''\n })()\n \n message = `${stime.pad(20)}${message}`\n \n if (color)\n message = message[color]\n \n console.log(message)\n}\n\n\nexport function log_line () {\n console.log('---')\n}\n\n\nexport async function delay (milliseconds: number) {\n return new Promise( resolve => {\n setTimeout(resolve, milliseconds)\n })\n}\n\n\n// ------------ text\nexport function has_chinese (str: string) {\n return /[\\u4E00-\\u9FA5]/.test(str)\n}\n\n\nexport function escape_line_feed (str: string) {\n return str.replace(/\\n/g, '\\\\n')\n}\n\n/** util.inspect(obj) \n - options\n - limit?: `10000`\n*/\nexport function inspect (\n obj: any, \n options: util.InspectOptions & {\n limit?: number\n omit?: string[]\n } = { }\n) {\n if (options.omit)\n obj = omit(obj, [inspect.custom, ...(options.omit || [])])\n \n let text = util.inspect(obj, options)\n \n if (!('limit' in options))\n options.limit = 10000\n if (options.limit && text.length > options.limit)\n return `${text.slice(0, options.limit)}……'\\u001b[39m\\n`\n else\n return text\n}\n\nexport namespace inspect {\n export const custom: typeof util.inspect.custom = util.inspect.custom\n}\n\n\n// ------------------------------------ Steam\nexport async function stream_to_buffer (stream: Readable) {\n let chunks = [ ]\n for await (const chunk of stream as AsyncIterable<Buffer>)\n chunks.push(chunk)\n return Buffer.concat(chunks)\n}\n\n\nexport async function * stream_to_lines (stream: Readable) {\n let buf = ''\n for await (const chunk of stream as AsyncIterable<string>) {\n let i = 0, j = 0\n for (; (i = chunk.indexOf('\\n', j)) >= 0; ) {\n let line = chunk.slice(j, i)\n if (buf) {\n line = buf + line\n buf = ''\n }\n j = i + 1\n yield line\n }\n buf = chunk.slice(j)\n }\n}\n\n"]}