diff --git a/README.md b/README.md index 06385fc..5270dd2 100644 --- a/README.md +++ b/README.md @@ -16,30 +16,48 @@ Also, extremely easy even when composing complicated network system like grid co ```typescript import { Driver, WebSocketConnector } from "tgrid"; -import { ICalculator } from "./interfaces/ICalculator"; -import { CalcEventListener } from "./providers/CalcEventListener"; - -export const main = async (): Promise => { - // CONNECT TO WEBSOCKET SERVER +import { ICalcConfig } from "../interfaces/ICalcConfig"; +import { ICalcEvent } from "../interfaces/ICalcEvent"; +import { ICalcEventListener } from "../interfaces/ICalcEventListener"; +import { ICompositeCalculator } from "../interfaces/ICompositeCalculator"; + +export const webSocketClientMain = async () => { + const stack: ICalcEvent[] = []; + const listener: ICalcEventListener = { + on: (evt: ICalcEvent) => stack.push(evt), + }; const connector: WebSocketConnector< - null, // header - CalcEventListener, // provider for remote server - ICalculator, // provider from remote server - > = new WebSocketConnector(null, new CalcEventListener()); - await connector.connect("ws://127.0.0.1:443/calculator"); - - // RPC (YOU CAN CALL REMOTE PROCEDURES) - const calc: Driver = connector.getDriver(); - console.log( - await calc.plus(2, 3), - await calc.minus(7, 1), - await calc.multiplies(3, 4), - await calc.divides(9, 3), + ICalcConfig, + ICalcEventListener, + ICompositeCalculator + > = new WebSocketConnector( + { precision: 2 }, // header + listener, // provider for remote server ); + await connector.connect("ws://127.0.0.1:37000/composite"); + + const remote: Driver = connector.getDriver(); + await remote.plus(10, 20); // returns 30 + await remote.multiplies(3, 4); // returns 12 + await remote.divides(5, 3); // returns 1.67 + await remote.scientific.sqrt(2); // returns 1.41 + await remote.statistics.mean(1, 3, 9); // returns 4.33 + await connector.close(); + console.log(...stack); }; ``` +> Execution result: +> +> ```bash +> { type: 'plus', input: [ 10, 20 ], output: 30 } +> { type: 'multiplies', input: [ 3, 4 ], output: 12 } +> { type: 'divides', input: [ 5, 3 ], output: 1.67 } +> { type: 'sqrt', input: [ 2 ], output: 1.41 } +> { type: 'mean', input: [ 1, 3, 9 ], output: 4.33 } +> ``` + @@ -50,7 +68,7 @@ npm install tgrid Just install with `npm` command. That's all. -If you wanna `tgrid` in `NestJS`, read `nestia` guide documents. +If you wanna use `tgrid` in `NestJS`, read `nestia` guide documents. - [Nestia > Guide Documents > Setup](https://nestia.io/docs/setup/) - [Nestia > Guide Documents > WebSocketRoute](https://nestia.io/docs/core/WebSocketRoute/) diff --git a/examples/docs/.nojekyll b/examples/docs/.nojekyll new file mode 100644 index 0000000..e2ac661 --- /dev/null +++ b/examples/docs/.nojekyll @@ -0,0 +1 @@ +TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/examples/docs/assets/highlight.css b/examples/docs/assets/highlight.css new file mode 100644 index 0000000..46ece49 --- /dev/null +++ b/examples/docs/assets/highlight.css @@ -0,0 +1,92 @@ +:root { + --light-hl-0: #AF00DB; + --dark-hl-0: #C586C0; + --light-hl-1: #000000; + --dark-hl-1: #D4D4D4; + --light-hl-2: #001080; + --dark-hl-2: #9CDCFE; + --light-hl-3: #A31515; + --dark-hl-3: #CE9178; + --light-hl-4: #0000FF; + --dark-hl-4: #569CD6; + --light-hl-5: #795E26; + --dark-hl-5: #DCDCAA; + --light-hl-6: #0070C1; + --dark-hl-6: #4FC1FF; + --light-hl-7: #267F99; + --dark-hl-7: #4EC9B0; + --light-hl-8: #098658; + --dark-hl-8: #B5CEA8; + --light-hl-9: #008000; + --dark-hl-9: #6A9955; + --light-code-background: #FFFFFF; + --dark-code-background: #1E1E1E; +} + +@media (prefers-color-scheme: light) { :root { + --hl-0: var(--light-hl-0); + --hl-1: var(--light-hl-1); + --hl-2: var(--light-hl-2); + --hl-3: var(--light-hl-3); + --hl-4: var(--light-hl-4); + --hl-5: var(--light-hl-5); + --hl-6: var(--light-hl-6); + --hl-7: var(--light-hl-7); + --hl-8: var(--light-hl-8); + --hl-9: var(--light-hl-9); + --code-background: var(--light-code-background); +} } + +@media (prefers-color-scheme: dark) { :root { + --hl-0: var(--dark-hl-0); + --hl-1: var(--dark-hl-1); + --hl-2: var(--dark-hl-2); + --hl-3: var(--dark-hl-3); + --hl-4: var(--dark-hl-4); + --hl-5: var(--dark-hl-5); + --hl-6: var(--dark-hl-6); + --hl-7: var(--dark-hl-7); + --hl-8: var(--dark-hl-8); + --hl-9: var(--dark-hl-9); + --code-background: var(--dark-code-background); +} } + +:root[data-theme='light'] { + --hl-0: var(--light-hl-0); + --hl-1: var(--light-hl-1); + --hl-2: var(--light-hl-2); + --hl-3: var(--light-hl-3); + --hl-4: var(--light-hl-4); + --hl-5: var(--light-hl-5); + --hl-6: var(--light-hl-6); + --hl-7: var(--light-hl-7); + --hl-8: var(--light-hl-8); + --hl-9: var(--light-hl-9); + --code-background: var(--light-code-background); +} + +:root[data-theme='dark'] { + --hl-0: var(--dark-hl-0); + --hl-1: var(--dark-hl-1); + --hl-2: var(--dark-hl-2); + --hl-3: var(--dark-hl-3); + --hl-4: var(--dark-hl-4); + --hl-5: var(--dark-hl-5); + --hl-6: var(--dark-hl-6); + --hl-7: var(--dark-hl-7); + --hl-8: var(--dark-hl-8); + --hl-9: var(--dark-hl-9); + --code-background: var(--dark-code-background); +} + +.hl-0 { color: var(--hl-0); } +.hl-1 { color: var(--hl-1); } +.hl-2 { color: var(--hl-2); } +.hl-3 { color: var(--hl-3); } +.hl-4 { color: var(--hl-4); } +.hl-5 { color: var(--hl-5); } +.hl-6 { color: var(--hl-6); } +.hl-7 { color: var(--hl-7); } +.hl-8 { color: var(--hl-8); } +.hl-9 { color: var(--hl-9); } +pre, code { background: var(--code-background); } diff --git a/examples/docs/assets/icons.js b/examples/docs/assets/icons.js new file mode 100644 index 0000000..b79c9e8 --- /dev/null +++ b/examples/docs/assets/icons.js @@ -0,0 +1,15 @@ +(function(svg) { + svg.innerHTML = ``; + svg.style.display = 'none'; + if (location.protocol === 'file:') { + if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', updateUseElements); + else updateUseElements() + function updateUseElements() { + document.querySelectorAll('use').forEach(el => { + if (el.getAttribute('href').includes('#icon-')) { + el.setAttribute('href', el.getAttribute('href').replace(/.*#/, '#')); + } + }); + } + } +})(document.body.appendChild(document.createElementNS('http://www.w3.org/2000/svg', 'svg'))) \ No newline at end of file diff --git a/examples/docs/assets/icons.svg b/examples/docs/assets/icons.svg new file mode 100644 index 0000000..7dead61 --- /dev/null +++ b/examples/docs/assets/icons.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/docs/assets/main.js b/examples/docs/assets/main.js new file mode 100644 index 0000000..1daeb69 --- /dev/null +++ b/examples/docs/assets/main.js @@ -0,0 +1,59 @@ +"use strict"; +"use strict";(()=>{var Ce=Object.create;var ne=Object.defineProperty;var Pe=Object.getOwnPropertyDescriptor;var Oe=Object.getOwnPropertyNames;var _e=Object.getPrototypeOf,Re=Object.prototype.hasOwnProperty;var Me=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var Fe=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Oe(e))!Re.call(t,i)&&i!==n&&ne(t,i,{get:()=>e[i],enumerable:!(r=Pe(e,i))||r.enumerable});return t};var De=(t,e,n)=>(n=t!=null?Ce(_e(t)):{},Fe(e||!t||!t.__esModule?ne(n,"default",{value:t,enumerable:!0}):n,t));var ae=Me((se,oe)=>{(function(){var t=function(e){var n=new t.Builder;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),n.searchPipeline.add(t.stemmer),e.call(n,n),n.build()};t.version="2.3.9";t.utils={},t.utils.warn=function(e){return function(n){e.console&&console.warn&&console.warn(n)}}(this),t.utils.asString=function(e){return e==null?"":e.toString()},t.utils.clone=function(e){if(e==null)return e;for(var n=Object.create(null),r=Object.keys(e),i=0;i0){var d=t.utils.clone(n)||{};d.position=[a,u],d.index=s.length,s.push(new t.Token(r.slice(a,o),d))}a=o+1}}return s},t.tokenizer.separator=/[\s\-]+/;t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions=Object.create(null),t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. +`,e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(r){var i=t.Pipeline.registeredFunctions[r];if(i)n.add(i);else throw new Error("Cannot load unregistered function: "+r)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(n){t.Pipeline.warnIfFunctionNotRegistered(n),this._stack.push(n)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var r=this._stack.indexOf(e);if(r==-1)throw new Error("Cannot find existingFn");r=r+1,this._stack.splice(r,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var r=this._stack.indexOf(e);if(r==-1)throw new Error("Cannot find existingFn");this._stack.splice(r,0,n)},t.Pipeline.prototype.remove=function(e){var n=this._stack.indexOf(e);n!=-1&&this._stack.splice(n,1)},t.Pipeline.prototype.run=function(e){for(var n=this._stack.length,r=0;r1&&(oe&&(r=s),o!=e);)i=r-n,s=n+Math.floor(i/2),o=this.elements[s*2];if(o==e||o>e)return s*2;if(ol?d+=2:a==l&&(n+=r[u+1]*i[d+1],u+=2,d+=2);return n},t.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},t.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),n=1,r=0;n0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new t.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),i.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var l=s.node.edges["*"];else{var l=new t.TokenSet;s.node.edges["*"]=l}if(s.str.length==0&&(l.final=!0),i.push({node:l,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&i.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),s.str.length==1&&(s.node.final=!0),s.str.length>=1){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new t.TokenSet;s.node.edges["*"]=u}s.str.length==1&&(u.final=!0),i.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var d=s.str.charAt(0),y=s.str.charAt(1),p;y in s.node.edges?p=s.node.edges[y]:(p=new t.TokenSet,s.node.edges[y]=p),s.str.length==1&&(p.final=!0),i.push({node:p,editsRemaining:s.editsRemaining-1,str:d+s.str.slice(2)})}}}return r},t.TokenSet.fromString=function(e){for(var n=new t.TokenSet,r=n,i=0,s=e.length;i=e;n--){var r=this.uncheckedNodes[n],i=r.child.toString();i in this.minimizedNodes?r.parent.edges[r.char]=this.minimizedNodes[i]:(r.child._str=i,this.minimizedNodes[i]=r.child),this.uncheckedNodes.pop()}};t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(n){var r=new t.QueryParser(e,n);r.parse()})},t.Index.prototype.query=function(e){for(var n=new t.Query(this.fields),r=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),l=0;l1?this._b=1:this._b=e},t.Builder.prototype.k1=function(e){this._k1=e},t.Builder.prototype.add=function(e,n){var r=e[this._ref],i=Object.keys(this._fields);this._documents[r]=n||{},this.documentCount+=1;for(var s=0;s=this.length)return t.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},t.QueryLexer.prototype.width=function(){return this.pos-this.start},t.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},t.QueryLexer.prototype.backup=function(){this.pos-=1},t.QueryLexer.prototype.acceptDigitRun=function(){var e,n;do e=this.next(),n=e.charCodeAt(0);while(n>47&&n<58);e!=t.QueryLexer.EOS&&this.backup()},t.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(t.QueryLexer.TERM)),e.ignore(),e.more())return t.QueryLexer.lexText},t.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.EDIT_DISTANCE),t.QueryLexer.lexText},t.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.BOOST),t.QueryLexer.lexText},t.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(t.QueryLexer.TERM)},t.QueryLexer.termSeparator=t.tokenizer.separator,t.QueryLexer.lexText=function(e){for(;;){var n=e.next();if(n==t.QueryLexer.EOS)return t.QueryLexer.lexEOS;if(n.charCodeAt(0)==92){e.escapeCharacter();continue}if(n==":")return t.QueryLexer.lexField;if(n=="~")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexEditDistance;if(n=="^")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexBoost;if(n=="+"&&e.width()===1||n=="-"&&e.width()===1)return e.emit(t.QueryLexer.PRESENCE),t.QueryLexer.lexText;if(n.match(t.QueryLexer.termSeparator))return t.QueryLexer.lexTerm}},t.QueryParser=function(e,n){this.lexer=new t.QueryLexer(e),this.query=n,this.currentClause={},this.lexemeIdx=0},t.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=t.QueryParser.parseClause;e;)e=e(this);return this.query},t.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},t.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},t.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},t.QueryParser.parseClause=function(e){var n=e.peekLexeme();if(n!=null)switch(n.type){case t.QueryLexer.PRESENCE:return t.QueryParser.parsePresence;case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var r="expected either a field or a term, found "+n.type;throw n.str.length>=1&&(r+=" with value '"+n.str+"'"),new t.QueryParseError(r,n.start,n.end)}},t.QueryParser.parsePresence=function(e){var n=e.consumeLexeme();if(n!=null){switch(n.str){case"-":e.currentClause.presence=t.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=t.Query.presence.REQUIRED;break;default:var r="unrecognised presence operator'"+n.str+"'";throw new t.QueryParseError(r,n.start,n.end)}var i=e.peekLexeme();if(i==null){var r="expecting term or field, found nothing";throw new t.QueryParseError(r,n.start,n.end)}switch(i.type){case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var r="expecting term or field, found '"+i.type+"'";throw new t.QueryParseError(r,i.start,i.end)}}},t.QueryParser.parseField=function(e){var n=e.consumeLexeme();if(n!=null){if(e.query.allFields.indexOf(n.str)==-1){var r=e.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),i="unrecognised field '"+n.str+"', possible fields: "+r;throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.fields=[n.str];var s=e.peekLexeme();if(s==null){var i="expecting term, found nothing";throw new t.QueryParseError(i,n.start,n.end)}switch(s.type){case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var i="expecting term, found '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseTerm=function(e){var n=e.consumeLexeme();if(n!=null){e.currentClause.term=n.str.toLowerCase(),n.str.indexOf("*")!=-1&&(e.currentClause.usePipeline=!1);var r=e.peekLexeme();if(r==null){e.nextClause();return}switch(r.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+r.type+"'";throw new t.QueryParseError(i,r.start,r.end)}}},t.QueryParser.parseEditDistance=function(e){var n=e.consumeLexeme();if(n!=null){var r=parseInt(n.str,10);if(isNaN(r)){var i="edit distance must be numeric";throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.editDistance=r;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseBoost=function(e){var n=e.consumeLexeme();if(n!=null){var r=parseInt(n.str,10);if(isNaN(r)){var i="boost must be numeric";throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.boost=r;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},function(e,n){typeof define=="function"&&define.amd?define(n):typeof se=="object"?oe.exports=n():e.lunr=n()}(this,function(){return t})})()});var re=[];function G(t,e){re.push({selector:e,constructor:t})}var U=class{constructor(){this.alwaysVisibleMember=null;this.createComponents(document.body),this.ensureFocusedElementVisible(),this.listenForCodeCopies(),window.addEventListener("hashchange",()=>this.ensureFocusedElementVisible()),document.body.style.display||(this.scrollToHash(),this.updateIndexVisibility())}createComponents(e){re.forEach(n=>{e.querySelectorAll(n.selector).forEach(r=>{r.dataset.hasInstance||(new n.constructor({el:r,app:this}),r.dataset.hasInstance=String(!0))})})}filterChanged(){this.ensureFocusedElementVisible()}showPage(){document.body.style.display&&(document.body.style.removeProperty("display"),this.scrollToHash(),this.updateIndexVisibility())}scrollToHash(){if(location.hash){let e=document.getElementById(location.hash.substring(1));if(!e)return;e.scrollIntoView({behavior:"instant",block:"start"})}}ensureActivePageVisible(){let e=document.querySelector(".tsd-navigation .current"),n=e?.parentElement;for(;n&&!n.classList.contains(".tsd-navigation");)n instanceof HTMLDetailsElement&&(n.open=!0),n=n.parentElement;if(e&&!e.checkVisibility()){let r=e.getBoundingClientRect().top-document.documentElement.clientHeight/4;document.querySelector(".site-menu").scrollTop=r}}updateIndexVisibility(){let e=document.querySelector(".tsd-index-content"),n=e?.open;e&&(e.open=!0),document.querySelectorAll(".tsd-index-section").forEach(r=>{r.style.display="block";let i=Array.from(r.querySelectorAll(".tsd-index-link")).every(s=>s.offsetParent==null);r.style.display=i?"none":"block"}),e&&(e.open=n)}ensureFocusedElementVisible(){if(this.alwaysVisibleMember&&(this.alwaysVisibleMember.classList.remove("always-visible"),this.alwaysVisibleMember.firstElementChild.remove(),this.alwaysVisibleMember=null),!location.hash)return;let e=document.getElementById(location.hash.substring(1));if(!e)return;let n=e.parentElement;for(;n&&n.tagName!=="SECTION";)n=n.parentElement;if(n&&n.offsetParent==null){this.alwaysVisibleMember=n,n.classList.add("always-visible");let r=document.createElement("p");r.classList.add("warning"),r.textContent="This member is normally hidden due to your filter settings.",n.prepend(r)}}listenForCodeCopies(){document.querySelectorAll("pre > button").forEach(e=>{let n;e.addEventListener("click",()=>{e.previousElementSibling instanceof HTMLElement&&navigator.clipboard.writeText(e.previousElementSibling.innerText.trim()),e.textContent="Copied!",e.classList.add("visible"),clearTimeout(n),n=setTimeout(()=>{e.classList.remove("visible"),n=setTimeout(()=>{e.textContent="Copy"},100)},1e3)})})}};var ie=(t,e=100)=>{let n;return()=>{clearTimeout(n),n=setTimeout(()=>t(),e)}};var de=De(ae());async function le(t,e){if(!window.searchData)return;let n=await fetch(window.searchData),r=new Blob([await n.arrayBuffer()]).stream().pipeThrough(new DecompressionStream("gzip")),i=await new Response(r).json();t.data=i,t.index=de.Index.load(i.index),e.classList.remove("loading"),e.classList.add("ready")}function he(){let t=document.getElementById("tsd-search");if(!t)return;let e={base:t.dataset.base+"/"},n=document.getElementById("tsd-search-script");t.classList.add("loading"),n&&(n.addEventListener("error",()=>{t.classList.remove("loading"),t.classList.add("failure")}),n.addEventListener("load",()=>{le(e,t)}),le(e,t));let r=document.querySelector("#tsd-search input"),i=document.querySelector("#tsd-search .results");if(!r||!i)throw new Error("The input field or the result list wrapper was not found");let s=!1;i.addEventListener("mousedown",()=>s=!0),i.addEventListener("mouseup",()=>{s=!1,t.classList.remove("has-focus")}),r.addEventListener("focus",()=>t.classList.add("has-focus")),r.addEventListener("blur",()=>{s||(s=!1,t.classList.remove("has-focus"))}),Ae(t,i,r,e)}function Ae(t,e,n,r){n.addEventListener("input",ie(()=>{Ne(t,e,n,r)},200));let i=!1;n.addEventListener("keydown",s=>{i=!0,s.key=="Enter"?Ve(e,n):s.key=="Escape"?n.blur():s.key=="ArrowUp"?ue(e,-1):s.key==="ArrowDown"?ue(e,1):i=!1}),n.addEventListener("keypress",s=>{i&&s.preventDefault()}),document.body.addEventListener("keydown",s=>{s.altKey||s.ctrlKey||s.metaKey||!n.matches(":focus")&&s.key==="/"&&(n.focus(),s.preventDefault())})}function Ne(t,e,n,r){if(!r.index||!r.data)return;e.textContent="";let i=n.value.trim(),s;if(i){let o=i.split(" ").map(a=>a.length?`*${a}*`:"").join(" ");s=r.index.search(o)}else s=[];for(let o=0;oa.score-o.score);for(let o=0,a=Math.min(10,s.length);o`,d=ce(l.name,i);globalThis.DEBUG_SEARCH_WEIGHTS&&(d+=` (score: ${s[o].score.toFixed(2)})`),l.parent&&(d=` + ${ce(l.parent,i)}.${d}`);let y=document.createElement("li");y.classList.value=l.classes??"";let p=document.createElement("a");p.href=r.base+l.url,p.innerHTML=u+d,y.append(p),e.appendChild(y)}}function ue(t,e){let n=t.querySelector(".current");if(!n)n=t.querySelector(e==1?"li:first-child":"li:last-child"),n&&n.classList.add("current");else{let r=n;if(e===1)do r=r.nextElementSibling??void 0;while(r instanceof HTMLElement&&r.offsetParent==null);else do r=r.previousElementSibling??void 0;while(r instanceof HTMLElement&&r.offsetParent==null);r&&(n.classList.remove("current"),r.classList.add("current"))}}function Ve(t,e){let n=t.querySelector(".current");if(n||(n=t.querySelector("li:first-child")),n){let r=n.querySelector("a");r&&(window.location.href=r.href),e.blur()}}function ce(t,e){if(e==="")return t;let n=t.toLocaleLowerCase(),r=e.toLocaleLowerCase(),i=[],s=0,o=n.indexOf(r);for(;o!=-1;)i.push(K(t.substring(s,o)),`${K(t.substring(o,o+r.length))}`),s=o+r.length,o=n.indexOf(r,s);return i.push(K(t.substring(s))),i.join("")}var He={"&":"&","<":"<",">":">","'":"'",'"':"""};function K(t){return t.replace(/[&<>"'"]/g,e=>He[e])}var I=class{constructor(e){this.el=e.el,this.app=e.app}};var F="mousedown",fe="mousemove",H="mouseup",J={x:0,y:0},pe=!1,ee=!1,Be=!1,D=!1,me=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);document.documentElement.classList.add(me?"is-mobile":"not-mobile");me&&"ontouchstart"in document.documentElement&&(Be=!0,F="touchstart",fe="touchmove",H="touchend");document.addEventListener(F,t=>{ee=!0,D=!1;let e=F=="touchstart"?t.targetTouches[0]:t;J.y=e.pageY||0,J.x=e.pageX||0});document.addEventListener(fe,t=>{if(ee&&!D){let e=F=="touchstart"?t.targetTouches[0]:t,n=J.x-(e.pageX||0),r=J.y-(e.pageY||0);D=Math.sqrt(n*n+r*r)>10}});document.addEventListener(H,()=>{ee=!1});document.addEventListener("click",t=>{pe&&(t.preventDefault(),t.stopImmediatePropagation(),pe=!1)});var X=class extends I{constructor(e){super(e),this.className=this.el.dataset.toggle||"",this.el.addEventListener(H,n=>this.onPointerUp(n)),this.el.addEventListener("click",n=>n.preventDefault()),document.addEventListener(F,n=>this.onDocumentPointerDown(n)),document.addEventListener(H,n=>this.onDocumentPointerUp(n))}setActive(e){if(this.active==e)return;this.active=e,document.documentElement.classList.toggle("has-"+this.className,e),this.el.classList.toggle("active",e);let n=(this.active?"to-has-":"from-has-")+this.className;document.documentElement.classList.add(n),setTimeout(()=>document.documentElement.classList.remove(n),500)}onPointerUp(e){D||(this.setActive(!0),e.preventDefault())}onDocumentPointerDown(e){if(this.active){if(e.target.closest(".col-sidebar, .tsd-filter-group"))return;this.setActive(!1)}}onDocumentPointerUp(e){if(!D&&this.active&&e.target.closest(".col-sidebar")){let n=e.target.closest("a");if(n){let r=window.location.href;r.indexOf("#")!=-1&&(r=r.substring(0,r.indexOf("#"))),n.href.substring(0,r.length)==r&&setTimeout(()=>this.setActive(!1),250)}}}};var te;try{te=localStorage}catch{te={getItem(){return null},setItem(){}}}var Q=te;var ye=document.head.appendChild(document.createElement("style"));ye.dataset.for="filters";var Y=class extends I{constructor(e){super(e),this.key=`filter-${this.el.name}`,this.value=this.el.checked,this.el.addEventListener("change",()=>{this.setLocalStorage(this.el.checked)}),this.setLocalStorage(this.fromLocalStorage()),ye.innerHTML+=`html:not(.${this.key}) .tsd-is-${this.el.name} { display: none; } +`,this.app.updateIndexVisibility()}fromLocalStorage(){let e=Q.getItem(this.key);return e?e==="true":this.el.checked}setLocalStorage(e){Q.setItem(this.key,e.toString()),this.value=e,this.handleValueChange()}handleValueChange(){this.el.checked=this.value,document.documentElement.classList.toggle(this.key,this.value),this.app.filterChanged(),this.app.updateIndexVisibility()}};var Z=class extends I{constructor(e){super(e),this.summary=this.el.querySelector(".tsd-accordion-summary"),this.icon=this.summary.querySelector("svg"),this.key=`tsd-accordion-${this.summary.dataset.key??this.summary.textContent.trim().replace(/\s+/g,"-").toLowerCase()}`;let n=Q.getItem(this.key);this.el.open=n?n==="true":this.el.open,this.el.addEventListener("toggle",()=>this.update());let r=this.summary.querySelector("a");r&&r.addEventListener("click",()=>{location.assign(r.href)}),this.update()}update(){this.icon.style.transform=`rotate(${this.el.open?0:-90}deg)`,Q.setItem(this.key,this.el.open.toString())}};function ge(t){let e=Q.getItem("tsd-theme")||"os";t.value=e,ve(e),t.addEventListener("change",()=>{Q.setItem("tsd-theme",t.value),ve(t.value)})}function ve(t){document.documentElement.dataset.theme=t}var Le;function be(){let t=document.getElementById("tsd-nav-script");t&&(t.addEventListener("load",xe),xe())}async function xe(){let t=document.getElementById("tsd-nav-container");if(!t||!window.navigationData)return;let n=await(await fetch(window.navigationData)).arrayBuffer(),r=new Blob([n]).stream().pipeThrough(new DecompressionStream("gzip")),i=await new Response(r).json();Le=t.dataset.base+"/",t.innerHTML="";for(let s of i)we(s,t,[]);window.app.createComponents(t),window.app.showPage(),window.app.ensureActivePageVisible()}function we(t,e,n){let r=e.appendChild(document.createElement("li"));if(t.children){let i=[...n,t.text],s=r.appendChild(document.createElement("details"));s.className=t.class?`${t.class} tsd-index-accordion`:"tsd-index-accordion",s.dataset.key=i.join("$");let o=s.appendChild(document.createElement("summary"));o.className="tsd-accordion-summary",o.innerHTML='',Ee(t,o);let a=s.appendChild(document.createElement("div"));a.className="tsd-accordion-details";let l=a.appendChild(document.createElement("ul"));l.className="tsd-nested-navigation";for(let u of t.children)we(u,l,i)}else Ee(t,r,t.class)}function Ee(t,e,n){if(t.path){let r=e.appendChild(document.createElement("a"));r.href=Le+t.path,n&&(r.className=n),location.pathname===r.pathname&&r.classList.add("current"),t.kind&&(r.innerHTML=``),r.appendChild(document.createElement("span")).textContent=t.text}else e.appendChild(document.createElement("span")).textContent=t.text}G(X,"a[data-toggle]");G(Z,".tsd-index-accordion");G(Y,".tsd-filter-item input[type=checkbox]");var Se=document.getElementById("tsd-theme");Se&&ge(Se);var je=new U;Object.defineProperty(window,"app",{value:je});he();be();})(); +/*! Bundled license information: + +lunr/lunr.js: + (** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 + * Copyright (C) 2020 Oliver Nightingale + * @license MIT + *) + (*! + * lunr.utils + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.Set + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.tokenizer + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.Pipeline + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.Vector + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.stemmer + * Copyright (C) 2020 Oliver Nightingale + * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt + *) + (*! + * lunr.stopWordFilter + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.trimmer + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.TokenSet + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.Index + * Copyright (C) 2020 Oliver Nightingale + *) + (*! + * lunr.Builder + * Copyright (C) 2020 Oliver Nightingale + *) +*/ diff --git a/examples/docs/assets/navigation.js b/examples/docs/assets/navigation.js new file mode 100644 index 0000000..e7335e9 --- /dev/null +++ b/examples/docs/assets/navigation.js @@ -0,0 +1 @@ +window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAACouOBQApu0wNAgAAAA==" \ No newline at end of file diff --git a/examples/docs/assets/search.js b/examples/docs/assets/search.js new file mode 100644 index 0000000..e72c08a --- /dev/null +++ b/examples/docs/assets/search.js @@ -0,0 +1 @@ +window.searchData = "data:application/octet-stream;base64,H4sIAAAAAAAACj2MMQqAMBAE/7J1sNDK/MAP2IiFmBUOkovEoIL4dwmK5ewscyHFY4MdRgNRxxP2ws60SVRY1FVTtTBYhN6VG3QKhMEcQ6BmjJ/rOeeY/tDOlOm6N1imVVZ6URa67wdtjdlXdgAAAA=="; \ No newline at end of file diff --git a/examples/docs/assets/style.css b/examples/docs/assets/style.css new file mode 100644 index 0000000..072daed --- /dev/null +++ b/examples/docs/assets/style.css @@ -0,0 +1,1415 @@ +:root { + /* Light */ + --light-color-background: #f2f4f8; + --light-color-background-secondary: #eff0f1; + --light-color-warning-text: #222; + --light-color-background-warning: #e6e600; + --light-color-icon-background: var(--light-color-background); + --light-color-accent: #c5c7c9; + --light-color-active-menu-item: var(--light-color-accent); + --light-color-text: #222; + --light-color-text-aside: #6e6e6e; + --light-color-link: #1f70c2; + + --light-color-ts-keyword: #056bd6; + --light-color-ts-project: #b111c9; + --light-color-ts-module: var(--light-color-ts-project); + --light-color-ts-namespace: var(--light-color-ts-project); + --light-color-ts-enum: #7e6f15; + --light-color-ts-enum-member: var(--light-color-ts-enum); + --light-color-ts-variable: #4760ec; + --light-color-ts-function: #572be7; + --light-color-ts-class: #1f70c2; + --light-color-ts-interface: #108024; + --light-color-ts-constructor: var(--light-color-ts-class); + --light-color-ts-property: var(--light-color-ts-variable); + --light-color-ts-method: var(--light-color-ts-function); + --light-color-ts-call-signature: var(--light-color-ts-method); + --light-color-ts-index-signature: var(--light-color-ts-property); + --light-color-ts-constructor-signature: var(--light-color-ts-constructor); + --light-color-ts-parameter: var(--light-color-ts-variable); + /* type literal not included as links will never be generated to it */ + --light-color-ts-type-parameter: #a55c0e; + --light-color-ts-accessor: var(--light-color-ts-property); + --light-color-ts-get-signature: var(--light-color-ts-accessor); + --light-color-ts-set-signature: var(--light-color-ts-accessor); + --light-color-ts-type-alias: #d51270; + /* reference not included as links will be colored with the kind that it points to */ + + --light-external-icon: url("data:image/svg+xml;utf8,"); + --light-color-scheme: light; + + /* Dark */ + --dark-color-background: #2b2e33; + --dark-color-background-secondary: #1e2024; + --dark-color-background-warning: #bebe00; + --dark-color-warning-text: #222; + --dark-color-icon-background: var(--dark-color-background-secondary); + --dark-color-accent: #9096a2; + --dark-color-active-menu-item: #5d5d6a; + --dark-color-text: #f5f5f5; + --dark-color-text-aside: #dddddd; + --dark-color-link: #00aff4; + + --dark-color-ts-keyword: #3399ff; + --dark-color-ts-project: #e358ff; + --dark-color-ts-module: var(--dark-color-ts-project); + --dark-color-ts-namespace: var(--dark-color-ts-project); + --dark-color-ts-enum: #f4d93e; + --dark-color-ts-enum-member: var(--dark-color-ts-enum); + --dark-color-ts-variable: #798dff; + --dark-color-ts-function: #a280ff; + --dark-color-ts-class: #8ac4ff; + --dark-color-ts-interface: #6cff87; + --dark-color-ts-constructor: var(--dark-color-ts-class); + --dark-color-ts-property: var(--dark-color-ts-variable); + --dark-color-ts-method: var(--dark-color-ts-function); + --dark-color-ts-call-signature: var(--dark-color-ts-method); + --dark-color-ts-index-signature: var(--dark-color-ts-property); + --dark-color-ts-constructor-signature: var(--dark-color-ts-constructor); + --dark-color-ts-parameter: var(--dark-color-ts-variable); + /* type literal not included as links will never be generated to it */ + --dark-color-ts-type-parameter: #e07d13; + --dark-color-ts-accessor: var(--dark-color-ts-property); + --dark-color-ts-get-signature: var(--dark-color-ts-accessor); + --dark-color-ts-set-signature: var(--dark-color-ts-accessor); + --dark-color-ts-type-alias: #ff6492; + /* reference not included as links will be colored with the kind that it points to */ + + --dark-external-icon: url("data:image/svg+xml;utf8,"); + --dark-color-scheme: dark; +} + +@media (prefers-color-scheme: light) { + :root { + --color-background: var(--light-color-background); + --color-background-secondary: var(--light-color-background-secondary); + --color-background-warning: var(--light-color-background-warning); + --color-warning-text: var(--light-color-warning-text); + --color-icon-background: var(--light-color-icon-background); + --color-accent: var(--light-color-accent); + --color-active-menu-item: var(--light-color-active-menu-item); + --color-text: var(--light-color-text); + --color-text-aside: var(--light-color-text-aside); + --color-link: var(--light-color-link); + + --color-ts-keyword: var(--light-color-ts-keyword); + --color-ts-module: var(--light-color-ts-module); + --color-ts-namespace: var(--light-color-ts-namespace); + --color-ts-enum: var(--light-color-ts-enum); + --color-ts-enum-member: var(--light-color-ts-enum-member); + --color-ts-variable: var(--light-color-ts-variable); + --color-ts-function: var(--light-color-ts-function); + --color-ts-class: var(--light-color-ts-class); + --color-ts-interface: var(--light-color-ts-interface); + --color-ts-constructor: var(--light-color-ts-constructor); + --color-ts-property: var(--light-color-ts-property); + --color-ts-method: var(--light-color-ts-method); + --color-ts-call-signature: var(--light-color-ts-call-signature); + --color-ts-index-signature: var(--light-color-ts-index-signature); + --color-ts-constructor-signature: var( + --light-color-ts-constructor-signature + ); + --color-ts-parameter: var(--light-color-ts-parameter); + --color-ts-type-parameter: var(--light-color-ts-type-parameter); + --color-ts-accessor: var(--light-color-ts-accessor); + --color-ts-get-signature: var(--light-color-ts-get-signature); + --color-ts-set-signature: var(--light-color-ts-set-signature); + --color-ts-type-alias: var(--light-color-ts-type-alias); + + --external-icon: var(--light-external-icon); + --color-scheme: var(--light-color-scheme); + } +} + +@media (prefers-color-scheme: dark) { + :root { + --color-background: var(--dark-color-background); + --color-background-secondary: var(--dark-color-background-secondary); + --color-background-warning: var(--dark-color-background-warning); + --color-warning-text: var(--dark-color-warning-text); + --color-icon-background: var(--dark-color-icon-background); + --color-accent: var(--dark-color-accent); + --color-active-menu-item: var(--dark-color-active-menu-item); + --color-text: var(--dark-color-text); + --color-text-aside: var(--dark-color-text-aside); + --color-link: var(--dark-color-link); + + --color-ts-keyword: var(--dark-color-ts-keyword); + --color-ts-module: var(--dark-color-ts-module); + --color-ts-namespace: var(--dark-color-ts-namespace); + --color-ts-enum: var(--dark-color-ts-enum); + --color-ts-enum-member: var(--dark-color-ts-enum-member); + --color-ts-variable: var(--dark-color-ts-variable); + --color-ts-function: var(--dark-color-ts-function); + --color-ts-class: var(--dark-color-ts-class); + --color-ts-interface: var(--dark-color-ts-interface); + --color-ts-constructor: var(--dark-color-ts-constructor); + --color-ts-property: var(--dark-color-ts-property); + --color-ts-method: var(--dark-color-ts-method); + --color-ts-call-signature: var(--dark-color-ts-call-signature); + --color-ts-index-signature: var(--dark-color-ts-index-signature); + --color-ts-constructor-signature: var( + --dark-color-ts-constructor-signature + ); + --color-ts-parameter: var(--dark-color-ts-parameter); + --color-ts-type-parameter: var(--dark-color-ts-type-parameter); + --color-ts-accessor: var(--dark-color-ts-accessor); + --color-ts-get-signature: var(--dark-color-ts-get-signature); + --color-ts-set-signature: var(--dark-color-ts-set-signature); + --color-ts-type-alias: var(--dark-color-ts-type-alias); + + --external-icon: var(--dark-external-icon); + --color-scheme: var(--dark-color-scheme); + } +} + +html { + color-scheme: var(--color-scheme); +} + +body { + margin: 0; +} + +:root[data-theme="light"] { + --color-background: var(--light-color-background); + --color-background-secondary: var(--light-color-background-secondary); + --color-background-warning: var(--light-color-background-warning); + --color-warning-text: var(--light-color-warning-text); + --color-icon-background: var(--light-color-icon-background); + --color-accent: var(--light-color-accent); + --color-active-menu-item: var(--light-color-active-menu-item); + --color-text: var(--light-color-text); + --color-text-aside: var(--light-color-text-aside); + --color-link: var(--light-color-link); + + --color-ts-keyword: var(--light-color-ts-keyword); + --color-ts-module: var(--light-color-ts-module); + --color-ts-namespace: var(--light-color-ts-namespace); + --color-ts-enum: var(--light-color-ts-enum); + --color-ts-enum-member: var(--light-color-ts-enum-member); + --color-ts-variable: var(--light-color-ts-variable); + --color-ts-function: var(--light-color-ts-function); + --color-ts-class: var(--light-color-ts-class); + --color-ts-interface: var(--light-color-ts-interface); + --color-ts-constructor: var(--light-color-ts-constructor); + --color-ts-property: var(--light-color-ts-property); + --color-ts-method: var(--light-color-ts-method); + --color-ts-call-signature: var(--light-color-ts-call-signature); + --color-ts-index-signature: var(--light-color-ts-index-signature); + --color-ts-constructor-signature: var( + --light-color-ts-constructor-signature + ); + --color-ts-parameter: var(--light-color-ts-parameter); + --color-ts-type-parameter: var(--light-color-ts-type-parameter); + --color-ts-accessor: var(--light-color-ts-accessor); + --color-ts-get-signature: var(--light-color-ts-get-signature); + --color-ts-set-signature: var(--light-color-ts-set-signature); + --color-ts-type-alias: var(--light-color-ts-type-alias); + + --external-icon: var(--light-external-icon); + --color-scheme: var(--light-color-scheme); +} + +:root[data-theme="dark"] { + --color-background: var(--dark-color-background); + --color-background-secondary: var(--dark-color-background-secondary); + --color-background-warning: var(--dark-color-background-warning); + --color-warning-text: var(--dark-color-warning-text); + --color-icon-background: var(--dark-color-icon-background); + --color-accent: var(--dark-color-accent); + --color-active-menu-item: var(--dark-color-active-menu-item); + --color-text: var(--dark-color-text); + --color-text-aside: var(--dark-color-text-aside); + --color-link: var(--dark-color-link); + + --color-ts-keyword: var(--dark-color-ts-keyword); + --color-ts-module: var(--dark-color-ts-module); + --color-ts-namespace: var(--dark-color-ts-namespace); + --color-ts-enum: var(--dark-color-ts-enum); + --color-ts-enum-member: var(--dark-color-ts-enum-member); + --color-ts-variable: var(--dark-color-ts-variable); + --color-ts-function: var(--dark-color-ts-function); + --color-ts-class: var(--dark-color-ts-class); + --color-ts-interface: var(--dark-color-ts-interface); + --color-ts-constructor: var(--dark-color-ts-constructor); + --color-ts-property: var(--dark-color-ts-property); + --color-ts-method: var(--dark-color-ts-method); + --color-ts-call-signature: var(--dark-color-ts-call-signature); + --color-ts-index-signature: var(--dark-color-ts-index-signature); + --color-ts-constructor-signature: var( + --dark-color-ts-constructor-signature + ); + --color-ts-parameter: var(--dark-color-ts-parameter); + --color-ts-type-parameter: var(--dark-color-ts-type-parameter); + --color-ts-accessor: var(--dark-color-ts-accessor); + --color-ts-get-signature: var(--dark-color-ts-get-signature); + --color-ts-set-signature: var(--dark-color-ts-set-signature); + --color-ts-type-alias: var(--dark-color-ts-type-alias); + + --external-icon: var(--dark-external-icon); + --color-scheme: var(--dark-color-scheme); +} + +.always-visible, +.always-visible .tsd-signatures { + display: inherit !important; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + line-height: 1.2; +} + +h1 > a:not(.link), +h2 > a:not(.link), +h3 > a:not(.link), +h4 > a:not(.link), +h5 > a:not(.link), +h6 > a:not(.link) { + text-decoration: none; + color: var(--color-text); +} + +h1 { + font-size: 1.875rem; + margin: 0.67rem 0; +} + +h2 { + font-size: 1.5rem; + margin: 0.83rem 0; +} + +h3 { + font-size: 1.25rem; + margin: 1rem 0; +} + +h4 { + font-size: 1.05rem; + margin: 1.33rem 0; +} + +h5 { + font-size: 1rem; + margin: 1.5rem 0; +} + +h6 { + font-size: 0.875rem; + margin: 2.33rem 0; +} + +.uppercase { + text-transform: uppercase; +} + +dl, +menu, +ol, +ul { + margin: 1em 0; +} + +dd { + margin: 0 0 0 40px; +} + +.container { + max-width: 1700px; + padding: 0 2rem; +} + +/* Footer */ +.tsd-generator { + border-top: 1px solid var(--color-accent); + padding-top: 1rem; + padding-bottom: 1rem; + max-height: 3.5rem; +} + +.tsd-generator > p { + margin-top: 0; + margin-bottom: 0; + padding: 0 1rem; +} + +.container-main { + margin: 0 auto; + /* toolbar, footer, margin */ + min-height: calc(100vh - 41px - 56px - 4rem); +} + +@keyframes fade-in { + from { + opacity: 0; + } + to { + opacity: 1; + } +} +@keyframes fade-out { + from { + opacity: 1; + visibility: visible; + } + to { + opacity: 0; + } +} +@keyframes fade-in-delayed { + 0% { + opacity: 0; + } + 33% { + opacity: 0; + } + 100% { + opacity: 1; + } +} +@keyframes fade-out-delayed { + 0% { + opacity: 1; + visibility: visible; + } + 66% { + opacity: 0; + } + 100% { + opacity: 0; + } +} +@keyframes pop-in-from-right { + from { + transform: translate(100%, 0); + } + to { + transform: translate(0, 0); + } +} +@keyframes pop-out-to-right { + from { + transform: translate(0, 0); + visibility: visible; + } + to { + transform: translate(100%, 0); + } +} +body { + background: var(--color-background); + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", + Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; + font-size: 16px; + color: var(--color-text); +} + +a { + color: var(--color-link); + text-decoration: none; +} +a:hover { + text-decoration: underline; +} +a.external[target="_blank"] { + background-image: var(--external-icon); + background-position: top 3px right; + background-repeat: no-repeat; + padding-right: 13px; +} + +code, +pre { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + padding: 0.2em; + margin: 0; + font-size: 0.875rem; + border-radius: 0.8em; +} + +pre { + position: relative; + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word; + padding: 10px; + border: 1px solid var(--color-accent); +} +pre code { + padding: 0; + font-size: 100%; +} +pre > button { + position: absolute; + top: 10px; + right: 10px; + opacity: 0; + transition: opacity 0.1s; + box-sizing: border-box; +} +pre:hover > button, +pre > button.visible { + opacity: 1; +} + +blockquote { + margin: 1em 0; + padding-left: 1em; + border-left: 4px solid gray; +} + +.tsd-typography { + line-height: 1.333em; +} +.tsd-typography ul { + list-style: square; + padding: 0 0 0 20px; + margin: 0; +} +.tsd-typography .tsd-index-panel h3, +.tsd-index-panel .tsd-typography h3, +.tsd-typography h4, +.tsd-typography h5, +.tsd-typography h6 { + font-size: 1em; +} +.tsd-typography h5, +.tsd-typography h6 { + font-weight: normal; +} +.tsd-typography p, +.tsd-typography ul, +.tsd-typography ol { + margin: 1em 0; +} +.tsd-typography table { + border-collapse: collapse; + border: none; +} +.tsd-typography td, +.tsd-typography th { + padding: 6px 13px; + border: 1px solid var(--color-accent); +} +.tsd-typography thead, +.tsd-typography tr:nth-child(even) { + background-color: var(--color-background-secondary); +} + +.tsd-breadcrumb { + margin: 0; + padding: 0; + color: var(--color-text-aside); +} +.tsd-breadcrumb a { + color: var(--color-text-aside); + text-decoration: none; +} +.tsd-breadcrumb a:hover { + text-decoration: underline; +} +.tsd-breadcrumb li { + display: inline; +} +.tsd-breadcrumb li:after { + content: " / "; +} + +.tsd-comment-tags { + display: flex; + flex-direction: column; +} +dl.tsd-comment-tag-group { + display: flex; + align-items: center; + overflow: hidden; + margin: 0.5em 0; +} +dl.tsd-comment-tag-group dt { + display: flex; + margin-right: 0.5em; + font-size: 0.875em; + font-weight: normal; +} +dl.tsd-comment-tag-group dd { + margin: 0; +} +code.tsd-tag { + padding: 0.25em 0.4em; + border: 0.1em solid var(--color-accent); + margin-right: 0.25em; + font-size: 70%; +} +h1 code.tsd-tag:first-of-type { + margin-left: 0.25em; +} + +dl.tsd-comment-tag-group dd:before, +dl.tsd-comment-tag-group dd:after { + content: " "; +} +dl.tsd-comment-tag-group dd pre, +dl.tsd-comment-tag-group dd:after { + clear: both; +} +dl.tsd-comment-tag-group p { + margin: 0; +} + +.tsd-panel.tsd-comment .lead { + font-size: 1.1em; + line-height: 1.333em; + margin-bottom: 2em; +} +.tsd-panel.tsd-comment .lead:last-child { + margin-bottom: 0; +} + +.tsd-filter-visibility h4 { + font-size: 1rem; + padding-top: 0.75rem; + padding-bottom: 0.5rem; + margin: 0; +} +.tsd-filter-item:not(:last-child) { + margin-bottom: 0.5rem; +} +.tsd-filter-input { + display: flex; + width: fit-content; + width: -moz-fit-content; + align-items: center; + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + cursor: pointer; +} +.tsd-filter-input input[type="checkbox"] { + cursor: pointer; + position: absolute; + width: 1.5em; + height: 1.5em; + opacity: 0; +} +.tsd-filter-input input[type="checkbox"]:disabled { + pointer-events: none; +} +.tsd-filter-input svg { + cursor: pointer; + width: 1.5em; + height: 1.5em; + margin-right: 0.5em; + border-radius: 0.33em; + /* Leaving this at full opacity breaks event listeners on Firefox. + Don't remove unless you know what you're doing. */ + opacity: 0.99; +} +.tsd-filter-input input[type="checkbox"]:focus + svg { + transform: scale(0.95); +} +.tsd-filter-input input[type="checkbox"]:focus:not(:focus-visible) + svg { + transform: scale(1); +} +.tsd-checkbox-background { + fill: var(--color-accent); +} +input[type="checkbox"]:checked ~ svg .tsd-checkbox-checkmark { + stroke: var(--color-text); +} +.tsd-filter-input input:disabled ~ svg > .tsd-checkbox-background { + fill: var(--color-background); + stroke: var(--color-accent); + stroke-width: 0.25rem; +} +.tsd-filter-input input:disabled ~ svg > .tsd-checkbox-checkmark { + stroke: var(--color-accent); +} + +.tsd-theme-toggle { + padding-top: 0.75rem; +} +.tsd-theme-toggle > h4 { + display: inline; + vertical-align: middle; + margin-right: 0.75rem; +} + +.tsd-hierarchy { + list-style: square; + margin: 0; +} +.tsd-hierarchy .target { + font-weight: bold; +} + +.tsd-full-hierarchy:not(:last-child) { + margin-bottom: 1em; + padding-bottom: 1em; + border-bottom: 1px solid var(--color-accent); +} +.tsd-full-hierarchy, +.tsd-full-hierarchy ul { + list-style: none; + margin: 0; + padding: 0; +} +.tsd-full-hierarchy ul { + padding-left: 1.5rem; +} +.tsd-full-hierarchy a { + padding: 0.25rem 0 !important; + font-size: 1rem; + display: inline-flex; + align-items: center; + color: var(--color-text); +} + +.tsd-panel-group.tsd-index-group { + margin-bottom: 0; +} +.tsd-index-panel .tsd-index-list { + list-style: none; + line-height: 1.333em; + margin: 0; + padding: 0.25rem 0 0 0; + overflow: hidden; + display: grid; + grid-template-columns: repeat(3, 1fr); + column-gap: 1rem; + grid-template-rows: auto; +} +@media (max-width: 1024px) { + .tsd-index-panel .tsd-index-list { + grid-template-columns: repeat(2, 1fr); + } +} +@media (max-width: 768px) { + .tsd-index-panel .tsd-index-list { + grid-template-columns: repeat(1, 1fr); + } +} +.tsd-index-panel .tsd-index-list li { + -webkit-page-break-inside: avoid; + -moz-page-break-inside: avoid; + -ms-page-break-inside: avoid; + -o-page-break-inside: avoid; + page-break-inside: avoid; +} + +.tsd-flag { + display: inline-block; + padding: 0.25em 0.4em; + border-radius: 4px; + color: var(--color-comment-tag-text); + background-color: var(--color-comment-tag); + text-indent: 0; + font-size: 75%; + line-height: 1; + font-weight: normal; +} + +.tsd-anchor { + position: relative; + top: -100px; +} + +.tsd-member { + position: relative; +} +.tsd-member .tsd-anchor + h3 { + display: flex; + align-items: center; + margin-top: 0; + margin-bottom: 0; + border-bottom: none; +} + +.tsd-navigation.settings { + margin: 1rem 0; +} +.tsd-navigation > a, +.tsd-navigation .tsd-accordion-summary { + width: calc(100% - 0.25rem); + display: flex; + align-items: center; +} +.tsd-navigation a, +.tsd-navigation summary > span, +.tsd-page-navigation a { + display: flex; + width: calc(100% - 0.25rem); + align-items: center; + padding: 0.25rem; + color: var(--color-text); + text-decoration: none; + box-sizing: border-box; +} +.tsd-navigation a.current, +.tsd-page-navigation a.current { + background: var(--color-active-menu-item); +} +.tsd-navigation a:hover, +.tsd-page-navigation a:hover { + text-decoration: underline; +} +.tsd-navigation ul, +.tsd-page-navigation ul { + margin-top: 0; + margin-bottom: 0; + padding: 0; + list-style: none; +} +.tsd-navigation li, +.tsd-page-navigation li { + padding: 0; + max-width: 100%; +} +.tsd-nested-navigation { + margin-left: 3rem; +} +.tsd-nested-navigation > li > details { + margin-left: -1.5rem; +} +.tsd-small-nested-navigation { + margin-left: 1.5rem; +} +.tsd-small-nested-navigation > li > details { + margin-left: -1.5rem; +} + +.tsd-page-navigation ul { + padding-left: 1.75rem; +} + +#tsd-sidebar-links a { + margin-top: 0; + margin-bottom: 0.5rem; + line-height: 1.25rem; +} +#tsd-sidebar-links a:last-of-type { + margin-bottom: 0; +} + +a.tsd-index-link { + padding: 0.25rem 0 !important; + font-size: 1rem; + line-height: 1.25rem; + display: inline-flex; + align-items: center; + color: var(--color-text); +} +.tsd-accordion-summary { + list-style-type: none; /* hide marker on non-safari */ + outline: none; /* broken on safari, so just hide it */ +} +.tsd-accordion-summary::-webkit-details-marker { + display: none; /* hide marker on safari */ +} +.tsd-accordion-summary, +.tsd-accordion-summary a { + user-select: none; + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + + cursor: pointer; +} +.tsd-accordion-summary a { + width: calc(100% - 1.5rem); +} +.tsd-accordion-summary > * { + margin-top: 0; + margin-bottom: 0; + padding-top: 0; + padding-bottom: 0; +} +.tsd-index-accordion .tsd-accordion-summary > svg { + margin-left: 0.25rem; +} +.tsd-index-content > :not(:first-child) { + margin-top: 0.75rem; +} +.tsd-index-heading { + margin-top: 1.5rem; + margin-bottom: 0.75rem; +} + +.tsd-kind-icon { + margin-right: 0.5rem; + width: 1.25rem; + height: 1.25rem; + min-width: 1.25rem; + min-height: 1.25rem; +} +.tsd-kind-icon path { + transform-origin: center; + transform: scale(1.1); +} +.tsd-signature > .tsd-kind-icon { + margin-right: 0.8rem; +} + +.tsd-panel { + margin-bottom: 2.5rem; +} +.tsd-panel.tsd-member { + margin-bottom: 4rem; +} +.tsd-panel:empty { + display: none; +} +.tsd-panel > h1, +.tsd-panel > h2, +.tsd-panel > h3 { + margin: 1.5rem -1.5rem 0.75rem -1.5rem; + padding: 0 1.5rem 0.75rem 1.5rem; +} +.tsd-panel > h1.tsd-before-signature, +.tsd-panel > h2.tsd-before-signature, +.tsd-panel > h3.tsd-before-signature { + margin-bottom: 0; + border-bottom: none; +} + +.tsd-panel-group { + margin: 4rem 0; +} +.tsd-panel-group.tsd-index-group { + margin: 2rem 0; +} +.tsd-panel-group.tsd-index-group details { + margin: 2rem 0; +} + +#tsd-search { + transition: background-color 0.2s; +} +#tsd-search .title { + position: relative; + z-index: 2; +} +#tsd-search .field { + position: absolute; + left: 0; + top: 0; + right: 2.5rem; + height: 100%; +} +#tsd-search .field input { + box-sizing: border-box; + position: relative; + top: -50px; + z-index: 1; + width: 100%; + padding: 0 10px; + opacity: 0; + outline: 0; + border: 0; + background: transparent; + color: var(--color-text); +} +#tsd-search .field label { + position: absolute; + overflow: hidden; + right: -40px; +} +#tsd-search .field input, +#tsd-search .title, +#tsd-toolbar-links a { + transition: opacity 0.2s; +} +#tsd-search .results { + position: absolute; + visibility: hidden; + top: 40px; + width: 100%; + margin: 0; + padding: 0; + list-style: none; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); +} +#tsd-search .results li { + background-color: var(--color-background); + line-height: initial; + padding: 4px; +} +#tsd-search .results li:nth-child(even) { + background-color: var(--color-background-secondary); +} +#tsd-search .results li.state { + display: none; +} +#tsd-search .results li.current:not(.no-results), +#tsd-search .results li:hover:not(.no-results) { + background-color: var(--color-accent); +} +#tsd-search .results a { + display: flex; + align-items: center; + padding: 0.25rem; + box-sizing: border-box; +} +#tsd-search .results a:before { + top: 10px; +} +#tsd-search .results span.parent { + color: var(--color-text-aside); + font-weight: normal; +} +#tsd-search.has-focus { + background-color: var(--color-accent); +} +#tsd-search.has-focus .field input { + top: 0; + opacity: 1; +} +#tsd-search.has-focus .title, +#tsd-search.has-focus #tsd-toolbar-links a { + z-index: 0; + opacity: 0; +} +#tsd-search.has-focus .results { + visibility: visible; +} +#tsd-search.loading .results li.state.loading { + display: block; +} +#tsd-search.failure .results li.state.failure { + display: block; +} + +#tsd-toolbar-links { + position: absolute; + top: 0; + right: 2rem; + height: 100%; + display: flex; + align-items: center; + justify-content: flex-end; +} +#tsd-toolbar-links a { + margin-left: 1.5rem; +} +#tsd-toolbar-links a:hover { + text-decoration: underline; +} + +.tsd-signature { + margin: 0 0 1rem 0; + padding: 1rem 0.5rem; + border: 1px solid var(--color-accent); + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + font-size: 14px; + overflow-x: auto; +} + +.tsd-signature-keyword { + color: var(--color-ts-keyword); + font-weight: normal; +} + +.tsd-signature-symbol { + color: var(--color-text-aside); + font-weight: normal; +} + +.tsd-signature-type { + font-style: italic; + font-weight: normal; +} + +.tsd-signatures { + padding: 0; + margin: 0 0 1em 0; + list-style-type: none; +} +.tsd-signatures .tsd-signature { + margin: 0; + border-color: var(--color-accent); + border-width: 1px 0; + transition: background-color 0.1s; +} +.tsd-description .tsd-signatures .tsd-signature { + border-width: 1px; +} + +ul.tsd-parameter-list, +ul.tsd-type-parameter-list { + list-style: square; + margin: 0; + padding-left: 20px; +} +ul.tsd-parameter-list > li.tsd-parameter-signature, +ul.tsd-type-parameter-list > li.tsd-parameter-signature { + list-style: none; + margin-left: -20px; +} +ul.tsd-parameter-list h5, +ul.tsd-type-parameter-list h5 { + font-size: 16px; + margin: 1em 0 0.5em 0; +} +.tsd-sources { + margin-top: 1rem; + font-size: 0.875em; +} +.tsd-sources a { + color: var(--color-text-aside); + text-decoration: underline; +} +.tsd-sources ul { + list-style: none; + padding: 0; +} + +.tsd-page-toolbar { + position: sticky; + z-index: 1; + top: 0; + left: 0; + width: 100%; + color: var(--color-text); + background: var(--color-background-secondary); + border-bottom: 1px var(--color-accent) solid; + transition: transform 0.3s ease-in-out; +} +.tsd-page-toolbar a { + color: var(--color-text); + text-decoration: none; +} +.tsd-page-toolbar a.title { + font-weight: bold; +} +.tsd-page-toolbar a.title:hover { + text-decoration: underline; +} +.tsd-page-toolbar .tsd-toolbar-contents { + display: flex; + justify-content: space-between; + height: 2.5rem; + margin: 0 auto; +} +.tsd-page-toolbar .table-cell { + position: relative; + white-space: nowrap; + line-height: 40px; +} +.tsd-page-toolbar .table-cell:first-child { + width: 100%; +} +.tsd-page-toolbar .tsd-toolbar-icon { + box-sizing: border-box; + line-height: 0; + padding: 12px 0; +} + +.tsd-widget { + display: inline-block; + overflow: hidden; + opacity: 0.8; + height: 40px; + transition: + opacity 0.1s, + background-color 0.2s; + vertical-align: bottom; + cursor: pointer; +} +.tsd-widget:hover { + opacity: 0.9; +} +.tsd-widget.active { + opacity: 1; + background-color: var(--color-accent); +} +.tsd-widget.no-caption { + width: 40px; +} +.tsd-widget.no-caption:before { + margin: 0; +} + +.tsd-widget.options, +.tsd-widget.menu { + display: none; +} +input[type="checkbox"] + .tsd-widget:before { + background-position: -120px 0; +} +input[type="checkbox"]:checked + .tsd-widget:before { + background-position: -160px 0; +} + +img { + max-width: 100%; +} + +.tsd-anchor-icon { + display: inline-flex; + align-items: center; + margin-left: 0.5rem; + vertical-align: middle; + color: var(--color-text); +} + +.tsd-anchor-icon svg { + width: 1em; + height: 1em; + visibility: hidden; +} + +.tsd-anchor-link:hover > .tsd-anchor-icon svg { + visibility: visible; +} + +.deprecated { + text-decoration: line-through !important; +} + +.warning { + padding: 1rem; + color: var(--color-warning-text); + background: var(--color-background-warning); +} + +.tsd-kind-project { + color: var(--color-ts-project); +} +.tsd-kind-module { + color: var(--color-ts-module); +} +.tsd-kind-namespace { + color: var(--color-ts-namespace); +} +.tsd-kind-enum { + color: var(--color-ts-enum); +} +.tsd-kind-enum-member { + color: var(--color-ts-enum-member); +} +.tsd-kind-variable { + color: var(--color-ts-variable); +} +.tsd-kind-function { + color: var(--color-ts-function); +} +.tsd-kind-class { + color: var(--color-ts-class); +} +.tsd-kind-interface { + color: var(--color-ts-interface); +} +.tsd-kind-constructor { + color: var(--color-ts-constructor); +} +.tsd-kind-property { + color: var(--color-ts-property); +} +.tsd-kind-method { + color: var(--color-ts-method); +} +.tsd-kind-call-signature { + color: var(--color-ts-call-signature); +} +.tsd-kind-index-signature { + color: var(--color-ts-index-signature); +} +.tsd-kind-constructor-signature { + color: var(--color-ts-constructor-signature); +} +.tsd-kind-parameter { + color: var(--color-ts-parameter); +} +.tsd-kind-type-literal { + color: var(--color-ts-type-literal); +} +.tsd-kind-type-parameter { + color: var(--color-ts-type-parameter); +} +.tsd-kind-accessor { + color: var(--color-ts-accessor); +} +.tsd-kind-get-signature { + color: var(--color-ts-get-signature); +} +.tsd-kind-set-signature { + color: var(--color-ts-set-signature); +} +.tsd-kind-type-alias { + color: var(--color-ts-type-alias); +} + +/* if we have a kind icon, don't color the text by kind */ +.tsd-kind-icon ~ span { + color: var(--color-text); +} + +* { + scrollbar-width: thin; + scrollbar-color: var(--color-accent) var(--color-icon-background); +} + +*::-webkit-scrollbar { + width: 0.75rem; +} + +*::-webkit-scrollbar-track { + background: var(--color-icon-background); +} + +*::-webkit-scrollbar-thumb { + background-color: var(--color-accent); + border-radius: 999rem; + border: 0.25rem solid var(--color-icon-background); +} + +/* mobile */ +@media (max-width: 769px) { + .tsd-widget.options, + .tsd-widget.menu { + display: inline-block; + } + + .container-main { + display: flex; + } + html .col-content { + float: none; + max-width: 100%; + width: 100%; + } + html .col-sidebar { + position: fixed !important; + overflow-y: auto; + -webkit-overflow-scrolling: touch; + z-index: 1024; + top: 0 !important; + bottom: 0 !important; + left: auto !important; + right: 0 !important; + padding: 1.5rem 1.5rem 0 0; + width: 75vw; + visibility: hidden; + background-color: var(--color-background); + transform: translate(100%, 0); + } + html .col-sidebar > *:last-child { + padding-bottom: 20px; + } + html .overlay { + content: ""; + display: block; + position: fixed; + z-index: 1023; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.75); + visibility: hidden; + } + + .to-has-menu .overlay { + animation: fade-in 0.4s; + } + + .to-has-menu .col-sidebar { + animation: pop-in-from-right 0.4s; + } + + .from-has-menu .overlay { + animation: fade-out 0.4s; + } + + .from-has-menu .col-sidebar { + animation: pop-out-to-right 0.4s; + } + + .has-menu body { + overflow: hidden; + } + .has-menu .overlay { + visibility: visible; + } + .has-menu .col-sidebar { + visibility: visible; + transform: translate(0, 0); + display: flex; + flex-direction: column; + gap: 1.5rem; + max-height: 100vh; + padding: 1rem 2rem; + } + .has-menu .tsd-navigation { + max-height: 100%; + } +} + +/* one sidebar */ +@media (min-width: 770px) { + .container-main { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); + grid-template-areas: "sidebar content"; + margin: 2rem auto; + } + + .col-sidebar { + grid-area: sidebar; + } + .col-content { + grid-area: content; + padding: 0 1rem; + } +} +@media (min-width: 770px) and (max-width: 1399px) { + .col-sidebar { + max-height: calc(100vh - 2rem - 42px); + overflow: auto; + position: sticky; + top: 42px; + padding-top: 1rem; + } + .site-menu { + margin-top: 1rem; + } +} + +/* two sidebars */ +@media (min-width: 1200px) { + .container-main { + grid-template-columns: minmax(0, 1fr) minmax(0, 2.5fr) minmax(0, 20rem); + grid-template-areas: "sidebar content toc"; + } + + .col-sidebar { + display: contents; + } + + .page-menu { + grid-area: toc; + padding-left: 1rem; + } + .site-menu { + grid-area: sidebar; + } + + .site-menu { + margin-top: 1rem 0; + } + + .page-menu, + .site-menu { + max-height: calc(100vh - 2rem - 42px); + overflow: auto; + position: sticky; + top: 42px; + } +} diff --git a/examples/docs/index.html b/examples/docs/index.html new file mode 100644 index 0000000..48eb0e0 --- /dev/null +++ b/examples/docs/index.html @@ -0,0 +1,55 @@ +@samchon/tgrid-example-websocket

@samchon/tgrid-example-websocket

TGrid

TGrid logo

+

GitHub license +npm version +Downloads +Build Status +Guide Documents

+

TypeScript Grid Computing Framework.

+

TypeScript RPC (Remote Procedure Call) framework for WebSocket and Worker protocols.

+

Also, extremely easy even when composing complicated network system like grid computing.

+
import { Driver, WebSocketConnector } from "tgrid";

import { ICalcConfig } from "../interfaces/ICalcConfig";
import { ICalcEvent } from "../interfaces/ICalcEvent";
import { ICalcEventListener } from "../interfaces/ICalcEventListener";
import { ICompositeCalculator } from "../interfaces/ICompositeCalculator";

export const webSocketClientMain = async () => {
const stack: ICalcEvent[] = [];
const listener: ICalcEventListener = {
on: (evt: ICalcEvent) => stack.push(evt),
};
const connector: WebSocketConnector<
ICalcConfig,
ICalcEventListener,
ICompositeCalculator
> = new WebSocketConnector(
{ precision: 2 }, // header
listener, // provider for remote server
);
await connector.connect("ws://127.0.0.1:37000/composite");

const remote: Driver<ICompositeCalculator> = connector.getDriver();
await remote.plus(10, 20); // returns 30
await remote.multiplies(3, 4); // returns 12
await remote.divides(5, 3); // returns 1.67
await remote.scientific.sqrt(2); // returns 1.41
await remote.statistics.mean(1, 3, 9); // returns 4.33

await connector.close();
console.log(...stack);
}; +
+
+

Execution result:

+
{ type: 'plus', input: [ 10, 20 ], output: 30 }
{ type: 'multiplies', input: [ 3, 4 ], output: 12 }
{ type: 'divides', input: [ 5, 3 ], output: 1.67 }
{ type: 'sqrt', input: [ 2 ], output: 1.41 }
{ type: 'mean', input: [ 1, 3, 9 ], output: 4.33 } +
+
+

Setup

npm install tgrid
+
+

Just install with npm command. That's all.

+

If you wanna use tgrid in NestJS, read nestia guide documents.

+ +

Guide Documents

Check out the document in the website:

+

🏠 Home

+

📖 Tutorial

+

🔗 Appendix

+

Generated using TypeDoc

\ No newline at end of file diff --git a/examples/docs/modules.html b/examples/docs/modules.html new file mode 100644 index 0000000..15e549f --- /dev/null +++ b/examples/docs/modules.html @@ -0,0 +1 @@ +@samchon/tgrid-example-websocket

@samchon/tgrid-example-websocket

Generated using TypeDoc

\ No newline at end of file diff --git a/examples/package.json b/examples/package.json index 07bae33..d222fd5 100644 --- a/examples/package.json +++ b/examples/package.json @@ -4,9 +4,8 @@ "description": "", "main": "index.js", "scripts": { - "websocket": "npx ts-node src/websocket/index.ts", - "websocket:server": "npx ts-node src/websocket/server.ts", - "websocket:client": "npx ts-node src/websocket/client.ts" + "start:websocket": "ts-node src/websocket", + "start:worker": "ts-node src/worker" }, "keywords": [], "author": "", diff --git a/examples/src/shared-worker/client.ts b/examples/src/shared-worker/client.ts new file mode 100644 index 0000000..186ae98 --- /dev/null +++ b/examples/src/shared-worker/client.ts @@ -0,0 +1,32 @@ +import { Driver, SharedWorkerConnector } from "tgrid"; + +import { ICalcConfig } from "../interfaces/ICalcConfig"; +import { ICalcEvent } from "../interfaces/ICalcEvent"; +import { ICalcEventListener } from "../interfaces/ICalcEventListener"; +import { ICompositeCalculator } from "../interfaces/ICompositeCalculator"; + +export const sharedWorkerClientMain = async () => { + const stack: ICalcEvent[] = []; + const listener: ICalcEventListener = { + on: (evt: ICalcEvent) => stack.push(evt), + }; + const connector: SharedWorkerConnector< + ICalcConfig, + ICalcEventListener, + ICompositeCalculator + > = new SharedWorkerConnector( + { precision: 2 }, // header + listener, // provider for remote server + ); + await connector.connect("./server.js"); + + const remote: Driver = connector.getDriver(); + await remote.plus(10, 20); // returns 30 + await remote.multiplies(3, 4); // returns 12 + await remote.divides(5, 3); // returns 1.67 + await remote.scientific.sqrt(2); // returns 1.41 + await remote.statistics.mean(1, 3, 9); // returns 4.33 + + await connector.close(); + console.log(stack); +}; diff --git a/examples/src/shared-worker/server.ts b/examples/src/shared-worker/server.ts new file mode 100644 index 0000000..4263e62 --- /dev/null +++ b/examples/src/shared-worker/server.ts @@ -0,0 +1,41 @@ +import { Driver, SharedWorkerAcceptor, SharedWorkerServer } from "tgrid"; + +import { ICalcConfig } from "../interfaces/ICalcConfig"; +import { ICalcEventListener } from "../interfaces/ICalcEventListener"; +import { CompositeCalculator } from "../providers/CompositeCalculator"; + +const main = async () => { + let pool: number = 0; + const server: SharedWorkerServer< + ICalcConfig, + CompositeCalculator, + ICalcEventListener + > = new SharedWorkerServer(); + await server.open( + async ( + acceptor: SharedWorkerAcceptor< + ICalcConfig, + CompositeCalculator, + ICalcEventListener + >, + ) => { + // LIST UP PROPERTIES + const config: ICalcConfig = acceptor.header; + const listener: Driver = acceptor.getDriver(); + + // ACCEPT OR REJECT THE CONNECTION + if (pool >= 8) { + await acceptor.reject("Too much connections."); + } else { + await acceptor.accept(new CompositeCalculator(config, listener)); + ++pool; + await acceptor.join(); + --pool; + } + }, + ); +}; +main().catch((exp) => { + console.error(exp); + process.exit(-1); +}); diff --git a/examples/src/worker/client.ts b/examples/src/worker/client.ts new file mode 100644 index 0000000..56e124d --- /dev/null +++ b/examples/src/worker/client.ts @@ -0,0 +1,35 @@ +import { Driver, WorkerConnector } from "tgrid"; + +import { ICalcConfig } from "../interfaces/ICalcConfig"; +import { ICalcEvent } from "../interfaces/ICalcEvent"; +import { ICalcEventListener } from "../interfaces/ICalcEventListener"; +import { ICompositeCalculator } from "../interfaces/ICompositeCalculator"; + +const EXTENSION = __filename.endsWith(".ts") ? "ts" : "js"; + +export const workerClientMain = async () => { + const stack: ICalcEvent[] = []; + const listener: ICalcEventListener = { + on: (evt: ICalcEvent) => stack.push(evt), + }; + const connector: WorkerConnector< + ICalcConfig, + ICalcEventListener, + ICompositeCalculator + > = new WorkerConnector( + { precision: 2 }, // header + listener, // provider for remote server + "process", + ); + await connector.connect(`${__dirname}/server.${EXTENSION}`); + + const remote: Driver = connector.getDriver(); + await remote.plus(10, 20); // returns 30 + await remote.multiplies(3, 4); // returns 12 + await remote.divides(5, 3); // returns 1.67 + await remote.scientific.sqrt(2); // returns 1.41 + await remote.statistics.mean(1, 3, 9); // returns 4.33 + + await connector.close(); + console.log(stack); +}; diff --git a/examples/src/worker/index.ts b/examples/src/worker/index.ts new file mode 100644 index 0000000..87a9932 --- /dev/null +++ b/examples/src/worker/index.ts @@ -0,0 +1,9 @@ +import { workerClientMain } from "./client"; + +const main = async (): Promise => { + await workerClientMain(); +}; +main().catch((exp) => { + console.error(exp); + process.exit(-1); +}); diff --git a/examples/src/worker/server.ts b/examples/src/worker/server.ts new file mode 100644 index 0000000..c95faf7 --- /dev/null +++ b/examples/src/worker/server.ts @@ -0,0 +1,25 @@ +import { Driver, WorkerServer } from "tgrid"; + +import { ICalcConfig } from "../interfaces/ICalcConfig"; +import { ICalcEventListener } from "../interfaces/ICalcEventListener"; +import { CompositeCalculator } from "../providers/CompositeCalculator"; + +const main = async () => { + const server: WorkerServer< + ICalcConfig, + CompositeCalculator, + ICalcEventListener + > = new WorkerServer(); + + const header: ICalcConfig = await server.getHeader(); + const listener: Driver = server.getDriver(); + const provider: CompositeCalculator = new CompositeCalculator( + header, + listener, + ); + await server.open(provider); +}; +main().catch((exp) => { + console.error(exp); + process.exit(-1); +}); diff --git a/src/protocols/web/WebSocketAcceptor.ts b/src/protocols/web/WebSocketAcceptor.ts index ec67af1..a01a245 100644 --- a/src/protocols/web/WebSocketAcceptor.ts +++ b/src/protocols/web/WebSocketAcceptor.ts @@ -14,14 +14,14 @@ import { IWebSocketCommunicator } from "./internal/IWebSocketCommunicator"; * - available only in the NodeJS. * * The `WebSocketAcceptor` is a communicator class interacting with the remote - * {@link WebSocketConnector websocket client} through RPC (Remote Procedure Call) - * concept, created by the {@link WebSocketServer} class whenever a remote client + * {@link WebSocketConnector websocket client} through RPC (Remote Procedure Call), + * created by the {@link WebSocketServer} class whenever a remote client * connects to the websocket server. * * When a remote client connects to the {@link WebSocketServer websocket server}, * so that a new `WebSocketAcceptor` instance being created, you can determine * whether to {@link accept} the client's connection or {@link reject not}, - * reading the {@lin header} and {@link path} properties. If you've decided to + * reading the {@link header} and {@link path} properties. If you've decided to * accept the connection, call the {@link accept} method with `Provider` instance. * Otherwise, reject it thorugh the {@link reject} method. * @@ -37,7 +37,7 @@ import { IWebSocketCommunicator } from "./internal/IWebSocketCommunicator"; * For reference, the first `Header` type repersents an initial data from the * remote client after the connection. I recommend utilize it as an activation tool * for security enhancement. The second generic argument `Provider` represents a - * provider from server to client, and other `Remote` means a provider from the + * provider from server to client, and the other `Remote` means a provider from the * remote client to server. * * @template Header Type of the header containing initial data. diff --git a/src/protocols/web/WebSocketConnector.ts b/src/protocols/web/WebSocketConnector.ts index 4fcccf1..b7ceb49 100644 --- a/src/protocols/web/WebSocketConnector.ts +++ b/src/protocols/web/WebSocketConnector.ts @@ -26,7 +26,7 @@ import { WebSocketPolyfill } from "./internal/WebSocketPolyfill"; * closing must be performed by the remote websocket server, you can wait the * remote server's closing signal through the {@link join} method. * - * Also, when declaring this {@link WebSocketConnector} type, you've to define three + * Also, when declaring this `WebSocketConnector` type, you've to define three * generic arguments; `Header`, `Provider` and `Remote`. Those generic arguments must * be same with the ones defined in the target {@link WebSocketServer} and * {@link WebSocketAcceptor} classes (`Provider` and `Remote` must be reversed). @@ -34,7 +34,7 @@ import { WebSocketPolyfill } from "./internal/WebSocketPolyfill"; * For reference, the first `Header` type repersents an initial data from the * remote client after the connection. I recommend utilize it as an activation tool * for security enhancement. The second generic argument `Provider` represents a - * provider from client to server, and other `Remote` means a provider from the + * provider from client to server, and the other `Remote` means a provider from the * remote server to client. * * @template Header Type of the header containing initial data. diff --git a/src/protocols/web/WebSocketServer.ts b/src/protocols/web/WebSocketServer.ts index 675d1d1..0f995ad 100644 --- a/src/protocols/web/WebSocketServer.ts +++ b/src/protocols/web/WebSocketServer.ts @@ -20,7 +20,7 @@ import { WebSocketAcceptor } from "./WebSocketAcceptor"; * * To open the websocket server, call the {@link open} method with your callback * function which would be called whenever a {@link WebSocketAcceptor} has been - * newly created ay a new client's connection. + * newly created by a new client's connection. * * Also, when declaring this {@link WebSocketServer} type, you have to define three * generic arguments; `Header`, `Provider` and `Remote`. Those generic arguments @@ -30,7 +30,7 @@ import { WebSocketAcceptor } from "./WebSocketAcceptor"; * For reference, the first `Header` type repersents an initial data from the * remote client after the connection. I recommend utilize it as an activation tool * for security enhancement. The second generic argument `Provider` represents a - * provider from server to client, and other `Remote` means a provider from the + * provider from server to client, and the other `Remote` means a provider from the * remote client to server. * * @template Header Type of header containing initialization data like activation. diff --git a/src/protocols/workers/SharedWorkerAcceptor.ts b/src/protocols/workers/SharedWorkerAcceptor.ts index e92050a..a8a00ef 100644 --- a/src/protocols/workers/SharedWorkerAcceptor.ts +++ b/src/protocols/workers/SharedWorkerAcceptor.ts @@ -10,27 +10,36 @@ import { IWorkerSystem } from "./internal/IWorkerSystem"; * * - available only in the Web Browser. * - * The `SharedWorkerAcceptor` is a communicator class communicating with the remote client - * ({@link SharedWorkerConnector}) using RFC (Remote Function Call). The `SharedAcceptor` - * objects are always created by the {@link SharedWorkerServer} class whenever a remote client - * connects to its server. + * The `SharedWorkerAcceptor` is a communicator class interacting with the + * {@link SharedWorkerConnector} through RFC (Remote Function Call), created by + * the {@link SharedWorkerServer} class whenever a client connects to the + * `SharedWorker` instance. * - * To accept connection and start interaction with the remote client, call the {@link accept} - * method with special `Provider`. After the {@link accept acceptance}, don't forget to closing - * the connection after your business has been completed. Otherwise, you don't want to accept but - * reject the connection, call the {@link reject} method. + * When a remote client connects to the {@link SharedWorkerServer}, + * so that a new `SharedworkerAcceptor` instance being created, you can determine + * whether to {@link accept} the client's connection or {@link reject not}, + * reading the {@link header} property. If you've decided to accept the connection, + * call the {@link accept} method with `Provider` instance. Otherwise, reject it + * thorugh the {@link reject} method. * - * Also, when declaring this {@link SharedWorkerAcceptor} type, you've to define two template - * arguments, *Header* and *Provider*. The *Header* type repersents an initial data gotten from - * the remote client after the connection. + * After {@link accept accepting} the connection, don't forget to + * {@link close closing} the connection after your business has been completed + * to clean up the resources. Otherwise the closing must be performed by the remote + * client, you can wait the remote client's closing signal by the {@link join} method. * - * The second template argument *Provider* represents the features provided for the remote client. - * If you don't have any plan to provide any feature to the remote client, just declare it as - * `null`. + * Also, when declaring this {@link SharedworkerAcceptor} type, you have to define three + * generic arguments; `Header`, `Provider` and `Remote`. Those generic arguments must + * be same with the ones defined in the {@link SharedWorkerServer} class. + * + * For reference, the first `Header` type repersents an initial data from the + * remote client after the connection. I recommend utilize it as an activation tool + * for security enhancement. The second generic argument `Provider` represents a + * provider from server to client, and the other `Remote` means a provider from the + * remote client to server. * * @template Header Type of the header containing initial data. - * @template Provider Type of features provided for the remote system. - * @template Remote Type of features supported by remote system, used for {@link getDriver} function. + * @template Provider Type of features provided for the remote client. + * @template Remote Type of features provided by remote client. * @author Jeongho Nam - https://github.com/samchon */ export class SharedWorkerAcceptor< diff --git a/src/protocols/workers/SharedWorkerConnector.ts b/src/protocols/workers/SharedWorkerConnector.ts index 1c7fd33..a8ee733 100644 --- a/src/protocols/workers/SharedWorkerConnector.ts +++ b/src/protocols/workers/SharedWorkerConnector.ts @@ -13,36 +13,35 @@ import { WebWorkerCompiler } from "./internal/WebWorkerCompiler"; * * - available only in the Web Browser. * - * The `SharedWorkerConnector` is a communicator class, who can connect to an `SharedWorker` - * instance and communicate with it using RFC (Remote Function Call), considering the - * `SharedWorker` as a remote system ({@link WorkerServer}). + * The `SharedWorkerConnector` is a communicator class which connects to an + * `SharedWorker` instance, and interacts with it through RFC (Remote Function Call) + * concept. * - * You can connect to an `SharedWorker` instance with {@link connect}() method. If the - * `SharedWorker` instance does not exist yet, a new `SharedWorker` instance would be newly - * created. After the creation, you have to let the `SharedWorker` program to open a sever - * using the {@link SharedWorkerServer.open}() method. Your connection would be linked with - * a {@link SharedWorkerAcceptor} object in the server. + * You can connect to the {@link SharedWorkerServer} using {@link connect} method. + * The interaction would be started if the server accepts your connection by calling + * the {@link SharedWorkerAcceptor.accept} method. If the remote server rejects your + * connection through {@link SharedWorkerAcceptor.reject} method, the exception + * would be thrown. * - * After your business has been completed, you've to close the `SharedWorker` using one of - * them below. If you don't close that, vulnerable memory usage and communication channel - * would not be destroyed and it may cause the memory leak: + * After the connection, don't forget to {@link closing} the connection, if your + * business logics have been completed, to clean up the resources. Otherwise, the + * closing must be performed by the remote shared worker server, you can wait the + * remote server's closing signal through the {@link join} method. * - * - {@link close}() - * - {@link SharedWorkerAcceptor.close}() - * - {@link SharedWorkerServer.close}() + * Also, when declaring this `SharedWorkerConnector` type, you've to define three + * generic arguments; `Header`, `Provider` and `Remote`. Those generic arguments must + * be same with the ones defined in the target {@link WebSocketServer} and + * {@link SharedWorkerAcceptor} classes (`Provider` and `Remote` must be reversed). * - * Also, when declaring this {@link SharedWorkerConnector} type, you've to define two template - * arguments, *Header* and *Provider*. The *Header* type repersents an initial data gotten from the - * remote client after the connection. - * - * The second template argument *Provider* represents the features provided for the remote system. - * If you don't have any plan to provide any feature to the remote system, just declare it as - * `null`. + * For reference, the first `Header` type repersents an initial data from the + * remote client after the connection. I recommend utilize it as an activation tool + * for security enhancement. The second generic argument `Provider` represents a + * provider from client to server, and the other `Remote` means a provider from the + * remote server to client. * * @template Header Type of the header containing initial data. - * @template Provider Type of features provided for the remote system. - * @template Remote Type of features supported by remote system, used for {@link getDriver} function. - * @author Jeongho Nam - https://github.com/samchon + * @template Provider Type of features provided for the remote server. + * @template Remote Type of features supported by remote server. */ export class SharedWorkerConnector< Header, diff --git a/src/protocols/workers/SharedWorkerServer.ts b/src/protocols/workers/SharedWorkerServer.ts index a2cd119..bf81311 100644 --- a/src/protocols/workers/SharedWorkerServer.ts +++ b/src/protocols/workers/SharedWorkerServer.ts @@ -10,30 +10,29 @@ import { SharedWorkerAcceptor } from "./SharedWorkerAcceptor"; * * - available only in the Web Browser. * - * The `SharedWorkerServer` is a class representing a server server in a `SharedWorker` - * environment. Clients connecting to the `SharedWorkerServer` would communicate with this - * server through {@link SharedWorkerAcceptor} objects using RFC (Remote Function Call). + * The `SharedWorkerServer` is a class representing a server in `SharedWorker` + * environment. Clients connecting to the `SharedWorkerServer` would communicate + * with this server through {@link SharedWorkerAcceptor} instaces using RPC + * (Remote Procedure Call) concept. * - * To open the server, use the {@link open}() method with a callback function which would be - * called whenever a client has been connected. After your business, don't forget to closing - * the connection using one of them below. If you don't close that, vulnerable memory usage - * and communication channel would not be destroyed and it may cause the memory leak. + * To open the server, call the {@link open} method with your callback function + * which would be called whenever a {@link SharedWorkerAcceptor} has been newly + * created by a new client's connection. * - * - {@link close}() - * - {@link SharedWorkerAcceptor.close}() - * - {@link SharedWorkerConnector.close}() + * Also, when declaring this `SharedWorkerServer` type, you have to define three + * generic arguments; `Header`, `Provider` and `Remote`. Those generic arguments + * would be propagated to the {@link SharedWorkerAcceptor}, so that + * {@link SharedWorkerAcceptor} would have the same generic arguments, too. * - * Also, when declaring this {@link SharedWorkerServer} type, you've to define two template - * arguments, *Header* and *Provider*. The *Header* type repersents an initial data gotten from the - * remote client after the connection. + * For reference, the first `Header` type repersents an initial data from the + * remote client after the connection. I recommend utilize it as an activation tool + * for security enhancement. The second generic argument `Provider` represents a + * provider from server to client, and the other `Remote` means a provider from the + * remote client to server. * - * The second template argument *Provider* represents the features provided for the remote client. - * If you don't have any plan to provide any feature to the remote client, just declare it as - * `null`. - * - * @template Header Type of the header containing initial data. - * @template Provider Type of features provided for the remote system. - * @template Remote Type of features supported by remote system, used for {@link getDriver} function. + * @template Header Type of header containing initialization data like activation. + * @template Provider Type of features provided for the remote client. + * @template Remote Type of features provided by remote client. * @author Jeongho Nam - https://github.com/samchon */ export class SharedWorkerServer< @@ -66,14 +65,16 @@ export class SharedWorkerServer< /** * Open shared worker server. * - * Open a server through the shared worker protocol, with *handler* function determining - * whether to accept the client's connection or not. After the server has been opened, clients - * can connect to that websocket server by using the {@link SharedWorkerServer} class. + * Open a server through the shared worker protocol, with *handler* function + * determining whether to accept the client's connection or not. After the server + * has been opened, clients can connect to that server by using the + * {@link SharedWorkerServer} class. * - * When implementing the *handler* function with the {@link SharedWorkerServer} instance, calls - * the {@link SharedWorkerAcceptor.accept} method if you want to accept the new client's - * connection. Otherwise you dont't want to accept the client and reject its connection, just - * calls the {@link SharedWorkerAcceptor.reject} instead. + * When implementing the *handler* function with the {@link SharedWorkerServer} + * instance, calls the {@link SharedWorkerAcceptor.accept} method if you want to + * accept the new client's connection. Otherwise you dont't want to accept the + * client and reject its connection, just calls the + * {@link SharedWorkerAcceptor.reject} instead. * * @param handler Callback function called whenever client connects. */ diff --git a/src/protocols/workers/WorkerConnector.ts b/src/protocols/workers/WorkerConnector.ts index f69b977..c5fc236 100644 --- a/src/protocols/workers/WorkerConnector.ts +++ b/src/protocols/workers/WorkerConnector.ts @@ -12,30 +12,34 @@ import { WebWorkerCompiler } from "./internal/WebWorkerCompiler"; /** * Worker Connector. * - * The `WorkerConnector` is a communicator class, who can create an `Worker` instance and - * communicate with it using RFC (Remote Function Call), considering the `Worker` as a - * remote system ({@link WorkerServer}). + * The `WorkerConnector` is a communicator class, which creates an `Worker` instance + * and interacts with it through RPC (Remote Procedure Call). In other words, + * `WorkerConnector` considers the `Worker` instance as a remote server accepting + * only one client; {@link WorkerServer}. * - * You can create an `Worker` instance with {@link compile}() or {@link connect}() method. - * Anyway, after creation of the `Worker` instance, the `Worker` program must open a server - * using the {@link WorkerServer.open}() method. + * You can create an `Worker` instance with {@link connect} or {@link compile} method. + * The {@link connect} method just opens an existing JS (or TS) file, and + * {@link compile} method writes a temporary JS (TS) file, and connects to it. + * Anyway, the `Worker` instanced program must open the {@link WorkerServer}. * - * Note that, after your business, don't forget terminating the worker using {@link close}() - * or {@link WorkerServer.close}(). If you don't terminate it, then vulnerable memory and - * communication channel would not be destroyed and it may cause the memory leak. + * By the way, don't forget {@link close closing} the worker to clean up the resources. + * If the closing be performed by {@link WorkerServer}, you can wait + * the worker server closing through the {@link join} method. * - * Also, when declaring this {@link WorkerConnector} type, you've to define two template arguments, - * *Header* and *Provider*. The *Header* type repersents an initial data gotten from the remote - * system after the connection. I hope you and server not to omit it and utilize it as an - * activation tool to enhance security. + * Also, when declaring this `WorkerConnector` type, you've to define three + * generic arguments; `Header`, `Provider` and `Remote`. Those generic arguments must + * be same with the ones defined in the target {@link WorkerServer} class + * (`Provider` and `Remote` must be reversed). * - * The second template argument *Provider* represents the features provided for the remote system. - * If you don't have any plan to provide any feature to the remote system, just declare it as - * `null`. + * For reference, the first `Header` type repersents an initial data from the + * remote client after the connection. I recommend utilize it as an activation tool + * for security enhancement. The second generic argument `Provider` represents a + * provider from client to server, and the other `Remote` means a provider from the + * remote server to client. * - * @template Header Type of header containing initialization data like activation. - * @template Provider Type of features provided for remote system. - * @template Remote Type of features supported by remote system, used for {@link getDriver} function. + * @template Header Type of the header containing initial data. + * @template Provider Type of features provided for the remote server. + * @template Remote Type of features supported by remote server. * @author Jeongho Nam - https://github.com/samchon */ export class WorkerConnector< diff --git a/src/protocols/workers/WorkerServer.ts b/src/protocols/workers/WorkerServer.ts index f6cd2b2..9699eb6 100644 --- a/src/protocols/workers/WorkerServer.ts +++ b/src/protocols/workers/WorkerServer.ts @@ -18,31 +18,34 @@ import { ThreadPort } from "./internal/threads/ThreadPort"; /** * Worker Server. * - * The `WorkerServer` is a class representing a `Worker` server who can communicate with - * remote client, parent and creator of the `Worker` (anyway {@link WorkerConnector}), using - * RFC (Remote Function Call). + * The `WorkerServer` is a class representing a `Worker` server which communicate + * with client ({@link WorkerConnector}), through the RPC (Remote Procedure Call). * - * Unlike other servers, `WorkerServer` can accept only a client ({@link WorkerConnector}) - * because the worker is dependent on its parent instance (web page, node or parent worker). - * Thus, `WorkerServer` does not have any acceptor and communicates with client (its parent) - * by itself. + * Unlike other servers, `WorkerServer` can accept only one client + * ({@link WorkerConnector}), because the `Worker` is dependent on its parent instance + * (web page, node or parent worker). Thus, `WorkerServer` does not have any acceptor + * and communicates with client (its parent) directly. * - * To start communication with the remote client, call the {@link open}() method with special - * `Provider`. After your business, don't forget terminating this worker using {@link close}() - * or {@link WorkerConnector.close}() method. If you don't terminate it, then vulnerable - * memory and communication channel would be kept and it may cause the memory leak. + * To start communication with the client, call the {@link open} method + * with `Provider` instance. After your business, don't forget {@link close cosing} + * this `Worker` instance. If the termination is performed by the + * {@link WorkerConnector}, you can wait the closing signal through the + * {@link join} method. * - * Also, when declaring this {@link WorkerServer} type, you've to define two template arguments, - * *Header* and *Provider*. The *Header* type repersents an initial data gotten from the remote - * system after the connection. + * Also, when declaring this `WorkerServer` type, you've to define three + * generic arguments; `Header`, `Provider` and `Remote`. Those generic arguments must + * be same with the ones defined in the target {@link WorkerConnector} class + * (`Provider` and `Remote` must be reversed). * - * The second template argument *Provider* represents the features provided for the remote system. - * If you don't have any plan to provide any feature to the remote system, just declare it as - * `null`. + * For reference, the first `Header` type repersents an initial data from the + * client after the connection. I recommend utilize it as an activation tool + * for security enhancement. The second generic argument `Provider` represents a + * provider from server to client, and the other `Remote` means a provider from the + * client to server. * - * @template Header Type of header containing initialization data like activation. - * @template Provider Type of features provided for remote system. - * @template Remote Type of features supported by remote system, used for {@link getDriver} function. + * @template Header Type of the header containing initial data. + * @template Provider Type of features provided for the client. + * @template Remote Type of features supported by client. * @author Jeongho Nam - https://github.com/samchon */ export class WorkerServer< @@ -99,14 +102,14 @@ export class WorkerServer< /** * Open server with `Provider`. * - * Open worker server and start communication with the remote system + * Open worker server and start communication with the client * ({@link WorkerConnector}). * - * Note that, after your business, you should terminate this worker to prevent waste - * of memory leak. Close this worker by yourself ({@link close}) or let remote client to - * close this worker ({@link WorkerConnector.close}). + * Note that, after your business, you should terminate this worker to prevent + * waste of memory leak. Close this worker by yourself ({@link close}) or let + * client to close this worker ({@link WorkerConnector.close}). * - * @param provider An object providing featrues for the remote system. + * @param provider An object providing featrues for the client. */ public async open(provider: Provider): Promise { // TEST CONDITION diff --git a/website/pages/docs/features/components.mdx b/website/pages/docs/features/components.mdx index e0bbe8b..80a1e7d 100644 --- a/website/pages/docs/features/components.mdx +++ b/website/pages/docs/features/components.mdx @@ -110,20 +110,18 @@ export const webSocketClientMain = async () => { await remote.scientific.sqrt(2); // returns 1.41 await remote.statistics.mean(1, 3, 9); // returns 4.33 - console.log(stack); + console.log(...stack); }; ``` > Execution result: > > ```bash -> [ -> { type: 'plus', input: [ 10, 20 ], output: 30 }, -> { type: 'multiplies', input: [ 3, 4 ], output: 12 }, -> { type: 'divides', input: [ 5, 3 ], output: 1.67 }, -> { type: 'sqrt', input: [ 2 ], output: 1.41 }, -> { type: 'mean', input: [ 1, 3, 9 ], output: 4.33 } -> ] +> { type: 'plus', input: [ 10, 20 ], output: 30 } +> { type: 'multiplies', input: [ 3, 4 ], output: 12 } +> { type: 'divides', input: [ 5, 3 ], output: 1.67 } +> { type: 'sqrt', input: [ 2 ], output: 1.41 } +> { type: 'mean', input: [ 1, 3, 9 ], output: 4.33 } > ``` Driver of Listener for RPC (Remote Procedure Call). diff --git a/website/pages/docs/features/websocket.mdx b/website/pages/docs/features/websocket.mdx index 312d590..fadc972 100644 --- a/website/pages/docs/features/websocket.mdx +++ b/website/pages/docs/features/websocket.mdx @@ -198,7 +198,7 @@ Also, when declaring `WebSocketServer` type, you have to specify three generic a For reference, the first `Header` type repersents an initial data from the remote client after the connection. I recommend utilize it as an activation tool for security enhancement. The second generic argument `Provider` represents a provider from server to client, and the other `Remote` means a provider from the remote client to server. - Above example case: - - `Header`: Nothing + - `Header`: `ICalcConfig` type - `Provider`: Server is providing one of below to the client - `SimpleCalculator` - `StatisticsCalculator` @@ -430,7 +430,8 @@ export const webSocketClientMain = async () => { await remote.scientific.sqrt(2); // returns 1.41 await remote.statistics.mean(1, 3, 9); // returns 4.33 - console.log(stack); + await connector.close(); + console.log(...stack); }; ``` @@ -474,13 +475,11 @@ export interface IStatisticsCalculator { > Execution result: > > ```bash -> [ -> { type: 'plus', input: [ 10, 20 ], output: 30 }, -> { type: 'multiplies', input: [ 3, 4 ], output: 12 }, -> { type: 'divides', input: [ 5, 3 ], output: 1.67 }, -> { type: 'sqrt', input: [ 2 ], output: 1.41 }, -> { type: 'mean', input: [ 1, 3, 9 ], output: 4.33 } -> ] +> { type: 'plus', input: [ 10, 20 ], output: 30 } +> { type: 'multiplies', input: [ 3, 4 ], output: 12 } +> { type: 'divides', input: [ 5, 3 ], output: 1.67 } +> { type: 'sqrt', input: [ 2 ], output: 1.41 } +> { type: 'mean', input: [ 1, 3, 9 ], output: 4.33 } > ``` @@ -500,7 +499,7 @@ Also, when declaring this `WebSocketConnector` type, you've to define three gene For reference, the first `Header` type repersents an initial data from the remote client after the connection. I recommend utilize it as an activation tool for security enhancement. The second generic argument `Provider` represents a provider from client to server, and the other `Remote` means a provider from the remote server to client. - Above example case: - - `Header`: Nothing + - `Header`: `ICalcConfig` type - `Provider`: Client is providing `ICalcEventListener` to the server - `Remote`: Server is providing `ISimpleCalculator` to the client diff --git a/website/pages/docs/features/worker.mdx b/website/pages/docs/features/worker.mdx index f24d2ca..84d1813 100644 --- a/website/pages/docs/features/worker.mdx +++ b/website/pages/docs/features/worker.mdx @@ -1,19 +1,782 @@ import { Callout, Tabs, Tab } from 'nextra-theme-docs' ## Outline -## Dedicated Worker +`TGrid` supports `Worker`/`SharedWorker` protocols. + +With `TGrid`, you can easily develop `Worker` programs under the RPC (Remote Procedure Call) concept. + +`TGrid` considers `Worker` as a 1: 1 dedicated server, and `SharedWorker` as a 1: N multi-client acceptable server running on the local. Therefore, the interfaces of `Worker` and `SharedWorker` in the `TGrid` are similar with [WebSocket components](./websocket). In such reason, if you're developing a complicate WebSocket system, you can simulate it in the local environment by using `Worker`/`SharedWorker` components. + + + + +## Worker Available in both Browser/NodeJS. +You can utilize RPC (Remote Procedure Call) even in the `Worker`. + ### `WorkerConnector` + + +```typescript filename="examples/src/worker/client.ts" showLineNumbers +import { Driver, WorkerConnector } from "tgrid"; + +import { ICalcConfig } from "../interfaces/ICalcConfig"; +import { ICalcEvent } from "../interfaces/ICalcEvent"; +import { ICalcEventListener } from "../interfaces/ICalcEventListener"; +import { ICompositeCalculator } from "../interfaces/ICompositeCalculator"; + +const EXTENSION = __filename.endsWith(".ts") ? "ts" : "js"; + +export const workerClientMain = async () => { + const stack: ICalcEvent[] = []; + const listener: ICalcEventListener = { + on: (evt: ICalcEvent) => stack.push(evt), + }; + const connector: WorkerConnector< + ICalcConfig, + ICalcEventListener, + ICompositeCalculator + > = new WorkerConnector( + { precision: 2 }, // header + listener, // provider for remote server + "process", + ); + await connector.connect(`${__dirname}/server.${EXTENSION}`); + + const remote: Driver = connector.getDriver(); + await remote.plus(10, 20); // returns 30 + await remote.multiplies(3, 4); // returns 12 + await remote.divides(5, 3); // returns 1.67 + await remote.scientific.sqrt(2); // returns 1.41 + await remote.statistics.mean(1, 3, 9); // returns 4.33 + + await connector.close(); + console.log(...stack); +}; +``` + + +```typescript filename="examples/src/interfaces/*.ts" showLineNumbers +export interface ICalcConfig { + precision: number; +} +export interface ICalcEvent { + type: string; + input: number[]; + output: number; +} +export interface ICalcEventListener { + on(event: ICalcEvent): void; +} + +export interface ICompositeCalculator extends ISimpleCalculator { + scientific: IScientificCalculator; + statistics: IStatisticsCalculator; +} +export interface ISimpleCalculator { + plus(x: number, y: number): number; + minus(x: number, y: number): number; + multiplies(x: number, y: number): number; + divides(x: number, y: number): number; +} +export interface IScientificCalculator { + pow(x: number, y: number): number; + sqrt(x: number): number; + log(x: number, base: number): number; +} +export interface IStatisticsCalculator { + mean(...values: number[]): number; + stdev(...values: number[]): number; +} +``` + + + +> Execution result: +> +> ```bash +> { type: 'plus', input: [ 10, 20 ], output: 30 } +> { type: 'multiplies', input: [ 3, 4 ], output: 12 } +> { type: 'divides', input: [ 5, 3 ], output: 1.67 } +> { type: 'sqrt', input: [ 2 ], output: 1.41 } +> { type: 'mean', input: [ 1, 3, 9 ], output: 4.33 } +> ``` + +Worker Connector. + +The `WorkerConnetor` is a [communicator](./components/#communicator) class, which creates an `Worker` instance, and interacts with it through RPC (Remote Procedure Call). In other words, `WorkerConnector` considers the `Worker` instance as a remote server accepting only one client; [`WorkerServer`](#workerserver). + +You can create the `Worker` instance and communicate with it by [`WorkerConnector.connect()`](/api/classes/WorkerConnector-1.html#connect) or [`WorkerConnector.compile()`](/api/classes/WorkerConnector-1.html#compile) method. The [`WorkerConnector.connect()`](/api/classes/WorkerConnector-1.html#connect) method just opens an existing JS (or TS) file, and the [`WorkerConnector.compile()`](/api/classes/WorkerConnector-1.html#compile) method writes a temporary JS (TS) file and connects to it. Anyway, the `Worker` instanced program must open the [`WorkerServer`](#workerserver). + +By the way, don't forget [closing](/api/classes/WorkerConnector-1.html#close) the worker to clean up the resources. If the closing be performed by [`WorkerServer`](#workerserver), you can wait the worker server closing through the [`WorkerConnector.wait()`](/api/classes/WorkerConnector-1.html#wait) method. + +Also, when declaring this `WorkerConnector` type, you've to define three generic arguments; `Header`, `Provider` and `Remote`. Those generic arguments must be same with the ones defined in the target [`WorkerServer`](#workerserver) class (`Provider` and `Remote` must be reversed). + +For reference, the first `Header` type repersents an initial data from the remote client after the connection. I recommend utilize it as an activation tool for security enhancement. The second generic argument `Provider` represents a provider from client to server, and the other `Remote` means a provider from the remote server to client. + + - Above example case: + - `Header`: `ICalcConfig` type + - `Provider`: Client is providing `ICalcEventListener` to the server + - `Remote`: Server is providing `ISimpleCalculator` to the client + ### `WorkerServer` + + +```typescript filename="examples/src/worker/server.ts" showLineNumbers +import { Driver, WorkerServer } from "tgrid"; + +import { ICalcConfig } from "../interfaces/ICalcConfig"; +import { ICalcEventListener } from "../interfaces/ICalcEventListener"; +import { CompositeCalculator } from "../providers/CompositeCalculator"; + +const main = async () => { + const server: WorkerServer< + ICalcConfig, + CompositeCalculator, + ICalcEventListener + > = new WorkerServer(); + + const header: ICalcConfig = await server.getHeader(); + const listener: Driver = server.getDriver(); + const provider: CompositeCalculator = new CompositeCalculator( + header, + listener, + ); + await server.open(provider); +}; +main().catch((exp) => { + console.error(exp); + process.exit(-1); +}); +``` + + +```typescript filename="examples/src/providers/*.ts" showLineNumbers +import { Driver } from "tgrid"; + +import { ICalcConfig } from "../interfaces/ICalcConfig"; +import { ICalcEventListener } from "../interfaces/ICalcEventListener"; +import { ICompositeCalculator } from "../interfaces/ICompositeCalculator"; +import { IScientificCalculator } from "../interfaces/IScientificCalculator"; +import { ISimpleCalculator } from "../interfaces/ISimpleCalculator"; +import { IStatisticsCalculator } from "../interfaces/IStatisticsCalculator"; + +export abstract class CalculatorBase { + public constructor( + private readonly config: ICalcConfig, + private readonly listener: Driver, + ) {} + + protected compute(type: string, input: number[], output: number): number { + const pow: number = Math.pow(10, this.config.precision); + output = Math.round(output * pow) / pow; + this.listener.on({ type, input, output }).catch(() => {}); + return output; + } +} + +export class SimpleCalculator + extends CalculatorBase + implements ISimpleCalculator +{ + public plus(x: number, y: number): number { + return this.compute("plus", [x, y], x + y); + } + public minus(x: number, y: number): number { + return this.compute("minus", [x, y], x - y); + } + public multiplies(x: number, y: number): number { + return this.compute("multiplies", [x, y], x * y); + } + public divides(x: number, y: number): number { + return this.compute("divides", [x, y], x / y); + } +} + +export class ScientificCalculator + extends CalculatorBase + implements IScientificCalculator +{ + public pow(x: number, y: number): number { + return this.compute("pow", [x, y], Math.pow(x, y)); + } + public sqrt(x: number): number { + return this.compute("sqrt", [x], Math.sqrt(x)); + } + public log(x: number, base: number): number { + return this.compute("log", [x, base], Math.log(x) / Math.log(base)); + } +} + +export class StatisticsCalculator + extends CalculatorBase + implements IStatisticsCalculator +{ + public mean(...values: number[]): number { + const sum: number = values.reduce((x, y) => x + y); + return this.compute("mean", values, sum / values.length); + } + public stdev(...values: number[]): number { + const mean: number = values.reduce((x, y) => x + y) / values.length; + const sum: number = values.reduce((x, y) => x + Math.pow(y - mean, 2)); + return this.compute("stdev", values, Math.sqrt(sum / values.length)); + } +} + +export class CompositeCalculator + extends SimpleCalculator + implements ICompositeCalculator +{ + public readonly scientific: ScientificCalculator; + public readonly statistics: StatisticsCalculator; + + public constructor( + config: ICalcConfig, + listener: Driver, + ) { + super(config, listener); + this.scientific = new ScientificCalculator(config, listener); + this.statistics = new StatisticsCalculator(config, listener); + } +} +``` + + +```typescript filename="examples/src/interfaces/*.ts" showLineNumbers +export interface ICalcConfig { + precision: number; +} +export interface ICalcEvent { + type: string; + input: number[]; + output: number; +} +export interface ICalcEventListener { + on(event: ICalcEvent): void; +} + +export interface ICompositeCalculator extends ISimpleCalculator { + scientific: IScientificCalculator; + statistics: IStatisticsCalculator; +} +export interface ISimpleCalculator { + plus(x: number, y: number): number; + minus(x: number, y: number): number; + multiplies(x: number, y: number): number; + divides(x: number, y: number): number; +} +export interface IScientificCalculator { + pow(x: number, y: number): number; + sqrt(x: number): number; + log(x: number, base: number): number; +} +export interface IStatisticsCalculator { + mean(...values: number[]): number; + stdev(...values: number[]): number; +} +``` + + + +Worker Server. + +The `WorkerServer` is a class representing a Worker server which communicate with client ([`WorkerConnector`](#workerconnector)), through the RPC (Remote Procedure Call). + +Unlike other servers, `WorkerServer` can accept only one client ([`WorkerConnector`](#workerconnector)), because the `Worker` is dependent on its parent instance (web page, node or parent worker). Thus, `WorkerServer` does not have any acceptor and communicates with client (its parent) directly. + +To start communication with the client, call the [`WorkerServer.open()`](http://127.0.0.1:3000/api/classes/WorkerServer-1.html#open) method with `Provider` instance. After your business, don't forget closing this Worker instance. If the termination is performed by the [`WorkerConnector`](#workerconnector), you can wait the closing signal through the [`WorkerServer.join()`](http://127.0.0.1:3000/api/classes/WorkerServer-1.html#join) method. + +Also, when declaring this WorkerServer type, you've to define three generic arguments; `Header`, `Provider` and `Remote`. Those generic arguments must be same with the ones defined in the target [`WorkerConnector`](#workerconnector) class (`Provider` and `Remote` must be reversed). + +For reference, the first `Header` type repersents an initial data from the client after the connection. I recommend utilize it as an activation tool for security enhancement. The second generic argument `Provider` represents a provider from server to client, and the other `Remote` means a provider from the client to server. + + - Above example case: + - `Header`: `ICalcConfig` type + - `Provider`: Server is providing `CompositeCalculator` to the client + - `Remote`: Client is providing `ICalcEventListener` to the server + + + ## Shared Worker Available only in the Web Browser. +In the Web Browser, you also can perform RPC (Remote Procedure Call) in the `SharedWorker`. + +Also, as `SharedWorker` can accept multiple clients, `TGrid` considers it as a local server running on the web browser, and its interfaces are similar with [WebSocket components](./websocket). + ### `SharedWorkerServer` + + +```typescript filename="examples/src/shared-worker/server.ts" showLineNumbers +import { Driver, SharedWorkerServer } from "tgrid"; + +import { ICalcConfig } from "../interfaces/ICalcConfig"; +import { ICalcEventListener } from "../interfaces/ICalcEventListener"; +import { CompositeCalculator } from "../providers/CompositeCalculator"; + +const main = async () => { + let pool: number = 0; + const server: SharedWorkerServer< + ICalcConfig, + CompositeCalculator, + ICalcEventListener + > = new SharedWorkerServer(); + await server.open(async (acceptor) => { + // LIST UP PROPERTIES + const config: ICalcConfig = acceptor.header; + const listener: Driver = acceptor.getDriver(); + + // ACCEPT OR REJECT THE CONNECTION + if (pool >= 8) { + await acceptor.reject("Too much connections."); + } else { + await acceptor.accept(new CompositeCalculator(config, listener)); + ++pool; + await acceptor.join(); + --pool; + } + }); +}; +main().catch((exp) => { + console.error(exp); + process.exit(-1); +}); +``` + + +```typescript filename="examples/src/providers/*.ts" showLineNumbers +import { Driver } from "tgrid"; + +import { ICalcConfig } from "../interfaces/ICalcConfig"; +import { ICalcEventListener } from "../interfaces/ICalcEventListener"; +import { ICompositeCalculator } from "../interfaces/ICompositeCalculator"; +import { IScientificCalculator } from "../interfaces/IScientificCalculator"; +import { ISimpleCalculator } from "../interfaces/ISimpleCalculator"; +import { IStatisticsCalculator } from "../interfaces/IStatisticsCalculator"; + +export abstract class CalculatorBase { + public constructor( + private readonly config: ICalcConfig, + private readonly listener: Driver, + ) {} + + protected compute(type: string, input: number[], output: number): number { + const pow: number = Math.pow(10, this.config.precision); + output = Math.round(output * pow) / pow; + this.listener.on({ type, input, output }).catch(() => {}); + return output; + } +} + +export class SimpleCalculator + extends CalculatorBase + implements ISimpleCalculator +{ + public plus(x: number, y: number): number { + return this.compute("plus", [x, y], x + y); + } + public minus(x: number, y: number): number { + return this.compute("minus", [x, y], x - y); + } + public multiplies(x: number, y: number): number { + return this.compute("multiplies", [x, y], x * y); + } + public divides(x: number, y: number): number { + return this.compute("divides", [x, y], x / y); + } +} + +export class ScientificCalculator + extends CalculatorBase + implements IScientificCalculator +{ + public pow(x: number, y: number): number { + return this.compute("pow", [x, y], Math.pow(x, y)); + } + public sqrt(x: number): number { + return this.compute("sqrt", [x], Math.sqrt(x)); + } + public log(x: number, base: number): number { + return this.compute("log", [x, base], Math.log(x) / Math.log(base)); + } +} + +export class StatisticsCalculator + extends CalculatorBase + implements IStatisticsCalculator +{ + public mean(...values: number[]): number { + const sum: number = values.reduce((x, y) => x + y); + return this.compute("mean", values, sum / values.length); + } + public stdev(...values: number[]): number { + const mean: number = values.reduce((x, y) => x + y) / values.length; + const sum: number = values.reduce((x, y) => x + Math.pow(y - mean, 2)); + return this.compute("stdev", values, Math.sqrt(sum / values.length)); + } +} + +export class CompositeCalculator + extends SimpleCalculator + implements ICompositeCalculator +{ + public readonly scientific: ScientificCalculator; + public readonly statistics: StatisticsCalculator; + + public constructor( + config: ICalcConfig, + listener: Driver, + ) { + super(config, listener); + this.scientific = new ScientificCalculator(config, listener); + this.statistics = new StatisticsCalculator(config, listener); + } +} +``` + + +```typescript filename="examples/src/interfaces/*.ts" showLineNumbers +export interface ICalcConfig { + precision: number; +} +export interface ICalcEvent { + type: string; + input: number[]; + output: number; +} +export interface ICalcEventListener { + on(event: ICalcEvent): void; +} + +export interface ICompositeCalculator extends ISimpleCalculator { + scientific: IScientificCalculator; + statistics: IStatisticsCalculator; +} +export interface ISimpleCalculator { + plus(x: number, y: number): number; + minus(x: number, y: number): number; + multiplies(x: number, y: number): number; + divides(x: number, y: number): number; +} +export interface IScientificCalculator { + pow(x: number, y: number): number; + sqrt(x: number): number; + log(x: number, base: number): number; +} +export interface IStatisticsCalculator { + mean(...values: number[]): number; + stdev(...values: number[]): number; +} +``` + + + +Shared Worker Server. + +The `SharedWorkerServer` is a class representing a server in `SharedWorker` environment. Clients connecting to the `SharedWorkerServer` would communicate with this server through [`SharedWorkerAcceptor`](#sharedworkeracceptor) instaces using RPC (Remote Procedure Call) concept. + +To open the server, call the [`SharedWorkerServer.open()`](/api/classes/SharedWorkerServer-1.html#open) method with your callback function which would be called whenever a [`SharedWorkerAcceptor`](#sharedworkeracceptor) has been newly created by a new client's connection. + +Also, when declaring this `SharedWorkerServer` type, you have to define three generic arguments; `Header`, `Provider` and `Remote`. Those generic arguments would be propagated to the [`SharedWorkerAcceptor`](#sharedworkeracceptor), so that [`SharedWorkerAcceptor`](#sharedworkeracceptor) would have the same generic arguments, too. + +For reference, the first `Header` type repersents an initial data from the remote client after the connection. I recommend utilize it as an activation tool for security enhancement. The second generic argument `Provider` represents a provider from server to client, and the other `Remote` means a provider from the remote client to server. + + - Above example case: + - `Header`: `ICalcConfig` type + - `Provider`: Server is providing `CompositeCalculator` to the client + - `Remote`: Client is providing `ICalcEventListener` to the server + ### `SharedWorkerAcceptor` -### `SharedWorkerConnector` \ No newline at end of file + + +```typescript filename="examples/src/shared-worker/server.ts" showLineNumbers {15-35} +import { Driver, SharedWorkerAcceptor, SharedWorkerServer } from "tgrid"; + +import { ICalcConfig } from "../interfaces/ICalcConfig"; +import { ICalcEventListener } from "../interfaces/ICalcEventListener"; +import { CompositeCalculator } from "../providers/CompositeCalculator"; + +const main = async () => { + let pool: number = 0; + const server: SharedWorkerServer< + ICalcConfig, + CompositeCalculator, + ICalcEventListener + > = new SharedWorkerServer(); + await server.open( + async ( + acceptor: SharedWorkerAcceptor< + ICalcConfig, + CompositeCalculator, + ICalcEventListener + >, + ) => { + // LIST UP PROPERTIES + const config: ICalcConfig = acceptor.header; + const listener: Driver = acceptor.getDriver(); + + // ACCEPT OR REJECT THE CONNECTION + if (pool >= 8) { + await acceptor.reject("Too much connections."); + } else { + await acceptor.accept(new CompositeCalculator(config, listener)); + ++pool; + await acceptor.join(); + --pool; + } + }, + ); +}; +main().catch((exp) => { + console.error(exp); + process.exit(-1); +}); +``` + + +```typescript filename="examples/src/providers/*.ts" showLineNumbers +import { Driver } from "tgrid"; + +import { ICalcConfig } from "../interfaces/ICalcConfig"; +import { ICalcEventListener } from "../interfaces/ICalcEventListener"; +import { ICompositeCalculator } from "../interfaces/ICompositeCalculator"; +import { IScientificCalculator } from "../interfaces/IScientificCalculator"; +import { ISimpleCalculator } from "../interfaces/ISimpleCalculator"; +import { IStatisticsCalculator } from "../interfaces/IStatisticsCalculator"; + +export abstract class CalculatorBase { + public constructor( + private readonly config: ICalcConfig, + private readonly listener: Driver, + ) {} + + protected compute(type: string, input: number[], output: number): number { + const pow: number = Math.pow(10, this.config.precision); + output = Math.round(output * pow) / pow; + this.listener.on({ type, input, output }).catch(() => {}); + return output; + } +} + +export class SimpleCalculator + extends CalculatorBase + implements ISimpleCalculator +{ + public plus(x: number, y: number): number { + return this.compute("plus", [x, y], x + y); + } + public minus(x: number, y: number): number { + return this.compute("minus", [x, y], x - y); + } + public multiplies(x: number, y: number): number { + return this.compute("multiplies", [x, y], x * y); + } + public divides(x: number, y: number): number { + return this.compute("divides", [x, y], x / y); + } +} + +export class ScientificCalculator + extends CalculatorBase + implements IScientificCalculator +{ + public pow(x: number, y: number): number { + return this.compute("pow", [x, y], Math.pow(x, y)); + } + public sqrt(x: number): number { + return this.compute("sqrt", [x], Math.sqrt(x)); + } + public log(x: number, base: number): number { + return this.compute("log", [x, base], Math.log(x) / Math.log(base)); + } +} + +export class StatisticsCalculator + extends CalculatorBase + implements IStatisticsCalculator +{ + public mean(...values: number[]): number { + const sum: number = values.reduce((x, y) => x + y); + return this.compute("mean", values, sum / values.length); + } + public stdev(...values: number[]): number { + const mean: number = values.reduce((x, y) => x + y) / values.length; + const sum: number = values.reduce((x, y) => x + Math.pow(y - mean, 2)); + return this.compute("stdev", values, Math.sqrt(sum / values.length)); + } +} + +export class CompositeCalculator + extends SimpleCalculator + implements ICompositeCalculator +{ + public readonly scientific: ScientificCalculator; + public readonly statistics: StatisticsCalculator; + + public constructor( + config: ICalcConfig, + listener: Driver, + ) { + super(config, listener); + this.scientific = new ScientificCalculator(config, listener); + this.statistics = new StatisticsCalculator(config, listener); + } +} +``` + + +```typescript filename="examples/src/interfaces/*.ts" showLineNumbers +export interface ICalcConfig { + precision: number; +} +export interface ICalcEvent { + type: string; + input: number[]; + output: number; +} +export interface ICalcEventListener { + on(event: ICalcEvent): void; +} + +export interface ICompositeCalculator extends ISimpleCalculator { + scientific: IScientificCalculator; + statistics: IStatisticsCalculator; +} +export interface ISimpleCalculator { + plus(x: number, y: number): number; + minus(x: number, y: number): number; + multiplies(x: number, y: number): number; + divides(x: number, y: number): number; +} +export interface IScientificCalculator { + pow(x: number, y: number): number; + sqrt(x: number): number; + log(x: number, base: number): number; +} +export interface IStatisticsCalculator { + mean(...values: number[]): number; + stdev(...values: number[]): number; +} +``` + + + +Shared Worker Acceptor. + +The `SharedWorkerAcceptor` is a [communicator](./components/#communicator) class interacting with the [`SharedWorkerConnector`](#sharedworkerconnector) through RFC (Remote Function Call), created by the [`SharedWorkerServer`](#sharedworkerserver) class whenever a client connects to the `SharedWorker` instance. + +When a remote client connects to the [`SharedWorkerServer`](#sharedworkerserver), so that a new `SharedworkerAcceptor` instance being created, you can determine whether to accept the client's connection or not, reading the [`SharedWorkerAcceptor.header`](/api/classes/SharedWorkerAcceptor-1.html#header-1) property. If you've decided to accept the connection, call the [`SharedWorkerAcceptor.accept()`](/api/classes/SharedWorkerAcceptor-1.html#accept) method with Provider instance. Otherwise, reject it thorugh the [`SharedWorkerAcceptor.reject()`](/api/classes/SharedWorkerAcceptor-1.html#reject) method. + +After [accepting](/api/classes/SharedWorkerAcceptor-1.html#accept) the connection, don't forget to [closing](/api/classes/SharedWorkerAcceptor-1.html#close) the connection after your business has been completed to clean up the resources. Otherwise the closing must be performed by the remote client, you can wait the remote client's closing signal by the [`SharedWorkerAcceptor.join()`](/api/classes/SharedWorkerAcceptor-1.html#accept) method. + +Also, when declaring this `SharedworkerAcceptor` type, you have to define three generic arguments; `Header`, `Provider` and `Remote`. Those generic arguments must be same with the ones defined in the [`SharedWorkerServer`](#sharedworkerserver) class. + +For reference, the first `Header` type repersents an initial data from the remote client after the connection. I recommend utilize it as an activation tool for security enhancement. The second generic argument `Provider` represents a provider from server to client, and the other `Remote` means a provider from the remote client to server. + +### `SharedWorkerConnector` + + +```typescript filename="examples/src/shared-worker/client.ts" showLineNumbers +import { Driver, SharedWorkerConnector } from "tgrid"; + +import { ICalcConfig } from "../interfaces/ICalcConfig"; +import { ICalcEvent } from "../interfaces/ICalcEvent"; +import { ICalcEventListener } from "../interfaces/ICalcEventListener"; +import { ICompositeCalculator } from "../interfaces/ICompositeCalculator"; + +export const sharedWorkerClientMain = async () => { + const stack: ICalcEvent[] = []; + const listener: ICalcEventListener = { + on: (evt: ICalcEvent) => stack.push(evt), + }; + const connector: SharedWorkerConnector< + ICalcConfig, + ICalcEventListener, + ICompositeCalculator + > = new SharedWorkerConnector( + { precision: 2 }, // header + listener, // provider for remote server + ); + await connector.connect("./server.js"); + + const remote: Driver = connector.getDriver(); + await remote.plus(10, 20); // returns 30 + await remote.multiplies(3, 4); // returns 12 + await remote.divides(5, 3); // returns 1.67 + await remote.scientific.sqrt(2); // returns 1.41 + await remote.statistics.mean(1, 3, 9); // returns 4.33 + + await connector.close(); + console.log(...stack); +}; +``` + + +```typescript filename="examples/src/interfaces/*.ts" showLineNumbers +export interface ICalcConfig { + precision: number; +} +export interface ICalcEvent { + type: string; + input: number[]; + output: number; +} +export interface ICalcEventListener { + on(event: ICalcEvent): void; +} + +export interface ICompositeCalculator extends ISimpleCalculator { + scientific: IScientificCalculator; + statistics: IStatisticsCalculator; +} +export interface ISimpleCalculator { + plus(x: number, y: number): number; + minus(x: number, y: number): number; + multiplies(x: number, y: number): number; + divides(x: number, y: number): number; +} +export interface IScientificCalculator { + pow(x: number, y: number): number; + sqrt(x: number): number; + log(x: number, base: number): number; +} +export interface IStatisticsCalculator { + mean(...values: number[]): number; + stdev(...values: number[]): number; +} +``` + + + +> Execution result: +> +> ```bash +> { type: 'plus', input: [ 10, 20 ], output: 30 } +> { type: 'multiplies', input: [ 3, 4 ], output: 12 } +> { type: 'divides', input: [ 5, 3 ], output: 1.67 } +> { type: 'sqrt', input: [ 2 ], output: 1.41 } +> { type: 'mean', input: [ 1, 3, 9 ], output: 4.33 } +> ``` + +Shared Worker Connector. + +The `SharedWorkerConnector` is a [communicator](./components/#communicator) class which connects to an `SharedWorker` instance, and interacts with it through RFC (Remote Function Call) concept. + +You can connect to the [`SharedWorkerServer`](#sharedworkerserver) using [`SharedWorkerConnector.connect()`](/api/classes/SharedWorkerConnector-1.html#connect) method. The interaction would be started if the server accepts your connection by calling the [`SharedWorkerAcceptor.accept()`](/api/classes/SharedWorkerAcceptor-1.html#accept) method. If the remote server rejects your connection through [`SharedWorkerAcceptor.reject()`](/api/classes/SharedWorkerAcceptor-1.html#reject) method, the exception would be thrown. + +After the connection, don't forget to [closing](/api/classes/SharedWorkerConnector-1.html#close) the connection, if your business logics have been completed, to clean up the resources. Otherwise, the closing must be performed by the remote shared worker server, you can wait the remote server's closing signal through the [`SharedWorkerConnector.join()`](/api/classes/SharedWorkerConnector-1.html#join) method. + +Also, when declaring this `SharedWorkerConnector` type, you've to define three generic arguments; `Header`, `Provider` and `Remote`. Those generic arguments must be same with the ones defined in the target [`SharedWorkerServer`](#sharedworkerserver) and [`SharedWorkerAcceptor`](#sharedworkeracceptor) classes (Provider and `Remote` must be reversed). + +For reference, the first `Header` type repersents an initial data from the remote client after the connection. I recommend utilize it as an activation tool for security enhancement. The second generic argument `Provider` represents a provider from client to server, and the other `Remote` means a provider from the remote server to client. + + - Above example case: + - `Header`: `ICalcConfig` type + - `Provider`: Client is providing `ICalcEventListener` to the server + - `Remote`: Server is providing `ISimpleCalculator` to the client \ No newline at end of file diff --git a/website/pages/docs/index.mdx b/website/pages/docs/index.mdx index 8c4f72d..f78d9f4 100644 --- a/website/pages/docs/index.mdx +++ b/website/pages/docs/index.mdx @@ -40,29 +40,47 @@ TypeScript RPC (Remote Procedure Call) framework for WebSocket and Worker protoc Also, extremely easy even when composing complicated network system like grid computing. -```typescript filename="examples/web-socket-client.ts" showLineNumbers +```typescript filename="examples/websocket/client.ts" showLineNumbers import { Driver, WebSocketConnector } from "tgrid"; -import { ICalculator } from "./interfaces/ICalculator"; -import { CalcEventListener } from "./providers/CalcEventListener"; +import { ICalcConfig } from "../interfaces/ICalcConfig"; +import { ICalcEvent } from "../interfaces/ICalcEvent"; +import { ICalcEventListener } from "../interfaces/ICalcEventListener"; +import { ICompositeCalculator } from "../interfaces/ICompositeCalculator"; -export const main = async (): Promise => { - // CONNECT TO WEBSOCKET SERVER +export const webSocketClientMain = async () => { + const stack: ICalcEvent[] = []; + const listener: ICalcEventListener = { + on: (evt: ICalcEvent) => stack.push(evt), + }; const connector: WebSocketConnector< - null, // header - CalcEventListener, // provider for remote server - ICalculator, // provider from remote server - > = new WebSocketConnector(null, new CalcEventListener()); - await connector.connect("ws://127.0.0.1:443/calculator"); - - // RPC (YOU CAN CALL REMOTE PROCEDURES) - const calc: Driver = connector.getDriver(); - console.log( - await calc.plus(2, 3), - await calc.minus(7, 1), - await calc.multiplies(3, 4), - await calc.divides(9, 3), + ICalcConfig, + ICalcEventListener, + ICompositeCalculator + > = new WebSocketConnector( + { precision: 2 }, // header + listener, // provider for remote server ); + await connector.connect("ws://127.0.0.1:37000/composite"); + + const remote: Driver = connector.getDriver(); + await remote.plus(10, 20); // returns 30 + await remote.multiplies(3, 4); // returns 12 + await remote.divides(5, 3); // returns 1.67 + await remote.scientific.sqrt(2); // returns 1.41 + await remote.statistics.mean(1, 3, 9); // returns 4.33 + await connector.close(); + console.log(stack); }; ``` + +> Execution result: +> +> ```bash +> { type: 'plus', input: [ 10, 20 ], output: 30 } +> { type: 'multiplies', input: [ 3, 4 ], output: 12 } +> { type: 'divides', input: [ 5, 3 ], output: 1.67 } +> { type: 'sqrt', input: [ 2 ], output: 1.41 } +> { type: 'mean', input: [ 1, 3, 9 ], output: 4.33 } +> ``` diff --git a/website/public/api/assets/highlight.css b/website/public/api/assets/highlight.css index d8f17e9..46ece49 100644 --- a/website/public/api/assets/highlight.css +++ b/website/public/api/assets/highlight.css @@ -11,14 +11,14 @@ --dark-hl-4: #569CD6; --light-hl-5: #795E26; --dark-hl-5: #DCDCAA; - --light-hl-6: #267F99; - --dark-hl-6: #4EC9B0; - --light-hl-7: #008000; - --dark-hl-7: #6A9955; - --light-hl-8: #0070C1; - --dark-hl-8: #4FC1FF; - --light-hl-9: #098658; - --dark-hl-9: #B5CEA8; + --light-hl-6: #0070C1; + --dark-hl-6: #4FC1FF; + --light-hl-7: #267F99; + --dark-hl-7: #4EC9B0; + --light-hl-8: #098658; + --dark-hl-8: #B5CEA8; + --light-hl-9: #008000; + --dark-hl-9: #6A9955; --light-code-background: #FFFFFF; --dark-code-background: #1E1E1E; } diff --git a/website/public/api/classes/Communicator.html b/website/public/api/classes/Communicator.html index a52f2bf..5aac8e4 100644 --- a/website/public/api/classes/Communicator.html +++ b/website/public/api/classes/Communicator.html @@ -12,7 +12,7 @@

Author

Jeongho Nam - https://github.com/samchon

Type Parameters

  • Provider extends object | null | undefined

    Type of features provided for remote system.

  • Remote extends object | null

    Type of features supported by remote system, used for getDriver function.

    -

Hierarchy (view full)

Constructors

Hierarchy (view full)

Constructors

Methods

Constructors

Methods

  • Destory the communicator.

    +

Returns Communicator<Provider, Remote>

Methods

  • Destory the communicator.

    A destory function must be called when the network communication has been closed. It would destroy all function calls in the remote system (by Driver<Controller>), which are not returned yet.

    The error instance would be thrown to those function calls. If the disconnection is abnormal, then write the detailed reason why into the error instance.

    Parameters

    • Optional error: Error

      An error instance to be thrown to the unreturned functions.

      -

    Returns Promise<void>

Returns Promise<void>

  • Get Driver for RFC (Remote Function Call).

    The Controller is an interface who defines provided functions from the remote system. The Driver is an object who makes to call remote functions, defined in the Controller and provided by Provider in the remote system, possible.

    @@ -43,30 +43,30 @@

    Type Parameters

    • Controller extends object = NonNullable<Remote>

      An interface for provided features (functions & objects) from the remote system (Provider).

    • UseParametric extends boolean = false

      Whether to convert type of function parameters to be compatible with their pritimive.

    Returns Driver<Controller, UseParametric>

    A Driver for the RFC.

    -
  • Get current Provider.

    Get an object providing features (functions & objects) for remote system. The remote system would call the features (Provider) by using its Driver<Controller>.

    Returns Provider

    Current Provider object

    -
  • A predicator inspects whether the network communication is on ready.

    Parameters

    • method: string

      The method name for tracing.

      -

    Returns null | Error

  • Join connection.

    +

Returns null | Error

  • Join connection.

    Wait until the connection to be closed.

    -

    Returns Promise<void>

  • Join connection or timeout.

    +

    Returns Promise<void>

  • Join connection or timeout.

    Wait until the connection to be clsoed until timeout.

    Parameters

    • ms: number

      The maximum milliseconds for joining.

    Returns Promise<boolean>

    Whether awaken by disconnection or timeout.

    -
  • Join connection or time expiration.

    +
  • Join connection or time expiration.

    Wait until the connection to be closed until time expiration.

    Parameters

    • at: Date

      The maximum time point to join.

    Returns Promise<boolean>

    Whether awaken by disconnection or time expiration.

    -
  • Data Reply Function.

    A function should be called when data has come from the remote system.

    When you receive a message from the remote system, then parse the message with your special protocol and covert it to be an Invoke object. After the conversion, call this method.

    Parameters

    • invoke: Invoke

      Structured data converted by your special protocol.

      -

    Returns void

  • A function sending data to the remote system.

    +

Returns void

  • Set Provider

    +

Returns Promise<void>

\ No newline at end of file +

Returns void

\ No newline at end of file diff --git a/website/public/api/classes/SharedWorkerAcceptor-1.html b/website/public/api/classes/SharedWorkerAcceptor-1.html index c449361..8a19f73 100644 --- a/website/public/api/classes/SharedWorkerAcceptor-1.html +++ b/website/public/api/classes/SharedWorkerAcceptor-1.html @@ -2,25 +2,33 @@
  • available only in the Web Browser.
-

The SharedWorkerAcceptor is a communicator class communicating with the remote client -(SharedWorkerConnector) using RFC (Remote Function Call). The SharedAcceptor -objects are always created by the SharedWorkerServer class whenever a remote client -connects to its server.

-

To accept connection and start interaction with the remote client, call the accept -method with special Provider. After the acceptance, don't forget to closing -the connection after your business has been completed. Otherwise, you don't want to accept but -reject the connection, call the reject method.

-

Also, when declaring this SharedWorkerAcceptor type, you've to define two template -arguments, Header and Provider. The Header type repersents an initial data gotten from -the remote client after the connection.

-

The second template argument Provider represents the features provided for the remote client. -If you don't have any plan to provide any feature to the remote client, just declare it as -null.

+

The SharedWorkerAcceptor is a communicator class interacting with the +SharedWorkerConnector through RFC (Remote Function Call), created by +the SharedWorkerServer class whenever a client connects to the +SharedWorker instance.

+

When a remote client connects to the SharedWorkerServer, +so that a new SharedworkerAcceptor instance being created, you can determine +whether to accept the client's connection or not, +reading the header property. If you've decided to accept the connection, +call the accept method with Provider instance. Otherwise, reject it +thorugh the reject method.

+

After accepting the connection, don't forget to +closing the connection after your business has been completed +to clean up the resources. Otherwise the closing must be performed by the remote +client, you can wait the remote client's closing signal by the join method.

+

Also, when declaring this SharedworkerAcceptor type, you have to define three +generic arguments; Header, Provider and Remote. Those generic arguments must +be same with the ones defined in the SharedWorkerServer class.

+

For reference, the first Header type repersents an initial data from the +remote client after the connection. I recommend utilize it as an activation tool +for security enhancement. The second generic argument Provider represents a +provider from server to client, and the other Remote means a provider from the +remote client to server.

Author

Jeongho Nam - https://github.com/samchon

Type Parameters

  • Header

    Type of the header containing initial data.

    -
  • Provider extends object | null

    Type of features provided for the remote system.

    -
  • Remote extends object | null

    Type of features supported by remote system, used for getDriver function.

    -

Hierarchy

Implements

  • IWorkerSystem

Accessors

  • Provider extends object | null

    Type of features provided for the remote client.

    +
  • Remote extends object | null

    Type of features provided by remote client.

    +
  • Hierarchy

    Implements

    • IWorkerSystem

    Accessors

    Methods

    accept close @@ -32,7 +40,7 @@ replyData setProvider

    Accessors

    Methods

    Methods

    • Destory the communicator.

      A destory function must be called when the network communication has been closed. It would destroy all function calls in the remote system (by Driver<Controller>), which are not returned yet.

      The error instance would be thrown to those function calls. If the disconnection is abnormal, then write the detailed reason why into the error instance.

      Parameters

      • Optional error: Error

        An error instance to be thrown to the unreturned functions.

        -

      Returns Promise<void>

    Returns Promise<void>

    • Get Driver for RFC (Remote Function Call).

      The Controller is an interface who defines provided functions from the remote system. The Driver is an object who makes to call remote functions, defined in the Controller and provided by Provider in the remote system, possible.

      @@ -63,29 +71,29 @@

      Type Parameters

      • Controller extends object = NonNullable<Remote>

        An interface for provided features (functions & objects) from the remote system (Provider).

      • UseParametric extends boolean = false

        Whether to convert type of function parameters to be compatible with their pritimive.

      Returns Driver<Controller, UseParametric>

      A Driver for the RFC.

      -
    • Get current Provider.

      Get an object providing features (functions & objects) for remote system. The remote system would call the features (Provider) by using its Driver<Controller>.

      Returns undefined | Provider

      Current Provider object

      -
    • Join connection.

      Wait until the connection to be closed.

      -

      Returns Promise<void>

    • Join connection or timeout.

      +

      Returns Promise<void>

    • Join connection or timeout.

      Wait until the connection to be clsoed until timeout.

      Parameters

      • ms: number

        The maximum milliseconds for joining.

      Returns Promise<boolean>

      Whether awaken by disconnection or timeout.

      -
    • Join connection or time expiration.

      +
    • Join connection or time expiration.

      Wait until the connection to be closed until time expiration.

      Parameters

      • at: Date

        The maximum time point to join.

      Returns Promise<boolean>

      Whether awaken by disconnection or time expiration.

      -
    • Reject connection.

      Reject without acceptance, any interaction. The connection would be closed immediately.

      Parameters

      • reason: string = "Rejected by server"

        Detailed reason of the rejection. Default is "Rejected by server".

        -

      Returns Promise<void>

    • Data Reply Function.

      +

    Returns Promise<void>

    • Data Reply Function.

      A function should be called when data has come from the remote system.

      When you receive a message from the remote system, then parse the message with your special protocol and covert it to be an Invoke object. After the conversion, call this method.

      Parameters

      • invoke: Invoke

        Structured data converted by your special protocol.

        -

      Returns void

    • Set Provider

      +

    Returns void

    • Set Provider

      Parameters

      • obj: undefined | Provider

        An object would be provided for remote system.

        -

      Returns void

    \ No newline at end of file +

    Returns void

    \ No newline at end of file diff --git a/website/public/api/classes/SharedWorkerConnector-1.html b/website/public/api/classes/SharedWorkerConnector-1.html index 379cc0a..b5c8c3c 100644 --- a/website/public/api/classes/SharedWorkerConnector-1.html +++ b/website/public/api/classes/SharedWorkerConnector-1.html @@ -2,33 +2,31 @@
    • available only in the Web Browser.
    -

    The SharedWorkerConnector is a communicator class, who can connect to an SharedWorker -instance and communicate with it using RFC (Remote Function Call), considering the -SharedWorker as a remote system (WorkerServer).

    -

    You can connect to an SharedWorker instance with connect() method. If the -SharedWorker instance does not exist yet, a new SharedWorker instance would be newly -created. After the creation, you have to let the SharedWorker program to open a sever -using the SharedWorkerServer.open() method. Your connection would be linked with -a SharedWorkerAcceptor object in the server.

    -

    After your business has been completed, you've to close the SharedWorker using one of -them below. If you don't close that, vulnerable memory usage and communication channel -would not be destroyed and it may cause the memory leak:

    - -

    Also, when declaring this SharedWorkerConnector type, you've to define two template -arguments, Header and Provider. The Header type repersents an initial data gotten from the -remote client after the connection.

    -

    The second template argument Provider represents the features provided for the remote system. -If you don't have any plan to provide any feature to the remote system, just declare it as -null.

    -

    Author

    Jeongho Nam - https://github.com/samchon

    -

    Type Parameters

    • Header

      Type of the header containing initial data.

      -
    • Provider extends object | null

      Type of features provided for the remote system.

      -
    • Remote extends object | null

      Type of features supported by remote system, used for getDriver function.

      -

    Hierarchy

    Implements

    • IWorkerSystem

    Constructors

    constructor +

    The SharedWorkerConnector is a communicator class which connects to an +SharedWorker instance, and interacts with it through RFC (Remote Function Call) +concept.

    +

    You can connect to the SharedWorkerServer using connect method. +The interaction would be started if the server accepts your connection by calling +the SharedWorkerAcceptor.accept method. If the remote server rejects your +connection through SharedWorkerAcceptor.reject method, the exception +would be thrown.

    +

    After the connection, don't forget to closing the connection, if your +business logics have been completed, to clean up the resources. Otherwise, the +closing must be performed by the remote shared worker server, you can wait the +remote server's closing signal through the join method.

    +

    Also, when declaring this SharedWorkerConnector type, you've to define three +generic arguments; Header, Provider and Remote. Those generic arguments must +be same with the ones defined in the target WebSocketServer and +SharedWorkerAcceptor classes (Provider and Remote must be reversed).

    +

    For reference, the first Header type repersents an initial data from the +remote client after the connection. I recommend utilize it as an activation tool +for security enhancement. The second generic argument Provider represents a +provider from client to server, and the other Remote means a provider from the +remote server to client.

    +

    Type Parameters

    • Header

      Type of the header containing initial data.

      +
    • Provider extends object | null

      Type of features provided for the remote server.

      +
    • Remote extends object | null

      Type of features supported by remote server.

      +

    Hierarchy

    Implements

    • IWorkerSystem

    Constructors

    Accessors

    Methods

    close @@ -42,8 +40,8 @@

    Constructors

    Accessors

    Returns SharedWorkerConnector<Header, Provider, Remote>

    Accessors

    Methods

    Methods

    • Connect to remote server.

      The connect() method tries to connect an SharedWorker instance. If the SharedWorker instance is not created yet, the SharedWorker instance would be newly created. After the creation, the SharedWorker program must open that server using @@ -68,14 +66,14 @@

    Parameters

    Returns Promise<void>

    • Destory the communicator.

      +

    Returns Promise<void>

    • Destory the communicator.

      A destory function must be called when the network communication has been closed. It would destroy all function calls in the remote system (by Driver<Controller>), which are not returned yet.

      The error instance would be thrown to those function calls. If the disconnection is abnormal, then write the detailed reason why into the error instance.

      Parameters

      • Optional error: Error

        An error instance to be thrown to the unreturned functions.

        -

      Returns Promise<void>

    Returns Promise<void>

    • Get Driver for RFC (Remote Function Call).

      The Controller is an interface who defines provided functions from the remote system. The Driver is an object who makes to call remote functions, defined in the Controller and provided by Provider in the remote system, possible.

      @@ -88,26 +86,26 @@

      Type Parameters

      • Controller extends object = NonNullable<Remote>

        An interface for provided features (functions & objects) from the remote system (Provider).

      • UseParametric extends boolean = false

        Whether to convert type of function parameters to be compatible with their pritimive.

      Returns Driver<Controller, UseParametric>

      A Driver for the RFC.

      -
    • Get current Provider.

      Get an object providing features (functions & objects) for remote system. The remote system would call the features (Provider) by using its Driver<Controller>.

      Returns Provider

      Current Provider object

      -
    • Join connection.

      Wait until the connection to be closed.

      -

      Returns Promise<void>

    • Join connection or timeout.

      +

      Returns Promise<void>

    • Join connection or timeout.

      Wait until the connection to be clsoed until timeout.

      Parameters

      • ms: number

        The maximum milliseconds for joining.

      Returns Promise<boolean>

      Whether awaken by disconnection or timeout.

      -
    • Join connection or time expiration.

      +
    • Join connection or time expiration.

      Wait until the connection to be closed until time expiration.

      Parameters

      • at: Date

        The maximum time point to join.

      Returns Promise<boolean>

      Whether awaken by disconnection or time expiration.

      -
    • Data Reply Function.

      A function should be called when data has come from the remote system.

      When you receive a message from the remote system, then parse the message with your special protocol and covert it to be an Invoke object. After the conversion, call this method.

      Parameters

      • invoke: Invoke

        Structured data converted by your special protocol.

        -

      Returns void

    • Set Provider

      +

    Returns void

    \ No newline at end of file +

    Returns void

    \ No newline at end of file diff --git a/website/public/api/classes/SharedWorkerServer-1.html b/website/public/api/classes/SharedWorkerServer-1.html index 3267884..a887888 100644 --- a/website/public/api/classes/SharedWorkerServer-1.html +++ b/website/public/api/classes/SharedWorkerServer-1.html @@ -2,34 +2,32 @@
    • available only in the Web Browser.
    -

    The SharedWorkerServer is a class representing a server server in a SharedWorker -environment. Clients connecting to the SharedWorkerServer would communicate with this -server through SharedWorkerAcceptor objects using RFC (Remote Function Call).

    -

    To open the server, use the open() method with a callback function which would be -called whenever a client has been connected. After your business, don't forget to closing -the connection using one of them below. If you don't close that, vulnerable memory usage -and communication channel would not be destroyed and it may cause the memory leak.

    - -

    Also, when declaring this SharedWorkerServer type, you've to define two template -arguments, Header and Provider. The Header type repersents an initial data gotten from the -remote client after the connection.

    -

    The second template argument Provider represents the features provided for the remote client. -If you don't have any plan to provide any feature to the remote client, just declare it as -null.

    +

    The SharedWorkerServer is a class representing a server in SharedWorker +environment. Clients connecting to the SharedWorkerServer would communicate +with this server through SharedWorkerAcceptor instaces using RPC +(Remote Procedure Call) concept.

    +

    To open the server, call the open method with your callback function +which would be called whenever a SharedWorkerAcceptor has been newly +created by a new client's connection.

    +

    Also, when declaring this SharedWorkerServer type, you have to define three +generic arguments; Header, Provider and Remote. Those generic arguments +would be propagated to the SharedWorkerAcceptor, so that +SharedWorkerAcceptor would have the same generic arguments, too.

    +

    For reference, the first Header type repersents an initial data from the +remote client after the connection. I recommend utilize it as an activation tool +for security enhancement. The second generic argument Provider represents a +provider from server to client, and the other Remote means a provider from the +remote client to server.

    Author

    Jeongho Nam - https://github.com/samchon

    -

    Type Parameters

    • Header

      Type of the header containing initial data.

      -
    • Provider extends object | null

      Type of features provided for the remote system.

      -
    • Remote extends object | null

      Type of features supported by remote system, used for getDriver function.

      -

    Implements

    Constructors

    Type Parameters

    • Header

      Type of header containing initialization data like activation.

      +
    • Provider extends object | null

      Type of features provided for the remote client.

      +
    • Remote extends object | null

      Type of features provided by remote client.

      +

    Implements

    Constructors

    Accessors

    Methods

    Constructors

    Accessors

    Accessors

    Methods

    Methods

    • Close server.

      Close all connections between its remote clients (SharedWorkerConnectors).

      It destories all RFCs (remote function calls) between this server and remote clients (through Driver<Controller>) that are not returned (completed) yet. The destruction causes all incompleted RFCs to throw exceptions.

      -

      Returns Promise<void>

    • Open shared worker server.

      -

      Open a server through the shared worker protocol, with handler function determining -whether to accept the client's connection or not. After the server has been opened, clients -can connect to that websocket server by using the SharedWorkerServer class.

      -

      When implementing the handler function with the SharedWorkerServer instance, calls -the SharedWorkerAcceptor.accept method if you want to accept the new client's -connection. Otherwise you dont't want to accept the client and reject its connection, just -calls the SharedWorkerAcceptor.reject instead.

      +

      Returns Promise<void>

    • Open shared worker server.

      +

      Open a server through the shared worker protocol, with handler function +determining whether to accept the client's connection or not. After the server +has been opened, clients can connect to that server by using the +SharedWorkerServer class.

      +

      When implementing the handler function with the SharedWorkerServer +instance, calls the SharedWorkerAcceptor.accept method if you want to +accept the new client's connection. Otherwise you dont't want to accept the +client and reject its connection, just calls the +SharedWorkerAcceptor.reject instead.

      Parameters

      • handler: ((acceptor) => Promise<void>)

        Callback function called whenever client connects.

        -

      Returns Promise<void>

    \ No newline at end of file +

    Returns Promise<void>

    \ No newline at end of file diff --git a/website/public/api/classes/WebSocketAcceptor-1.html b/website/public/api/classes/WebSocketAcceptor-1.html index 3efbba4..8f92973 100644 --- a/website/public/api/classes/WebSocketAcceptor-1.html +++ b/website/public/api/classes/WebSocketAcceptor-1.html @@ -3,13 +3,13 @@
  • available only in the NodeJS.
  • The WebSocketAcceptor is a communicator class interacting with the remote -websocket client through RPC (Remote Procedure Call) -concept, created by the WebSocketServer class whenever a remote client +websocket client through RPC (Remote Procedure Call), +created by the WebSocketServer class whenever a remote client connects to the websocket server.

    When a remote client connects to the websocket server, so that a new WebSocketAcceptor instance being created, you can determine whether to accept the client's connection or not, -reading the {@lin header} and path properties. If you've decided to +reading the header and path properties. If you've decided to accept the connection, call the accept method with Provider instance. Otherwise, reject it thorugh the reject method.

    After accepting the connection, don't forget to @@ -22,13 +22,13 @@

    For reference, the first Header type repersents an initial data from the remote client after the connection. I recommend utilize it as an activation tool for security enhancement. The second generic argument Provider represents a -provider from server to client, and other Remote means a provider from the +provider from server to client, and the other Remote means a provider from the remote client to server.

    Author

    Jeongho Nam - https://github.com/samchon

    Type Parameters

    • Header

      Type of the header containing initial data.

    • Provider extends object | null

      Type of features provided for the remote client.

    • Remote extends object | null

      Type of features provided by remote client.

      -

    Hierarchy

    Implements

    • IWebSocketCommunicator

    Accessors

    Hierarchy

    Implements

    • IWebSocketCommunicator

    Accessors

    header ip path state @@ -42,9 +42,9 @@ setProvider upgrade

    Accessors

    Methods

    • Parameters

      • Optional code: number
      • Optional reason: string

      Returns Promise<void>

      Inherit Doc

    Methods

    • Parameters

      • Optional code: number
      • Optional reason: string

      Returns Promise<void>

      Inherit Doc

    • Get Driver for RFC (Remote Function Call).

      The Controller is an interface who defines provided functions from the remote system. The Driver is an object who makes to call remote functions, defined in the Controller and provided by Provider in the remote system, possible.

      @@ -68,33 +68,33 @@

      Type Parameters

      • Controller extends object = NonNullable<Remote>

        An interface for provided features (functions & objects) from the remote system (Provider).

      • UseParametric extends boolean = false

        Whether to convert type of function parameters to be compatible with their pritimive.

      Returns Driver<Controller, UseParametric>

      A Driver for the RFC.

      -
    • Get current Provider.

      Get an object providing features (functions & objects) for remote system. The remote system would call the features (Provider) by using its Driver<Controller>.

      Returns undefined | Provider

      Current Provider object

      -
    • Join connection.

      Wait until the connection to be closed.

      -

      Returns Promise<void>

    • Join connection or timeout.

      +

      Returns Promise<void>

    • Join connection or timeout.

      Wait until the connection to be clsoed until timeout.

      Parameters

      • ms: number

        The maximum milliseconds for joining.

      Returns Promise<boolean>

      Whether awaken by disconnection or timeout.

      -
    • Join connection or time expiration.

      +
    • Join connection or time expiration.

      Wait until the connection to be closed until time expiration.

      Parameters

      • at: Date

        The maximum time point to join.

      Returns Promise<boolean>

      Whether awaken by disconnection or time expiration.

      -
    • Reject connection.

      Reject without acceptance, any interaction. The connection would be closed immediately.

      Parameters

      • Optional status: number

        Status code.

      • Optional reason: string

        Detailed reason to reject.

        -

      Returns Promise<void>

    • Data Reply Function.

      +

    Returns Promise<void>

    • Data Reply Function.

      A function should be called when data has come from the remote system.

      When you receive a message from the remote system, then parse the message with your special protocol and covert it to be an Invoke object. After the conversion, call this method.

      Parameters

      • invoke: Invoke

        Structured data converted by your special protocol.

        -

      Returns void

    • Set Provider

      +

    Returns void

    • Set Provider

      Parameters

      • obj: undefined | Provider

        An object would be provided for remote system.

        -

      Returns void

    Returns void

    • Upgrade to WebSocket protocol.

      If you've not opened websocket server from WebSocketServer, you can still compose the WebSocketAcceptor instance by yourself, by upgrading the HTTP connection to the websocket protocol.

      @@ -107,4 +107,4 @@

      Type Parameters

      • Header
      • Provider extends null | object
      • Remote extends null | object

      Parameters

      • request: IncomingMessage

        HTTP incoming message.

      • socket: WebSocket

        WebSocket instance

      • Optional handler: ((acceptor) => Promise<any>)

        A callback function after the connection has been established.

        -

      Returns void

    \ No newline at end of file +

    Returns void

    \ No newline at end of file diff --git a/website/public/api/classes/WebSocketConnector-1.html b/website/public/api/classes/WebSocketConnector-1.html index bc7aa2d..4cd704d 100644 --- a/website/public/api/classes/WebSocketConnector-1.html +++ b/website/public/api/classes/WebSocketConnector-1.html @@ -7,25 +7,24 @@ the WebSocketAcceptor.accept method. If the remote server rejects your connection through WebSocketAcceptor.reject method, the exception would be thrown.

    -

    After the connection and approval from the websocket server, don't forget to -close the connection if your business logics have been completed, -to clean up the resources. Otherwise the closing must be performed by the remote -websocket server, you can wait the remote server's closing signal by the -join method.

    -

    Also, when declaring this WebSocketConnector type, you've to define three +

    After the connection, don't forget to closing the connection, if your +business logics have been completed, to clean up the resources. Otherwise, the +closing must be performed by the remote websocket server, you can wait the +remote server's closing signal through the join method.

    +

    Also, when declaring this WebSocketConnector type, you've to define three generic arguments; Header, Provider and Remote. Those generic arguments must be same with the ones defined in the target WebSocketServer and WebSocketAcceptor classes (Provider and Remote must be reversed).

    For reference, the first Header type repersents an initial data from the remote client after the connection. I recommend utilize it as an activation tool for security enhancement. The second generic argument Provider represents a -provider from client to server, and other Remote means a provider from the +provider from client to server, and the other Remote means a provider from the remote server to client.

    Author

    Jeongho Nam - https://github.com/samchon

    Type Parameters

    • Header

      Type of the header containing initial data.

    • Provider extends object | null

      Type of features provided for the remote server.

    • Remote extends object | null

      Type of features supported by remote server.

      -

    Hierarchy

    Implements

    • IWebSocketCommunicator

    Constructors

    Hierarchy

    Implements

    • IWebSocketCommunicator

    Constructors

    Accessors

    header state url @@ -40,8 +39,8 @@

    Constructors

    Accessors

    Returns WebSocketConnector<Header, Provider, Remote>

    Accessors

    Methods

    • Parameters

      • Optional code: number
      • Optional reason: string

      Returns Promise<void>

      Inherit Doc

    Methods

    • Parameters

      • Optional code: number
      • Optional reason: string

      Returns Promise<void>

      Inherit Doc

    • Connect to remote websocket server.

      Try connection to the remote websocket server with its address and waiting for the server to accept the trial. If the server rejects your connection, then exception would be thrown (in Promise.catch, as WebSocketError).

      @@ -60,14 +59,14 @@ connection in time to prevent waste of the server resource.

      Parameters

      Returns Promise<void>

    • Destory the communicator.

      +

    Returns Promise<void>

    • Destory the communicator.

      A destory function must be called when the network communication has been closed. It would destroy all function calls in the remote system (by Driver<Controller>), which are not returned yet.

      The error instance would be thrown to those function calls. If the disconnection is abnormal, then write the detailed reason why into the error instance.

      Parameters

      • Optional error: Error

        An error instance to be thrown to the unreturned functions.

        -

      Returns Promise<void>

    Returns Promise<void>

    • Get Driver for RFC (Remote Function Call).

      The Controller is an interface who defines provided functions from the remote system. The Driver is an object who makes to call remote functions, defined in the Controller and provided by Provider in the remote system, possible.

      @@ -80,26 +79,26 @@

      Type Parameters

      • Controller extends object = NonNullable<Remote>

        An interface for provided features (functions & objects) from the remote system (Provider).

      • UseParametric extends boolean = false

        Whether to convert type of function parameters to be compatible with their pritimive.

      Returns Driver<Controller, UseParametric>

      A Driver for the RFC.

      -
    • Get current Provider.

      Get an object providing features (functions & objects) for remote system. The remote system would call the features (Provider) by using its Driver<Controller>.

      Returns Provider

      Current Provider object

      -
    • Join connection.

      Wait until the connection to be closed.

      -

      Returns Promise<void>

    • Join connection or timeout.

      +

      Returns Promise<void>

    • Join connection or timeout.

      Wait until the connection to be clsoed until timeout.

      Parameters

      • ms: number

        The maximum milliseconds for joining.

      Returns Promise<boolean>

      Whether awaken by disconnection or timeout.

      -
    • Join connection or time expiration.

      +
    • Join connection or time expiration.

      Wait until the connection to be closed until time expiration.

      Parameters

      • at: Date

        The maximum time point to join.

      Returns Promise<boolean>

      Whether awaken by disconnection or time expiration.

      -
    • Data Reply Function.

      A function should be called when data has come from the remote system.

      When you receive a message from the remote system, then parse the message with your special protocol and covert it to be an Invoke object. After the conversion, call this method.

      Parameters

      • invoke: Invoke

        Structured data converted by your special protocol.

        -

      Returns void

    • Set Provider

      +

    Returns void

    \ No newline at end of file +

    Returns void

    \ No newline at end of file diff --git a/website/public/api/classes/WebSocketError.html b/website/public/api/classes/WebSocketError.html index e85eeb1..b8488b4 100644 --- a/website/public/api/classes/WebSocketError.html +++ b/website/public/api/classes/WebSocketError.html @@ -1,7 +1,7 @@ WebSocketError | tgrid

    Class WebSocketError

    Web Socket Error.

    Hierarchy

    • Error
      • WebSocketError

    Constructors

    Hierarchy

    • Error
      • WebSocketError

    Constructors

    Properties

    message name stack? @@ -12,7 +12,7 @@

    Author

    Jeongho Nam - https://git

    Constructors

    Properties

    message: string
    name: string
    stack?: string
    status: number
    prepareStackTrace?: ((err, stackTraces) => any)

    Optional override for formatting stack traces

    +

    Returns WebSocketError

    Properties

    message: string
    name: string
    stack?: string
    status: number
    prepareStackTrace?: ((err, stackTraces) => any)

    Optional override for formatting stack traces

    Type declaration

      • (err, stackTraces): any
      • Parameters

        • err: Error
        • stackTraces: CallSite[]

        Returns any

    stackTraceLimit: number

    Methods

    • Create .stack property on a target object

      Parameters

      • targetObject: object
      • Optional constructorOpt: Function

      Returns void

    \ No newline at end of file diff --git a/website/public/api/classes/WebSocketServer-1.html b/website/public/api/classes/WebSocketServer-1.html index 73b3b73..510662d 100644 --- a/website/public/api/classes/WebSocketServer-1.html +++ b/website/public/api/classes/WebSocketServer-1.html @@ -8,7 +8,7 @@ concept.

    To open the websocket server, call the open method with your callback function which would be called whenever a WebSocketAcceptor has been -newly created ay a new client's connection.

    +newly created by a new client's connection.

    Also, when declaring this WebSocketServer type, you have to define three generic arguments; Header, Provider and Remote. Those generic arguments would be propagated to the WebSocketAcceptor, so that @@ -16,23 +16,23 @@

    For reference, the first Header type repersents an initial data from the remote client after the connection. I recommend utilize it as an activation tool for security enhancement. The second generic argument Provider represents a -provider from server to client, and other Remote means a provider from the +provider from server to client, and the other Remote means a provider from the remote client to server.

    Author

    Jeongho Nam - https://github.com/samchon

    Type Parameters

    • Header

      Type of header containing initialization data like activation.

    • Provider extends object | null

      Type of features provided for the remote client.

    • Remote extends object | null

      Type of features provided by remote client.

      -

    Implements

    Constructors

    Implements

    Constructors

    Accessors

    Methods

    Constructors

    Accessors

    Returns WebSocketServer<Header, Provider, Remote>

    Accessors

    Methods

    Methods

    • Close server.

      Close all connections between its remote clients (WebSocketConnectors).

      It destories all RFCs (remote function calls) between this server and remote clients (through Driver<Controller>) that are not returned (completed) yet. The destruction causes all incompleted RFCs to throw exceptions.

      -

      Returns Promise<void>

    • Open websocket server.

      Open a server through the web-socket protocol, with its port number and handler function determining whether to accept the client's connection or not. After the server has been opened, clients can connect to that websocket server by using the WebSocketConnector @@ -58,4 +58,4 @@ WebSocketAcceptor.reject instead.

      Parameters

      • port: number

        Port number to listen.

      • handler: ((acceptor) => Promise<void>)

        Callback function for client connection.

        -

      Returns Promise<void>

    \ No newline at end of file +

    Returns Promise<void>

    \ No newline at end of file diff --git a/website/public/api/classes/WorkerConnector-1.html b/website/public/api/classes/WorkerConnector-1.html index 11e9152..3f616de 100644 --- a/website/public/api/classes/WorkerConnector-1.html +++ b/website/public/api/classes/WorkerConnector-1.html @@ -1,25 +1,29 @@ WorkerConnector | tgrid

    Class WorkerConnector<Header, Provider, Remote>

    Worker Connector.

    -

    The WorkerConnector is a communicator class, who can create an Worker instance and -communicate with it using RFC (Remote Function Call), considering the Worker as a -remote system (WorkerServer).

    -

    You can create an Worker instance with compile() or connect() method. -Anyway, after creation of the Worker instance, the Worker program must open a server -using the WorkerServer.open() method.

    -

    Note that, after your business, don't forget terminating the worker using close() -or WorkerServer.close(). If you don't terminate it, then vulnerable memory and -communication channel would not be destroyed and it may cause the memory leak.

    -

    Also, when declaring this WorkerConnector type, you've to define two template arguments, -Header and Provider. The Header type repersents an initial data gotten from the remote -system after the connection. I hope you and server not to omit it and utilize it as an -activation tool to enhance security.

    -

    The second template argument Provider represents the features provided for the remote system. -If you don't have any plan to provide any feature to the remote system, just declare it as -null.

    +

    The WorkerConnector is a communicator class, which creates an Worker instance +and interacts with it through RPC (Remote Procedure Call). In other words, +WorkerConnector considers the Worker instance as a remote server accepting +only one client; WorkerServer.

    +

    You can create an Worker instance with connect or compile method. +The connect method just opens an existing JS (or TS) file, and +compile method writes a temporary JS (TS) file, and connects to it. +Anyway, the Worker instanced program must open the WorkerServer.

    +

    By the way, don't forget closing the worker to clean up the resources. +If the closing be performed by WorkerServer, you can wait +the worker server closing through the join method.

    +

    Also, when declaring this WorkerConnector type, you've to define three +generic arguments; Header, Provider and Remote. Those generic arguments must +be same with the ones defined in the target WorkerServer class +(Provider and Remote must be reversed).

    +

    For reference, the first Header type repersents an initial data from the +remote client after the connection. I recommend utilize it as an activation tool +for security enhancement. The second generic argument Provider represents a +provider from client to server, and the other Remote means a provider from the +remote server to client.

    Author

    Jeongho Nam - https://github.com/samchon

    -

    Type Parameters

    • Header

      Type of header containing initialization data like activation.

      -
    • Provider extends object | null

      Type of features provided for remote system.

      -
    • Remote extends object | null

      Type of features supported by remote system, used for getDriver function.

      -

    Hierarchy

    Implements

    • IWorkerSystem

    Constructors

    Type Parameters

    • Header

      Type of the header containing initial data.

      +
    • Provider extends object | null

      Type of features provided for the remote server.

      +
    • Remote extends object | null

      Type of features supported by remote server.

      +

    Hierarchy

    Implements

    • IWorkerSystem

    Constructors

    Accessors

    Methods

    close @@ -38,8 +42,8 @@

    Type Parameters

    • Header
    • Provider extends null | object
    • Remote extends null | object

    Parameters

    • header: Header

      An object containing initialization data like activation.

    • provider: Provider

      An object providing features for remote system.

    • Optional type: "process" | "thread"

      You can specify the worker mode when NodeJS. Default is "process".

      -

    Returns WorkerConnector<Header, Provider, Remote>

    Accessors

    Returns WorkerConnector<Header, Provider, Remote>

    Accessors

    Methods

    Methods

    • Compile server and connect to there.

      The compile method tries compile JS source code, creates Worker instance with that code connects to the Worker. To complete the compilation and connection, the Worker program must open that server using the WorkerServer.open() @@ -59,7 +63,7 @@ memory usage and communication channel would not be destroyed and it may cause the memory leak.

      Parameters

      Returns Promise<void>

    Returns Promise<void>

    Returns Promise<void>

    • Destory the communicator.

      A destory function must be called when the network communication has been closed. It would destroy all function calls in the remote system (by Driver<Controller>), which are not returned yet.

      The error instance would be thrown to those function calls. If the disconnection is abnormal, then write the detailed reason why into the error instance.

      Parameters

      • Optional error: Error

        An error instance to be thrown to the unreturned functions.

        -

      Returns Promise<void>

    Returns Promise<void>

    • Get Driver for RFC (Remote Function Call).

      The Controller is an interface who defines provided functions from the remote system. The Driver is an object who makes to call remote functions, defined in the Controller and provided by Provider in the remote system, possible.

      @@ -88,26 +92,26 @@

      Type Parameters

      • Controller extends object = NonNullable<Remote>

        An interface for provided features (functions & objects) from the remote system (Provider).

      • UseParametric extends boolean = false

        Whether to convert type of function parameters to be compatible with their pritimive.

      Returns Driver<Controller, UseParametric>

      A Driver for the RFC.

      -
    • Get current Provider.

      Get an object providing features (functions & objects) for remote system. The remote system would call the features (Provider) by using its Driver<Controller>.

      Returns Provider

      Current Provider object

      -
    • Join connection.

      Wait until the connection to be closed.

      -

      Returns Promise<void>

    • Join connection or timeout.

      +

      Returns Promise<void>

    • Join connection or timeout.

      Wait until the connection to be clsoed until timeout.

      Parameters

      • ms: number

        The maximum milliseconds for joining.

      Returns Promise<boolean>

      Whether awaken by disconnection or timeout.

      -
    • Join connection or time expiration.

      +
    • Join connection or time expiration.

      Wait until the connection to be closed until time expiration.

      Parameters

      • at: Date

        The maximum time point to join.

      Returns Promise<boolean>

      Whether awaken by disconnection or time expiration.

      -
    • Data Reply Function.

      A function should be called when data has come from the remote system.

      When you receive a message from the remote system, then parse the message with your special protocol and covert it to be an Invoke object. After the conversion, call this method.

      Parameters

      • invoke: Invoke

        Structured data converted by your special protocol.

        -

      Returns void

    • Set Provider

      +

    Returns void

    \ No newline at end of file +

    Returns void

    \ No newline at end of file diff --git a/website/public/api/classes/WorkerServer-1.html b/website/public/api/classes/WorkerServer-1.html index e0d08f4..03ae718 100644 --- a/website/public/api/classes/WorkerServer-1.html +++ b/website/public/api/classes/WorkerServer-1.html @@ -1,26 +1,29 @@ WorkerServer | tgrid

    Class WorkerServer<Header, Provider, Remote>

    Worker Server.

    -

    The WorkerServer is a class representing a Worker server who can communicate with -remote client, parent and creator of the Worker (anyway WorkerConnector), using -RFC (Remote Function Call).

    -

    Unlike other servers, WorkerServer can accept only a client (WorkerConnector) -because the worker is dependent on its parent instance (web page, node or parent worker). -Thus, WorkerServer does not have any acceptor and communicates with client (its parent) -by itself.

    -

    To start communication with the remote client, call the open() method with special -Provider. After your business, don't forget terminating this worker using close() -or WorkerConnector.close() method. If you don't terminate it, then vulnerable -memory and communication channel would be kept and it may cause the memory leak.

    -

    Also, when declaring this WorkerServer type, you've to define two template arguments, -Header and Provider. The Header type repersents an initial data gotten from the remote -system after the connection.

    -

    The second template argument Provider represents the features provided for the remote system. -If you don't have any plan to provide any feature to the remote system, just declare it as -null.

    +

    The WorkerServer is a class representing a Worker server which communicate +with client (WorkerConnector), through the RPC (Remote Procedure Call).

    +

    Unlike other servers, WorkerServer can accept only one client +(WorkerConnector), because the Worker is dependent on its parent instance +(web page, node or parent worker). Thus, WorkerServer does not have any acceptor +and communicates with client (its parent) directly.

    +

    To start communication with the client, call the open method +with Provider instance. After your business, don't forget cosing +this Worker instance. If the termination is performed by the +WorkerConnector, you can wait the closing signal through the +join method.

    +

    Also, when declaring this WorkerServer type, you've to define three +generic arguments; Header, Provider and Remote. Those generic arguments must +be same with the ones defined in the target WorkerConnector class +(Provider and Remote must be reversed).

    +

    For reference, the first Header type repersents an initial data from the +client after the connection. I recommend utilize it as an activation tool +for security enhancement. The second generic argument Provider represents a +provider from server to client, and the other Remote means a provider from the +client to server.

    Author

    Jeongho Nam - https://github.com/samchon

    -

    Type Parameters

    • Header

      Type of header containing initialization data like activation.

      -
    • Provider extends object | null

      Type of features provided for remote system.

      -
    • Remote extends object | null

      Type of features supported by remote system, used for getDriver function.

      -

    Hierarchy (view full)

    Implements

    Constructors

    Type Parameters

    • Header

      Type of the header containing initial data.

      +
    • Provider extends object | null

      Type of features provided for the client.

      +
    • Remote extends object | null

      Type of features supported by client.

      +

    Hierarchy (view full)

    Implements

    Constructors

    Accessors

    Methods

    close destructor @@ -32,14 +35,14 @@ replyData setProvider

    Constructors

    Accessors

    Methods

    Accessors

    Methods

    • Destory the communicator.

      A destory function must be called when the network communication has been closed. It would destroy all function calls in the remote system (by Driver<Controller>), which are not returned yet.

      The error instance would be thrown to those function calls. If the disconnection is abnormal, then write the detailed reason why into the error instance.

      Parameters

      • Optional error: Error

        An error instance to be thrown to the unreturned functions.

        -

      Returns Promise<void>

    Returns Promise<void>

    • Get Driver for RFC (Remote Function Call).

      The Controller is an interface who defines provided functions from the remote system. The Driver is an object who makes to call remote functions, defined in the Controller and provided by Provider in the remote system, possible.

      @@ -52,34 +55,34 @@

      Type Parameters

      • Controller extends object = NonNullable<Remote>

        An interface for provided features (functions & objects) from the remote system (Provider).

      • UseParametric extends boolean = false

        Whether to convert type of function parameters to be compatible with their pritimive.

      Returns Driver<Controller, UseParametric>

      A Driver for the RFC.

      -
    • Open server with Provider.

      +

      Open worker server and start communication with the client (WorkerConnector).

      -

      Note that, after your business, you should terminate this worker to prevent waste -of memory leak. Close this worker by yourself (close) or let remote client to -close this worker (WorkerConnector.close).

      -

      Parameters

      • provider: Provider

        An object providing featrues for the remote system.

        -

      Returns Promise<void>

    • Data Reply Function.

      +

      Note that, after your business, you should terminate this worker to prevent +waste of memory leak. Close this worker by yourself (close) or let +client to close this worker (WorkerConnector.close).

      +

      Parameters

      • provider: Provider

        An object providing featrues for the client.

        +

      Returns Promise<void>

    • Data Reply Function.

      A function should be called when data has come from the remote system.

      When you receive a message from the remote system, then parse the message with your special protocol and covert it to be an Invoke object. After the conversion, call this method.

      Parameters

      • invoke: Invoke

        Structured data converted by your special protocol.

        -

      Returns void

    • Set Provider

      +

    Returns void

    \ No newline at end of file +

    Returns void

    \ No newline at end of file diff --git a/website/public/api/enums/WebSocketAcceptor.State.html b/website/public/api/enums/WebSocketAcceptor.State.html index ac2c648..02c2fd3 100644 --- a/website/public/api/enums/WebSocketAcceptor.State.html +++ b/website/public/api/enums/WebSocketAcceptor.State.html @@ -1,8 +1,8 @@ State | tgrid

    Enumeration StateConst

    Current state type of acceptor.

    -

    Enumeration Members

    Enumeration Members

    Enumeration Members

    ACCEPTING: 0
    CLOSED: 3
    CLOSING: 2
    NONE: -1
    OPEN: 1
    REJECTING: -2
    \ No newline at end of file +

    Enumeration Members

    ACCEPTING: 0
    CLOSED: 3
    CLOSING: 2
    NONE: -1
    OPEN: 1
    REJECTING: -2
    \ No newline at end of file diff --git a/website/public/api/enums/WebSocketConnector.State.html b/website/public/api/enums/WebSocketConnector.State.html index 776d78f..5a56416 100644 --- a/website/public/api/enums/WebSocketConnector.State.html +++ b/website/public/api/enums/WebSocketConnector.State.html @@ -1,7 +1,7 @@ State | tgrid

    Enumeration StateConst

    Current state type of connector.

    -

    Enumeration Members

    Enumeration Members

    Enumeration Members

    CLOSED: 3
    CLOSING: 2
    CONNECTING: 0
    NONE: -1
    OPEN: 1
    \ No newline at end of file +

    Enumeration Members

    CLOSED: 3
    CLOSING: 2
    CONNECTING: 0
    NONE: -1
    OPEN: 1
    \ No newline at end of file diff --git a/website/public/api/enums/WebSocketServer.State.html b/website/public/api/enums/WebSocketServer.State.html index 06899de..90b8d05 100644 --- a/website/public/api/enums/WebSocketServer.State.html +++ b/website/public/api/enums/WebSocketServer.State.html @@ -1,6 +1,6 @@ -State | tgrid

    Enumeration StateConst

    Enumeration Members

    CLOSED +State | tgrid

    Enumeration StateConst

    Enumeration Members

    Enumeration Members

    CLOSED: 3
    CLOSING: 2
    NONE: -1
    OPEN: 1
    OPENING: 0
    \ No newline at end of file +

    Enumeration Members

    CLOSED: 3
    CLOSING: 2
    NONE: -1
    OPEN: 1
    OPENING: 0
    \ No newline at end of file diff --git a/website/public/api/functions/SharedWorkerConnector.compile.html b/website/public/api/functions/SharedWorkerConnector.compile.html index 48b20ae..df38c5e 100644 --- a/website/public/api/functions/SharedWorkerConnector.compile.html +++ b/website/public/api/functions/SharedWorkerConnector.compile.html @@ -1,4 +1,4 @@ compile | tgrid
    \ No newline at end of file +
    \ No newline at end of file diff --git a/website/public/api/functions/SharedWorkerConnector.remove.html b/website/public/api/functions/SharedWorkerConnector.remove.html index b6fcdf3..69d127c 100644 --- a/website/public/api/functions/SharedWorkerConnector.remove.html +++ b/website/public/api/functions/SharedWorkerConnector.remove.html @@ -1,3 +1,3 @@ remove | tgrid
    \ No newline at end of file +

    Returns Promise<void>

    \ No newline at end of file diff --git a/website/public/api/index.html b/website/public/api/index.html index dae7518..7deb3f3 100644 --- a/website/public/api/index.html +++ b/website/public/api/index.html @@ -7,12 +7,17 @@

    TypeScript Grid Computing Framework.

    TypeScript RPC (Remote Procedure Call) framework for WebSocket and Worker protocols.

    Also, extremely easy even when composing complicated network system like grid computing.

    -
    import { Driver, WebSocketConnector } from "tgrid";

    import { ICalculator } from "./interfaces/ICalculator";
    import { CalcEventListener } from "./providers/CalcEventListener";

    export const main = async (): Promise<void> => {
    // CONNECT TO WEBSOCKET SERVER
    const connector: WebSocketConnector<
    null, // header
    CalcEventListener, // provider for remote server
    ICalculator, // provider from remote server
    > = new WebSocketConnector(null, new CalcEventListener());
    await connector.connect("ws://127.0.0.1:443/calculator");

    // RPC (YOU CAN CALL REMOTE PROCEDURES)
    const calc: Driver<ICalculator> = connector.getDriver();
    console.log(
    await calc.plus(2, 3),
    await calc.minus(7, 1),
    await calc.multiplies(3, 4),
    await calc.divides(9, 3),
    );
    await connector.close();
    }; +
    import { Driver, WebSocketConnector } from "tgrid";

    import { ICalcConfig } from "../interfaces/ICalcConfig";
    import { ICalcEvent } from "../interfaces/ICalcEvent";
    import { ICalcEventListener } from "../interfaces/ICalcEventListener";
    import { ICompositeCalculator } from "../interfaces/ICompositeCalculator";

    export const webSocketClientMain = async () => {
    const stack: ICalcEvent[] = [];
    const listener: ICalcEventListener = {
    on: (evt: ICalcEvent) => stack.push(evt),
    };
    const connector: WebSocketConnector<
    ICalcConfig,
    ICalcEventListener,
    ICompositeCalculator
    > = new WebSocketConnector(
    { precision: 2 }, // header
    listener, // provider for remote server
    );
    await connector.connect("ws://127.0.0.1:37000/composite");

    const remote: Driver<ICompositeCalculator> = connector.getDriver();
    await remote.plus(10, 20); // returns 30
    await remote.multiplies(3, 4); // returns 12
    await remote.divides(5, 3); // returns 1.67
    await remote.scientific.sqrt(2); // returns 1.41
    await remote.statistics.mean(1, 3, 9); // returns 4.33

    await connector.close();
    console.log(...stack);
    };
    +
    +

    Execution result:

    +
    { type: 'plus', input: [ 10, 20 ], output: 30 }
    { type: 'multiplies', input: [ 3, 4 ], output: 12 }
    { type: 'divides', input: [ 5, 3 ], output: 1.67 }
    { type: 'sqrt', input: [ 2 ], output: 1.41 }
    { type: 'mean', input: [ 1, 3, 9 ], output: 4.33 } +
    +

    Setup

    npm install tgrid
     

    Just install with npm command. That's all.

    -

    If you wanna tgrid in NestJS, read nestia guide documents.

    +

    If you wanna use tgrid in NestJS, read nestia guide documents.

    • Nestia > Guide Documents > Setup
    • Nestia > Guide Documents > WebSocketRoute
    • diff --git a/website/public/api/interfaces/Invoke.IFunction.html b/website/public/api/interfaces/Invoke.IFunction.html index c03dc77..8382b88 100644 --- a/website/public/api/interfaces/Invoke.IFunction.html +++ b/website/public/api/interfaces/Invoke.IFunction.html @@ -1,8 +1,8 @@ IFunction | tgrid

      Interface IFunction

      Message for Requesting RFC.

      -
      interface IFunction {
          listener: string;
          parameters: IParameter[];
          uid: number;
      }

      Hierarchy

      • IBase
        • IFunction

      Properties

      interface IFunction {
          listener: string;
          parameters: IParameter[];
          uid: number;
      }

      Hierarchy

      • IBase
        • IFunction

      Properties

      listener: string

      Target function (sometimes calsuled in objects) to call.

      -
      parameters: IParameter[]

      Parameters for the function call.

      -
      uid: number

      Unique identifier.

      -
      \ No newline at end of file +
      parameters: IParameter[]

      Parameters for the function call.

      +
      uid: number

      Unique identifier.

      +
      \ No newline at end of file diff --git a/website/public/api/interfaces/Invoke.IParameter.html b/website/public/api/interfaces/Invoke.IParameter.html index 187c97a..6d61595 100644 --- a/website/public/api/interfaces/Invoke.IParameter.html +++ b/website/public/api/interfaces/Invoke.IParameter.html @@ -1,3 +1,3 @@ -IParameter | tgrid

      Interface IParameter

      interface IParameter {
          type: string;
          value: any;
      }

      Properties

      type +IParameter | tgrid

      Interface IParameter

      interface IParameter {
          type: string;
          value: any;
      }

      Properties

      Properties

      type: string
      value: any
      \ No newline at end of file +

      Properties

      type: string
      value: any
      \ No newline at end of file diff --git a/website/public/api/interfaces/Invoke.IReturn.html b/website/public/api/interfaces/Invoke.IReturn.html index 1a96bd8..20ee4a7 100644 --- a/website/public/api/interfaces/Invoke.IReturn.html +++ b/website/public/api/interfaces/Invoke.IReturn.html @@ -1,8 +1,8 @@ IReturn | tgrid

      Interface IReturn

      Message for Returning RFC.

      -
      interface IReturn {
          success: boolean;
          uid: number;
          value: any;
      }

      Hierarchy

      • IBase
        • IReturn

      Properties

      interface IReturn {
          success: boolean;
          uid: number;
          value: any;
      }

      Hierarchy

      • IBase
        • IReturn

      Properties

      Properties

      success: boolean

      true -> return, false -> exception.

      -
      uid: number

      Unique identifier.

      -
      value: any

      Returned value or thrown exception.

      -
      \ No newline at end of file +
      uid: number

      Unique identifier.

      +
      value: any

      Returned value or thrown exception.

      +
      \ No newline at end of file diff --git a/website/public/api/interfaces/SharedWorkerConnector.IConnectOptions.html b/website/public/api/interfaces/SharedWorkerConnector.IConnectOptions.html index 965020b..65b67db 100644 --- a/website/public/api/interfaces/SharedWorkerConnector.IConnectOptions.html +++ b/website/public/api/interfaces/SharedWorkerConnector.IConnectOptions.html @@ -1,4 +1,4 @@ IConnectOptions | tgrid

      Connection options for the SharedWorkerConnector.connect.

      -
      interface IConnectOptions {
          timeout: number;
      }

      Properties

      interface IConnectOptions {
          timeout: number;
      }

      Properties

      Properties

      timeout: number

      Milliseconds to wait the shared-worker server to accept or reject it. If omitted, the waiting would be forever.

      -
      \ No newline at end of file +
      \ No newline at end of file diff --git a/website/public/api/interfaces/WebSocketConnector.IConnectOptions.html b/website/public/api/interfaces/WebSocketConnector.IConnectOptions.html index 479432b..bd8fe10 100644 --- a/website/public/api/interfaces/WebSocketConnector.IConnectOptions.html +++ b/website/public/api/interfaces/WebSocketConnector.IConnectOptions.html @@ -1,4 +1,4 @@ IConnectOptions | tgrid

      Connection options for the WebSocketConnector.connect.

      -
      interface IConnectOptions {
          timeout: number;
      }

      Properties

      interface IConnectOptions {
          timeout: number;
      }

      Properties

      Properties

      timeout: number

      Milliseconds to wait the web-socket server to accept or reject it. If omitted, the waiting would be forever.

      -
      \ No newline at end of file +
      \ No newline at end of file diff --git a/website/public/api/interfaces/WorkerConnector.IConnectOptions.html b/website/public/api/interfaces/WorkerConnector.IConnectOptions.html index 207bc1c..73b0b6c 100644 --- a/website/public/api/interfaces/WorkerConnector.IConnectOptions.html +++ b/website/public/api/interfaces/WorkerConnector.IConnectOptions.html @@ -1,6 +1,6 @@ IConnectOptions | tgrid

      Interface IConnectOptions

      Connection options for the WorkerConnector.connect.

      -
      interface IConnectOptions {
          execArgv: string[];
          timeout: number;
      }

      Properties

      interface IConnectOptions {
          execArgv: string[];
          timeout: number;
      }

      Properties

      Properties

      execArgv: string[]

      Arguments only for the NodeJS environments.

      -
      timeout: number

      Milliseconds to wait the worker server to accept or reject it. If omitted, the waiting would be forever.

      -
      \ No newline at end of file +
      timeout: number

      Milliseconds to wait the worker server to accept or reject it. If omitted, the waiting would be forever.

      +
      \ No newline at end of file diff --git a/website/public/api/modules/Invoke.html b/website/public/api/modules/Invoke.html index be627a4..9989af5 100644 --- a/website/public/api/modules/Invoke.html +++ b/website/public/api/modules/Invoke.html @@ -1,4 +1,4 @@ -Invoke | tgrid

      Namespace Invoke

      Index

      Interfaces

      IFunction +Invoke | tgrid
      \ No newline at end of file diff --git a/website/public/api/modules/SharedWorkerAcceptor.html b/website/public/api/modules/SharedWorkerAcceptor.html index 1db508d..4c963a7 100644 --- a/website/public/api/modules/SharedWorkerAcceptor.html +++ b/website/public/api/modules/SharedWorkerAcceptor.html @@ -1,2 +1,2 @@ -SharedWorkerAcceptor | tgrid

      Namespace SharedWorkerAcceptor

      References

      State +SharedWorkerAcceptor | tgrid

      Namespace SharedWorkerAcceptor

      References

      References

      Re-exports State
      \ No newline at end of file diff --git a/website/public/api/modules/SharedWorkerConnector.html b/website/public/api/modules/SharedWorkerConnector.html index 5c68cf2..8d0ce8b 100644 --- a/website/public/api/modules/SharedWorkerConnector.html +++ b/website/public/api/modules/SharedWorkerConnector.html @@ -1,4 +1,4 @@ -SharedWorkerConnector | tgrid

      Namespace SharedWorkerConnector

      References

      State +SharedWorkerConnector | tgrid

      Namespace SharedWorkerConnector

      References

      Interfaces

      Functions

      compile remove diff --git a/website/public/api/modules/SharedWorkerServer.html b/website/public/api/modules/SharedWorkerServer.html index 1276b76..1bc92a1 100644 --- a/website/public/api/modules/SharedWorkerServer.html +++ b/website/public/api/modules/SharedWorkerServer.html @@ -1,2 +1,2 @@ -SharedWorkerServer | tgrid

      Namespace SharedWorkerServer

      References

      State +SharedWorkerServer | tgrid

      Namespace SharedWorkerServer

      References

      References

      Re-exports State
      \ No newline at end of file diff --git a/website/public/api/modules/WebSocketAcceptor.html b/website/public/api/modules/WebSocketAcceptor.html index ce8d9d3..8f51ff7 100644 --- a/website/public/api/modules/WebSocketAcceptor.html +++ b/website/public/api/modules/WebSocketAcceptor.html @@ -1,2 +1,2 @@ -WebSocketAcceptor | tgrid

      Namespace WebSocketAcceptor

      Index

      Enumerations

      State +WebSocketAcceptor | tgrid
      \ No newline at end of file diff --git a/website/public/api/modules/WebSocketConnector.html b/website/public/api/modules/WebSocketConnector.html index 413c173..c957af4 100644 --- a/website/public/api/modules/WebSocketConnector.html +++ b/website/public/api/modules/WebSocketConnector.html @@ -1,3 +1,3 @@ -WebSocketConnector | tgrid

      Namespace WebSocketConnector

      Index

      Enumerations

      State +WebSocketConnector | tgrid
      \ No newline at end of file diff --git a/website/public/api/modules/WebSocketServer.html b/website/public/api/modules/WebSocketServer.html index 4dda914..b53c12b 100644 --- a/website/public/api/modules/WebSocketServer.html +++ b/website/public/api/modules/WebSocketServer.html @@ -1,2 +1,2 @@ -WebSocketServer | tgrid

      Namespace WebSocketServer

      Index

      Enumerations

      State +WebSocketServer | tgrid
      \ No newline at end of file diff --git a/website/public/api/modules/WorkerConnector.html b/website/public/api/modules/WorkerConnector.html index f36e498..c05a1b7 100644 --- a/website/public/api/modules/WorkerConnector.html +++ b/website/public/api/modules/WorkerConnector.html @@ -1,3 +1,3 @@ -WorkerConnector | tgrid

      Namespace WorkerConnector

      References

      State +WorkerConnector | tgrid

      Namespace WorkerConnector

      References

      Interfaces

      References

      Re-exports State
      \ No newline at end of file diff --git a/website/public/api/modules/WorkerServer.html b/website/public/api/modules/WorkerServer.html index 461a2b4..8ba381c 100644 --- a/website/public/api/modules/WorkerServer.html +++ b/website/public/api/modules/WorkerServer.html @@ -1,2 +1,2 @@ -WorkerServer | tgrid

      Namespace WorkerServer

      References

      State +WorkerServer | tgrid

      Namespace WorkerServer

      References

      References

      Re-exports State
      \ No newline at end of file diff --git a/website/public/api/modules/default.html b/website/public/api/modules/default.html index a0ab782..069ebc2 100644 --- a/website/public/api/modules/default.html +++ b/website/public/api/modules/default.html @@ -1,4 +1,4 @@ -default | tgrid

      Namespace default

      References

      Communicator +default | tgrid

      Namespace default

      References

      Communicator Driver Invoke Primitive diff --git a/website/public/api/types/Driver.html b/website/public/api/types/Driver.html index 44ffa5a..0fecb2b 100644 --- a/website/public/api/types/Driver.html +++ b/website/public/api/types/Driver.html @@ -11,4 +11,4 @@

      Type Parameters

      • Controller extends object

        An interface defining features (functions & objects) provided from the remote system.

      • Parametric extends boolean = false

      Template: UseParametric

      Whether to convert type of function parameters to be compatible with their pritimive.

      Author

      Jeongho Nam - https://github.com/samchon

      -
      \ No newline at end of file +
      \ No newline at end of file diff --git a/website/public/api/types/Invoke-1.html b/website/public/api/types/Invoke-1.html index d1e73d7..131777d 100644 --- a/website/public/api/types/Invoke-1.html +++ b/website/public/api/types/Invoke-1.html @@ -1,3 +1,3 @@ Invoke | tgrid

      Type alias Invoke

      Invoke: IFunction | IReturn

      Message structure for RFC (Remote Function Call).

      Author

      Jeongho Nam - https://github.com/samchon

      -
      \ No newline at end of file +
      \ No newline at end of file diff --git a/website/public/api/types/Primitive.html b/website/public/api/types/Primitive.html index 1607297..c1668f3 100644 --- a/website/public/api/types/Primitive.html +++ b/website/public/api/types/Primitive.html @@ -51,4 +51,4 @@

    Author

    Jeongho Nam - https://github.com/samchon

    Author

    Kyungsu Kang - https://github.com/kakasoo

    Author

    Michael - https://github.com/8471919

    -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/website/public/api/types/Promisive.html b/website/public/api/types/Promisive.html index d670864..c36f314 100644 --- a/website/public/api/types/Promisive.html +++ b/website/public/api/types/Promisive.html @@ -7,4 +7,4 @@

    Type Parameters

    • Instance extends object

      An object type to be promised.

    • UseParametric extends boolean = false

      Whether to convert type of function parameters to be compatible with their pritimive.

      -
    \ No newline at end of file +
    \ No newline at end of file diff --git a/website/public/api/variables/Driver-1.html b/website/public/api/variables/Driver-1.html index c1169fd..187f573 100644 --- a/website/public/api/variables/Driver-1.html +++ b/website/public/api/variables/Driver-1.html @@ -1 +1 @@ -Driver | tgrid

    Variable Driver

    Driver: typeof __class
    \ No newline at end of file +Driver | tgrid

    Variable Driver

    Driver: typeof __class
    \ No newline at end of file