xshell 0.0.55 → 0.0.58

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/file.d.ts CHANGED
@@ -91,15 +91,16 @@ export declare function flist(fpd: string, options?: {
91
91
  print?: boolean;
92
92
  }): Promise<string[]>;
93
93
  export declare function fstat(fp: string): Promise<fs.BigIntStats>;
94
- /** delete file or directory (use rimraf to delete directory fast)
95
- - fp: path
94
+ /** delete files or folders
95
+ - fp: file path
96
96
  - options?:
97
- - print?: `true` (effective only delete single file)
97
+ - print?: `true`
98
+
99
+ Returns whether the delete operation actually took place
98
100
  */
99
- export declare function fdelete(fp: string, { print, fast }?: {
101
+ export declare function fdelete(fp: string, { print }?: {
100
102
  print?: boolean;
101
- fast?: boolean;
102
- }): Promise<void>;
103
+ }): Promise<boolean>;
103
104
  /** copy file or direcotry
104
105
  - src: src file/directory absolute path
105
106
  - dst: dst file/directory absolute path
package/file.js CHANGED
@@ -2,7 +2,6 @@ import { promises as fsp, default as fs, } from 'fs';
2
2
  import path from 'upath';
3
3
  import iconv from 'iconv-lite';
4
4
  import fse from 'fs-extra';
5
- import rimraf from 'rimraf';
6
5
  import debounce from 'lodash/debounce.js';
7
6
  import MFS from 'memfs';
8
7
  import { to_json } from './prototype.js';
@@ -159,32 +158,37 @@ export async function fstat(fp) {
159
158
  throw new Error(`fp (${fp}) must be absolute path`);
160
159
  return fsp.stat(fp, { bigint: true });
161
160
  }
162
- /** delete file or directory (use rimraf to delete directory fast)
163
- - fp: path
161
+ /** delete files or folders
162
+ - fp: file path
164
163
  - options?:
165
- - print?: `true` (effective only delete single file)
164
+ - print?: `true`
165
+
166
+ Returns whether the delete operation actually took place
166
167
  */
