mirror of
https://github.com/esiur/esiur-js.git
synced 2026-04-03 21:48:21 +00:00
2.0.0
This commit is contained in:
@@ -28,10 +28,10 @@
|
||||
|
||||
export default class CustomResourceEvent
|
||||
{
|
||||
constructor(issuer, receivers, args)
|
||||
constructor(issuer, receivers, value)
|
||||
{
|
||||
this.issuer = issuer;
|
||||
this.receivers = receivers;
|
||||
this.args = args;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
20
src/Resource/EventOccurredInfo.js
Normal file
20
src/Resource/EventOccurredInfo.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import Session from '../Security/Authority/Session.js';
|
||||
import IResource from './IResource.js';
|
||||
import EventTemplate from './Template/EventTemplate.js';
|
||||
|
||||
export default class EventOccurredInfo {
|
||||
|
||||
get name(){
|
||||
return this.eventTemplate.name;
|
||||
}
|
||||
|
||||
|
||||
constructor(resource, eventTemplate, value, issuer,
|
||||
receivers) {
|
||||
this.resource =resource;
|
||||
this.eventTemplate = eventTemplate;
|
||||
this.value = value;
|
||||
this.issuer = issuer;
|
||||
this.receivers = receivers;
|
||||
}
|
||||
}
|
||||
34
src/Resource/FactoryEntry.js
Normal file
34
src/Resource/FactoryEntry.js
Normal file
@@ -0,0 +1,34 @@
|
||||
export default class FactoryEntry {
|
||||
|
||||
//Type get type => T;
|
||||
|
||||
//late Type nullableType;
|
||||
//final Function instanceCreator;
|
||||
//final Function arrayCreator = () => <T>[];
|
||||
//final RepresentationType representationType;
|
||||
|
||||
isMapKeySubType(map) {
|
||||
//return map is Map<T, dynamic>;
|
||||
}
|
||||
|
||||
isMapValueSubType(map) {
|
||||
//return map is Map<dynamic, T>;
|
||||
}
|
||||
|
||||
isListSubType(list) {
|
||||
//return list is List<T>;
|
||||
}
|
||||
|
||||
constructor(type, representationType) {
|
||||
this.type = type;
|
||||
this.nullableType = this.getNullableType(type);
|
||||
this.representationType = representationType;
|
||||
}
|
||||
|
||||
getNullableType(type){
|
||||
let c = class extends type {};
|
||||
Object.defineProperty(c, "name", {value: "Nullable" + type.name});
|
||||
Object.defineProperty(c, "nullable", {value: true});
|
||||
return c;
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,10 @@ export default class IResource extends IDestructible
|
||||
super();
|
||||
}
|
||||
|
||||
toString(){
|
||||
return this?.instance?.template?.namespace ?? "IResource";
|
||||
}
|
||||
|
||||
static get template()
|
||||
{
|
||||
return {
|
||||
|
||||
@@ -46,6 +46,11 @@ export default class IStore extends IResource {
|
||||
|
||||
}
|
||||
|
||||
modify(resource, propertyName, value, age, dateTime)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
getRecord(resource, fromDate, toDate)
|
||||
{
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
import IEventHandler from '../Core/IEventHandler.js';
|
||||
import IPermissionsManager from '../Security/Permissions/IPermissionsManager.js';
|
||||
import StructureArray from '../Data/StructureArray.js';
|
||||
import AutoList from '../Data/AutoList.js';
|
||||
import KeyList from '../Data/KeyList.js';
|
||||
import Structure from '../Data/Structure.js';
|
||||
@@ -36,6 +35,11 @@ import PropertyValue from '../Data/PropertyValue.js';
|
||||
import CustomResourceEvent from './CustomResourceEvent.js';
|
||||
import Warehouse from './Warehouse.js';
|
||||
import Ruling from '../Security/Permissions/Ruling.js';
|
||||
import TypedMap from '../Data/TypedMap.js';
|
||||
import TypedList from '../Data/TypedList.js';
|
||||
import EventOccurredInfo from './EventOccurredInfo.js';
|
||||
import PropertyModificationInfo from './PropertyModificationInfo.js';
|
||||
import PropertyValueArray from '../Data/PropertyValueArray.js';
|
||||
|
||||
export default class Instance extends IEventHandler
|
||||
{
|
||||
@@ -110,7 +114,7 @@ export default class Instance extends IEventHandler
|
||||
|
||||
serialize()
|
||||
{
|
||||
var props = [];
|
||||
var props = new PropertyValueArray();
|
||||
|
||||
for (var i = 0; i < this.template.properties.length; i++)
|
||||
props.push(new PropertyValue(this.resource[this.template.properties[i].name],
|
||||
@@ -122,7 +126,7 @@ export default class Instance extends IEventHandler
|
||||
|
||||
isStorable()
|
||||
{
|
||||
return resource instanceof Storable;
|
||||
return false;
|
||||
}
|
||||
|
||||
emitModification(pt, value)
|
||||
@@ -136,10 +140,17 @@ export default class Instance extends IEventHandler
|
||||
|
||||
if (pt.recordable)
|
||||
this.store.record(this.resource, pt.name, value, this.ages[pt.index], now);
|
||||
else
|
||||
this.store.modify(this.resource, pt.name, value, this.ages[pt.index], now);
|
||||
|
||||
super._emit("ResourceModified", this.resource, pt.name, value);
|
||||
//this.resource._emit("modified", pt.name, value);
|
||||
this.resource._emit(":" + pt.name, value);
|
||||
let pmInfo = new PropertyModificationInfo(this.resource, pt, value, this.instanceAge);
|
||||
|
||||
super._emit("PropertyModified", pmInfo);
|
||||
this.resource._emit(`:${pt.name}`, value);
|
||||
//this.resource.emitProperty(pmInfo);
|
||||
|
||||
//super._emit("ResourceModified", this.resource, pt.name, value);
|
||||
//this.resource._emit(":" + pt.name, value);
|
||||
}
|
||||
|
||||
modified(propertyName = null)
|
||||
@@ -155,9 +166,11 @@ export default class Instance extends IEventHandler
|
||||
}
|
||||
}
|
||||
|
||||
_emitResourceEvent(issuer, receivers, name, args)
|
||||
_emitResourceEvent(issuer, receivers, eventTemplate, value)
|
||||
{
|
||||
super._emit("ResourceEventOccurred", this.resource, issuer, receivers, name, args);
|
||||
super._emit("EventOccurred",
|
||||
new EventOccurredInfo(this.resource, eventTemplate, value, issuer, receivers));
|
||||
//super._emit("ResourceEventOccurred", this.resource, issuer, receivers, name, args);
|
||||
}
|
||||
|
||||
getPropertyValue(name, resultObject)
|
||||
@@ -173,6 +186,9 @@ export default class Instance extends IEventHandler
|
||||
}
|
||||
|
||||
|
||||
get age() {
|
||||
return this.instanceAge;
|
||||
}
|
||||
|
||||
constructor(id, name, resource, store, customTemplate = null, age = 0)
|
||||
{
|
||||
@@ -223,20 +239,20 @@ export default class Instance extends IEventHandler
|
||||
}
|
||||
|
||||
// connect events
|
||||
for (var i = 0; i < this.template.events.length; i++)
|
||||
this.resource.on(this.template.events[i].name, this._makeHandler(this.template.events[i].name));
|
||||
for (let i = 0; i < this.template.events.length; i++)
|
||||
this.resource.on(this.template.events[i].name, this._makeHandler(this.template.events[i]));
|
||||
|
||||
}
|
||||
|
||||
_makeHandler(name)
|
||||
_makeHandler(eventTemplate)
|
||||
{
|
||||
var self = this;
|
||||
return function(args)
|
||||
return function(argument)
|
||||
{
|
||||
if (args instanceof CustomResourceEvent)
|
||||
self._emitResourceEvent(args.issuer, args.receivers, name, args.args);
|
||||
if (argument instanceof CustomResourceEvent)
|
||||
self._emitResourceEvent(argument.issuer, argument.receivers, eventTemplate, argument.value);
|
||||
else
|
||||
self._emitResourceEvent(null, null, name, args);
|
||||
self._emitResourceEvent(null, null, eventTemplate, argument);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -294,14 +310,14 @@ export default class Instance extends IEventHandler
|
||||
|
||||
else if (attr == "managers")
|
||||
{
|
||||
var mngrs = new StructureArray();
|
||||
var mngrs = new (TypedList.of(TypedMap.of(String, Object)));
|
||||
|
||||
for(var j = 0; j < this.managers.length; j++)
|
||||
{
|
||||
var manager = this.managers.item(j);
|
||||
var sm = new Structure();
|
||||
sm["type"] = manager.constructor.name;
|
||||
sm["settings"] = manager.settings;
|
||||
var sm = new (TypedMap.of(String, Object));
|
||||
sm.set("type", manager.constructor.name);
|
||||
sm.set("settings", manager.settings);
|
||||
|
||||
mngrs.push(sm);
|
||||
}
|
||||
|
||||
17
src/Resource/PropertyModificationInfo.js
Normal file
17
src/Resource/PropertyModificationInfo.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import IResource from './IResource.js';
|
||||
import PropertyTemplate from './Template/PropertyTemplate.js';
|
||||
|
||||
export default class PropertyModificationInfo {
|
||||
|
||||
get name(){
|
||||
return this.propertyTemplate.name;
|
||||
}
|
||||
|
||||
PropertyModificationInfo(
|
||||
resource, propertyTemplate, value, age) {
|
||||
this.resource = resource;
|
||||
this.propertyTemplate = propertyTemplate;
|
||||
this.value = value;
|
||||
this.age = age;
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,38 @@
|
||||
import DC from "../../Data/DataConverter.js";
|
||||
import BinaryList from "../../Data/BinaryList.js";
|
||||
import TemplateDataType from "./TemplateDataType.js";
|
||||
|
||||
export default class ArgumentTemplate
|
||||
{
|
||||
static parse(data, offset)
|
||||
{
|
||||
var cs = data[offset++];
|
||||
var name = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
var {size, value} = TemplateDataType.parse(data, offset);
|
||||
import {DC, BL} from '../../Data/DC.js';
|
||||
import RepresentationType from '../../Data/RepresentationType.js';
|
||||
|
||||
return {size: cs + 1 + size, value: new ArgumentTemplate(name, value)};
|
||||
}
|
||||
import ParseResult from "../../Data/ParseResult.js";
|
||||
|
||||
constructor(name, type){
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
export default class ArgumentTemplate {
|
||||
|
||||
compose()
|
||||
{
|
||||
var name = DC.stringToBytes(this.name);
|
||||
static parse(data, offset, index) {
|
||||
var optional = (data[offset++] & 0x1) == 0x1;
|
||||
|
||||
return new BinaryList()
|
||||
.addUint8(name.length)
|
||||
.addUint8Array(name)
|
||||
.addUint8Array(this.type.compose())
|
||||
.toArray();
|
||||
}
|
||||
var cs = data[offset++];
|
||||
var name = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
var tdr = RepresentationType.parse(data, offset);
|
||||
|
||||
return new ParseResult(
|
||||
cs + 2 + tdr.size, new ArgumentTemplate(name, tdr.type, optional, index));
|
||||
}
|
||||
|
||||
constructor(name, type, optional, index){
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.optional = optional;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
compose() {
|
||||
var name = DC.stringToBytes(this.name);
|
||||
|
||||
return (BL()
|
||||
.addUint8(this.optional ? 1 : 0)
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(this.type.compose()))
|
||||
.toDC();
|
||||
}
|
||||
}
|
||||
|
||||
46
src/Resource/Template/ConstantTemplate.js
Normal file
46
src/Resource/Template/ConstantTemplate.js
Normal file
@@ -0,0 +1,46 @@
|
||||
import {DC, BL} from '../../Data/DC.js';
|
||||
import MemberTemplate from './MemberTemplate.js';
|
||||
import Codec from '../../Data/Codec.js';
|
||||
|
||||
export default class ConstantTemplate extends MemberTemplate {
|
||||
//final dynamic value;
|
||||
//final String? expansion;
|
||||
//final RepresentationType valueType;
|
||||
|
||||
constructor(template, index, name,
|
||||
inherited, valueType, value, expansion){
|
||||
super(template, index, name, inherited) ;
|
||||
this.valueType = valueType;
|
||||
this.value = value;
|
||||
this.expansion = expansion;
|
||||
}
|
||||
|
||||
compose() {
|
||||
var name = super.compose();
|
||||
var hdr = this.inherited ? 0x80 : 0;
|
||||
|
||||
if (this.expansion != null) {
|
||||
var exp = DC.stringToBytes(this.expansion);
|
||||
hdr |= 0x70;
|
||||
return (BL()
|
||||
.addUint8(hdr)
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(this.valueType.compose())
|
||||
.addDC(Codec.compose(this.value, null))
|
||||
.addInt32(exp.length)
|
||||
.addDC(exp))
|
||||
.toDC();
|
||||
} else {
|
||||
hdr |= 0x60;
|
||||
|
||||
return (BL()
|
||||
.addUint8(hdr)
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(this.valueType.compose())
|
||||
.addDC(Codec.compose(this.value, null)))
|
||||
.toDC();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,39 +26,48 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
import {DC, BL} from '../../Data/DataConverter.js';
|
||||
import {DC, BL} from '../../Data/DC.js';
|
||||
import MemberTemplate from './MemberTemplate.js';
|
||||
import MemberType from './MemberType.js';
|
||||
|
||||
|
||||
export default class EventTemplate extends MemberTemplate
|
||||
{
|
||||
export default class EventTemplate extends MemberTemplate {
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
this.type = MemberType.Event;
|
||||
compose() {
|
||||
let name = super.compose();
|
||||
|
||||
let hdr = this.inherited ? 0x80 : 0;
|
||||
|
||||
if (this.listenable) hdr |= 0x8;
|
||||
|
||||
if (this.expansion != null) {
|
||||
let exp = DC.stringToBytes(this.expansion);
|
||||
hdr |= 0x50;
|
||||
return (BL()
|
||||
.addUint8(hdr)
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(this.argumentType.compose())
|
||||
.addInt32(exp.length)
|
||||
.addDC(exp))
|
||||
.toDC();
|
||||
} else {
|
||||
hdr |= 0x40;
|
||||
return (BL()
|
||||
.addUint8(hdr)
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(this.argumentType.compose()))
|
||||
.toDC();
|
||||
}
|
||||
}
|
||||
|
||||
constructor(template, index, name, inherited, argumentType,
|
||||
expansion = null, listenable = false)
|
||||
{
|
||||
super(template, index, name, inherited) ;
|
||||
this.argumentType = argumentType;
|
||||
this.expansion = expansion;
|
||||
this.listenable = listenable;
|
||||
}
|
||||
|
||||
compose()
|
||||
{
|
||||
var rt = BL();
|
||||
|
||||
var name = super.compose();
|
||||
if (this.expansion != null) {
|
||||
var exp = DC.stringToBytes(this.expansion);
|
||||
return rt.addUint8(this.listenable ? 0x58 : 0x50)
|
||||
.addUint8(name.length)
|
||||
.addUint8Array(name)
|
||||
.addUint8Array(this.argumentType.compose())
|
||||
.addUint32(exp.length)
|
||||
.addUint8Array(exp)
|
||||
.toArray();
|
||||
}
|
||||
else
|
||||
return rt.addUint8(this.listenable ? 0x48 : 0x40)
|
||||
.addUint8(name.length)
|
||||
.addUint8Array(name)
|
||||
.addUint8Array(this.argumentType.compose())
|
||||
.toArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
* Copyright (c) 2017-2022 Ahmed Kh. Zamil
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -26,38 +26,38 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
import {DC, BL} from '../../Data/DataConverter.js';
|
||||
import {DC, BL} from '../../Data/DC.js';
|
||||
import MemberTemplate from './MemberTemplate.js';
|
||||
import MemberType from './MemberType.js';
|
||||
|
||||
export default class FunctionTemplate extends MemberTemplate {
|
||||
compose() {
|
||||
var name = super.compose();
|
||||
compose() {
|
||||
var name = super.compose();
|
||||
|
||||
var bl = BL()
|
||||
.addUint8(name.length)
|
||||
.addUint8Array(name)
|
||||
.addUint8Array(this.returnType.compose())
|
||||
.addUint8(this.arguments.length);
|
||||
var bl = new BL()
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(this.returnType.compose())
|
||||
.addUint8(this.args.length);
|
||||
|
||||
for (var i = 0; i < this.arguments.length; i++)
|
||||
bl.addUint8Array(this.arguments[i].compose());
|
||||
for (var i = 0; i < this.args.length; i++) bl.addDC(this.args[i].compose());
|
||||
|
||||
if (this.expansion != null)
|
||||
{
|
||||
var exp = DC.stringToBytes(this.expansion);
|
||||
bl.addInt32(exp.length)
|
||||
.addUint8Array(exp);
|
||||
bl.insertUint8(0, 0x10);
|
||||
}
|
||||
else
|
||||
bl.addUint8(0x0, 0);
|
||||
|
||||
return bl.toArray();
|
||||
}
|
||||
if (this.expansion != null) {
|
||||
var exp = DC.stringToBytes(this.expansion);
|
||||
bl
|
||||
.addInt32(exp.length)
|
||||
.addDC(exp);
|
||||
bl.insertUint8(0, this.inherited ? 0x90 : 0x10);
|
||||
} else
|
||||
bl.insertUint8(0, this.inherited ? 0x80 : 0x0);
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.type = MemberType.Function;
|
||||
}
|
||||
return bl.toDC();
|
||||
}
|
||||
|
||||
constructor(template, index, name, inherited, args, returnType, expansion = null){
|
||||
super(template, index, name, inherited);
|
||||
|
||||
this.args = args;
|
||||
this.returnType = returnType;
|
||||
this.expansion = expansion;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,10 +26,21 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
import DC from '../../Data/DataConverter.js';
|
||||
import DC from '../../Data/DC.js';
|
||||
|
||||
|
||||
export default class MemberTemplate {
|
||||
compose() {
|
||||
return DC.stringToBytes(this.name);
|
||||
}
|
||||
}
|
||||
|
||||
constructor(template, index, name, inherited) {
|
||||
this.template = template;
|
||||
this.index = index;
|
||||
this.name = name;
|
||||
this.inherited = inherited;
|
||||
}
|
||||
|
||||
get fullname() {return this.template.className + "." + this.name;}
|
||||
|
||||
compose() {
|
||||
return DC.stringToBytes(this.name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
* Copyright (c) 2017-2022 Ahmed Kh. Zamil
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -24,74 +24,66 @@
|
||||
* Created by Ahmed Zamil on 27/08/2017.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
import {DC, BL} from '../../Data/DataConverter.js';
|
||||
import {DC, BL} from '../../Data/DC.js';
|
||||
import MemberTemplate from './MemberTemplate.js';
|
||||
import MemberType from './MemberType.js';
|
||||
|
||||
export const PropertyPermission = {
|
||||
Read: 1,
|
||||
Write: 2,
|
||||
ReadWrite: 3
|
||||
};
|
||||
export default class PropertyTemplate extends MemberTemplate {
|
||||
|
||||
export default class PropertyTemplate extends MemberTemplate
|
||||
{
|
||||
compose() {
|
||||
var name = super.compose();
|
||||
var pv = (this.permission << 1) | (this.recordable ? 1 : 0);
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
this.type = MemberType.Property;
|
||||
}
|
||||
if (this.inherited) pv |= 0x80;
|
||||
|
||||
compose()
|
||||
{
|
||||
var name = super.compose();
|
||||
var rt = BL();
|
||||
var pv = (this.permission << 1) | (this.recordable ? 1 : 0);
|
||||
if (this.writeExpansion != null && this.readExpansion != null) {
|
||||
let rexp = DC.stringToBytes(this.readExpansion);
|
||||
let wexp = DC.stringToBytes(this.writeExpansion);
|
||||
return (BL()
|
||||
.addUint8(0x38 | pv)
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(this.valueType.compose())
|
||||
.addInt32(wexp.length)
|
||||
.addDC(wexp)
|
||||
.addInt32(rexp.length)
|
||||
.addDC(rexp))
|
||||
.toDC();
|
||||
} else if (this.writeExpansion != null) {
|
||||
let wexp = DC.stringToBytes(this.writeExpansion);
|
||||
return (BL()
|
||||
.addUint8(0x30 | pv)
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(this.valueType.compose())
|
||||
.addInt32(wexp.length)
|
||||
.addDC(wexp))
|
||||
.toDC();
|
||||
} else if (this.readExpansion != null) {
|
||||
let rexp = DC.stringToBytes(this.readExpansion);
|
||||
return (BL()
|
||||
.addUint8(0x28 | pv)
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(this.valueType.compose())
|
||||
.addInt32(rexp.length)
|
||||
.addDC(rexp))
|
||||
.toDC();
|
||||
} else
|
||||
return (BL()
|
||||
.addUint8(0x20 | pv)
|
||||
.addUint8(name.length)
|
||||
.addDC(name)
|
||||
.addDC(this.valueType.compose()))
|
||||
.toDC();
|
||||
}
|
||||
|
||||
if (this.writeExpansion != null && this.readExpansion != null)
|
||||
{
|
||||
var rexp = DC.stringToBytes(this.readExpansion);
|
||||
var wexp = DC.stringToBytes(this.writeExpansion);
|
||||
return rt.addUint8(0x38 | pv)
|
||||
.addUint8(name.length)
|
||||
.addUint8Array(name)
|
||||
.addUint8Array(this.valueType.compose())
|
||||
.addUint32(wexp.length)
|
||||
.addUint8Array(wexp)
|
||||
.addUint32(rexp.length)
|
||||
.addUint8Array(rexp)
|
||||
.toArray();
|
||||
}
|
||||
else if (this.writeExpansion != null)
|
||||
{
|
||||
var wexp = DC.stringToBytes(this.writeExpansion);
|
||||
return rt.addUint8(0x30 | pv)
|
||||
.addUint8(name.length)
|
||||
.addUint8Array(name)
|
||||
.addUint8Array(this.valueType.compose())
|
||||
.addUint32(wexp.length)
|
||||
.addUint8Array(wexp)
|
||||
.toArray();
|
||||
}
|
||||
else if (this.readExpansion != null)
|
||||
{
|
||||
var rexp = DC.stringToBytes(this.readExpansion);
|
||||
return rt.addUint8(0x28 | pv)
|
||||
.addUint8(name.length)
|
||||
.addUint8Array(name)
|
||||
.addUint8Array(this.valueType.compose())
|
||||
.addUint32(rexp.length)
|
||||
.addUint8Array(rexp)
|
||||
.toArray();
|
||||
}
|
||||
else
|
||||
return rt.addUint8(0x20 | pv)
|
||||
.addUint8(name.length)
|
||||
.addUint8Array(name)
|
||||
.addUint8Array(this.valueType.compose())
|
||||
.toArray();
|
||||
}
|
||||
constructor(template, index, name,
|
||||
inherited, valueType, readExpansion = null, writeExpansion = null, recordable = false)
|
||||
{
|
||||
super(template, index, name, inherited);
|
||||
this.valueType = valueType;
|
||||
this.readExpansion = readExpansion;
|
||||
this.writeExpansion = writeExpansion;
|
||||
this.recordable = recordable;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
import {DC, BL} from '../../Data/DataConverter.js';
|
||||
import {DC, BL} from '../../Data/DC.js';
|
||||
import DataType from "../../Data/DataType.js";
|
||||
import Structure from '../../Data/Structure.js';
|
||||
import IResource from '../IResource.js';
|
||||
|
||||
@@ -4,4 +4,5 @@ export default
|
||||
Resource: 1,
|
||||
Record: 2,
|
||||
Wrapper: 3,
|
||||
Enum: 4
|
||||
}
|
||||
@@ -26,15 +26,20 @@ import FunctionTemplate from './FunctionTemplate.js';
|
||||
import PropertyTemplate from './PropertyTemplate.js';
|
||||
import EventTemplate from './EventTemplate.js';
|
||||
import SHA256 from '../../Security/Integrity/SHA256.js';
|
||||
import {DC, BL} from '../../Data/DataConverter.js';
|
||||
import {DC, BL} from '../../Data/DC.js';
|
||||
import ArgumentTemplate from './ArgumentTemplate.js';
|
||||
import TemplateDataType from "./TemplateDataType.js";
|
||||
import IResource from '../IResource.js';
|
||||
import IRecord from '../../Data/IRecord.js';
|
||||
import TemplateType from './TemplateType.js'
|
||||
import Warehouse from '../Warehouse.js';
|
||||
import DistributedConnection from '../../Net/IIP/DistributedConnection.js';
|
||||
|
||||
import ConstantTemplate from './ConstantTemplate.js';
|
||||
import IEnum from '../../Data/IEnum.js';
|
||||
import DistributedResource from '../../Net/IIP/DistributedResource.js';
|
||||
import RepresentationType from '../../Data/RepresentationType.js';
|
||||
import Codec from '../../Data/Codec.js';
|
||||
|
||||
export default class TypeTemplate {
|
||||
|
||||
getEventTemplateByName(eventName) {
|
||||
@@ -79,6 +84,20 @@ export default class TypeTemplate {
|
||||
return null;
|
||||
}
|
||||
|
||||
getConstantTemplateByName(constantName) {
|
||||
for (var i = 0; i < this.constants.length; i++)
|
||||
if (this.constants[i].name == constantName)
|
||||
return this.constants[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
getConstantTemplateByIndex(index) {
|
||||
for (var i = 0; i < this.constants.length; i++)
|
||||
if (this.constants[i].index == index)
|
||||
return this.constants[i];
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -217,16 +236,22 @@ export default class TypeTemplate {
|
||||
this.events = [];
|
||||
this.functions = [];
|
||||
this.members = [];
|
||||
this.constants = [];
|
||||
|
||||
|
||||
if (type === undefined)
|
||||
return;
|
||||
|
||||
|
||||
if (type.prototype instanceof DistributedResource)
|
||||
this.templateType = TemplateType.Wrapper;
|
||||
if (type.prototype instanceof IRecord)
|
||||
this.templateType = TemplateType.Record;
|
||||
else if (type.prototype instanceof IResource)
|
||||
this.templateType = TemplateType.Resource;
|
||||
else if (type.prototype instanceof IEnum)
|
||||
this.templateType = TemplateType.Enum;
|
||||
else
|
||||
throw new Error("Type is neither a resource nor a record.");
|
||||
throw new Error("Type must implement IResource, IRecord, IEnum or a subtype of DistributedResource.");
|
||||
|
||||
this.definedType = type;
|
||||
|
||||
@@ -244,35 +269,38 @@ export default class TypeTemplate {
|
||||
//byte currentIndex = 0;
|
||||
|
||||
if (template.properties != null)
|
||||
for (var i = 0; i < template.properties.length; i++) {
|
||||
for (let i = 0; i < template.properties.length; i++) {
|
||||
//[name, type, {read: comment, write: comment, recordable: }]
|
||||
var pi = template.properties[i];
|
||||
var pt = new PropertyTemplate();
|
||||
pt.name = pi[0];
|
||||
pt.index = i;
|
||||
pt.valueType = TemplateDataType.fromType(pi[1]);
|
||||
pt.readExpansion = pi[2]?.read;
|
||||
pt.writeExpansion = pi[2]?.write;
|
||||
pt.recordable = pi[2]?.recordable;
|
||||
let pi = template.properties[i];
|
||||
let pt = new PropertyTemplate(this, i, pi[0], false,
|
||||
RepresentationType.fromType(pi[1]) ?? RepresentationType.Void,
|
||||
pi[2]?.read, pi[2]?.write, pi[2]?.recordable);
|
||||
pt.propertyInfo = pi;
|
||||
this.properties.push(pt);
|
||||
}
|
||||
|
||||
|
||||
if (template.constants != null)
|
||||
for (let i = 0; i < template.constants.length; i++) {
|
||||
let ci = template.constants[i];
|
||||
let ct = new ConstantTemplate(this, i, ci[0], false,
|
||||
RepresentationType.fromType(ci[1]) ?? RepresentationType.Void,
|
||||
ci.value, ci.help);
|
||||
ct.propertyInfo = ci;
|
||||
this.constants.push(ct);
|
||||
}
|
||||
|
||||
if (this.templateType == TemplateType.Resource)
|
||||
{
|
||||
|
||||
if (template.events != null)
|
||||
{
|
||||
for (let i = 0; i < template.events.length; i++) {
|
||||
|
||||
// [name, type, {listenable: true/false, help: ""}]
|
||||
var ei = template.events[i];
|
||||
var et = new EventTemplate();
|
||||
et.name = ei[0];
|
||||
et.index = i;
|
||||
et.argumentType = TemplateDataType.fromType(ei[1]),
|
||||
et.expansion = ei[2]?.help;
|
||||
et.listenable = ei[2]?.listenable;
|
||||
var et = new EventTemplate(this, i, ei[0], false,
|
||||
RepresentationType.fromType(ei[1]) ?? RepresentationType.Void,
|
||||
ei[2]?.help, ei[2]?.listenable)
|
||||
et.eventInfo = ei;
|
||||
this.events.push(et);
|
||||
}
|
||||
@@ -284,16 +312,15 @@ export default class TypeTemplate {
|
||||
|
||||
var fi = template.functions[i];
|
||||
|
||||
// [name, {param1: type, param2: int}, returnType, "Description"]
|
||||
var ft = new FunctionTemplate();
|
||||
ft.name = fi[0];
|
||||
ft.index = i;
|
||||
ft.returnType = TemplateDataType.fromType(fi[2]);
|
||||
ft.expansion = fi[3];
|
||||
ft.arguments = [];
|
||||
let args = [];
|
||||
for(let ai = 0; ai < fi[1].length; ai++)
|
||||
args.push(new ArgumentTemplate(fi[1][ai][0], RepresentationType.fromType(fi[1][ai][1])
|
||||
?? RepresentationType.Dynamic, fi[1][ai][2]?.optional, ai));
|
||||
|
||||
for(var arg in fi[1])
|
||||
ft.arguments.push(new ArgumentTemplate(arg, TemplateDataType.fromType(fi[1][arg])))
|
||||
// [name, {param1: type, param2: int}, returnType, "Description"]
|
||||
var ft = new FunctionTemplate(this, i, fi[0], false, args,
|
||||
RepresentationType.fromType(fi[2]) ?? RepresentationType.Void,
|
||||
fi[3]);
|
||||
|
||||
ft.methodInfo = fi;
|
||||
|
||||
@@ -312,6 +339,9 @@ export default class TypeTemplate {
|
||||
// append properties
|
||||
for (let i = 0; i < this.properties.length; i++)
|
||||
this.members.push(this.properties[i]);
|
||||
// append constants
|
||||
for (let i = 0; i < this.constants.length; i++)
|
||||
this.members.push(this.constants[i]);
|
||||
|
||||
// bake it binarily
|
||||
var b = BL();
|
||||
@@ -369,41 +399,52 @@ export default class TypeTemplate {
|
||||
var od = new TypeTemplate();
|
||||
od.content = data.clip(offset, contentLength);
|
||||
|
||||
od.templateType = data.getUint8(offset++);
|
||||
let hasParent = (data.getUint8(offset) & 0x80) > 0;
|
||||
|
||||
od.templateType = data.getUint8(offset++) & 0xF;
|
||||
|
||||
|
||||
od.classId = data.getGuid(offset);
|
||||
offset += 16;
|
||||
od.className = data.getString(offset + 1, data.getUint8(offset));
|
||||
offset += data.getUint8(offset) + 1;
|
||||
|
||||
if (hasParent) {
|
||||
od.parentId = data.getGuid(offset);
|
||||
offset += 16;
|
||||
}
|
||||
|
||||
od.version = data.getInt32(offset);
|
||||
offset += 4;
|
||||
|
||||
var methodsCount = data.getUint16(offset);
|
||||
let methodsCount = data.getUint16(offset);
|
||||
offset += 2;
|
||||
|
||||
var functionIndex = 0;
|
||||
var propertyIndex = 0;
|
||||
var eventIndex = 0;
|
||||
let functionIndex = 0;
|
||||
let propertyIndex = 0;
|
||||
let eventIndex = 0;
|
||||
let constantIndex = 0;
|
||||
|
||||
for (var i = 0; i < methodsCount; i++) {
|
||||
var type = data.getUint8(offset) >> 5;
|
||||
for (let i = 0; i < methodsCount; i++) {
|
||||
|
||||
let inherited = (data.getUint8(offset) & 0x80) > 0;
|
||||
let type = (data.getUint8(offset) >> 5) & 0x3;
|
||||
|
||||
if (type == 0) // function
|
||||
{
|
||||
let ft = new FunctionTemplate();
|
||||
ft.index = functionIndex++;
|
||||
let expansion = null;
|
||||
let hasExpansion = ((data.getUint8(offset++) & 0x10) == 0x10);
|
||||
|
||||
let len = data.getUint8(offset++);
|
||||
ft.name = data.getString(offset, len);
|
||||
let name = data.getString(offset, len);
|
||||
offset += len;
|
||||
|
||||
// return type
|
||||
let {size, value: returnType} = TemplateDataType.parse(data, offset);
|
||||
offset += size;
|
||||
let dt = RepresentationType.parse(data, offset);
|
||||
|
||||
ft.returnType = returnType;
|
||||
offset += dt.size;
|
||||
|
||||
//ft.returnType = returnType;
|
||||
|
||||
// arguments count
|
||||
var argsCount = data.getUint8(offset++);
|
||||
@@ -411,47 +452,45 @@ export default class TypeTemplate {
|
||||
|
||||
for (var a = 0; a < argsCount; a++)
|
||||
{
|
||||
let {size: argSize, value: argType} = ArgumentTemplate.parse(data, offset);
|
||||
let {size: argSize, value: argType} = ArgumentTemplate.parse(data, offset, a);
|
||||
args.push(argType);
|
||||
offset += argSize;
|
||||
}
|
||||
|
||||
ft.arguments = args;
|
||||
|
||||
if (hasExpansion) // expansion ?
|
||||
{
|
||||
var cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
ft.expansion = data.getString(offset, cs);
|
||||
expansion = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
let ft = new FunctionTemplate(od, functionIndex++, name, inherited,
|
||||
args, dt.type, expansion);
|
||||
|
||||
od.functions.push(ft);
|
||||
}
|
||||
else if (type == 1) // property
|
||||
{
|
||||
|
||||
let pt = new PropertyTemplate();
|
||||
pt.index = propertyIndex++;
|
||||
let hasReadExpansion = ((data.getUint8(offset) & 0x8) == 0x8);
|
||||
let hasWriteExpansion = ((data.getUint8(offset) & 0x10) == 0x10);
|
||||
pt.recordable = ((data.getUint8(offset) & 1) == 1);
|
||||
pt.permission = ((data.getUint8(offset++) >> 1) & 0x3);
|
||||
let readExpansion, writeExpansion;
|
||||
let recordable = ((data.getUint8(offset) & 1) == 1);
|
||||
let permission = ((data.getUint8(offset++) >> 1) & 0x3);
|
||||
let len = data.getUint8(offset++);
|
||||
pt.name = data.getString(offset, len);
|
||||
let name = data.getString(offset, len);
|
||||
offset += len;
|
||||
|
||||
let {size, value: valueType} = TemplateDataType.parse(data, offset);
|
||||
var dt = RepresentationType.parse(data, offset);
|
||||
|
||||
offset += size;
|
||||
|
||||
pt.valueType = valueType;
|
||||
offset += dt.size;
|
||||
|
||||
if (hasReadExpansion) // expansion ?
|
||||
{
|
||||
let cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
pt.readExpansion = data.getString(offset, cs);
|
||||
readExpansion = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
@@ -459,39 +498,70 @@ export default class TypeTemplate {
|
||||
{
|
||||
let cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
pt.writeExpansion = data.getString(offset, cs);
|
||||
writeExpansion = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
let pt = new PropertyTemplate(od, propertyIndex++, name, inherited, dt.type, readExpansion, writeExpansion, recordable);
|
||||
|
||||
od.properties.push(pt);
|
||||
}
|
||||
else if (type == 2) // Event
|
||||
{
|
||||
let et = new EventTemplate();
|
||||
et.index = eventIndex++;
|
||||
let hasExpansion = ((data.getUint8(offset) & 0x10) == 0x10);
|
||||
et.listenable = ((data.getUint8(offset++) & 0x8) == 0x8);
|
||||
let listenable = ((data.getUint8(offset++) & 0x8) == 0x8);
|
||||
let len = data.getUint8(offset++);
|
||||
et.name = data.getString(offset, len);
|
||||
let name = data.getString(offset, len);
|
||||
let expansion;
|
||||
|
||||
offset += len;
|
||||
|
||||
let {size, value: argType} = TemplateDataType.parse(data, offset);
|
||||
let dt = RepresentationType.parse(data, offset);
|
||||
|
||||
offset += size;
|
||||
et.argumentType = argType;
|
||||
offset += dt.size;
|
||||
|
||||
|
||||
if (hasExpansion) // expansion ?
|
||||
{
|
||||
let cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
et.expansion = data.getString(offset, cs);
|
||||
expansion = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
let et = new EventTemplate(od, eventIndex++, name, inherited, dt.type, expansion, listenable);
|
||||
od.events.push(et);
|
||||
|
||||
}
|
||||
else if (type == 3) // constant
|
||||
{
|
||||
let expansion = null;
|
||||
let hasExpansion = ((data[offset++] & 0x10) == 0x10);
|
||||
|
||||
let name = data.getString(offset + 1, data[offset]);
|
||||
offset += data[offset] + 1;
|
||||
|
||||
let dt = RepresentationType.parse(data, offset);
|
||||
|
||||
offset += dt.size;
|
||||
|
||||
let parsed = Codec.parse(data, offset, null);
|
||||
|
||||
offset += parsed.size;
|
||||
|
||||
if (hasExpansion) // expansion ?
|
||||
{
|
||||
let cs = data.getUint32(offset);
|
||||
offset += 4;
|
||||
expansion = data.getString(offset, cs);
|
||||
offset += cs;
|
||||
}
|
||||
|
||||
let ct = new ConstantTemplate(this, constantIndex++, name, inherited,
|
||||
dt.type, parsed.reply.result, expansion);
|
||||
|
||||
od.constants.push(ct);
|
||||
}
|
||||
}
|
||||
|
||||
// append signals
|
||||
@@ -503,6 +573,9 @@ export default class TypeTemplate {
|
||||
// append properties
|
||||
for (let i = 0; i < od.properties.length; i++)
|
||||
od.members.push(od.properties[i]);
|
||||
// append constants
|
||||
for (let i = 0; i < od.constants.length; i++)
|
||||
od.members.push(od.constants[i]);
|
||||
|
||||
|
||||
return od;
|
||||
|
||||
@@ -42,7 +42,12 @@ import AsyncBag from '../Core/AsyncBag.js';
|
||||
import IRecord from '../Data/IRecord.js';
|
||||
import TemplateType from './Template/TemplateType.js';
|
||||
import DistributedResource from '../Net/IIP/DistributedResource.js';
|
||||
|
||||
import TypedList from '../Data/TypedList.js';
|
||||
import { Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32, UInt64, Float32, Float64 } from '../Data/ExtendedTypes.js';
|
||||
import Record from '../Data/Record.js';
|
||||
import TypedMap from '../Data/TypedMap.js';
|
||||
import {RepresentationType, RepresentationTypeIdentifier} from '../Data/RepresentationType.js';
|
||||
import FactoryEntry from './FactoryEntry.js'; './FactoryEntry.js';
|
||||
export class WH extends IEventHandler
|
||||
{
|
||||
constructor()
|
||||
@@ -58,8 +63,12 @@ export class WH extends IEventHandler
|
||||
this.templates.add(TemplateType.Resource, new KeyList());
|
||||
this.templates.add(TemplateType.Record, new KeyList());
|
||||
this.templates.add(TemplateType.Wrapper, new KeyList());
|
||||
this.templates.add(TemplateType.Enum, new KeyList());
|
||||
|
||||
this.protocols = new KeyList();
|
||||
|
||||
this.typesFactory = this._getBuiltInTypes();
|
||||
|
||||
this._register("connected");
|
||||
this._register("disconnected");
|
||||
///this._urlRegex = /^(?:([\S]*):\/\/([^\/]*)\/?)/;
|
||||
@@ -529,6 +538,91 @@ export class WH extends IEventHandler
|
||||
return rt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Function} instanceCreator - creator
|
||||
* @param {RepresentationType} representationType - type
|
||||
*/
|
||||
_getTypeEntries(type, representationType) {
|
||||
|
||||
let listType = TypedList.of(type);
|
||||
|
||||
|
||||
var entry = new FactoryEntry(type, representationType);
|
||||
let nullableEntry = new FactoryEntry(entry.nullableType, representationType.toNullable());
|
||||
let listEntry = new FactoryEntry(listType,
|
||||
new RepresentationType(RepresentationTypeIdentifier.TypedList, false,
|
||||
null, [representationType]));
|
||||
let nullableList = new FactoryEntry(listEntry.nullableType,
|
||||
new RepresentationType(RepresentationTypeIdentifier.TypedList, true, null,
|
||||
[representationType]));
|
||||
|
||||
let nullableItemListType = TypedList.of(entry.nullableType);
|
||||
let listNullableItemEntry = new FactoryEntry(nullableItemListType,
|
||||
new RepresentationType(RepresentationTypeIdentifier.TypedList, false,
|
||||
null, [representationType.toNullable()]));
|
||||
|
||||
let nullableListNullableItemEntry = new FactoryEntry(nullableItemListType,
|
||||
new RepresentationType(RepresentationTypeIdentifier.TypedList, true, null,
|
||||
[representationType.toNullable()]));
|
||||
|
||||
return [
|
||||
entry, nullableEntry, listEntry, nullableList, listNullableItemEntry, nullableListNullableItemEntry
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {Function} instanceCreator - creator
|
||||
* @param {RepresentationType} representationType - type
|
||||
*/
|
||||
defineType(type, representationType) {
|
||||
var entries = this._getTypeEntries(type, representationType);
|
||||
|
||||
for(var e of entries)
|
||||
this.typesFactory[e.type] = e; //.push(e);
|
||||
}
|
||||
|
||||
_getBuiltInTypes() {
|
||||
|
||||
let entries = [
|
||||
...this._getTypeEntries(Int8, new RepresentationType(RepresentationTypeIdentifier.Int8, false)),
|
||||
...this._getTypeEntries(UInt8, new RepresentationType(RepresentationTypeIdentifier.UInt8, false)),
|
||||
...this._getTypeEntries(Int16, new RepresentationType(RepresentationTypeIdentifier.Int16, false)),
|
||||
...this._getTypeEntries(UInt16, new RepresentationType(RepresentationTypeIdentifier.UInt16, false)),
|
||||
...this._getTypeEntries(Int32, new RepresentationType(RepresentationTypeIdentifier.Int32, false)),
|
||||
...this._getTypeEntries(UInt32, new RepresentationType(RepresentationTypeIdentifier.UInt32, false)),
|
||||
...this._getTypeEntries(Int64, new RepresentationType(RepresentationTypeIdentifier.Int64, false)),
|
||||
...this._getTypeEntries(UInt64, new RepresentationType(RepresentationTypeIdentifier.UInt64, false)),
|
||||
...this._getTypeEntries(Float32, new RepresentationType(RepresentationTypeIdentifier.Float32, false)),
|
||||
...this._getTypeEntries(Float64, new RepresentationType(RepresentationTypeIdentifier.Float64, false)),
|
||||
...this._getTypeEntries(String, new RepresentationType(RepresentationTypeIdentifier.Int8, String)),
|
||||
...this._getTypeEntries(Date, new RepresentationType(RepresentationTypeIdentifier.Int8, Date)),
|
||||
...this._getTypeEntries(Record, new RepresentationType(RepresentationTypeIdentifier.Record, false)),
|
||||
...this._getTypeEntries(IResource, new RepresentationType(RepresentationTypeIdentifier.Resource, false)),
|
||||
...this._getTypeEntries(Array, new RepresentationType(RepresentationTypeIdentifier.List, false)),
|
||||
...this._getTypeEntries(Map, new RepresentationType(RepresentationTypeIdentifier.Map, false)),
|
||||
//...this._getTypeEntries(IResource, new RepresentationType(RepresentationTypeIdentifier.Resource, false)),
|
||||
//...this._getTypeEntries(TypedMap, new RepresentationType(RepresentationTypeIdentifier.Resource, false)),
|
||||
|
||||
...this._getTypeEntries(TypedMap.of(String, Object), new RepresentationType(RepresentationTypeIdentifier.TypedMap, false, null, [
|
||||
new RepresentationType(RepresentationTypeIdentifier.String, false),
|
||||
RepresentationType.Dynamic])),
|
||||
|
||||
...this._getTypeEntries(TypedMap.of(UInt8, Object), new RepresentationType(RepresentationTypeIdentifier.TypedMap, false, null, [
|
||||
new RepresentationType(RepresentationTypeIdentifier.UInt8, false),
|
||||
RepresentationType.Dynamic])),
|
||||
|
||||
...this._getTypeEntries(TypedMap.of(Int32, Object), new RepresentationType(RepresentationTypeIdentifier.TypedMap, false, null, [
|
||||
new RepresentationType(RepresentationTypeIdentifier.Int32, false),
|
||||
RepresentationType.Dynamic])),
|
||||
|
||||
];
|
||||
|
||||
let rt = {};
|
||||
for(let entry of entries)
|
||||
rt[entry.type] = entry;
|
||||
return rt;
|
||||
}
|
||||
}
|
||||
|
||||
let Warehouse = new WH();
|
||||
|
||||
Reference in New Issue
Block a user