UNPKG

6.59 kBJavaScriptView Raw
1/**
2 * Copyright (c) 2015 Tiinusen
3 *
4 * Licensed under The MIT License
5 * For full copyright and license information, please see the LICENSE
6 * Redistributions of files must retain the above copyright notice.
7 *
8 * @copyright Copyright (c) 2015 Tiinusen
9 * @link https://github.com/cakejsframework/cakejs
10 * @license http://www.opensource.org/licenses/mit-license.php MIT License
11 */
12
13var itemIndexCounter = 1;
14var sio = io.connect();
15sio.on('error', function(error){
16 if(error === "BAD"){
17 window.location.reload(true);
18 }
19});
20
21class Request
22{
23 constructor(args)
24 {
25 this.controller = null;
26 this.action = null;
27 this.arguments = [];
28 this.data = null;
29 var _args = new Array();
30 for(var key in args){
31 if(/^[0-9]{1,}$/.test(key)){
32 _args.push(args[key]);
33 }
34 }
35 do{
36 var item = _args.shift();
37 if(typeof item === 'string'){
38 if(this.controller === null){
39 this.controller = item;
40 }else if(this.action === null){
41 this.action = item;
42 }else{
43 this.arguments.push(item);
44 }
45 }else if(typeof item === 'object'){
46 if(this.controller === null){
47 if('controller' in item){
48 this.controller = item.controller;
49 delete item.controller;
50 }
51 if('action' in item){
52 this.action = item.action;
53 delete item.action;
54 }
55 for(var key in item){
56 this.arguments.push(item[key]);
57 }
58 }else{
59 this.data = item;
60 }
61 }
62 }while(_args.length > 0);
63 }
64}
65
66class Item
67{
68 constructor(args, timeout)
69 {
70 this.index = itemIndexCounter++;
71 this.request = new Request(args);
72 this.timeout = typeof timeout === 'undefined' ? 60*1000 : timeout;
73 this.resolve = null;
74 this.reject = null;
75 }
76 _run(){return new Promise((resolve, reject) => {reject("Not Implemented");})}
77 run()
78 {
79 return new Promise((resolve, reject) => {
80 if(this.request.controller === null)
81 return reject("Post failed due to invalid controller name");
82 var timeout = setTimeout(() => {
83 timeout = null;
84 }, this.timeout);
85 this._run().then((response) => {
86 if(timeout !== null){
87 clearTimeout(timeout);
88 timeout = null;
89 }
90 resolve(response);
91 },(error) => {
92 if(timeout !== null){
93 clearTimeout(timeout);
94 timeout = null;
95 }
96 reject(error);
97 });
98 });
99 }
100}
101
102class CallItem extends Item
103{
104 _run()
105 {
106 return new Promise((resolve, reject) => {
107 this.resolve = resolve;
108 this.reject = reject;
109 try{
110 sio.emit('WebSocketRequest', {
111 index: this.index,
112 request: this.request
113 });
114 }catch(e){
115 this.reject('Call to '+this.request.controller+'->'+this.request.action+' failed');
116 }
117 });
118 }
119}
120
121class PostItem extends Item
122{
123 _run()
124 {
125 return new Promise((resolve, reject) => {
126 this.resolve = resolve;
127 this.reject = reject;
128 try{
129 $.ajax({
130 url: '/'+this.request.controller+"/"+(this.request.action===null?'':this.request.action)+"/"+this.request.arguments.join("/"),
131 method: 'POST',
132 data: typeof this.request.data === 'undefined'?null:this.request.data
133 }).done((data) => {
134 this.resolve(data);
135 }).fail((e) => {
136 if(e.status === 200){
137 this.resolve();
138 }else if(e.status === 520){
139 try{
140 this.reject(JSON.parse(e.responseText));
141 }catch(e){
142 this.reject('Post to '+this.request.controller+'->'+this.request.action+' failed');
143 }
144 }else{
145 this.reject('Post to '+this.request.controller+'->'+this.request.action+' failed');
146 }
147 });
148 }catch(e){
149 this.reject('Post to '+this.request.controller+'->'+this.request.action+' failed');
150 }
151 });
152 }
153}
154
155class GetItem extends Item
156{
157 _run()
158 {
159 return new Promise((resolve, reject) => {
160 this.resolve = resolve;
161 this.reject = reject;
162 try{
163 $.ajax({
164 url: '/'+this.request.controller+"/"+(this.request.action===null?'':this.request.action)+"/"+this.request.arguments.join("/"),
165 method: 'GET'
166 }).done((data) => {
167 this.resolve(data);
168 }).fail((e) => {
169 if(e.status === 200){
170 this.resolve();
171 }else if(e.status === 520){
172 try{
173 this.reject(JSON.parse(e.responseText));
174 }catch(e){
175 this.reject('Get to '+this.request.controller+'->'+this.request.action+' failed');
176 }
177 }else{
178 this.reject('Get to '+this.request.controller+'->'+this.request.action+' failed');
179 }
180 });
181 }catch(e){
182 this.reject('Get to '+this.request.controller+'->'+this.request.action+' failed');
183 }
184 });
185 }
186}
187
188export default class Client
189{
190 static _items = {};
191 static _events = {};
192
193 static initialize()
194 {
195 sio.on('WebSocketResponse', (response) => {
196 if(typeof response === 'object' && 'index' in response && response.index in Client._items){
197 if('error' in response){
198 if(response.error === null){
199 console.error("CALL FAILED WITH 500 (Internal Server Error)");
200 Client._items[response.index].reject('Call to '+Client._items[response.index].request.controller+'->'+Client._items[response.index].request.action+' failed');
201 }else{
202 Client._items[response.index].reject(response.error);
203 }
204 }else{
205 Client._items[response.index].resolve(response);
206 }
207 }
208 });
209 sio.on('WebSocketEmit', (response) => {
210 if(!('event' in response)){
211 return;
212 }
213 if(!(response.event in Client._events)){
214 return;
215 }
216 for(var i = 0; i < Client._events[response.event].length; i++){
217 var callback = Client._events[response.event][i];
218 callback.apply(callback, response.arguments);
219 }
220 });
221 }
222
223 static _invoke(item)
224 {
225 return new Promise((resolve, reject) => {
226 Client._items[item.index] = item;
227 item.run().then(response => {
228 delete Client._items[item.index];
229 if(response !== null && typeof response === 'object' && 'data' in response){
230 resolve(response.data);
231 }
232 return resolve(response);
233 },error => {
234 delete Client._items[item.index];
235 reject(error);
236 });
237 });
238 }
239
240 static call()
241 {
242 return Client._invoke(new CallItem(arguments, 130*1000));
243 }
244
245 static post()
246 {
247 return Client._invoke(new PostItem(arguments, 20*1000));
248 }
249
250 static get()
251 {
252 return Client._invoke(new GetItem(arguments, 20*1000));
253 }
254
255 static on(event, callback)
256 {
257 if(typeof event !== 'string')
258 throw "Expected first argument to be a string";
259 callback = typeof callback !== 'function' ? null : callback;
260 if(callback === null){
261 if(event in Client._events){
262 delete Client._events[event];
263 }
264 }else{
265 if(!(event in Client._events)){
266 Client._events[event] = [];
267 }
268 Client._events[event].push(callback);
269 }
270 }
271}
272
273Client.initialize();
\No newline at end of file