diff --git a/.vscode/launch.json b/.vscode/launch.json index 0d1005c..78665b3 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -14,19 +14,19 @@ "program": "${workspaceFolder}/dev/tests/unit.mjs" }, { - "command": "function prompt{echo \" `b\"}\ncls\nnpm run test:dev:repl\nexit", + "command": "cls\nnpm run test:dev:repl\nexit", "name": "启动REPL", "request": "launch", "type": "node-terminal" }, { - "command": "function prompt{echo \" `b\"}\ncls\nnpm run build:dist\nexit", + "command": "cls\nnpm run build:dist\nexit", "name": "构建dist", "request": "launch", "type": "node-terminal" }, { - "command": "function prompt{echo \" `b\"}\ncls\nnpm run build:doc\nexit", + "command": "cls\nnpm run build:doc\nexit", "name": "构建doc", "request": "launch", "type": "node-terminal" diff --git a/dev/build/build.mjs b/dev/build/build.mjs deleted file mode 100644 index c7d2d46..0000000 --- a/dev/build/build.mjs +++ /dev/null @@ -1,244 +0,0 @@ - -//npm install rollup terser uglify-js -g -import { rollup } from 'rollup'; -import { minify as terser } from 'terser'; -import { minify as uglifyjs } from 'uglify-js'; - -import { renameSync,readdirSync } from 'fs'; -import { join } from 'path'; -//file io -import { readFileSync, writeFileSync } from 'fs'; - -import dts from "rollup-plugin-dts"; -async function build_dts_file(lang){ - console.log(`正在编译${lang}语言的.d.ts文件`); - const path=`./src/.decls/${lang}`; - //在调用rollup前,我们需要先做一件事: - //将path+/types/中的所有.s.ts文件重命名为.d.ts文件 - const base_path=path+"/types"; - for(const file_name of readdirSync(base_path)){ - if(file_name.endsWith(".s.ts")){ - //先将原有的同名.d.ts文件重命名到.d.ts.tmp - renameSync(join(base_path,file_name.replace(/\.s\.ts$/,".d.ts")),join(base_path,file_name.replace(/\.s\.ts$/,".d.ts.tmp"))); - //再将.s.ts文件重命名为.d.ts文件 - renameSync(join(base_path,file_name),join(base_path,file_name.replace(/\.s\.ts$/,".d.ts"))); - } - } - const rollup_config={ - input: path+'/jsstp.d.ts', - output: [ - { - format: 'esm' - } - ], - plugins: [dts()] - } - var bundle=await rollup(rollup_config) - //回复.s.ts文件 - for(const file_name of readdirSync(base_path)){ - if(file_name.endsWith(".d.ts.tmp")){ - //先将原有的同名.d.ts文件重命名到.s.ts - renameSync(join(base_path,file_name.replace(/\.d\.ts\.tmp$/,".d.ts")),join(base_path,file_name.replace(/\.d\.ts\.tmp$/,".s.ts"))); - //再将.d.ts.tmp文件重命名为.d.ts文件 - renameSync(join(base_path,file_name),join(base_path,file_name.replace(/\.d\.ts\.tmp$/,".d.ts"))); - } - } - - var dts_code= (await bundle.generate(rollup_config.output[0])).output[0].code; - - //修补d.ts - //`info_object$1`=>`info_object` - dts_code=dts_code.replace(/info_object\$1/g,'info_object'); - //remove all `//**remove from dist**//` - dts_code=dts_code.replace(/\/\/\*\*remove from dist\*\*\/\/\n/g,''); - - { - var dts_code_array=dts_code.split("\n"); - //remove all single line comments - dts_code_array=dts_code_array.filter(line=>!/^[ \t]*\/\//.test(line)); - //remove all multi line comments - var in_comment=false; - dts_code_array=dts_code_array.filter(line=>{ - if(/[ \t]*\/\*(?![\*@])/.test(line)) - in_comment=true; - if(in_comment && /\*\/$/.test(line)){ - in_comment=false; - return false; - } - if(!in_comment) - return true; - return false; - }); - //remove all multi empty lines to single empty line - var last_line_is_empty=false; - dts_code_array=dts_code_array.filter(line=>{ - if(line.length==0){ - if(last_line_is_empty) - return false; - else - last_line_is_empty=true; - }else - last_line_is_empty=false; - return true; - }); - dts_code=dts_code_array.join("\n"); - } - - writeFileSync(`dist/${lang}/jsstp.d.ts`,dts_code); -} -//对于每个在src/.decls/中的文件夹,我们都需要调用一次build_dts_file -for(const lang of readdirSync("./src/.decls")) - build_dts_file(lang); - -//rollup -c ./.github/rollup.config.mjs -var rollup_config=await import('./rollup.config.mjs').then(m=>m.default); -for(const config of rollup_config){ - const bundle = await rollup(config); - for(const output of config.output) - await bundle.write(output); -} - - -var name_caches={}; -function terser_minify(code,is_module){ - var compress_options={ - unsafe:true, - //inline:2, - computed_props:false, - unsafe_arrows:true, - unsafe_comps:true, - unsafe_Function:true, - unsafe_math:true, - unsafe_symbols:true, - unsafe_methods:true, - unsafe_proto:true, - unsafe_regexp:true, - unsafe_undefined:true - }; - return terser(code,{ - compress:compress_options, - mangle:{ - properties:{regex:/^_.*_$/} - }, - nameCache: name_caches, - module:is_module - }).then(({code})=>code); -} -function uglifyjs_minify(code,is_module){ - var compress_options={ - unsafe:true, - unsafe_comps:true, - unsafe_Function:true, - unsafe_math:true, - unsafe_proto:true, - unsafe_regexp:true, - unsafe_undefined:true, - properties:false - }; - return new Promise((resolve,reject)=>{ - let result=uglifyjs(code,{ - compress:compress_options, - mangle:false, - module:is_module, - //nameCache:name_caches - }); - if(result.error) - reject(result.error); - else - resolve(result.code); - }); -} - -//minify -async function jsstp_minify(code_path,is_module){ - console.log(`minifing ${code_path}`); - let code=readFileSync(code_path,'utf8'); - if(code.startsWith("Object.defineProperty(exports, '__esModule', { value: true });")){ - code=code.substring("Object.defineProperty(exports, '__esModule', { value: true });".length); - code+="exports.__esModule=true;\n" - } - await terser_minify(code,is_module).then(async code=>{ - await uglifyjs_minify(code,is_module).then(async code=>{ - if(is_module){ - { - let exports_str=""; - let exports_reg=/exports\.([a-zA-Z0-9_$]+)\s*=\s*([a-zA-Z0-9_$!]+)[,;]/; - let match; - while(match=exports_reg.exec(code)){ - exports_str+=`${match[1]}:${match[2]},`; - code=code.replace(match[0],""); - } - if(exports_str){ - var assign=name_caches.vars.props["$assign"]; - if(assign){ - code=code.replace(/,$/,";"); - code+=assign+"(exports,{"+exports_str.replace(/,$/,"});"); - code=await uglifyjs_minify(code,is_module); - } - else - console.error("assign not found") - } - } - code=code.replace(/;$/g,`\n`); - } - else{ - code=code.replace(/^var [a-zA-Z0-9_$]+=function\(\){/,`var jsstp=(()=>{`); - code=code.replace(/}\(\);$/g,`})()\n`); - } - code = code.replace("document.currentScript&&document.currentScript.src","document.currentScript?.src"); - code = code.replace( - "K=(e,s,r)=>{return new i(e,n({get:(h=s,(e,s)=>{var r;if(!h.t?.(e,s))return(r=z(s,X)?h.i?.(e,s):h.h?.(e,s))!==t?r:h.o?h.o(e,s):z(r=e[s],A)?r.bind(e):r}),set:B},r));var h}", - "K=(e,r,o)=>new i(e,n({get:(e,i)=>{var n;if(!r.t?.(e,i))return(n=z(i,X)?r.i?.(e,i):r.h?.(e,i))!==t?n:r.o?r.o(e,i):z(n=e[i],A)?n.bind(e):n},set:B},o))" - ); - code = code.replace("t=>{return(t=+t)==t}","t=>+t==t"); - code = code.replace("var t,r=Object","var t,e=\"local\",s=\"external\",r=Object"); - { - var get_key= (old_key) => { - var key = name_caches.vars.props["$" + old_key]; - //尝试使用正则表达式找到key - //匹配: key="old_key" - var reg = new RegExp(`\\s*([a-zA-Z0-9_$]+)\\s*=\\s*["']${old_key}["']\\s*`); - var match = reg.exec(code)?.[1]; - if (match) - if (!key) { - console.warn(`name_caches not working, use regex to find key ${old_key} = ${match}`); - key = match; - } - else if (key != match) { - console.warn(`name_caches may not right(${old_key} = ${key}), use regex to find key ${old_key} = ${match}`); - key = match; - } - return key; - } - //一些小问题的修复 - var key_fix = (old_key) => { - var key = get_key(old_key); - if(key) - code=code.replace(new RegExp(`${old_key}\:`,"g"),`[${key}]:`); - else - console.error(`key ${old_key} not found`) - - } - key_fix("unknown_lines"); - key_fix("SEND"); - key_fix("local"); - key_fix("external"); - key_fix("RequestHeader"); - key_fix("default_info"); - key_fix("default_security_level"); - key_fix("sstp_version_table"); - key_fix("ghost_info"); - let local=get_key("local"); - let external=get_key("external"); - if(local && external) - code=code.replace("\"local\":\"external\"",`${local}:${external}`); - } - writeFileSync(code_path,code); - }).catch(e=>console.error(e)); - }).catch(e=>console.error(e)); -} - -//minify -await jsstp_minify("./dist/jsstp.mjs",true); -await jsstp_minify("./dist/jsstp.cjs",true); -await jsstp_minify("./dist/jsstp.min.js",false); diff --git a/dev/build/build_code.mjs b/dev/build/build_code.mjs new file mode 100644 index 0000000..9102e5a --- /dev/null +++ b/dev/build/build_code.mjs @@ -0,0 +1,141 @@ + +import { rollup } from 'rollup'; +import { minify as terser } from 'terser'; +import { minify as uglifyjs } from 'uglify-js'; + +//rollup -c ./.github/rollup.config.mjs +var rollup_config=await import('./rollup.config.mjs').then(m=>m.default); +for(const config of rollup_config){ + const bundle = await rollup(config); + for(const output of config.output) + await bundle.write(output); +} + + +var name_caches={}; +function terser_minify(code,is_module){ + var compress_options={ + unsafe:true, + //inline:2, + computed_props:false, + unsafe_arrows:true, + unsafe_comps:true, + unsafe_Function:true, + unsafe_math:true, + unsafe_symbols:true, + unsafe_methods:true, + unsafe_proto:true, + unsafe_regexp:true, + unsafe_undefined:true + }; + return terser(code,{ + compress:compress_options, + mangle:{ + properties:{regex:/^_.*_$/}, + keep_classnames:/^(base_sstp_info_t|list_info_t|fmo_info_t|ghost_events_queryer_t|jsstp_t|sstp_info_t)$/, + }, + nameCache: name_caches, + module:is_module + }).then(({code})=>code); +} +function uglifyjs_minify(code,is_module){ + var compress_options={ + unsafe:true, + unsafe_comps:true, + unsafe_Function:true, + unsafe_math:true, + unsafe_proto:true, + unsafe_regexp:true, + unsafe_undefined:true, + properties:false + }; + return new Promise((resolve,reject)=>{ + let result=uglifyjs(code,{ + compress:compress_options, + mangle:false, + module:is_module, + //nameCache:name_caches + }); + if(result.error) + reject(result.error); + else + resolve(result.code); + }); +} + +//file io +import { readFileSync, writeFileSync } from 'fs'; +import { pack } from 'packer'; +//minify +async function jsstp_minify(code_path,is_module){ + console.log(`minifing ${code_path}`); + let code=readFileSync(code_path,'utf8'); + if(code.startsWith("Object.defineProperty(exports, '__esModule', { value: true });")){ + code=code.substring("Object.defineProperty(exports, '__esModule', { value: true });".length); + code+="exports.__esModule=true;\n" + } + return terser_minify(code,is_module).then(code => uglifyjs_minify(code,is_module)).then(async code=>{ + if(is_module){ + let exports_str=""; + let exports_reg=/exports\.([a-zA-Z0-9_$]+)\s*=\s*([a-zA-Z0-9_$!]+)[,;]/; + let match; + while(match=exports_reg.exec(code)){ + exports_str+=`${match[1]}:${match[2]},`; + code=code.replace(match[0],""); + } + if(exports_str){ + var assign=name_caches.vars.props["$assign"]; + if(assign){ + code=code.replace(/,$/,";"); + code+=assign+"(exports,{"+exports_str.replace(/,$/,"});"); + code=await uglifyjs_minify(code,is_module); + } + else + console.error("assign not found") + } + } + else{ + code=code.replace(/^var [a-zA-Z0-9_$]+=function\(\){/,`var jsstp=(()=>{`); + code=code.replace(/}\(\);$/g,`})()\n`); + } + code = code.replace("document.currentScript&&document.currentScript.src","document.currentScript?.src"); + code = code.replace( + "_=(s,r,n)=>{return new Proxy(s,e({get:(i=r,(e,s)=>{var r;if(!i.t?.(e,s))return(r=o(s,String)?i.i?.(e,s):i.h?.(e,s))!==t?r:i.o?i.o(e,s):o(r=e[s],Function)?r.bind(e):r}),set:u},n));var i}", + "_=(i,n,r)=>new Proxy(i,e({get(i,r){var a;if(!n.t?.(i,r))return(a=o(r,String)?n.i?.(i,r):n.h?.(i,r))!==t?a:n.o?n.o(i,r):o(a=i[r],Function)?a.bind(i):a},set:u},r))" + ); + code = code.replace("t=>{return(t=+t)==t}","t=>+t==t"); + return code.replace(/;$/g,`\n`); + }).catch(e=>console.error(e)); +} + + +//minify +var cjscode = await jsstp_minify("./dist/jsstp.cjs",true); +var jscode = await jsstp_minify("./dist/jsstp.min.js",false); +if(!jscode.startsWith("var jsstp=(()=>{") || !jscode.endsWith("})()\n")) + throw new Error("minify failed!"); +var jsstpdefcode = jscode.substring("var jsstp=(()=>{".length,jscode.length-"})()\n".length).replace( + /return (\w+)\(jsstp_t.prototype/g, + "$1(jsstp_t.prototype" +); +jsstpdefcode = jsstpdefcode.replace(/new jsstp_t$/g,"[new jsstp_t,jsstp_t,base_sstp_info_t,sstp_info_t,list_info_t,fmo_info_t,ghost_events_queryer_t]"); +//pack +jscode=pack(jscode,true,true); +cjscode=pack(cjscode,true,true); +jsstpdefcode=pack(jsstpdefcode,true,true); +//build mjs code +var mjscode="var[a,b,c,d,e,f,g]="+jsstpdefcode+"\ +\nexport{a as default,a as jsstp,b as jsstp_t,c as base_sstp_info_t,d as sstp_info_t,e as list_info_t,f as fmo_info_t,g as ghost_events_queryer_t}" +//re minify +name_caches={} +function reminify(code,is_module){ + return terser_minify(code,is_module).then(code => uglifyjs_minify(code,is_module)).then(code=>code.replace(/;$/g,`\n`)).catch(e=>console.error(e)); +} +jscode=await reminify(jscode,false); +cjscode=await reminify(cjscode,false);//作为普通的js而非模块 +mjscode=await reminify(mjscode,true); +//write +writeFileSync("./dist/jsstp.min.js",jscode); +writeFileSync("./dist/jsstp.cjs",cjscode); +writeFileSync("./dist/jsstp.mjs",mjscode); +//*/ diff --git a/dev/build/build_dts.mjs b/dev/build/build_dts.mjs new file mode 100644 index 0000000..bcd8f35 --- /dev/null +++ b/dev/build/build_dts.mjs @@ -0,0 +1,64 @@ + +import { rollup } from 'rollup'; +import { readdirSync ,writeFileSync } from 'fs'; + +import dts from "rollup-plugin-dts"; + +async function build_dts_file(lang){ + console.log(`正在编译${lang}语言的.d.ts文件`); + const path=`./src/.decls/${lang}`; + const rollup_config={ + input: path+'/jsstp.d.ts', + output: [ + { + format: 'esm' + } + ], + plugins: [dts()] + } + var bundle=await rollup(rollup_config) + var dts_code= (await bundle.generate(rollup_config.output[0])).output[0].code; + + //修补d.ts + //`info_object$1`=>`info_object` + dts_code=dts_code.replace(/info_object\$1/g,'info_object'); + // `some ${string}` => string + dts_code=dts_code.replace(/`some \${string}`/g,'string'); + + { + var dts_code_array=dts_code.split("\n"); + //remove all single line comments + dts_code_array=dts_code_array.filter(line=>!/^[ \t]*\/\//.test(line)); + //remove all multi line comments + var in_comment=false; + dts_code_array=dts_code_array.filter(line=>{ + if(/[ \t]*\/\*(?![\*@])/.test(line)) + in_comment=true; + if(in_comment && /\*\/$/.test(line)){ + in_comment=false; + return false; + } + if(!in_comment) + return true; + return false; + }); + //remove all multi empty lines to single empty line + var last_line_is_empty=false; + dts_code_array=dts_code_array.filter(line=>{ + if(line.length==0){ + if(last_line_is_empty) + return false; + else + last_line_is_empty=true; + }else + last_line_is_empty=false; + return true; + }); + dts_code=dts_code_array.join("\n"); + } + + writeFileSync(`dist/${lang}/jsstp.d.ts`,dts_code); +} +//对于每个在src/.decls/中的文件夹,我们都需要调用一次build_dts_file +for(const lang of readdirSync("./src/.decls")) + build_dts_file(lang); diff --git a/dev/build/docs-language-sidebar.mjs b/dev/build/docs-language-sidebar.mjs index a6d196c..70bb9ba 100644 --- a/dev/build/docs-language-sidebar.mjs +++ b/dev/build/docs-language-sidebar.mjs @@ -3,7 +3,7 @@ import td from "typedoc"; import path from "path"; const template = ` - diff --git a/dev/build/rollup.config.mjs b/dev/build/rollup.config.mjs index 92fd519..fbe45ee 100644 --- a/dev/build/rollup.config.mjs +++ b/dev/build/rollup.config.mjs @@ -4,10 +4,6 @@ export default [ { input: 'src/jsstp.mjs', output: [ - { - file: 'dist/jsstp.mjs', - format: 'esm' - }, { file: 'dist/jsstp.cjs', format: 'cjs', diff --git a/dev/tests/base_jsstp_test.mjs b/dev/tests/base_jsstp_test.mjs index 2492a49..b2812c9 100644 --- a/dev/tests/base_jsstp_test.mjs +++ b/dev/tests/base_jsstp_test.mjs @@ -6,9 +6,9 @@ var base_jsstp_test = ( )=>{ jsstp.if_available(async ()=>{ console.log("jsstp test"); - console.log((await jsstp.get_fmo_infos()).to_string()); + console.log((await jsstp.get_fmo_infos()).TextContent()); - console.log((await jsstp.OnTest()).to_string()); + console.log((await jsstp.OnTest()).TextContent()); console.log(await jsstp.has_event("OnTest")); console.log(jsstp.clone); diff --git a/package.json b/package.json index af91de3..b9dd6f8 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,9 @@ "test:dist": "npm run test:dist:mjs && npm run test:dist:cjs", "build": "npm run build:dist", - "build:dist": "node dev/build/build.mjs", + "build:dist:code": "node dev/build/build_code.mjs", + "build:dist:dts": "node dev/build/build_dts.mjs", + "build:dist": "npm run build:dist:code && npm run build:dist:dts", "build:doc:cn": "npx typedoc --plugin typedoc-plugin-missing-exports --plugin ./dev/build/docs-language-sidebar.mjs --excludeExternals --tsconfig \"./src/.decls/cn/tsconfig.json\"", "build:doc:en": "npx typedoc --plugin typedoc-plugin-missing-exports --plugin ./dev/build/docs-language-sidebar.mjs --excludeExternals --tsconfig \"./src/.decls/en/tsconfig.json\"", @@ -85,6 +87,7 @@ }, "homepage": "https://github.com/ukatech/jsstp-lib#readme", "devDependencies": { + "packer": "github:steve02081504/packer", "rollup": "^4.2.0", "rollup-plugin-dts": "^6.1.0", "terser": "^5.24.0", diff --git a/src/.decls/cn/jsstp.d.ts b/src/.decls/cn/jsstp.d.ts index 082ea61..6d8f1f3 100644 --- a/src/.decls/cn/jsstp.d.ts +++ b/src/.decls/cn/jsstp.d.ts @@ -8,6 +8,7 @@ import type fmo_info_t from "./types/fmo_info_t.d.ts"; import type ghost_events_queryer_t from "./types/ghost_events_queryer_t.d.ts"; import type jsstp_t from "./types/jsstp_t.d.ts"; +import type list_info_t from "./types/list_info_t.d.js"; //定义一个包装器 /** @@ -31,5 +32,6 @@ export { base_sstp_info_t, sstp_info_t, fmo_info_t, + list_info_t, ghost_events_queryer_t } diff --git a/src/.decls/cn/types/base_sstp_info_t.d.ts b/src/.decls/cn/types/base_sstp_info_t.d.ts index a43f1ee..b2baf05 100644 --- a/src/.decls/cn/types/base_sstp_info_t.d.ts +++ b/src/.decls/cn/types/base_sstp_info_t.d.ts @@ -43,12 +43,7 @@ declare class base_sstp_info_t extends info_objec * @returns {String} 字符串报文 * @ignore */ - /*@__PURE__*/toString(): String; - /** - * 获取字符串报文 - * @returns {String} 字符串报文 - */ - /*@__PURE__*/to_string(): String; + /*@__PURE__*/TextContent(): String; /** * 获取用于`JSON.stringify`的对象 * @returns {Object} 用于`JSON.stringify`的对象 diff --git a/src/.decls/cn/types/fmo_info_t.d.ts b/src/.decls/cn/types/fmo_info_t.d.ts index 8fef8bb..cabab36 100644 --- a/src/.decls/cn/types/fmo_info_t.d.ts +++ b/src/.decls/cn/types/fmo_info_t.d.ts @@ -78,20 +78,19 @@ declare interface single_fmo_info_t extends info_object { modulestate: string; } /** - * fmo报文类:类定义实现 - * @see fmo_info_t + * fmo报文类 * @example * let fmo = jsstp.get_fmo_infos(); * let kikka_uuid = fmo.get_uuid_by("name", "橘花"); * if(kikka_uuid) * console.log(fmo[kikka_uuid].ghostpath); + * @alias jsstp.fmo_info_t * @see {@link jsstp_t.get_fmo_infos} * @see {@link http://ssp.shillest.net/ukadoc/manual/spec_fmo_mutex.html} - * @group fmo_info_t implementations */ -declare class fmo_info_t_class_impl extends base_sstp_info_t { +declare class fmo_info_t extends base_sstp_info_t { /** - * 自字符串构造fmo_info_t,不建议直接使用 + * 自字符串构造fmo_info_t * @param {String} fmo_text * @returns {void} * @ignore @@ -124,71 +123,11 @@ declare class fmo_info_t_class_impl extends base_sstp_info_t { - /** - * @description 正在运行的基础软件根文件夹的完整路径 - * @example E:\ssp\ - */ - path: string; - /** - * @description 主窗口的窗口句柄 - * @example 918820 - */ - hwnd: string; - /** - * @description descript.txt的sakura.name - * @example 橘花 - */ - name: string; - /** - * @description descript.txt的kero.name - * @example 斗和 - */ - keroname: string; - /** - * @description \0侧当前显示的surface ID - * @example 0 - */ - "sakura.surface": string; - /** - * @description \1侧当前显示的surface ID - * @example 10 - */ - "kero.surface": string; - /** - * @description \1侧窗口的窗口句柄 - * @example 67008 - */ - kerohwnd: string; - /** - * @description 当前使用的窗口句柄的逗号分隔列表 - * @example 918820,67008 - */ - hwndlist: string; - /** - * @description 正在运行的ghost的完整路径 - * @example E:\ssp\ghost\Taromati2\ - */ - ghostpath: string; - /** - * @description 正在运行的ghost的descript.txt的name - * @example Taromati2 - */ - fullname: string; - /** - * @description 正在运行的ghost的模块状态 - * @example shiori:running,makoto-ghost:running - */ - modulestate: string; -}; -/** - * fmo报文类 - * @example - * let fmo = jsstp.get_fmo_infos(); - * let kikka_uuid = fmo.get_uuid_by("name", "橘花"); - * if(kikka_uuid) - * console.log(fmo[kikka_uuid].ghostpath); - * @alias jsstp.fmo_info_t - * @see {@link jsstp_t.get_fmo_infos} - * @see {@link http://ssp.shillest.net/ukadoc/manual/spec_fmo_mutex.html} - */ -declare class fmo_info_t extends base_sstp_info_t { - /** - * 自字符串构造fmo_info_t,不建议直接使用 - * @param {String} fmo_text - * @returns {void} - * @ignore - */ - /*@__PURE__*/constructor(fmo_text: String); - /** - * @param {String} name 要检查的属性名 - * @param {String} value 期望的属性值 - * @returns {String|undefined} 对应的uuid(如果有的话) - * @description 获取具有指定属性且属性值为指定值的fmo的uuid - * @example - * let kikka_uuid = fmo_info.get_uuid_by("name", "橘花"); - * @description 等价于`this.uuids.find(uuid => this[uuid][name] == value)` - */ - /*@__PURE__*/get_uuid_by(name: String, value: String): String | undefined; - /** - * @param {String} name - * @returns {Array} - * @description 获取所有指定属性的值 - * @example - * let ghost_list = fmo_info.get_list_of("name"); - * @description 等价于`this.uuids.map(uuid => this[uuid][name])` - */ - /*@__PURE__*/get_list_of(name: String): Array; - /** - * @description 获取所有uuid - */ - /*@__PURE__*/get uuids(): Array; - /** - * @description 判断fmo是否有效 - */ - /*@__PURE__*/get available(): Boolean; - //注入toString方法便于使用 - /** - * 获取字符串报文 - * @returns {String} 字符串报文 - * @ignore - */ - /*@__PURE__*/toString(): String; - /** - * 获取用于`JSON.stringify`的对象 - * @returns {Object} 用于`JSON.stringify`的对象 - * @ignore - */ - /*@__PURE__*/toJSON(): Object; - /** - * fmo成员 - * @type {single_fmo_info_t|undefined} - */ - [uuid: string]: single_fmo_info_t|undefined; -}; - -export { - single_fmo_info_t, - fmo_info_t, - fmo_info_t as default, -}; diff --git a/src/.decls/cn/types/jsstp_t.d.ts b/src/.decls/cn/types/jsstp_t.d.ts index ce3d6cc..1d1d75c 100644 --- a/src/.decls/cn/types/jsstp_t.d.ts +++ b/src/.decls/cn/types/jsstp_t.d.ts @@ -2,6 +2,7 @@ import type { single_fmo_info_t , fmo_info_t } from "./fmo_info_t.d.ts"; import type ghost_events_queryer_t from "./ghost_events_queryer_t.d.ts"; import type sstp_info_t from "./sstp_info_t.d.ts"; import type base_sstp_info_t from "./base_sstp_info_t.d.ts"; +import type list_info_t from "./list_info_t.d.js"; import type { info_object } from "./info_object.d.ts"; import { security_level_t } from "../base/tools.js"; @@ -9,35 +10,28 @@ import { security_level_t } from "../base/tools.js"; * sstp方法调用器 * @group callers */ -interface method_caller{ - (info: Object): Promise, - get_raw(info: Object): Promise +interface method_caller { + (...args: Rest): Promise; + get_raw(...args: Rest): Promise; + with_type(result_type: new (str:string) => nT): method_caller; + bind_args_processor(processor: (...args: Rest) => Object): method_caller; } /** - * 事件调用器 + * 可以通过成员访问扩充指定key值的拓展调用器 * @group callers */ -interface base_event_caller{ - [key: string]: base_event_caller,//扩展事件名称 +interface base_keyed_method_caller extends method_caller { + /** + * 扩展调用器 + */ + [uuid: `some ${string}`]: base_keyed_method_caller } /** - * 简易事件调用器 - * 直接调用以触发事件! - * @example - * let data=await jsstp.OnTest(123,"abc"); - * //等价于 - * let data = await jsstp.SEND({ - * "Event": "OnTest", - * "Reference0": 123, - * "Reference1": "abc" - * }); + * 对调用参数进行简易处理的可扩展调用器 * @group callers */ -interface simple_event_caller extends base_event_caller { - (...args: any[]): Promise, - [key: string]: simple_event_caller,//扩展事件名称 -} +interface simple_keyed_method_caller extends base_keyed_method_caller {} /** * 通用事件调用器 * 调用时传入一个对象以触发事件! @@ -56,10 +50,41 @@ interface simple_event_caller extends base_event_caller { * }); * @group callers */ -interface common_event_caller extends base_event_caller{ - (info: Object): Promise, - [key: string]: common_event_caller,//扩展事件名称 -} +interface event_caller extends base_keyed_method_caller {} +/** + * 简易事件调用器 + * 直接调用以触发事件! + * @example + * let data=await jsstp.OnTest(123,"abc"); + * //等价于 + * let data = await jsstp.SEND({ + * "Event": "OnTest", + * "Reference0": 123, + * "Reference1": "abc" + * }); + * @group callers + */ +interface simple_event_caller extends simple_keyed_method_caller {} +/** + * 命令调用器 + * @group callers + */ +interface command_caller extends base_keyed_method_caller {} +/** + * 简易命令调用器 + * @group callers + */ +interface simple_command_caller extends simple_keyed_method_caller {} +/** + * 列表返值命令执行器 + * @group callers + */ +interface list_command_caller extends base_keyed_method_caller {} +/** + * 对参数进行简易处理的列表返值命令执行器 + * @group callers + */ +interface simple_list_command_caller extends simple_keyed_method_caller {} /** * 比{@link jsstp_t}多了一个ghost_info属性 @@ -97,6 +122,10 @@ declare class jsstp_t{ * @group Types */ fmo_info_t: typeof fmo_info_t; + /** + * @group Types + */ + list_info_t: typeof list_info_t; /** * @group Types */ @@ -125,11 +154,25 @@ declare class jsstp_t{ /** * 匹配事件名称以产生简易调用器 - * @group jsstp_event_members + * @group Index reflactions * @example * let data=await jsstp.OnTest(123,"abc"); */ [key: `On${string}`]: simple_event_caller; + /** + * 匹配事件名称以产生简易调用器 + * @group Index reflactions + * @example + * let data=await jsstp.GetNames(); + */ + [key: `Get${string}`]: simple_list_command_caller; + /** + * 匹配事件名称以产生简易调用器 + * @group Index reflactions + * @example + * let data=await jsstp.SetCookie("abc","def"); + */ + [key: `Set${string}`]: simple_command_caller; /** * 在fecth时使用的header @@ -229,37 +272,48 @@ declare class jsstp_t{ * 发送报文 * @param {String} sstphead 报文头 * @param {Object} info 报文体 + * @param {new (info: String)=> result_type} result_type 返回结果的类型,默认为sstp_info_t * @returns {Promise} 返回一个promise * @group Basic Send Methods */ - costom_send(sstphead: String, info: Object): Promise; - + costom_send(sstphead: String, info: Object, result_type: new (str: string) => T): Promise; + /** * 获取指定方法的调用器 * @param {String} method_name 方法名称 - * @returns {{ - * (info: Object): Promise, - * get_raw(info: Object): Promise - * }} 调用器 + * @param {new (info: String) => result_type} [result_type=sstp_info_t] 返回结果的类型,默认为sstp_info_t + * @param {Function} [args_processor=info => info] 参数处理器,默认直接返回输入参数 + * @returns {method_caller} 调用器 * @group Caller Methods */ - /*@__PURE__*/get_caller_of_method(method_name: String): method_caller; + /*@__PURE__*/get_caller_of_method(method_name: String, result_type?: new (str: string) => any, args_processor?: (...args: any[]) => Object): method_caller; /** - * 获取指定事件的调用器 - * @param {String} event_name 事件名称 - * @param {String|undefined} method_name 方法名称 - * @returns {{(info: Object) => Promise}} 调用器 + * 获取指定key的调用器 + * @param {String} key_name 键名 + * @param {String} value_name 键值 + * @param {Function} method_caller 方法调用器 + * @param {Function} args_processor 参数处理器 + * @returns {Proxy} 调用器 * @group Caller Methods */ - /*@__PURE__*/get_caller_of_event(event_name: String, method_name?: String): common_event_caller; + /*@__PURE__*/get_caller_of_key( + key_name: String, value_name: String, + method_caller?: method_caller, + args_processor?: (...args: Rest) => Res + ): base_keyed_method_caller; + /** - * 用于获取指定事件的简单调用器 - * @param {String} event_name 事件名称 - * @param {String|undefined} method_name 方法名称 - * @returns {{(info: Object) => Promise}} 调用器 + * 用于获取指定key的简单调用器 + * @param {String} key_name 键名 + * @param {String} value_name 键值 + * @param {Function} method_caller 方法调用器 + * @returns {Proxy} 调用器 * @group Caller Methods */ - /*@__PURE__*/get_simple_caller_of_event(event_name: String, method_name?: String): simple_event_caller; + /*@__PURE__*/get_simple_caller_of_key( + key_name: String, value_name: String, + method_caller?: method_caller, + ): simple_keyed_method_caller; /** * 用于获取指定事件的简单调用器的代理 * @returns {Proxy} @@ -270,6 +324,16 @@ declare class jsstp_t{ /*@__PURE__*/get event(): { [event_name: string]: simple_event_caller } + /** + * 用于获取指定命令的执行器的代理 + * @returns {Proxy} + * @example + * jsstp.command.GetFMO(); + * @group Indexer Members + */ + /*@__PURE__*/get command(): { + [command_name: string]: simple_command_caller + } /** * 判断是否存在某个事件 * 若可能频繁调用,使用{@link ghost_events_queryer_t}(通过{@link jsstp_t.new_event_queryer}获取)来查询 diff --git a/src/.decls/cn/types/list_info_t.d.ts b/src/.decls/cn/types/list_info_t.d.ts new file mode 100644 index 0000000..adc0a0e --- /dev/null +++ b/src/.decls/cn/types/list_info_t.d.ts @@ -0,0 +1,46 @@ +import type base_sstp_info_t from "./base_sstp_info_t.d.ts"; + +/** + * list报文对象 + * @example + * let list = jsstp.GetNames(); + * for(let name of list) + * console.log(name); + * @alias jsstp.list_info_t + */ +declare class list_info_t extends base_sstp_info_t { + /** + * 自字符串构造list_info_t + * @param {String} list_text + * @ignore + */ + /*@__PURE__*/constructor(list_text: String) + /*@__PURE__*/toString(): String + /** + * 获取字符串报文 + * @returns {String} 字符串报文 + * @ignore + */ + /*@__PURE__*/TextContent(): String + /** + * 获取用于`JSON.stringify`的对象 + * @returns {Object} 用于`JSON.stringify`的对象 + * @ignore + */ + /*@__PURE__*/toJSON(): Object + /** + * 获取迭代器 + * @returns {Iterator>} 迭代器 + */ + /*@__PURE__*/[Symbol.iterator](): Iterator> + /** + * 数组成员 + * @type {string|undefined} + */ + [uuid: number]: string|undefined; +} + +export { + list_info_t, + list_info_t as default, +}; diff --git a/src/.decls/cn/types/sstp_info_t.d.ts b/src/.decls/cn/types/sstp_info_t.d.ts index 9e3271c..ab0f0cd 100644 --- a/src/.decls/cn/types/sstp_info_t.d.ts +++ b/src/.decls/cn/types/sstp_info_t.d.ts @@ -12,26 +12,14 @@ Option: notranslate 由一行固定的报文头和一组可选的报文体组成,以\r\n换行,结尾以\r\n\r\n结束。 */ /** - * sstp报文类:类定义实现 - * @see sstp_info_t + * sstp报文类 * @example * let info = jsstp.sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); * console.log(info.head);//SSTP/1.4 200 OK * console.log(info.Option);//notranslate * @alias jsstp.sstp_info_t - * @group sstp_info_t implementations */ -declare class sstp_info_t_class_impl extends base_sstp_info_t { - /** - * 自拆分好的字符串报文或对象报文构造sstp_info_t,不建议直接使用 - * @param {String} info_head 报文头 - * @param {Object} info_body 对象格式的报文体 - * @param {Array|undefined} unknown_lines 未知行的数组 - * @see {@link sstp_info_t.from_string} - * @returns {sstp_info_t} - * @ignore - */ - /*@__PURE__*/constructor(info_head: String, info_body: Object, unknown_lines?: String[]); +declare class sstp_info_t extends base_sstp_info_t { /** * 从字符串构造sstp_info_t * @param {String} str 字符串报文 @@ -39,7 +27,7 @@ declare class sstp_info_t_class_impl extends base_sstp_info_t { * @example * let info = sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); */ - /*@__PURE__*/static from_string(str: String): sstp_info_t; + /*@__PURE__*/constructor(str: String); /** * 获取PassThru的值 * @param {String} key 获取的PassThru名称 @@ -56,63 +44,11 @@ declare class sstp_info_t_class_impl extends base_sstp_info_t { * @returns {sstp_info_t} 原始对象 */ /*@__PURE__*/get raw(): sstp_info_t; -} -/** - * 补充sstp报文类的默认成员 - * @group sstp_info_t implementations - */ -type sstp_info_t_members = { /** * 其他报文成员 * @type {String|undefined} */ - [key: string]: String | undefined; -}; -/** - * sstp报文类:构造器接口声明 - * @group sstp_info_t implementations - */ -type sstp_info_t_constructor = { - /** - * 自拆分好的字符串报文或对象报文构造sstp_info_t,不建议直接使用 - * @param {String} info_head 报文头 - * @param {Object} info_body 对象格式的报文体 - * @param {Array|undefined} unknown_lines 未知行的数组 - * @see {@link sstp_info_t.from_string} - * @returns {sstp_info_t} - * @ignore - */ - /*@__PURE__*/new(info_head: String, info_body: Object, unknown_lines?: String[]): sstp_info_t; - /** - * 从字符串构造sstp_info_t - * @param {String} str 字符串报文 - * @returns {sstp_info_t} 构造的sstp_info_t - * @example - * let info = sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); - */ - /*@__PURE__*/from_string(str: String): sstp_info_t; -}; -/** - * sstp报文类 - * @example - * let info = jsstp.sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); - * console.log(info.head);//SSTP/1.4 200 OK - * console.log(info.Option);//notranslate - * @alias jsstp.sstp_info_t - * @group sstp_info_t implementations - */ -declare const sstp_info_t: typeof sstp_info_t_class_impl & sstp_info_t_constructor; -/** - * sstp报文类 - * @example - * let info = jsstp.sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); - * console.log(info.head);//SSTP/1.4 200 OK - * console.log(info.Option);//notranslate - * @alias jsstp.sstp_info_t - * @group sstp_info_t implementations - */ -type sstp_info_t = sstp_info_t_class_impl & sstp_info_t_members & { - constructor: typeof sstp_info_t; + [key: `some ${string}`]: String | undefined; } export default sstp_info_t; diff --git a/src/.decls/cn/types/sstp_info_t.s.ts b/src/.decls/cn/types/sstp_info_t.s.ts deleted file mode 100644 index 5d9b645..0000000 --- a/src/.decls/cn/types/sstp_info_t.s.ts +++ /dev/null @@ -1,65 +0,0 @@ -import type base_sstp_info_t from "./base_sstp_info_t.d.ts"; -import type { info_object } from "./info_object.d.ts"; - -//定义sstp报文类 -/* -sstp报文格式: -SEND SSTP/1.1 -Charset: UTF-8 -Sender: SSTPクライアント -Script: \h\s0テストー。\u\s[10]テストやな。 -Option: notranslate -由一行固定的报文头和一组可选的报文体组成,以\r\n换行,结尾以\r\n\r\n结束。 -*/ -/** - * sstp报文类 - * @example - * let info = jsstp.sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); - * console.log(info.head);//SSTP/1.4 200 OK - * console.log(info.Option);//notranslate - * @alias jsstp.sstp_info_t - */ -declare class sstp_info_t extends base_sstp_info_t { - /** - * 自拆分好的字符串报文或对象报文构造sstp_info_t,不建议直接使用 - * @param {String} info_head 报文头 - * @param {Object} info_body 对象格式的报文体 - * @param {Array|undefined} unknown_lines 未知行的数组 - * @see {@link sstp_info_t.from_string} - * @returns {sstp_info_t} - * @ignore - */ - /*@__PURE__*/constructor(info_head: String, info_body: Object, unknown_lines?: String[]); - /** - * 从字符串构造sstp_info_t - * @param {String} str 字符串报文 - * @returns {sstp_info_t} 构造的sstp_info_t - * @example - * let info = sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); - */ - /*@__PURE__*/static from_string(str: String): sstp_info_t; - /** - * 获取PassThru的值 - * @param {String} key 获取的PassThru名称 - * @returns {String|undefined} PassThru的值 - */ - /*@__PURE__*/get_passthrough(key: String): String | undefined; - /** - * 获取所有的PassThru - * @returns {info_object} 所有的PassThru - */ - /*@__PURE__*/get passthroughs(): info_object; - /** - * 获取原始对象 - * @returns {sstp_info_t} 原始对象 - */ - /*@__PURE__*/get raw(): sstp_info_t; - - /** - * 其他报文成员 - * @type {String|undefined} - */ - [key: string]: String | undefined; -}; - -export default sstp_info_t; diff --git a/src/.decls/en/base/tools.d.ts b/src/.decls/en/base/tools.d.ts index 9ed114c..24c612b 100644 --- a/src/.decls/en/base/tools.d.ts +++ b/src/.decls/en/base/tools.d.ts @@ -4,7 +4,6 @@ declare class ExtensibleFunction,return_T> extends Function { /** * Initialising from a function instance - * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) * @param {Function} func * @returns {ExtensibleFunction} */ diff --git a/src/.decls/en/jsstp.d.ts b/src/.decls/en/jsstp.d.ts index 6c263a1..e23d53a 100644 --- a/src/.decls/en/jsstp.d.ts +++ b/src/.decls/en/jsstp.d.ts @@ -8,6 +8,7 @@ import type fmo_info_t from "./types/fmo_info_t.d.ts"; import type ghost_events_queryer_t from "./types/ghost_events_queryer_t.d.ts"; import type jsstp_t from "./types/jsstp_t.d.ts"; +import type list_info_t from "./types/list_info_t.d.js"; //Define a wrapper /** @@ -31,5 +32,6 @@ export { base_sstp_info_t, sstp_info_t, fmo_info_t, + list_info_t, ghost_events_queryer_t } diff --git a/src/.decls/en/types/base_sstp_info_t.d.ts b/src/.decls/en/types/base_sstp_info_t.d.ts index 86b50a5..e2d865d 100644 --- a/src/.decls/en/types/base_sstp_info_t.d.ts +++ b/src/.decls/en/types/base_sstp_info_t.d.ts @@ -37,18 +37,12 @@ declare class base_sstp_info_t extends info_objec * @returns {String} message header */ /*@__PURE__*/get head(): String; - //注入toString方法便于使用 /** * Getting a String Message * @returns {String} String message. * @ignore */ - /*@__PURE__*/toString(): String; - /** - * Getting a String Message - * @returns {String} String message. - */ - /*@__PURE__*/to_string(): String; + /*@__PURE__*/TextContent(): String; /** * Get the object to use for `JSON.stringify`. * @returns {Object} The object to use for `JSON.stringify`. diff --git a/src/.decls/en/types/fmo_info_t.d.ts b/src/.decls/en/types/fmo_info_t.d.ts index 7851cf4..d7fbf9b 100644 --- a/src/.decls/en/types/fmo_info_t.d.ts +++ b/src/.decls/en/types/fmo_info_t.d.ts @@ -78,20 +78,19 @@ declare interface single_fmo_info_t extends info_object { modulestate: string; } /** - * fmo message class: class definition implementation - * @see fmo_info_t + * fmo message class * @example * let fmo = jsstp.get_fmo_infos(); * let kikka_uuid = fmo.get_uuid_by("name", "橘花"); * if(kikka_uuid) * console.log(fmo[kikka_uuid].ghostpath); + * @alias jsstp.fmo_info_t * @see {@link jsstp_t.get_fmo_infos} * @see {@link http://ssp.shillest.net/ukadoc/manual/spec_fmo_mutex.html} - * @group fmo_info_t implementations */ -declare class fmo_info_t_class_impl extends base_sstp_info_t { +declare class fmo_info_t extends base_sstp_info_t { /** - * Self-string construction fmo_info_t, not recommended for direct use + * Construct fmo_info_t from a string, not recommended for direct use * @param {String} fmo_text * @returns {void} * @ignore @@ -101,16 +100,16 @@ declare class fmo_info_t_class_impl extends base_sstp_info_t this[uuid][name] == value)` + * @description Equivalent to `this.uuids.find(uuid => this[uuid][name] == value)` */ /*@__PURE__*/get_uuid_by(name: String, value: String): String | undefined; /** * @param {String} name * @returns {Array} - * @description Get the values of all the specified properties. + * @description Gets the values of all the specified properties * @example * let ghost_list = fmo_info.get_list_of("name"); * @description Equivalent to `this.uuids.map(uuid => this[uuid][name])` @@ -125,70 +124,11 @@ declare class fmo_info_t_class_impl extends base_sstp_info_t { - /** - * @description Full path to the root folder of the running base software - * @example E:\ssp\ - */ - path: string; - /** - * @description Window handle of the main window - * @example 918820 - */ - hwnd: string; - /** - * @description descript.txt's sakura.name - * @example 橘花 - */ - name: string; - /** - * @description descript.txt's kero.name - * @example 斗和 - */ - keroname: string; - /** - * @description Surface ID currently displayed on side \0 - * @example 0 - */ - "sakura.surface": string; - /** - * @description Surface ID currently displayed on the \1 side - * @example 10 - */ - "kero.surface": string; - /** - * @description Window handle of the \1 side window - * @example 67008 - */ - kerohwnd: string; - /** - * @description Comma-separated list of currently used window handles - * @example 918820,67008 - */ - hwndlist: string; - /** - * @description Full path to the running ghost - * @example E:\ssp\ghost\Taromati2\ - */ - ghostpath: string; - /** - * @description Name in the running ghost's descript.txt - * @example Taromati2 - */ - fullname: string; - /** - * @description Module status of the running ghost - * @example shiori:running,makoto-ghost:running - */ - modulestate: string; -} -/** - * fmo message class - * @example - * let fmo = jsstp.get_fmo_infos(); - * let kikka_uuid = fmo.get_uuid_by("name", "橘花"); - * if(kikka_uuid) - * console.log(fmo[kikka_uuid].ghostpath); - * @alias jsstp.fmo_info_t - * @see {@link jsstp_t.get_fmo_infos} - * @see {@link http://ssp.shillest.net/ukadoc/manual/spec_fmo_mutex.html} - */ -declare class fmo_info_t extends base_sstp_info_t { - /** - * Construct fmo_info_t from a string, not recommended for direct use - * @param {String} fmo_text - * @returns {void} - * @ignore - */ - /*@__PURE__*/constructor(fmo_text: String); - /** - * @param {String} name The name of the property to be checked. - * @param {String} value The value of the property to be checked. - * @returns {String|undefined} corresponding uuid (if any) - * @description Get the uuid of the fmo with the specified attribute and the value of the attribute is the specified value - * @example - * let kikka_uuid = fmo_info.get_uuid_by("name", "橘花"); - * @description Equivalent to `this.uuids.find(uuid => this[uuid][name] == value)` - */ - /*@__PURE__*/get_uuid_by(name: String, value: String): String | undefined; - /** - * @param {String} name - * @returns {Array} - * @description Gets the values of all the specified properties - * @example - * let ghost_list = fmo_info.get_list_of("name"); - * @description Equivalent to `this.uuids.map(uuid => this[uuid][name])` - */ - /*@__PURE__*/get_list_of(name: String): Array; - /** - * @description Get all uuids - */ - /*@__PURE__*/get uuids(): Array; - /** - * @description Determining whether fmo is valid - */ - /*@__PURE__*/get available(): Boolean; - //注入toString方法便于使用 - /** - * Getting a String Message - * @returns {String} String message. - * @ignore - */ - /*@__PURE__*/toString(): String; - /** - * Get the object to use for `JSON.stringify`. - * @returns {Object} The object to use for `JSON.stringify`. - * @ignore - */ - /*@__PURE__*/toJSON(): Object; - - /** - * fmo members - * @type {single_fmo_info_t|undefined} - */ - [uuid: string]: single_fmo_info_t|undefined; -}; - -export { - single_fmo_info_t, - fmo_info_t, - fmo_info_t as default, -}; diff --git a/src/.decls/en/types/jsstp_t.d.ts b/src/.decls/en/types/jsstp_t.d.ts index 7aadbde..6b7d9dd 100644 --- a/src/.decls/en/types/jsstp_t.d.ts +++ b/src/.decls/en/types/jsstp_t.d.ts @@ -2,6 +2,7 @@ import type { single_fmo_info_t , fmo_info_t } from "./fmo_info_t.d.ts"; import type ghost_events_queryer_t from "./ghost_events_queryer_t.d.ts"; import type sstp_info_t from "./sstp_info_t.d.ts"; import type base_sstp_info_t from "./base_sstp_info_t.d.ts"; +import type list_info_t from "./list_info_t.d.js"; import type { info_object } from "./info_object.d.ts"; import { security_level_t } from "../base/tools.js"; @@ -9,35 +10,28 @@ import { security_level_t } from "../base/tools.js"; * sstp method caller * @group callers */ -interface method_caller{ - (info: Object): Promise, - get_raw(info: Object): Promise +interface method_caller { + (...args: Rest): Promise; + get_raw(...args: Rest): Promise; + with_type(result_type: new (str:string) => nT): method_caller; + bind_args_processor(processor: (...args: Rest) => Object): method_caller; } /** - * event caller + * 可以通过成员访问扩充指定key值的拓展调用器 * @group callers */ -interface base_event_caller{ - [key: string]: base_event_caller,//扩展事件名称 +interface base_keyed_method_caller extends method_caller { + /** + * 扩展调用器 + */ + [uuid: `some ${string}`]: base_keyed_method_caller } /** - * Simple event caller - * Called directly to trigger an event! - * @example - * let data=await jsstp.OnTest(123,"abc"); - * //equivalent to - * let data = await jsstp.SEND({ - * "Event": "OnTest", - * "Reference0": 123, - * "Reference1": "abc" - * }); + * 对调用参数进行简易处理的可扩展调用器 * @group callers */ -interface simple_event_caller extends base_event_caller { - (...args: any[]): Promise, - [key: string]: simple_event_caller,//扩展事件名称 -} +interface simple_keyed_method_caller extends base_keyed_method_caller {} /** * Generic Event Caller * Called by passing in an object to trigger an event! @@ -56,10 +50,41 @@ interface simple_event_caller extends base_event_caller { * }); * @group callers */ -interface common_event_caller extends base_event_caller{ - (info: Object): Promise, - [key: string]: common_event_caller,//扩展事件名称 -} +interface event_caller extends base_keyed_method_caller {} +/** + * 简易事件调用器 + * 直接调用以触发事件! + * @example + * let data=await jsstp.OnTest(123,"abc"); + * //等价于 + * let data = await jsstp.SEND({ + * "Event": "OnTest", + * "Reference0": 123, + * "Reference1": "abc" + * }); + * @group callers + */ +interface simple_event_caller extends simple_keyed_method_caller {} +/** + * 命令调用器 + * @group callers + */ +interface command_caller extends base_keyed_method_caller {} +/** + * 简易命令调用器 + * @group callers + */ +interface simple_command_caller extends simple_keyed_method_caller {} +/** + * 列表返值命令执行器 + * @group callers + */ +interface list_command_caller extends base_keyed_method_caller {} +/** + * 对参数进行简易处理的列表返值命令执行器 + * @group callers + */ +interface simple_list_command_caller extends simple_keyed_method_caller {} /** * One more ghost_info attribute than {@link jsstp_t} @@ -97,6 +122,10 @@ declare class jsstp_t{ * @group Types */ fmo_info_t: typeof fmo_info_t; + /** + * @group Types + */ + list_info_t: typeof list_info_t; /** * @group Types */ @@ -124,12 +153,26 @@ declare class jsstp_t{ GIVE: method_caller; /** - * Match event names to generate simple callers - * @group jsstp_event_members + * 匹配事件名称以产生简易调用器 + * @group Index reflactions * @example * let data=await jsstp.OnTest(123,"abc"); */ [key: `On${string}`]: simple_event_caller; + /** + * 匹配事件名称以产生简易调用器 + * @group Index reflactions + * @example + * let data=await jsstp.GetNames(); + */ + [key: `Get${string}`]: simple_list_command_caller; + /** + * 匹配事件名称以产生简易调用器 + * @group Index reflactions + * @example + * let data=await jsstp.SetCookie("abc","def"); + */ + [key: `Set${string}`]: simple_command_caller; /** * The header used in fecth. @@ -229,37 +272,48 @@ declare class jsstp_t{ * Send message * @param {String} sstphead Message header * @param {Object} info The body of the message. - * @returns {Promise} returns a promise + * @param {new (info: String)=> result_type} result_type 返回结果的类型,默认为sstp_info_t + * @returns {Promise} 返回一个promise * @group Basic Send Methods */ - costom_send(sstphead: String, info: Object): Promise; - + costom_send(sstphead: String, info: Object, result_type: new (str: string) => T): Promise; + /** - * Get the caller of the specified method - * @param {String} method_name method_name - * @returns {{ - * (info: Object): Promise, - * get_raw(info: Object): Promise - * }} caller + * 获取指定方法的调用器 + * @param {String} method_name 方法名称 + * @param {new (info: String) => result_type} [result_type=sstp_info_t] 返回结果的类型,默认为sstp_info_t + * @param {Function} [args_processor=info => info] 参数处理器,默认直接返回输入参数 + * @returns {method_caller} 调用器 * @group Caller Methods */ - /*@__PURE__*/get_caller_of_method(method_name: String): method_caller; + /*@__PURE__*/get_caller_of_method(method_name: String, result_type?: new (str: string) => any, args_processor?: (...args: any[]) => Object): method_caller; /** - * Get the caller of the specified event - * @param {String} event_name event_name - * @param {String|undefined} method_name method_name - * @returns {{(info: Object) => Promise}} caller + * 获取指定key的调用器 + * @param {String} key_name 键名 + * @param {String} value_name 键值 + * @param {Function} method_caller 方法调用器 + * @param {Function} args_processor 参数处理器 + * @returns {Proxy} 调用器 * @group Caller Methods */ - /*@__PURE__*/get_caller_of_event(event_name: String, method_name?: String): common_event_caller; + /*@__PURE__*/get_caller_of_key( + key_name: String, value_name: String, + method_caller?: method_caller, + args_processor?: (...args: Rest) => Res + ): base_keyed_method_caller; + /** - * Simple caller for getting the specified event - * @param {String} event_name event_name - * @param {String|undefined} method_name method_name - * @returns {{(info: Object) => Promise}} caller + * 用于获取指定key的简单调用器 + * @param {String} key_name 键名 + * @param {String} value_name 键值 + * @param {Function} method_caller 方法调用器 + * @returns {Proxy} 调用器 * @group Caller Methods */ - /*@__PURE__*/get_simple_caller_of_event(event_name: String, method_name?: String): simple_event_caller; + /*@__PURE__*/get_simple_caller_of_key( + key_name: String, value_name: String, + method_caller?: method_caller, + ): simple_keyed_method_caller; /** * Proxy for a simple caller to get a specified event * @returns {Proxy} @@ -270,6 +324,16 @@ declare class jsstp_t{ /*@__PURE__*/get event(): { [event_name: string]: simple_event_caller } + /** + * 用于获取指定命令的执行器的代理 + * @returns {Proxy} + * @example + * jsstp.command.GetFMO(); + * @group Indexer Members + */ + /*@__PURE__*/get command(): { + [command_name: string]: simple_command_caller + } /** * Determine if an event exists * Use {@link ghost_events_queryer_t} (obtained via {@link jsstp_t.new_event_queryer}) to query if it is likely to be called frequently diff --git a/src/.decls/en/types/list_info_t.d.ts b/src/.decls/en/types/list_info_t.d.ts new file mode 100644 index 0000000..adc0a0e --- /dev/null +++ b/src/.decls/en/types/list_info_t.d.ts @@ -0,0 +1,46 @@ +import type base_sstp_info_t from "./base_sstp_info_t.d.ts"; + +/** + * list报文对象 + * @example + * let list = jsstp.GetNames(); + * for(let name of list) + * console.log(name); + * @alias jsstp.list_info_t + */ +declare class list_info_t extends base_sstp_info_t { + /** + * 自字符串构造list_info_t + * @param {String} list_text + * @ignore + */ + /*@__PURE__*/constructor(list_text: String) + /*@__PURE__*/toString(): String + /** + * 获取字符串报文 + * @returns {String} 字符串报文 + * @ignore + */ + /*@__PURE__*/TextContent(): String + /** + * 获取用于`JSON.stringify`的对象 + * @returns {Object} 用于`JSON.stringify`的对象 + * @ignore + */ + /*@__PURE__*/toJSON(): Object + /** + * 获取迭代器 + * @returns {Iterator>} 迭代器 + */ + /*@__PURE__*/[Symbol.iterator](): Iterator> + /** + * 数组成员 + * @type {string|undefined} + */ + [uuid: number]: string|undefined; +} + +export { + list_info_t, + list_info_t as default, +}; diff --git a/src/.decls/en/types/sstp_info_t.d.ts b/src/.decls/en/types/sstp_info_t.d.ts index 111776c..e124221 100644 --- a/src/.decls/en/types/sstp_info_t.d.ts +++ b/src/.decls/en/types/sstp_info_t.d.ts @@ -12,33 +12,22 @@ Option: notranslate 由一行固定的报文头和一组可选的报文体组成,以\r\n换行,结尾以\r\n\r\n结束。 */ /** - * sstp message class: class definition implementation - * @see sstp_info_t + * sstp message class * @example * let info = jsstp.sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); * console.log(info.head);//SSTP/1.4 200 OK * console.log(info.Option);//notranslate * @alias jsstp.sstp_info_t */ -declare class sstp_info_t_class_impl extends base_sstp_info_t { - /** - * Constructing sstp_info_t from split string or object messages is not recommended. - * @param {String} info_head The header of the message. - * @param {Object} info_body The body of the message in object format. - * @param {Array|undefined} unknown_lines Array of unknown lines. - * @see {@link sstp_info_t.from_string} - * @returns {sstp_info_t} - * @ignore - */ - /*@__PURE__*/constructor(info_head: String, info_body: Object, unknown_lines?: String[]); +declare class sstp_info_t extends base_sstp_info_t { /** - * Construct sstp_info_t from string - * @param {String} str String message - * @returns {sstp_info_t} constructed sstp_info_t + * 从字符串构造sstp_info_t + * @param {String} str 字符串报文 + * @returns {sstp_info_t} 构造的sstp_info_t * @example * let info = sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); */ - /*@__PURE__*/static from_string(str: String): sstp_info_t; + /*@__PURE__*/constructor(str: String); /** * Get the value of PassThru * @param {String} key The name of the PassThru to get. @@ -51,63 +40,16 @@ declare class sstp_info_t_class_impl extends base_sstp_info_t { */ /*@__PURE__*/get passthroughs(): info_object; /** - * Getting the raw object + * Get the original object * @returns {sstp_info_t} raw object */ /*@__PURE__*/get raw(): sstp_info_t; -} -/** - * Default members of the supplementary sstp message class - */ -type sstp_info_t_members = { + /** * Other message members * @type {String|undefined} */ - [key: string]: String | undefined; -}; -/** - * sstp message class: constructor interface declaration - */ -type sstp_info_t_constructor = { - /** - * Constructing sstp_info_t from split string or object messages is not recommended. - * @param {String} info_head The header of the message. - * @param {Object} info_body The body of the message in object format. - * @param {Array|undefined} unknown_lines Array of unknown lines. - * @see {@link sstp_info_t.from_string} - * @returns {sstp_info_t} - * @ignore - */ - /*@__PURE__*/new(info_head: String, info_body: Object, unknown_lines?: String[]): sstp_info_t; - /** - * Construct sstp_info_t from string - * @param {String} str String message - * @returns {sstp_info_t} constructed sstp_info_t - * @example - * let info = sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); - */ - /*@__PURE__*/from_string(str: String): sstp_info_t; -}; -/** - * sstp message class - * @example - * let info = jsstp.sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); - * console.log(info.head);//SSTP/1.4 200 OK - * console.log(info.Option);//notranslate - * @alias jsstp.sstp_info_t - */ -declare const sstp_info_t: typeof sstp_info_t_class_impl & sstp_info_t_constructor; -/** - * sstp message class - * @example - * let info = jsstp.sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); - * console.log(info.head);//SSTP/1.4 200 OK - * console.log(info.Option);//notranslate - * @alias jsstp.sstp_info_t - */ -type sstp_info_t = sstp_info_t_class_impl & sstp_info_t_members & { - constructor: typeof sstp_info_t; + [key: `some ${string}`]: String | undefined; } export default sstp_info_t; diff --git a/src/.decls/en/types/sstp_info_t.s.ts b/src/.decls/en/types/sstp_info_t.s.ts deleted file mode 100644 index 97ca82f..0000000 --- a/src/.decls/en/types/sstp_info_t.s.ts +++ /dev/null @@ -1,65 +0,0 @@ -import type base_sstp_info_t from "./base_sstp_info_t.d.ts"; -import type { info_object } from "./info_object.d.ts"; - -//定义sstp报文类 -/* -sstp报文格式: -SEND SSTP/1.1 -Charset: UTF-8 -Sender: SSTPクライアント -Script: \h\s0テストー。\u\s[10]テストやな。 -Option: notranslate -由一行固定的报文头和一组可选的报文体组成,以\r\n换行,结尾以\r\n\r\n结束。 -*/ -/** - * sstp message class - * @example - * let info = jsstp.sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); - * console.log(info.head);//SSTP/1.4 200 OK - * console.log(info.Option);//notranslate - * @alias jsstp.sstp_info_t - */ -declare class sstp_info_t extends base_sstp_info_t { - /** - * Construct sstp_info_t from split string or object messages, not recommended to use directly - * @param {String} info_head The header of the message. - * @param {Object} info_body The body of the message in object format. - * @param {Array|undefined} unknown_lines Array of unknown lines. - * @see {@link sstp_info_t.from_string} - * @returns {sstp_info_t} - * @ignore - */ - /*@__PURE__*/constructor(info_head: String, info_body: Object, unknown_lines?: String[]); - /** - * Construct sstp_info_t from string - * @param {String} str String message. - * @returns {sstp_info_t} constructed sstp_info_t - * @example - * let info = sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); - */ - /*@__PURE__*/static from_string(str: String): sstp_info_t; - /** - * Get the value of PassThru - * @param {String} key The name of the PassThru to get. - * @returns {String|undefined} the value of PassThru - */ - /*@__PURE__*/get_passthrough(key: String): String | undefined; - /** - * Get all PassThru - * @returns {info_object} all PassThru - */ - /*@__PURE__*/get passthroughs(): info_object; - /** - * Get the original object - * @returns {sstp_info_t} raw object - */ - /*@__PURE__*/get raw(): sstp_info_t; - - /** - * Other message members - * @type {String|undefined} - */ - [key: string]: String | undefined; -}; - -export default sstp_info_t; diff --git a/src/.decls/jp/jsstp.d.ts b/src/.decls/jp/jsstp.d.ts index 8f7719c..c6cc39a 100644 --- a/src/.decls/jp/jsstp.d.ts +++ b/src/.decls/jp/jsstp.d.ts @@ -8,6 +8,7 @@ import type fmo_info_t from "./types/fmo_info_t.d.ts"; import type ghost_events_queryer_t from "./types/ghost_events_queryer_t.d.ts"; import type jsstp_t from "./types/jsstp_t.d.ts"; +import type list_info_t from "./types/list_info_t.d.js"; //定义一个包装器 /** @@ -31,5 +32,6 @@ export { base_sstp_info_t, sstp_info_t, fmo_info_t, + list_info_t, ghost_events_queryer_t } diff --git a/src/.decls/jp/types/base_sstp_info_t.d.ts b/src/.decls/jp/types/base_sstp_info_t.d.ts index 50f6b16..b4049f3 100644 --- a/src/.decls/jp/types/base_sstp_info_t.d.ts +++ b/src/.decls/jp/types/base_sstp_info_t.d.ts @@ -43,12 +43,7 @@ declare class base_sstp_info_t extends info_objec * @returns {String} 文字列メッセージ。 * @ignore */ - /*@__PURE__*/toString(): String; - /** - * 文字列メッセージの取得 - * @returns {String} 文字列メッセージ。 - */ - /*@__PURE__*/to_string(): String; + /*@__PURE__*/TextContent(): String; /** * JSON.stringify` で使用するオブジェクトを取得する。 * @returns {Object} `JSON.stringify` で使用するオブジェクト。 diff --git a/src/.decls/jp/types/fmo_info_t.d.ts b/src/.decls/jp/types/fmo_info_t.d.ts index 382e28f..66008a6 100644 --- a/src/.decls/jp/types/fmo_info_t.d.ts +++ b/src/.decls/jp/types/fmo_info_t.d.ts @@ -78,18 +78,17 @@ declare interface single_fmo_info_t extends info_object { modulestate: string; } /** - * fmoメッセージクラス:クラス定義の実装 - * @see fmo_info_t + * FMOメッセージクラス * @example * let fmo = jsstp.get_fmo_infos(); * let kikka_uuid = fmo.get_uuid_by("name", "橘花"); * if(kikka_uuid) * console.log(fmo[kikka_uuid].ghostpath); + * @alias jsstp.fmo_info_t * @see {@link jsstp_t.get_fmo_infos} * @see {@link http://ssp.shillest.net/ukadoc/manual/spec_fmo_mutex.html} - * @group fmo_info_t implementations */ -declare class fmo_info_t_class_impl extends base_sstp_info_t { +declare class fmo_info_t extends base_sstp_info_t { /** * 分割された文字列メッセージまたはオブジェクト・メッセージから fmo_info_t を構築する,直接の使用は推奨されない。 * @param {String} fmo_text @@ -98,13 +97,13 @@ declare class fmo_info_t_class_impl extends base_sstp_info_t this[uuid][name] == value)` と等価です。 + * @description this.uuids.find(uuid => this[uuid][name] == value)`に相当する。 */ /*@__PURE__*/get_uuid_by(name: String, value: String): String | undefined; /** @@ -113,82 +112,22 @@ declare class fmo_info_t_class_impl extends base_sstp_info_tthis[uuid][name])`と同じ。 + * @description this.uuids.map(uuid=>this[uuid][name])`に相当する。 */ /*@__PURE__*/get_list_of(name: String): Array; /** - * @description すべてのuidsを取得する + * @description すべてのuuidsを取得する */ /*@__PURE__*/get uuids(): Array; /** * @description fmoが有効かどうかの判断 */ /*@__PURE__*/get available(): Boolean; - //注入toString方法便于使用 - /** - * 文字列メッセージの取得 - * @returns {String} 文字列メッセージ - * @ignore - */ - /*@__PURE__*/toString(): String; - /** - * `JSON.stringify` で使用するオブジェクトを取得する。 - * @returns {Object} `JSON.stringify` で使用するオブジェクト。 - * @ignore - */ - /*@__PURE__*/toJSON(): Object; -} -/** - * 補足fmoメッセージ・クラスのデフォルト・メンバー - * @group fmo_info_t implementations - */ -type fmo_info_t_members = { /** * fmoメンバー * @type {single_fmo_info_t|undefined} */ - [uuid: string]: single_fmo_info_t|undefined; -}; -/** - * fmoメッセージ・クラス:コンストラクタ・インターフェース宣言 - * @group fmo_info_t implementations - */ -type fmo_info_t_constructor = { - /** - * 分割された文字列メッセージまたはオブジェクト・メッセージから fmo_info_t を構築する,直接の使用は推奨されない。 - * @param {String} fmo_text - * @returns {void} - * @ignore - */ - /*@__PURE__*/new(fmo_text: String): fmo_info_t; -}; -/** - * FMOメッセージクラス - * @example - * let fmo = jsstp.get_fmo_infos(); - * let kikka_uuid = fmo.get_uuid_by("name", "橘花"); - * if(kikka_uuid) - * console.log(fmo[kikka_uuid].ghostpath); - * @alias jsstp.fmo_info_t - * @see {@link jsstp_t.get_fmo_infos} - * @see {@link http://ssp.shillest.net/ukadoc/manual/spec_fmo_mutex.html} - * @group fmo_info_t implementations - */ -declare const fmo_info_t: typeof fmo_info_t_class_impl & fmo_info_t_constructor; -/** - * FMOメッセージクラス - * @example - * let fmo = jsstp.get_fmo_infos(); - * let kikka_uuid = fmo.get_uuid_by("name", "橘花"); - * if(kikka_uuid) - * console.log(fmo[kikka_uuid].ghostpath); - * @alias jsstp.fmo_info_t - * @see {@link jsstp_t.get_fmo_infos} - * @see {@link http://ssp.shillest.net/ukadoc/manual/spec_fmo_mutex.html} - * @group fmo_info_t implementations - */ -type fmo_info_t = fmo_info_t_class_impl & fmo_info_t_members & { - constructor: typeof fmo_info_t; + [uuid: `some ${string}`]: single_fmo_info_t|undefined; } export { diff --git a/src/.decls/jp/types/fmo_info_t.s.ts b/src/.decls/jp/types/fmo_info_t.s.ts deleted file mode 100644 index cde25df..0000000 --- a/src/.decls/jp/types/fmo_info_t.s.ts +++ /dev/null @@ -1,151 +0,0 @@ -import type base_sstp_info_t from "./base_sstp_info_t.d.ts"; -import type { info_object } from "./info_object.d.ts"; - -/** - * fmoメッセージクラス:単一のfmo情報クラス - * 単一のゴーストの全てのfmo情報を記録します。 - * @example - * info_object { - * path: 'E:\\ssp\\', - * hwnd: '918820', - * name: '橘花', - * keroname: '斗和', - * 'sakura.surface': '-1', - * 'kero.surface': '-1', - * kerohwnd: '67008', - * hwndlist: '918820,67008', - * ghostpath: 'E:\\ssp\\ghost\\Taromati2\\', - * fullname: 'Taromati2', - * modulestate: 'shiori:running' - * } - * @see {@link http://ssp.shillest.net/ukadoc/manual/spec_fmo_mutex.html} - */ -declare interface single_fmo_info_t extends info_object { - /** - * @description 実行中のベースソフトのルートフォルダへのフルパス - * @example E:\ssp\ - */ - path: string; - /** - * @description メインウィンドウのウィンドウハンドル - * @example 918820 - */ - hwnd: string; - /** - * @description ディスクリプタ.txtのsakura.name - * @example 橘花 - */ - name: string; - /** - * @description descript.txtのkero.name - * @example 斗和 - */ - keroname: string; - /** - * @description 現在サイドに表示されているサーフェスID - * @example 0 - */ - "sakura.surface": string; - /** - * @description 現在表示されているサーフェスID - * @example 10 - */ - "kero.surface": string; - /** - * @description サイドウィンドウのハンドル - * @example 67008 - */ - kerohwnd: string; - /** - * @description 現在使用されているウィンドウハンドルのカンマ区切りリスト - * @example 918820,67008 - */ - hwndlist: string; - /** - * @description 実行中のゴーストへのフルパス - * @example E:\ssp\ghost\Taromati2\ - */ - ghostpath: string; - /** - * @description 実行中のゴーストのdescript.txtの名前 - * @example Taromati2 - */ - fullname: string; - /** - * @description 実行中のゴーストのモジュール状態 - * @example shiori:running,makoto-ghost:running - */ - modulestate: string; -} -/** - * FMOメッセージクラス - * @example - * let fmo = jsstp.get_fmo_infos(); - * let kikka_uuid = fmo.get_uuid_by("name", "橘花"); - * if(kikka_uuid) - * console.log(fmo[kikka_uuid].ghostpath); - * @alias jsstp.fmo_info_t - * @see {@link jsstp_t.get_fmo_infos} - * @see {@link http://ssp.shillest.net/ukadoc/manual/spec_fmo_mutex.html} - */ -declare class fmo_info_t extends base_sstp_info_t { - /** - * 分割された文字列メッセージまたはオブジェクト・メッセージから fmo_info_t を構築する,直接の使用は推奨されない。 - * @param {String} fmo_text - * @returns {void} - * @ignore - */ - /*@__PURE__*/constructor(fmo_text: String); - /** - * @param {String} name チェックするプロパティの名前 - * @param {String} value 望ましい属性値 - * @returns {String|undefined} 対応するuuid(もしあれば) - * @description 指定された属性を持ち、その属性の値が指定された値であるfmoのuuidを取得する。 - * @example - * let kikka_uuid = fmo_info.get_uuid_by("name", "橘花"); - * @description this.uuids.find(uuid => this[uuid][name] == value)`に相当する。 - */ - /*@__PURE__*/get_uuid_by(name: String, value: String): String | undefined; - /** - * @param {String} name - * @returns {Array} - * @description 指定されたすべてのプロパティの値を取得する - * @example - * let ghost_list = fmo_info.get_list_of("name"); - * @description this.uuids.map(uuid=>this[uuid][name])`に相当する。 - */ - /*@__PURE__*/get_list_of(name: String): Array; - /** - * @description すべてのuuidsを取得する - */ - /*@__PURE__*/get uuids(): Array; - /** - * @description fmoが有効かどうかの判断 - */ - /*@__PURE__*/get available(): Boolean; - //注入toString方法便于使用 - /** - * 文字列メッセージの取得 - * @returns {String} 文字列メッセージ。 - * @ignore - */ - /*@__PURE__*/toString(): String; - /** - * `JSON.stringify`用オブジェクトの取得 - * @returns {Object} `JSON.stringify` 用のオブジェクト。 - * @ignore - */ - /*@__PURE__*/toJSON(): Object; - - /** - * fmoメンバー - * @type {single_fmo_info_t|undefined} - */ - [uuid: string]: single_fmo_info_t|undefined; -}; - -export { - single_fmo_info_t, - fmo_info_t, - fmo_info_t as default, -}; diff --git a/src/.decls/jp/types/jsstp_t.d.ts b/src/.decls/jp/types/jsstp_t.d.ts index 718e8c7..5c7164d 100644 --- a/src/.decls/jp/types/jsstp_t.d.ts +++ b/src/.decls/jp/types/jsstp_t.d.ts @@ -2,6 +2,7 @@ import type { single_fmo_info_t , fmo_info_t } from "./fmo_info_t.d.ts"; import type ghost_events_queryer_t from "./ghost_events_queryer_t.d.ts"; import type sstp_info_t from "./sstp_info_t.d.ts"; import type base_sstp_info_t from "./base_sstp_info_t.d.ts"; +import type list_info_t from "./list_info_t.d.js"; import type { info_object } from "./info_object.d.ts"; import { security_level_t } from "../base/tools.js"; @@ -9,35 +10,29 @@ import { security_level_t } from "../base/tools.js"; * sstp メソッド呼び出し元 * @group callers */ -interface method_caller{ - (info: Object): Promise, - get_raw(info: Object): Promise +interface method_caller { + (...args: Rest): Promise; + get_raw(...args: Rest): Promise; + with_type(result_type: new (str:string) => nT): method_caller; + bind_args_processor(processor: (...args: Rest) => Object): method_caller; } /** - * イベント呼び出し元 + * 可以通过成员访问扩充指定key值的拓展调用器 * @group callers */ -interface base_event_caller{ - [key: string]: base_event_caller,//扩展事件名称 +interface base_keyed_method_caller extends method_caller { + /** + * 扩展调用器 + */ + [uuid: `some ${string}`]: base_keyed_method_caller + //_call Ts-index-excluder get_raw,with_type,bind_args_processor base_keyed_method_caller } /** - * シンプルなイベント・コーラー - * イベントをトリガーするために直接呼び出される! - * @example - * let data=await jsstp.OnTest(123,"abc"); - * //に相当する。 - * let data = await jsstp.SEND({ - * "Event": "OnTest", - * "Reference0": 123, - * "Reference1": "abc" - * }); + * 对调用参数进行简易处理的可扩展调用器 * @group callers */ -interface simple_event_caller extends base_event_caller { - (...args: any[]): Promise, - [key: string]: simple_event_caller,//扩展事件名称 -} +interface simple_keyed_method_caller extends base_keyed_method_caller {} /** * 汎用イベント・コーラー * イベントをトリガーするオブジェクトを渡すことで呼び出される! @@ -56,10 +51,41 @@ interface simple_event_caller extends base_event_caller { * }); * @group callers */ -interface common_event_caller extends base_event_caller{ - (info: Object): Promise, - [key: string]: common_event_caller,//扩展事件名称 -} +interface event_caller extends base_keyed_method_caller {} +/** + * 简易事件调用器 + * 直接调用以触发事件! + * @example + * let data=await jsstp.OnTest(123,"abc"); + * //等价于 + * let data = await jsstp.SEND({ + * "Event": "OnTest", + * "Reference0": 123, + * "Reference1": "abc" + * }); + * @group callers + */ +interface simple_event_caller extends simple_keyed_method_caller {} +/** + * 命令调用器 + * @group callers + */ +interface command_caller extends base_keyed_method_caller {} +/** + * 简易命令调用器 + * @group callers + */ +interface simple_command_caller extends simple_keyed_method_caller {} +/** + * 列表返值命令执行器 + * @group callers + */ +interface list_command_caller extends base_keyed_method_caller {} +/** + * 对参数进行简易处理的列表返值命令执行器 + * @group callers + */ +interface simple_list_command_caller extends simple_keyed_method_caller {} /** * link jsstp_t} よりも ghost_info 属性が1つ多い。 @@ -97,6 +123,10 @@ declare class jsstp_t{ * @group Types */ fmo_info_t: typeof fmo_info_t; + /** + * @group Types + */ + list_info_t: typeof list_info_t; /** * @group Types */ @@ -124,12 +154,26 @@ declare class jsstp_t{ GIVE: method_caller; /** - * イベント名をマッチさせて単純な呼び出し元を生成する - * @group jsstp_event_members + * 匹配事件名称以产生简易调用器 + * @group Index reflactions * @example * let data=await jsstp.OnTest(123,"abc"); */ [key: `On${string}`]: simple_event_caller; + /** + * 匹配事件名称以产生简易调用器 + * @group Index reflactions + * @example + * let data=await jsstp.GetNames(); + */ + [key: `Get${string}`]: simple_list_command_caller; + /** + * 匹配事件名称以产生简易调用器 + * @group Index reflactions + * @example + * let data=await jsstp.SetCookie("abc","def"); + */ + [key: `Set${string}`]: simple_command_caller; /** * fecth のヘッダ @@ -226,40 +270,51 @@ declare class jsstp_t{ */ costom_text_send(sstphead: String, info: Object): Promise; /** - * メッセージの送信 - * @param {String} sstphead メッセージヘッダ - * @param {Object} info メッセージ本文 * @returns {Promise} プロミスを返します。 + * 发送报文 + * @param {String} sstphead 报文头 + * @param {Object} info 报文体 + * @param {new (info: String)=> result_type} result_type 返回结果的类型,默认为sstp_info_t * @group Basic Send Methods */ - costom_send(sstphead: String, info: Object): Promise; - + costom_send(sstphead: String, info: Object, result_type: new (str: string) => T): Promise; + /** - * 指定したメソッドの呼び出し元を取得する - * @param {String} method_name メソッド名 - * @returns {{ - * (info: Object): Promise, - * get_raw(info: Object): Promise - * }} 呼び出し側 + * 获取指定方法的调用器 + * @param {String} method_name 方法名称 + * @param {new (info: String) => result_type} [result_type=sstp_info_t] 返回结果的类型,默认为sstp_info_t + * @param {Function} [args_processor=info => info] 参数处理器,默认直接返回输入参数 + * @returns {method_caller} 调用器 * @group Caller Methods */ - /*@__PURE__*/get_caller_of_method(method_name: String): method_caller; + /*@__PURE__*/get_caller_of_method(method_name: String, result_type?: new (str: string) => any, args_processor?: (...args: any[]) => Object): method_caller; /** - * 指定されたイベントの呼び出し元を取得する - * @param {String} event_name イベント名 - * @param {String|undefined} method_name メソッド名 - * @returns {{(info: Object) => Promise}} 呼び出し元 + * 获取指定key的调用器 + * @param {String} key_name 键名 + * @param {String} value_name 键值 + * @param {Function} method_caller 方法调用器 + * @param {Function} args_processor 参数处理器 + * @returns {Proxy} 调用器 * @group Caller Methods */ - /*@__PURE__*/get_caller_of_event(event_name: String, method_name?: String): common_event_caller; + /*@__PURE__*/get_caller_of_key( + key_name: String, value_name: String, + method_caller?: method_caller, + args_processor?: (...args: Rest) => Res + ): base_keyed_method_caller; + /** - * 指定されたイベントを取得するためのシンプルな呼び出し元 - * @param {String} event_name イベント名 - * @param {String|undefined} method_name メソッド名 - * @returns {{(info: Object) => Promise}} 呼び出し元 + * 用于获取指定key的简单调用器 + * @param {String} key_name 键名 + * @param {String} value_name 键值 + * @param {Function} method_caller 方法调用器 + * @returns {Proxy} 调用器 * @group Caller Methods */ - /*@__PURE__*/get_simple_caller_of_event(event_name: String, method_name?: String): simple_event_caller; + /*@__PURE__*/get_simple_caller_of_key( + key_name: String, value_name: String, + method_caller?: method_caller, + ): simple_keyed_method_caller; /** * 単純な呼び出し元が指定されたイベントを取得するためのプロキシ * @returns {Proxy} @@ -270,6 +325,16 @@ declare class jsstp_t{ /*@__PURE__*/get event(): { [event_name: string]: simple_event_caller } + /** + * 用于获取指定命令的执行器的代理 + * @returns {Proxy} + * @example + * jsstp.command.GetFMO(); + * @group Indexer Members + */ + /*@__PURE__*/get command(): { + [command_name: string]: simple_command_caller + } /** * イベントが存在するかどうかを判断する * {@link ghost_events_queryer_t}({@link jsstp_t.new_event_queryer}で取得)を使って、頻繁に呼び出されそうかどうかを問い合わせる。 diff --git a/src/.decls/jp/types/list_info_t.d.ts b/src/.decls/jp/types/list_info_t.d.ts new file mode 100644 index 0000000..adc0a0e --- /dev/null +++ b/src/.decls/jp/types/list_info_t.d.ts @@ -0,0 +1,46 @@ +import type base_sstp_info_t from "./base_sstp_info_t.d.ts"; + +/** + * list报文对象 + * @example + * let list = jsstp.GetNames(); + * for(let name of list) + * console.log(name); + * @alias jsstp.list_info_t + */ +declare class list_info_t extends base_sstp_info_t { + /** + * 自字符串构造list_info_t + * @param {String} list_text + * @ignore + */ + /*@__PURE__*/constructor(list_text: String) + /*@__PURE__*/toString(): String + /** + * 获取字符串报文 + * @returns {String} 字符串报文 + * @ignore + */ + /*@__PURE__*/TextContent(): String + /** + * 获取用于`JSON.stringify`的对象 + * @returns {Object} 用于`JSON.stringify`的对象 + * @ignore + */ + /*@__PURE__*/toJSON(): Object + /** + * 获取迭代器 + * @returns {Iterator>} 迭代器 + */ + /*@__PURE__*/[Symbol.iterator](): Iterator> + /** + * 数组成员 + * @type {string|undefined} + */ + [uuid: number]: string|undefined; +} + +export { + list_info_t, + list_info_t as default, +}; diff --git a/src/.decls/jp/types/sstp_info_t.d.ts b/src/.decls/jp/types/sstp_info_t.d.ts index cca38bd..58f70ec 100644 --- a/src/.decls/jp/types/sstp_info_t.d.ts +++ b/src/.decls/jp/types/sstp_info_t.d.ts @@ -12,26 +12,14 @@ Option: notranslate 由一行固定的报文头和一组可选的报文体组成,以\r\n换行,结尾以\r\n\r\n结束。 */ /** - * sstpメッセージクラス:クラス定義の実装 - * @see sstp_info_t + * SSTPメッセージクラス * @example * let info = jsstp.sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); * console.log(info.head);//SSTP/1.4 200 OK * console.log(info.Option);//notranslate * @alias jsstp.sstp_info_t - * @group sstp_info_t implementations */ -declare class sstp_info_t_class_impl extends base_sstp_info_t { - /** - * 分割された文字列メッセージまたはオブジェクト・メッセージから sstp_info_t を構築する,直接の使用は推奨されない。 - * @param {String} info_head メッセージのヘッダー。 - * @param {Object} info_body オブジェクト形式のメッセージ本文。 - * @param {Array|undefined} unknown_lines 未知の行の配列。 - * @see {@link sstp_info_t.from_string} - * @returns {sstp_info_t} - * @ignore - */ - /*@__PURE__*/constructor(info_head: String, info_body: Object, unknown_lines?: String[]); +declare class sstp_info_t extends base_sstp_info_t { /** * 文字列から sstp_info_t を構築する * @param {String} str メッセージ文字列 @@ -39,7 +27,7 @@ declare class sstp_info_t_class_impl extends base_sstp_info_t { * @example * let info = sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); */ - /*@__PURE__*/static from_string(str: String): sstp_info_t; + /*@__PURE__*/constructor(str: String); /** * PassThruの値を取得する * @param {String} key 取得するPassThruの名前。 @@ -56,63 +44,12 @@ declare class sstp_info_t_class_impl extends base_sstp_info_t { * @returns {sstp_info_t} 原物 */ /*@__PURE__*/get raw(): sstp_info_t; -} -/** - * 補足sstpメッセージ・クラスのデフォルト・メンバー - * @group sstp_info_t implementations - */ -type sstp_info_t_members = { + /** - * 其他报文成员 + * その他のメッセージメンバー * @type {String|undefined} */ - [key: string]: String | undefined; -}; -/** - * sstp メッセージクラス: コンストラクタ インタフェース宣言 - * @group sstp_info_t implementations - */ -type sstp_info_t_constructor = { - /** - * 分割された文字列メッセージまたはオブジェクト・メッセージから sstp_info_t を構築する,直接の使用は推奨されない。 - * @param {String} info_head メッセージのヘッダー。 - * @param {Object} info_body オブジェクト形式のメッセージ本文。 - * @param {Array|undefined} unknown_lines 未知の行の配列。 - * @see {@link sstp_info_t.from_string} - * @returns {sstp_info_t} - * @ignore - */ - /*@__PURE__*/new(info_head: String, info_body: Object, unknown_lines?: String[]): sstp_info_t; - /** - * 文字列から sstp_info_t を構築する - * @param {String} str メッセージ文字列 - * @returns {sstp_info_t} 構築された sstp_info_t - * @example - * let info = sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); - */ - /*@__PURE__*/from_string(str: String): sstp_info_t; -}; -/** - * SSTPメッセージクラス - * @example - * let info = jsstp.sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); - * console.log(info.head);//SSTP/1.4 200 OK - * console.log(info.Option);//notranslate - * @alias jsstp.sstp_info_t - * @group sstp_info_t implementations - */ -declare const sstp_info_t: typeof sstp_info_t_class_impl & sstp_info_t_constructor; -/** - * SSTPメッセージクラス - * @example - * let info = jsstp.sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); - * console.log(info.head);//SSTP/1.4 200 OK - * console.log(info.Option);//notranslate - * @alias jsstp.sstp_info_t - * @group sstp_info_t implementations - */ -type sstp_info_t = sstp_info_t_class_impl & sstp_info_t_members & { - constructor: typeof sstp_info_t; + [key: `some ${string}`]: String | undefined; } export default sstp_info_t; diff --git a/src/.decls/jp/types/sstp_info_t.s.ts b/src/.decls/jp/types/sstp_info_t.s.ts deleted file mode 100644 index 4b251f6..0000000 --- a/src/.decls/jp/types/sstp_info_t.s.ts +++ /dev/null @@ -1,65 +0,0 @@ -import type base_sstp_info_t from "./base_sstp_info_t.d.ts"; -import type { info_object } from "./info_object.d.ts"; - -//定义sstp报文类 -/* -sstp报文格式: -SEND SSTP/1.1 -Charset: UTF-8 -Sender: SSTPクライアント -Script: \h\s0テストー。\u\s[10]テストやな。 -Option: notranslate -由一行固定的报文头和一组可选的报文体组成,以\r\n换行,结尾以\r\n\r\n结束。 -*/ -/** - * SSTPメッセージクラス - * @example - * let info = jsstp.sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); - * console.log(info.head);//SSTP/1.4 200 OK - * console.log(info.Option);//notranslate - * @alias jsstp.sstp_info_t - */ -declare class sstp_info_t extends base_sstp_info_t { - /** - * 分割された文字列メッセージまたはオブジェクト・メッセージから sstp_info_t を構築する,直接の使用は推奨されない。 - * @param {String} info_head メッセージのヘッダー。 - * @param {Object} info_body オブジェクト形式のメッセージ本文。 - * @param {Array|undefined} unknown_lines 未知の行の配列。 - * @see {@link sstp_info_t.from_string} - * @returns {sstp_info_t} - * @ignore - */ - /*@__PURE__*/constructor(info_head: String, info_body: Object, unknown_lines?: String[]); - /** - * 文字列から sstp_info_t を構築する - * @param {String} str メッセージ文字列 - * @returns {sstp_info_t} 構築された sstp_info_t - * @example - * let info = sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); - */ - /*@__PURE__*/static from_string(str: String): sstp_info_t; - /** - * PassThruの値を取得する - * @param {String} key 取得するPassThruの名前。 - * @returns {String|undefined} PassThruの値。 - */ - /*@__PURE__*/get_passthrough(key: String): String | undefined; - /** - * すべてのPassThruを取得する - * @returns {info_object} すべてのパススルー - */ - /*@__PURE__*/get passthroughs(): info_object; - /** - * 元のオブジェクトの取得 - * @returns {sstp_info_t} 原物 - */ - /*@__PURE__*/get raw(): sstp_info_t; - - /** - * その他のメッセージメンバー - * @type {String|undefined} - */ - [key: string]: String | undefined; -}; - -export default sstp_info_t; diff --git a/src/base/base_values.mjs b/src/base/base_values.mjs deleted file mode 100644 index 49b992b..0000000 --- a/src/base/base_values.mjs +++ /dev/null @@ -1,9 +0,0 @@ -//这里定义一些关键内容以致于我们需要在其他地方前先行定义 - -var local = "local"; -var external = "external"; - -export { - local, - external, -}; diff --git a/src/base/tools.mjs b/src/base/tools.mjs index ea9f51a..7d3a70c 100644 --- a/src/base/tools.mjs +++ b/src/base/tools.mjs @@ -1,20 +1,10 @@ -import { - the_object, - the_proxy, - the_string, - the_function, +import { + assign, undefined, void_string, - - substring, - length, - prototype, - assign, } from "./value_table.mjs" -import{local,external}from"./base_values.mjs"; - /** * 以spliter分割字符串str,只对第一个匹配的分隔符做分割 * @param {String} str 需要分割的字符串 @@ -26,7 +16,7 @@ import{local,external}from"./base_values.mjs"; */ var key_value_split = /*@__PURE__*/(str, spliter) => { let index = str.indexOf(spliter); - return [str[substring](0, index), str[substring](index + spliter[length])]; + return [str.substring(0, index), str.substring(index + spliter.length)]; } /** * 判断某一string是否符合给定的正则表达式 @@ -50,7 +40,7 @@ var is_event_name = /*@__PURE__*/(str) => /*@__INLINE__*/reg_test(/^On/, str); * @returns {String} 重整后的事件名 * @ignore */ -var get_reorganized_event_name = /*@__PURE__*/(str) => str[2] == "_" ? str[substring](3) : str; +var get_reorganized_event_name = /*@__PURE__*/(str) => str[2] == "_" ? str.substring(3) : str; /** * 判断一个数是否不是NaN * @param {Number} num 要判断的数 @@ -74,7 +64,7 @@ var is_not_nan = /*@__PURE__*/(num) => num == num; * @returns {Boolean} 是否为X类型 * @ignore */ -var type_judge = /*@__PURE__*/(value, X) => the_object(value) instanceof X; +var type_judge = /*@__PURE__*/(value, X) => Object(value) instanceof X; /** * 对代理的get方法进行封装,使其定义更为简单 * @param {{ @@ -91,7 +81,7 @@ var new_get_handler = /*@__PURE__*/(info) => if (info._blocker_?.(target, key)) return; let result; - if (type_judge(key, the_string)) + if (type_judge(key, String)) result = info._string_key_handler_?.(target, key); else//symbol result = info._symbol_key_handler_?.(target, key); @@ -99,7 +89,7 @@ var new_get_handler = /*@__PURE__*/(info) => return result; else if (info._default_handler_) return info._default_handler_(target, key) - return type_judge(result = target[key], the_function) ? result.bind(target) : result; + return type_judge(result = target[key], Function) ? result.bind(target) : result; } /** * 更合适的默认代理setter @@ -123,21 +113,21 @@ var default_setter = (target, key, value)=>((target[key] = value),1); * @returns {Proxy} 代理 * @ignore */ -var new_getter_proxy = (target, getter_info, other_info) => new the_proxy(target,assign({ +var new_getter_proxy = (target, getter_info, other_info) => new Proxy(target,assign({ get: new_get_handler(getter_info), set: default_setter },other_info)); /** * 一个可用函数初始化的可扩展的函数类型,用于更为可读的派生类函数类型 */ -class ExtensibleFunction extends the_function { +class ExtensibleFunction extends Function { /** * 自函数实例初始化 * @param {Function} func * @returns {ExtensibleFunction} */ constructor(func) { - return the_object.setPrototypeOf(func, new.target[prototype]); + return Object.setPrototypeOf(func, new.target.prototype); } } @@ -173,7 +163,7 @@ var get_local_address = /*@__PURE__*/(port) => `http://localhost:${port??9801}`; */ var in_browser = !!globalThis.window;//尽管globalThis.self也可以做到同样的事情(并且可以在压缩后的代码中节省2字节) //但是为了避免node今后实现self,我们使用window -//node大概率不会实现window,因为多数代码都在使用windows判断是否在浏览器中 +//node大概率不会实现window,因为多数代码都在使用window判断是否在浏览器中 //这样做还能兼容html4!...大概? /** @@ -189,7 +179,7 @@ var my_origin = in_browser ? location.origin : get_local_address(process.env.POR * @see {@link https://www.google.com/search?q=site%3Assp.shillest.net%2Fukadoc%2F+SecurityLevel} * @ignore */ -var my_default_security_level = /*@__INLINE__*/reg_test(/^\w+:\/\/localhost/, my_origin) ? local : external; +var my_default_security_level = /*@__INLINE__*/reg_test(/^\w+:\/\/localhost/, my_origin) ? "local" : "external"; /** * 自身的代码内容 @@ -198,8 +188,8 @@ var my_default_security_level = /*@__INLINE__*/reg_test(/^\w+:\/\/localhost/, my */ var my_code = /*@__PURE__*/(()=>{ let my_url = import.meta.url; - if(my_url[substring](0,5) == "file:" && !in_browser) - import("fs").then(fs=>fs.readFileSync(my_url[substring](8))).then(buffer=>my_code=buffer.toString()); + if(my_url.substring(0,5) == "file:" && !in_browser) + import("fs").then(fs=>fs.readFileSync(my_url.substring(8))).then(buffer=>my_code=to_string(buffer)); else fetch(my_url).then(res=>res.text()).then(text=>my_code=text); })(); diff --git a/src/base/value_table.mjs b/src/base/value_table.mjs index 115d40e..12a182d 100644 --- a/src/base/value_table.mjs +++ b/src/base/value_table.mjs @@ -1,143 +1,23 @@ //一些会反复用到的常量或函数,提前定义以便在压缩时能够以短名称存在 -/** - * @typename the_object - * @type {ObjectConstructor} - * @ignore - */ -var the_object = Object; -/** - * @typename the_proxy - * @type {ProxyConstructor} - * @ignore - */ -var the_proxy = Proxy; -var assign = the_object.assign; +var assign = Object.assign; var endline = "\r\n"; var undefined;// =undefined -/** - * 将字符串转换为小写 - * @param {String} str 要转换的字符串 - * @returns {String} 转换后的字符串 - */ -var to_lower_case = str => str.toLowerCase(); - -var Get_Supported_Events = "Get_Supported_Events"; -var Has_Event = "Has_Event"; -var get_supported_events = to_lower_case(Get_Supported_Events); -var has_event = to_lower_case(Has_Event); -var get_simple_caller_of_event = "get_simple_caller_of_event"; -var trivial_clone = "trivial_clone"; -var default_info = "default_info"; -var default_security_level="default_security_level"; -var sstp_version_table = "sstp_version_table"; -var substring = "substring"; -var length = "length"; -var available = "available"; -var split = "split"; -var entries = "entries"; -var costom_text_send = "costom_text_send"; -var forEach = "forEach"; -var get_caller_of_method = "get_caller_of_method"; -var unknown_lines = "unknown_lines"; -var get_caller_of_event = "get_caller_of_event"; -var sendername = "sendername"; -var proxy = "proxy"; -var constructor = "constructor"; -var then = "then"; -var prototype = "prototype"; -var SEND = "SEND"; -var get_fmo_infos = "get_fmo_infos"; -var get_passthrough = "get_passthrough"; -var flat_map = "flat_map"; -var RequestHeader = "RequestHeader"; -var check_event = "check_event"; -var from_string = "from_string"; -var ghost_info = "ghost_info"; - -import{local,external}from"./base_values.mjs"; - var void_string = ""; var _false_ = !1; -/** - * @typename the_string - * @type {StringConstructor} - * @ignore - */ -var the_string = void_string[constructor]; - -/** - * @typename the_function - * @type {FunctionConstructor} - * @ignore - */ -var the_function = to_lower_case[constructor]; - -/** - * @typename the_number - * @type {NumberConstructor} - * @ignore - */ -var the_number = 0[constructor]; - -/** - * @typename the_array - * @type {ArrayConstructor} - * @ignore - */ -var the_array = [][constructor]; - var x_sstp_passthru_head = "X-SSTP-PassThru-"; +var SEND = "SEND"; export { - the_object, - the_proxy, - the_function, - the_string, - the_number, - the_array, assign, endline, undefined, - Get_Supported_Events, - Has_Event, - get_supported_events, - has_event, - get_simple_caller_of_event, - sstp_version_table, - substring, - available, - split, - default_security_level, - trivial_clone, - default_info, - costom_text_send, - forEach, - length, - get_caller_of_method, - get_caller_of_event, - unknown_lines, - get_fmo_infos, - get_passthrough, - sendername, - entries, - proxy, - prototype, - then, - SEND, - flat_map, - from_string, - RequestHeader, - check_event, - ghost_info, - - local, - external, x_sstp_passthru_head, void_string, _false_, + SEND, }; diff --git a/src/jsstp.mjs b/src/jsstp.mjs index 888a84d..f7870b6 100644 --- a/src/jsstp.mjs +++ b/src/jsstp.mjs @@ -4,6 +4,7 @@ import base_sstp_info_t from "./types/base_sstp_info_t.mjs"; import sstp_info_t from "./types/sstp_info_t.mjs"; +import list_info_t from "./types/list_info_t.mjs"; import fmo_info_t from "./types/fmo_info_t.mjs"; import ghost_events_queryer_t from "./types/ghost_events_queryer_t.mjs"; @@ -31,5 +32,6 @@ export { base_sstp_info_t, sstp_info_t, fmo_info_t, - ghost_events_queryer_t + ghost_events_queryer_t, + list_info_t } diff --git a/src/types/base_sstp_info_t.mjs b/src/types/base_sstp_info_t.mjs index e99ed28..1163b04 100644 --- a/src/types/base_sstp_info_t.mjs +++ b/src/types/base_sstp_info_t.mjs @@ -4,12 +4,6 @@ import { //undefined, void_string, - - entries, - length, - split, - trivial_clone, - unknown_lines, } from "../base/value_table.mjs"; import { is_not_nan, @@ -50,42 +44,34 @@ class base_sstp_info_t extends info_object { * @see {@link sstp_info_t.from_string} * @ignore */ - /*@__PURE__*/constructor(info_head, info_body, unknown_lines = {}) { - super(); - this.#head = /*@__INLINE__*/to_string(info_head); - if (unknown_lines[length]) - this.#unknown_lines = unknown_lines; - assign(this, info_body); + /*@__PURE__*/constructor(info_head, info_body, unknown_lines) { + super(info_body); + this.#head = info_head; + this.#unknown_lines = unknown_lines || []; } /** * 获取未知行的数组 * @returns {Array} 未知行的数组 */ - /*@__PURE__*/get [unknown_lines]() { return this.#unknown_lines || []; } + /*@__PURE__*/get unknown_lines() { return this.#unknown_lines || []; } /** * 获取报文头 * @returns {String} 报文头 */ /*@__PURE__*/get head() { return this.#head; } - //注入toString方法便于使用 /** * 获取字符串报文 * @returns {String} 字符串报文 * @ignore */ - /*@__PURE__*/toString() { + /*@__PURE__*/TextContent() { return [ this.#head, - ...this[unknown_lines], - ...this[entries].map(([key, value]) => `${key}: ${value}`), + ...this.#unknown_lines, + ...this.entries.map(([key, value]) => `${key}: ${value}`), void_string,void_string//空行结尾 ].join(endline); } - /** - * 获取字符串报文 - * @returns {String} 字符串报文 - */ - /*@__PURE__*/to_string() { return /*@__INLINE__*/to_string(this); }//兼容命名 /** * 获取用于`JSON.stringify`的对象 * @returns {Object} 用于`JSON.stringify`的对象 @@ -94,8 +80,8 @@ class base_sstp_info_t extends info_object { /*@__PURE__*/toJSON() { return { head: this.#head, - [unknown_lines]: this.#unknown_lines, - body: this[trivial_clone] + unknown_lines: this.#unknown_lines, + body: this.trivial_clone }; } /** @@ -104,8 +90,23 @@ class base_sstp_info_t extends info_object { */ /*@__PURE__*/get status_code() { //比如:SSTP/1.4 200 OK,返回200 - return +this.#head[split](" ").find(value => is_not_nan(+value)); + return +this.#head.split(" ").find(value => is_not_nan(+value)); } } +/** + * 从字符串分割出报文头和报文体 + * @param {String} info_text 字符串报文 + * @returns {Array} [报文头, ...报文体] + */ +/*@__PURE__*/function split_sstp_text(info_text) { + let result = info_text.split(endline); + //去掉最后的空行*2 + result.length -= 2; + return result; +} -export default base_sstp_info_t; +export { + base_sstp_info_t as default, + base_sstp_info_t, + split_sstp_text, +}; diff --git a/src/types/fmo_info_t.mjs b/src/types/fmo_info_t.mjs index 1fdf9f5..6b62e9a 100644 --- a/src/types/fmo_info_t.mjs +++ b/src/types/fmo_info_t.mjs @@ -4,18 +4,12 @@ import { //undefined, void_string, - - length, - split, - available, - trivial_clone, - flat_map, } from "../base/value_table.mjs"; import { key_value_split, } from "../base/tools.mjs"; import new_object from "./info_object.mjs"; -import base_sstp_info_t from "./base_sstp_info_t.mjs"; +import {base_sstp_info_t,split_sstp_text} from "./base_sstp_info_t.mjs"; /** * fmo报文类 @@ -30,16 +24,15 @@ import base_sstp_info_t from "./base_sstp_info_t.mjs"; */ class fmo_info_t extends base_sstp_info_t { /** - * 自字符串构造fmo_info_t,不建议直接使用 + * 自字符串构造fmo_info_t * @param {String} fmo_text * @ignore */ /*@__PURE__*/constructor(fmo_text) { - let [head, ...lines] = fmo_text[split](endline); + let [head, _, ...lines] = split_sstp_text(fmo_text); super(head, {}); //fmo_info每个key的格式都是"uuid.属性名" for (let line of lines) { - if (!line) continue; let [key_base, value] = key_value_split(line, String.fromCharCode(1)); let [uuid, key] = key_value_split(key_base, "."); (this[uuid] ||= new_object())[key] = value;//uuid对应的对象应是info_object以方便使用,且下方flat_map调用需要其方法 @@ -75,18 +68,17 @@ class fmo_info_t extends base_sstp_info_t { /** * @description 判断fmo是否有效 */ - /*@__PURE__*/get [available]() { return !!this[length]; } - //注入toString方法便于使用 + /*@__PURE__*/get available() { return !!this.length; } /** * 获取字符串报文 * @returns {String} 字符串报文 * @ignore */ - /*@__PURE__*/toString() { + /*@__PURE__*/TextContent() { return [ this.head, void_string, - ...this[flat_map]((uuid, key, value) => uuid + "." + key + String.fromCharCode(1) + value), + ...this.flat_map((uuid, key, value) => uuid + "." + key + String.fromCharCode(1) + value), void_string,void_string ].join(endline); } @@ -98,7 +90,7 @@ class fmo_info_t extends base_sstp_info_t { /*@__PURE__*/toJSON() { return { head: this.head, - fmo_infos: this[trivial_clone] + fmo_infos: this.trivial_clone }; } } diff --git a/src/types/ghost_events_queryer_t.mjs b/src/types/ghost_events_queryer_t.mjs index a98b218..df2c1d4 100644 --- a/src/types/ghost_events_queryer_t.mjs +++ b/src/types/ghost_events_queryer_t.mjs @@ -5,18 +5,6 @@ import { undefined, */ - Get_Supported_Events, - Has_Event, - get_supported_events, - has_event, - default_security_level, - available, - - local, - external, - - check_event, - _false_, } from "../base/value_table.mjs"; import { @@ -89,7 +77,7 @@ class ghost_events_queryer_t extends ExtensibleFunction { * let result = await ghost_events_queryer("On_connect"); * @see 基于 {@link ghost_events_queryer_t.check_event} */ - (event_name, security_level = this[default_security_level])=>this[check_event](event_name, security_level) + (event_name, security_level = this.default_security_level)=>this.check_event(event_name, security_level) ); this.#base_jsstp = base_jsstp; /** @@ -97,7 +85,7 @@ class ghost_events_queryer_t extends ExtensibleFunction { * @type {String} * @see {@link https://www.google.com/search?q=site%3Assp.shillest.net%2Fukadoc%2F+SecurityLevel} */ - this[default_security_level] = base_jsstp[default_security_level]; + this.default_security_level = base_jsstp.default_security_level; } /** * 检查事件是否存在,ghost至少需要`Has_Event`事件的支持,并可以通过提供`Get_Supported_Events`事件来提高效率 @@ -108,11 +96,11 @@ class ghost_events_queryer_t extends ExtensibleFunction { * let result = await ghost_events_queryer.check_event("On_connect"); * @see 基于 {@link jsstp_t.has_event} 和 {@link jsstp_t.get_supported_events} */ - /*@__PURE__*/async [check_event](event_name, security_level = this[default_security_level]) { + /*@__PURE__*/async check_event(event_name, security_level = this.default_security_level) { if (this.#ghost_has_get_supported_events) return this.#ghost_event_list[security_level].includes(event_name); else if (this.#ghost_has_has_event) - return this.#ghost_event_list_cache[security_level][event_name] ??= await this.#base_jsstp[has_event](event_name); + return this.#ghost_event_list_cache[security_level][event_name] ??= await this.#base_jsstp.has_event(event_name); else return _false_; } @@ -123,7 +111,7 @@ class ghost_events_queryer_t extends ExtensibleFunction { * if(!ghost_events_queryer.available) * console.error("无法检查事件"); */ - /*@__PURE__*/get [available]() { return this.#ghost_has_has_event; } + /*@__PURE__*/get available() { return this.#ghost_has_has_event; } /** * 检查是否能够使用`Get_Supported_Events`快速获取支持的事件列表 * @returns {Promise} @@ -147,15 +135,15 @@ class ghost_events_queryer_t extends ExtensibleFunction { */ async init() { let jsstp = this.#base_jsstp; - this.#ghost_has_has_event = await jsstp[has_event](Has_Event); - this.#ghost_has_get_supported_events = this.#ghost_has_has_event && await jsstp[has_event](Get_Supported_Events); + this.#ghost_has_has_event = await jsstp.has_event("Has_Event"); + this.#ghost_has_get_supported_events = this.#ghost_has_has_event && await jsstp.has_event("Get_Supported_Events"); if (this.#ghost_has_get_supported_events) - this.#ghost_event_list = await jsstp[get_supported_events](); + this.#ghost_event_list = await jsstp.get_supported_events(); return this; } clear() { this.#ghost_has_has_event = this.#ghost_has_get_supported_events = _false_; - this.#ghost_event_list_cache = { [local]: {}, [external]: {} }; + this.#ghost_event_list_cache = { local: {}, external: {} }; } } diff --git a/src/types/info_object.mjs b/src/types/info_object.mjs index 3c138f1..05bd70a 100644 --- a/src/types/info_object.mjs +++ b/src/types/info_object.mjs @@ -1,13 +1,6 @@ import { - the_object, assign, undefined, - - entries, - length, - forEach, - trivial_clone, - flat_map, } from "../base/value_table.mjs"; import { type_judge, @@ -21,30 +14,30 @@ class info_object { * @param {Object} base_value */ constructor(base_value) { - assign(this, base_value); + Object.assign(this, base_value); } /** * @description 获取所有key的数组 */ - /*@__PURE__*/get keys() { return the_object.keys(this); } + /*@__PURE__*/get keys() { return Object.keys(this); } /** * @description 获取所有value的数组 */ - /*@__PURE__*/get values() { return the_object.values(this); } + /*@__PURE__*/get values() { return Object.values(this); } /** * @description 获取所有key-value对的数组 */ - /*@__PURE__*/get [entries]() { return the_object[entries](this); } + /*@__PURE__*/get entries() { return Object.entries(this); } /** * @description 获取成员数量 */ - /*@__PURE__*/get [length]() { return this.keys[length]; } + /*@__PURE__*/get length() { return this.keys.length; } /** * @description 对每个key-value对执行某个函数 * @param {(value,key?)} func 要执行的函数 */ - /*@__PURE__*/[forEach](func) { - this[entries][forEach](([key, value]) => { + /*@__PURE__*/forEach(func) { + this.entries.forEach(([key, value]) => { this[key] = func(value, key) ?? value; }); } @@ -52,19 +45,19 @@ class info_object { * @description 复制一个新的对象 * @returns {info_object} 复制的对象 */ - /*@__PURE__*/get [trivial_clone]() { + /*@__PURE__*/get trivial_clone() { return assign(new_object(), this); } /** * @description 遍历自身和子对象并返回一个由遍历结果构成的一维数组 * @param {(dimensions[...],value):any} func 要执行的函数,返回值将被添加到数组中 */ - /*@__PURE__*/[flat_map](func) { + /*@__PURE__*/flat_map(func) { let result = []; - this[entries].map(([key, value]) => + this.entries.map(([key, value]) => result.push(...( type_judge(value, info_object)? - value[flat_map](func.bind(func, key)): + value.flat_map(func.bind(func, key)): [func(key, value)]//构建数组,因为外部有展开操作 )) ); @@ -75,14 +68,14 @@ class info_object { * @param {(value,key?):any} func 要执行的函数,返回值将被添加到数组中 */ /*@__PURE__*/map(func) { - return this[entries].map(([key, value]) => func(value, key)); + return this.entries.map(([key, value]) => func(value, key)); } /** * @description 对自身按照数组追加元素 * @param {[undefined|[PropertyKey,any]]} array 要追加的数组 */ /*@__PURE__*/push(array) { - array[forEach]((pair) => pair ? this[pair[0]] = pair[1] : undefined); + array.forEach((pair) => pair ? this[pair[0]] = pair[1] : undefined); return this; } /** @@ -90,7 +83,7 @@ class info_object { * @param {(value,key?):boolean} func 要执行的函数 */ /*@__PURE__*/every(func) { - return this[entries].every(([key, value]) => func(value, key)); + return this.entries.every(([key, value]) => func(value, key)); } } /** diff --git a/src/types/jsstp_t.mjs b/src/types/jsstp_t.mjs index 8984f98..2218bd4 100644 --- a/src/types/jsstp_t.mjs +++ b/src/types/jsstp_t.mjs @@ -2,49 +2,18 @@ //发信方法:Content-Type: text/plain HTTP/1.1でPOST //收信方法:HTTP/1.1 200 OKのContent-Type: text/plain import { - the_proxy, - assign, //endline, undefined, void_string, - Get_Supported_Events, - Has_Event, - get_supported_events, - has_event, - get_simple_caller_of_event, - default_info, - default_security_level, - sstp_version_table, - available, - forEach, - costom_text_send, - get_caller_of_method, - get_caller_of_event, - sendername, - get_fmo_infos, - split, - proxy, - then, - prototype, - from_string, - RequestHeader, - SEND, - ghost_info, - - local, - external, - _false_, - the_number, } from "../base/value_table.mjs"; import { is_event_name, get_reorganized_event_name, new_getter_proxy, - to_string, type_judge, clone, @@ -70,6 +39,7 @@ var get_sstp_header = (type,version_table) => `${type} SSTP/${version_table[type import{SEND as default_sstp_method}from"../base/value_table.mjs" import new_object from "./info_object.mjs"; +import list_info_t from "./list_info_t.mjs"; //定义一个包装器 /** @@ -93,20 +63,20 @@ class jsstp_t { */ /*@__PURE__*/constructor(sender_name, host) { //super(); - this[RequestHeader] = { + this.RequestHeader = { //"Content-Type": "text/plain",//省略Content-Type并不会导致sstp无法正常工作,还能压缩dist体积。 "Origin": my_origin }; - this[default_info] = { Charset: "UTF-8" };//指定字符集,否则ssp会以本地字符集解码 + this.default_info = { Charset: "UTF-8" };//指定字符集,否则ssp会以本地字符集解码 this.host = host; - this[sendername] = sender_name; + this.sendername = sender_name; /** * SSTP协议版本号列表 */ - this[sstp_version_table] = { - [SEND]: 1.4, + this.sstp_version_table = { + SEND: 1.4, NOTIFY: 1.1, COMMUNICATE: 1.1, EXECUTE: 1.2, @@ -117,14 +87,18 @@ class jsstp_t { * @type {"local"|"external"} * @see {@link https://www.google.com/search?q=site%3Assp.shillest.net%2Fukadoc%2F+SecurityLevel} */ - this[default_security_level] = my_default_security_level; + this.default_security_level = my_default_security_level; - return this[proxy] = new_getter_proxy(this,{ + return this.proxy = new_getter_proxy(this,{ _string_key_handler_: (target, key) => - type_judge(target[sstp_version_table][key], the_number) ? - target[get_caller_of_method](key) : + type_judge(target.sstp_version_table[key], Number) ? + target.get_caller_of_method(key) : is_event_name(key) ? - target[get_simple_caller_of_event](get_reorganized_event_name(key)) : + target.event[get_reorganized_event_name(key)] : + key.startsWith("Get") ? + target.command[key].with_type(list_info_t) : + key.startsWith("Set") ? + target.command[key] : undefined }); } @@ -133,15 +107,14 @@ class jsstp_t { * @group Clone Methods */ get clone() { - let self=this; return assign(new jsstp_t(), { - [RequestHeader]: clone(self[RequestHeader]), - [default_info]: clone(self[default_info]), - [default_security_level]: self[default_security_level], - [sstp_version_table]: clone(self[sstp_version_table]), + RequestHeader: clone(this.RequestHeader), + default_info: clone(this.default_info), + default_security_level: this.default_security_level, + sstp_version_table: clone(this.sstp_version_table), //[sendername]: self[sendername], //不需要:default_info已经包含了sendername - host: self.host, - [ghost_info]: self[ghost_info], + host: this.host, + ghost_info: this.ghost_info, }); } /** @@ -152,8 +125,8 @@ class jsstp_t { */ by_fmo_info(fmo_info){ let result=this.clone; - result[ghost_info]=fmo_info, - result[default_info].ReceiverGhostHWnd=fmo_info.hwnd; + result.ghost_info=fmo_info, + result.default_info.ReceiverGhostHWnd=fmo_info.hwnd; return result; } /** @@ -162,7 +135,7 @@ class jsstp_t { */ for_all_ghost_infos(operation){ let result = new_object(); - return this.get_fmo_infos()[then](fmo_infos=>{ + return this.get_fmo_infos().then(fmo_infos=>{ for(let uuid in fmo_infos) result[uuid] = operation?.(fmo_infos[uuid]); return result; @@ -187,8 +160,8 @@ class jsstp_t { * @param {String} sender_name * @group Properties */ - set [sendername](sender_name) { this[default_info].Sender = sender_name || "jsstp-client"; } - /*@__PURE__*/get [sendername]() { return this[default_info].Sender; } + set sendername(sender_name) { this.default_info.Sender = sender_name || "jsstp-client"; } + /*@__PURE__*/get sendername() { return this.default_info.Sender; } /** * 以文本发送报文并以文本接收返信 * @param {any} info 报文体(文本) @@ -200,8 +173,8 @@ class jsstp_t { //使用fetch发送数据 let response=await fetch(this.#host, { method: "POST", - headers: this[RequestHeader], - body: /*@__INLINE__*/to_string(info) + headers: this.RequestHeader, + body: info }); if(response.status != 200) throw_error(response.status); @@ -215,91 +188,83 @@ class jsstp_t { * 若一切正常其内容为发送后得到的返回值,否则为`undefined` * @group Basic Send Methods */ - [costom_text_send](sstphead, info) { - return this.row_send(new sstp_info_t(sstphead, { ...this[default_info], ...info })); + costom_text_send(sstphead, info) { + return this.row_send((new base_sstp_info_t(sstphead, { ...this.default_info, ...info })).TextContent()); } /** * 发送报文 * @param {String} sstphead 报文头 * @param {Object} info 报文体 - * @returns {Promise} 返回一个promise + * @param {new (info: String) => result_type} [result_type=sstp_info_t] 返回结果的类型,默认为sstp_info_t + * @returns {Promise} 返回一个promise * @group Basic Send Methods */ - costom_send(sstphead, info) { - return this[costom_text_send](sstphead, info)[then]( - result => sstp_info_t[from_string](result) + costom_send(sstphead, info, result_type = sstp_info_t) { + return this.costom_text_send(sstphead, info).then( + result => new result_type(result) ); } /** * 获取指定方法的调用器 * @param {String} method_name 方法名称 - * @returns {{ - * (info: Object): Promise, - * get_raw(info: Object): Promise + * @param {new (info: String) => result_type} [result_type=sstp_info_t] 返回结果的类型,默认为sstp_info_t + * @param {Function} [args_processor=info => info] 参数处理器,默认直接返回输入参数 + * @returns {this={ + * (info: Object): Promise, + * get_raw(info: Object): Promise, + * with_type(result_type: Function): Function, + * bind_args_processor(processor: Function): Function * }} 调用器 - * @group Caller Methods + * @group Caller Methods */ - /*@__PURE__*/[get_caller_of_method](method_name) { - let header = get_sstp_header(method_name,this[sstp_version_table]); - return assign((info) => this.costom_send(header, info), { - get_raw: (info) => this[costom_text_send](header, info) + /*@__PURE__*/get_caller_of_method(method_name, result_type = sstp_info_t, args_processor = info => info) { + let header = get_sstp_header(method_name,this.sstp_version_table); + return assign((...args) => this.costom_send(header, args_processor(...args), result_type), { + get_raw: (...args) => this.costom_text_send(header, args_processor(...args)), + with_type: (result_type) => this.get_caller_of_method(method_name, result_type, args_processor), + bind_args_processor: (processor) => this.get_caller_of_method(method_name, result_type, processor) }); } /** - * 对指定事件名的调用器进行适当的包装 - * 作用1:使得调用器可以像promise一样使用then方法 - * 作用2:使得调用器可以通过属性追加事件名来获取新的调用器 - * @param {String} event_name 事件名称 - * @param {String|undefined} method_name 方法名称 - * @param {Function} value 调用器的值 - * @param {{[String]:(event_name: String, method_name: String)}} caller_factory 调用器工厂 + * 用于获取指定key的调用器 + * @param {String} key_name 键名 + * @param {String} value_name 键值 + * @param {Function} method_caller 方法调用器 + * @param {Function} args_processor 参数处理器 * @returns {Proxy} 调用器 * @group Caller Methods */ - /*@__PURE__*/#warp_the_caller_of_event(event_name,method_name,value,caller_factory) { - return new the_proxy(value, { - get: (target, prop) => - prop in target ? - target[prop] : + /*@__PURE__*/get_caller_of_key(key_name,value_name, + method_caller = this.get_caller_of_method(default_sstp_method), args_processor=info=>info + ) { + return new Proxy(method_caller.bind_args_processor( + (...args) => assign({ [key_name]: value_name }, args_processor(...args)) + ), { + get: (target, prop) => + prop in target? + target[prop]: //else - this[caller_factory](event_name+"."+prop, method_name) + this.get_caller_of_key(key_name,value_name+"."+prop, method_caller, args_processor) }); } /** - * 获取指定事件的调用器 - * @param {String} event_name 事件名称 - * @param {String|undefined} method_name 方法名称 - * @returns {{(info: Object) => Promise}} 调用器 - * @group Caller Methods - */ - /*@__PURE__*/[get_caller_of_event](event_name, method_name = default_sstp_method) { - return this.#warp_the_caller_of_event( - event_name, - method_name, - (info) => this[proxy][method_name](assign({ Event: event_name }, info)), - get_caller_of_event - ); - } - /** - * 用于获取指定事件的简单调用器 - * @param {String} event_name 事件名称 - * @param {String|undefined} method_name 方法名称 + * 用于获取指定key的简单调用器 + * @param {String} key_name 键名 + * @param {String} value_name 键值 + * @param {Function} method_caller 方法调用器 * @returns {{(info: Object) => Promise}} 调用器 * @group Caller Methods */ - /*@__PURE__*/[get_simple_caller_of_event](event_name, method_name = default_sstp_method) { - return this.#warp_the_caller_of_event( - event_name, - method_name, + /*@__PURE__*/get_simple_caller_of_key(key_name, value_name, method_caller = this.get_caller_of_method(default_sstp_method)) { + return this.get_caller_of_key(key_name, value_name, method_caller, (...args) => { - let reference_num = 0; - let info = {}; - args[forEach]((arg) => + let reference_num = 0 + let info = {} + args.forEach((arg) => info[`Reference${reference_num++}`] = arg - ); - return this[get_caller_of_event](event_name, method_name)(info); - }, - get_simple_caller_of_event + ) + return info + } ); } /** @@ -310,8 +275,20 @@ class jsstp_t { * @group Indexer Members */ /*@__PURE__*/get event() { - return new the_proxy({}, { - get: (_target, prop) => this[get_simple_caller_of_event](prop) + return new Proxy({}, { + get: (_target, prop) => this.get_simple_caller_of_key("Event", prop) + }); + } + /** + * 用于获取指定命令的执行器的代理 + * @returns {Proxy} + * @example + * jsstp.command.GetFMO(); + * @group Indexer Members + */ + /*@__PURE__*/get command() { + return new Proxy({}, { + get: (_target, prop) => this.get_simple_caller_of_key("Command", prop, this.get_caller_of_method("EXECUTE")) }); } /** @@ -343,8 +320,8 @@ class jsstp_t { * SHIORI_EV.On_Has_Event * } */ - /*@__PURE__*/[has_event](event_name, security_level = this[default_security_level]) { - return this.event[Has_Event](event_name, security_level)[then](({ Result }) => Result == 1); + /*@__PURE__*/has_event(event_name, security_level = this.default_security_level) { + return this.event.Has_Event(event_name, security_level).then(({ Result }) => Result == 1); } /** * 以约定好的结构获取支持的事件,需要ghost支持`Get_Supported_Events`事件 @@ -388,11 +365,11 @@ class jsstp_t { * SHIORI_EV.On_Get_Supported_Events * } */ - /*@__PURE__*/[get_supported_events]() { - return this.event[Get_Supported_Events]()[then](({ [local]:local_evt, [external]:external_evt }) => ( + /*@__PURE__*/get_supported_events() { + return this.event.Get_Supported_Events().then(({ local:local_evt, external:external_evt }) => ( { - [local]: (local_evt || void_string)[split](","), - [external]: (external_evt || void_string)[split](",") + local: (local_evt || void_string).split(","), + external: (external_evt || void_string).split(",") } )); } @@ -404,12 +381,8 @@ class jsstp_t { * if(fmo.available) * console.log(fmo); */ - /*@__PURE__*/[get_fmo_infos]() { - return this[proxy].EXECUTE.get_raw({ - Command: "GetFMO" - })[then]( - fmo_text => new fmo_info_t(fmo_text) - ); + /*@__PURE__*/get_fmo_infos() { + return this.proxy.GetFMO.with_type(fmo_info_t)() } /** * 获取当前ghost是否可用 @@ -420,8 +393,8 @@ class jsstp_t { * else * console.error("ghost不可用,请检查ghost是否启动"); */ - /*@__PURE__*/[available]() { - return this[get_fmo_infos]()[then](fmo => fmo[available],/*catch*/() => _false_); + /*@__PURE__*/available() { + return this.get_fmo_infos().then(fmo => fmo.available,/*catch*/_ => _false_); } /** * 获取当前ghost是否可用 @@ -439,8 +412,8 @@ class jsstp_t { */ /*@__PURE__*/if_available(resolve) { //available不会有任何异常风险,所以我们不需要catch - return this[available]()[then](result => - result ? resolve?.(this[proxy]) : throw_error() + return this.available().then(result => + result ? resolve?.(this.proxy) : throw_error() ); } /** @@ -470,10 +443,11 @@ class jsstp_t { } //对定义中的所有类型补充到原型 //纯为了压缩体积(不然每个类型都要写一遍`static`) -assign(jsstp_t[prototype], { +assign(jsstp_t.prototype, { type: jsstp_t, base_sstp_info_t: base_sstp_info_t, sstp_info_t: sstp_info_t, + list_info_t: list_info_t, fmo_info_t: fmo_info_t, ghost_events_queryer_t: ghost_events_queryer_t }); diff --git a/src/types/list_info_t.mjs b/src/types/list_info_t.mjs new file mode 100644 index 0000000..c483dbb --- /dev/null +++ b/src/types/list_info_t.mjs @@ -0,0 +1,63 @@ +import { + //assign, + endline, + //undefined, + + void_string +} from "../base/value_table.mjs"; +import {base_sstp_info_t,split_sstp_text} from "./base_sstp_info_t.mjs"; + +/** + * list报文对象 + * @example + * let list = jsstp.GetNames(); + * for(let name of list) + * console.log(name); + * @alias jsstp.list_info_t + */ +class list_info_t extends base_sstp_info_t { + /** + * 自字符串构造list_info_t + * @param {String} list_text + * @ignore + */ + /*@__PURE__*/constructor(list_text) { + let [head, _, ...lines] = split_sstp_text(list_text); + super(head, lines); + } + /*@__PURE__*/toString() { return this.length == 1 ? this[0] : to_string(this.values); } + /** + * 获取字符串报文 + * @returns {String} 字符串报文 + * @ignore + */ + /*@__PURE__*/TextContent() { + return [ + this.head, + void_string, + ...this.values, + void_string,void_string + ].join(endline); + } + /** + * 获取用于`JSON.stringify`的对象 + * @returns {Object} 用于`JSON.stringify`的对象 + * @ignore + */ + /*@__PURE__*/toJSON() { + return { + head: this.head, + data: this.values + }; + } + //可迭代 + /** + * 获取迭代器 + * @returns {Iterator>} 迭代器 + */ + /*@__PURE__*/[Symbol.iterator]() { + return this.values[Symbol.iterator]() + } +} + +export default list_info_t; diff --git a/src/types/smart_array_object.mjs b/src/types/smart_array_object.mjs deleted file mode 100644 index 201dea1..0000000 --- a/src/types/smart_array_object.mjs +++ /dev/null @@ -1,44 +0,0 @@ -import { throw_error } from "../base/tools.mjs"; -import { - //assign, - //endline, - undefined, - - //void_string, - - the_proxy, - the_object, - then, -} from "../base/value_table.mjs"; -import new_object, { info_object } from "./info_object.mjs"; - -class smart_array_object extends info_object { - static #build_new_with_result_base(result_base, default_value){ - //若每个值都是undefined,则返回target[key] - if(result_base.every(([_key,value])=>value===undefined)) - return default_value; - return new smart_array_object(the_object.fromEntries(result_base)); - } - - constructor(base_value) { - let value_base = new_object(base_value); - return new the_proxy(throw_error, { - get: (_target, key) => { - if(key === then) - return; - //对于每个在数组中的值,以key为索引,构建一个新的smart_array - return smart_array_object.#build_new_with_result_base(value_base.map((value,the_key) => [the_key,value?.[key]]), value_base[key]); - }, - apply: (_target, _thisArg, argumentsList) => { - //对于每个在数组中的值,以key为索引,以argumentsList为参数,用调用结果构建一个新的smart_array - return smart_array_object.#build_new_with_result_base(value_base.map((value,the_key) => [the_key,value(...argumentsList)])); - }, - set: (_target, key, value) => { - value_base[key] = value; - return true; - } - }); - } -} - -export default smart_array_object; diff --git a/src/types/sstp_info_t.mjs b/src/types/sstp_info_t.mjs index 8c5d653..ee364c0 100644 --- a/src/types/sstp_info_t.mjs +++ b/src/types/sstp_info_t.mjs @@ -1,23 +1,14 @@ import { - the_object, - //assign, endline, undefined, - - get_passthrough, - - length, - split, - prototype, - from_string, } from "../base/value_table.mjs"; import { key_value_split, new_getter_proxy, reg_test, } from "../base/tools.mjs"; -import base_sstp_info_t from "./base_sstp_info_t.mjs"; +import {base_sstp_info_t,split_sstp_text} from "./base_sstp_info_t.mjs"; import new_object from "./info_object.mjs"; //定义sstp报文类 @@ -40,23 +31,6 @@ Option: notranslate * @alias jsstp.sstp_info_t */ class sstp_info_t extends base_sstp_info_t { - /** - * 自拆分好的字符串报文或对象报文构造sstp_info_t,不建议直接使用 - * @param {String} info_head 报文头 - * @param {Object} info_body 对象格式的报文体 - * @param {Array|undefined} unknown_lines 未知行的数组 - * @see {@link sstp_info_t.from_string} - * @ignore - */ - /*@__PURE__*/constructor(info_head, info_body, unknown_lines = {}) { - super(info_head, info_body, unknown_lines); - return new_getter_proxy(this, { - _string_key_handler_: (target, key) => - x_sstp_passthru_head + key in target && !the_object.getOwnPropertyNames(sstp_info_t[prototype]).includes(key)? - target[get_passthrough](key) : - undefined - }); - } /** * 从字符串构造sstp_info_t * @param {String} str 字符串报文 @@ -64,13 +38,11 @@ class sstp_info_t extends base_sstp_info_t { * @example * let info = sstp_info_t.from_string("SSTP/1.4 200 OK\r\nCharset: UTF-8\r\nSender: SSTPクライアント\r\nScript: \\h\\s0テストー。\\u\\s[10]テストやな。\r\nOption: notranslate\r\n\r\n"); */ - /*@__PURE__*/static [from_string](str) { - let [head, ...lines] = str[split](endline); + /*@__PURE__*/constructor(str) { + let [head, ...lines] = split_sstp_text(str); let body = {}; let unknown_lines = []; let last_key; - //去掉最后的空行*2 - lines[length] -= 2; for (let line of lines) { let [key, value] = key_value_split(line, ': '); if (!/*@__INLINE__*/reg_test(/^\w[^\s]*$/, key)) { @@ -82,14 +54,20 @@ class sstp_info_t extends base_sstp_info_t { else body[last_key = key] = value; } - return new sstp_info_t(head, body, unknown_lines); + super(head, body, unknown_lines); + return new_getter_proxy(this, { + _string_key_handler_: (target, key) => + x_sstp_passthru_head + key in target && !Object.getOwnPropertyNames(sstp_info_t.prototype).includes(key)? + target.get_passthrough(key) : + undefined + }); } /** * 获取PassThru的值 * @param {String} key 获取的PassThru名称 * @returns {String|undefined} PassThru的值 */ - /*@__PURE__*/[get_passthrough](key) { return this[x_sstp_passthru_head + key]; } + /*@__PURE__*/get_passthrough(key) { return this[x_sstp_passthru_head + key]; } /** * 用于缓存所有的PassThru * @type {info_object} @@ -103,7 +81,7 @@ class sstp_info_t extends base_sstp_info_t { /*@__PURE__*/get passthroughs() { return this.#passthroughs ??= new_object().push( this.map((value, key) => key.startsWith(x_sstp_passthru_head) ? - [key.slice(x_sstp_passthru_head[length]), value] : undefined + [key.slice(x_sstp_passthru_head.length), value] : undefined ) ); }