Skip to content

Commit

Permalink
Merge pull request #9 from Amarok24/same-conn-twice
Browse files Browse the repository at this point in the history
v1.2.1
  • Loading branch information
Amarok24 authored Feb 11, 2022
2 parents 858f265 + 757b430 commit c0c28b6
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 44 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Oxhr v1.2.0
# Oxhr v1.2.1
An object-oriented and asynchronous XHR (XMLHttpRequest) wrapper.

### Modern programmers use fetch, others prefer Oxhr 🐮
Expand Down Expand Up @@ -117,6 +117,9 @@ __Can I open multiple connections at once?__


## Changelog
### _v1.2.1_
- Fixed a too strict connection handling, now the same Oxhr instance can safely be re-used for further requests.

### _v1.2.0_
- Many code improvements, now the library is more robust and handles all kind of wrong usage in a nice way
- Added 4 new getters: instanceId, status, success, isProcessed
Expand Down
7 changes: 1 addition & 6 deletions dist/demo.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Oxhr } from './oxhr.js';
import { ResourcesType } from './swapi-schema.js';
import { OxhrError } from './oxhr-error.js';
import { ResourcesType } from './swapi-schema.js';
const startButton = document.querySelector('#startButton');
const abortButton = document.querySelector('#abortButton');
const swButton = document.querySelector('#swButton');
Expand Down Expand Up @@ -49,12 +49,7 @@ async function tryToSendData() {
const myData = `{ "test": 123 }`;
try {
console.log('try-block of tryToSendData');
console.log(`myConnection.instanceId = ${myConnection.instanceId}`);
console.log(`XHR status of myConnection is ${myConnection.status}`);
if (myConnection.isProcessed) {
console.log('You have probably clicked on that button while a connection is being processed.');
return;
}
console.log('Now we will await myConnection.send');
response = await myConnection.send(myData);
console.log('await myConnection.send is DONE, all data received!');
Expand Down
7 changes: 2 additions & 5 deletions dist/generate-uuid.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
export { generateUUID };
function generateUUID() {
let cryptoRef = null;
let cryptoRef;
let r = '';
if (typeof self.crypto !== 'undefined') {
cryptoRef = self.crypto;
r = cryptoRef.randomUUID?.();
}
if (!r) {
r = 'Crypto API or randomUUID method not supported.';
}
return r;
return r ? r : '';
}
16 changes: 11 additions & 5 deletions dist/xhr-handler.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { OxhrError } from './oxhr-error.js';
import { XhrReadyState, XhrStatus } from './xhr-codes.js';
import { generateUUID } from './generate-uuid.js';
export { XhrHandler };
class XhrHandler {
constructor(parameters) {
this._eventHandlersAssigned = false;
this._instanceId = generateUUID();
this.xhr = new XMLHttpRequest();
this.xhrExecutor = (resolve, reject) => {
const handleLoad = (ev) => {
Expand All @@ -27,7 +29,7 @@ class XhrHandler {
if (this.params.consoleMessage)
console.group(this.params.consoleMessage);
console.log(ev);
console.error(`xhr status: ${this.xhr.status}`);
console.warn(`xhr status: ${this.xhr.status}`);
if (this.params.consoleMessage)
console.groupEnd();
};
Expand Down Expand Up @@ -67,7 +69,7 @@ class XhrHandler {
if (this.params.requestHeaders) {
this.params.requestHeaders.forEach((h) => {
if ((h.header !== '') && (h.value !== '')) {
this.debugMessage(`setting custom request header '${h.header}, ${h.value}'`);
this.debugMessage(`Setting custom request header '${h.header}, ${h.value}'`);
this.xhr.setRequestHeader(h.header, h.value);
}
});
Expand All @@ -76,7 +78,7 @@ class XhrHandler {
this.xhr.responseType = this.responseType;
if (!this._eventHandlersAssigned) {
this._eventHandlersAssigned = true;
this.debugMessage('adding event listeners');
this.debugMessage('Adding event listeners.');
this.xhr.addEventListener('load', handleLoad);
this.xhr.addEventListener('loadend', handleLoadEnd);
this.xhr.addEventListener('error', handleError);
Expand All @@ -91,18 +93,19 @@ class XhrHandler {
}
}
if (this.xhr.readyState !== XhrReadyState.OPENED) {
this.debugMessage('warning, connection not opened, this will cause an error.');
this.debugMessage('Warning, connection not opened, this will cause an error.');
}
this.xhr.send(this.data);
};
this.params = parameters;
this.method = parameters.method ?? 'GET';
this.data = parameters.data ?? null;
this.responseType = parameters.responseType ?? '';
this.debugMessage('A new instance was created.');
}
debugMessage(m) {
if (this.params.debug)
console.log(`Oxhr: ${m}`);
console.info(`Oxhr: ${m}\nInstance UUID ${this._instanceId}`);
}
get readyState() {
return this.xhr.readyState;
Expand All @@ -118,4 +121,7 @@ class XhrHandler {
return (this.xhr.readyState !== XhrReadyState.DONE &&
this.xhr.readyState !== XhrReadyState.UNSENT);
}
get instanceId() {
return this._instanceId;
}
}
9 changes: 4 additions & 5 deletions src/demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ https://github.com/Amarok24/Oxhr
*/

import {Oxhr} from './oxhr.js';
import {IPeople, ResourcesType} from './swapi-schema.js';
import {OxhrError} from './oxhr-error.js';
import {IPeople, ResourcesType} from './swapi-schema.js';
import type {IOxhrParams, IRequestHeader} from './oxhr-types.js';

const startButton = document.querySelector<HTMLButtonElement>('#startButton');
Expand Down Expand Up @@ -99,15 +99,14 @@ async function tryToSendData(): Promise<void>
try
{
console.log('try-block of tryToSendData');
console.log(`myConnection.instanceId = ${ myConnection.instanceId }`);
console.log(`XHR status of myConnection is ${ myConnection.status }`);

/*
if (myConnection.isProcessed)
{
console.log('You have probably clicked on that button while a connection is being processed.');
console.log('You have clicked on the button while a connection is being processed.');
return;
}

*/
console.log('Now we will await myConnection.send');
// In this example we pass the data to be sent with request with the 'send' method.
response = await myConnection.send(myData);
Expand Down
17 changes: 3 additions & 14 deletions src/oxhr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ limitations under the License.
*/

import {XhrHandler} from './xhr-handler.js';
import {OxhrError} from './oxhr-error.js';
import {XhrReadyState} from './xhr-codes.js';
import {generateUUID} from './generate-uuid.js';

import type {IOxhrParams, CombinedDataType} from "./oxhr-types.js";

Expand All @@ -27,27 +25,18 @@ export {Oxhr};

class Oxhr<T = unknown> extends XhrHandler<T>
{
private _instanceId: string = generateUUID();

constructor(parameters: IOxhrParams)
{
super(parameters);
}

/**
* Returns a unique instance UUID.
*/
get instanceId(): string
{
return this._instanceId;
}

send(data?: CombinedDataType): Promise<T> | never
{
this.debugMessage(`xhr.readyState ${ this.xhr.readyState }`);
if (this.xhr.readyState !== XhrReadyState.UNSENT)
if (this.isProcessed)
{
throw new OxhrError('A violation occured, the same connection is already being processed or has already finished.');
// Calling the "open" method for an already active request (one for which open() has already been called) is the equivalent of calling abort().
console.warn(`Oxhr: Either a request is being processed or has already finished. A new request using the same Oxhr instance will be opened.\nInstace UUID ${this.instanceId}`);
}

this.data = data ?? this.data;
Expand Down
25 changes: 17 additions & 8 deletions src/xhr-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Licensed under the Apache License, Version 2.0

import {OxhrError} from './oxhr-error.js';
import {XhrReadyState, XhrStatus} from './xhr-codes.js';
import {generateUUID} from './generate-uuid.js';

import type {IResolve, IReject, IOxhrParams, HttpRequestMethod, CombinedDataType} from "./oxhr-types.js";

Expand All @@ -15,6 +16,7 @@ export {XhrHandler};
class XhrHandler<T>
{
private _eventHandlersAssigned: boolean = false;
private _instanceId: string = generateUUID();
protected readonly xhr: XMLHttpRequest = new XMLHttpRequest();
protected data: CombinedDataType;
protected params: IOxhrParams;
Expand All @@ -27,6 +29,7 @@ class XhrHandler<T>
this.method = parameters.method ?? 'GET';
this.data = parameters.data ?? null;
this.responseType = parameters.responseType ?? '';
this.debugMessage('A new instance was created.');
// Here this.xhr.readyState == 0
}

Expand Down Expand Up @@ -65,7 +68,7 @@ class XhrHandler<T>
reject(new OxhrError('Failed to send request!'));
if (this.params.consoleMessage) console.group(this.params.consoleMessage);
console.log(ev);
console.error(`xhr status: ${ this.xhr.status }`);
console.warn(`xhr status: ${ this.xhr.status }`);
if (this.params.consoleMessage) console.groupEnd();
};

Expand All @@ -86,8 +89,7 @@ class XhrHandler<T>

const handleTimeout = (): void =>
{
// Notice that we don't "throw" an error here, this would be unhandled later.
// Here xhr.status is 0.
// Notice that we don't "throw" an error here, this would be unhandled later. Note: xhr.status is 0.
this.debugMessage('handleTimeout()');
reject(new OxhrError('Timeout'));
};
Expand Down Expand Up @@ -118,7 +120,7 @@ class XhrHandler<T>
this._eventHandlersAssigned = false;
};


// Calling the "open" method for an already active request (one for which open() has already been called) is the equivalent of calling abort().
this.xhr.open(this.method, this.params.url);

if (this.params.requestHeaders)
Expand All @@ -127,7 +129,7 @@ class XhrHandler<T>
{
if ((h.header !== '') && (h.value !== ''))
{
this.debugMessage(`setting custom request header '${ h.header }, ${ h.value }'`);
this.debugMessage(`Setting custom request header '${ h.header }, ${ h.value }'`);
this.xhr.setRequestHeader(h.header, h.value);
}
});
Expand All @@ -143,7 +145,7 @@ class XhrHandler<T>
if (!this._eventHandlersAssigned)
{
this._eventHandlersAssigned = true;
this.debugMessage('adding event listeners');
this.debugMessage('Adding event listeners.');

// All XHR events: https://xhr.spec.whatwg.org/#events
this.xhr.addEventListener('load', handleLoad);
Expand All @@ -167,7 +169,7 @@ class XhrHandler<T>
if (this.xhr.readyState !== XhrReadyState.OPENED)
{
// Only when readyState is opened it is possible to call 'send', else error will be thrown. It is now safe to define connection as running.
this.debugMessage('warning, connection not opened, this will cause an error.');
this.debugMessage('Warning, connection not opened, this will cause an error.');
}

// The send() method is async by default, notification of a completed transaction is provided using event listeners.
Expand All @@ -177,7 +179,7 @@ class XhrHandler<T>

protected debugMessage(m: string): void
{
if (this.params.debug) console.log(`Oxhr: ${ m }`);
if (this.params.debug) console.info(`Oxhr: ${ m }\nInstance UUID ${ this._instanceId }`);
}

/**
Expand Down Expand Up @@ -219,6 +221,13 @@ class XhrHandler<T>
);
}

/**
* Returns a unique instance UUID.
*/
get instanceId(): string
{
return this._instanceId;
}
}

// TODO: implement event handlers for processing uploads
Expand Down

0 comments on commit c0c28b6

Please sign in to comment.