UNPKG

44.4 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('rxjs'), require('rxjs/operators'), require('brolog'), require('state-switch')) :
3 typeof define === 'function' && define.amd ? define('@chatie/angular', ['exports', '@angular/core', 'rxjs', 'rxjs/operators', 'brolog', 'state-switch'], factory) :
4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.chatie = global.chatie || {}, global.chatie.angular = {}), global.ng.core, global.rxjs, global.rxjs.operators, global.brolog, global.stateSwitch));
5}(this, (function (exports, core, rxjs, operators, brolog, stateSwitch) { 'use strict';
6
7 /*! *****************************************************************************
8 Copyright (c) Microsoft Corporation.
9
10 Permission to use, copy, modify, and/or distribute this software for any
11 purpose with or without fee is hereby granted.
12
13 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
14 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
16 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
18 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 PERFORMANCE OF THIS SOFTWARE.
20 ***************************************************************************** */
21 /* global Reflect, Promise */
22 var extendStatics = function (d, b) {
23 extendStatics = Object.setPrototypeOf ||
24 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
25 function (d, b) { for (var p in b)
26 if (Object.prototype.hasOwnProperty.call(b, p))
27 d[p] = b[p]; };
28 return extendStatics(d, b);
29 };
30 function __extends(d, b) {
31 extendStatics(d, b);
32 function __() { this.constructor = d; }
33 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
34 }
35 var __assign = function () {
36 __assign = Object.assign || function __assign(t) {
37 for (var s, i = 1, n = arguments.length; i < n; i++) {
38 s = arguments[i];
39 for (var p in s)
40 if (Object.prototype.hasOwnProperty.call(s, p))
41 t[p] = s[p];
42 }
43 return t;
44 };
45 return __assign.apply(this, arguments);
46 };
47 function __rest(s, e) {
48 var t = {};
49 for (var p in s)
50 if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
51 t[p] = s[p];
52 if (s != null && typeof Object.getOwnPropertySymbols === "function")
53 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
54 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
55 t[p[i]] = s[p[i]];
56 }
57 return t;
58 }
59 function __decorate(decorators, target, key, desc) {
60 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
61 if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
62 r = Reflect.decorate(decorators, target, key, desc);
63 else
64 for (var i = decorators.length - 1; i >= 0; i--)
65 if (d = decorators[i])
66 r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
67 return c > 3 && r && Object.defineProperty(target, key, r), r;
68 }
69 function __param(paramIndex, decorator) {
70 return function (target, key) { decorator(target, key, paramIndex); };
71 }
72 function __metadata(metadataKey, metadataValue) {
73 if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
74 return Reflect.metadata(metadataKey, metadataValue);
75 }
76 function __awaiter(thisArg, _arguments, P, generator) {
77 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
78 return new (P || (P = Promise))(function (resolve, reject) {
79 function fulfilled(value) { try {
80 step(generator.next(value));
81 }
82 catch (e) {
83 reject(e);
84 } }
85 function rejected(value) { try {
86 step(generator["throw"](value));
87 }
88 catch (e) {
89 reject(e);
90 } }
91 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
92 step((generator = generator.apply(thisArg, _arguments || [])).next());
93 });
94 }
95 function __generator(thisArg, body) {
96 var _ = { label: 0, sent: function () { if (t[0] & 1)
97 throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
98 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g;
99 function verb(n) { return function (v) { return step([n, v]); }; }
100 function step(op) {
101 if (f)
102 throw new TypeError("Generator is already executing.");
103 while (_)
104 try {
105 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done)
106 return t;
107 if (y = 0, t)
108 op = [op[0] & 2, t.value];
109 switch (op[0]) {
110 case 0:
111 case 1:
112 t = op;
113 break;
114 case 4:
115 _.label++;
116 return { value: op[1], done: false };
117 case 5:
118 _.label++;
119 y = op[1];
120 op = [0];
121 continue;
122 case 7:
123 op = _.ops.pop();
124 _.trys.pop();
125 continue;
126 default:
127 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
128 _ = 0;
129 continue;
130 }
131 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) {
132 _.label = op[1];
133 break;
134 }
135 if (op[0] === 6 && _.label < t[1]) {
136 _.label = t[1];
137 t = op;
138 break;
139 }
140 if (t && _.label < t[2]) {
141 _.label = t[2];
142 _.ops.push(op);
143 break;
144 }
145 if (t[2])
146 _.ops.pop();
147 _.trys.pop();
148 continue;
149 }
150 op = body.call(thisArg, _);
151 }
152 catch (e) {
153 op = [6, e];
154 y = 0;
155 }
156 finally {
157 f = t = 0;
158 }
159 if (op[0] & 5)
160 throw op[1];
161 return { value: op[0] ? op[1] : void 0, done: true };
162 }
163 }
164 var __createBinding = Object.create ? (function (o, m, k, k2) {
165 if (k2 === undefined)
166 k2 = k;
167 Object.defineProperty(o, k2, { enumerable: true, get: function () { return m[k]; } });
168 }) : (function (o, m, k, k2) {
169 if (k2 === undefined)
170 k2 = k;
171 o[k2] = m[k];
172 });
173 function __exportStar(m, o) {
174 for (var p in m)
175 if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p))
176 __createBinding(o, m, p);
177 }
178 function __values(o) {
179 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
180 if (m)
181 return m.call(o);
182 if (o && typeof o.length === "number")
183 return {
184 next: function () {
185 if (o && i >= o.length)
186 o = void 0;
187 return { value: o && o[i++], done: !o };
188 }
189 };
190 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
191 }
192 function __read(o, n) {
193 var m = typeof Symbol === "function" && o[Symbol.iterator];
194 if (!m)
195 return o;
196 var i = m.call(o), r, ar = [], e;
197 try {
198 while ((n === void 0 || n-- > 0) && !(r = i.next()).done)
199 ar.push(r.value);
200 }
201 catch (error) {
202 e = { error: error };
203 }
204 finally {
205 try {
206 if (r && !r.done && (m = i["return"]))
207 m.call(i);
208 }
209 finally {
210 if (e)
211 throw e.error;
212 }
213 }
214 return ar;
215 }
216 function __spread() {
217 for (var ar = [], i = 0; i < arguments.length; i++)
218 ar = ar.concat(__read(arguments[i]));
219 return ar;
220 }
221 function __spreadArrays() {
222 for (var s = 0, i = 0, il = arguments.length; i < il; i++)
223 s += arguments[i].length;
224 for (var r = Array(s), k = 0, i = 0; i < il; i++)
225 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
226 r[k] = a[j];
227 return r;
228 }
229 ;
230 function __await(v) {
231 return this instanceof __await ? (this.v = v, this) : new __await(v);
232 }
233 function __asyncGenerator(thisArg, _arguments, generator) {
234 if (!Symbol.asyncIterator)
235 throw new TypeError("Symbol.asyncIterator is not defined.");
236 var g = generator.apply(thisArg, _arguments || []), i, q = [];
237 return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
238 function verb(n) { if (g[n])
239 i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
240 function resume(n, v) { try {
241 step(g[n](v));
242 }
243 catch (e) {
244 settle(q[0][3], e);
245 } }
246 function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
247 function fulfill(value) { resume("next", value); }
248 function reject(value) { resume("throw", value); }
249 function settle(f, v) { if (f(v), q.shift(), q.length)
250 resume(q[0][0], q[0][1]); }
251 }
252 function __asyncDelegator(o) {
253 var i, p;
254 return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
255 function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
256 }
257 function __asyncValues(o) {
258 if (!Symbol.asyncIterator)
259 throw new TypeError("Symbol.asyncIterator is not defined.");
260 var m = o[Symbol.asyncIterator], i;
261 return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
262 function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
263 function settle(resolve, reject, d, v) { Promise.resolve(v).then(function (v) { resolve({ value: v, done: d }); }, reject); }
264 }
265 function __makeTemplateObject(cooked, raw) {
266 if (Object.defineProperty) {
267 Object.defineProperty(cooked, "raw", { value: raw });
268 }
269 else {
270 cooked.raw = raw;
271 }
272 return cooked;
273 }
274 ;
275 var __setModuleDefault = Object.create ? (function (o, v) {
276 Object.defineProperty(o, "default", { enumerable: true, value: v });
277 }) : function (o, v) {
278 o["default"] = v;
279 };
280 function __importStar(mod) {
281 if (mod && mod.__esModule)
282 return mod;
283 var result = {};
284 if (mod != null)
285 for (var k in mod)
286 if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k))
287 __createBinding(result, mod, k);
288 __setModuleDefault(result, mod);
289 return result;
290 }
291 function __importDefault(mod) {
292 return (mod && mod.__esModule) ? mod : { default: mod };
293 }
294 function __classPrivateFieldGet(receiver, privateMap) {
295 if (!privateMap.has(receiver)) {
296 throw new TypeError("attempted to get private field on non-instance");
297 }
298 return privateMap.get(receiver);
299 }
300 function __classPrivateFieldSet(receiver, privateMap, value) {
301 if (!privateMap.has(receiver)) {
302 throw new TypeError("attempted to set private field on non-instance");
303 }
304 privateMap.set(receiver, value);
305 return value;
306 }
307
308 /**
309 * This file was auto generated from scripts/generate-version.sh
310 */
311 var VERSION = '0.7.4';
312
313 var ReadyState;
314 (function (ReadyState) {
315 ReadyState[ReadyState["CLOSED"] = WebSocket.CLOSED] = "CLOSED";
316 ReadyState[ReadyState["CLOSING"] = WebSocket.CLOSING] = "CLOSING";
317 ReadyState[ReadyState["CONNECTING"] = WebSocket.CONNECTING] = "CONNECTING";
318 ReadyState[ReadyState["OPEN"] = WebSocket.OPEN] = "OPEN";
319 })(ReadyState || (ReadyState = {}));
320 var IoService = /** @class */ (function () {
321 function IoService() {
322 this.autoReconnect = true;
323 this.log = brolog.Brolog.instance();
324 this.CONNECT_TIMEOUT = 10 * 1000; // 10 seconds
325 this.ENDPOINT = 'wss://api.chatie.io/v0/websocket/token/';
326 this.PROTOCOL = 'web|0.0.1';
327 this.sendBuffer = [];
328 this.log.verbose('IoService', 'constructor()');
329 }
330 Object.defineProperty(IoService.prototype, "readyState", {
331 get: function () {
332 return this._readyState.asObservable();
333 },
334 enumerable: false,
335 configurable: true
336 });
337 IoService.prototype.init = function () {
338 return __awaiter(this, void 0, void 0, function () {
339 var e_1;
340 var _this = this;
341 return __generator(this, function (_b) {
342 switch (_b.label) {
343 case 0:
344 this.log.verbose('IoService', 'init()');
345 if (this.state) {
346 throw new Error('re-init');
347 }
348 this.snapshot = {
349 readyState: ReadyState.CLOSED,
350 event: null,
351 };
352 this._readyState = new rxjs.BehaviorSubject(ReadyState.CLOSED);
353 this.state = new stateSwitch.StateSwitch('IoService', this.log);
354 this.state.setLog(this.log);
355 _b.label = 1;
356 case 1:
357 _b.trys.push([1, 4, , 5]);
358 return [4 /*yield*/, this.initStateDealer()];
359 case 2:
360 _b.sent();
361 return [4 /*yield*/, this.initRxSocket()];
362 case 3:
363 _b.sent();
364 return [3 /*break*/, 5];
365 case 4:
366 e_1 = _b.sent();
367 this.log.silly('IoService', 'init() exception: %s', e_1.message);
368 throw e_1;
369 case 5:
370 this.readyState.subscribe(function (s) {
371 _this.log.silly('IoService', 'init() readyState.subscribe(%s)', ReadyState[s]);
372 _this.snapshot.readyState = s;
373 });
374 // IMPORTANT: subscribe to event and make it HOT!
375 this.event.subscribe(function (s) {
376 _this.log.silly('IoService', 'init() event.subscribe({name:%s})', s.name);
377 _this.snapshot.event = s;
378 });
379 return [2 /*return*/];
380 }
381 });
382 });
383 };
384 IoService.prototype.token = function (newToken) {
385 this.log.silly('IoService', 'token(%s)', newToken);
386 if (newToken) {
387 this._token = newToken;
388 return;
389 }
390 return this._token;
391 };
392 IoService.prototype.start = function () {
393 return __awaiter(this, void 0, void 0, function () {
394 var e_2;
395 return __generator(this, function (_b) {
396 switch (_b.label) {
397 case 0:
398 this.log.verbose('IoService', 'start() with token:%s', this._token);
399 if (!this._token) {
400 throw new Error('start() without token');
401 }
402 if (this.state.on()) {
403 throw new Error('state is already ON');
404 }
405 if (this.state.pending()) {
406 throw new Error('state is pending');
407 }
408 this.state.on('pending');
409 this.autoReconnect = true;
410 _b.label = 1;
411 case 1:
412 _b.trys.push([1, 3, , 4]);
413 return [4 /*yield*/, this.connectRxSocket()];
414 case 2:
415 _b.sent();
416 this.state.on(true);
417 return [3 /*break*/, 4];
418 case 3:
419 e_2 = _b.sent();
420 this.log.warn('IoService', 'start() failed:%s', e_2.message);
421 this.state.off(true);
422 return [3 /*break*/, 4];
423 case 4: return [2 /*return*/];
424 }
425 });
426 });
427 };
428 IoService.prototype.stop = function () {
429 return __awaiter(this, void 0, void 0, function () {
430 return __generator(this, function (_b) {
431 switch (_b.label) {
432 case 0:
433 this.log.verbose('IoService', 'stop()');
434 if (this.state.off()) {
435 this.log.warn('IoService', 'stop() state is already off');
436 if (this.state.pending()) {
437 throw new Error('state pending() is true');
438 }
439 return [2 /*return*/];
440 }
441 this.state.off('pending');
442 this.autoReconnect = false;
443 if (!this._websocket) {
444 throw new Error('no websocket');
445 }
446 return [4 /*yield*/, this.socketClose(1000, 'IoService.stop()')];
447 case 1:
448 _b.sent();
449 this.state.off(true);
450 return [2 /*return*/];
451 }
452 });
453 });
454 };
455 IoService.prototype.restart = function () {
456 return __awaiter(this, void 0, void 0, function () {
457 var e_3;
458 return __generator(this, function (_b) {
459 switch (_b.label) {
460 case 0:
461 this.log.verbose('IoService', 'restart()');
462 _b.label = 1;
463 case 1:
464 _b.trys.push([1, 4, , 5]);
465 return [4 /*yield*/, this.stop()];
466 case 2:
467 _b.sent();
468 return [4 /*yield*/, this.start()];
469 case 3:
470 _b.sent();
471 return [3 /*break*/, 5];
472 case 4:
473 e_3 = _b.sent();
474 this.log.error('IoService', 'restart() error:%s', e_3.message);
475 throw e_3;
476 case 5: return [2 /*return*/];
477 }
478 });
479 });
480 };
481 IoService.prototype.initStateDealer = function () {
482 var _this = this;
483 this.log.verbose('IoService', 'initStateDealer()');
484 var isReadyStateOpen = function (s) { return s === ReadyState.OPEN; };
485 this.readyState.pipe(operators.filter(isReadyStateOpen))
486 .subscribe(function (open) { return _this.stateOnOpen(); });
487 };
488 /**
489 * Creates a subject from the specified observer and observable.
490 * - https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/subject.md
491 * Create an Rx.Subject using Subject.create that allows onNext without subscription
492 * A socket implementation (example, don't use)
493 * - http://stackoverflow.com/a/34862286/1123955
494 */
495 IoService.prototype.initRxSocket = function () {
496 return __awaiter(this, void 0, void 0, function () {
497 var observable;
498 var _this = this;
499 return __generator(this, function (_b) {
500 this.log.verbose('IoService', 'initRxSocket()');
501 if (this.event) {
502 throw new Error('re-init is not permitted');
503 }
504 // 1. Mobile Originated. moObserver.next() means mobile is sending
505 this.moObserver = {
506 next: this.socketSend.bind(this),
507 error: this.socketClose.bind(this),
508 complete: this.socketClose.bind(this),
509 };
510 observable = new rxjs.Observable(function (observer) {
511 _this.log.verbose('IoService', 'initRxSocket() Observable.create()');
512 _this.mtObserver = observer;
513 return _this.socketClose.bind(_this);
514 });
515 // 3. Subject for MO & MT Observers
516 this.event = rxjs.Subject.create(this.moObserver, observable.pipe(operators.share()));
517 return [2 /*return*/];
518 });
519 });
520 };
521 IoService.prototype.connectRxSocket = function () {
522 return __awaiter(this, void 0, void 0, function () {
523 var onOpenPromise;
524 var _this = this;
525 return __generator(this, function (_b) {
526 this.log.verbose('IoService', 'connectRxSocket()');
527 // FIXME: check & close the old one
528 if (this._websocket) {
529 throw new Error('already has a websocket');
530 }
531 // if (this.state.target() !== 'open'
532 // || this.state.current() !== 'open'
533 // || this.state.stable()
534 if (this.state.off()) {
535 throw new Error('switch state is off');
536 }
537 else if (!this.state.pending()) {
538 throw new Error('switch state is already ON');
539 }
540 this._websocket = new WebSocket(this.endPoint(), this.PROTOCOL);
541 this.socketUpdateState();
542 onOpenPromise = new Promise(function (resolve, reject) {
543 _this.log.verbose('IoService', 'connectRxSocket() Promise()');
544 var id = setTimeout(function () {
545 _this._websocket = null;
546 var e = new Error('rxSocket connect timeout after '
547 + Math.round(_this.CONNECT_TIMEOUT / 1000));
548 reject(e);
549 }, _this.CONNECT_TIMEOUT); // timeout for connect websocket
550 _this._websocket.onopen = function (e) {
551 _this.log.verbose('IoService', 'connectRxSocket() Promise() WebSocket.onOpen() resolve()');
552 _this.socketUpdateState();
553 clearTimeout(id);
554 resolve();
555 };
556 });
557 // Handle the payload
558 this._websocket.onmessage = this.socketOnMessage.bind(this);
559 // Deal the event
560 this._websocket.onerror = this.socketOnError.bind(this);
561 this._websocket.onclose = this.socketOnClose.bind(this);
562 return [2 /*return*/, onOpenPromise];
563 });
564 });
565 };
566 IoService.prototype.endPoint = function () {
567 var url = this.ENDPOINT + this._token;
568 this.log.verbose('IoService', 'endPoint() => %s', url);
569 return url;
570 };
571 /******************************************************************
572 *
573 * State Event Listeners
574 *
575 */
576 IoService.prototype.stateOnOpen = function () {
577 this.log.verbose('IoService', 'stateOnOpen()');
578 this.socketSendBuffer();
579 this.rpcUpdate('from stateOnOpen()');
580 };
581 /******************************************************************
582 *
583 * Io RPC Methods
584 *
585 */
586 IoService.prototype.rpcDing = function (payload) {
587 return __awaiter(this, void 0, void 0, function () {
588 var e;
589 return __generator(this, function (_b) {
590 this.log.verbose('IoService', 'ding(%s)', payload);
591 e = {
592 name: 'ding',
593 payload: payload,
594 };
595 this.event.next(e);
596 return [2 /*return*/];
597 });
598 });
599 };
600 IoService.prototype.rpcUpdate = function (payload) {
601 return __awaiter(this, void 0, void 0, function () {
602 return __generator(this, function (_b) {
603 this.event.next({
604 name: 'update',
605 payload: payload,
606 });
607 return [2 /*return*/];
608 });
609 });
610 };
611 /******************************************************************
612 *
613 * Socket Actions
614 *
615 */
616 IoService.prototype.socketClose = function (code, reason) {
617 return __awaiter(this, void 0, void 0, function () {
618 var future;
619 var _this = this;
620 return __generator(this, function (_b) {
621 switch (_b.label) {
622 case 0:
623 this.log.verbose('IoService', 'socketClose()');
624 if (!this._websocket) {
625 throw new Error('no websocket');
626 }
627 this._websocket.close(code, reason);
628 this.socketUpdateState();
629 future = new Promise(function (resolve) {
630 _this.readyState.pipe(operators.filter(function (s) { return s === ReadyState.CLOSED; }))
631 .subscribe(resolve);
632 });
633 return [4 /*yield*/, future];
634 case 1:
635 _b.sent();
636 return [2 /*return*/];
637 }
638 });
639 });
640 };
641 IoService.prototype.socketSend = function (ioEvent) {
642 this.log.silly('IoService', 'socketSend({name:%s, payload:%s})', ioEvent.name, ioEvent.payload);
643 if (!this._websocket) {
644 this.log.silly('IoService', 'socketSend() no _websocket');
645 }
646 var strEvt = JSON.stringify(ioEvent);
647 this.sendBuffer.push(strEvt);
648 // XXX can move this to onOpen?
649 this.socketSendBuffer();
650 };
651 IoService.prototype.socketSendBuffer = function () {
652 this.log.silly('IoService', 'socketSendBuffer() length:%s', this.sendBuffer.length);
653 if (!this._websocket) {
654 throw new Error('socketSendBuffer(): no _websocket');
655 }
656 if (this._websocket.readyState !== WebSocket.OPEN) {
657 this.log.warn('IoService', 'socketSendBuffer() readyState is not OPEN, send job delayed.');
658 return;
659 }
660 while (this.sendBuffer.length) {
661 var buf = this.sendBuffer.shift();
662 this.log.silly('IoService', 'socketSendBuffer() sending(%s)', buf);
663 this._websocket.send(buf);
664 }
665 };
666 IoService.prototype.socketUpdateState = function () {
667 var _a;
668 this.log.verbose('IoService', 'socketUpdateState() is %s', ReadyState[(_a = this._websocket) === null || _a === void 0 ? void 0 : _a.readyState]);
669 if (!this._websocket) {
670 this.log.error('IoService', 'socketUpdateState() no _websocket');
671 return;
672 }
673 this._readyState.next(this._websocket.readyState);
674 };
675 /******************************************************************
676 *
677 * Socket Events Listener
678 *
679 */
680 IoService.prototype.socketOnMessage = function (message) {
681 this.log.verbose('IoService', 'onMessage({data: %s})', message.data);
682 var data = message.data; // WebSocket data
683 var ioEvent = {
684 name: 'raw',
685 payload: data,
686 }; // this is default io event for unknown format message
687 try {
688 var obj = JSON.parse(data);
689 ioEvent.name = obj.name;
690 ioEvent.payload = obj.payload;
691 }
692 catch (e) {
693 this.log.warn('IoService', 'onMessage parse message fail. save as RAW');
694 }
695 this.mtObserver.next(ioEvent);
696 };
697 IoService.prototype.socketOnError = function (event) {
698 this.log.silly('IoService', 'socketOnError(%s)', event);
699 // this._websocket = null
700 };
701 /**
702 * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
703 * code: 1006 CLOSE_ABNORMAL
704 * - Reserved. Used to indicate that a connection was closed abnormally
705 * (that is, with no close frame being sent) when a status code is expected.
706 */
707 IoService.prototype.socketOnClose = function (closeEvent) {
708 var _this = this;
709 this.log.verbose('IoService', 'socketOnClose({code:%s, reason:%s, returnValue:%s})', closeEvent.code, closeEvent.reason, closeEvent.returnValue);
710 this.socketUpdateState();
711 /**
712 * reconnect inside onClose
713 */
714 if (this.autoReconnect) {
715 this.state.on('pending');
716 setTimeout(function () { return __awaiter(_this, void 0, void 0, function () {
717 var e_4;
718 return __generator(this, function (_b) {
719 switch (_b.label) {
720 case 0:
721 _b.trys.push([0, 2, , 3]);
722 return [4 /*yield*/, this.connectRxSocket()];
723 case 1:
724 _b.sent();
725 this.state.on(true);
726 return [3 /*break*/, 3];
727 case 2:
728 e_4 = _b.sent();
729 this.log.warn('IoService', 'socketOnClose() autoReconnect() exception: %s', e_4);
730 this.state.off(true);
731 return [3 /*break*/, 3];
732 case 3: return [2 /*return*/];
733 }
734 });
735 }); }, 1000);
736 }
737 else {
738 this.state.off(true);
739 }
740 this._websocket = null;
741 if (!closeEvent.wasClean) {
742 this.log.warn('IoService', 'socketOnClose() event.wasClean FALSE');
743 // TODO emit error
744 }
745 };
746 return IoService;
747 }());
748
749 var WechatyComponent = /** @class */ (function () {
750 function WechatyComponent(log, ngZone) {
751 this.log = log;
752 this.ngZone = ngZone;
753 this.message = new core.EventEmitter();
754 this.scan = new core.EventEmitter();
755 this.login = new core.EventEmitter();
756 this.logout = new core.EventEmitter();
757 this.error = new core.EventEmitter();
758 this.heartbeat = new core.EventEmitter();
759 this.timerSub = null;
760 this.counter = 0;
761 this.timestamp = new Date();
762 this.log.verbose('WechatyComponent', 'constructor() v%s', VERSION);
763 }
764 Object.defineProperty(WechatyComponent.prototype, "token", {
765 get: function () { return this._token; },
766 set: function (_newToken) {
767 this.log.verbose('WechatyComponent', 'set token(%s)', _newToken);
768 var newToken = (_newToken || '').trim();
769 if (this._token === newToken) {
770 this.log.silly('WechatyComponent', 'set token(%s) not new', newToken);
771 return;
772 }
773 this._token = newToken;
774 if (!this.ioService) {
775 this.log.silly('WechatyComponent', 'set token() skip token init value');
776 this.log.silly('WechatyComponent', 'set token() because ioService will do it inside ngOnInit()');
777 return;
778 }
779 this.log.silly('WechatyComponent', 'set token(%s) reloading ioService now...', newToken);
780 this.ioService.token(this.token);
781 this.ioService.restart(); // async
782 },
783 enumerable: false,
784 configurable: true
785 });
786 WechatyComponent.prototype.ngOnInit = function () {
787 return __awaiter(this, void 0, void 0, function () {
788 return __generator(this, function (_a) {
789 switch (_a.label) {
790 case 0:
791 this.log.verbose('WechatyComponent', 'ngOnInit() with token: ' + this.token);
792 this.ioService = new IoService();
793 return [4 /*yield*/, this.ioService.init()];
794 case 1:
795 _a.sent();
796 this.ioService.event.subscribe(this.onIo.bind(this));
797 this.log.silly('WechatyComponent', 'ngOnInit() ioService.event.subscribe()-ed');
798 if (!this.token) return [3 /*break*/, 3];
799 this.ioService.token(this.token);
800 return [4 /*yield*/, this.ioService.start()];
801 case 2:
802 _a.sent();
803 _a.label = 3;
804 case 3: return [2 /*return*/];
805 }
806 });
807 });
808 };
809 WechatyComponent.prototype.ngOnDestroy = function () {
810 this.log.verbose('WechatyComponent', 'ngOnDestroy()');
811 this.endTimer();
812 if (this.ioService) {
813 this.ioService.stop();
814 // this.ioService = null
815 }
816 };
817 WechatyComponent.prototype.onIo = function (e) {
818 this.log.silly('WechatyComponent', 'onIo#%d(%s)', this.counter++, e.name);
819 this.timestamp = new Date();
820 switch (e.name) {
821 case 'scan':
822 this.scan.emit(e.payload);
823 break;
824 case 'login':
825 this.login.emit(e.payload);
826 break;
827 case 'logout':
828 this.logout.emit(e.payload);
829 break;
830 case 'message':
831 this.message.emit(e.payload);
832 break;
833 case 'error':
834 this.error.emit(e.payload);
835 break;
836 case 'ding':
837 case 'dong':
838 case 'raw':
839 this.heartbeat.emit(e.name + '[' + e.payload + ']');
840 break;
841 case 'heartbeat':
842 this.heartbeat.emit(e.payload);
843 break;
844 case 'sys':
845 this.log.silly('WechatyComponent', 'onIo(%s): %s', e.name, e.payload);
846 break;
847 default:
848 this.log.warn('WechatyComponent', 'onIo() unknown event name: %s[%s]', e.name, e.payload);
849 break;
850 }
851 };
852 WechatyComponent.prototype.reset = function (reason) {
853 this.log.verbose('WechatyComponent', 'reset(%s)', reason);
854 var resetEvent = {
855 name: 'reset',
856 payload: reason,
857 };
858 if (!this.ioService) {
859 throw new Error('no ioService');
860 }
861 this.ioService.event.next(resetEvent);
862 };
863 WechatyComponent.prototype.shutdown = function (reason) {
864 this.log.verbose('WechatyComponent', 'shutdown(%s)', reason);
865 var shutdownEvent = {
866 name: 'shutdown',
867 payload: reason,
868 };
869 if (!this.ioService) {
870 throw new Error('no ioService');
871 }
872 this.ioService.event.next(shutdownEvent);
873 };
874 WechatyComponent.prototype.startSyncMessage = function () {
875 this.log.verbose('WechatyComponent', 'startSyncMessage()');
876 var botieEvent = {
877 name: 'botie',
878 payload: {
879 args: ['message'],
880 source: 'return this.syncMessage(message)',
881 },
882 };
883 if (!this.ioService) {
884 throw new Error('no ioService');
885 }
886 this.ioService.event.next(botieEvent);
887 };
888 WechatyComponent.prototype.startTimer = function () {
889 var _this = this;
890 this.log.verbose('WechatyComponent', 'startTimer()');
891 this.ender = new rxjs.Subject();
892 // https://github.com/angular/protractor/issues/3349#issuecomment-232253059
893 // https://github.com/juliemr/ngconf-2016-zones/blob/master/src/app/main.ts#L38
894 this.ngZone.runOutsideAngular(function () {
895 _this.timer = rxjs.interval(3000).pipe(operators.tap(function (i) { _this.log.verbose('do', ' %d', i); }), operators.takeUntil(_this.ender), operators.share());
896 // .publish()
897 });
898 this.timerSub = this.timer.subscribe(function (t) {
899 _this.counter = t;
900 if (!_this.ioService) {
901 throw new Error('no ioService');
902 }
903 _this.ioService.rpcDing(_this.counter);
904 // this.message.emit('#' + this.token + ':' + dong)
905 });
906 };
907 WechatyComponent.prototype.endTimer = function () {
908 this.log.verbose('WechatyComponent', 'endTimer()');
909 if (this.timerSub) {
910 this.timerSub.unsubscribe();
911 this.timerSub = null;
912 }
913 // this.timer = null
914 if (this.ender) {
915 this.ender.next(null);
916 // this.ender = null
917 }
918 };
919 WechatyComponent.prototype.logoff = function (reason) {
920 this.log.silly('WechatyComponent', 'logoff(%s)', reason);
921 var quitEvent = {
922 name: 'logout',
923 payload: reason,
924 };
925 this.ioService.event.next(quitEvent);
926 };
927 Object.defineProperty(WechatyComponent.prototype, "readyState", {
928 get: function () {
929 return this.ioService.readyState;
930 },
931 enumerable: false,
932 configurable: true
933 });
934 return WechatyComponent;
935 }());
936 WechatyComponent.decorators = [
937 { type: core.Component, args: [{
938 // tslint:disable-next-line:component-selector
939 selector: 'wechaty',
940 /**
941 * http://localhost:4200/app.component.html 404 (Not Found)
942 * zone.js:344 Unhandled Promise rejection: Failed to load app.component.html
943 * https://github.com/angular/angular-cli/issues/2592#issuecomment-266635266
944 * https://github.com/angular/angular-cli/issues/2293
945 *
946 * console.log from angular:
947 * If you're using Webpack you should inline the template and the styles,
948 * see https://goo.gl/X2J8zc.
949 */
950 template: '<ng-content></ng-content>'
951 },] }
952 ];
953 WechatyComponent.ctorParameters = function () { return [
954 { type: brolog.Brolog },
955 { type: core.NgZone }
956 ]; };
957 WechatyComponent.propDecorators = {
958 message: [{ type: core.Output }],
959 scan: [{ type: core.Output }],
960 login: [{ type: core.Output }],
961 logout: [{ type: core.Output }],
962 error: [{ type: core.Output }],
963 heartbeat: [{ type: core.Output }],
964 token: [{ type: core.Input }]
965 };
966
967 var WechatyModule = /** @class */ (function () {
968 function WechatyModule() {
969 }
970 return WechatyModule;
971 }());
972 WechatyModule.decorators = [
973 { type: core.NgModule, args: [{
974 id: 'wechaty',
975 declarations: [
976 WechatyComponent,
977 ],
978 exports: [
979 WechatyComponent,
980 ],
981 },] }
982 ];
983
984 /**
985 * Generated bundle index. Do not edit.
986 */
987
988 exports.VERSION = VERSION;
989 exports.WechatyComponent = WechatyComponent;
990 exports.WechatyModule = WechatyModule;
991 exports.ɵa = WechatyComponent;
992
993 Object.defineProperty(exports, '__esModule', { value: true });
994
995})));
996//# sourceMappingURL=chatie-angular.umd.js.map