From ec7dcf7d8305e858fce6e67f5904b8c6a8a7a8c1 Mon Sep 17 00:00:00 2001 From: jmderuty Date: Mon, 4 May 2015 16:13:18 +0200 Subject: [PATCH] Added support to protocol v2 --- build/stormancer.d.ts | 81 +- build/stormancer.js | 2446 +++++++++-------- build/stormancer.js.map | 2 +- samples/Samples.Echo/Samples.Echo.csproj | 3 +- samples/Samples.Echo/app.ts | 10 +- src/stormancer-sdk-js/Client.ts | 27 +- src/stormancer-sdk-js/MessageIDTypes.ts | 12 +- .../Processors/RequestProcessor.ts | 16 +- .../Processors/SceneDispatcher.ts | 29 +- 9 files changed, 1362 insertions(+), 1264 deletions(-) diff --git a/build/stormancer.d.ts b/build/stormancer.d.ts index 13bcb79..80435c7 100644 --- a/build/stormancer.d.ts +++ b/build/stormancer.d.ts @@ -1,37 +1,4 @@ /// -declare module Stormancer { - interface Map { - [key: string]: string; - } - interface IMap { - [key: string]: T; - } - class Helpers { - static base64ToByteArray(data: string): Uint8Array; - static stringFormat(str: string, ...args: any[]): string; - static mapKeys(map: { - [key: string]: any; - }): string[]; - static mapValues(map: IMap): T[]; - static promiseFromResult(result: T): JQueryPromise; - static promiseIf(condition: boolean, action: () => JQueryPromise, context?: any): JQueryPromise; - } - interface IObserver { - onCompleted(): void; - onError(error: any): void; - onNext(value: T): void; - } -} -declare module Stormancer { - interface Request { - lastRefresh: Date; - id: number; - observer: IObserver>; - deferred: JQueryDeferred; - } -} -declare function vblen(b: any): any; -declare function vbstr(b: any): any; declare module Stormancer { class ApiClient { constructor(config: Configuration, tokenHandler: ITokenHandler); @@ -90,6 +57,7 @@ declare module Stormancer { getPublicScene(sceneId: string, userData: T): JQueryPromise; getScene(token: string): JQueryPromise; private getSceneImpl(sceneId, ci); + private updateMetadata(); private sendSystemRequest(id, parameter); private _systemSerializer; private ensureTransportStarted(ci); @@ -237,6 +205,29 @@ declare module Stormancer { constructor(scene: IScene, name: string, index?: number, metadata?: Map); } } +declare module Stormancer { + interface Map { + [key: string]: string; + } + interface IMap { + [key: string]: T; + } + class Helpers { + static base64ToByteArray(data: string): Uint8Array; + static stringFormat(str: string, ...args: any[]): string; + static mapKeys(map: { + [key: string]: any; + }): string[]; + static mapValues(map: IMap): T[]; + static promiseFromResult(result: T): JQueryPromise; + static promiseIf(condition: boolean, action: () => JQueryPromise, context?: any): JQueryPromise; + } + interface IObserver { + onCompleted(): void; + onError(error: any): void; + onNext(value: T): void; + } +} declare module Stormancer { interface IClient { applicationName: string; @@ -326,15 +317,28 @@ declare module Stormancer { } declare module Stormancer { class MessageIDTypes { - static ID_CONNECT_TO_SCENE: number; - static ID_DISCONNECT_FROM_SCENE: number; - static ID_GET_SCENE_INFOS: number; + static ID_SYSTEM_REQUEST: number; static ID_REQUEST_RESPONSE_MSG: number; static ID_REQUEST_RESPONSE_COMPLETE: number; static ID_REQUEST_RESPONSE_ERROR: number; static ID_CONNECTION_RESULT: number; static ID_SCENES: number; } + class SystemRequestIDTypes { + static ID_GET_SCENE_INFOS: number; + static ID_CONNECT_TO_SCENE: number; + static ID_SET_METADATA: number; + static ID_SCENE_READY: number; + static ID_DISCONNECT_FROM_SCENE: number; + } +} +declare module Stormancer { + interface Request { + lastRefresh: Date; + id: number; + observer: IObserver>; + deferred: JQueryDeferred; + } } declare module Stormancer { class RequestContext { @@ -365,8 +369,9 @@ declare module Stormancer { declare module Stormancer { class SceneDispatcher implements IPacketProcessor { private _scenes; + private _buffers; registerProcessor(config: PacketProcessorConfig): void; - private handler(sceneHandler, packet); + private handler(sceneHandle, packet); addScene(scene: Scene): void; removeScene(sceneHandle: number): void; } @@ -426,6 +431,8 @@ declare module Stormancer { send(route: string, data: Uint8Array, priority: PacketPriority, reliability: PacketReliability): void; } } +declare function vblen(b: any): any; +declare function vbstr(b: any): any; declare module Stormancer { class jQueryWrapper { static $: JQueryStatic; diff --git a/build/stormancer.js b/build/stormancer.js index 437c37b..2d64c43 100644 --- a/build/stormancer.js +++ b/build/stormancer.js @@ -1,1342 +1,1382 @@ var Stormancer; (function (Stormancer) { - var Helpers = (function () { - function Helpers() { + var ApiClient = (function () { + function ApiClient(config, tokenHandler) { + this.createTokenUri = "/{0}/{1}/scenes/{2}/token"; + this._config = config; + this._tokenHandler = tokenHandler; } - Helpers.base64ToByteArray = function (data) { - return new Uint8Array(atob(data).split('').map(function (c) { - return c.charCodeAt(0); - })); + ApiClient.prototype.getSceneEndpoint = function (accountId, applicationName, sceneId, userData) { + var _this = this; + var serializer = new Stormancer.MsgPackSerializer(); + var data = serializer.serialize(userData); + var url = this._config.getApiEndpoint() + Stormancer.Helpers.stringFormat(this.createTokenUri, accountId, applicationName, sceneId); + return $.ajax({ + type: "POST", + url: url, + contentType: "application/msgpack", + headers: { + "Accept": "application/json", + "x-version": "1.0.0" + }, + data: data + }).then(function (result) { + return _this._tokenHandler.decodeToken(result); + }); }; - Helpers.stringFormat = function (str) { - var args = []; - for (var _i = 1; _i < arguments.length; _i++) { - args[_i - 1] = arguments[_i]; - } - for (var i in args) { - str = str.replace('{' + i + '}', args[i]); + return ApiClient; + })(); + Stormancer.ApiClient = ApiClient; +})(Stormancer || (Stormancer = {})); +var Cancellation; +(function (Cancellation) { + var tokenSource = (function () { + function tokenSource() { + this.data = { + reason: null, + isCancelled: false, + listeners: [] + }; + this.token = new token(this.data); + } + tokenSource.prototype.cancel = function (reason) { + this.data.isCancelled = true; + reason = reason || 'Operation Cancelled'; + this.data.reason = reason; + setTimeout(function () { + for (var i = 0; i < this.data.listeners.length; i++) { + if (typeof this.data.listeners[i] === 'function') { + this.data.listeners[i](reason); + } + } + }, 0); + }; + return tokenSource; + })(); + Cancellation.tokenSource = tokenSource; + var token = (function () { + function token(data) { + this.data = data; + } + token.prototype.isCancelled = function () { + return this.data.isCancelled; + }; + token.prototype.throwIfCancelled = function () { + if (this.isCancelled()) { + throw this.data.reason; } - return str; }; - Helpers.mapKeys = function (map) { - var keys = []; - for (var key in map) { - if (map.hasOwnProperty(key)) { - keys.push(key); - } + token.prototype.onCancelled = function (callBack) { + if (this.isCancelled()) { + setTimeout(function () { + callBack(this.data.reason); + }, 0); + } + else { + this.data.listeners.push(callBack); } - return keys; }; - Helpers.mapValues = function (map) { - var result = []; - for (var key in map) { - result.push(map[key]); + return token; + })(); + Cancellation.token = token; +})(Cancellation || (Cancellation = {})); +var Stormancer; +(function (Stormancer) { + var ConnectionHandler = (function () { + function ConnectionHandler() { + this._current = 0; + } + ConnectionHandler.prototype.generateNewConnectionId = function () { + return this._current++; + }; + ConnectionHandler.prototype.newConnection = function (connection) { + }; + ConnectionHandler.prototype.getConnection = function (id) { + throw new Error("Not implemented."); + }; + ConnectionHandler.prototype.closeConnection = function (connection, reason) { + }; + return ConnectionHandler; + })(); + Stormancer.ConnectionHandler = ConnectionHandler; + var Client = (function () { + function Client(config) { + this._tokenHandler = new Stormancer.TokenHandler(); + this._serializers = { "msgpack/map": new Stormancer.MsgPackSerializer() }; + this._systemSerializer = new Stormancer.MsgPackSerializer(); + this._accountId = config.account; + this._applicationName = config.application; + this._apiClient = new Stormancer.ApiClient(config, this._tokenHandler); + this._transport = config.transport; + this._dispatcher = config.dispatcher; + this._requestProcessor = new Stormancer.RequestProcessor(this._logger, []); + this._scenesDispatcher = new Stormancer.SceneDispatcher(); + this._dispatcher.addProcessor(this._requestProcessor); + this._dispatcher.addProcessor(this._scenesDispatcher); + this._metadata = config.metadata; + for (var i in config.serializers) { + var serializer = config.serializers[i]; + this._serializers[serializer.name] = serializer; + } + this._metadata["serializers"] = Stormancer.Helpers.mapKeys(this._serializers).join(','); + this._metadata["transport"] = this._transport.name; + this._metadata["version"] = "1.0.0a"; + this._metadata["platform"] = "JS"; + this._metadata["protocol"] = "2"; + this.initialize(); + } + Client.prototype.initialize = function () { + var _this = this; + if (!this._initialized) { + this._initialized = true; + this._transport.packetReceived.push(function (packet) { return _this.transportPacketReceived(packet); }); } - return result; }; - Helpers.promiseFromResult = function (result) { - var deferred = jQuery.Deferred(); - deferred.resolve(result); - return deferred.promise(); + Client.prototype.transportPacketReceived = function (packet) { + this._dispatcher.dispatchPacket(packet); }; - Helpers.promiseIf = function (condition, action, context) { - if (condition) { - if (context) { - return action.call(context); - } - else { - return action(); + Client.prototype.getPublicScene = function (sceneId, userData) { + var _this = this; + return this._apiClient.getSceneEndpoint(this._accountId, this._applicationName, sceneId, userData).then(function (ci) { return _this.getSceneImpl(sceneId, ci); }); + }; + Client.prototype.getScene = function (token) { + var ci = this._tokenHandler.decodeToken(token); + return this.getSceneImpl(ci.tokenData.SceneId, ci); + }; + Client.prototype.getSceneImpl = function (sceneId, ci) { + var self = this; + return this.ensureTransportStarted(ci).then(function () { + var parameter = { Metadata: self._serverConnection.metadata, Token: ci.token }; + return self.sendSystemRequest(Stormancer.SystemRequestIDTypes.ID_GET_SCENE_INFOS, parameter); + }).then(function (result) { + if (!self._serverConnection.serializerChosen) { + if (!result.SelectedSerializer) { + throw new Error("No serializer selected."); + } + self._serverConnection.serializer = self._serializers[result.SelectedSerializer]; + self._serverConnection.metadata["serializer"] = result.SelectedSerializer; + self._serverConnection.serializerChosen = true; } + return self.updateMetadata().then(function (_) { return result; }); + }).then(function (r) { + var scene = new Stormancer.Scene(self._serverConnection, self, sceneId, ci.token, r); + return scene; + }); + }; + Client.prototype.updateMetadata = function () { + return this._requestProcessor.sendSystemRequest(this._serverConnection, Stormancer.SystemRequestIDTypes.ID_SET_METADATA, this._systemSerializer.serialize(this._serverConnection.metadata)).then(function (packet) { + }); + }; + Client.prototype.sendSystemRequest = function (id, parameter) { + var _this = this; + return this._requestProcessor.sendSystemRequest(this._serverConnection, id, this._systemSerializer.serialize(parameter)).then(function (packet) { return _this._systemSerializer.deserialize(packet.data); }); + }; + Client.prototype.ensureTransportStarted = function (ci) { + var self = this; + return Stormancer.Helpers.promiseIf(self._serverConnection == null, function () { + return Stormancer.Helpers.promiseIf(!self._transport.isRunning, self.startTransport, self).then(function () { + return self._transport.connect(ci.tokenData.Endpoints[self._transport.name]).then(function (c) { + self.registerConnection(c); + return self.updateMetadata(); + }); + }); + }, self); + }; + Client.prototype.startTransport = function () { + this._cts = new Cancellation.tokenSource(); + return this._transport.start("client", new ConnectionHandler(), this._cts.token); + }; + Client.prototype.registerConnection = function (connection) { + this._serverConnection = connection; + for (var key in this._metadata) { + this._serverConnection.metadata[key] = this._metadata[key]; } - else { - return Helpers.promiseFromResult(null); + }; + Client.prototype.disconnectScene = function (scene, sceneHandle) { + var _this = this; + return this.sendSystemRequest(Stormancer.SystemRequestIDTypes.ID_DISCONNECT_FROM_SCENE, sceneHandle).then(function () { return _this._scenesDispatcher.removeScene(sceneHandle); }); + }; + Client.prototype.disconnect = function () { + if (this._serverConnection) { + this._serverConnection.close(); } }; - return Helpers; + Client.prototype.connectToScene = function (scene, token, localRoutes) { + var _this = this; + var parameter = { + Token: token, + Routes: [], + ConnectionMetadata: this._serverConnection.metadata + }; + for (var i = 0; i < localRoutes.length; i++) { + var r = localRoutes[i]; + parameter.Routes.push({ + Handle: r.index, + Metadata: r.metadata, + Name: r.name + }); + } + return this.sendSystemRequest(Stormancer.SystemRequestIDTypes.ID_CONNECT_TO_SCENE, parameter).then(function (result) { + scene.completeConnectionInitialization(result); + _this._scenesDispatcher.addScene(scene); + }); + }; + return Client; })(); - Stormancer.Helpers = Helpers; + Stormancer.Client = Client; })(Stormancer || (Stormancer = {})); -this.msgpack || (function (globalScope) { - globalScope.msgpack = { - pack: msgpackpack, - unpack: msgpackunpack, - worker: "msgpack.js", - upload: msgpackupload, - download: msgpackdownload - }; - var _ie = /MSIE/.test(navigator.userAgent), _bin2num = {}, _num2bin = {}, _num2b64 = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz0123456789+/").split(""), _buf = [], _idx = 0, _error = 0, _isArray = Array.isArray || (function (mix) { - return Object.prototype.toString.call(mix) === "[object Array]"; - }), _toString = String.fromCharCode, _MAX_DEPTH = 512; - self.importScripts && (onmessage = function (event) { - if (event.data.method === "pack") { - window.postMessage(base64encode(msgpackpack(event.data.data))); - } - else { - window.postMessage(msgpackunpack(event.data.data)); - } - }); - function msgpackpack(data, settings) { - var toString = false; - _error = 0; - if (!settings) { - settings = { byteProperties: [] }; - } - var byteArray = encode([], data, 0, settings); - return _error ? false : toString ? byteArrayToByteString(byteArray) : byteArray; - } - function msgpackunpack(data, settings) { - if (!settings) { - settings = { byteProperties: [] }; - } - _buf = typeof data === "string" ? toByteArray(data) : data; - _idx = -1; - return decode(settings); - } - function encode(rv, mix, depth, settings, bytesArray) { - var size, i, iz, c, pos, high, low, sign, exp, frac; - if (mix == null) { - rv.push(0xc0); - } - else if (mix === false) { - rv.push(0xc2); - } - else if (mix === true) { - rv.push(0xc3); - } - else { - switch (typeof mix) { - case "number": - if (mix !== mix) { - rv.push(0xcb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff); - } - else if (mix === Infinity) { - rv.push(0xcb, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); - } - else if (Math.floor(mix) === mix) { - if (mix < 0) { - if (mix >= -32) { - rv.push(0xe0 + mix + 32); - } - else if (mix > -0x80) { - rv.push(0xd0, mix + 0x100); - } - else if (mix > -0x8000) { - mix += 0x10000; - rv.push(0xd1, mix >> 8, mix & 0xff); - } - else if (mix > -0x80000000) { - mix += 0x100000000; - rv.push(0xd2, mix >>> 24, (mix >> 16) & 0xff, (mix >> 8) & 0xff, mix & 0xff); - } - else { - high = Math.floor(mix / 0x100000000); - low = mix & 0xffffffff; - rv.push(0xd3, (high >> 24) & 0xff, (high >> 16) & 0xff, (high >> 8) & 0xff, high & 0xff, (low >> 24) & 0xff, (low >> 16) & 0xff, (low >> 8) & 0xff, low & 0xff); - } - } - else { - if (mix < 0x80) { - rv.push(mix); - } - else if (mix < 0x100) { - rv.push(0xcc, mix); - } - else if (mix < 0x10000) { - rv.push(0xcd, mix >> 8, mix & 0xff); - } - else if (mix < 0x100000000) { - rv.push(0xce, mix >>> 24, (mix >> 16) & 0xff, (mix >> 8) & 0xff, mix & 0xff); - } - else { - high = Math.floor(mix / 0x100000000); - low = mix & 0xffffffff; - rv.push(0xcf, (high >> 24) & 0xff, (high >> 16) & 0xff, (high >> 8) & 0xff, high & 0xff, (low >> 24) & 0xff, (low >> 16) & 0xff, (low >> 8) & 0xff, low & 0xff); - } - } - } - else { - sign = mix < 0; - sign && (mix *= -1); - exp = ((Math.log(mix) / 0.6931471805599453) + 1023) | 0; - frac = mix * Math.pow(2, 52 + 1023 - exp); - low = frac & 0xffffffff; - sign && (exp |= 0x800); - high = ((frac / 0x100000000) & 0xfffff) | (exp << 20); - rv.push(0xcb, (high >> 24) & 0xff, (high >> 16) & 0xff, (high >> 8) & 0xff, high & 0xff, (low >> 24) & 0xff, (low >> 16) & 0xff, (low >> 8) & 0xff, low & 0xff); - } - break; - case "string": - iz = mix.length; - pos = rv.length; - rv.push(0); - for (i = 0; i < iz; ++i) { - c = mix.charCodeAt(i); - if (c < 0x80) { - rv.push(c & 0x7f); - } - else if (c < 0x0800) { - rv.push(((c >>> 6) & 0x1f) | 0xc0, (c & 0x3f) | 0x80); - } - else if (c < 0x10000) { - rv.push(((c >>> 12) & 0x0f) | 0xe0, ((c >>> 6) & 0x3f) | 0x80, (c & 0x3f) | 0x80); - } - } - size = rv.length - pos - 1; - if (size < 32) { - rv[pos] = 0xa0 + size; - } - else if (size < 0x10000) { - rv.splice(pos, 1, 0xda, size >> 8, size & 0xff); - } - else if (size < 0x100000000) { - rv.splice(pos, 1, 0xdb, size >>> 24, (size >> 16) & 0xff, (size >> 8) & 0xff, size & 0xff); - } - break; - default: - if (++depth >= _MAX_DEPTH) { - _error = 1; - return rv = []; - } - if (_isArray(mix)) { - if (bytesArray) { - size = mix.length; - if (size < 32) { - rv.push(0xa0 + size); - } - else if (size < 0x10000) { - rv.push(0xda, size >> 8, size & 0xff); - } - else if (size < 0x100000000) { - rv.push(0xdb, size >>> 24, (size >> 16) & 0xff, (size >> 8) & 0xff, size & 0xff); - } - for (i = 0; i < size; ++i) { - rv.push(mix[i]); - } - } - else { - size = mix.length; - if (size < 16) { - rv.push(0x90 + size); - } - else if (size < 0x10000) { - rv.push(0xdc, size >> 8, size & 0xff); - } - else if (size < 0x100000000) { - rv.push(0xdd, size >>> 24, (size >> 16) & 0xff, (size >> 8) & 0xff, size & 0xff); - } - for (i = 0; i < size; ++i) { - encode(rv, mix[i], depth, settings); - } - } - } - else { - pos = rv.length; - rv.push(0); - size = 0; - for (i in mix) { - if (typeof (mix[i]) == "function") { - continue; - } - ++size; - encode(rv, i, depth); - if ($.inArray(i, settings.byteProperties) != -1) { - encode(rv, mix[i], depth, settings, true); - } - else { - encode(rv, mix[i], depth, settings, false); - } - } - if (size < 16) { - rv[pos] = 0x80 + size; - } - else if (size < 0x10000) { - rv.splice(pos, 1, 0xde, size >> 8, size & 0xff); - } - else if (size < 0x100000000) { - rv.splice(pos, 1, 0xdf, size >>> 24, (size >> 16) & 0xff, (size >> 8) & 0xff, size & 0xff); - } - } - } - } - return rv; - } - function decode(settings, rawAsArray) { - var size, i, iz, c, num = 0, sign, exp, frac, ary, hash, buf = _buf, type = buf[++_idx], key; - if (type >= 0xe0) { - return type - 0x100; - } - if (type < 0xc0) { - if (type < 0x80) { - return type; - } - if (type < 0x90) { - num = type - 0x80; - type = 0x80; - } - else if (type < 0xa0) { - num = type - 0x90; - type = 0x90; - } - else { - num = type - 0xa0; - type = 0xa0; - } - } - switch (type) { - case 0xc0: return null; - case 0xc2: return false; - case 0xc3: return true; - case 0xca: - num = buf[++_idx] * 0x1000000 + (buf[++_idx] << 16) + (buf[++_idx] << 8) + buf[++_idx]; - sign = num & 0x80000000; - exp = (num >> 23) & 0xff; - frac = num & 0x7fffff; - if (!num || num === 0x80000000) { - return 0; - } - if (exp === 0xff) { - return frac ? NaN : Infinity; - } - return (sign ? -1 : 1) * (frac | 0x800000) * Math.pow(2, exp - 127 - 23); - case 0xcb: - num = buf[++_idx] * 0x1000000 + (buf[++_idx] << 16) + (buf[++_idx] << 8) + buf[++_idx]; - sign = num & 0x80000000; - exp = (num >> 20) & 0x7ff; - frac = num & 0xfffff; - if (!num || num === 0x80000000) { - _idx += 4; - return 0; - } - if (exp === 0x7ff) { - _idx += 4; - return frac ? NaN : Infinity; - } - num = buf[++_idx] * 0x1000000 + (buf[++_idx] << 16) + (buf[++_idx] << 8) + buf[++_idx]; - return (sign ? -1 : 1) * ((frac | 0x100000) * Math.pow(2, exp - 1023 - 20) + num * Math.pow(2, exp - 1023 - 52)); - case 0xcf: - num = buf[++_idx] * 0x1000000 + (buf[++_idx] << 16) + (buf[++_idx] << 8) + buf[++_idx]; - return num * 0x100000000 + buf[++_idx] * 0x1000000 + (buf[++_idx] << 16) + (buf[++_idx] << 8) + buf[++_idx]; - case 0xce: num += buf[++_idx] * 0x1000000 + (buf[++_idx] << 16); - case 0xcd: num += buf[++_idx] << 8; - case 0xcc: return num + buf[++_idx]; - case 0xd3: - num = buf[++_idx]; - if (num & 0x80) { - return ((num ^ 0xff) * 0x100000000000000 + (buf[++_idx] ^ 0xff) * 0x1000000000000 + (buf[++_idx] ^ 0xff) * 0x10000000000 + (buf[++_idx] ^ 0xff) * 0x100000000 + (buf[++_idx] ^ 0xff) * 0x1000000 + (buf[++_idx] ^ 0xff) * 0x10000 + (buf[++_idx] ^ 0xff) * 0x100 + (buf[++_idx] ^ 0xff) + 1) * -1; - } - return num * 0x100000000000000 + buf[++_idx] * 0x1000000000000 + buf[++_idx] * 0x10000000000 + buf[++_idx] * 0x100000000 + buf[++_idx] * 0x1000000 + buf[++_idx] * 0x10000 + buf[++_idx] * 0x100 + buf[++_idx]; - case 0xd2: - num = buf[++_idx] * 0x1000000 + (buf[++_idx] << 16) + (buf[++_idx] << 8) + buf[++_idx]; - return num < 0x80000000 ? num : num - 0x100000000; - case 0xd1: - num = (buf[++_idx] << 8) + buf[++_idx]; - return num < 0x8000 ? num : num - 0x10000; - case 0xd0: - num = buf[++_idx]; - return num < 0x80 ? num : num - 0x100; - case 0xdb: num += buf[++_idx] * 0x1000000 + (buf[++_idx] << 16); - case 0xda: num += (buf[++_idx] << 8) + buf[++_idx]; - case 0xa0: - if (rawAsArray) { - for (ary = [], i = _idx, iz = i + num; i < iz;) { - ary.push(buf[++i]); - } - _idx = i; - return ary; - } - else { - for (ary = [], i = _idx, iz = i + num; i < iz;) { - c = buf[++i]; - ary.push(c < 0x80 ? c : c < 0xe0 ? ((c & 0x1f) << 6 | (buf[++i] & 0x3f)) : ((c & 0x0f) << 12 | (buf[++i] & 0x3f) << 6 | (buf[++i] & 0x3f))); - } - _idx = i; - return ary.length < 10240 ? _toString.apply(null, ary) : byteArrayToByteString(ary); - } - case 0xdf: num += buf[++_idx] * 0x1000000 + (buf[++_idx] << 16); - case 0xde: num += (buf[++_idx] << 8) + buf[++_idx]; - case 0x80: - hash = {}; - while (num--) { - size = buf[++_idx] - 0xa0; - for (ary = [], i = _idx, iz = i + size; i < iz;) { - c = buf[++i]; - ary.push(c < 0x80 ? c : c < 0xe0 ? ((c & 0x1f) << 6 | (buf[++i] & 0x3f)) : ((c & 0x0f) << 12 | (buf[++i] & 0x3f) << 6 | (buf[++i] & 0x3f))); - } - _idx = i; - key = _toString.apply(null, ary); - if ($.inArray(key, settings.byteProperties) != -1) { - hash[key] = decode(settings, true); - } - else { - hash[key] = decode(settings); - } - } - return hash; - case 0xdd: num += buf[++_idx] * 0x1000000 + (buf[++_idx] << 16); - case 0xdc: num += (buf[++_idx] << 8) + buf[++_idx]; - case 0x90: - ary = []; - while (num--) { - ary.push(decode(settings, rawAsArray)); - } - return ary; - } - return; - } - function byteArrayToByteString(byteArray) { - try { - return _toString.apply(this, byteArray); - } - catch (err) { - ; - } - var rv = [], i = 0, iz = byteArray.length, num2bin = _num2bin; - for (; i < iz; ++i) { - rv[i] = num2bin[byteArray[i]]; - } - return rv.join(""); - } - function msgpackdownload(url, option, callback) { - option.method = "GET"; - option.binary = true; - ajax(url, option, callback); - } - function msgpackupload(url, option, callback) { - option.method = "PUT"; - option.binary = true; - if (option.worker && globalScope.Worker) { - var worker = new Worker(globalScope.msgpack.worker); - worker.onmessage = function (event) { - option.data = event.data; - ajax(url, option, callback); - }; - worker.postMessage({ method: "pack", data: option.data }); - } - else { - option.data = base64encode(msgpackpack(option.data)); - ajax(url, option, callback); +var Stormancer; +(function (Stormancer) { + var Configuration = (function () { + function Configuration() { + this.metadata = {}; + this.transport = new Stormancer.WebSocketTransport(); + this.dispatcher = new Stormancer.DefaultPacketDispatcher(); + this.serializers = []; + this.serializers.push(new Stormancer.MsgPackSerializer()); } - } - function ajax(url, option, callback) { - function readyStateChange() { - if (xhr.readyState === 4) { - var data, status = xhr.status, worker, byteArray, rv = { status: status, ok: status >= 200 && status < 300 }; - if (!run++) { - if (method === "PUT") { - data = rv.ok ? xhr.responseText : ""; - } - else { - if (rv.ok) { - if (option.worker && globalScope.Worker) { - worker = new Worker(globalScope.msgpack.worker); - worker.onmessage = function (event) { - callback(event.data, option, rv); - }; - worker.postMessage({ - method: "unpack", - data: xhr.responseText - }); - gc(); - return; - } - else { - byteArray = _ie ? toByteArrayIE(xhr) : toByteArray(xhr.responseText); - data = msgpackunpack(byteArray); - } - } - } - after && after(xhr, option, rv); - callback(data, option, rv); - gc(); - } - } + Configuration.prototype.getApiEndpoint = function () { + return this.serverEndpoint ? this.serverEndpoint : Configuration.apiEndpoint; + }; + Configuration.forAccount = function (accountId, applicationName) { + var config = new Configuration(); + config.account = accountId; + config.application = applicationName; + return config; + }; + Configuration.prototype.Metadata = function (key, value) { + this.metadata[key] = value; + return this; + }; + Configuration.apiEndpoint = "http://api1.stormancer.com/"; + return Configuration; + })(); + Stormancer.Configuration = Configuration; +})(Stormancer || (Stormancer = {})); +var Stormancer; +(function (Stormancer) { + (function (ConnectionState) { + ConnectionState[ConnectionState["Disconnected"] = 0] = "Disconnected"; + ConnectionState[ConnectionState["Connecting"] = 1] = "Connecting"; + ConnectionState[ConnectionState["Connected"] = 2] = "Connected"; + })(Stormancer.ConnectionState || (Stormancer.ConnectionState = {})); + var ConnectionState = Stormancer.ConnectionState; +})(Stormancer || (Stormancer = {})); +var Stormancer; +(function (Stormancer) { + var Packet = (function () { + function Packet(source, data, metadata) { + this.connection = source; + this.data = data; + this._metadata = metadata; } - function ng(abort, status) { - if (!run++) { - var rv = { status: status || 400, ok: false }; - after && after(xhr, option, rv); - callback(null, option, rv); - gc(abort); + Packet.prototype.setMetadata = function (metadata) { + this._metadata = metadata; + }; + Packet.prototype.getMetadata = function () { + if (!this._metadata) { + this._metadata = {}; } - } - function gc(abort) { - abort && xhr && xhr.abort && xhr.abort(); - watchdog && (clearTimeout(watchdog), watchdog = 0); - xhr = null; - globalScope.addEventListener && globalScope.removeEventListener("beforeunload", ng, false); - } - var watchdog = 0, method = option.method || "GET", header = option.header || {}, before = option.before, after = option.after, data = option.data || null, xhr = globalScope.XMLHttpRequest ? new XMLHttpRequest() : globalScope.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : null, run = 0, i, overrideMimeType = "overrideMimeType", setRequestHeader = "setRequestHeader", getbinary = method === "GET" && option.binary; - try { - xhr.onreadystatechange = readyStateChange; - xhr.open(method, url, true); - before && before(xhr, option); - getbinary && xhr[overrideMimeType] && xhr[overrideMimeType]("text/plain; charset=x-user-defined"); - data && xhr[setRequestHeader]("Content-Type", "application/x-www-form-urlencoded"); - for (i in header) { - xhr[setRequestHeader](i, header[i]); + return this._metadata; + }; + Packet.prototype.setMetadataValue = function (key, value) { + if (!this._metadata) { + this._metadata = {}; } - globalScope.addEventListener && globalScope.addEventListener("beforeunload", ng, false); - xhr.send(data); - watchdog = setTimeout(function () { - ng(1, 408); - }, (option.timeout || 10) * 1000); - } - catch (err) { - ng(0, 400); - } - } - function toByteArray(data) { - var rv = [], bin2num = _bin2num, remain, ary = data.split(""), i = -1, iz; - iz = ary.length; - remain = iz % 8; - while (remain--) { - ++i; - rv[i] = bin2num[ary[i]]; - } - remain = iz >> 3; - while (remain--) { - rv.push(bin2num[ary[++i]], bin2num[ary[++i]], bin2num[ary[++i]], bin2num[ary[++i]], bin2num[ary[++i]], bin2num[ary[++i]], bin2num[ary[++i]], bin2num[ary[++i]]); - } - return rv; - } - function toByteArrayIE(xhr) { - var rv = [], data, remain, charCodeAt = "charCodeAt", loop, v0, v1, v2, v3, v4, v5, v6, v7, i = -1, iz; - iz = vblen(xhr); - data = vbstr(xhr); - loop = Math.ceil(iz / 2); - remain = loop % 8; - while (remain--) { - v0 = data[charCodeAt](++i); - rv.push(v0 & 0xff, v0 >> 8); - } - remain = loop >> 3; - while (remain--) { - v0 = data[charCodeAt](++i); - v1 = data[charCodeAt](++i); - v2 = data[charCodeAt](++i); - v3 = data[charCodeAt](++i); - v4 = data[charCodeAt](++i); - v5 = data[charCodeAt](++i); - v6 = data[charCodeAt](++i); - v7 = data[charCodeAt](++i); - rv.push(v0 & 0xff, v0 >> 8, v1 & 0xff, v1 >> 8, v2 & 0xff, v2 >> 8, v3 & 0xff, v3 >> 8, v4 & 0xff, v4 >> 8, v5 & 0xff, v5 >> 8, v6 & 0xff, v6 >> 8, v7 & 0xff, v7 >> 8); - } - iz % 2 && rv.pop(); - return rv; - } - function base64encode(data) { - var rv = [], c = 0, i = -1, iz = data.length, pad = [0, 2, 1][data.length % 3], num2bin = _num2bin, num2b64 = _num2b64; - if (globalScope.btoa) { - while (i < iz) { - rv.push(num2bin[data[++i]]); + this._metadata[key] = value; + }; + Packet.prototype.getMetadataValue = function (key) { + if (!this._metadata) { + this._metadata = {}; } - return btoa(rv.join("")); - } - --iz; - while (i < iz) { - c = (data[++i] << 16) | (data[++i] << 8) | (data[++i]); - rv.push(num2b64[(c >> 18) & 0x3f], num2b64[(c >> 12) & 0x3f], num2b64[(c >> 6) & 0x3f], num2b64[c & 0x3f]); - } - pad > 1 && (rv[rv.length - 2] = "="); - pad > 0 && (rv[rv.length - 1] = "="); - return rv.join(""); - } - (function () { - var i = 0, v; - for (; i < 0x100; ++i) { - v = _toString(i); - _bin2num[v] = i; - _num2bin[i] = v; - } - for (i = 0x80; i < 0x100; ++i) { - _bin2num[_toString(0xf700 + i)] = i; - } + return this._metadata[key]; + }; + return Packet; })(); - _ie && document.write('