diff --git a/README.md b/README.md index 5f27194..305506d 100644 --- a/README.md +++ b/README.md @@ -221,11 +221,11 @@ Create a `Body` instance from raw data (e.g. `Readable | ReadableStream | Buffer If you're building the transports for Servie, there are some life cycle events you need to be aware of: 1. Listen to the `error` event on `Request` and `Response` for errors -2. Listen to the `abort` event on `Request` and `Response` to destroy the connection -3. Resolve `trailer` promise and append to HTTP request -4. Emit a `response` event (with `Response` provided) on `Request` when server responds -5. Set `started = true` and `finished = true` on `Request` and `Response` (as appropriate) -6. Set `bytesTransferred` on `Request` and `Response` when monitoring HTTP transfer progress +2. Listen to the `abort` event on `Request` to destroy the connection and, when destroyed, set `req.aborted = true` +3. Resolve `trailer` promise and append to HTTP request or response +4. Set `started = true` and `finished = true` on `Request` and `Response` (as appropriate) +5. Set `bytesTransferred` on `Request` and `Response` with transfer progress +6. Set `req.closed = true` when the connection has finished ## JavaScript diff --git a/src/base.ts b/src/base.ts index d56b176..e90bb1e 100644 --- a/src/base.ts +++ b/src/base.ts @@ -10,6 +10,9 @@ export interface ServieOptions { trailer?: Headers | Promise } +/** + * @internal + */ export const kBytesTransferred = Symbol('bytesTransferred') export abstract class Servie implements ServieOptions { @@ -63,20 +66,6 @@ export abstract class Servie implements ServieOptions { } } - get aborted () { return false } - - abort () { - const shouldAbort = !this.aborted && !this.finished - - if (shouldAbort) { - this.events.emit('abort') - Object.defineProperty(this, 'aborted', { value: true }) - this.events.emit('aborted') - } - - return shouldAbort - } - abstract clone (): Servie } diff --git a/src/body/common.ts b/src/body/common.ts index 5f18431..0ced133 100644 --- a/src/body/common.ts +++ b/src/body/common.ts @@ -10,7 +10,14 @@ export interface BodyCommonOptions { bodyUsed?: boolean } +/** + * @internal + */ export const kRawBody = Symbol('rawBody') + +/** + * @internal + */ export const kBodyUsed = Symbol('bodyUsed') export abstract class BodyCommon implements BodyCommonOptions { diff --git a/src/headers.ts b/src/headers.ts index 34557e6..0914de0 100644 --- a/src/headers.ts +++ b/src/headers.ts @@ -10,7 +10,14 @@ export interface HeadersValuesObject { [key: string]: HeaderValues } +/** + * @internal + */ export const kHeaderList = Symbol('headerList') + +/** + * @internal + */ export const kHeaderNames = Symbol('headerNames') /** diff --git a/src/request.ts b/src/request.ts index 0daa4b5..6375c80 100644 --- a/src/request.ts +++ b/src/request.ts @@ -21,9 +21,21 @@ export interface RequestOptions extends ServieOptions { connection?: Connection } +/** + * @internal + */ export const kUrl = Symbol('url') + +/** + * @internal + */ export const kUrlObject = Symbol('urlObject') +/** + * @internal + */ +export const kAborted = Symbol('aborted') + /** * The HTTP request class. */ @@ -33,6 +45,7 @@ export class Request extends Servie implements RequestOptions { protected [kUrl]: string protected [kUrlObject]?: Url + protected [kAborted]?: boolean constructor (options: RequestOptions) { super(options) @@ -66,6 +79,35 @@ export class Request extends Servie implements RequestOptions { } } + get closed () { return false } + + set closed (value: boolean) { + if (value) { + Object.defineProperty(this, 'closed', { value }) + this.events.emit('closed') + } + } + + get aborted () { return false } + + set aborted (value: boolean) { + if (value) { + this[kAborted] = true + Object.defineProperty(this, 'aborted', { value }) + this.events.emit('aborted') + } + } + + abort () { + if (this.closed || this[kAborted]) return false + + // Block repeat "abort" events. + this[kAborted] = true + this.events.emit('abort') + + return true + } + toJSON () { return { url: this.url, @@ -81,6 +123,7 @@ export class Request extends Servie implements RequestOptions { clone () { if (this.started) throw new TypeError('Request already started') + if (this[kAborted]) throw new TypeError('Request has been aborted') return new Request({ url: this.url, diff --git a/tsconfig.json b/tsconfig.json index 69c2c39..ed2cf50 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,7 @@ "outDir": "dist", "module": "commonjs", "strict": true, + "stripInternal": true, "declaration": true, "removeComments": false, "sourceMap": true,