diff --git a/src/Net/IIP/DistributedConnection.js b/src/Net/IIP/DistributedConnection.js index 9b42c5a..8f71077 100644 --- a/src/Net/IIP/DistributedConnection.js +++ b/src/Net/IIP/DistributedConnection.js @@ -710,7 +710,7 @@ export default class DistributedConnection extends IStore { put(resource) { this.resources.add(parseInt(resource.instance.name), resource); - return true; + return new AsyncReply(true); } remove(resource) { @@ -908,7 +908,8 @@ export default class DistributedConnection extends IStore { var item = new AsyncReply(); self.queue.add(item); - Codec.parseVarArray(content, 0, content.length, self).then(function (args) { + // Codec.parseVarArray(content, 0, content.length, self).then(function (args) { + Codec.parse(content, 0, {}, self).then(function (args) { item.trigger(new DistributedResourceQueueItem(r, DistributedResourceQueueItemType.Event, args, index)); }).error(function (ex) { @@ -1199,7 +1200,7 @@ export default class DistributedConnection extends IStore { IIPRequestInvokeFunctionArrayArguments(callback, resourceId, index, content) { var self = this; - + Warehouse.getById(resourceId).then(function (r) { if (r != null) { Codec.parseVarArray(content, 0, content.length, self).then(function (args) { @@ -1230,14 +1231,20 @@ export default class DistributedConnection extends IStore { if (fi instanceof Function) { args.push(self); - var rt = fi.apply(r, args); - - function* itt() { - - }; + var rt; + + try + { + rt = fi.apply(r, args); + } + catch(ex) + { + self.sendError(ErrorType.Exception, callback, 0, ex.toString()); + return; + } // Is iterator ? - if (rt[Symbol.iterator] instanceof Function) { + if (rt != null && rt[Symbol.iterator] instanceof Function) { for (let v of rt) self.sendChunk(callback, v); @@ -1250,6 +1257,24 @@ export default class DistributedConnection extends IStore { self.sendReply(IIPPacketAction.InvokeFunctionArrayArguments, callback) .addUint8Array(Codec.compose(res, self)) .done(); + }).error(ex => { + self.sendError(ErrorType.Exception, callback, ex.code, ex.message); + }).progress((pt, pv, pm) => + { + self.sendProgress(callback, pv, pm); + }).chunk(v => + { + self.sendChunk(callback, v); + }); + } + else if (rt instanceof Promise) + { + rt.then(function (res) { + self.sendReply(IIPPacketAction.InvokeFunctionArrayArguments, callback) + .addUint8Array(Codec.compose(res, self)) + .done(); + }).catch(ex => { + self.sendError(ErrorType.Exception, callback, 0, ex.toString()); }); } else { @@ -1260,16 +1285,19 @@ export default class DistributedConnection extends IStore { } else { // ft found, fi not found, this should never happen + this.sendError(ErrorType.Management, callback, ExceptionCode.MethodNotFound); } } } else { // no function at this index + this.sendError(ErrorType.Management, callback, ExceptionCode.MethodNotFound); } }); } else { // no resource with this id + this.sendError(ErrorType.Management, callback, ExceptionCode.ResourceNotFound); } }); } @@ -1320,10 +1348,21 @@ export default class DistributedConnection extends IStore { if (args[args.length - 1] === undefined) args[args.length - 1] = self; - var rt = fi.apply(r, args); + + var rt; + + try + { + rt = fi.apply(r, args); + } + catch(ex) + { + self.sendError(ErrorType.Exception, callback, 0, ex.toString()); + return; + } // Is iterator ? - if (rt[Symbol.iterator] instanceof Function) { + if (rt != null && rt[Symbol.iterator] instanceof Function) { for (let v of rt) self.sendChunk(callback, v); @@ -1336,6 +1375,24 @@ export default class DistributedConnection extends IStore { self.sendReply(IIPPacketAction.InvokeFunctionNamedArguments, callback) .addUint8Array(Codec.compose(res, self)) .done(); + }).error(ex => { + self.sendError(ErrorType.Exception, callback, ex.code, ex.message); + }).progress((pt, pv, pm) => + { + self.sendProgress(callback, pv, pm); + }).chunk(v => + { + self.sendChunk(callback, v); + }); + } + else if (rt instanceof Promise) + { + rt.then(function (res) { + self.sendReply(IIPPacketAction.InvokeFunctionNamedArguments, callback) + .addUint8Array(Codec.compose(res, self)) + .done(); + }).catch(ex => { + self.sendError(ErrorType.Exception, callback, 0, ex.toString()); }); } else { @@ -1346,16 +1403,19 @@ export default class DistributedConnection extends IStore { } else { // ft found, fi not found, this should never happen + this.sendError(ErrorType.Management, callback, ExceptionCode.MethodNotFound); } } } else { // no function at this index + this.sendError(ErrorType.Management, callback, ExceptionCode.MethodNotFound); } }); } else { // no resource with this id + this.sendError(ErrorType.Management, callback, ExceptionCode.ResourceNotFound); } }); } @@ -1492,14 +1552,19 @@ export default class DistributedConnection extends IStore { Warehouse.query(resourceLink).then(function (resources) { - var list = resources.filter(function (r) { return r.instance.applicable(self.session, ActionType.Attach, null) != Ruling.Denied }); - - if (list.length == 0) + if (resources == null) self.sendError(ErrorType.Management, callback, ExceptionCode.ResourceNotFound); else - self.sendReply(IIPPacketAction.QueryLink, callback) - .addUint8Array(Codec.composeResourceArray(list, self, true)) - .done(); + { + var list = resources.filter(function (r) { return r.instance.applicable(self.session, ActionType.Attach, null) != Ruling.Denied }); + + if (list.length == 0) + self.sendError(ErrorType.Management, callback, ExceptionCode.ResourceNotFound); + else + self.sendReply(IIPPacketAction.QueryLink, callback) + .addUint8Array(Codec.composeResourceArray(list, self, true)) + .done(); + } }); } @@ -1664,13 +1729,15 @@ export default class DistributedConnection extends IStore { // ClassId, ResourceAge, ResourceLink, Content if (resource == null) { - Warehouse.put(dr, id.toString(), self, null, tmp).then(function(ok){ + let wp = Warehouse.put(dr, id.toString(), self, null, tmp).then(function(ok){ Codec.parsePropertyValueArray(rt[3], 0, rt[3].length, self).then(function (ar) { dr._attach(ar); self.resourceRequests.remove(id); reply.trigger(dr); }); - }).error(function(ex){ + }); + + wp.error(function(ex){ reply.triggerError(ex); }); } @@ -1753,11 +1820,12 @@ export default class DistributedConnection extends IStore { if (resource.instance.applicable(this.session, ActionType.ReceiveEvent, et, issuer) == Ruling.Denied) return; + // compose the packet this.sendEvent(IIPPacketEvent.EventOccurred) .addUint32(resource.instance.id) .addUint8(et.index) - .addUint8Array(Codec.composeVarArray(args, this, true)) + .addUint8Array(Codec.compose(args, this, true)) .done(); } diff --git a/src/Net/IIP/DistributedResource.js b/src/Net/IIP/DistributedResource.js index 55dae1e..fe6aea0 100644 --- a/src/Net/IIP/DistributedResource.js +++ b/src/Net/IIP/DistributedResource.js @@ -169,7 +169,9 @@ export default class DistributedResource extends IResource _emitEventByIndex(index, args) { var et = this.instance.template.getEventTemplateByIndex(index); - this._emitArgs(et.name, args); + //@TODO if array _emitArgs + //this._emitArgs(et.name, [args]); + this._emit(et.name, args); this.instance._emitResourceEvent(null, null, et.name, args); } diff --git a/src/Net/Packets/IIPPacket.js b/src/Net/Packets/IIPPacket.js index b7682f7..f30e191 100644 --- a/src/Net/Packets/IIPPacket.js +++ b/src/Net/Packets/IIPPacket.js @@ -146,7 +146,8 @@ export default class IIPPacket offset += cl; } - else if (this.event == IIPPacketEvent.PropertyUpdated) + else if (this.event == IIPPacketEvent.PropertyUpdated + || this.event == IIPPacketEvent.EventOccurred) { if (this.notEnough(offset, ends, 2)) return -this.dataLengthNeeded; @@ -179,22 +180,22 @@ export default class IIPPacket offset += size; } } - else if (this.event == IIPPacketEvent.EventOccurred) - { - if (this.notEnough(offset, ends, 5)) - return -this.dataLengthNeeded; + // else if (this.event == IIPPacketEvent.EventOccurred) + // { + // if (this.notEnough(offset, ends, 5)) + // return -this.dataLengthNeeded; - this.methodIndex = data.getUint8(offset++); + // this.methodIndex = data.getUint8(offset++); - var cl = data.getUint32(offset); - offset += 4; + // var cl = data.getUint32(offset); + // offset += 4; - if (this.notEnough(offset, ends, cl)) - return -this.dataLengthNeeded; + // if (this.notEnough(offset, ends, cl)) + // return -this.dataLengthNeeded; - this.content = data.clip(offset, cl); - offset += cl; - } + // this.content = data.clip(offset, cl); + // offset += cl; + // } // Attribute else if (this.event == IIPPacketEvent.AttributesUpdated) { @@ -368,9 +369,10 @@ export default class IIPPacket offset += 8; } - else if ( this.action == IIPPacket.InvokeFunctionArrayArguments + else if ( this.action == IIPPacketAction.InvokeFunctionArrayArguments || this.action == IIPPacketAction.InvokeFunctionNamedArguments) { + if (this.notEnough(offset, ends, 9)) return -this.dataLengthNeeded; @@ -554,6 +556,7 @@ export default class IIPPacket || this.action == IIPPacketAction.GetProperty || this.action == IIPPacketAction.GetPropertyIfModified) { + if (this.notEnough(offset, ends, 1)) return -this.dataLengthNeeded; diff --git a/src/Resource/IResource.js b/src/Resource/IResource.js index af1e34d..2effe64 100644 --- a/src/Resource/IResource.js +++ b/src/Resource/IResource.js @@ -26,6 +26,8 @@ "use strict"; +import AsyncBag from '../Core/AsyncBag.js'; +import AsyncReply from '../Core/AsyncReply.js'; import IDestructible from '../Core/IDestructible.js'; export const ResourceTrigger = @@ -43,7 +45,7 @@ export default class IResource extends IDestructible { trigger(trigger) { - + return new AsyncReply(true); } constructor() diff --git a/src/Resource/Instance.js b/src/Resource/Instance.js index 3833f04..16770db 100644 --- a/src/Resource/Instance.js +++ b/src/Resource/Instance.js @@ -35,6 +35,7 @@ import Structure from '../Data/Structure.js'; import PropertyValue from '../Data/PropertyValue.js'; import CustomResourceEvent from './CustomResourceEvent.js'; import Warehouse from './Warehouse.js'; +import Ruling from '../Security/Permissions/Ruling.js'; export default class Instance extends IEventHandler { diff --git a/src/Resource/Template/EventTemplate.js b/src/Resource/Template/EventTemplate.js index 8ec036f..41b4bc5 100644 --- a/src/Resource/Template/EventTemplate.js +++ b/src/Resource/Template/EventTemplate.js @@ -46,10 +46,18 @@ export default class EventTemplate extends MemberTemplate var name = super.compose(); if (this.expansion != null) { var exp = DC.stringToBytes(this.expansion); - return rt.addUint8(0x50).addUint8(name.length).addUint8Array(name).addUint32(exp.length).addUint8Array(exp).toArray(); + return rt.addUint8(0x50) + .addUint8(name.length) + .addUint8Array(name) + .addUint32(exp.length) + .addUint8Array(exp) + .toArray(); } else - return rt.addUint8(0x40).addUint32(name.length).addUint8Array(name).toArray(); + return rt.addUint8(0x40) + .addUint8(name.length) + .addUint8Array(name) + .toArray(); } } diff --git a/src/Resource/Template/FunctionTemplate.js b/src/Resource/Template/FunctionTemplate.js index 89e5cd6..10706c4 100644 --- a/src/Resource/Template/FunctionTemplate.js +++ b/src/Resource/Template/FunctionTemplate.js @@ -39,11 +39,17 @@ export default class FunctionTemplate extends MemberTemplate { var exp = DC.stringToBytes(this.expansion); return rt.addUint8(0x10 | (this.isVoid ? 0x8 : 0x0)) - .addUint8(name.length).addUint8Array(name) - .addUint32(exp.length).addUint8Array(exp).toArray(); + .addUint8(name.length) + .addUint8Array(name) + .addUint32(exp.length) + .addUint8Array(exp) + .toArray(); } else - return rt.addUint8(this.isVoid ? 0x8 : 0x0).addUint8(name.length).addUint8Array(name).toArray(); + return rt.addUint8(this.isVoid ? 0x8 : 0x0) + .addUint8(name.length) + .addUint8Array(name) + .toArray(); } constructor() { diff --git a/src/Resource/Template/PropertyTemplate.js b/src/Resource/Template/PropertyTemplate.js index 40ac0ad..1750f49 100644 --- a/src/Resource/Template/PropertyTemplate.js +++ b/src/Resource/Template/PropertyTemplate.js @@ -49,7 +49,7 @@ export default class PropertyTemplate extends MemberTemplate { var name = super.compose(); var rt = BL(); - var pv = (this.permission >> 1) | (this.recordable ? 1 : 0); + var pv = (this.permission << 1) | (this.recordable ? 1 : 0); if (this.writeExpansion != null && this.readExpansion != null) { @@ -86,7 +86,7 @@ export default class PropertyTemplate extends MemberTemplate } else return rt.addUint8(0x20 | pv) - .addUint32(name.length) + .addUint8(name.length) .addUint8Array(name) .toArray(); } diff --git a/src/Resource/Template/ResourceTemplate.js b/src/Resource/Template/ResourceTemplate.js index 2731e6a..b834a84 100644 --- a/src/Resource/Template/ResourceTemplate.js +++ b/src/Resource/Template/ResourceTemplate.js @@ -150,7 +150,10 @@ export default class ResourceTemplate { var b = BL(); var cls = DC.stringToBytes(this.className); b.addUint8Array(this.classId.value) - .addUint8(cls.length).addUint8Array(cls).addUint32(template.version).addUint16(this.members.length); + .addUint8(cls.length) + .addUint8Array(cls) + .addUint32(template.version) + .addUint16(this.members.length); for (var i = 0; i < this.functions.length; i++) b.addUint8Array(this.functions[i].compose()); diff --git a/src/Resource/Warehouse.js b/src/Resource/Warehouse.js index 36bc701..ff2d3fc 100644 --- a/src/Resource/Warehouse.js +++ b/src/Resource/Warehouse.js @@ -36,8 +36,9 @@ import MemoryStore from '../Stores/MemoryStore.js'; import Instance from '../Resource/Instance.js'; import IStore from './IStore.js'; import { ResourceTrigger } from './IResource.js'; -import IndexDBStore from '../Stores/IndexDBStore.js'; +import IndexedDBStore from '../Stores/IndexedDBStore.js'; import ResourceProxy from '../Proxy/ResourceProxy.js'; +import AsyncBag from '../Core/AsyncBag.js'; export class WH extends IEventHandler @@ -57,17 +58,22 @@ export class WH extends IEventHandler this._urlRegex = /^(?:([^\s|:]*):\/\/([^\/]*)\/?)/; } - async new(type, name, store = null, parent = null, manager = null, attributes = null, properties = null) + new(type, name, store = null, parent = null, manager = null, attributes = null, properties = null) { var proxyType = ResourceProxy.getProxy(type); + var rt = new AsyncReply(); + var res = new proxyType(); if (properties != null) Object.assign(res, properties); - await this.put(res, name, store, parent, null, 0, manager, attributes); - return res; + this.put(res, name, store, parent, null, 0, manager, attributes) + .then((ok)=>rt.trigger(res)) + .error((ex)=>rt.triggerError(ex)); + + return rt; } getById(id) @@ -75,82 +81,57 @@ export class WH extends IEventHandler return new AsyncReply(this.resources.item(id)); } - async get(path, attributes = null, parent = null, manager = null) + get(path, attributes = null, parent = null, manager = null) { - //var rt = new AsyncReply(); - //var self = this; + var rt = new AsyncReply(); + var self = this; // Should we create a new store ? if (path.match(this._urlRegex)) - //if (path.includes("://")) { // with port //var url = path.split(/(?:):\/\/([^:\/]*):?(\d*)/); // without port let url = path.split(this._urlRegex); - + var handler; + const initResource = ()=>{ + handler(url[2], attributes).then(store => { + if (url[3].length > 0 && url[3] != "") + store.get(url[3]).then(r=>rt.trigger(r)).error(ex=>rt.triggerError(ex)); + else + rt.triggerError(store); + }).error(ex=>{ + Warehouse.remove(resource); + rt.triggerError(ex); + }); + } + if (handler = this.protocols.item(url[1])) { if (!this.warehouseIsOpen) - await this.open(); - - var store = await handler(url[2], attributes); - //await this.put(store, url[2], null, parent, null, 0, manager, attributes); - //await store.trigger(ResourceTrigger.Open); - //this.warehouseIsOpen = true; - - try { - if (url[3].length > 0 && url[3] != "") - return await store.get(url[3]); - else - return store; - } catch(ex) - { - this.remove(resource); - throw ex; + this.open().then((ok)=>{ + initResource(); + }).error(ex=>rt.triggerError(ex)); } - - // store.trigger(ResourceTrigger.Open).then(x => { - - // this.warehouseIsOpen = true; - - // if (url[3].length > 0 && url[3] != "") - // store.get(url[3]).then(r => { - // rt.trigger(r); - // }).error(e => rt.triggerError(e)); - // else - // rt.trigger(store); - // }).error(e => { - // rt.triggerError(e); - // self.remove(store); - // }); - - // return rt; + else + initResource(); + + return rt; } } - var rs = await this.query(path); - - if (rs != null && rs.length > 0) - return rs[0]; - else - return null; - - // .then(rs => - // { - // if (rs != null && rs.length > 0) - // rt.trigger(rs[0]); - // else - // rt.trigger(null); - // }); - - //return rt; - + this.query(path).then(rs => { + if (rs != null && rs.length > 0) + rt.trigger(rs[0]); + else + rt.trigger( null); + }).error(ex => rt.triggerError(ex)); + return rt; } @@ -194,7 +175,9 @@ export class WH extends IEventHandler return true; } - async put(resource, name, store, parent, customTemplate = null, age = 0, manager = null, attributes = null){ + put(resource, name, store, parent, customTemplate = null, age = 0, manager = null, attributes = null){ + + var rt = new AsyncReply(); resource.instance = new Instance(this.resourceCounter++, name, resource, store, customTemplate, age); //resource.instance.children.on("add", Warehouse._onChildrenAdd).on("remove", Warehouse._onChildrenRemove); @@ -216,25 +199,42 @@ export class WH extends IEventHandler store.instance.children.add(resource); } - if (resource instanceof IStore) - this.stores.add(resource); - else - await store.put(resource); + let self = this; - this.resources.add(resource.instance.id, resource); + const initResource = ()=>{ + self.resources.add(resource.instance.id, resource); - if (this.warehouseIsOpen) - { - await resource.trigger(ResourceTrigger.Initialize); - - if (resource instanceof IStore) - await resource.trigger(ResourceTrigger.Open); + if (self.warehouseIsOpen) + { + resource.trigger(ResourceTrigger.Initialize).then(x=>{ + if (resource instanceof IStore) + resource.trigger(ResourceTrigger.Open).then(y=>{ rt.trigger(true); + self._emit("connected", resource) + }).error(ex => rt.triggerError(ex)); + else + rt.trigger(true); + + }).error(ex=>rt.triggerError(ex)); + } + else + { + if (resource instanceof IStore) + self._emit("connected", resource); + rt.trigger(true); + } } if (resource instanceof IStore) - this._emit("connected", resource); + { + this.stores.add(resource); + initResource(); + } + else + store.put(resource).then(ok=>{ + initResource(); + }).error(ex=>rt.triggerError(ex)); - return new AsyncReply(true); + return rt; } _onParentsRemove(value) @@ -325,14 +325,10 @@ export class WH extends IEventHandler return rt; } - async query(path) + query(path) { - //var p = path.split('/'); - //return new AsyncReply(this._qureyIn(p, 0, this.stores)); - - var rt = new AsyncReply(); var p = path.trim().split('/'); var resource; @@ -345,65 +341,102 @@ export class WH extends IEventHandler { if (p.length == 1) - return [store]; - + return new AsyncReply([store]); - var res = await store.get(p.splice(1).join("/")); - if (res != null) - return [res]; - - - resource = store; - for (var i = 1; i < p.length; i++) - { - var children = await resource.instance.children.list.filter(x=>x.instance.name == p[i]);// (p[i]); - if (children.length > 0) - { - if (i == p.length - 1) - return children; - else - resource = children[0]; - } + var rt = new AsyncReply(); + + store.get(p.splice(1).join("/")).then(res=>{ + if (res != null) + rt.trigger([res]); else - break; - } + { + resource = store; - return null; + for (var i = 1; i < p.length; i++) + { + var children = resource.instance.children.list.filter(x=>x.instance.name == p[i]);// (p[i]); + if (children.length > 0) + { + if (i == p.length - 1) + { + rt.trigger(children); + return; + } + else + resource = children[0]; + } + else + break; + } + + rt.trigger(null); + } + }).error(ex => rt.triggerError(ex)); + + return rt; } - } - return null; - + return new AsyncReply(null); } - async open() + open() { if (this.warehouseIsOpen) return new AsyncReply(false); - this.warehouseIsOpen = true; + var initBag = new AsyncBag(); + + let rt = new AsyncReply(); + let self = this; for (var i = 0; i < this.resources.length; i++) { var r = this.resources.at(i); - - var rt = await r.trigger(ResourceTrigger.Initialize); - - if (!rt) - console.log(`Resource failed at Initialize ${r.Instance.Name} [${r.Instance.Template.ClassName}]`); + initBag.add(r.trigger(ResourceTrigger.Initialize)); + //if (!rt) + // console.log(`Resource failed at Initialize ${r.Instance.Name} [${r.Instance.Template.ClassName}]`); } - for (var i = 0; i < this.resources.length; i++) - { - var r = this.resources.at(i); - var rt = await r.trigger(ResourceTrigger.SystemInitialized); - if (!rt) - console.log(`Resource failed at SystemInitialized ${r.Instance.Name} [${r.Instance.Template.ClassName}]`); - } + initBag.seal(); - return new AsyncReply(true); + initBag.then(ar => { + + for(var i = 0; i < ar.length; i++) + if (!ar[i]) + console.log(`Resource failed at Initialize ${self.resources.at(i).Instance.Name} [${self.resources.at(i).Instance.Template.ClassName}]`); + + var sysBag = new AsyncBag(); + + for (var i = 0; i < this.resources.length; i++) + { + var r = this.resources.at(i); + sysBag.add(r.trigger(ResourceTrigger.SystemInitialized)); + } + + sysBag.seal(); + sysBag.then(ar2 => { + for(var i = 0; i < ar2.length; i++) + if (!ar2[i]) + console.log(`Resource failed at Initialize ${self.resources.at(i).Instance.Name} [${self.resources.at(i).Instance.Template.ClassName}]`); + + self.warehouseIsOpen = true; + rt.trigger(true); + + }).error(ex => rt.triggerError(ex)); + + }).error(ex => rt.triggerError(ex)); + + // for (var i = 0; i < this.resources.length; i++) + // { + // var r = this.resources.at(i); + // var rt = await r.trigger(ResourceTrigger.SystemInitialized); + // if (!rt) + // console.log(`Resource failed at SystemInitialized ${r.Instance.Name} [${r.Instance.Template.ClassName}]`); + // } + + return rt; } } @@ -412,7 +445,7 @@ let Warehouse = new WH(); Warehouse.protocols.add("iip", (name, attributes) => Warehouse.new(DistributedConnection, name, null, null, null, attributes)); Warehouse.protocols.add("mem", (name, attributes) => Warehouse.new(MemoryStore, name, null, null, null, attributes)); -Warehouse.protocols.add("db", (name, attributes) => Warehouse.new(IndexDBStore, name, null, null, null, attributes)); +Warehouse.protocols.add("db", (name, attributes) => Warehouse.new(IndexedDBStore, name, null, null, null, attributes)); export default Warehouse; diff --git a/src/Stores/IndexedDBStore.js b/src/Stores/IndexedDBStore.js index 4ee258f..f28cd73 100644 --- a/src/Stores/IndexedDBStore.js +++ b/src/Stores/IndexedDBStore.js @@ -32,6 +32,9 @@ import AsyncReply from '../Core/AsyncReply.js'; import Codec from '../Data/Codec.js'; import Warehouse from '../Resource/Warehouse.js'; import DataType from '../Data/DataType.js'; +import AsyncBag from '../Core/AsyncBag.js'; +import ErrorType from '../Core/ErrorType.js'; +import ExceptionCode from '../Core/ExceptionCode.js'; export default class IndexedDBStore extends IStore { @@ -133,8 +136,10 @@ export default class IndexedDBStore extends IStore this.classes.set(className, type); } - async fetch(id) + fetch(id) { + let self = this; + if (this.resources.has(id)) return new AsyncReply(this.resources.get(id)); @@ -145,44 +150,68 @@ export default class IndexedDBStore extends IStore var request = objectStore.get(id); request.onerror = function(event) { - rt.trigger(null); + rt.triggerError(event); }; - - request.onsuccess = async function(event) { + + request.onsuccess = function(event) { var doc = request.result; - if (!this.classes.has(doc.className)) + if (doc == null) { - rt.triggerError(0, 0, "Class not found"); + //rt.triggerError(ErrorType.Management, ExceptionCode.ResourceNotFound); + rt.trigger(null); + return; + } + + if (!self.classes.has(doc.className)) + { + rt.triggerError(ErrorType.Management, ExceptionCode.ClassNotFound); return; } //let r = await Warehouse.new(, doc.name, this, null, null, this); - let type = this.classes.get(doc.className); + let type = self.classes.get(doc.className); var proxyType = ResourceProxy.getProxy(type); var resource = new proxyType(); - this.resources.set(doc._id, resource); + self.resources.set(doc.id, resource); - await Warehouse.put(resource, doc.name, this, null, null, null, null); + resource._id = doc.id; - var attributes = await parse(doc.attributes); - resource.instance.setAttributes(attributes); + Warehouse.put(resource, doc.name, self, null, null, null, null).then(ok=>{ + self.parse(doc.attributes).then(attributes=>{ - - // Apply store managers - for (var i = 0; i < this.instance.managers.length; i++) - resource.instance.managers.add(this.instance.managers[i]); + resource.instance.setAttributes(attributes); + + // Apply store managers + for (var i = 0; i < self.instance.managers.length; i++) + resource.instance.managers.add(self.instance.managers[i]); + + // Load values + + var bag = new AsyncBag(); - // Load values + for(var i = 0; i < doc.values.length; i++) + { + let v = doc.values[i]; - for(var i = 0; i < doc.values.length; i++) - { - let v = doc.values[i]; - var x = await this.parse(v.value); - resource.instance.loadProperty(v.name, v.age, v.modification, x); - } + bag.add(self.parse(v.value)); + //var x = await this.parse(v.value); + resource.instance.loadProperty(v.name, v.age, v.modification, x); + } - rt.trigger(resource); + bag.seal(); + + bag.then(ar=>{ + for(var i = 0; i < ar.length; i++) + { + let v = doc.values[i]; + resource.instance.loadProperty(v.name, v.age, v.modification, ar[i]); + } + + rt.trigger(resource); + }).error(ex => rt.triggerError(ex)); + }).error(ex => rt.triggerError(ex)); + }).error(ex => rt.triggerError(ex)); }; return rt; @@ -190,6 +219,7 @@ export default class IndexedDBStore extends IStore put(resource) { + let rt = new AsyncReply(); var transaction = this.db.transaction(["resources"], "readwrite"); @@ -202,9 +232,11 @@ export default class IndexedDBStore extends IStore className: resource.instance.template.className, name: resource.instance.name, attributes: this.composeStructure(attrs), - _id: resource._id // if it has an Id will be replaced }; + if (resource._id != null) + record.id = resource._id; + // copy resource data let props = resource.instance.template.properties; @@ -219,12 +251,8 @@ export default class IndexedDBStore extends IStore } record.values = snap; - - //snap[props[i].name] = resource[props[i].name]; - - // debugger; - - var request = objectStore.put(snap); + + var request = objectStore.put(record); request.onerror = function(event) { rt.trigger(false); @@ -264,7 +292,7 @@ export default class IndexedDBStore extends IStore if (p[0] == "id") { // load from Id - return this.fetch(p[1]); + return this.fetch(parseInt(p[1])); } return new AsyncReply(null); @@ -287,7 +315,7 @@ export default class IndexedDBStore extends IStore let rt = new AsyncReply(); request.onupgradeneeded = function(event) { - self._store = request.result.createObjectStore("resources", {keyPath: "_id", autoIncrement: true}); + self._store = request.result.createObjectStore("resources", {keyPath: "id", autoIncrement: true}); console.log(self._store); };