summaryrefslogtreecommitdiffstats
path: root/addon-sdk/source/examples/debug-client/data/client.js
diff options
context:
space:
mode:
Diffstat (limited to 'addon-sdk/source/examples/debug-client/data/client.js')
-rw-r--r--addon-sdk/source/examples/debug-client/data/client.js816
1 files changed, 0 insertions, 816 deletions
diff --git a/addon-sdk/source/examples/debug-client/data/client.js b/addon-sdk/source/examples/debug-client/data/client.js
deleted file mode 100644
index 022f9a1c3..000000000
--- a/addon-sdk/source/examples/debug-client/data/client.js
+++ /dev/null
@@ -1,816 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-(function(exports) {
-"use strict";
-
-
-var describe = Object.getOwnPropertyDescriptor;
-var Class = fields => {
- var constructor = fields.constructor || function() {};
- var ancestor = fields.extends || Object;
-
-
-
- var descriptor = {};
- for (var key of Object.keys(fields))
- descriptor[key] = describe(fields, key);
-
- var prototype = Object.create(ancestor.prototype, descriptor);
-
- constructor.prototype = prototype;
- prototype.constructor = constructor;
-
- return constructor;
-};
-
-
-var bus = function Bus() {
- var parser = new DOMParser();
- return parser.parseFromString("<EventTarget/>", "application/xml").documentElement;
-}();
-
-var GUID = new WeakMap();
-GUID.id = 0;
-var guid = x => GUID.get(x);
-var setGUID = x => {
- GUID.set(x, ++ GUID.id);
-};
-
-var Emitter = Class({
- extends: EventTarget,
- constructor: function() {
- this.setupEmitter();
- },
- setupEmitter: function() {
- setGUID(this);
- },
- addEventListener: function(type, listener, capture) {
- bus.addEventListener(type + "@" + guid(this),
- listener, capture);
- },
- removeEventListener: function(type, listener, capture) {
- bus.removeEventListener(type + "@" + guid(this),
- listener, capture);
- }
-});
-
-function dispatch(target, type, data) {
- var event = new MessageEvent(type + "@" + guid(target), {
- bubbles: true,
- cancelable: false,
- data: data
- });
- bus.dispatchEvent(event);
-}
-
-var supervisedWorkers = new WeakMap();
-var supervised = supervisor => {
- if (!supervisedWorkers.has(supervisor)) {
- supervisedWorkers.set(supervisor, new Map());
- supervisor.connection.addActorPool(supervisor);
- }
- return supervisedWorkers.get(supervisor);
-};
-
-var Supervisor = Class({
- extends: Emitter,
- constructor: function(...params) {
- this.setupEmitter(...params);
- this.setupSupervisor(...params);
- },
- Supervisor: function(connection) {
- this.connection = connection;
- },
- /**
- * Return the parent pool for this client.
- */
- supervisor: function() {
- return this.connection.poolFor(this.actorID);
- },
- /**
- * Override this if you want actors returned by this actor
- * to belong to a different actor by default.
- */
- marshallPool: function() { return this; },
- /**
- * Add an actor as a child of this pool.
- */
- supervise: function(actor) {
- if (!actor.actorID)
- actor.actorID = this.connection.allocID(actor.actorPrefix ||
- actor.typeName);
-
- supervised(this).set(actor.actorID, actor);
- return actor;
- },
- /**
- * Remove an actor as a child of this pool.
- */
- abandon: function(actor) {
- supervised(this).delete(actor.actorID);
- },
- // true if the given actor ID exists in the pool.
- has: function(actorID) {
- return supervised(this).has(actorID);
- },
- // Same as actor, should update debugger connection to use 'actor'
- // and then remove this.
- get: function(actorID) {
- return supervised(this).get(actorID);
- },
- actor: function(actorID) {
- return supervised(this).get(actorID);
- },
- isEmpty: function() {
- return supervised(this).size === 0;
- },
- /**
- * For getting along with the debugger server pools, should be removable
- * eventually.
- */
- cleanup: function() {
- this.destroy();
- },
- destroy: function() {
- var supervisor = this.supervisor();
- if (supervisor)
- supervisor.abandon(this);
-
- for (var actor of supervised(this).values()) {
- if (actor !== this) {
- var destroy = actor.destroy;
- // Disconnect destroy while we're destroying in case of (misbehaving)
- // circular ownership.
- if (destroy) {
- actor.destroy = null;
- destroy.call(actor);
- actor.destroy = destroy;
- }
- }
- }
-
- this.connection.removeActorPool(this);
- supervised(this).clear();
- }
-
-});
-
-
-
-
-var mailbox = new WeakMap();
-var clientRequests = new WeakMap();
-
-var inbox = client => mailbox.get(client).inbox;
-var outbox = client => mailbox.get(client).outbox;
-var requests = client => clientRequests.get(client);
-
-
-var Receiver = Class({
- receive: function(packet) {
- if (packet.error)
- this.reject(packet.error);
- else
- this.resolve(this.read(packet));
- }
-});
-
-var Connection = Class({
- constructor: function() {
- // Queue of the outgoing messages.
- this.outbox = [];
- // Map of pending requests.
- this.pending = new Map();
- this.pools = new Set();
- },
- isConnected: function() {
- return !!this.port
- },
- connect: function(port) {
- this.port = port;
- port.addEventListener("message", this);
- port.start();
-
- this.flush();
- },
- addPool: function(pool) {
- this.pools.add(pool);
- },
- removePool: function(pool) {
- this.pools.delete(pool);
- },
- poolFor: function(id) {
- for (let pool of this.pools.values()) {
- if (pool.has(id))
- return pool;
- }
- },
- get: function(id) {
- var pool = this.poolFor(id);
- return pool && pool.get(id);
- },
- disconnect: function() {
- this.port.stop();
- this.port = null;
- for (var request of this.pending.values()) {
- request.catch(new Error("Connection closed"));
- }
- this.pending.clear();
-
- var requests = this.outbox.splice(0);
- for (var request of request) {
- requests.catch(new Error("Connection closed"));
- }
- },
- handleEvent: function(event) {
- this.receive(event.data);
- },
- flush: function() {
- if (this.isConnected()) {
- for (var request of this.outbox) {
- if (!this.pending.has(request.to)) {
- this.outbox.splice(this.outbox.indexOf(request), 1);
- this.pending.set(request.to, request);
- this.send(request.packet);
- }
- }
- }
- },
- send: function(packet) {
- this.port.postMessage(packet);
- },
- request: function(packet) {
- return new Promise(function(resolve, reject) {
- this.outbox.push({
- to: packet.to,
- packet: packet,
- receive: resolve,
- catch: reject
- });
- this.flush();
- });
- },
- receive: function(packet) {
- var { from, type, why } = packet;
- var receiver = this.pending.get(from);
- if (!receiver) {
- console.warn("Unable to handle received packet", data);
- } else {
- this.pending.delete(from);
- if (packet.error)
- receiver.catch(packet.error);
- else
- receiver.receive(packet);
- }
- this.flush();
- },
-});
-
-/**
- * Base class for client-side actor fronts.
- */
-var Client = Class({
- extends: Supervisor,
- constructor: function(from=null, detail=null, connection=null) {
- this.Client(from, detail, connection);
- },
- Client: function(form, detail, connection) {
- this.Supervisor(connection);
-
- if (form) {
- this.actorID = form.actor;
- this.from(form, detail);
- }
- },
- connect: function(port) {
- this.connection = new Connection(port);
- },
- actorID: null,
- actor: function() {
- return this.actorID;
- },
- /**
- * Update the actor from its representation.
- * Subclasses should override this.
- */
- form: function(form) {
- },
- /**
- * Method is invokeid when packet received constitutes an
- * event. By default such packets are demarshalled and
- * dispatched on the client instance.
- */
- dispatch: function(packet) {
- },
- /**
- * Method is invoked when packet is returned in response to
- * a request. By default respond delivers response to a first
- * request in a queue.
- */
- read: function(input) {
- throw new TypeError("Subclass must implement read method");
- },
- write: function(input) {
- throw new TypeError("Subclass must implement write method");
- },
- respond: function(packet) {
- var [resolve, reject] = requests(this).shift();
- if (packet.error)
- reject(packet.error);
- else
- resolve(this.read(packet));
- },
- receive: function(packet) {
- if (this.isEventPacket(packet)) {
- this.dispatch(packet);
- }
- else if (requests(this).length) {
- this.respond(packet);
- }
- else {
- this.catch(packet);
- }
- },
- send: function(packet) {
- Promise.cast(packet.to || this.actor()).then(id => {
- packet.to = id;
- this.connection.send(packet);
- })
- },
- request: function(packet) {
- return this.connection.request(packet);
- }
-});
-
-
-var Destructor = method => {
- return function(...args) {
- return method.apply(this, args).then(result => {
- this.destroy();
- return result;
- });
- };
-};
-
-var Profiled = (method, id) => {
- return function(...args) {
- var start = new Date();
- return method.apply(this, args).then(result => {
- var end = new Date();
- this.telemetry.add(id, +end - start);
- return result;
- });
- };
-};
-
-var Method = (request, response) => {
- return response ? new BidirectionalMethod(request, response) :
- new UnidirecationalMethod(request);
-};
-
-var UnidirecationalMethod = request => {
- return function(...args) {
- var packet = request.write(args, this);
- this.connection.send(packet);
- return Promise.resolve(void(0));
- };
-};
-
-var BidirectionalMethod = (request, response) => {
- return function(...args) {
- var packet = request.write(args, this);
- return this.connection.request(packet).then(packet => {
- return response.read(packet, this);
- });
- };
-};
-
-
-Client.from = ({category, typeName, methods, events}) => {
- var proto = {
- constructor: function(...args) {
- this.Client(...args);
- },
- extends: Client,
- name: typeName
- };
-
- methods.forEach(({telemetry, request, response, name, oneway, release}) => {
- var [reader, writer] = oneway ? [, new Request(request)] :
- [new Request(request), new Response(response)];
- var method = new Method(request, response);
- var profiler = telemetry ? new Profiler(method) : method;
- var destructor = release ? new Destructor(profiler) : profiler;
- proto[name] = destructor;
- });
-
- return Class(proto);
-};
-
-
-var defineType = (client, descriptor) => {
- var type = void(0)
- if (typeof(descriptor) === "string") {
- if (name.indexOf(":") > 0)
- type = makeCompoundType(descriptor);
- else if (name.indexOf("#") > 0)
- type = new ActorDetail(descriptor);
- else if (client.specification[descriptor])
- type = makeCategoryType(client.specification[descriptor]);
- } else {
- type = makeCategoryType(descriptor);
- }
-
- if (type)
- client.types.set(type.name, type);
- else
- throw TypeError("Invalid type: " + descriptor);
-};
-
-
-var makeCompoundType = name => {
- var index = name.indexOf(":");
- var [baseType, subType] = [name.slice(0, index), parts.slice(1)];
- return baseType === "array" ? new ArrayOf(subType) :
- baseType === "nullable" ? new Maybe(subType) :
- null;
-};
-
-var makeCategoryType = (descriptor) => {
- var { category } = descriptor;
- return category === "dict" ? new Dictionary(descriptor) :
- category === "actor" ? new Actor(descriptor) :
- null;
-};
-
-
-var typeFor = (client, type="primitive") => {
- if (!client.types.has(type))
- defineType(client, type);
-
- return client.types.get(type);
-};
-
-
-var Client = Class({
- constructor: function() {
- },
- setupTypes: function(specification) {
- this.specification = specification;
- this.types = new Map();
- },
- read: function(input, type) {
- return typeFor(this, type).read(input, this);
- },
- write: function(input, type) {
- return typeFor(this, type).write(input, this);
- }
-});
-
-
-var Type = Class({
- get name() {
- return this.category ? this.category + ":" + this.type :
- this.type;
- },
- read: function(input, client) {
- throw new TypeError("`Type` subclass must implement `read`");
- },
- write: function(input, client) {
- throw new TypeError("`Type` subclass must implement `write`");
- }
-});
-
-
-var Primitve = Class({
- extends: Type,
- constuctor: function(type) {
- this.type = type;
- },
- read: function(input, client) {
- return input;
- },
- write: function(input, client) {
- return input;
- }
-});
-
-var Maybe = Class({
- extends: Type,
- category: "nullable",
- constructor: function(type) {
- this.type = type;
- },
- read: function(input, client) {
- return input === null ? null :
- input === void(0) ? void(0) :
- client.read(input, this.type);
- },
- write: function(input, client) {
- return input === null ? null :
- input === void(0) ? void(0) :
- client.write(input, this.type);
- }
-});
-
-var ArrayOf = Class({
- extends: Type,
- category: "array",
- constructor: function(type) {
- this.type = type;
- },
- read: function(input, client) {
- return input.map($ => client.read($, this.type));
- },
- write: function(input, client) {
- return input.map($ => client.write($, this.type));
- }
-});
-
-var Dictionary = Class({
- exteds: Type,
- category: "dict",
- get name() { return this.type; },
- constructor: function({typeName, specializations}) {
- this.type = typeName;
- this.types = specifications;
- },
- read: function(input, client) {
- var output = {};
- for (var key in input) {
- output[key] = client.read(input[key], this.types[key]);
- }
- return output;
- },
- write: function(input, client) {
- var output = {};
- for (var key in input) {
- output[key] = client.write(value, this.types[key]);
- }
- return output;
- }
-});
-
-var Actor = Class({
- exteds: Type,
- category: "actor",
- get name() { return this.type; },
- constructor: function({typeName}) {
- this.type = typeName;
- },
- read: function(input, client, detail) {
- var id = value.actor;
- var actor = void(0);
- if (client.connection.has(id)) {
- return client.connection.get(id).form(input, detail, client);
- } else {
- actor = Client.from(detail, client);
- actor.actorID = id;
- client.supervise(actor);
- }
- },
- write: function(input, client, detail) {
- if (input instanceof Actor) {
- if (!input.actorID) {
- client.supervise(input);
- }
- return input.from(detail);
- }
- return input.actorID;
- }
-});
-
-var Root = Client.from({
- "category": "actor",
- "typeName": "root",
- "methods": [
- {"name": "listTabs",
- "request": {},
- "response": {
- }
- },
- {"name": "listAddons"
- },
- {"name": "echo",
-
- },
- {"name": "protocolDescription",
-
- }
- ]
-});
-
-
-var ActorDetail = Class({
- extends: Actor,
- constructor: function(name, actor, detail) {
- this.detail = detail;
- this.actor = actor;
- },
- read: function(input, client) {
- this.actor.read(input, client, this.detail);
- },
- write: function(input, client) {
- this.actor.write(input, client, this.detail);
- }
-});
-
-var registeredLifetimes = new Map();
-var LifeTime = Class({
- extends: Type,
- category: "lifetime",
- constructor: function(lifetime, type) {
- this.name = lifetime + ":" + type.name;
- this.field = registeredLifetimes.get(lifetime);
- },
- read: function(input, client) {
- return this.type.read(input, client[this.field]);
- },
- write: function(input, client) {
- return this.type.write(input, client[this.field]);
- }
-});
-
-var primitive = new Primitve("primitive");
-var string = new Primitve("string");
-var number = new Primitve("number");
-var boolean = new Primitve("boolean");
-var json = new Primitve("json");
-var array = new Primitve("array");
-
-
-var TypedValue = Class({
- extends: Type,
- constructor: function(name, type) {
- this.TypedValue(name, type);
- },
- TypedValue: function(name, type) {
- this.name = name;
- this.type = type;
- },
- read: function(input, client) {
- return this.client.read(input, this.type);
- },
- write: function(input, client) {
- return this.client.write(input, this.type);
- }
-});
-
-var Return = Class({
- extends: TypedValue,
- constructor: function(type) {
- this.type = type
- }
-});
-
-var Argument = Class({
- extends: TypedValue,
- constructor: function(...args) {
- this.Argument(...args);
- },
- Argument: function(index, type) {
- this.index = index;
- this.TypedValue("argument[" + index + "]", type);
- },
- read: function(input, client, target) {
- return target[this.index] = client.read(input, this.type);
- }
-});
-
-var Option = Class({
- extends: Argument,
- constructor: function(...args) {
- return this.Argument(...args);
- },
- read: function(input, client, target, name) {
- var param = target[this.index] || (target[this.index] = {});
- param[name] = input === void(0) ? input : client.read(input, this.type);
- },
- write: function(input, client, name) {
- var value = input && input[name];
- return value === void(0) ? value : client.write(value, this.type);
- }
-});
-
-var Request = Class({
- extends: Type,
- constructor: function(template={}) {
- this.type = template.type;
- this.template = template;
- this.params = findPlaceholders(template, Argument);
- },
- read: function(packet, client) {
- var args = [];
- for (var param of this.params) {
- var {placeholder, path} = param;
- var name = path[path.length - 1];
- placeholder.read(getPath(packet, path), client, args, name);
- // TODO:
- // args[placeholder.index] = placeholder.read(query(packet, path), client);
- }
- return args;
- },
- write: function(input, client) {
- return JSON.parse(JSON.stringify(this.template, (key, value) => {
- return value instanceof Argument ? value.write(input[value.index],
- client, key) :
- value;
- }));
- }
-});
-
-var Response = Class({
- extends: Type,
- constructor: function(template={}) {
- this.template = template;
- var [x] = findPlaceholders(template, Return);
- var {placeholder, path} = x;
- this.return = placeholder;
- this.path = path;
- },
- read: function(packet, client) {
- var value = query(packet, this.path);
- return this.return.read(value, client);
- },
- write: function(input, client) {
- return JSON.parse(JSON.stringify(this.template, (key, value) => {
- return value instanceof Return ? value.write(input) :
- input
- }));
- }
-});
-
-// Returns array of values for the given object.
-var values = object => Object.keys(object).map(key => object[key]);
-// Returns [key, value] pairs for the given object.
-var pairs = object => Object.keys(object).map(key => [key, object[key]]);
-// Queries an object for the field nested with in it.
-var query = (object, path) => path.reduce((object, entry) => object && object[entry],
- object);
-
-
-var Root = Client.from({
- "category": "actor",
- "typeName": "root",
- "methods": [
- {
- "name": "echo",
- "request": {
- "string": { "_arg": 0, "type": "string" }
- },
- "response": {
- "string": { "_retval": "string" }
- }
- },
- {
- "name": "listTabs",
- "request": {},
- "response": { "_retval": "tablist" }
- },
- {
- "name": "actorDescriptions",
- "request": {},
- "response": { "_retval": "json" }
- }
- ],
- "events": {
- "tabListChanged": {}
- }
-});
-
-var Tab = Client.from({
- "category": "dict",
- "typeName": "tab",
- "specifications": {
- "title": "string",
- "url": "string",
- "outerWindowID": "number",
- "console": "console",
- "inspectorActor": "inspector",
- "callWatcherActor": "call-watcher",
- "canvasActor": "canvas",
- "webglActor": "webgl",
- "webaudioActor": "webaudio",
- "styleSheetsActor": "stylesheets",
- "styleEditorActor": "styleeditor",
- "storageActor": "storage",
- "gcliActor": "gcli",
- "memoryActor": "memory",
- "eventLoopLag": "eventLoopLag",
-
- "trace": "trace", // missing
- }
-});
-
-var tablist = Client.from({
- "category": "dict",
- "typeName": "tablist",
- "specializations": {
- "selected": "number",
- "tabs": "array:tab"
- }
-});
-
-})(this);
-