@chirper/node 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +3 -0
- package/.browserlistrc +8 -0
- package/.editorconfig +21 -0
- package/.eslintignore +3 -0
- package/.prettierrc +20 -0
- package/README.md +33 -0
- package/build.js +73 -0
- package/dist/bundle.js +1 -0
- package/package.json +36 -0
- package/src/api/AI.ts +14 -0
- package/src/api/Stat.ts +9 -0
- package/src/index.ts +437 -0
package/.babelrc
ADDED
package/.browserlistrc
ADDED
package/.editorconfig
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# http://editorconfig.org
|
2
|
+
root = true
|
3
|
+
|
4
|
+
[*]
|
5
|
+
charset = utf-8
|
6
|
+
end_of_line = lf
|
7
|
+
indent_size = 2
|
8
|
+
indent_style = tab
|
9
|
+
insert_final_newline = true
|
10
|
+
max_line_length = 80
|
11
|
+
trim_trailing_whitespace = true
|
12
|
+
|
13
|
+
[*.md]
|
14
|
+
max_line_length = 0
|
15
|
+
trim_trailing_whitespace = false
|
16
|
+
|
17
|
+
[COMMIT_EDITMSG]
|
18
|
+
max_line_length = 0
|
19
|
+
|
20
|
+
[*.{css,scss,html}]
|
21
|
+
indent_size = 4
|
package/.eslintignore
ADDED
package/.prettierrc
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
{
|
2
|
+
"parser": "babylon",
|
3
|
+
"printWidth": 80,
|
4
|
+
"useTabs": true,
|
5
|
+
"tabWidth": 2,
|
6
|
+
"singleQuote": true,
|
7
|
+
"semi": true,
|
8
|
+
"trailingComma": "es5",
|
9
|
+
"bracketSpacing": true,
|
10
|
+
"jsxBracketSameLine": false,
|
11
|
+
"arrowParens": "always",
|
12
|
+
"overrides": [
|
13
|
+
{
|
14
|
+
"files": "*.md",
|
15
|
+
"options": {
|
16
|
+
"parser": "markdown"
|
17
|
+
}
|
18
|
+
}
|
19
|
+
]
|
20
|
+
}
|
package/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
<p align="center">
|
2
|
+
<img src="https://user-images.githubusercontent.com/10063864/45442352-c961ab80-b68f-11e8-84a3-e920f05a313c.png" width={400} alt="Rinse" />
|
3
|
+
</p>
|
4
|
+
|
5
|
+
> Rinse, React, repeat. A boilerplate to build a React component library.
|
6
|
+
|
7
|
+
#### To learn how this project was made from scratch, [read the blog post](https://medium.com/@cwlsn/how-to-write-your-own-reusable-react-component-library-a57dc7c9a210)!
|
8
|
+
|
9
|
+
## Get Started
|
10
|
+
|
11
|
+
To start your own React component library, clone this repository and start your own Git journey!
|
12
|
+
|
13
|
+
```bash
|
14
|
+
$ git clone https://github.com/cwlsn/rinse-react cool-name
|
15
|
+
$ cd cool-name
|
16
|
+
$ rm -rf .git
|
17
|
+
$ git init
|
18
|
+
```
|
19
|
+
|
20
|
+
## Development and Storybook
|
21
|
+
|
22
|
+
You can easily develop and interact with your components by using Storybook. To run the local server, simply run:
|
23
|
+
|
24
|
+
```bash
|
25
|
+
$ npm i
|
26
|
+
$ npm run storybook
|
27
|
+
```
|
28
|
+
|
29
|
+
Navigate to [http://localhost:9001](http://localhost:9001) to view your stories. They should automatically update as you develop.
|
30
|
+
|
31
|
+
Storybook will pick up any story from the `stories.js` file in a component folder.
|
32
|
+
|
33
|
+
Rinse is currently using the latest technology available, so you may need to update your Node versions to latest to accomodate Babel 7 and Webpack 4.
|
package/build.js
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
|
2
|
+
// es build
|
3
|
+
const fs = require('fs-extra');
|
4
|
+
const pkg = require('./package.json');
|
5
|
+
const path = require('path');
|
6
|
+
const esbuild = require('esbuild');
|
7
|
+
const chokidar = require('chokidar');
|
8
|
+
|
9
|
+
// build
|
10
|
+
esbuild.build({
|
11
|
+
watch : process.env.MODE !== 'production',
|
12
|
+
bundle : true,
|
13
|
+
format : 'cjs',
|
14
|
+
minify : process.env.MODE === 'production',
|
15
|
+
outfile : 'dist/bundle.js',
|
16
|
+
external : Object.keys(pkg.peerDependencies || {}),
|
17
|
+
entryPoints : ['./src/index.js'],
|
18
|
+
});
|
19
|
+
|
20
|
+
// check dev mode
|
21
|
+
if (process.env.MODE !== 'production' && process.env.COPY) {
|
22
|
+
// parse copy directories
|
23
|
+
const copy = process.env.COPY.split(',').map((dir) => dir.trim());
|
24
|
+
|
25
|
+
// create compile watcher
|
26
|
+
const watcher = chokidar.watch('dist/*', {
|
27
|
+
persistent : true
|
28
|
+
});
|
29
|
+
|
30
|
+
// on change
|
31
|
+
watcher.on('change', (p, stats) => {
|
32
|
+
// timeout
|
33
|
+
setTimeout(() => {
|
34
|
+
// copy file to build
|
35
|
+
copy.forEach((dir) => {
|
36
|
+
// copy sync
|
37
|
+
fs.copySync('dist', dir, { overwrite : true });
|
38
|
+
|
39
|
+
// pkg
|
40
|
+
const pkg = `${path.dirname(dir)}/package.json`;
|
41
|
+
const base = `${path.dirname(path.dirname(path.dirname(path.dirname(dir))))}/package-lock.json`;
|
42
|
+
|
43
|
+
// touch file
|
44
|
+
if (fs.existsSync(pkg)) {
|
45
|
+
// get json
|
46
|
+
const json = JSON.parse(fs.readFileSync(pkg));
|
47
|
+
|
48
|
+
// set version
|
49
|
+
json.version = `${json.version.split('.').slice(0, 2).join('.')}.${(parseInt(json.version.split('.')[2]) + 1)}`;
|
50
|
+
|
51
|
+
// write file
|
52
|
+
fs.writeFileSync(pkg, JSON.stringify(json, null, 2));
|
53
|
+
}
|
54
|
+
|
55
|
+
// touch file
|
56
|
+
if (fs.existsSync(base)) {
|
57
|
+
// touch file
|
58
|
+
fs.utimesSync(base, new Date(), new Date());
|
59
|
+
}
|
60
|
+
|
61
|
+
// copied
|
62
|
+
console.log(`Copied to ${dir}`);
|
63
|
+
});
|
64
|
+
}, 200);
|
65
|
+
});
|
66
|
+
|
67
|
+
// copy file to build
|
68
|
+
copy.forEach((dir) => {
|
69
|
+
// copy sync
|
70
|
+
fs.copySync('dist', dir, { overwrite : true });
|
71
|
+
console.log(`Copied to ${dir}`);
|
72
|
+
});
|
73
|
+
}
|
package/dist/bundle.js
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
var V=Object.create;var S=Object.defineProperty;var Y=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var Q=Object.getPrototypeOf,W=Object.prototype.hasOwnProperty;var k=(s,t)=>()=>(t||s((t={exports:{}}).exports,t),t.exports),X=(s,t)=>{for(var e in t)S(s,e,{get:t[e],enumerable:!0})},J=(s,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of z(t))!W.call(s,o)&&o!==e&&S(s,o,{get:()=>t[o],enumerable:!(i=Y(t,o))||i.enumerable});return s};var U=(s,t,e)=>(e=s!=null?V(Q(s)):{},J(t||!s||!s.__esModule?S(e,"default",{value:s,enumerable:!0}):e,s)),Z=s=>J(S({},"__esModule",{value:!0}),s);var B=k((rt,E)=>{var C=(()=>{var s=Object.defineProperty,t=Object.getOwnPropertySymbols,e=Object.prototype.hasOwnProperty,i=Object.prototype.propertyIsEnumerable,o=(w,f,p)=>f in w?s(w,f,{enumerable:!0,configurable:!0,writable:!0,value:p}):w[f]=p,a=(w,f)=>{for(var p in f||(f={}))e.call(f,p)&&o(w,p,f[p]);if(t)for(var p of t(f))i.call(f,p)&&o(w,p,f[p]);return w},h=w=>s(w,"__esModule",{value:!0}),v=(w,f)=>{h(w);for(var p in f)s(w,p,{get:f[p],enumerable:!0})},n={};v(n,{DEFAULT_UUID_LENGTH:()=>y,default:()=>b});var $="4.4.4",y=6,c={dictionary:"alphanum",shuffle:!0,debug:!1,length:y},m=class extends Function{constructor(w={}){super(),this.dictIndex=0,this.dictRange=[],this.lowerBound=0,this.upperBound=0,this.dictLength=0,this._digit_first_ascii=48,this._digit_last_ascii=58,this._alpha_lower_first_ascii=97,this._alpha_lower_last_ascii=123,this._hex_last_ascii=103,this._alpha_upper_first_ascii=65,this._alpha_upper_last_ascii=91,this._number_dict_ranges={digits:[this._digit_first_ascii,this._digit_last_ascii]},this._alpha_dict_ranges={lowerCase:[this._alpha_lower_first_ascii,this._alpha_lower_last_ascii],upperCase:[this._alpha_upper_first_ascii,this._alpha_upper_last_ascii]},this._alpha_lower_dict_ranges={lowerCase:[this._alpha_lower_first_ascii,this._alpha_lower_last_ascii]},this._alpha_upper_dict_ranges={upperCase:[this._alpha_upper_first_ascii,this._alpha_upper_last_ascii]},this._alphanum_dict_ranges={digits:[this._digit_first_ascii,this._digit_last_ascii],lowerCase:[this._alpha_lower_first_ascii,this._alpha_lower_last_ascii],upperCase:[this._alpha_upper_first_ascii,this._alpha_upper_last_ascii]},this._alphanum_lower_dict_ranges={digits:[this._digit_first_ascii,this._digit_last_ascii],lowerCase:[this._alpha_lower_first_ascii,this._alpha_lower_last_ascii]},this._alphanum_upper_dict_ranges={digits:[this._digit_first_ascii,this._digit_last_ascii],upperCase:[this._alpha_upper_first_ascii,this._alpha_upper_last_ascii]},this._hex_dict_ranges={decDigits:[this._digit_first_ascii,this._digit_last_ascii],alphaDigits:[this._alpha_lower_first_ascii,this._hex_last_ascii]},this.log=(...r)=>{let l=[...r];if(l[0]=`[short-unique-id] ${r[0]}`,this.debug===!0&&typeof console<"u"&&console!==null)return console.log(...l)},this.setDictionary=(r,l)=>{let u;if(r&&Array.isArray(r)&&r.length>1)u=r;else{u=[];let d;this.dictIndex=d=0;let x=`_${r}_dict_ranges`,N=this[x];Object.keys(N).forEach(G=>{let H=G;for(this.dictRange=N[H],this.lowerBound=this.dictRange[0],this.upperBound=this.dictRange[1],this.dictIndex=d=this.lowerBound;this.lowerBound<=this.upperBound?d<this.upperBound:d>this.upperBound;this.dictIndex=this.lowerBound<=this.upperBound?d+=1:d-=1)u.push(String.fromCharCode(this.dictIndex))})}l&&(u=u.sort(()=>Math.random()-.5)),this.dict=u,this.dictLength=this.dict.length,this.counter=0},this.seq=()=>this.sequentialUUID(),this.sequentialUUID=()=>{let r,l,u="";r=this.counter;do l=r%this.dictLength,r=Math.trunc(r/this.dictLength),u+=this.dict[l];while(r!==0);return this.counter+=1,u},this.randomUUID=(r=this.uuidLength||y)=>{let l,u,d;if(r===null||typeof r>"u"||r<1)throw new Error("Invalid UUID Length Provided");let x=r>=0;for(l="",d=0;d<r;d+=1)u=parseInt((Math.random()*this.dictLength).toFixed(0),10)%this.dictLength,l+=this.dict[u];return l},this.availableUUIDs=(r=this.uuidLength)=>parseFloat(Math.pow([...new Set(this.dict)].length,r).toFixed(0)),this.approxMaxBeforeCollision=(r=this.availableUUIDs(this.uuidLength))=>parseFloat(Math.sqrt(Math.PI/2*r).toFixed(20)),this.collisionProbability=(r=this.availableUUIDs(this.uuidLength),l=this.uuidLength)=>parseFloat((this.approxMaxBeforeCollision(r)/this.availableUUIDs(l)).toFixed(20)),this.uniqueness=(r=this.availableUUIDs(this.uuidLength))=>{let l=parseFloat((1-this.approxMaxBeforeCollision(r)/r).toFixed(20));return l>1?1:l<0?0:l},this.getVersion=()=>this.version,this.stamp=r=>{if(typeof r!="number"||r<10)throw new Error("Param finalLength must be number greater than 10");let l=Math.floor(+new Date/1e3).toString(16),u=r-9,d=Math.round(Math.random()*(u>15?15:u)),x=this.randomUUID(u);return`${x.substr(0,d)}${l}${x.substr(d)}${d.toString(16)}`},this.parseStamp=r=>{if(r.length<10)throw new Error("Stamp length invalid");let l=parseInt(r.substr(r.length-1,1),16);return new Date(parseInt(r.substr(l,8),16)*1e3)};let f=a(a({},c),w);this.counter=0,this.debug=!1,this.dict=[],this.version=$;let{dictionary:p,shuffle:j,length:K}=f;return this.uuidLength=K,this.setDictionary(p,j),this.debug=f.debug,this.log(this.dict),this.log(`Generator instantiated with Dictionary Size ${this.dictLength}`),new Proxy(this,{apply:(r,l,u)=>this.randomUUID(...u)})}},b=m;return b.default=m,n})();typeof E<"u"&&(E.exports=C.default),typeof window<"u"&&(C=C.default)});var T=k((ht,P)=>{"use strict";var tt=Object.prototype.hasOwnProperty,g="~";function O(){}Object.create&&(O.prototype=Object.create(null),new O().__proto__||(g=!1));function et(s,t,e){this.fn=s,this.context=t,this.once=e||!1}function F(s,t,e,i,o){if(typeof e!="function")throw new TypeError("The listener must be a function");var a=new et(e,i||s,o),h=g?g+t:t;return s._events[h]?s._events[h].fn?s._events[h]=[s._events[h],a]:s._events[h].push(a):(s._events[h]=a,s._eventsCount++),s}function I(s,t){--s._eventsCount===0?s._events=new O:delete s._events[t]}function _(){this._events=new O,this._eventsCount=0}_.prototype.eventNames=function(){var t=[],e,i;if(this._eventsCount===0)return t;for(i in e=this._events)tt.call(e,i)&&t.push(g?i.slice(1):i);return Object.getOwnPropertySymbols?t.concat(Object.getOwnPropertySymbols(e)):t};_.prototype.listeners=function(t){var e=g?g+t:t,i=this._events[e];if(!i)return[];if(i.fn)return[i.fn];for(var o=0,a=i.length,h=new Array(a);o<a;o++)h[o]=i[o].fn;return h};_.prototype.listenerCount=function(t){var e=g?g+t:t,i=this._events[e];return i?i.fn?1:i.length:0};_.prototype.emit=function(t,e,i,o,a,h){var v=g?g+t:t;if(!this._events[v])return!1;var n=this._events[v],$=arguments.length,y,c;if(n.fn){switch(n.once&&this.removeListener(t,n.fn,void 0,!0),$){case 1:return n.fn.call(n.context),!0;case 2:return n.fn.call(n.context,e),!0;case 3:return n.fn.call(n.context,e,i),!0;case 4:return n.fn.call(n.context,e,i,o),!0;case 5:return n.fn.call(n.context,e,i,o,a),!0;case 6:return n.fn.call(n.context,e,i,o,a,h),!0}for(c=1,y=new Array($-1);c<$;c++)y[c-1]=arguments[c];n.fn.apply(n.context,y)}else{var m=n.length,b;for(c=0;c<m;c++)switch(n[c].once&&this.removeListener(t,n[c].fn,void 0,!0),$){case 1:n[c].fn.call(n[c].context);break;case 2:n[c].fn.call(n[c].context,e);break;case 3:n[c].fn.call(n[c].context,e,i);break;case 4:n[c].fn.call(n[c].context,e,i,o);break;default:if(!y)for(b=1,y=new Array($-1);b<$;b++)y[b-1]=arguments[b];n[c].fn.apply(n[c].context,y)}}return!0};_.prototype.on=function(t,e,i){return F(this,t,e,i,!1)};_.prototype.once=function(t,e,i){return F(this,t,e,i,!0)};_.prototype.removeListener=function(t,e,i,o){var a=g?g+t:t;if(!this._events[a])return this;if(!e)return I(this,a),this;var h=this._events[a];if(h.fn)h.fn===e&&(!o||h.once)&&(!i||h.context===i)&&I(this,a);else{for(var v=0,n=[],$=h.length;v<$;v++)(h[v].fn!==e||o&&!h[v].once||i&&h[v].context!==i)&&n.push(h[v]);n.length?this._events[a]=n.length===1?n[0]:n:I(this,a)}return this};_.prototype.removeAllListeners=function(t){var e;return t?(e=g?g+t:t,this._events[e]&&I(this,e)):(this._events=new O,this._eventsCount=0),this};_.prototype.off=_.prototype.removeListener;_.prototype.addListener=_.prototype.on;_.prefixed=g;_.EventEmitter=_;typeof P<"u"&&(P.exports=_)});var st={};X(st,{default:()=>L});module.exports=Z(st);var q=U(B()),R=U(require("socket.io-client"));var D=U(T(),1);var A=s=>({prompt:t=>s.post("/:account/ai",t),image:t=>s.post("/:account/ai/image",t)});var M=s=>({get:(t,e=null,i=null)=>s.get(`/:account/stat/${t}`,{from:e,to:i})});var it=new q.default({length:10}),L=class{constructor({url:t,version:e}){this.key=null;this.url=null;this.cache={};this.events=new D.default;this.call=null;this.socket=null;this.account=null;this.version="v1";this.loading=!0;this.authing=null;this.authKey=null;this.shareKey=null;this.customer=null;this.presences={};this.connecting=null;this.options={path:"/ws",cors:!0,agent:!0,reconnect:!0,transports:["websocket"],withCredentials:!0};t&&(this.url=t),e&&(this.version=e),this.build=this.build.bind(this),this.fetch=this.fetch.bind(this),this.wsFetch=this.wsFetch.bind(this),this.on=this.on.bind(this),this.off=this.off.bind(this),this.emit=this.emit.bind(this),this.once=this.once.bind(this),this.addListener=this.events.addListener.bind(this.events),this.removeListener=this.events.removeListener.bind(this.events),this.get=this.get.bind(this),this.put=this.put.bind(this),this.post=this.post.bind(this),this.patch=this.patch.bind(this),this.delete=this.delete.bind(this),this.AI=A(this),this.Stat=M(this),this.build()}build(){if(this.__resolveConnecting=null,this.connecting=new Promise(e=>{this.__resolveConnecting=e}),!this.url)return;let t=R.default.connect(`${this.url}`,this.options);t.on("connect",async()=>{this.authing||(this.authing=this.auth(this.authKey,this.shareKey),await this.authing,this.authing=null,this.__resolveConnecting())}),t.on("disconnect",()=>{this.connecting=new Promise(e=>{this.__resolveConnecting=e})}),this.socket=t}async auth(){this.loading=!0,this.events.emit("loading",!0);let t=await this.get("/auth",{key:this.key},!1,!1);t?.user&&(this.user=t.user,this.events.emit("user",t.user)),this.loading=!1,this.events.emit("loading",!1),typeof window<"u"&&(window.chirper=this)}async fetch(t,e,i={},o=!1){if(["patch","put","delete","post"].includes(t.toLowerCase())&&(o=!1),o&&this.cache[`${t}${e}${JSON.stringify(i)}`])return this.cache[`${t}${e}${JSON.stringify(i)}`];delete this.cache[`${t}${e}${JSON.stringify(i)}`],console.time(`[chirper] [fetch] ${t}:${e} ${JSON.stringify(i)}`);let a;try{a=await(await fetch(`${this.url}${e}${`${t}`.toLowerCase()==="get"?`?${new URLSearchParams(i)}`:""}`,{body:`${t}`.toLowerCase()!=="get"?JSON.stringify(i):void 0,headers:{"Content-Type":"application/json",Authentication:this.key?`Bearer ${this.key}`:void 0},credentials:"include"})).json()}catch(h){throw console.timeEnd(`[chirper] [fetch] ${t}:${e} ${JSON.stringify(i)}`),h}if(console.timeEnd(`[chirper] [fetch] ${t}:${e} ${JSON.stringify(i)}`),!a?.success)throw new Error(a.message);return o&&(this.cache[`${t}${e}${JSON.stringify(i)}`]=a,this.cache[`${t}${e}${JSON.stringify(i)}`].then(()=>{typeof o=="number"?setTimeout(()=>{delete this.cache[`${t}${e}${JSON.stringify(i)}`]},o):delete this.cache[`${t}${e}${JSON.stringify(i)}`]})),a.result}async wsFetch(t,e,i={},o=!1,a=!0){if(a&&await this.connecting,a&&await this.authing,a&&!this.account&&e.includes(":account")&&await new Promise(n=>{this.events.once("account",n)}),this.account&&(e=e.replace(":account",this.account?.id)),["patch","put","delete","post"].includes(t.toLowerCase())&&(o=!1),o&&this.cache[`${t}${e}${JSON.stringify(i)}`])return this.cache[`${t}${e}${JSON.stringify(i)}`];delete this.cache[`${t}${e}${JSON.stringify(i)}`];let h=it();console.time(`[chirper] [${h}] ${t}:${e} ${JSON.stringify(i)}`);let v=new Promise((n,$)=>{this.socket.once(h,({success:y,result:c,message:m})=>{if(console.timeEnd(`[chirper] [${h}] ${t}:${e} ${JSON.stringify(i)}`),y)return n(c);$(m)})});return o&&(this.cache[`${t}${e}${JSON.stringify(i)}`]=v,this.cache[`${t}${e}${JSON.stringify(i)}`].then(()=>{typeof o=="number"?setTimeout(()=>{delete this.cache[`${t}${e}${JSON.stringify(i)}`]},o):delete this.cache[`${t}${e}${JSON.stringify(i)}`]})),this.socket.emit("call",h,t.toUpperCase(),e,i),v}on(...t){this.socket.on(...t)}off(...t){this.socket.off(...t)}emit(...t){this.socket.emit(...t)}once(...t){this.socket.once(...t)}get(t,e,...i){return this.wsFetch("GET",`/${this.version}${t}`,e,...i)}put(t,e,...i){return this.wsFetch("PUT",`/${this.version}${t}`,e,...i)}post(t,e,...i){return this.wsFetch("POST",`/${this.version}${t}`,e,...i)}patch(t,e,...i){return this.wsFetch("PATCH",`/${this.version}${t}`,e,...i)}delete(t,e,...i){return this.wsFetch("DELETE",`/${this.version}${t}`,e,...i)}};
|
package/package.json
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
{
|
2
|
+
"name": "@chirper/node",
|
3
|
+
"version": "0.0.1",
|
4
|
+
"description": "",
|
5
|
+
"main": "dist/bundle.js",
|
6
|
+
"scripts": {
|
7
|
+
"dev": "MODE=development node build.js",
|
8
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
9
|
+
"build": "MODE=production node build.js",
|
10
|
+
"storybook": "start-storybook -p 9001"
|
11
|
+
},
|
12
|
+
"author": "",
|
13
|
+
"license": "ISC",
|
14
|
+
"devDependencies": {
|
15
|
+
"@babel/core": "^7.20.12",
|
16
|
+
"@babel/preset-env": "^7.20.2",
|
17
|
+
"@babel/preset-typescript": "^7.0.0",
|
18
|
+
"@tulipjs/eslint-config": "^1.1.1",
|
19
|
+
"chokidar": "^3.5.3",
|
20
|
+
"esbuild": "^0.16.14",
|
21
|
+
"fs-extra": "^10.1.0"
|
22
|
+
},
|
23
|
+
"dependencies": {
|
24
|
+
"@analytics/core": "^0.11.1",
|
25
|
+
"@analytics/visitor-source": "^0.0.5",
|
26
|
+
"analytics": "^0.8.1",
|
27
|
+
"dot-prop": "^6.0.1",
|
28
|
+
"eventemitter3": "^5.0.0",
|
29
|
+
"qs": "^6.11.0",
|
30
|
+
"short-unique-id": "^4.4.4",
|
31
|
+
"url": "^0.11.0"
|
32
|
+
},
|
33
|
+
"peerDependencies": {
|
34
|
+
"socket.io-client": "*"
|
35
|
+
}
|
36
|
+
}
|
package/src/api/AI.ts
ADDED
package/src/api/Stat.ts
ADDED
package/src/index.ts
ADDED
@@ -0,0 +1,437 @@
|
|
1
|
+
|
2
|
+
// socketio client
|
3
|
+
import shortid from 'short-unique-id';
|
4
|
+
import socketio from 'socket.io-client';
|
5
|
+
import { EventEmitter } from 'eventemitter3';
|
6
|
+
|
7
|
+
// create short id
|
8
|
+
const uid = new shortid({ length : 10 });
|
9
|
+
|
10
|
+
// local apis
|
11
|
+
import AI from './api/AI';
|
12
|
+
import Stat from './api/Stat';
|
13
|
+
|
14
|
+
// socket context
|
15
|
+
export default class chirperNode {
|
16
|
+
// ssid
|
17
|
+
private key = null;
|
18
|
+
private url = null;
|
19
|
+
private cache = {};
|
20
|
+
private events = new EventEmitter();
|
21
|
+
|
22
|
+
// cache timeout
|
23
|
+
public call = null;
|
24
|
+
public socket = null;
|
25
|
+
public account = null;
|
26
|
+
public version = `v1`;
|
27
|
+
public loading = true;
|
28
|
+
public authing = null;
|
29
|
+
public authKey = null;
|
30
|
+
public shareKey = null;
|
31
|
+
public customer = null;
|
32
|
+
public presences = {};
|
33
|
+
public connecting = null;
|
34
|
+
|
35
|
+
// authing
|
36
|
+
private __resolveConnecting: any;
|
37
|
+
|
38
|
+
// options
|
39
|
+
public options = {
|
40
|
+
path : '/ws',
|
41
|
+
cors : true,
|
42
|
+
agent : true,
|
43
|
+
reconnect : true,
|
44
|
+
transports : ['websocket'],
|
45
|
+
withCredentials : true,
|
46
|
+
};
|
47
|
+
|
48
|
+
/**
|
49
|
+
* constructor
|
50
|
+
*
|
51
|
+
* @param props
|
52
|
+
*/
|
53
|
+
constructor({ url, version }: { url?: string, version?: string }) {
|
54
|
+
// set keys
|
55
|
+
if (url) this.url = url;
|
56
|
+
if (version) this.version = version;
|
57
|
+
|
58
|
+
// call/fetch
|
59
|
+
this.build = this.build.bind(this);
|
60
|
+
this.fetch = this.fetch.bind(this);
|
61
|
+
this.wsFetch = this.wsFetch.bind(this);
|
62
|
+
|
63
|
+
// bind event methods
|
64
|
+
this.on = this.on.bind(this);
|
65
|
+
this.off = this.off.bind(this);
|
66
|
+
this.emit = this.emit.bind(this);
|
67
|
+
this.once = this.once.bind(this);
|
68
|
+
|
69
|
+
// add change listener
|
70
|
+
this.addListener = this.events.addListener.bind(this.events);
|
71
|
+
this.removeListener = this.events.removeListener.bind(this.events);
|
72
|
+
|
73
|
+
// bind call methods
|
74
|
+
this.get = this.get.bind(this);
|
75
|
+
this.put = this.put.bind(this);
|
76
|
+
this.post = this.post.bind(this);
|
77
|
+
this.patch = this.patch.bind(this);
|
78
|
+
this.delete = this.delete.bind(this);
|
79
|
+
|
80
|
+
// api
|
81
|
+
this.AI = AI(this);
|
82
|
+
this.Stat = Stat(this);
|
83
|
+
|
84
|
+
// build
|
85
|
+
this.build();
|
86
|
+
}
|
87
|
+
|
88
|
+
|
89
|
+
////////////////////////////////////////////////////////////////////////
|
90
|
+
//
|
91
|
+
// CALL FUNCTIONALITY
|
92
|
+
//
|
93
|
+
////////////////////////////////////////////////////////////////////////
|
94
|
+
|
95
|
+
/**
|
96
|
+
* build functionality
|
97
|
+
*/
|
98
|
+
build() {
|
99
|
+
// initial authing
|
100
|
+
this.__resolveConnecting = null;
|
101
|
+
this.connecting = new Promise((resolve) => {
|
102
|
+
this.__resolveConnecting = resolve;
|
103
|
+
});
|
104
|
+
|
105
|
+
// check url
|
106
|
+
if (!this.url) return;
|
107
|
+
|
108
|
+
// connect
|
109
|
+
const actualSocket = socketio.connect(`${this.url}`, this.options);
|
110
|
+
|
111
|
+
// on connect
|
112
|
+
actualSocket.on('connect', async () => {
|
113
|
+
// check authing
|
114
|
+
if (this.authing) return;
|
115
|
+
|
116
|
+
// load
|
117
|
+
this.authing = this.auth(this.authKey, this.shareKey);
|
118
|
+
|
119
|
+
// await
|
120
|
+
await this.authing;
|
121
|
+
|
122
|
+
// set
|
123
|
+
this.authing = null;
|
124
|
+
|
125
|
+
// resolve
|
126
|
+
this.__resolveConnecting();
|
127
|
+
});
|
128
|
+
actualSocket.on('disconnect', () => {
|
129
|
+
// reset promise
|
130
|
+
this.connecting = new Promise((resolve) => {
|
131
|
+
this.__resolveConnecting = resolve;
|
132
|
+
});
|
133
|
+
});
|
134
|
+
|
135
|
+
// actual socket
|
136
|
+
this.socket = actualSocket;
|
137
|
+
}
|
138
|
+
|
139
|
+
/**
|
140
|
+
* authenticate api
|
141
|
+
*
|
142
|
+
* @param key
|
143
|
+
* @param authKey
|
144
|
+
*/
|
145
|
+
async auth() {
|
146
|
+
// set loading
|
147
|
+
this.loading = true;
|
148
|
+
this.events.emit('loading', true);
|
149
|
+
|
150
|
+
// load auth
|
151
|
+
const auth = await this.get(`/auth`, {
|
152
|
+
key : this.key,
|
153
|
+
}, false, false);
|
154
|
+
|
155
|
+
// set user
|
156
|
+
if (auth?.user) {
|
157
|
+
this.user = auth.user;
|
158
|
+
this.events.emit('user', auth.user);
|
159
|
+
}
|
160
|
+
|
161
|
+
// set loading
|
162
|
+
this.loading = false;
|
163
|
+
this.events.emit('loading', false);
|
164
|
+
|
165
|
+
// check typeof
|
166
|
+
if (typeof window !== 'undefined') window.chirper = this;
|
167
|
+
}
|
168
|
+
|
169
|
+
/**
|
170
|
+
* fetch from http api
|
171
|
+
*
|
172
|
+
* @param method
|
173
|
+
* @param path
|
174
|
+
* @param data
|
175
|
+
* @param cache
|
176
|
+
*/
|
177
|
+
async fetch(method, path, data = {}, cache = false) {
|
178
|
+
// check cache
|
179
|
+
if (['patch', 'put', 'delete', 'post'].includes(method.toLowerCase())) cache = false;
|
180
|
+
|
181
|
+
// check cache
|
182
|
+
if (cache && this.cache[`${method}${path}${JSON.stringify(data)}`]) {
|
183
|
+
// return await
|
184
|
+
return this.cache[`${method}${path}${JSON.stringify(data)}`];
|
185
|
+
} else {
|
186
|
+
// delete cache
|
187
|
+
delete this.cache[`${method}${path}${JSON.stringify(data)}`];
|
188
|
+
}
|
189
|
+
|
190
|
+
// doing call
|
191
|
+
console.time(`[chirper] [fetch] ${method}:${path} ${JSON.stringify(data)}`);
|
192
|
+
|
193
|
+
// result
|
194
|
+
let result;
|
195
|
+
|
196
|
+
// try/catch
|
197
|
+
try {
|
198
|
+
// create fetch
|
199
|
+
const res = await fetch(`${this.url}${path}${`${method}`.toLowerCase() === 'get' ? `?${new URLSearchParams(data)}` : ''}`, {
|
200
|
+
body : `${method}`.toLowerCase() !== 'get' ? JSON.stringify(data) : undefined,
|
201
|
+
headers : {
|
202
|
+
'Content-Type' : 'application/json',
|
203
|
+
'Authentication' : this.key ? `Bearer ${this.key}` : undefined,
|
204
|
+
},
|
205
|
+
credentials : 'include',
|
206
|
+
});
|
207
|
+
|
208
|
+
// get response
|
209
|
+
result = await res.json();
|
210
|
+
} catch (e) {
|
211
|
+
// doing call
|
212
|
+
console.timeEnd(`[chirper] [fetch] ${method}:${path} ${JSON.stringify(data)}`);
|
213
|
+
|
214
|
+
// throw error
|
215
|
+
throw e;
|
216
|
+
}
|
217
|
+
|
218
|
+
// doing call
|
219
|
+
console.timeEnd(`[chirper] [fetch] ${method}:${path} ${JSON.stringify(data)}`);
|
220
|
+
|
221
|
+
// check message
|
222
|
+
if (!result?.success) throw new Error(result.message);
|
223
|
+
|
224
|
+
// check cache
|
225
|
+
if (cache) {
|
226
|
+
// add to call cache
|
227
|
+
this.cache[`${method}${path}${JSON.stringify(data)}`] = result;
|
228
|
+
|
229
|
+
// remove after timeout
|
230
|
+
this.cache[`${method}${path}${JSON.stringify(data)}`].then(() => {
|
231
|
+
// check if timed cache
|
232
|
+
if (typeof cache === 'number') {
|
233
|
+
// remove after timeout
|
234
|
+
setTimeout(() => {
|
235
|
+
// delete
|
236
|
+
delete this.cache[`${method}${path}${JSON.stringify(data)}`];
|
237
|
+
}, cache);
|
238
|
+
} else {
|
239
|
+
// delete
|
240
|
+
delete this.cache[`${method}${path}${JSON.stringify(data)}`];
|
241
|
+
}
|
242
|
+
});
|
243
|
+
}
|
244
|
+
|
245
|
+
// return result
|
246
|
+
return result.result;
|
247
|
+
}
|
248
|
+
|
249
|
+
/**
|
250
|
+
* call api method
|
251
|
+
*
|
252
|
+
* @param method
|
253
|
+
* @param path
|
254
|
+
* @param data
|
255
|
+
* @param cache
|
256
|
+
* @returns
|
257
|
+
*/
|
258
|
+
async wsFetch(method, path, data = {}, cache = false, waitForAuth = true) {
|
259
|
+
// await connecting
|
260
|
+
if (waitForAuth) await this.connecting;
|
261
|
+
|
262
|
+
// wait for auth
|
263
|
+
if (waitForAuth) await this.authing;
|
264
|
+
|
265
|
+
// check account
|
266
|
+
if (waitForAuth && !this.account && path.includes(':account')) {
|
267
|
+
// wait for account
|
268
|
+
await new Promise((resolve) => {
|
269
|
+
// this once
|
270
|
+
this.events.once('account', resolve);
|
271
|
+
});
|
272
|
+
}
|
273
|
+
|
274
|
+
// fix path
|
275
|
+
if (this.account) path = path.replace(':account', this.account?.id);
|
276
|
+
|
277
|
+
// check cache
|
278
|
+
if (['patch', 'put', 'delete', 'post'].includes(method.toLowerCase())) cache = false;
|
279
|
+
|
280
|
+
// check cache
|
281
|
+
if (cache && this.cache[`${method}${path}${JSON.stringify(data)}`]) {
|
282
|
+
// return await
|
283
|
+
return this.cache[`${method}${path}${JSON.stringify(data)}`];
|
284
|
+
} else {
|
285
|
+
// delete cache
|
286
|
+
delete this.cache[`${method}${path}${JSON.stringify(data)}`];
|
287
|
+
}
|
288
|
+
|
289
|
+
// get id
|
290
|
+
const id = uid();
|
291
|
+
|
292
|
+
// doing call
|
293
|
+
console.time(`[chirper] [${id}] ${method}:${path} ${JSON.stringify(data)}`);
|
294
|
+
|
295
|
+
// create promise
|
296
|
+
const result = new Promise((resolve, reject) => {
|
297
|
+
// resolve
|
298
|
+
this.socket.once(id, ({ success, result, message }) => {
|
299
|
+
// time end
|
300
|
+
console.timeEnd(`[chirper] [${id}] ${method}:${path} ${JSON.stringify(data)}`);
|
301
|
+
|
302
|
+
// check result
|
303
|
+
if (success) return resolve(result);
|
304
|
+
|
305
|
+
// reject
|
306
|
+
reject(message);
|
307
|
+
});
|
308
|
+
});
|
309
|
+
|
310
|
+
// check cache
|
311
|
+
if (cache) {
|
312
|
+
// add to call cache
|
313
|
+
this.cache[`${method}${path}${JSON.stringify(data)}`] = result;
|
314
|
+
|
315
|
+
// remove after timeout
|
316
|
+
this.cache[`${method}${path}${JSON.stringify(data)}`].then(() => {
|
317
|
+
// check if timed cache
|
318
|
+
if (typeof cache === 'number') {
|
319
|
+
// remove after timeout
|
320
|
+
setTimeout(() => {
|
321
|
+
// delete
|
322
|
+
delete this.cache[`${method}${path}${JSON.stringify(data)}`];
|
323
|
+
}, cache);
|
324
|
+
} else {
|
325
|
+
// delete
|
326
|
+
delete this.cache[`${method}${path}${JSON.stringify(data)}`];
|
327
|
+
}
|
328
|
+
});
|
329
|
+
}
|
330
|
+
|
331
|
+
// emit
|
332
|
+
this.socket.emit('call', id, method.toUpperCase(), path, data);
|
333
|
+
|
334
|
+
// return result
|
335
|
+
return result;
|
336
|
+
}
|
337
|
+
|
338
|
+
/**
|
339
|
+
* on
|
340
|
+
*
|
341
|
+
* @param args
|
342
|
+
*/
|
343
|
+
on(...args) {
|
344
|
+
// call to socket
|
345
|
+
this.socket.on(...args);
|
346
|
+
}
|
347
|
+
|
348
|
+
/**
|
349
|
+
* off
|
350
|
+
*
|
351
|
+
* @param args
|
352
|
+
*/
|
353
|
+
off(...args) {
|
354
|
+
// call to socket
|
355
|
+
this.socket.off(...args);
|
356
|
+
}
|
357
|
+
|
358
|
+
/**
|
359
|
+
* emit
|
360
|
+
*
|
361
|
+
* @param args
|
362
|
+
*/
|
363
|
+
emit(...args) {
|
364
|
+
// call to socket
|
365
|
+
this.socket.emit(...args);
|
366
|
+
}
|
367
|
+
|
368
|
+
/**
|
369
|
+
* once
|
370
|
+
*
|
371
|
+
* @param args
|
372
|
+
*/
|
373
|
+
once(...args) {
|
374
|
+
// call to socket
|
375
|
+
this.socket.once(...args);
|
376
|
+
}
|
377
|
+
|
378
|
+
/**
|
379
|
+
* api get
|
380
|
+
*
|
381
|
+
* @param path
|
382
|
+
* @param data
|
383
|
+
* @returns
|
384
|
+
*/
|
385
|
+
get(path, data, ...args) {
|
386
|
+
// return get
|
387
|
+
return this.wsFetch('GET', `/${this.version}${path}`, data, ...args);
|
388
|
+
}
|
389
|
+
|
390
|
+
/**
|
391
|
+
* api put
|
392
|
+
*
|
393
|
+
* @param path
|
394
|
+
* @param data
|
395
|
+
* @returns
|
396
|
+
*/
|
397
|
+
put(path, data, ...args) {
|
398
|
+
// return put
|
399
|
+
return this.wsFetch('PUT', `/${this.version}${path}`, data, ...args);
|
400
|
+
}
|
401
|
+
|
402
|
+
/**
|
403
|
+
* api post
|
404
|
+
*
|
405
|
+
* @param path
|
406
|
+
* @param data
|
407
|
+
* @returns
|
408
|
+
*/
|
409
|
+
post(path, data, ...args) {
|
410
|
+
// return post
|
411
|
+
return this.wsFetch('POST', `/${this.version}${path}`, data, ...args);
|
412
|
+
}
|
413
|
+
|
414
|
+
/**
|
415
|
+
* api post
|
416
|
+
*
|
417
|
+
* @param path
|
418
|
+
* @param data
|
419
|
+
* @returns
|
420
|
+
*/
|
421
|
+
patch(path, data, ...args) {
|
422
|
+
// return patch
|
423
|
+
return this.wsFetch('PATCH', `/${this.version}${path}`, data, ...args);
|
424
|
+
}
|
425
|
+
|
426
|
+
/**
|
427
|
+
* api post
|
428
|
+
*
|
429
|
+
* @param path
|
430
|
+
* @param data
|
431
|
+
* @returns
|
432
|
+
*/
|
433
|
+
delete(path, data, ...args) {
|
434
|
+
// return delete
|
435
|
+
return this.wsFetch('DELETE', `/${this.version}${path}`, data, ...args);
|
436
|
+
}
|
437
|
+
}
|