realm-js/lib/util.js

99 lines
2.4 KiB
JavaScript

'use strict';
let keys = require('./keys');
let rpc = require('./rpc');
module.exports = {
createList,
createMethods,
getterForProperty,
setterForProperty,
};
function createList(prototype, realmId, info, mutable) {
let list = Object.create(prototype);
let size = 0;
Object.defineProperty(list, 'length', {get: getterForProperty('length')});
list[keys.resize] = function(length) {
if (length == null) {
length = this.length;
}
if (length == size) {
return;
}
if (length > size) {
let props = {};
for (let i = size; i < length; i++) {
props[i] = {
get: getterForProperty(i),
set: mutable ? setterForProperty(i) : undefined,
enumerable: true,
configurable: true,
};
}
Object.defineProperties(this, props);
}
else if (length < size) {
for (let i = size - 1; i >= length; i--) {
delete this[i];
}
}
size = length;
};
list[keys.realm] = realmId;
list[keys.id] = info.id;
list[keys.type] = info.type;
list[keys.resize](info.size);
return list;
}
function createMethods(prototype, type, methodNames, resize) {
let props = {};
for (let name of methodNames) {
props[name] = {
value: function() {
let realmId = this[keys.realm];
let id = this[keys.id];
if (!realmId || !id) {
throw new TypeError(name + ' method was not called a Realm object!');
}
if (this[keys.type] !== type) {
throw new TypeError(name + ' method was called on an object of the wrong type!');
}
let result = rpc.callMethod(realmId, id, type, name, Array.from(arguments));
if (resize) {
this[keys.resize]();
}
return result;
}
};
}
Object.defineProperties(prototype, props);
}
function getterForProperty(name) {
return function() {
return rpc.getProperty(this[keys.realm], this[keys.id], name);
};
}
function setterForProperty(name) {
return function(value) {
rpc.setProperty(this[keys.realm], this[keys.id], name, value);
};
}