@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 ADDED
@@ -0,0 +1,3 @@
1
+ {
2
+ "presets": ["@babel/preset-env", "@babel/preset-typescript"]
3
+ }
package/.browserlistrc ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "browserslist": [
3
+ "last 1 version",
4
+ "> 1%",
5
+ "maintained node versions",
6
+ "not dead"
7
+ ]
8
+ }
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
@@ -0,0 +1,3 @@
1
+ /node_modules/
2
+ /dist/
3
+ /docs/
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
@@ -0,0 +1,14 @@
1
+
2
+ /**
3
+ * key api
4
+ */
5
+ export default (api) => ({
6
+ prompt : (opts) => {
7
+ // return promise
8
+ return api.post(`/:account/ai`, opts);
9
+ },
10
+ image : (opts) => {
11
+ // return promise
12
+ return api.post(`/:account/ai/image`, opts);
13
+ },
14
+ });
@@ -0,0 +1,9 @@
1
+
2
+ /**
3
+ * key api
4
+ */
5
+ export default (api) => ({
6
+ get : (metric, from = null, to = null) => {
7
+ return api.get(`/:account/stat/${metric}`, { from, to });
8
+ },
9
+ });
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
+ }