167
- export async function fdelete(fp, { print = true, fast = false } = {}) {
168
+ export async function fdelete(fp, { print = true } = {}) {
168
169
  if (fp.length < 6)
169
- throw new Error(`${fp} too short`);
170
+ throw new Error(`${fp} 太短`);
170
171
  if (!path.isAbsolute(fp))
171
- throw new Error('fpd must be absolute path');
172
- if (fp.endsWith('/')) {
172
+ throw new Error('fp must be an absolute path');
173
+ try {
174
+ await fsp.rm(fp, { recursive: true });
173
175
  if (print)
174
- console.log(`delete directory: ${fp}`.red);
175
- await new Promise((resolve, reject) => {
176
- rimraf(fp, { glob: false, disableGlob: true }, error => {
177
- if (error)
178
- reject(error);
179
- else
180
- resolve();
181
- });
182
- });
176
+ if (fp.endsWith('/'))
177
+ console.log(`deleted folder: ${fp}`.red);
178
+ else
179
+ console.log(`deleted file: ${fp}`.red);
180
+ return true;
183
181
  }
184
- else {
185
- if (print)
186
- console.log('delete:', fp);
187
- await fsp.unlink(fp);
182
+ catch (error) {
183
+ if (error.code === 'ENOENT') {
184
+ if (print)
185
+ if (fp.endsWith('/'))
186
+ console.log(`folder no longer exists: ${fp}`);
187
+ else
188
+ console.log(`file no longer exists: ${fp}`);
189
+ return false;
190
+ }
191
+ throw error;
188
192
  }
189
193
  }
190
194
  /** copy file or direcotry
package/file.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"file.js","sourceRoot":"","sources":["file.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n promises as fsp,\n default as fs,\n} from 'fs'\ntype FileHandle = fsp.FileHandle & { fp: string }\n\nimport path from 'upath'\nimport iconv from 'iconv-lite'\nimport fse from 'fs-extra'\nimport rimraf from 'rimraf'\n\nimport debounce from 'lodash/debounce.js'\n\n\nimport MFS from 'memfs'\ndeclare module 'memfs' {\n interface IFs {\n join: typeof path.join\n is_mfs: true\n }\n}\n\nimport { to_json } from './prototype.js'\nexport * from './ufs.js'\n\n\nexport { MFS }\n\nexport type Encoding = 'utf-8' | 'gb18030' | 'shift-jis' | 'binary'\n\n\n/** Does the file/folder pointed to by fp exist? */\nexport function fexists (fp: string, { print = true }: { print?: boolean } = { }) {\n const exists = fs.existsSync(fp)\n \n if (print)\n console.log(\n exists ? 'exists:' : 'not exists:',\n fp\n )\n \n return exists\n}\n\n\n/**\n open file, return FileHandle \n Some characters (`< > : \" / \\ | ? *`) are reserved under Windows as documented\n by [Naming Files, Paths, and Namespaces](https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file). Under NTFS, if the filename contains\n a colon, Node.js will open a file system stream, as described by [this MSDN page](https://docs.microsoft.com/en-us/windows/desktop/FileIO/using-streams).\n \n - flags: `'r'`\n - options?:\n - mode?: `'0o666'` Sets the file mode (permission and sticky bits) if the file is created.\n*/\nexport async function fopen (\n fp: string,\n flags: string | number,\n {\n mode,\n print\n }: {\n mode?: fs.Mode\n print?: boolean\n } = { }\n) {\n if (print)\n console.log('fopen:', fp)\n return Object.assign(\n await fsp.open(fp, flags, mode),\n {\n fp,\n flags,\n mode\n }\n )\n}\n\n\nexport function create_mfs () {\n let mfs = MFS.createFsFromVolume(\n new MFS.Volume()\n )\n \n mfs.join = path.join.bind(path)\n mfs.is_mfs = true\n \n return mfs\n}\n\n\nexport async function fread (fp: string): Promise<string>\nexport async function fread (fp: string, { dir, encoding, print }?: { dir?: string, encoding: 'binary', print?: boolean }): Promise<Buffer>\nexport async function fread (fp: string, { dir, encoding, print }?: { dir?: string, encoding?: Encoding | 'auto', print?: boolean }): Promise<string>\nexport async function fread (fp: string, {\n dir, \n encoding = 'utf-8', \n print = true\n}: {\n dir?: string\n encoding?: Encoding | 'auto'\n print?: boolean } = { }\n) {\n if (dir)\n fp = path.join(dir, fp)\n else if (!path.isAbsolute(fp))\n throw new Error('fp must be absolute path, or pass in \\'dir\\' parameter')\n \n if (print)\n console.log(`read: ${fp}`)\n \n const buffer = await fsp.readFile(fp)\n \n if (encoding === 'binary')\n return buffer\n \n if (encoding === 'utf-8')\n return buffer.toString('utf8')\n \n if (encoding === 'auto') {\n const { detect } = await import('chardet')\n encoding = detect(buffer) as any\n if (print)\n console.log(`${fp} probably has encoding: ${encoding.toLowerCase()}`)\n }\n \n return iconv.decode(buffer, encoding)\n}\n\nexport async function fread_lines (fp: string, options: { dir?: string, encoding?: Exclude<Encoding, 'binary'> | 'auto', print?: boolean } = { }) {\n return (await fread(fp, options))\n .split_lines()\n}\n\nexport async function fread_json <T = any> (fp: string, options: { dir?: string, encoding?: Encoding, print?: boolean } = { }): Promise<T> {\n return JSON.parse(\n await fread(fp, options)\n )\n}\n\n\nexport async function fwrite (fp: string | FileHandle, data: Buffer, options?: { dir?: string, print?: boolean, mkdir?: boolean }): Promise<void>\nexport async function fwrite (fp: string | FileHandle, data: any, options?: { dir?: string, encoding?: Encoding, print?: boolean, mkdir?: boolean }): Promise<void>\nexport async function fwrite (\n fp: string | FileHandle,\n data: any,\n {\n dir,\n encoding = 'utf-8',\n print = true,\n mkdir = false,\n }: {\n dir?: string\n encoding?: Encoding\n print?: boolean\n mkdir?: boolean\n } = { }\n) {\n const is_handle = typeof fp === 'object' && fp && 'fd' in fp\n if (is_handle) {\n if (print)\n console.log('write:', (fp as FileHandle).fp)\n } else {\n if (dir)\n fp = path.join(dir, fp)\n else if (!path.isAbsolute(fp as string))\n throw new Error('fp must be absolute path, or pass in \"dir\" parameter')\n \n if (print)\n console.log('write:', fp)\n }\n \n if (encoding === 'gb18030')\n data = iconv.encode(data, encoding)\n \n if (!Buffer.isBuffer(data) && typeof data !== 'string')\n data = to_json(data)\n \n try {\n await fsp.writeFile(fp, data)\n } catch (error) {\n if (!mkdir || error.code !== 'ENOENT' || is_handle)\n throw error\n \n await fmkdir((fp as string).fdir)\n await fsp.writeFile(fp, data)\n }\n}\n\nexport async function fappend (fp: string, data: any, { dir, print = true }: { dir?: string, print?: boolean } = { }) {\n if (dir)\n fp = path.join(dir, fp)\n else if (!path.isAbsolute(fp))\n throw new Error('fp must be absolute path, or pass in \"dir\" parameter')\n \n if (print)\n console.log('append:', fp)\n \n if (!Buffer.isBuffer(data) && typeof data !== 'string')\n throw new Error('data is not Buffer or string')\n \n await fsp.appendFile(fp, data)\n}\n\n\n/**\n - fpd: absolute path of directory\n - optoins?:\n - deep?: `false` recursively\n - absolute?: `false` Return, print full path instead of relative path\n - print?: `true`\n - filter?: `true` RegExp | (fp: string) => any, Note that when deep = true, \n directories and files in directories that are filtered out by the filter will not be included in the results\n*/\nexport async function flist (\n fpd: string,\n options: {\n filter?: RegExp | ((fp: string) => any)\n deep?: boolean\n absolute?: boolean\n print?: boolean\n } = { }\n): Promise<string[]> {\n const {\n filter,\n deep = false,\n absolute = false,\n print = true,\n } = options\n \n if (!path.isAbsolute(fpd))\n throw new Error(`fpd (${fpd}) must be absolute path`)\n \n if (!fpd.endsWith('/'))\n throw new Error(`Argument fpd (${fpd}) must end with /`)\n \n // readdir withFileTypes 参数在底层有什么区别,速度上有什么差异\n // 都调用了 uv_fs_scandir, 且调用参数相同,仅仅是 Node.js 侧的回调不同 AfterScanDir / AfterScanDirWithTypes\n // 回调中通过 uv_fs_scandir_next 获取到每个条目的信息,而 uv_fs_scandir_next 中都会读取 type\n // 速度上:都在 0.2 ms 左右就可以完成\n \n const files = await fsp.readdir(fpd, {\n withFileTypes: true,\n encoding: 'utf-8',\n })\n \n const filter_regexp = filter instanceof RegExp\n const filter_fn = Boolean(filter && !filter_regexp)\n \n let fps: string[] = [ ]\n \n for (const file of files) {\n const fp = \n (absolute ? fpd : '') +\n file.name +\n (file.isDirectory() ? '/' : '')\n \n if (filter_regexp && !filter.test(fp))\n continue\n \n if (filter_fn && !(filter as Function)(fp))\n continue\n \n if (print)\n console.log(\n deep || absolute ? fpd + fp : fp\n )\n \n fps.push(fp)\n }\n \n return deep ? (\n await Promise.all(\n fps.map(async fp => \n fp.endsWith('/') ?\n [\n fp,\n ... (await flist(\n absolute ? fp : fpd + fp,\n options\n )).map(fp_ => \n absolute ? fp_ : fp + fp_)\n ]\n :\n fp)\n )\n ).flat()\n :\n fps\n}\n\n\nexport async function fstat (fp: string) {\n if (!path.isAbsolute(fp))\n throw new Error(`fp (${fp}) must be absolute path`)\n \n return fsp.stat(fp, { bigint: true })\n}\n\n\n/** delete file or directory (use rimraf to delete directory fast) \n - fp: path\n - options?:\n - print?: `true` (effective only delete single file)\n*/\nexport async function fdelete (fp: string, { print = true, fast = false }: { print?: boolean, fast?: boolean } = { }) {\n if (fp.length < 6) throw new Error(`${fp} too short`)\n if (!path.isAbsolute(fp))\n throw new Error('fpd must be absolute path')\n \n if (fp.endsWith('/')) {\n if (print)\n console.log(`delete directory: ${fp}`.red)\n await new Promise<void>((resolve, reject) => {\n rimraf(fp, { glob: false, disableGlob: true }, error => {\n if (error)\n reject(error)\n else\n resolve()\n })\n })\n } else {\n if (print)\n console.log('delete:', fp)\n await fsp.unlink(fp)\n }\n}\n\n\n/** copy file or direcotry\n - src: src file/directory absolute path\n - dst: dst file/directory absolute path\n @example\n fcopy('d:/temp/camera/', 'd:/camera/')\n*/\nexport async function fcopy (fp_src: string, fp_dst: string, {\n print = true,\n overwrite = true,\n}: {\n print?: boolean\n overwrite?: boolean\n} = { }) {\n if (fp_src.endsWith('/') !== fp_dst.endsWith('/'))\n throw new Error('fp_src and fp_dst must be both file path or directory path')\n \n if (!path.isAbsolute(fp_src) || !path.isAbsolute(fp_dst))\n throw new Error('fp_src and fp_dst must be absolute path')\n \n if (print)\n console.log(`copy: ${fp_src} → ${fp_dst}`)\n \n await fse.copy(fp_src, fp_dst, { overwrite, errorOnExist: true })\n}\n\n\n/** move file or direcotry\n - src: src file/directory absolute path\n - dst: dst file/directory absolute path\n @example\n fmove('d:/temp/camera/', 'd:/camera/')\n*/\nexport async function fmove (src: string, dst: string, {\n overwrite = false,\n print = true\n}: {\n overwrite?: boolean\n print?: boolean\n} = { }) {\n if (src.endsWith('/') !== dst.endsWith('/'))\n throw new Error('src and dst must be both file path or directory path')\n \n if (!path.isAbsolute(src) || !path.isAbsolute(dst))\n throw new Error('src and dst must be absolute path')\n \n if (print)\n console.log(`move: ${src} → ${dst}`)\n \n await fse.move(src, dst, { overwrite })\n}\n\n\n/** rename file \n - fp: current filename/path\n - fp_: new filename/path\n - options?:\n - fpd?: fp and fp_ is in same directory\n - print?: `true`\n - overwrite?: `true` better performance without check\n */\nexport async function frename (\n fp: string, \n fp_: string,\n {\n fpd,\n print = true,\n overwrite = true\n }: {\n fpd?: string\n print?: boolean\n overwrite?: boolean\n } = { }\n) {\n if (fpd) {\n fp = path.join(fpd, fp)\n fp_ = path.join(fpd, fp_)\n } else if (!path.isAbsolute(fp) || !path.isAbsolute(fp_))\n throw new Error('fp and fp_ must be absolute path')\n \n if (print)\n console.log('rename:', fp, '→', fp_)\n \n if (!overwrite && fexists(fp_))\n throw new Error(`file already exists:${fp_}`)\n \n await fsp.rename(fp, fp_)\n}\n\n\n/**\n Create folders recursively, make sure the folder pointed to by fpd exists \n Returns the first created folder or undefined\n \n - fpd: Folder full path\n - options?:\n - print?: `true`\n - mode?: `'0o777'`\n*/\nexport async function fmkdir (\n fpd: string,\n {\n print = true,\n mode,\n }: {\n print?: boolean\n \n /** `0o777` A file mode. If a string is passed, it is parsed as an octal integer. */\n mode?: string | number\n } = { }\n) {\n if (!path.isAbsolute(fpd))\n throw new Error(`fpd must be an absolute path: ${fpd}`)\n \n if (!fpd.endsWith('/'))\n throw new Error(`fpd must end with /: ${fpd}`)\n \n // CallingfsPromises.mkdir() when path is a directory that exists results in a rejection only when recursive is false.\n const fpd_ = (\n await fsp.mkdir(fpd, { recursive: true, mode })\n )?.replaceAll('\\\\', '/')\n \n if (fpd_) {\n if (print)\n console.log('folder created:', fpd)\n } else\n if (print)\n console.log('folder already exists:', fpd)\n \n return fpd_\n}\n\n\n/** \n - fp_real: current real file/directory path\n - fp_link: target file/directory path\n*/\nexport async function flink (\n fp_real: string, \n fp_link: string, \n {\n junction = false,\n print = true \n }: { \n junction?: boolean\n print?: boolean\n} = { }) {\n if (!path.isAbsolute(fp_real) || !path.isAbsolute(fp_link))\n throw new Error('fp must be absolute path')\n \n const is_fpd_real = fp_real.endsWith('/')\n const is_fpd_link = fp_link.endsWith('/')\n \n if (is_fpd_real !== is_fpd_link)\n throw new Error('fp_real and fp_link must be both file path or folder path')\n \n if (fexists(fp_link))\n throw new Error(`${ is_fpd_link ? 'folder' : 'file' } exists: ${fp_link}, could not create link`)\n \n if (print)\n console.log(`source file ${fp_real} linked to ${fp_link}`)\n \n if (junction)\n fsp.symlink(fp_real, fp_link, 'junction')\n else\n fsp.symlink(fp_real, fp_link, is_fpd_real ? 'dir' : 'file')\n}\n\n\nexport let fwatchers: Record<string, fs.FSWatcher> = { }\n\n/**\n - fp: path of file or directory\n - callback: called when modified\n - exec: call callback when watch is executed\n \n save fs.FSWatcher in watchers, subsequent call will auto close existing watcher for the same fp\n \n https://nodejs.org/dist/latest-v15.x/docs/api/fs.html#fs_fs_watch_filename_options_listener \n The listener callback gets two arguments (event, fname). \n event is either 'rename' or 'change', and filename is the name of the file which triggered the event.\n On most platforms, 'rename' is emitted whenever a filename appears or disappears in the directory.\n \n The listener callback is attached to the 'change' event fired by fs.FSWatcher, but it is not the same thing as the 'change' value of event. \n \n*/\nexport async function fwatch (\n fp: string,\n onchange: (event: string, fname: string) => any, \n { exec = true }: { exec?: boolean } = { }\n) {\n if (!path.isAbsolute(fp))\n throw new Error('fp must be absolute path')\n \n const _watcher = fwatchers[fp]\n if (_watcher)\n _watcher.close()\n \n if (exec)\n await onchange('change', fp.fname)\n \n const start = new Date().getTime()\n \n const debounced_onchange = debounce(\n (event, fname) => {\n if (new Date().getTime() - start < 800)\n return\n console.log(`file ${event}: ${fname}`)\n onchange(event, path.normalize(fname))\n },\n 500,\n { leading: false, trailing: true }\n )\n \n let watcher = fs.watch(fp, debounced_onchange)\n watcher.on('error', error => {\n console.error(error)\n })\n return fwatchers[fp] = watcher\n}\n\n\n/** open a file and replace certain pattern */\nexport async function freplace (fp: string, pattern: string | RegExp, replacement: string) {\n await fwrite(\n fp,\n (await fread(fp))\n .replaceAll(pattern, replacement)\n )\n}\n\n/** convert file encoding to UTF-8\n - fp: file absolute path\n - options?:\n - dryrun?: `true`\n - encoding?: `'auto'`\n*/\nexport async function f2utf8 (fp: string, {\n dryrun = true,\n encoding = 'auto',\n}: {\n dryrun?: boolean\n encoding?: Encoding | 'auto'\n} = { }) {\n const text = await fread(fp, { encoding })\n if (dryrun) {\n console.log(text.slice(0, 10000))\n return\n }\n \n const fp_bak = `${fp.fdir}${fp.fname.replace(/(.*?)(\\.[^.]+)?$/, '$1.bak$2')}`\n if (!fexists(fp_bak))\n await fcopy(fp, fp_bak)\n \n await fwrite(fp, text)\n}\n\n"]}
1
+ {"version":3,"file":"file.js","sourceRoot":"","sources":["file.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n promises as fsp,\n default as fs,\n} from 'fs'\ntype FileHandle = fsp.FileHandle & { fp: string }\n\nimport path from 'upath'\nimport iconv from 'iconv-lite'\nimport fse from 'fs-extra'\n\nimport debounce from 'lodash/debounce.js'\n\n\nimport MFS from 'memfs'\ndeclare module 'memfs' {\n interface IFs {\n join: typeof path.join\n is_mfs: true\n }\n}\n\nimport { to_json } from './prototype.js'\nexport * from './ufs.js'\n\n\nexport { MFS }\n\nexport type Encoding = 'utf-8' | 'gb18030' | 'shift-jis' | 'binary'\n\n\n/** Does the file/folder pointed to by fp exist? */\nexport function fexists (fp: string, { print = true }: { print?: boolean } = { }) {\n const exists = fs.existsSync(fp)\n \n if (print)\n console.log(\n exists ? 'exists:' : 'not exists:',\n fp\n )\n \n return exists\n}\n\n\n/**\n open file, return FileHandle \n Some characters (`< > : \" / \\ | ? *`) are reserved under Windows as documented\n by [Naming Files, Paths, and Namespaces](https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file). Under NTFS, if the filename contains\n a colon, Node.js will open a file system stream, as described by [this MSDN page](https://docs.microsoft.com/en-us/windows/desktop/FileIO/using-streams).\n \n - flags: `'r'`\n - options?:\n - mode?: `'0o666'` Sets the file mode (permission and sticky bits) if the file is created.\n*/\nexport async function fopen (\n fp: string,\n flags: string | number,\n {\n mode,\n print\n }: {\n mode?: fs.Mode\n print?: boolean\n } = { }\n) {\n if (print)\n console.log('fopen:', fp)\n return Object.assign(\n await fsp.open(fp, flags, mode),\n {\n fp,\n flags,\n mode\n }\n )\n}\n\n\nexport function create_mfs () {\n let mfs = MFS.createFsFromVolume(\n new MFS.Volume()\n )\n \n mfs.join = path.join.bind(path)\n mfs.is_mfs = true\n \n return mfs\n}\n\n\nexport async function fread (fp: string): Promise<string>\nexport async function fread (fp: string, { dir, encoding, print }?: { dir?: string, encoding: 'binary', print?: boolean }): Promise<Buffer>\nexport async function fread (fp: string, { dir, encoding, print }?: { dir?: string, encoding?: Encoding | 'auto', print?: boolean }): Promise<string>\nexport async function fread (fp: string, {\n dir, \n encoding = 'utf-8', \n print = true\n}: {\n dir?: string\n encoding?: Encoding | 'auto'\n print?: boolean } = { }\n) {\n if (dir)\n fp = path.join(dir, fp)\n else if (!path.isAbsolute(fp))\n throw new Error('fp must be absolute path, or pass in \\'dir\\' parameter')\n \n if (print)\n console.log(`read: ${fp}`)\n \n const buffer = await fsp.readFile(fp)\n \n if (encoding === 'binary')\n return buffer\n \n if (encoding === 'utf-8')\n return buffer.toString('utf8')\n \n if (encoding === 'auto') {\n const { detect } = await import('chardet')\n encoding = detect(buffer) as any\n if (print)\n console.log(`${fp} probably has encoding: ${encoding.toLowerCase()}`)\n }\n \n return iconv.decode(buffer, encoding)\n}\n\nexport async function fread_lines (fp: string, options: { dir?: string, encoding?: Exclude<Encoding, 'binary'> | 'auto', print?: boolean } = { }) {\n return (await fread(fp, options))\n .split_lines()\n}\n\nexport async function fread_json <T = any> (fp: string, options: { dir?: string, encoding?: Encoding, print?: boolean } = { }): Promise<T> {\n return JSON.parse(\n await fread(fp, options)\n )\n}\n\n\nexport async function fwrite (fp: string | FileHandle, data: Buffer, options?: { dir?: string, print?: boolean, mkdir?: boolean }): Promise<void>\nexport async function fwrite (fp: string | FileHandle, data: any, options?: { dir?: string, encoding?: Encoding, print?: boolean, mkdir?: boolean }): Promise<void>\nexport async function fwrite (\n fp: string | FileHandle,\n data: any,\n {\n dir,\n encoding = 'utf-8',\n print = true,\n mkdir = false,\n }: {\n dir?: string\n encoding?: Encoding\n print?: boolean\n mkdir?: boolean\n } = { }\n) {\n const is_handle = typeof fp === 'object' && fp && 'fd' in fp\n if (is_handle) {\n if (print)\n console.log('write:', (fp as FileHandle).fp)\n } else {\n if (dir)\n fp = path.join(dir, fp)\n else if (!path.isAbsolute(fp as string))\n throw new Error('fp must be absolute path, or pass in \"dir\" parameter')\n \n if (print)\n console.log('write:', fp)\n }\n \n if (encoding === 'gb18030')\n data = iconv.encode(data, encoding)\n \n if (!Buffer.isBuffer(data) && typeof data !== 'string')\n data = to_json(data)\n \n try {\n await fsp.writeFile(fp, data)\n } catch (error) {\n if (!mkdir || error.code !== 'ENOENT' || is_handle)\n throw error\n \n await fmkdir((fp as string).fdir)\n await fsp.writeFile(fp, data)\n }\n}\n\nexport async function fappend (fp: string, data: any, { dir, print = true }: { dir?: string, print?: boolean } = { }) {\n if (dir)\n fp = path.join(dir, fp)\n else if (!path.isAbsolute(fp))\n throw new Error('fp must be absolute path, or pass in \"dir\" parameter')\n \n if (print)\n console.log('append:', fp)\n \n if (!Buffer.isBuffer(data) && typeof data !== 'string')\n throw new Error('data is not Buffer or string')\n \n await fsp.appendFile(fp, data)\n}\n\n\n/**\n - fpd: absolute path of directory\n - optoins?:\n - deep?: `false` recursively\n - absolute?: `false` Return, print full path instead of relative path\n - print?: `true`\n - filter?: `true` RegExp | (fp: string) => any, Note that when deep = true, \n directories and files in directories that are filtered out by the filter will not be included in the results\n*/\nexport async function flist (\n fpd: string,\n options: {\n filter?: RegExp | ((fp: string) => any)\n deep?: boolean\n absolute?: boolean\n print?: boolean\n } = { }\n): Promise<string[]> {\n const {\n filter,\n deep = false,\n absolute = false,\n print = true,\n } = options\n \n if (!path.isAbsolute(fpd))\n throw new Error(`fpd (${fpd}) must be absolute path`)\n \n if (!fpd.endsWith('/'))\n throw new Error(`Argument fpd (${fpd}) must end with /`)\n \n // readdir withFileTypes 参数在底层有什么区别,速度上有什么差异\n // 都调用了 uv_fs_scandir, 且调用参数相同,仅仅是 Node.js 侧的回调不同 AfterScanDir / AfterScanDirWithTypes\n // 回调中通过 uv_fs_scandir_next 获取到每个条目的信息,而 uv_fs_scandir_next 中都会读取 type\n // 速度上:都在 0.2 ms 左右就可以完成\n \n const files = await fsp.readdir(fpd, {\n withFileTypes: true,\n encoding: 'utf-8',\n })\n \n const filter_regexp = filter instanceof RegExp\n const filter_fn = Boolean(filter && !filter_regexp)\n \n let fps: string[] = [ ]\n \n for (const file of files) {\n const fp = \n (absolute ? fpd : '') +\n file.name +\n (file.isDirectory() ? '/' : '')\n \n if (filter_regexp && !filter.test(fp))\n continue\n \n if (filter_fn && !(filter as Function)(fp))\n continue\n \n if (print)\n console.log(\n deep || absolute ? fpd + fp : fp\n )\n \n fps.push(fp)\n }\n \n return deep ? (\n await Promise.all(\n fps.map(async fp => \n fp.endsWith('/') ?\n [\n fp,\n ... (await flist(\n absolute ? fp : fpd + fp,\n options\n )).map(fp_ => \n absolute ? fp_ : fp + fp_)\n ]\n :\n fp)\n )\n ).flat()\n :\n fps\n}\n\n\nexport async function fstat (fp: string) {\n if (!path.isAbsolute(fp))\n throw new Error(`fp (${fp}) must be absolute path`)\n \n return fsp.stat(fp, { bigint: true })\n}\n\n\n/** delete files or folders \n - fp: file path\n - options?:\n - print?: `true`\n \n Returns whether the delete operation actually took place\n*/\nexport async function fdelete (fp: string, { print = true }: { print?: boolean } = { }) {\n if (fp.length < 6)\n throw new Error(`${fp} 太短`)\n \n if (!path.isAbsolute(fp))\n throw new Error('fp must be an absolute path')\n \n try {\n await fsp.rm(fp, { recursive: true })\n if (print)\n if (fp.endsWith('/'))\n console.log(`deleted folder: ${fp}`.red)\n else\n console.log(`deleted file: ${fp}`.red)\n return true\n } catch (error) {\n if (error.code === 'ENOENT') {\n if (print)\n if (fp.endsWith('/'))\n console.log(`folder no longer exists: ${fp}`)\n else\n console.log(`file no longer exists: ${fp}`)\n return false\n }\n \n throw error\n }\n}\n\n\n/** copy file or direcotry\n - src: src file/directory absolute path\n - dst: dst file/directory absolute path\n @example\n fcopy('d:/temp/camera/', 'd:/camera/')\n*/\nexport async function fcopy (fp_src: string, fp_dst: string, {\n print = true,\n overwrite = true,\n}: {\n print?: boolean\n overwrite?: boolean\n} = { }) {\n if (fp_src.endsWith('/') !== fp_dst.endsWith('/'))\n throw new Error('fp_src and fp_dst must be both file path or directory path')\n \n if (!path.isAbsolute(fp_src) || !path.isAbsolute(fp_dst))\n throw new Error('fp_src and fp_dst must be absolute path')\n \n if (print)\n console.log(`copy: ${fp_src} → ${fp_dst}`)\n \n await fse.copy(fp_src, fp_dst, { overwrite, errorOnExist: true })\n}\n\n\n/** move file or direcotry\n - src: src file/directory absolute path\n - dst: dst file/directory absolute path\n @example\n fmove('d:/temp/camera/', 'd:/camera/')\n*/\nexport async function fmove (src: string, dst: string, {\n overwrite = false,\n print = true\n}: {\n overwrite?: boolean\n print?: boolean\n} = { }) {\n if (src.endsWith('/') !== dst.endsWith('/'))\n throw new Error('src and dst must be both file path or directory path')\n \n if (!path.isAbsolute(src) || !path.isAbsolute(dst))\n throw new Error('src and dst must be absolute path')\n \n if (print)\n console.log(`move: ${src} → ${dst}`)\n \n await fse.move(src, dst, { overwrite })\n}\n\n\n/** rename file \n - fp: current filename/path\n - fp_: new filename/path\n - options?:\n - fpd?: fp and fp_ is in same directory\n - print?: `true`\n - overwrite?: `true` better performance without check\n */\nexport async function frename (\n fp: string, \n fp_: string,\n {\n fpd,\n print = true,\n overwrite = true\n }: {\n fpd?: string\n print?: boolean\n overwrite?: boolean\n } = { }\n) {\n if (fpd) {\n fp = path.join(fpd, fp)\n fp_ = path.join(fpd, fp_)\n } else if (!path.isAbsolute(fp) || !path.isAbsolute(fp_))\n throw new Error('fp and fp_ must be absolute path')\n \n if (print)\n console.log('rename:', fp, '→', fp_)\n \n if (!overwrite && fexists(fp_))\n throw new Error(`file already exists:${fp_}`)\n \n await fsp.rename(fp, fp_)\n}\n\n\n/**\n Create folders recursively, make sure the folder pointed to by fpd exists \n Returns the first created folder or undefined\n \n - fpd: Folder full path\n - options?:\n - print?: `true`\n - mode?: `'0o777'`\n*/\nexport async function fmkdir (\n fpd: string,\n {\n print = true,\n mode,\n }: {\n print?: boolean\n \n /** `0o777` A file mode. If a string is passed, it is parsed as an octal integer. */\n mode?: string | number\n } = { }\n) {\n if (!path.isAbsolute(fpd))\n throw new Error(`fpd must be an absolute path: ${fpd}`)\n \n if (!fpd.endsWith('/'))\n throw new Error(`fpd must end with /: ${fpd}`)\n \n // CallingfsPromises.mkdir() when path is a directory that exists results in a rejection only when recursive is false.\n const fpd_ = (\n await fsp.mkdir(fpd, { recursive: true, mode })\n )?.replaceAll('\\\\', '/')\n \n if (fpd_) {\n if (print)\n console.log('folder created:', fpd)\n } else\n if (print)\n console.log('folder already exists:', fpd)\n \n return fpd_\n}\n\n\n/** \n - fp_real: current real file/directory path\n - fp_link: target file/directory path\n*/\nexport async function flink (\n fp_real: string, \n fp_link: string, \n {\n junction = false,\n print = true \n }: { \n junction?: boolean\n print?: boolean\n} = { }) {\n if (!path.isAbsolute(fp_real) || !path.isAbsolute(fp_link))\n throw new Error('fp must be absolute path')\n \n const is_fpd_real = fp_real.endsWith('/')\n const is_fpd_link = fp_link.endsWith('/')\n \n if (is_fpd_real !== is_fpd_link)\n throw new Error('fp_real and fp_link must be both file path or folder path')\n \n if (fexists(fp_link))\n throw new Error(`${ is_fpd_link ? 'folder' : 'file' } exists: ${fp_link}, could not create link`)\n \n if (print)\n console.log(`source file ${fp_real} linked to ${fp_link}`)\n \n if (junction)\n fsp.symlink(fp_real, fp_link, 'junction')\n else\n fsp.symlink(fp_real, fp_link, is_fpd_real ? 'dir' : 'file')\n}\n\n\nexport let fwatchers: Record<string, fs.FSWatcher> = { }\n\n/**\n - fp: path of file or directory\n - callback: called when modified\n - exec: call callback when watch is executed\n \n save fs.FSWatcher in watchers, subsequent call will auto close existing watcher for the same fp\n \n https://nodejs.org/dist/latest-v15.x/docs/api/fs.html#fs_fs_watch_filename_options_listener \n The listener callback gets two arguments (event, fname). \n event is either 'rename' or 'change', and filename is the name of the file which triggered the event.\n On most platforms, 'rename' is emitted whenever a filename appears or disappears in the directory.\n \n The listener callback is attached to the 'change' event fired by fs.FSWatcher, but it is not the same thing as the 'change' value of event. \n \n*/\nexport async function fwatch (\n fp: string,\n onchange: (event: string, fname: string) => any, \n { exec = true }: { exec?: boolean } = { }\n) {\n if (!path.isAbsolute(fp))\n throw new Error('fp must be absolute path')\n \n const _watcher = fwatchers[fp]\n if (_watcher)\n _watcher.close()\n \n if (exec)\n await onchange('change', fp.fname)\n \n const start = new Date().getTime()\n \n const debounced_onchange = debounce(\n (event, fname) => {\n if (new Date().getTime() - start < 800)\n return\n console.log(`file ${event}: ${fname}`)\n onchange(event, path.normalize(fname))\n },\n 500,\n { leading: false, trailing: true }\n )\n \n let watcher = fs.watch(fp, debounced_onchange)\n watcher.on('error', error => {\n console.error(error)\n })\n return fwatchers[fp] = watcher\n}\n\n\n/** open a file and replace certain pattern */\nexport async function freplace (fp: string, pattern: string | RegExp, replacement: string) {\n await fwrite(\n fp,\n (await fread(fp))\n .replaceAll(pattern, replacement)\n )\n}\n\n/** convert file encoding to UTF-8\n - fp: file absolute path\n - options?:\n - dryrun?: `true`\n - encoding?: `'auto'`\n*/\nexport async function f2utf8 (fp: string, {\n dryrun = true,\n encoding = 'auto',\n}: {\n dryrun?: boolean\n encoding?: Encoding | 'auto'\n} = { }) {\n const text = await fread(fp, { encoding })\n if (dryrun) {\n console.log(text.slice(0, 10000))\n return\n }\n \n const fp_bak = `${fp.fdir}${fp.fname.replace(/(.*?)(\\.[^.]+)?$/, '$1.bak$2')}`\n if (!fexists(fp_bak))\n await fcopy(fp, fp_bak)\n \n await fwrite(fp, text)\n}\n\n"]}
package/net.browser.d.ts CHANGED
@@ -21,6 +21,12 @@ export declare function request(url: string | URL, options: RequestRawOptions):
21
21
  export declare function request(url: string | URL, options: RequestOptions): Promise<string>;
22
22
  /** 发起 http 请求并将响应体作为 json 解析 */
23
23
  export declare function request_json<T = any>(url: string, options?: RequestOptions): Promise<T>;
24
+ /** 连接 websocket url, 设置各种事件监听器
25
+ - url
26
+ - options:
27
+ - on_message: 根据 websocket frame 的 opcode 不同 (text frame 或 binary frame) event 中的 data 对应为 ArrayBuffer 或者 string
28
+ https://datatracker.ietf.org/doc/html/rfc6455#section-5.2
29
+ */
24
30
  export declare function connect_websocket(url: string | URL, { protocols, on_open, on_close, on_error, on_message }: {
25
31
  protocols?: string | string[];
26
32
  on_open?(event: any, websocket: WebSocket): any;
@@ -30,7 +36,7 @@ export declare function connect_websocket(url: string | URL, { protocols, on_ope
30
36
  }, websocket: WebSocket): any;
31
37
  on_error?(event: any, websocket: WebSocket): any;
32
38
  on_message(event: {
33
- data: ArrayBuffer;
39
+ data: ArrayBuffer | string;
34
40
  }, websocket: WebSocket): any;
35
41
  }): Promise<WebSocket>;
36
42
  /** 二进制消息格式
package/net.browser.js CHANGED
@@ -66,6 +66,12 @@ export async function request_json(url, options) {
66
66
  }
67
67
  let decoder = new TextDecoder();
68
68
  let encoder = new TextEncoder();
69
+ /** 连接 websocket url, 设置各种事件监听器
70
+ - url
71
+ - options:
72
+ - on_message: 根据 websocket frame 的 opcode 不同 (text frame 或 binary frame) event 中的 data 对应为 ArrayBuffer 或者 string
73
+ https://datatracker.ietf.org/doc/html/rfc6455#section-5.2
74
+ */
69
75
  export async function connect_websocket(url, { protocols, on_open, on_close, on_error, on_message }) {
70
76
  let websocket = new WebSocket(url, protocols);
71
77
  // https://stackoverflow.com/questions/11821096/what-is-the-difference-between-an-arraybuffer-and-a-blob/39951543
@@ -1 +1 @@
1
- {"version":3,"file":"net.browser.js","sourceRoot":"","sources":["net.browser.ts"],"names":[],"mappings":"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","sourcesContent":["/// <reference types='tampermonkey' />\n\nimport { concat } from './utils.browser.js'\n\nexport interface RequestOptions {\n method?: 'get' | 'post' | 'put' | 'head' | 'delete' | 'patch'\n \n queries?: Record<string, any>\n \n headers?: Record<string, string>\n \n body?: string | object | HTMLFormElement\n \n type?: 'application/json' | 'application/x-www-form-urlencoded' | 'multipart/form-data'\n \n cors?: boolean\n \n by?: 'fetch' | 'GM_xmlhttpRequest'\n}\n\nexport interface RequestRawOptions extends RequestOptions {\n raw: true\n}\n\n/**\n - url: 可以只有 pathname 部分\n - options:\n - type: `'application/json'` 请求的 content-type 头 (如果有 body)\n - by: `window.GM_xmlhttpRequest ? 'GM_xmlhttpRequest' : 'fetch'` 发起请求所使用的底层方法\n*/\nexport async function request (url: string | URL): Promise<string>\nexport async function request (url: string | URL, options: RequestRawOptions): Promise<Response>\nexport async function request (url: string | URL, options: RequestOptions): Promise<string>\nexport async function request (url: string | URL, {\n method,\n \n queries,\n \n headers,\n \n body,\n \n type = 'application/json',\n \n cors,\n \n by = window.GM_xmlhttpRequest ? 'GM_xmlhttpRequest' : 'fetch',\n \n raw,\n}: RequestOptions & { raw?: boolean } = { }) {\n url = new URL(url, location.href)\n \n if (queries)\n for (const key in queries) {\n let value = queries[key]\n if (typeof value === 'boolean')\n value = value ? '1' : '0'\n url.searchParams.append(key, value)\n }\n \n if (body && !method)\n method = 'post'\n \n if (type === 'application/json' && typeof body !== 'undefined' && typeof body !== 'string')\n body = JSON.stringify(body)\n \n url = url.toString()\n \n if (by === 'fetch') {\n const options: RequestInit = {\n ... method ? { method: method.toUpperCase() } : { },\n \n ... cors ? { mode: 'cors' } : { },\n \n credentials: 'include',\n \n headers: {\n ... body ? { 'content-type': type } : { },\n ... headers,\n },\n \n ... body ? { body: body as string } : { },\n }\n \n const response = await fetch(\n url,\n options\n )\n \n if (!response.ok)\n throw Object.assign(\n new Error(`StatusCodeError: ${response.status}`),\n { url, response, ...options }\n )\n \n if (raw)\n return response\n \n return response.text()\n }\n \n \n return new Promise((resolve, reject) => {\n GM_xmlhttpRequest({\n ... method ? { method: (method as any).toUpperCase() } : { },\n \n url: url as string,\n \n headers: {\n ... body ? { 'content-type': type } : { },\n ... headers,\n },\n \n ... body ? { data: body as string, } : { },\n \n onload (response) {\n if (!(200 <= response.status && response.status <= 299)) {\n reject(\n Object.assign(\n new Error(`StatusCodeError: ${response.status}`), \n { url, queries, method, headers, body, response }\n )\n )\n return\n }\n \n resolve(response.responseText)\n }\n })\n })\n}\n\n\n/** 发起 http 请求并将响应体作为 json 解析 */\nexport async function request_json <T = any> (url: string, options?: RequestOptions): Promise<T> {\n const resp = await request(url, options)\n if (!resp) return\n try {\n return JSON.parse(resp)\n } catch (error) {\n console.error(resp)\n throw error\n }\n}\n\n\n\nlet decoder = new TextDecoder()\n\nlet encoder = new TextEncoder()\n\n\nexport async function connect_websocket (\n url: string | URL,\n {\n protocols,\n on_open,\n on_close,\n on_error,\n on_message\n }: {\n protocols?: string | string[]\n on_open? (event: any, websocket: WebSocket): any\n on_close? (event: { code: number, reason: string }, websocket: WebSocket): any\n on_error? (event: any, websocket: WebSocket): any\n on_message (event: { data: ArrayBuffer }, websocket: WebSocket): any\n }\n) {\n let websocket = new WebSocket(url, protocols)\n \n // https://stackoverflow.com/questions/11821096/what-is-the-difference-between-an-arraybuffer-and-a-blob/39951543\n websocket.binaryType = 'arraybuffer'\n \n return new Promise<WebSocket>((resolve, reject) => {\n websocket.addEventListener('open', async event => {\n console.log(`${websocket.url} opened`)\n \n await on_open?.(event, websocket)\n \n resolve(websocket)\n })\n \n websocket.addEventListener('close', event => {\n console.log(`${websocket.url} closed with code = ${event.code}, reason = '${event.reason}'`)\n on_close?.(event, websocket)\n })\n \n websocket.addEventListener('error', event => {\n const message = `${websocket.url} errored`\n on_error?.(event, websocket)\n reject(\n Object.assign(\n new Error(message),\n { event }\n )\n )\n })\n \n websocket.addEventListener('message', event => {\n on_message(event as any, websocket)\n })\n })\n}\n\n\n/** 二进制消息格式 \n - json.length (小端序): 4 字节\n - json 数据\n - binary 数据\n*/\nexport interface Message <T extends any[] = any[]> {\n /** 本次 rpc 的 id */\n id?: number\n \n /** rpc 发起方指定被调用的 function name, 多个相同 id, func 的 message 组成一个请求流 */\n func?: string\n \n /** 等待执行,但不要序列化返回 func 的执行结果 (message 中无 args) */\n ignore?: boolean\n \n /** 不等待 func 执行,remote 收到后直接确认返回 (message 中 done = true) */\n async?: boolean\n \n /** 这个数组里面要么是对应的 JS 参数,要么是 Uint8Array 参数对应的 binary length \n args 可以是: \n - rpc 发起方调用 func 的参数,或者请求流 message 携带的数据\n - 作为结果或者响应流的 message 数据,传给请求发起方\n */\n args?: T\n \n /** bins: 哪几个 arg 是 Uint8Array 类型的,如: [0, 3] */\n bins?: number[]\n \n /** 被调方执行 func 产生的错误 */\n error?: Error\n \n /** 如果请求或者响应是一个流,通过这个 flag 表明是最后一个 message, 并且可以销毁 handler 了 */\n done?: boolean\n}\n\n/** 通过创建 Remote 对象对 WebSocket RPC 进行抽象 \n 调用方使用 remote.call 进行调用 \n 被调方在创建 Remote 对象时传入 funcs 注册处理函数,并使用 Remote.handle 方法处理 WebSocket message \n*/\nexport class Remote {\n url: string\n \n websocket: WebSocket\n \n id = 0\n \n /** 被调方的 message 处理器 */\n funcs: Record<\n string, \n (message: Message, websocket?: WebSocket) => void | Promise<void>\n > = { }\n \n /** 调用方发起的 rpc 对应响应的 message 处理器 */\n handlers: ((message: Message) => any)[] = [ ]\n \n print = false\n \n /** 在未连接时或连接断开后,调用 call 是否自动连接到 remote */\n autoconnect = true\n \n pconnect: Promise<any>\n \n \n get connected () {\n return this.websocket?.readyState === WebSocket.OPEN\n }\n \n \n static parse <T extends any[] = any[]> (array_buffer: ArrayBuffer) {\n const buf = new Uint8Array(array_buffer as ArrayBuffer)\n const dv = new DataView(array_buffer)\n \n const len_json = dv.getUint32(0, true)\n \n let offset = 4 + len_json\n \n let message: Message<T> = JSON.parse(\n decoder.decode(\n buf.subarray(4, offset)\n )\n )\n \n if (message.bins) {\n const { bins } = message\n let { args } = message\n \n for (const ibin of bins) {\n const len_buf = args[ibin]\n args[ibin] = buf.subarray(offset, offset + len_buf)\n offset += len_buf\n }\n }\n \n return message\n }\n \n \n static pack ({\n id,\n func,\n ignore,\n async: _async,\n done,\n error,\n args: _args = [ ],\n }: Message) {\n let args = [..._args]\n \n let bins: number[] = [ ]\n let bufs: Uint8Array[] = [ ]\n \n for (let i = 0; i < args.length; i++) {\n const arg = args[i]\n if (arg instanceof Uint8Array) {\n bins.push(i)\n bufs.push(arg)\n args[i] = arg.length\n }\n }\n \n const data_json = {\n id,\n ... func ? { func } : { },\n ... ignore ? { ignore } : { },\n ... _async ? { async: _async } : { },\n ... done ? { done } : { },\n ... error ? { error } : { },\n ... args.length ? { args } : { },\n ... bins.length ? { bins } : { },\n }\n \n const str_json = encoder.encode(\n JSON.stringify(data_json)\n )\n \n let dv = new DataView(\n new ArrayBuffer(4)\n )\n \n dv.setUint32(0, str_json.length, true)\n \n return concat([\n dv,\n str_json,\n ... bufs\n ])\n }\n \n \n constructor ({\n url,\n funcs,\n websocket,\n autoconnect\n }: {\n url?: string\n funcs?: Remote['funcs']\n websocket?: WebSocket\n autoconnect?: boolean\n } = { }) {\n this.url = url\n \n if (funcs)\n this.funcs = funcs\n \n this.websocket = websocket\n \n if (typeof autoconnect !== 'undefined')\n this.autoconnect = autoconnect\n }\n \n \n async connect () {\n this.websocket = await connect_websocket(this.url, {\n on_message: this.handle.bind(this),\n on_close: () => {\n this.id = 0\n this.handlers = [ ]\n },\n })\n }\n \n \n disconnect () {\n this.websocket?.close()\n this.id = 0\n this.handlers = [ ]\n }\n \n \n send (message: Message, websocket = this.websocket) {\n if (websocket?.readyState !== WebSocket.OPEN)\n throw new Error(`${websocket?.url || 'websocket'} 已断开,无法调用 remote.send`)\n \n if (!('id' in message))\n message.id = this.id\n \n websocket.send(\n Remote.pack(message)\n )\n }\n \n \n /** 调用 remote 中的 func, 中间消息及返回结果可由 handler 处理,处理 done message 之后的返回值作为 call 函数的返回值 \n 如果为 unary rpc, 可以不传 handler, await call 之后可以得到响应 message 的 args\n */\n async call <T extends any[] = any[]> (\n message: Message,\n handler?: (message: Message<T>) => any\n ) {\n if (!this.connected)\n if (this.autoconnect) {\n // 临界区:保证多个 call 并发时只连接一次\n const ptail = this.pconnect\n \n let resolve: () => void\n this.pconnect = new Promise<void>((_resolve, _reject) => {\n resolve = _resolve\n })\n \n try {\n await ptail\n } catch { }\n // 临界区结束,只有一个 call 调用运行到这里,可以开始连接 WebSocket\n \n if (!this.connected) {\n if (this.websocket)\n console.log(`${this.url} 已断开,尝试自动重连`)\n else\n console.log(`${this.url} 未连接,尝试自动连接`)\n \n try {\n await this.connect()\n } finally {\n resolve()\n }\n }\n } else\n throw new Error(`${this.url} 未连接或已断开,无法调用 remote.call`)\n \n return new Promise<T>((resolve, reject) => {\n this.handlers[this.id] = async (message: Message<T>) => {\n const { error, done } = message\n \n if (error) {\n reject(\n Object.assign(\n new Error(),\n error\n )\n )\n return\n }\n \n const result = handler ?\n await handler(message)\n :\n message.args\n \n if (done)\n resolve(result)\n }\n \n this.send(message)\n \n this.id++\n })\n }\n \n \n /** 处理接收到的 WebSocket message\n 1. 被调用方接收 message 并开始处理\n 2. 调用方处理 message 响应\n */\n async handle (event: { data: ArrayBuffer }, websocket: WebSocket) {\n const message = Remote.parse(event.data)\n \n const { func, id, done } = message\n \n if (this.print)\n console.log(message)\n \n if (func) // 作为被调方\n try {\n const handler = this.funcs[func]\n \n if (!handler)\n throw new Error(`找不到 rpc handler for '${func}'`)\n \n await handler(message, websocket)\n } catch (error) {\n this.send(\n {\n id,\n error,\n done: true\n },\n websocket\n )\n \n throw error\n }\n else { // 作为发起方\n this.handlers[id](message)\n \n if (done)\n this.handlers[id] = null\n }\n }\n}\n\n\n"]}
1
+ {"version":3,"file":"net.browser.js","sourceRoot":"","sources":["net.browser.ts"],"names":[],"mappings":"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","sourcesContent":["/// <reference types='tampermonkey' />\n\nimport { concat } from './utils.browser.js'\n\nexport interface RequestOptions {\n method?: 'get' | 'post' | 'put' | 'head' | 'delete' | 'patch'\n \n queries?: Record<string, any>\n \n headers?: Record<string, string>\n \n body?: string | object | HTMLFormElement\n \n type?: 'application/json' | 'application/x-www-form-urlencoded' | 'multipart/form-data'\n \n cors?: boolean\n \n by?: 'fetch' | 'GM_xmlhttpRequest'\n}\n\nexport interface RequestRawOptions extends RequestOptions {\n raw: true\n}\n\n/**\n - url: 可以只有 pathname 部分\n - options:\n - type: `'application/json'` 请求的 content-type 头 (如果有 body)\n - by: `window.GM_xmlhttpRequest ? 'GM_xmlhttpRequest' : 'fetch'` 发起请求所使用的底层方法\n*/\nexport async function request (url: string | URL): Promise<string>\nexport async function request (url: string | URL, options: RequestRawOptions): Promise<Response>\nexport async function request (url: string | URL, options: RequestOptions): Promise<string>\nexport async function request (url: string | URL, {\n method,\n \n queries,\n \n headers,\n \n body,\n \n type = 'application/json',\n \n cors,\n \n by = window.GM_xmlhttpRequest ? 'GM_xmlhttpRequest' : 'fetch',\n \n raw,\n}: RequestOptions & { raw?: boolean } = { }) {\n url = new URL(url, location.href)\n \n if (queries)\n for (const key in queries) {\n let value = queries[key]\n if (typeof value === 'boolean')\n value = value ? '1' : '0'\n url.searchParams.append(key, value)\n }\n \n if (body && !method)\n method = 'post'\n \n if (type === 'application/json' && typeof body !== 'undefined' && typeof body !== 'string')\n body = JSON.stringify(body)\n \n url = url.toString()\n \n if (by === 'fetch') {\n const options: RequestInit = {\n ... method ? { method: method.toUpperCase() } : { },\n \n ... cors ? { mode: 'cors' } : { },\n \n credentials: 'include',\n \n headers: {\n ... body ? { 'content-type': type } : { },\n ... headers,\n },\n \n ... body ? { body: body as string } : { },\n }\n \n const response = await fetch(\n url,\n options\n )\n \n if (!response.ok)\n throw Object.assign(\n new Error(`StatusCodeError: ${response.status}`),\n { url, response, ...options }\n )\n \n if (raw)\n return response\n \n return response.text()\n }\n \n \n return new Promise((resolve, reject) => {\n GM_xmlhttpRequest({\n ... method ? { method: (method as any).toUpperCase() } : { },\n \n url: url as string,\n \n headers: {\n ... body ? { 'content-type': type } : { },\n ... headers,\n },\n \n ... body ? { data: body as string, } : { },\n \n onload (response) {\n if (!(200 <= response.status && response.status <= 299)) {\n reject(\n Object.assign(\n new Error(`StatusCodeError: ${response.status}`), \n { url, queries, method, headers, body, response }\n )\n )\n return\n }\n \n resolve(response.responseText)\n }\n })\n })\n}\n\n\n/** 发起 http 请求并将响应体作为 json 解析 */\nexport async function request_json <T = any> (url: string, options?: RequestOptions): Promise<T> {\n const resp = await request(url, options)\n if (!resp) return\n try {\n return JSON.parse(resp)\n } catch (error) {\n console.error(resp)\n throw error\n }\n}\n\n\n\nlet decoder = new TextDecoder()\n\nlet encoder = new TextEncoder()\n\n\n/** 连接 websocket url, 设置各种事件监听器 \n - url\n - options:\n - on_message: 根据 websocket frame 的 opcode 不同 (text frame 或 binary frame) event 中的 data 对应为 ArrayBuffer 或者 string\n https://datatracker.ietf.org/doc/html/rfc6455#section-5.2\n*/\nexport async function connect_websocket (\n url: string | URL,\n {\n protocols,\n on_open,\n on_close,\n on_error,\n on_message\n }: {\n protocols?: string | string[]\n on_open? (event: any, websocket: WebSocket): any\n on_close? (event: { code: number, reason: string }, websocket: WebSocket): any\n on_error? (event: any, websocket: WebSocket): any\n on_message (event: { data: ArrayBuffer | string }, websocket: WebSocket): any\n }\n) {\n let websocket = new WebSocket(url, protocols)\n \n // https://stackoverflow.com/questions/11821096/what-is-the-difference-between-an-arraybuffer-and-a-blob/39951543\n websocket.binaryType = 'arraybuffer'\n \n return new Promise<WebSocket>((resolve, reject) => {\n websocket.addEventListener('open', async event => {\n console.log(`${websocket.url} opened`)\n \n await on_open?.(event, websocket)\n \n resolve(websocket)\n })\n \n websocket.addEventListener('close', event => {\n console.log(`${websocket.url} closed with code = ${event.code}, reason = '${event.reason}'`)\n on_close?.(event, websocket)\n })\n \n websocket.addEventListener('error', event => {\n const message = `${websocket.url} errored`\n on_error?.(event, websocket)\n reject(\n Object.assign(\n new Error(message),\n { event }\n )\n )\n })\n \n websocket.addEventListener('message', event => {\n on_message(event as any, websocket)\n })\n })\n}\n\n\n/** 二进制消息格式 \n - json.length (小端序): 4 字节\n - json 数据\n - binary 数据\n*/\nexport interface Message <T extends any[] = any[]> {\n /** 本次 rpc 的 id */\n id?: number\n \n /** rpc 发起方指定被调用的 function name, 多个相同 id, func 的 message 组成一个请求流 */\n func?: string\n \n /** 等待执行,但不要序列化返回 func 的执行结果 (message 中无 args) */\n ignore?: boolean\n \n /** 不等待 func 执行,remote 收到后直接确认返回 (message 中 done = true) */\n async?: boolean\n \n /** 这个数组里面要么是对应的 JS 参数,要么是 Uint8Array 参数对应的 binary length \n args 可以是: \n - rpc 发起方调用 func 的参数,或者请求流 message 携带的数据\n - 作为结果或者响应流的 message 数据,传给请求发起方\n */\n args?: T\n \n /** bins: 哪几个 arg 是 Uint8Array 类型的,如: [0, 3] */\n bins?: number[]\n \n /** 被调方执行 func 产生的错误 */\n error?: Error\n \n /** 如果请求或者响应是一个流,通过这个 flag 表明是最后一个 message, 并且可以销毁 handler 了 */\n done?: boolean\n}\n\n/** 通过创建 Remote 对象对 WebSocket RPC 进行抽象 \n 调用方使用 remote.call 进行调用 \n 被调方在创建 Remote 对象时传入 funcs 注册处理函数,并使用 Remote.handle 方法处理 WebSocket message \n*/\nexport class Remote {\n url: string\n \n websocket: WebSocket\n \n id = 0\n \n /** 被调方的 message 处理器 */\n funcs: Record<\n string, \n (message: Message, websocket?: WebSocket) => void | Promise<void>\n > = { }\n \n /** 调用方发起的 rpc 对应响应的 message 处理器 */\n handlers: ((message: Message) => any)[] = [ ]\n \n print = false\n \n /** 在未连接时或连接断开后,调用 call 是否自动连接到 remote */\n autoconnect = true\n \n pconnect: Promise<any>\n \n \n get connected () {\n return this.websocket?.readyState === WebSocket.OPEN\n }\n \n \n static parse <T extends any[] = any[]> (array_buffer: ArrayBuffer) {\n const buf = new Uint8Array(array_buffer as ArrayBuffer)\n const dv = new DataView(array_buffer)\n \n const len_json = dv.getUint32(0, true)\n \n let offset = 4 + len_json\n \n let message: Message<T> = JSON.parse(\n decoder.decode(\n buf.subarray(4, offset)\n )\n )\n \n if (message.bins) {\n const { bins } = message\n let { args } = message\n \n for (const ibin of bins) {\n const len_buf = args[ibin]\n args[ibin] = buf.subarray(offset, offset + len_buf)\n offset += len_buf\n }\n }\n \n return message\n }\n \n \n static pack ({\n id,\n func,\n ignore,\n async: _async,\n done,\n error,\n args: _args = [ ],\n }: Message) {\n let args = [..._args]\n \n let bins: number[] = [ ]\n let bufs: Uint8Array[] = [ ]\n \n for (let i = 0; i < args.length; i++) {\n const arg = args[i]\n if (arg instanceof Uint8Array) {\n bins.push(i)\n bufs.push(arg)\n args[i] = arg.length\n }\n }\n \n const data_json = {\n id,\n ... func ? { func } : { },\n ... ignore ? { ignore } : { },\n ... _async ? { async: _async } : { },\n ... done ? { done } : { },\n ... error ? { error } : { },\n ... args.length ? { args } : { },\n ... bins.length ? { bins } : { },\n }\n \n const str_json = encoder.encode(\n JSON.stringify(data_json)\n )\n \n let dv = new DataView(\n new ArrayBuffer(4)\n )\n \n dv.setUint32(0, str_json.length, true)\n \n return concat([\n dv,\n str_json,\n ... bufs\n ])\n }\n \n \n constructor ({\n url,\n funcs,\n websocket,\n autoconnect\n }: {\n url?: string\n funcs?: Remote['funcs']\n websocket?: WebSocket\n autoconnect?: boolean\n } = { }) {\n this.url = url\n \n if (funcs)\n this.funcs = funcs\n \n this.websocket = websocket\n \n if (typeof autoconnect !== 'undefined')\n this.autoconnect = autoconnect\n }\n \n \n async connect () {\n this.websocket = await connect_websocket(this.url, {\n on_message: this.handle.bind(this),\n on_close: () => {\n this.id = 0\n this.handlers = [ ]\n },\n })\n }\n \n \n disconnect () {\n this.websocket?.close()\n this.id = 0\n this.handlers = [ ]\n }\n \n \n send (message: Message, websocket = this.websocket) {\n if (websocket?.readyState !== WebSocket.OPEN)\n throw new Error(`${websocket?.url || 'websocket'} 已断开,无法调用 remote.send`)\n \n if (!('id' in message))\n message.id = this.id\n \n websocket.send(\n Remote.pack(message)\n )\n }\n \n \n /** 调用 remote 中的 func, 中间消息及返回结果可由 handler 处理,处理 done message 之后的返回值作为 call 函数的返回值 \n 如果为 unary rpc, 可以不传 handler, await call 之后可以得到响应 message 的 args\n */\n async call <T extends any[] = any[]> (\n message: Message,\n handler?: (message: Message<T>) => any\n ) {\n if (!this.connected)\n if (this.autoconnect) {\n // 临界区:保证多个 call 并发时只连接一次\n const ptail = this.pconnect\n \n let resolve: () => void\n this.pconnect = new Promise<void>((_resolve, _reject) => {\n resolve = _resolve\n })\n \n try {\n await ptail\n } catch { }\n // 临界区结束,只有一个 call 调用运行到这里,可以开始连接 WebSocket\n \n if (!this.connected) {\n if (this.websocket)\n console.log(`${this.url} 已断开,尝试自动重连`)\n else\n console.log(`${this.url} 未连接,尝试自动连接`)\n \n try {\n await this.connect()\n } finally {\n resolve()\n }\n }\n } else\n throw new Error(`${this.url} 未连接或已断开,无法调用 remote.call`)\n \n return new Promise<T>((resolve, reject) => {\n this.handlers[this.id] = async (message: Message<T>) => {\n const { error, done } = message\n \n if (error) {\n reject(\n Object.assign(\n new Error(),\n error\n )\n )\n return\n }\n \n const result = handler ?\n await handler(message)\n :\n message.args\n \n if (done)\n resolve(result)\n }\n \n this.send(message)\n \n this.id++\n })\n }\n \n \n /** 处理接收到的 WebSocket message\n 1. 被调用方接收 message 并开始处理\n 2. 调用方处理 message 响应\n */\n async handle (event: { data: ArrayBuffer }, websocket: WebSocket) {\n const message = Remote.parse(event.data)\n \n const { func, id, done } = message\n \n if (this.print)\n console.log(message)\n \n if (func) // 作为被调方\n try {\n const handler = this.funcs[func]\n \n if (!handler)\n throw new Error(`找不到 rpc handler for '${func}'`)\n \n await handler(message, websocket)\n } catch (error) {\n this.send(\n {\n id,\n error,\n done: true\n },\n websocket\n )\n \n throw error\n }\n else { // 作为发起方\n this.handlers[id](message)\n \n if (done)\n this.handlers[id] = null\n }\n }\n}\n\n\n"]}
package/net.d.ts CHANGED
@@ -81,6 +81,12 @@ export declare function rpc(func: string, args?: any[], { url, async: _async, ig
81
81
  async?: boolean;
82
82
  ignore?: boolean;
83
83
  }): Promise<any>;
84
+ /** 连接 websocket url, 设置各种事件监听器
85
+ - url
86
+ - options:
87
+ - on_message: 根据 websocket frame 的 opcode 不同 (text frame 或 binary frame) event 中的 data 对应为 ArrayBuffer 或者 string
88
+ https://datatracker.ietf.org/doc/html/rfc6455#section-5.2
89
+ */
84
90
  export declare function connect_websocket(url: string | URL, { protocols, max_payload, // 8 GB
85
91
  on_open, on_close, on_error, on_message }: {
86
92
  protocols?: string | string[];
@@ -92,7 +98,7 @@ on_open, on_close, on_error, on_message }: {
92
98
  }, websocket: WebSocket): any;
93
99
  on_error?(event: any, websocket: WebSocket): any;
94
100
  on_message(event: {
95
- data: ArrayBuffer;
101
+ data: ArrayBuffer | string;
96
102
  }, websocket: WebSocket): any;
97
103
  }): Promise<WebSocket>;
98
104
  /** 二进制消息格式
package/net.js CHANGED
@@ -84,7 +84,7 @@ export async function request(url, { queries, body, type = 'application/json', p
84
84
  resolveWithFullResponse: true,
85
85
  headers: {
86
86
  'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,ja-JP;q=0.6,ja;q=0.5',
87
- 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36',
87
+ 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36',
88
88
  ...body ? { 'content-type': type } : {},
89
89
  ...cookies ? {
90
90
  cookie: Object.entries(cookies)
@@ -247,9 +247,18 @@ export async function rpc(func, args, { url = 'http://localhost:8421/api/rpc', a
247
247
  }
248
248
  let decoder = new TextDecoder();
249
249
  let encoder = new TextEncoder();
250
+ /** 连接 websocket url, 设置各种事件监听器
251
+ - url
252
+ - options:
253
+ - on_message: 根据 websocket frame 的 opcode 不同 (text frame 或 binary frame) event 中的 data 对应为 ArrayBuffer 或者 string
254
+ https://datatracker.ietf.org/doc/html/rfc6455#section-5.2
255
+ */
250
256
  export async function connect_websocket(url, { protocols, max_payload = 2 ** 33, // 8 GB
251
257
  on_open, on_close, on_error, on_message }) {
252
- let websocket = new WebSocket(url, protocols, { maxPayload: max_payload });
258
+ let websocket = new WebSocket(url, protocols, {
259
+ maxPayload: max_payload,
260
+ skipUTF8Validation: true
261
+ });
253
262
  // https://stackoverflow.com/questions/11821096/what-is-the-difference-between-an-arraybuffer-and-a-blob/39951543
254
263
  websocket.binaryType = 'arraybuffer';
255
264
  return new Promise((resolve, reject) => {