From ac718ef1f0b7a09b1f349ccb629c47502b3f9087 Mon Sep 17 00:00:00 2001 From: Universal Web Date: Tue, 26 Sep 2023 01:58:50 -0400 Subject: [PATCH] Merge in progress don't run New Request Object Class New Response Object Class Seperation of Data & Logic Base Classes --- udsp/index.js | 4 +- udsp/request/ask.js | 29 ++-- udsp/request/base.js | 115 +++--------- udsp/request/client/clientResponse.js | 164 ------------------ udsp/request/object.js | 164 ------------------ .../{requestObject.js => objects/base.js} | 73 ++++---- udsp/request/objects/client/request.js | 26 +++ udsp/request/objects/client/response.js | 19 ++ udsp/request/objects/dataMethods.js | 117 +++++++++++++ udsp/request/objects/objectGetSetMethods.js | 43 +++++ udsp/request/objects/server/request.js | 26 +++ udsp/request/objects/server/response.js | 17 ++ udsp/request/reply.js | 7 +- udsp/requestMethods/fetch.js | 2 +- 14 files changed, 333 insertions(+), 473 deletions(-) delete mode 100644 udsp/request/client/clientResponse.js delete mode 100644 udsp/request/object.js rename udsp/request/{requestObject.js => objects/base.js} (51%) create mode 100644 udsp/request/objects/client/request.js create mode 100644 udsp/request/objects/client/response.js create mode 100644 udsp/request/objects/dataMethods.js create mode 100644 udsp/request/objects/objectGetSetMethods.js create mode 100644 udsp/request/objects/server/request.js create mode 100644 udsp/request/objects/server/response.js diff --git a/udsp/index.js b/udsp/index.js index 5f2ddcf7..7c5eb7b8 100644 --- a/udsp/index.js +++ b/udsp/index.js @@ -1,4 +1,4 @@ export * from './client/index.js'; export * from './server/index.js'; -export * from './request/requestObject.js'; -export * from './request/client/clientResponse.js'; +export * from './request/objects/client/request'; +export * from './request/objects/client/response.js'; diff --git a/udsp/request/ask.js b/udsp/request/ask.js index 9af9e5f8..d4457d16 100644 --- a/udsp/request/ask.js +++ b/udsp/request/ask.js @@ -10,7 +10,9 @@ import { failed, info, msgReceived, msgSent } from '#logs'; import { Base } from './base.js'; -import { clientResponse } from './client/clientResponse.js'; +import { clientResponse } from './objects/client/response.js'; +import { objectGetSetMethods } from './objects/objectGetSetMethods.js'; +import { ClientRequest } from './objects/client/request.js'; export class Ask extends Base { constructor(method = 'get', path, parameters, data, head, options = {}, source) { super(options, source); @@ -25,20 +27,14 @@ export class Ask extends Base { this.request.method = methodSanitized; this.method = methodSanitized; this.id = streamId; - if (path) { - this.request.path = path; - this.path = path; - } - if (parameters) { - this.request.parameters = parameters; - this.parameters = parameters; - } - if (data) { - this.request.data = data; - } - if (head) { - this.request.head = head; - } + this.request = new ClientRequest(path, { + method, + parameters, + data, + head, + source: this + }); + this.response = clientResponse(this); requestQueue.set(streamId, this); } completeReceived() { @@ -48,8 +44,7 @@ export class Ask extends Base { } this.readyState = 4; this.flush(); - const response = clientResponse(this); - this.accept(response); + this.accept(this.response); } isAsk = true; type = 'ask'; diff --git a/udsp/request/base.js b/udsp/request/base.js index f9293cec..a2f89b5f 100644 --- a/udsp/request/base.js +++ b/udsp/request/base.js @@ -4,8 +4,14 @@ import { on } from './on.js'; import { flushOutgoing, flushIncoming, flush } from './flush.js'; import { onPacket } from './onPacket.js'; import { - isBuffer, isPlainObject, isString, promise, assign, - objectSize, eachArray, jsonParse, construct, isArray, clear, isFalse, isTrue, clearBuffer, hasValue + isBuffer, + isPlainObject, + isString, + promise, + assign, + objectSize, eachArray, jsonParse, + construct, isArray, clear, isFalse, + isTrue, clearBuffer, hasValue } from '@universalweb/acid'; import { encode, decode } from 'msgpackr'; import { toBase64 } from '#crypto'; @@ -91,6 +97,11 @@ export class Base { } else { this.head = {}; } + if (this.isAsk) { + this.response.head = this.head; + } else { + this.request.head = this.head; + } this.readyState = 2; this.headAssembled = true; } @@ -105,6 +116,11 @@ export class Base { } else { this.parameters = null; } + if (this.isAsk) { + this.response.parameters = this.parameters; + } else { + this.request.parameters = this.parameters; + } this.readyState = 2; this.parametersAssembled = true; } @@ -119,6 +135,11 @@ export class Base { } else { this.path = ''; } + if (this.isAsk) { + this.response.path = this.path; + } else { + this.request.path = this.path; + } this.readyState = 2; this.pathAssembled = true; } @@ -213,29 +234,12 @@ export class Base { console.log('Missing packets: ', missingDataPackets); } else if (this.head.dataSize === this.currentIncomingDataSize) { this.completeReceived(); - } - } - get data() { - if (this.compiledDataAlready) { - return this.compiledData; - } - this.incomingDataPackets = null; - const { head: { serialize } } = this; - const dataConcatinated = Buffer.concat(this.incomingData); - this.incomingData.fill(0); - this.incomingData = null; - if (serialize) { - if (isTrue(serialize)) { - this.compiledData = decode(dataConcatinated); - } else if (serialize === 1) { - this.compiledData = jsonParse(dataConcatinated); + if (this.isAsk) { + this.response.dataBuffer = this.incomingData; + } else { + this.request.dataBuffer = this.incomingData; } - dataConcatinated.fill(0); - } else { - this.compiledData = dataConcatinated; } - this.compiledDataAlready = true; - return this.compiledData; } sendSetup() { const { isAsk } = this; @@ -512,70 +516,6 @@ export class Base { }; return message; } - toString(cache) { - if (cache) { - if (this.toStringCached) { - return this.toStringCached; - } - } - const target = this.data.toString(); - if (cache) { - this.toStringCached = target; - } - return target; - } - toJSON(cache) { - if (cache) { - if (this.toJSONCached) { - return this.toJSONCached; - } - } - const target = jsonParse(this.data); - if (cache) { - this.toJSONCached = target; - } - return jsonParse(this.data); - } - serialize(cache) { - if (cache) { - if (this.serializeCached) { - return this.serializeCached; - } - } - const target = decode(this.data); - if (cache) { - this.serializeCached = target; - } - return target; - } - toObject(cache) { - if (cache) { - if (this.toObjectRawCached) { - return this.toObjectRawCached; - } - } - const { - head, - data, - id, - method, - } = this; - const target = { - head, - data, - method - }; - if (cache) { - this.toObjectRawCached = target; - } - return target; - } - get headers() { - return this.head; - } - get body() { - return this.data; - } destroy = destroy; onPacket = onPacket; sendPacket(message, headers, footer) { @@ -646,5 +586,4 @@ export class Base { outgoingParametersSize = 0; outgoingHeadSize = 0; outgoingDataSize = 0; - bg = 0; } diff --git a/udsp/request/client/clientResponse.js b/udsp/request/client/clientResponse.js deleted file mode 100644 index 20246b5f..00000000 --- a/udsp/request/client/clientResponse.js +++ /dev/null @@ -1,164 +0,0 @@ -import { - jsonParse, isTrue, construct, hasValue, noValue -} from '@universalweb/acid'; -import { decode } from 'msgpackr'; -export class ClientResponse { - constructor(source, options) { - if (source.isAsk) { - const { - head, - method, - parameters, - path, - incomingData, - status, - type, - } = source; - return this.construct(incomingData, { - head, - method, - parameters, - path, - status, - type, - }); - } else { - return this.construct(source, options); - } - } - construct(data, options = {}) { - const { - head, - headers, - params, - parameters = params, - method, - status, - type, - url, - path = url - } = options; - this.head = head || {}; - if (hasValue(data)) { - this.dataBuffer = data; - } - this.method = method; - if (hasValue(status)) { - this.status = status; - } - if (hasValue(path)) { - this.path = path; - } - if (hasValue(type)) { - this.type = type; - } - if (hasValue(parameters)) { - this.parameters = parameters; - } - } - get data() { - if (this.compiledDataAlready) { - return this.compiledData; - } - if (noValue(this.dataBuffer)) { - return undefined; - } - const { head: { serialize } } = this; - const dataConcatinated = Buffer.concat(this.dataBuffer); - if (serialize) { - if (isTrue(serialize) || serialize === 0) { - this.compiledData = decode(dataConcatinated); - } else if (serialize === 1 || serialize === 'json') { - this.compiledData = jsonParse(dataConcatinated); - } - dataConcatinated.fill(0); - } else { - this.compiledData = dataConcatinated; - } - this.compiledDataAlready = true; - return this.compiledData; - } - get headers() { - return this.head; - } - get body() { - return this.data; - } - get url() { - return this.path; - } - toString(cache) { - if (cache) { - if (this.toStringCached) { - return this.toStringCached; - } - } - if (noValue(this.dataBuffer)) { - return; - } - const target = this.data.toString(); - if (cache) { - this.toStringCached = target; - } - return target; - } - toJSON(cache) { - if (cache) { - if (this.toJSONCached) { - return this.toJSONCached; - } - } - if (noValue(this.dataBuffer)) { - return; - } - const target = jsonParse(this.data); - if (cache) { - this.toJSONCached = target; - } - return jsonParse(this.data); - } - serialize(cache) { - if (cache) { - if (this.serializeCached) { - return this.serializeCached; - } - } - if (noValue(this.dataBuffer)) { - return; - } - const target = decode(this.data); - if (cache) { - this.serializeCached = target; - } - return target; - } - toObject(cache) { - if (cache) { - if (this.toObjectRawCached) { - return this.toObjectRawCached; - } - } - if (noValue(this.dataBuffer)) { - return; - } - const { - head, - data, - id, - method, - } = this; - const target = { - head, - data, - method - }; - if (cache) { - this.toObjectRawCached = target; - } - return target; - } - isResponse = true; -} -export function clientResponse(...args) { - return construct(ClientResponse, args); -} diff --git a/udsp/request/object.js b/udsp/request/object.js deleted file mode 100644 index 3798424c..00000000 --- a/udsp/request/object.js +++ /dev/null @@ -1,164 +0,0 @@ -import { - jsonParse, isTrue, construct, hasValue, noValue -} from '@universalweb/acid'; -import { decode } from 'msgpackr'; -export class baseObject { - constructor(source, options) { - if (source.isAsk || source.isReply) { - const { - head, - method, - parameters, - path, - incomingData, - status, - type, - } = source; - return this.construct(incomingData, { - head, - method, - parameters, - path, - status, - type, - }); - } else { - return this.construct(source, options); - } - } - construct(data, options = {}) { - const { - head, - headers, - params, - parameters = params, - method, - status, - type, - url, - path = url - } = options; - this.head = head || {}; - if (hasValue(data)) { - this.dataBuffer = data; - } - this.method = method; - if (hasValue(status)) { - this.status = status; - } - if (hasValue(path)) { - this.path = path; - } - if (hasValue(type)) { - this.type = type; - } - if (hasValue(parameters)) { - this.parameters = parameters; - } - } - get data() { - if (this.compiledDataAlready) { - return this.compiledData; - } - if (noValue(this.dataBuffer)) { - return undefined; - } - const { head: { serialize } } = this; - const dataConcatinated = Buffer.concat(this.dataBuffer); - if (serialize) { - if (isTrue(serialize) || serialize === 0) { - this.compiledData = decode(dataConcatinated); - } else if (serialize === 1 || serialize === 'json') { - this.compiledData = jsonParse(dataConcatinated); - } - dataConcatinated.fill(0); - } else { - this.compiledData = dataConcatinated; - } - this.compiledDataAlready = true; - return this.compiledData; - } - get headers() { - return this.head; - } - get body() { - return this.data; - } - get url() { - return this.path; - } - toString(cache) { - if (cache) { - if (this.toStringCached) { - return this.toStringCached; - } - } - if (noValue(this.dataBuffer)) { - return; - } - const target = this.data.toString(); - if (cache) { - this.toStringCached = target; - } - return target; - } - toJSON(cache) { - if (cache) { - if (this.toJSONCached) { - return this.toJSONCached; - } - } - if (noValue(this.dataBuffer)) { - return; - } - const target = jsonParse(this.data); - if (cache) { - this.toJSONCached = target; - } - return jsonParse(this.data); - } - serialize(cache) { - if (cache) { - if (this.serializeCached) { - return this.serializeCached; - } - } - if (noValue(this.dataBuffer)) { - return; - } - const target = decode(this.data); - if (cache) { - this.serializeCached = target; - } - return target; - } - toObject(cache) { - if (cache) { - if (this.toObjectRawCached) { - return this.toObjectRawCached; - } - } - if (noValue(this.dataBuffer)) { - return; - } - const { - head, - data, - id, - method, - } = this; - const target = { - head, - data, - method - }; - if (cache) { - this.toObjectRawCached = target; - } - return target; - } - isResponse = true; -} -export function uwResponseObject(...args) { - return construct(baseObject, args); -} diff --git a/udsp/request/requestObject.js b/udsp/request/objects/base.js similarity index 51% rename from udsp/request/requestObject.js rename to udsp/request/objects/base.js index e0c5e450..9e8ddee8 100644 --- a/udsp/request/requestObject.js +++ b/udsp/request/objects/base.js @@ -1,5 +1,8 @@ import { - promise, assign, omit, eachArray, stringify, get, isBuffer, isPlainObject, isArray, isMap, construct, each, hasLength, hasValue, UniqID + promise, assign, omit, eachArray, + stringify, get, isBuffer, + isPlainObject, isArray, isMap, construct, + each, hasLength, hasValue, UniqID } from '@universalweb/acid'; import { decode, encode } from 'msgpackr'; import { @@ -8,8 +11,37 @@ import { msgReceived, msgSent } from '#logs'; -export class UWRequest { - constructor(path, options = {}) { +export class Base { + constructor(source, options) { + this.processConfig(source, options); + } + processConfig(source, options) { + if (source.isAsk || source.isReply) { + const { + head, + method, + parameters, + path, + incomingData, + status, + type, + } = source; + this.source = function() { + return source; + }; + return this.construct(incomingData, { + head, + method, + parameters, + path, + status, + type, + }); + } else { + return this.construct(source, options); + } + } + construct(path, options = {}) { const { method = 'get', parameters, @@ -29,7 +61,8 @@ export class UWRequest { signal, domainCertificate, profileCertificate, - params + params, + url } = options; if (method) { this.method = method; @@ -44,8 +77,10 @@ export class UWRequest { } else if (hasValue(headers)) { this.head = headers; } - if (path) { + if (hasValue(path)) { this.path = path; + } else if (hasValue(url)) { + this.path = url; } if (hasValue(parameters)) { this.parameters = parameters; @@ -53,32 +88,4 @@ export class UWRequest { this.parameters = params; } } - get headers() { - return this.head; - } - get body() { - return this.data; - } - get url() { - return this.path; - } - get params() { - return this.parameters; - } - set headers(value) { - this.head = value; - } - set body(value) { - this.data = value; - } - set url(value) { - this.path = value; - } - set params(value) { - this.parameters = value; - } - isRequest = true; -} -export async function uwRequestObject(source) { - return construct(UWRequest, omit); } diff --git a/udsp/request/objects/client/request.js b/udsp/request/objects/client/request.js new file mode 100644 index 00000000..000bf769 --- /dev/null +++ b/udsp/request/objects/client/request.js @@ -0,0 +1,26 @@ +import { + promise, assign, omit, eachArray, + stringify, get, isBuffer, + isPlainObject, isArray, isMap, construct, + each, hasLength, hasValue, UniqID +} from '@universalweb/acid'; +import { decode, encode } from 'msgpackr'; +import { + failed, + info, + msgReceived, + msgSent +} from '#logs'; +import { Base } from '../base.js'; +import { objectGetSetMethods } from '../objectGetSetMethods.js'; +export class ClientRequest extends Base { + constructor(path, options = {}) { + super(path, options); + } + isRequest = true; + isServerRequest = true; +} +objectGetSetMethods.attachMethods(ClientRequest); +export async function uwClientRequestObject(source) { + return construct(ClientRequest, omit); +} diff --git a/udsp/request/objects/client/response.js b/udsp/request/objects/client/response.js new file mode 100644 index 00000000..5a5ba594 --- /dev/null +++ b/udsp/request/objects/client/response.js @@ -0,0 +1,19 @@ +import { + jsonParse, isTrue, construct, hasValue, noValue +} from '@universalweb/acid'; +import { decode } from 'msgpackr'; +import { objectGetSetMethods } from '../objectGetSetMethods.js'; +import { Base } from '../base.js'; +import { objectDataMethods } from '../dataMethods.js'; +export class ClientResponse extends Base { + construct(source, options) { + super(source, options); + } + isResponse = true; + isServerResponse = true; +} +objectGetSetMethods.attachMethods(ClientResponse); +objectDataMethods.attachMethods(ClientResponse); +export function clientResponse(...args) { + return construct(ClientResponse, args); +} diff --git a/udsp/request/objects/dataMethods.js b/udsp/request/objects/dataMethods.js new file mode 100644 index 00000000..d8b9f486 --- /dev/null +++ b/udsp/request/objects/dataMethods.js @@ -0,0 +1,117 @@ +import { + eachObject, jsonParse, isTrue, noValue, assign +} from '@universalweb/acid'; +import { decode } from 'msgpackr'; +export const objectDataMethods = { + getters: { + data() { + if (this.compiledDataAlready) { + return this.compiledData; + } + if (noValue(this.dataBuffer)) { + return undefined; + } + const { head: { serialize } } = this; + const dataConcatinated = Buffer.concat(this.dataBuffer); + if (serialize) { + if (isTrue(serialize) || serialize === 0) { + this.compiledData = decode(dataConcatinated); + } else if (serialize === 1 || serialize === 'json') { + this.compiledData = jsonParse(dataConcatinated); + } + dataConcatinated.fill(0); + } else { + this.compiledData = dataConcatinated; + } + this.compiledDataAlready = true; + return this.compiledData; + }, + }, + setters: { + data(data) { + this.compiledData = data; + }, + }, + methods: { + toString(cache) { + if (cache) { + if (this.toStringCached) { + return this.toStringCached; + } + } + if (noValue(this.dataBuffer)) { + return; + } + const target = this.data.toString(); + if (cache) { + this.toStringCached = target; + } + return target; + }, + toJSON(cache) { + if (cache) { + if (this.toJSONCached) { + return this.toJSONCached; + } + } + if (noValue(this.dataBuffer)) { + return; + } + const target = jsonParse(this.data); + if (cache) { + this.toJSONCached = target; + } + return jsonParse(this.data); + }, + serialize(cache) { + if (cache) { + if (this.serializeCached) { + return this.serializeCached; + } + } + if (noValue(this.dataBuffer)) { + return; + } + const target = decode(this.data); + if (cache) { + this.serializeCached = target; + } + return target; + }, + toObject(cache) { + if (cache) { + if (this.toObjectRawCached) { + return this.toObjectRawCached; + } + } + if (noValue(this.dataBuffer)) { + return; + } + const { + head, + data, + id, + method, + } = this; + const target = { + head, + data, + method + }; + if (cache) { + this.toObjectRawCached = target; + } + return target; + } + }, + attachMethods(target) { + assign(target.prototype, objectDataMethods.methods); + eachObject(objectDataMethods.getters, (key, value) => { + Object.defineProperty(target.prototype, key, { + get: value, + set: objectDataMethods.setters[key] + }); + }); + } +}; + diff --git a/udsp/request/objects/objectGetSetMethods.js b/udsp/request/objects/objectGetSetMethods.js new file mode 100644 index 00000000..a578e05f --- /dev/null +++ b/udsp/request/objects/objectGetSetMethods.js @@ -0,0 +1,43 @@ +import { + eachObject, jsonParse, isTrue, noValue +} from '@universalweb/acid'; +import { decode } from 'msgpackr'; +export const objectGetSetMethods = { + getters: { + headers() { + return this.head; + }, + body() { + return this.data; + }, + url() { + return this.path; + }, + params() { + return this.parameters; + }, + }, + setters: { + headers(value) { + this.head = value; + }, + body(value) { + this.data = value; + }, + url(value) { + this.path = value; + }, + params(value) { + this.parameters = value; + } + }, + attachMethods(target) { + eachObject(objectGetSetMethods.getters, (key, value) => { + Object.defineProperty(target.prototype, key, { + get: value, + set: objectGetSetMethods.setters[key] + }); + }); + } +}; + diff --git a/udsp/request/objects/server/request.js b/udsp/request/objects/server/request.js new file mode 100644 index 00000000..a7f20e12 --- /dev/null +++ b/udsp/request/objects/server/request.js @@ -0,0 +1,26 @@ +import { + promise, assign, omit, eachArray, + stringify, get, isBuffer, + isPlainObject, isArray, isMap, construct, + each, hasLength, hasValue, UniqID +} from '@universalweb/acid'; +import { decode, encode } from 'msgpackr'; +import { + failed, + info, + msgReceived, + msgSent +} from '#logs'; +import { Base } from '../base.js'; +import { objectGetSetMethods } from '../objectGetSetMethods.js'; +export class ServerRequest extends Base { + constructor(path, options = {}) { + super(path, options); + } + isRequest = true; + isServerRequest = true; +} +objectGetSetMethods.attachMethods(ServerRequest); +export async function uwServerRequestObject(source) { + return construct(ServerRequest, omit); +} diff --git a/udsp/request/objects/server/response.js b/udsp/request/objects/server/response.js new file mode 100644 index 00000000..faab3a77 --- /dev/null +++ b/udsp/request/objects/server/response.js @@ -0,0 +1,17 @@ +import { + jsonParse, isTrue, construct, hasValue, noValue +} from '@universalweb/acid'; +import { decode } from 'msgpackr'; +import { Base } from '../base.js'; +import { objectGetSetMethods } from '../objectGetSetMethods.js'; +export class ServerResponse extends Base { + construct(source, options) { + super(source, options); + } + isResponse = true; + isClientResponse = true; +} +objectGetSetMethods.attachMethods(ServerResponse); +export function clientResponse(...args) { + return construct(ServerResponse, args); +} diff --git a/udsp/request/reply.js b/udsp/request/reply.js index 1aa41170..c383595e 100644 --- a/udsp/request/reply.js +++ b/udsp/request/reply.js @@ -13,7 +13,7 @@ import { processEvent } from '#udsp/processEvent'; import { Base } from './base.js'; import { numberEncodedSize } from './numberEncodedSize.js'; import { flushOutgoing } from './flush.js'; -import { uwRequestObject } from './requestObject.js'; +import { uwRequestObject } from './objects/client/request'; /** * @todo */ @@ -36,16 +36,15 @@ export class Reply extends Base { this.response.id = id; this.streamIdSize = numberEncodedSize(id); this.request = uwRequestObject(this); + this.response = uwRequestObject(this); replyQueue.set(id, this); } type = 'reply'; isReply = true; async completeReceived() { this.state = 1; - await processEvent(this.request, this); + await processEvent(this.request, this.response, this); } - response = {}; - request = {}; } export function reply(packet, client) { // console.log(client); diff --git a/udsp/requestMethods/fetch.js b/udsp/requestMethods/fetch.js index 9e17c954..91c7f0cd 100644 --- a/udsp/requestMethods/fetch.js +++ b/udsp/requestMethods/fetch.js @@ -2,7 +2,7 @@ import { success, failed, imported, msgSent, info } from '#logs'; import { promise, construct, isString } from '@universalweb/acid'; -import { UWResponse } from '../request/client/clientResponse.js'; +import { UWResponse } from '../request/objects/client/response.js'; // If path arg has params in it then paramArg becomes dataArg // params support both Complex Data Binary Supported Params and simple traditional URL percent encoded params export async function fetchRequest(path, config = {}) {