UNPKG

@triniwiz/nativescript-socketio

Version:
293 lines 11.3 kB
import { Common } from './common'; export class SocketIO extends Common { /** * Class Constructor * args[0]: Connection URL as String * args[1]: Connection Options */ constructor(...args) { super(); let opts = {}; let urlComponent; let count; let connectParams = {}; const config = NSCSocketIOConfiguration.new(); switch (args.length) { case 2: urlComponent = NSURLComponents.alloc().initWithString(args[0]); const obj = args[1]; const keys = Object.keys(obj); count = urlComponent.queryItems ? urlComponent.queryItems.count : 0; for (let i = 0; i < count; i++) { const component = urlComponent.queryItems.objectAtIndex(i); const componentObj = {}; componentObj[component.name] = component.value; Object.assign(connectParams, componentObj); } keys.forEach((key) => { if (key === 'query') { let query = obj[key]; if (typeof query === 'object') { const queryKeys = Object.keys(query); for (let queryKey of queryKeys) { const value = query[queryKey]; Object.assign(connectParams, { [queryKey]: value, }); } } else if (typeof query === 'string') { if (query.startsWith('?')) { query = query.replace('?', ''); } const optionsQuery = query .split('&') .map((p) => p.split('=')) .reduce((obj, pair) => { const [key, value] = pair.map(decodeURIComponent); return { ...obj, [key]: value }; }, {}); Object.assign(connectParams, optionsQuery); } } else if (key === 'auth') { this.auth_payload = obj[key]; } else if (key === 'debug' && obj[key]) { config.log = true; } else if (key === 'cookie') { const cookie = obj[key]; const properties = {}; properties[NSHTTPCookiePath] = '/'; properties[NSHTTPCookieDomain] = (urlComponent.scheme || '') + '://' + (urlComponent.host || ''); cookie.split(';').forEach((item, index) => { if (item.trim() === 'Secure') { properties[NSHTTPCookieSecure] = true; } else if (item.trim() === 'HttpOnly') { } else { const keyVal = item.trim(); if (item.indexOf('=') > -1) { const keyValItems = keyVal.split('='); const key = keyValItems[0]; const val = keyValItems[1]; if (index === 0) { properties[NSHTTPCookieName] = key; properties[NSHTTPCookieValue] = val; } else { switch (key) { case 'path': case 'Path': properties[NSHTTPCookiePath] = val; break; case 'domain': case 'Domain': properties[NSHTTPCookieDomain] = val; break; case 'expires': case 'Expires': properties[NSHTTPCookieExpires] = val; break; case 'max-age': case 'Max-Age': properties[NSHTTPCookieMaximumAge] = val; break; default: } } } } }); const props = NSDictionary.dictionaryWithDictionary(properties); const native_cookie = NSHTTPCookie.cookieWithProperties(props); if (native_cookie) { config.cookies = NSArray.arrayWithObject(native_cookie); } } else if (key === 'transports') { const transports = obj[key]; if (Array.isArray(transports) && transports.length === 1) { if (transports.indexOf('websocket') > -1) { config.forceWebsockets = true; } else if (transports.indexOf('polling') > -1) { config.forcePolling = true; } } } else { opts[key] = serialize(obj[key]); } }); if (opts.connectParams === null) { delete opts.connectParams; } Object.assign(opts, { connectParams: connectParams }); config.connectParams = connectParams; this.socket = NSCSocketIO.alloc().init(args[0], config); break; case 3: const s = args.pop(); this.socket = s; break; default: urlComponent = NSURLComponents.alloc().initWithString(args[0]); count = urlComponent.queryItems ? urlComponent.queryItems.count : 0; for (let i = 0; i < count; i++) { const component = urlComponent.queryItems.objectAtIndex(i); const componentObj = {}; componentObj[component.name] = component.value; Object.assign(connectParams, componentObj); } if (urlComponent.queryItems) { config.connectParams = connectParams; } this.socket = this.socket = NSCSocketIO.alloc().init(args[0], config); break; } } connect() { if (!this.connected) { this.socket.connect(this.auth_payload); } } disconnect() { this.socket.disconnect(); } get connected() { return this.socket.connected; } on(event, callback) { const off = this.socket.onCallback(event, (data, ack) => { const d = deserialize(data); if (Array.isArray(d)) { data = d[0]; } else { data = d; } if (ack) { callback(data, ack); } else { callback(data); } }); return () => { off(); }; } once(event, callback) { const off = this.socket.onceCallback(event, (data, ack) => { const d = deserialize(data); if (Array.isArray(d)) { data = d[0]; } else { data = d; } if (ack) { callback(data, ack); } else { callback(data); } }); return () => { off(); }; } off(event) { this.socket.off(event); } emit(event, ...payload) { if (!event) { return console.error('Emit Failed: No Event argument'); } // Check for ack callback let ack = payload.pop(); // Remove ack if final argument is not a function if (ack && typeof ack !== 'function') { payload.push(ack); ack = null; } // Serialize Emit const final = payload.map(serialize); if (ack) { const _ack = function (args) { ack.apply(null, deserialize(args)); }; this.socket.emit(event, final, (args) => { _ack(args); }); } else { // Emit without Ack Callback this.socket.emit(event, final, null); } } joinNamespace(nsp) { return new SocketIO(null, null, this.socket.joinNamespaceWithNsp(nsp)); } leaveNamespace() { this.socket.leaveNamespace(); } } export function serialize(data) { switch (typeof data) { case 'string': case 'boolean': case 'number': { return data; } case 'object': { if (data instanceof Date) { return data.toJSON(); } if (!data) { return NSNull.new(); } if (Array.isArray(data)) { return NSArray.arrayWithArray(data.map(serialize)); } let node = {}; Object.keys(data).forEach(function (key) { let value = data[key]; node[key] = serialize(value); }); return NSDictionary.dictionaryWithDictionary(node); } default: return NSNull.new(); } } export function deserialize(data) { if (data instanceof NSNull) { return null; } if (data instanceof NSArray) { let array = []; for (let i = 0, n = data.count; i < n; i++) { array[i] = deserialize(data.objectAtIndex(i)); } return array; } if (data instanceof NSDictionary) { let dict = {}; for (let i = 0, n = data.allKeys.count; i < n; i++) { let key = data.allKeys.objectAtIndex(i); dict[key] = deserialize(data.objectForKey(key)); } return dict; } return data; } export function connect(uri, options) { let socketio = new SocketIO(uri, options || {}); socketio.connect(); return socketio; } //# sourceMappingURL=index.ios.js.map