Backend half
This commit is contained in:
+201
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2018-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
# @aws-sdk/lib-storage
|
||||
|
||||
[](https://www.npmjs.com/package/@aws-sdk/lib-storage)
|
||||
[](https://www.npmjs.com/package/@aws-sdk/lib-storage)
|
||||
|
||||
### Upload
|
||||
|
||||
Upload allows for easy and efficient uploading of buffers, blobs, or streams, using a configurable amount of concurrency to perform multipart uploads where possible. This abstraction enables uploading large files or streams of unknown size due to the use of multipart uploads under the hood.
|
||||
|
||||
```js
|
||||
import { Upload } from "@aws-sdk/lib-storage";
|
||||
import { S3Client, S3 } from "@aws-sdk/client-s3";
|
||||
|
||||
try {
|
||||
const parallelUploads3 = new Upload({
|
||||
client: new S3({}) || new S3Client({}),
|
||||
params: { Bucket, Key, Body },
|
||||
|
||||
// optional tags
|
||||
tags: [
|
||||
/*...*/
|
||||
],
|
||||
|
||||
// additional optional fields show default values below:
|
||||
|
||||
// (optional) concurrency configuration
|
||||
queueSize: 4,
|
||||
|
||||
// (optional) size of each part, in bytes, at least 5MB
|
||||
partSize: 1024 * 1024 * 5,
|
||||
|
||||
// (optional) when true, do not automatically call AbortMultipartUpload when
|
||||
// a multipart upload fails to complete. You should then manually handle
|
||||
// the leftover parts.
|
||||
leavePartsOnError: false,
|
||||
});
|
||||
|
||||
parallelUploads3.on("httpUploadProgress", (progress) => {
|
||||
console.log(progress);
|
||||
});
|
||||
|
||||
await parallelUploads3.done();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
```
|
||||
+505
@@ -0,0 +1,505 @@
|
||||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
|
||||
// src/index.ts
|
||||
var index_exports = {};
|
||||
__export(index_exports, {
|
||||
Upload: () => Upload
|
||||
});
|
||||
module.exports = __toCommonJS(index_exports);
|
||||
|
||||
// src/Upload.ts
|
||||
var import_client_s3 = require("@aws-sdk/client-s3");
|
||||
var import_abort_controller = require("@smithy/abort-controller");
|
||||
var import_middleware_endpoint = require("@smithy/middleware-endpoint");
|
||||
var import_smithy_client = require("@smithy/smithy-client");
|
||||
var import_events = require("events");
|
||||
|
||||
// src/bytelength.ts
|
||||
var import_buffer = require("buffer");
|
||||
var import_runtimeConfig = require("././runtimeConfig");
|
||||
var byteLength = /* @__PURE__ */ __name((input) => {
|
||||
if (input === null || input === void 0) return 0;
|
||||
if (typeof input === "string") {
|
||||
return import_buffer.Buffer.byteLength(input);
|
||||
}
|
||||
if (typeof input.byteLength === "number") {
|
||||
return input.byteLength;
|
||||
} else if (typeof input.length === "number") {
|
||||
return input.length;
|
||||
} else if (typeof input.size === "number") {
|
||||
return input.size;
|
||||
} else if (typeof input.path === "string") {
|
||||
try {
|
||||
return import_runtimeConfig.ClientDefaultValues.lstatSync(input.path).size;
|
||||
} catch (error) {
|
||||
return void 0;
|
||||
}
|
||||
}
|
||||
return void 0;
|
||||
}, "byteLength");
|
||||
|
||||
// src/chunker.ts
|
||||
|
||||
var import_stream = require("stream");
|
||||
|
||||
// src/chunks/getChunkStream.ts
|
||||
|
||||
async function* getChunkStream(data, partSize, getNextData) {
|
||||
let partNumber = 1;
|
||||
const currentBuffer = { chunks: [], length: 0 };
|
||||
for await (const datum of getNextData(data)) {
|
||||
currentBuffer.chunks.push(datum);
|
||||
currentBuffer.length += datum.byteLength;
|
||||
while (currentBuffer.length > partSize) {
|
||||
const dataChunk = currentBuffer.chunks.length > 1 ? import_buffer.Buffer.concat(currentBuffer.chunks) : currentBuffer.chunks[0];
|
||||
yield {
|
||||
partNumber,
|
||||
data: dataChunk.subarray(0, partSize)
|
||||
};
|
||||
currentBuffer.chunks = [dataChunk.subarray(partSize)];
|
||||
currentBuffer.length = currentBuffer.chunks[0].byteLength;
|
||||
partNumber += 1;
|
||||
}
|
||||
}
|
||||
yield {
|
||||
partNumber,
|
||||
data: currentBuffer.chunks.length !== 1 ? import_buffer.Buffer.concat(currentBuffer.chunks) : currentBuffer.chunks[0],
|
||||
lastPart: true
|
||||
};
|
||||
}
|
||||
__name(getChunkStream, "getChunkStream");
|
||||
|
||||
// src/chunks/getChunkUint8Array.ts
|
||||
async function* getChunkUint8Array(data, partSize) {
|
||||
let partNumber = 1;
|
||||
let startByte = 0;
|
||||
let endByte = partSize;
|
||||
while (endByte < data.byteLength) {
|
||||
yield {
|
||||
partNumber,
|
||||
data: data.subarray(startByte, endByte)
|
||||
};
|
||||
partNumber += 1;
|
||||
startByte = endByte;
|
||||
endByte = startByte + partSize;
|
||||
}
|
||||
yield {
|
||||
partNumber,
|
||||
data: data.subarray(startByte),
|
||||
lastPart: true
|
||||
};
|
||||
}
|
||||
__name(getChunkUint8Array, "getChunkUint8Array");
|
||||
|
||||
// src/chunks/getDataReadable.ts
|
||||
|
||||
async function* getDataReadable(data) {
|
||||
for await (const chunk of data) {
|
||||
if (import_buffer.Buffer.isBuffer(chunk) || chunk instanceof Uint8Array) {
|
||||
yield chunk;
|
||||
} else {
|
||||
yield import_buffer.Buffer.from(chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
__name(getDataReadable, "getDataReadable");
|
||||
|
||||
// src/chunks/getDataReadableStream.ts
|
||||
|
||||
async function* getDataReadableStream(data) {
|
||||
const reader = data.getReader();
|
||||
try {
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) {
|
||||
return;
|
||||
}
|
||||
if (import_buffer.Buffer.isBuffer(value) || value instanceof Uint8Array) {
|
||||
yield value;
|
||||
} else {
|
||||
yield import_buffer.Buffer.from(value);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} finally {
|
||||
reader.releaseLock();
|
||||
}
|
||||
}
|
||||
__name(getDataReadableStream, "getDataReadableStream");
|
||||
|
||||
// src/chunker.ts
|
||||
var getChunk = /* @__PURE__ */ __name((data, partSize) => {
|
||||
if (data instanceof Uint8Array) {
|
||||
return getChunkUint8Array(data, partSize);
|
||||
}
|
||||
if (data instanceof import_stream.Readable) {
|
||||
return getChunkStream(data, partSize, getDataReadable);
|
||||
}
|
||||
if (data instanceof String || typeof data === "string") {
|
||||
return getChunkUint8Array(import_buffer.Buffer.from(data), partSize);
|
||||
}
|
||||
if (typeof data.stream === "function") {
|
||||
return getChunkStream(data.stream(), partSize, getDataReadableStream);
|
||||
}
|
||||
if (data instanceof ReadableStream) {
|
||||
return getChunkStream(data, partSize, getDataReadableStream);
|
||||
}
|
||||
throw new Error(
|
||||
"Body Data is unsupported format, expected data to be one of: string | Uint8Array | Buffer | Readable | ReadableStream | Blob;."
|
||||
);
|
||||
}, "getChunk");
|
||||
|
||||
// src/Upload.ts
|
||||
var Upload = class _Upload extends import_events.EventEmitter {
|
||||
static {
|
||||
__name(this, "Upload");
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
* modified in testing only.
|
||||
*/
|
||||
static MIN_PART_SIZE = 1024 * 1024 * 5;
|
||||
/**
|
||||
* S3 multipart upload does not allow more than 10,000 parts.
|
||||
*/
|
||||
MAX_PARTS = 1e4;
|
||||
// Defaults.
|
||||
queueSize = 4;
|
||||
partSize = _Upload.MIN_PART_SIZE;
|
||||
leavePartsOnError = false;
|
||||
tags = [];
|
||||
client;
|
||||
params;
|
||||
// used for reporting progress.
|
||||
totalBytes;
|
||||
bytesUploadedSoFar;
|
||||
// used in the upload.
|
||||
abortController;
|
||||
concurrentUploaders = [];
|
||||
createMultiPartPromise;
|
||||
abortMultipartUploadCommand = null;
|
||||
uploadedParts = [];
|
||||
uploadEnqueuedPartsCount = 0;
|
||||
/**
|
||||
* Last UploadId if the upload was done with MultipartUpload and not PutObject.
|
||||
*/
|
||||
uploadId;
|
||||
uploadEvent;
|
||||
isMultiPart = true;
|
||||
singleUploadResult;
|
||||
sent = false;
|
||||
constructor(options) {
|
||||
super();
|
||||
this.queueSize = options.queueSize || this.queueSize;
|
||||
this.partSize = options.partSize || this.partSize;
|
||||
this.leavePartsOnError = options.leavePartsOnError || this.leavePartsOnError;
|
||||
this.tags = options.tags || this.tags;
|
||||
this.client = options.client;
|
||||
this.params = options.params;
|
||||
this.__validateInput();
|
||||
this.totalBytes = byteLength(this.params.Body);
|
||||
this.bytesUploadedSoFar = 0;
|
||||
this.abortController = options.abortController ?? new import_abort_controller.AbortController();
|
||||
}
|
||||
async abort() {
|
||||
this.abortController.abort();
|
||||
}
|
||||
async done() {
|
||||
if (this.sent) {
|
||||
throw new Error(
|
||||
"@aws-sdk/lib-storage: this instance of Upload has already executed .done(). Create a new instance."
|
||||
);
|
||||
}
|
||||
this.sent = true;
|
||||
return await Promise.race([this.__doMultipartUpload(), this.__abortTimeout(this.abortController.signal)]);
|
||||
}
|
||||
on(event, listener) {
|
||||
this.uploadEvent = event;
|
||||
return super.on(event, listener);
|
||||
}
|
||||
async __uploadUsingPut(dataPart) {
|
||||
this.isMultiPart = false;
|
||||
const params = { ...this.params, Body: dataPart.data };
|
||||
const clientConfig = this.client.config;
|
||||
const requestHandler = clientConfig.requestHandler;
|
||||
const eventEmitter = requestHandler instanceof import_events.EventEmitter ? requestHandler : null;
|
||||
const uploadEventListener = /* @__PURE__ */ __name((event) => {
|
||||
this.bytesUploadedSoFar = event.loaded;
|
||||
this.totalBytes = event.total;
|
||||
this.__notifyProgress({
|
||||
loaded: this.bytesUploadedSoFar,
|
||||
total: this.totalBytes,
|
||||
part: dataPart.partNumber,
|
||||
Key: this.params.Key,
|
||||
Bucket: this.params.Bucket
|
||||
});
|
||||
}, "uploadEventListener");
|
||||
if (eventEmitter !== null) {
|
||||
eventEmitter.on("xhr.upload.progress", uploadEventListener);
|
||||
}
|
||||
const resolved = await Promise.all([this.client.send(new import_client_s3.PutObjectCommand(params)), clientConfig?.endpoint?.()]);
|
||||
const putResult = resolved[0];
|
||||
let endpoint = resolved[1];
|
||||
if (!endpoint) {
|
||||
endpoint = (0, import_middleware_endpoint.toEndpointV1)(
|
||||
await (0, import_middleware_endpoint.getEndpointFromInstructions)(params, import_client_s3.PutObjectCommand, {
|
||||
...clientConfig
|
||||
})
|
||||
);
|
||||
}
|
||||
if (!endpoint) {
|
||||
throw new Error('Could not resolve endpoint from S3 "client.config.endpoint()" nor EndpointsV2.');
|
||||
}
|
||||
if (eventEmitter !== null) {
|
||||
eventEmitter.off("xhr.upload.progress", uploadEventListener);
|
||||
}
|
||||
const locationKey = this.params.Key.split("/").map((segment) => (0, import_smithy_client.extendedEncodeURIComponent)(segment)).join("/");
|
||||
const locationBucket = (0, import_smithy_client.extendedEncodeURIComponent)(this.params.Bucket);
|
||||
const Location = (() => {
|
||||
const endpointHostnameIncludesBucket = endpoint.hostname.startsWith(`${locationBucket}.`);
|
||||
const forcePathStyle = this.client.config.forcePathStyle;
|
||||
const optionalPort = endpoint.port ? `:${endpoint.port}` : ``;
|
||||
if (forcePathStyle) {
|
||||
return `${endpoint.protocol}//${endpoint.hostname}${optionalPort}/${locationBucket}/${locationKey}`;
|
||||
}
|
||||
if (endpointHostnameIncludesBucket) {
|
||||
return `${endpoint.protocol}//${endpoint.hostname}${optionalPort}/${locationKey}`;
|
||||
}
|
||||
return `${endpoint.protocol}//${locationBucket}.${endpoint.hostname}${optionalPort}/${locationKey}`;
|
||||
})();
|
||||
this.singleUploadResult = {
|
||||
...putResult,
|
||||
Bucket: this.params.Bucket,
|
||||
Key: this.params.Key,
|
||||
Location
|
||||
};
|
||||
const totalSize = byteLength(dataPart.data);
|
||||
this.__notifyProgress({
|
||||
loaded: totalSize,
|
||||
total: totalSize,
|
||||
part: 1,
|
||||
Key: this.params.Key,
|
||||
Bucket: this.params.Bucket
|
||||
});
|
||||
}
|
||||
async __createMultipartUpload() {
|
||||
const requestChecksumCalculation = await this.client.config.requestChecksumCalculation();
|
||||
if (!this.createMultiPartPromise) {
|
||||
const createCommandParams = { ...this.params, Body: void 0 };
|
||||
if (requestChecksumCalculation === "WHEN_SUPPORTED") {
|
||||
createCommandParams.ChecksumAlgorithm = this.params.ChecksumAlgorithm || import_client_s3.ChecksumAlgorithm.CRC32;
|
||||
}
|
||||
this.createMultiPartPromise = this.client.send(new import_client_s3.CreateMultipartUploadCommand(createCommandParams)).then((createMpuResponse) => {
|
||||
this.abortMultipartUploadCommand = new import_client_s3.AbortMultipartUploadCommand({
|
||||
Bucket: this.params.Bucket,
|
||||
Key: this.params.Key,
|
||||
UploadId: createMpuResponse.UploadId
|
||||
});
|
||||
return createMpuResponse;
|
||||
});
|
||||
}
|
||||
return this.createMultiPartPromise;
|
||||
}
|
||||
async __doConcurrentUpload(dataFeeder) {
|
||||
for await (const dataPart of dataFeeder) {
|
||||
if (this.uploadEnqueuedPartsCount > this.MAX_PARTS) {
|
||||
throw new Error(
|
||||
`Exceeded ${this.MAX_PARTS} parts in multipart upload to Bucket: ${this.params.Bucket} Key: ${this.params.Key}.`
|
||||
);
|
||||
}
|
||||
if (this.abortController.signal.aborted) {
|
||||
return;
|
||||
}
|
||||
if (dataPart.partNumber === 1 && dataPart.lastPart) {
|
||||
return await this.__uploadUsingPut(dataPart);
|
||||
}
|
||||
if (!this.uploadId) {
|
||||
const { UploadId } = await this.__createMultipartUpload();
|
||||
this.uploadId = UploadId;
|
||||
if (this.abortController.signal.aborted) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const partSize = byteLength(dataPart.data) || 0;
|
||||
const requestHandler = this.client.config.requestHandler;
|
||||
const eventEmitter = requestHandler instanceof import_events.EventEmitter ? requestHandler : null;
|
||||
let lastSeenBytes = 0;
|
||||
const uploadEventListener = /* @__PURE__ */ __name((event, request) => {
|
||||
const requestPartSize = Number(request.query["partNumber"]) || -1;
|
||||
if (requestPartSize !== dataPart.partNumber) {
|
||||
return;
|
||||
}
|
||||
if (event.total && partSize) {
|
||||
this.bytesUploadedSoFar += event.loaded - lastSeenBytes;
|
||||
lastSeenBytes = event.loaded;
|
||||
}
|
||||
this.__notifyProgress({
|
||||
loaded: this.bytesUploadedSoFar,
|
||||
total: this.totalBytes,
|
||||
part: dataPart.partNumber,
|
||||
Key: this.params.Key,
|
||||
Bucket: this.params.Bucket
|
||||
});
|
||||
}, "uploadEventListener");
|
||||
if (eventEmitter !== null) {
|
||||
eventEmitter.on("xhr.upload.progress", uploadEventListener);
|
||||
}
|
||||
this.uploadEnqueuedPartsCount += 1;
|
||||
const partResult = await this.client.send(
|
||||
new import_client_s3.UploadPartCommand({
|
||||
...this.params,
|
||||
// dataPart.data is chunked into a non-streaming buffer
|
||||
// so the ContentLength from the input should not be used for MPU.
|
||||
ContentLength: void 0,
|
||||
UploadId: this.uploadId,
|
||||
Body: dataPart.data,
|
||||
PartNumber: dataPart.partNumber
|
||||
})
|
||||
);
|
||||
if (eventEmitter !== null) {
|
||||
eventEmitter.off("xhr.upload.progress", uploadEventListener);
|
||||
}
|
||||
if (this.abortController.signal.aborted) {
|
||||
return;
|
||||
}
|
||||
if (!partResult.ETag) {
|
||||
throw new Error(
|
||||
`Part ${dataPart.partNumber} is missing ETag in UploadPart response. Missing Bucket CORS configuration for ETag header?`
|
||||
);
|
||||
}
|
||||
this.uploadedParts.push({
|
||||
PartNumber: dataPart.partNumber,
|
||||
ETag: partResult.ETag,
|
||||
...partResult.ChecksumCRC32 && { ChecksumCRC32: partResult.ChecksumCRC32 },
|
||||
...partResult.ChecksumCRC32C && { ChecksumCRC32C: partResult.ChecksumCRC32C },
|
||||
...partResult.ChecksumSHA1 && { ChecksumSHA1: partResult.ChecksumSHA1 },
|
||||
...partResult.ChecksumSHA256 && { ChecksumSHA256: partResult.ChecksumSHA256 }
|
||||
});
|
||||
if (eventEmitter === null) {
|
||||
this.bytesUploadedSoFar += partSize;
|
||||
}
|
||||
this.__notifyProgress({
|
||||
loaded: this.bytesUploadedSoFar,
|
||||
total: this.totalBytes,
|
||||
part: dataPart.partNumber,
|
||||
Key: this.params.Key,
|
||||
Bucket: this.params.Bucket
|
||||
});
|
||||
}
|
||||
}
|
||||
async __doMultipartUpload() {
|
||||
const dataFeeder = getChunk(this.params.Body, this.partSize);
|
||||
const concurrentUploaderFailures = [];
|
||||
for (let index = 0; index < this.queueSize; index++) {
|
||||
const currentUpload = this.__doConcurrentUpload(dataFeeder).catch((err) => {
|
||||
concurrentUploaderFailures.push(err);
|
||||
});
|
||||
this.concurrentUploaders.push(currentUpload);
|
||||
}
|
||||
await Promise.all(this.concurrentUploaders);
|
||||
if (concurrentUploaderFailures.length >= 1) {
|
||||
await this.markUploadAsAborted();
|
||||
throw concurrentUploaderFailures[0];
|
||||
}
|
||||
if (this.abortController.signal.aborted) {
|
||||
await this.markUploadAsAborted();
|
||||
throw Object.assign(new Error("Upload aborted."), { name: "AbortError" });
|
||||
}
|
||||
let result;
|
||||
if (this.isMultiPart) {
|
||||
this.uploadedParts.sort((a, b) => a.PartNumber - b.PartNumber);
|
||||
const uploadCompleteParams = {
|
||||
...this.params,
|
||||
Body: void 0,
|
||||
UploadId: this.uploadId,
|
||||
MultipartUpload: {
|
||||
Parts: this.uploadedParts
|
||||
}
|
||||
};
|
||||
result = await this.client.send(new import_client_s3.CompleteMultipartUploadCommand(uploadCompleteParams));
|
||||
if (typeof result?.Location === "string" && result.Location.includes("%2F")) {
|
||||
result.Location = result.Location.replace(/%2F/g, "/");
|
||||
}
|
||||
} else {
|
||||
result = this.singleUploadResult;
|
||||
}
|
||||
this.abortMultipartUploadCommand = null;
|
||||
if (this.tags.length) {
|
||||
await this.client.send(
|
||||
new import_client_s3.PutObjectTaggingCommand({
|
||||
...this.params,
|
||||
Tagging: {
|
||||
TagSet: this.tags
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Abort the last multipart upload in progress
|
||||
* if we know the upload id, the user did not specify to leave the parts, and
|
||||
* we have a prepared AbortMultipartUpload command.
|
||||
*/
|
||||
async markUploadAsAborted() {
|
||||
if (this.uploadId && !this.leavePartsOnError && null !== this.abortMultipartUploadCommand) {
|
||||
await this.client.send(this.abortMultipartUploadCommand);
|
||||
this.abortMultipartUploadCommand = null;
|
||||
}
|
||||
}
|
||||
__notifyProgress(progress) {
|
||||
if (this.uploadEvent) {
|
||||
this.emit(this.uploadEvent, progress);
|
||||
}
|
||||
}
|
||||
async __abortTimeout(abortSignal) {
|
||||
return new Promise((resolve, reject) => {
|
||||
abortSignal.onabort = () => {
|
||||
const abortError = new Error("Upload aborted.");
|
||||
abortError.name = "AbortError";
|
||||
reject(abortError);
|
||||
};
|
||||
});
|
||||
}
|
||||
__validateInput() {
|
||||
if (!this.params) {
|
||||
throw new Error(`InputError: Upload requires params to be passed to upload.`);
|
||||
}
|
||||
if (!this.client) {
|
||||
throw new Error(`InputError: Upload requires a AWS client to do uploads with.`);
|
||||
}
|
||||
if (this.partSize < _Upload.MIN_PART_SIZE) {
|
||||
throw new Error(
|
||||
`EntityTooSmall: Your proposed upload partsize [${this.partSize}] is smaller than the minimum allowed size [${_Upload.MIN_PART_SIZE}] (5MB)`
|
||||
);
|
||||
}
|
||||
if (this.queueSize < 1) {
|
||||
throw new Error(`Queue size: Must have at least one uploading queue.`);
|
||||
}
|
||||
}
|
||||
};
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
|
||||
0 && (module.exports = {
|
||||
Upload
|
||||
});
|
||||
|
||||
Generated
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ClientDefaultValues = void 0;
|
||||
const runtimeConfig_shared_1 = require("./runtimeConfig.shared");
|
||||
exports.ClientDefaultValues = {
|
||||
...runtimeConfig_shared_1.ClientSharedValues,
|
||||
runtime: "browser",
|
||||
};
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ClientDefaultValues = void 0;
|
||||
const fs_1 = require("fs");
|
||||
const runtimeConfig_shared_1 = require("./runtimeConfig.shared");
|
||||
exports.ClientDefaultValues = {
|
||||
...runtimeConfig_shared_1.ClientSharedValues,
|
||||
runtime: "node",
|
||||
lstatSync: fs_1.lstatSync,
|
||||
};
|
||||
Generated
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ClientDefaultValues = void 0;
|
||||
const runtimeConfig_browser_1 = require("./runtimeConfig.browser");
|
||||
exports.ClientDefaultValues = {
|
||||
...runtimeConfig_browser_1.ClientDefaultValues,
|
||||
runtime: "react-native",
|
||||
};
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ClientSharedValues = void 0;
|
||||
exports.ClientSharedValues = {
|
||||
lstatSync: () => { },
|
||||
};
|
||||
+304
@@ -0,0 +1,304 @@
|
||||
import { AbortMultipartUploadCommand, ChecksumAlgorithm, CompleteMultipartUploadCommand, CreateMultipartUploadCommand, PutObjectCommand, PutObjectTaggingCommand, UploadPartCommand, } from "@aws-sdk/client-s3";
|
||||
import { AbortController } from "@smithy/abort-controller";
|
||||
import { getEndpointFromInstructions, toEndpointV1, } from "@smithy/middleware-endpoint";
|
||||
import { extendedEncodeURIComponent } from "@smithy/smithy-client";
|
||||
import { EventEmitter } from "events";
|
||||
import { byteLength } from "./bytelength";
|
||||
import { getChunk } from "./chunker";
|
||||
export class Upload extends EventEmitter {
|
||||
static MIN_PART_SIZE = 1024 * 1024 * 5;
|
||||
MAX_PARTS = 10_000;
|
||||
queueSize = 4;
|
||||
partSize = Upload.MIN_PART_SIZE;
|
||||
leavePartsOnError = false;
|
||||
tags = [];
|
||||
client;
|
||||
params;
|
||||
totalBytes;
|
||||
bytesUploadedSoFar;
|
||||
abortController;
|
||||
concurrentUploaders = [];
|
||||
createMultiPartPromise;
|
||||
abortMultipartUploadCommand = null;
|
||||
uploadedParts = [];
|
||||
uploadEnqueuedPartsCount = 0;
|
||||
uploadId;
|
||||
uploadEvent;
|
||||
isMultiPart = true;
|
||||
singleUploadResult;
|
||||
sent = false;
|
||||
constructor(options) {
|
||||
super();
|
||||
this.queueSize = options.queueSize || this.queueSize;
|
||||
this.partSize = options.partSize || this.partSize;
|
||||
this.leavePartsOnError = options.leavePartsOnError || this.leavePartsOnError;
|
||||
this.tags = options.tags || this.tags;
|
||||
this.client = options.client;
|
||||
this.params = options.params;
|
||||
this.__validateInput();
|
||||
this.totalBytes = byteLength(this.params.Body);
|
||||
this.bytesUploadedSoFar = 0;
|
||||
this.abortController = options.abortController ?? new AbortController();
|
||||
}
|
||||
async abort() {
|
||||
this.abortController.abort();
|
||||
}
|
||||
async done() {
|
||||
if (this.sent) {
|
||||
throw new Error("@aws-sdk/lib-storage: this instance of Upload has already executed .done(). Create a new instance.");
|
||||
}
|
||||
this.sent = true;
|
||||
return await Promise.race([this.__doMultipartUpload(), this.__abortTimeout(this.abortController.signal)]);
|
||||
}
|
||||
on(event, listener) {
|
||||
this.uploadEvent = event;
|
||||
return super.on(event, listener);
|
||||
}
|
||||
async __uploadUsingPut(dataPart) {
|
||||
this.isMultiPart = false;
|
||||
const params = { ...this.params, Body: dataPart.data };
|
||||
const clientConfig = this.client.config;
|
||||
const requestHandler = clientConfig.requestHandler;
|
||||
const eventEmitter = requestHandler instanceof EventEmitter ? requestHandler : null;
|
||||
const uploadEventListener = (event) => {
|
||||
this.bytesUploadedSoFar = event.loaded;
|
||||
this.totalBytes = event.total;
|
||||
this.__notifyProgress({
|
||||
loaded: this.bytesUploadedSoFar,
|
||||
total: this.totalBytes,
|
||||
part: dataPart.partNumber,
|
||||
Key: this.params.Key,
|
||||
Bucket: this.params.Bucket,
|
||||
});
|
||||
};
|
||||
if (eventEmitter !== null) {
|
||||
eventEmitter.on("xhr.upload.progress", uploadEventListener);
|
||||
}
|
||||
const resolved = await Promise.all([this.client.send(new PutObjectCommand(params)), clientConfig?.endpoint?.()]);
|
||||
const putResult = resolved[0];
|
||||
let endpoint = resolved[1];
|
||||
if (!endpoint) {
|
||||
endpoint = toEndpointV1(await getEndpointFromInstructions(params, PutObjectCommand, {
|
||||
...clientConfig,
|
||||
}));
|
||||
}
|
||||
if (!endpoint) {
|
||||
throw new Error('Could not resolve endpoint from S3 "client.config.endpoint()" nor EndpointsV2.');
|
||||
}
|
||||
if (eventEmitter !== null) {
|
||||
eventEmitter.off("xhr.upload.progress", uploadEventListener);
|
||||
}
|
||||
const locationKey = this.params
|
||||
.Key.split("/")
|
||||
.map((segment) => extendedEncodeURIComponent(segment))
|
||||
.join("/");
|
||||
const locationBucket = extendedEncodeURIComponent(this.params.Bucket);
|
||||
const Location = (() => {
|
||||
const endpointHostnameIncludesBucket = endpoint.hostname.startsWith(`${locationBucket}.`);
|
||||
const forcePathStyle = this.client.config.forcePathStyle;
|
||||
const optionalPort = endpoint.port ? `:${endpoint.port}` : ``;
|
||||
if (forcePathStyle) {
|
||||
return `${endpoint.protocol}//${endpoint.hostname}${optionalPort}/${locationBucket}/${locationKey}`;
|
||||
}
|
||||
if (endpointHostnameIncludesBucket) {
|
||||
return `${endpoint.protocol}//${endpoint.hostname}${optionalPort}/${locationKey}`;
|
||||
}
|
||||
return `${endpoint.protocol}//${locationBucket}.${endpoint.hostname}${optionalPort}/${locationKey}`;
|
||||
})();
|
||||
this.singleUploadResult = {
|
||||
...putResult,
|
||||
Bucket: this.params.Bucket,
|
||||
Key: this.params.Key,
|
||||
Location,
|
||||
};
|
||||
const totalSize = byteLength(dataPart.data);
|
||||
this.__notifyProgress({
|
||||
loaded: totalSize,
|
||||
total: totalSize,
|
||||
part: 1,
|
||||
Key: this.params.Key,
|
||||
Bucket: this.params.Bucket,
|
||||
});
|
||||
}
|
||||
async __createMultipartUpload() {
|
||||
const requestChecksumCalculation = await this.client.config.requestChecksumCalculation();
|
||||
if (!this.createMultiPartPromise) {
|
||||
const createCommandParams = { ...this.params, Body: undefined };
|
||||
if (requestChecksumCalculation === "WHEN_SUPPORTED") {
|
||||
createCommandParams.ChecksumAlgorithm = this.params.ChecksumAlgorithm || ChecksumAlgorithm.CRC32;
|
||||
}
|
||||
this.createMultiPartPromise = this.client
|
||||
.send(new CreateMultipartUploadCommand(createCommandParams))
|
||||
.then((createMpuResponse) => {
|
||||
this.abortMultipartUploadCommand = new AbortMultipartUploadCommand({
|
||||
Bucket: this.params.Bucket,
|
||||
Key: this.params.Key,
|
||||
UploadId: createMpuResponse.UploadId,
|
||||
});
|
||||
return createMpuResponse;
|
||||
});
|
||||
}
|
||||
return this.createMultiPartPromise;
|
||||
}
|
||||
async __doConcurrentUpload(dataFeeder) {
|
||||
for await (const dataPart of dataFeeder) {
|
||||
if (this.uploadEnqueuedPartsCount > this.MAX_PARTS) {
|
||||
throw new Error(`Exceeded ${this.MAX_PARTS} parts in multipart upload to Bucket: ${this.params.Bucket} Key: ${this.params.Key}.`);
|
||||
}
|
||||
if (this.abortController.signal.aborted) {
|
||||
return;
|
||||
}
|
||||
if (dataPart.partNumber === 1 && dataPart.lastPart) {
|
||||
return await this.__uploadUsingPut(dataPart);
|
||||
}
|
||||
if (!this.uploadId) {
|
||||
const { UploadId } = await this.__createMultipartUpload();
|
||||
this.uploadId = UploadId;
|
||||
if (this.abortController.signal.aborted) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const partSize = byteLength(dataPart.data) || 0;
|
||||
const requestHandler = this.client.config.requestHandler;
|
||||
const eventEmitter = requestHandler instanceof EventEmitter ? requestHandler : null;
|
||||
let lastSeenBytes = 0;
|
||||
const uploadEventListener = (event, request) => {
|
||||
const requestPartSize = Number(request.query["partNumber"]) || -1;
|
||||
if (requestPartSize !== dataPart.partNumber) {
|
||||
return;
|
||||
}
|
||||
if (event.total && partSize) {
|
||||
this.bytesUploadedSoFar += event.loaded - lastSeenBytes;
|
||||
lastSeenBytes = event.loaded;
|
||||
}
|
||||
this.__notifyProgress({
|
||||
loaded: this.bytesUploadedSoFar,
|
||||
total: this.totalBytes,
|
||||
part: dataPart.partNumber,
|
||||
Key: this.params.Key,
|
||||
Bucket: this.params.Bucket,
|
||||
});
|
||||
};
|
||||
if (eventEmitter !== null) {
|
||||
eventEmitter.on("xhr.upload.progress", uploadEventListener);
|
||||
}
|
||||
this.uploadEnqueuedPartsCount += 1;
|
||||
const partResult = await this.client.send(new UploadPartCommand({
|
||||
...this.params,
|
||||
ContentLength: undefined,
|
||||
UploadId: this.uploadId,
|
||||
Body: dataPart.data,
|
||||
PartNumber: dataPart.partNumber,
|
||||
}));
|
||||
if (eventEmitter !== null) {
|
||||
eventEmitter.off("xhr.upload.progress", uploadEventListener);
|
||||
}
|
||||
if (this.abortController.signal.aborted) {
|
||||
return;
|
||||
}
|
||||
if (!partResult.ETag) {
|
||||
throw new Error(`Part ${dataPart.partNumber} is missing ETag in UploadPart response. Missing Bucket CORS configuration for ETag header?`);
|
||||
}
|
||||
this.uploadedParts.push({
|
||||
PartNumber: dataPart.partNumber,
|
||||
ETag: partResult.ETag,
|
||||
...(partResult.ChecksumCRC32 && { ChecksumCRC32: partResult.ChecksumCRC32 }),
|
||||
...(partResult.ChecksumCRC32C && { ChecksumCRC32C: partResult.ChecksumCRC32C }),
|
||||
...(partResult.ChecksumSHA1 && { ChecksumSHA1: partResult.ChecksumSHA1 }),
|
||||
...(partResult.ChecksumSHA256 && { ChecksumSHA256: partResult.ChecksumSHA256 }),
|
||||
});
|
||||
if (eventEmitter === null) {
|
||||
this.bytesUploadedSoFar += partSize;
|
||||
}
|
||||
this.__notifyProgress({
|
||||
loaded: this.bytesUploadedSoFar,
|
||||
total: this.totalBytes,
|
||||
part: dataPart.partNumber,
|
||||
Key: this.params.Key,
|
||||
Bucket: this.params.Bucket,
|
||||
});
|
||||
}
|
||||
}
|
||||
async __doMultipartUpload() {
|
||||
const dataFeeder = getChunk(this.params.Body, this.partSize);
|
||||
const concurrentUploaderFailures = [];
|
||||
for (let index = 0; index < this.queueSize; index++) {
|
||||
const currentUpload = this.__doConcurrentUpload(dataFeeder).catch((err) => {
|
||||
concurrentUploaderFailures.push(err);
|
||||
});
|
||||
this.concurrentUploaders.push(currentUpload);
|
||||
}
|
||||
await Promise.all(this.concurrentUploaders);
|
||||
if (concurrentUploaderFailures.length >= 1) {
|
||||
await this.markUploadAsAborted();
|
||||
throw concurrentUploaderFailures[0];
|
||||
}
|
||||
if (this.abortController.signal.aborted) {
|
||||
await this.markUploadAsAborted();
|
||||
throw Object.assign(new Error("Upload aborted."), { name: "AbortError" });
|
||||
}
|
||||
let result;
|
||||
if (this.isMultiPart) {
|
||||
this.uploadedParts.sort((a, b) => a.PartNumber - b.PartNumber);
|
||||
const uploadCompleteParams = {
|
||||
...this.params,
|
||||
Body: undefined,
|
||||
UploadId: this.uploadId,
|
||||
MultipartUpload: {
|
||||
Parts: this.uploadedParts,
|
||||
},
|
||||
};
|
||||
result = await this.client.send(new CompleteMultipartUploadCommand(uploadCompleteParams));
|
||||
if (typeof result?.Location === "string" && result.Location.includes("%2F")) {
|
||||
result.Location = result.Location.replace(/%2F/g, "/");
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = this.singleUploadResult;
|
||||
}
|
||||
this.abortMultipartUploadCommand = null;
|
||||
if (this.tags.length) {
|
||||
await this.client.send(new PutObjectTaggingCommand({
|
||||
...this.params,
|
||||
Tagging: {
|
||||
TagSet: this.tags,
|
||||
},
|
||||
}));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
async markUploadAsAborted() {
|
||||
if (this.uploadId && !this.leavePartsOnError && null !== this.abortMultipartUploadCommand) {
|
||||
await this.client.send(this.abortMultipartUploadCommand);
|
||||
this.abortMultipartUploadCommand = null;
|
||||
}
|
||||
}
|
||||
__notifyProgress(progress) {
|
||||
if (this.uploadEvent) {
|
||||
this.emit(this.uploadEvent, progress);
|
||||
}
|
||||
}
|
||||
async __abortTimeout(abortSignal) {
|
||||
return new Promise((resolve, reject) => {
|
||||
abortSignal.onabort = () => {
|
||||
const abortError = new Error("Upload aborted.");
|
||||
abortError.name = "AbortError";
|
||||
reject(abortError);
|
||||
};
|
||||
});
|
||||
}
|
||||
__validateInput() {
|
||||
if (!this.params) {
|
||||
throw new Error(`InputError: Upload requires params to be passed to upload.`);
|
||||
}
|
||||
if (!this.client) {
|
||||
throw new Error(`InputError: Upload requires a AWS client to do uploads with.`);
|
||||
}
|
||||
if (this.partSize < Upload.MIN_PART_SIZE) {
|
||||
throw new Error(`EntityTooSmall: Your proposed upload partsize [${this.partSize}] is smaller than the minimum allowed size [${Upload.MIN_PART_SIZE}] (5MB)`);
|
||||
}
|
||||
if (this.queueSize < 1) {
|
||||
throw new Error(`Queue size: Must have at least one uploading queue.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import { Buffer } from "buffer";
|
||||
import { ClientDefaultValues } from "./runtimeConfig";
|
||||
export const byteLength = (input) => {
|
||||
if (input === null || input === undefined)
|
||||
return 0;
|
||||
if (typeof input === "string") {
|
||||
return Buffer.byteLength(input);
|
||||
}
|
||||
if (typeof input.byteLength === "number") {
|
||||
return input.byteLength;
|
||||
}
|
||||
else if (typeof input.length === "number") {
|
||||
return input.length;
|
||||
}
|
||||
else if (typeof input.size === "number") {
|
||||
return input.size;
|
||||
}
|
||||
else if (typeof input.path === "string") {
|
||||
try {
|
||||
return ClientDefaultValues.lstatSync(input.path).size;
|
||||
}
|
||||
catch (error) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import { Buffer } from "buffer";
|
||||
import { Readable } from "stream";
|
||||
import { getChunkStream } from "./chunks/getChunkStream";
|
||||
import { getChunkUint8Array } from "./chunks/getChunkUint8Array";
|
||||
import { getDataReadable } from "./chunks/getDataReadable";
|
||||
import { getDataReadableStream } from "./chunks/getDataReadableStream";
|
||||
export const getChunk = (data, partSize) => {
|
||||
if (data instanceof Uint8Array) {
|
||||
return getChunkUint8Array(data, partSize);
|
||||
}
|
||||
if (data instanceof Readable) {
|
||||
return getChunkStream(data, partSize, getDataReadable);
|
||||
}
|
||||
if (data instanceof String || typeof data === "string") {
|
||||
return getChunkUint8Array(Buffer.from(data), partSize);
|
||||
}
|
||||
if (typeof data.stream === "function") {
|
||||
return getChunkStream(data.stream(), partSize, getDataReadableStream);
|
||||
}
|
||||
if (data instanceof ReadableStream) {
|
||||
return getChunkStream(data, partSize, getDataReadableStream);
|
||||
}
|
||||
throw new Error("Body Data is unsupported format, expected data to be one of: string | Uint8Array | Buffer | Readable | ReadableStream | Blob;.");
|
||||
};
|
||||
Generated
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
import { Buffer } from "buffer";
|
||||
export async function* getChunkStream(data, partSize, getNextData) {
|
||||
let partNumber = 1;
|
||||
const currentBuffer = { chunks: [], length: 0 };
|
||||
for await (const datum of getNextData(data)) {
|
||||
currentBuffer.chunks.push(datum);
|
||||
currentBuffer.length += datum.byteLength;
|
||||
while (currentBuffer.length > partSize) {
|
||||
const dataChunk = currentBuffer.chunks.length > 1 ? Buffer.concat(currentBuffer.chunks) : currentBuffer.chunks[0];
|
||||
yield {
|
||||
partNumber,
|
||||
data: dataChunk.subarray(0, partSize),
|
||||
};
|
||||
currentBuffer.chunks = [dataChunk.subarray(partSize)];
|
||||
currentBuffer.length = currentBuffer.chunks[0].byteLength;
|
||||
partNumber += 1;
|
||||
}
|
||||
}
|
||||
yield {
|
||||
partNumber,
|
||||
data: currentBuffer.chunks.length !== 1 ? Buffer.concat(currentBuffer.chunks) : currentBuffer.chunks[0],
|
||||
lastPart: true,
|
||||
};
|
||||
}
|
||||
Generated
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
export async function* getChunkUint8Array(data, partSize) {
|
||||
let partNumber = 1;
|
||||
let startByte = 0;
|
||||
let endByte = partSize;
|
||||
while (endByte < data.byteLength) {
|
||||
yield {
|
||||
partNumber,
|
||||
data: data.subarray(startByte, endByte),
|
||||
};
|
||||
partNumber += 1;
|
||||
startByte = endByte;
|
||||
endByte = startByte + partSize;
|
||||
}
|
||||
yield {
|
||||
partNumber,
|
||||
data: data.subarray(startByte),
|
||||
lastPart: true,
|
||||
};
|
||||
}
|
||||
Generated
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
import { Buffer } from "buffer";
|
||||
export async function* getDataReadable(data) {
|
||||
for await (const chunk of data) {
|
||||
if (Buffer.isBuffer(chunk) || chunk instanceof Uint8Array) {
|
||||
yield chunk;
|
||||
}
|
||||
else {
|
||||
yield Buffer.from(chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
import { Buffer } from "buffer";
|
||||
export async function* getDataReadableStream(data) {
|
||||
const reader = data.getReader();
|
||||
try {
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) {
|
||||
return;
|
||||
}
|
||||
if (Buffer.isBuffer(value) || value instanceof Uint8Array) {
|
||||
yield value;
|
||||
}
|
||||
else {
|
||||
yield Buffer.from(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
reader.releaseLock();
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export * from "./Upload";
|
||||
export * from "./types";
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
import { ClientSharedValues } from "./runtimeConfig.shared";
|
||||
export const ClientDefaultValues = {
|
||||
...ClientSharedValues,
|
||||
runtime: "browser",
|
||||
};
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
import { lstatSync } from "fs";
|
||||
import { ClientSharedValues } from "./runtimeConfig.shared";
|
||||
export const ClientDefaultValues = {
|
||||
...ClientSharedValues,
|
||||
runtime: "node",
|
||||
lstatSync,
|
||||
};
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
import { ClientDefaultValues as BrowserDefaults } from "./runtimeConfig.browser";
|
||||
export const ClientDefaultValues = {
|
||||
...BrowserDefaults,
|
||||
runtime: "react-native",
|
||||
};
|
||||
Generated
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
export const ClientSharedValues = {
|
||||
lstatSync: () => { },
|
||||
};
|
||||
+1
@@ -0,0 +1 @@
|
||||
export {};
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
import { CompleteMultipartUploadCommandOutput } from "@aws-sdk/client-s3";
|
||||
import { EventEmitter } from "events";
|
||||
import { BodyDataTypes, Options, Progress } from "./types";
|
||||
export interface RawDataPart {
|
||||
partNumber: number;
|
||||
data: BodyDataTypes;
|
||||
lastPart?: boolean;
|
||||
}
|
||||
export declare class Upload extends EventEmitter {
|
||||
/**
|
||||
* @internal
|
||||
* modified in testing only.
|
||||
*/
|
||||
private static MIN_PART_SIZE;
|
||||
/**
|
||||
* S3 multipart upload does not allow more than 10,000 parts.
|
||||
*/
|
||||
private MAX_PARTS;
|
||||
private readonly queueSize;
|
||||
private readonly partSize;
|
||||
private readonly leavePartsOnError;
|
||||
private readonly tags;
|
||||
private readonly client;
|
||||
private readonly params;
|
||||
private totalBytes?;
|
||||
private bytesUploadedSoFar;
|
||||
private abortController;
|
||||
private concurrentUploaders;
|
||||
private createMultiPartPromise?;
|
||||
private abortMultipartUploadCommand;
|
||||
private uploadedParts;
|
||||
private uploadEnqueuedPartsCount;
|
||||
/**
|
||||
* Last UploadId if the upload was done with MultipartUpload and not PutObject.
|
||||
*/
|
||||
uploadId?: string;
|
||||
uploadEvent?: string;
|
||||
private isMultiPart;
|
||||
private singleUploadResult?;
|
||||
private sent;
|
||||
constructor(options: Options);
|
||||
abort(): Promise<void>;
|
||||
done(): Promise<CompleteMultipartUploadCommandOutput>;
|
||||
on(event: "httpUploadProgress", listener: (progress: Progress) => void): this;
|
||||
private __uploadUsingPut;
|
||||
private __createMultipartUpload;
|
||||
private __doConcurrentUpload;
|
||||
private __doMultipartUpload;
|
||||
/**
|
||||
* Abort the last multipart upload in progress
|
||||
* if we know the upload id, the user did not specify to leave the parts, and
|
||||
* we have a prepared AbortMultipartUpload command.
|
||||
*/
|
||||
private markUploadAsAborted;
|
||||
private __notifyProgress;
|
||||
private __abortTimeout;
|
||||
private __validateInput;
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
export declare const byteLength: (input: any) => any;
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import { BodyDataTypes } from "./types";
|
||||
import type { RawDataPart } from "./Upload";
|
||||
export declare const getChunk: (data: BodyDataTypes, partSize: number) => AsyncGenerator<RawDataPart, void, undefined>;
|
||||
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
import { RawDataPart } from "../Upload";
|
||||
export declare function getChunkStream<T>(data: T, partSize: number, getNextData: (data: T) => AsyncGenerator<Uint8Array>): AsyncGenerator<RawDataPart, void, undefined>;
|
||||
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
import { RawDataPart } from "../Upload";
|
||||
export declare function getChunkUint8Array(data: Uint8Array, partSize: number): AsyncGenerator<RawDataPart, void, undefined>;
|
||||
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
import { Readable } from "stream";
|
||||
export declare function getDataReadable(data: Readable): AsyncGenerator<Uint8Array>;
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
export declare function getDataReadableStream(data: ReadableStream): AsyncGenerator<Uint8Array>;
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
export * from "./Upload";
|
||||
export * from "./types";
|
||||
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export declare const ClientDefaultValues: {
|
||||
runtime: string;
|
||||
lstatSync: () => void;
|
||||
};
|
||||
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export declare const ClientDefaultValues: {
|
||||
runtime: string;
|
||||
lstatSync: import("fs").StatSyncFn;
|
||||
};
|
||||
Generated
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export declare const ClientDefaultValues: {
|
||||
runtime: string;
|
||||
lstatSync: () => void;
|
||||
};
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export declare const ClientSharedValues: {
|
||||
lstatSync: () => void;
|
||||
};
|
||||
Generated
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
import { CompleteMultipartUploadCommandOutput } from "@aws-sdk/client-s3";
|
||||
import { EventEmitter } from "events";
|
||||
import { BodyDataTypes, Options, Progress } from "./types";
|
||||
export interface RawDataPart {
|
||||
partNumber: number;
|
||||
data: BodyDataTypes;
|
||||
lastPart?: boolean;
|
||||
}
|
||||
export declare class Upload extends EventEmitter {
|
||||
private static MIN_PART_SIZE;
|
||||
private MAX_PARTS;
|
||||
private readonly queueSize;
|
||||
private readonly partSize;
|
||||
private readonly leavePartsOnError;
|
||||
private readonly tags;
|
||||
private readonly client;
|
||||
private readonly params;
|
||||
private totalBytes?;
|
||||
private bytesUploadedSoFar;
|
||||
private abortController;
|
||||
private concurrentUploaders;
|
||||
private createMultiPartPromise?;
|
||||
private abortMultipartUploadCommand;
|
||||
private uploadedParts;
|
||||
private uploadEnqueuedPartsCount;
|
||||
uploadId?: string;
|
||||
uploadEvent?: string;
|
||||
private isMultiPart;
|
||||
private singleUploadResult?;
|
||||
private sent;
|
||||
constructor(options: Options);
|
||||
abort(): Promise<void>;
|
||||
done(): Promise<CompleteMultipartUploadCommandOutput>;
|
||||
on(event: "httpUploadProgress", listener: (progress: Progress) => void): this;
|
||||
private __uploadUsingPut;
|
||||
private __createMultipartUpload;
|
||||
private __doConcurrentUpload;
|
||||
private __doMultipartUpload;
|
||||
private markUploadAsAborted;
|
||||
private __notifyProgress;
|
||||
private __abortTimeout;
|
||||
private __validateInput;
|
||||
}
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
export declare const byteLength: (input: any) => any;
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
import { BodyDataTypes } from "./types";
|
||||
import { RawDataPart } from "./Upload";
|
||||
export declare const getChunk: (
|
||||
data: BodyDataTypes,
|
||||
partSize: number
|
||||
) => AsyncGenerator<RawDataPart, void, undefined>;
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
import { RawDataPart } from "../Upload";
|
||||
export declare function getChunkStream<T>(
|
||||
data: T,
|
||||
partSize: number,
|
||||
getNextData: (data: T) => AsyncGenerator<Uint8Array>
|
||||
): AsyncGenerator<RawDataPart, void, undefined>;
|
||||
Generated
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
import { RawDataPart } from "../Upload";
|
||||
export declare function getChunkUint8Array(
|
||||
data: Uint8Array,
|
||||
partSize: number
|
||||
): AsyncGenerator<RawDataPart, void, undefined>;
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
import { Readable } from "stream";
|
||||
export declare function getDataReadable(
|
||||
data: Readable
|
||||
): AsyncGenerator<Uint8Array>;
|
||||
Generated
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
export declare function getDataReadableStream(
|
||||
data: ReadableStream
|
||||
): AsyncGenerator<Uint8Array>;
|
||||
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
export * from "./Upload";
|
||||
export * from "./types";
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
export declare const ClientDefaultValues: {
|
||||
runtime: string;
|
||||
lstatSync: () => void;
|
||||
};
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
export declare const ClientDefaultValues: {
|
||||
runtime: string;
|
||||
lstatSync: import("fs").StatSyncFn;
|
||||
};
|
||||
Generated
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
export declare const ClientDefaultValues: {
|
||||
runtime: string;
|
||||
lstatSync: () => void;
|
||||
};
|
||||
Generated
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
export declare const ClientSharedValues: {
|
||||
lstatSync: () => void;
|
||||
};
|
||||
Generated
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
import { PutObjectCommandInput, S3Client, Tag } from "@aws-sdk/client-s3";
|
||||
import { AbortController } from "@smithy/types";
|
||||
export interface Progress {
|
||||
loaded?: number;
|
||||
total?: number;
|
||||
part?: number;
|
||||
Key?: string;
|
||||
Bucket?: string;
|
||||
}
|
||||
export type BodyDataTypes = PutObjectCommandInput["Body"];
|
||||
export type ServiceClients = S3Client;
|
||||
export interface Configuration {
|
||||
queueSize: number;
|
||||
partSize: number;
|
||||
leavePartsOnError: boolean;
|
||||
tags: Tag[];
|
||||
abortController?: AbortController;
|
||||
}
|
||||
export interface Options extends Partial<Configuration> {
|
||||
params: PutObjectCommandInput;
|
||||
client: S3Client;
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
import { PutObjectCommandInput, S3Client, Tag } from "@aws-sdk/client-s3";
|
||||
import type { AbortController } from "@smithy/types";
|
||||
export interface Progress {
|
||||
loaded?: number;
|
||||
total?: number;
|
||||
part?: number;
|
||||
Key?: string;
|
||||
Bucket?: string;
|
||||
}
|
||||
export type BodyDataTypes = PutObjectCommandInput["Body"];
|
||||
/**
|
||||
* @deprecated redundant, use {@link S3Client} directly.
|
||||
*/
|
||||
export type ServiceClients = S3Client;
|
||||
export interface Configuration {
|
||||
/**
|
||||
* The size of the concurrent queue manager to upload parts in parallel. Set to 1 for synchronous uploading of parts. Note that the uploader will buffer at most queueSize * partSize bytes into memory at any given time.
|
||||
* default: 4
|
||||
*/
|
||||
queueSize: number;
|
||||
/**
|
||||
* Default: 5 mb
|
||||
* The size in bytes for each individual part to be uploaded. Adjust the part size to ensure the number of parts does not exceed maxTotalParts. See 5mb is the minimum allowed part size.
|
||||
*/
|
||||
partSize: number;
|
||||
/**
|
||||
* Default: false
|
||||
* Whether to abort the multipart upload if an error occurs. Set to true if you want to handle failures manually. If set to false (default)
|
||||
* the upload will drop parts that have failed.
|
||||
*/
|
||||
leavePartsOnError: boolean;
|
||||
/**
|
||||
* The tags to apply to the object.
|
||||
*/
|
||||
tags: Tag[];
|
||||
/**
|
||||
* Optional abort controller for controlling this upload's abort signal externally.
|
||||
*/
|
||||
abortController?: AbortController;
|
||||
}
|
||||
export interface Options extends Partial<Configuration> {
|
||||
/**
|
||||
* This is the data that is uploaded.
|
||||
*/
|
||||
params: PutObjectCommandInput;
|
||||
/**
|
||||
* A service client.
|
||||
* This the target where we upload data.
|
||||
*/
|
||||
client: S3Client;
|
||||
}
|
||||
Generated
Vendored
+62
@@ -0,0 +1,62 @@
|
||||
# Authors
|
||||
|
||||
#### Ordered by first contribution.
|
||||
|
||||
- Romain Beauxis (toots@rastageeks.org)
|
||||
- Tobias Koppers (tobias.koppers@googlemail.com)
|
||||
- Janus (ysangkok@gmail.com)
|
||||
- Rainer Dreyer (rdrey1@gmail.com)
|
||||
- Tõnis Tiigi (tonistiigi@gmail.com)
|
||||
- James Halliday (mail@substack.net)
|
||||
- Michael Williamson (mike@zwobble.org)
|
||||
- elliottcable (github@elliottcable.name)
|
||||
- rafael (rvalle@livelens.net)
|
||||
- Andrew Kelley (superjoe30@gmail.com)
|
||||
- Andreas Madsen (amwebdk@gmail.com)
|
||||
- Mike Brevoort (mike.brevoort@pearson.com)
|
||||
- Brian White (mscdex@mscdex.net)
|
||||
- Feross Aboukhadijeh (feross@feross.org)
|
||||
- Ruben Verborgh (ruben@verborgh.org)
|
||||
- eliang (eliang.cs@gmail.com)
|
||||
- Jesse Tane (jesse.tane@gmail.com)
|
||||
- Alfonso Boza (alfonso@cloud.com)
|
||||
- Mathias Buus (mathiasbuus@gmail.com)
|
||||
- Devon Govett (devongovett@gmail.com)
|
||||
- Daniel Cousens (github@dcousens.com)
|
||||
- Joseph Dykstra (josephdykstra@gmail.com)
|
||||
- Parsha Pourkhomami (parshap+git@gmail.com)
|
||||
- Damjan Košir (damjan.kosir@gmail.com)
|
||||
- daverayment (dave.rayment@gmail.com)
|
||||
- kawanet (u-suke@kawa.net)
|
||||
- Linus Unnebäck (linus@folkdatorn.se)
|
||||
- Nolan Lawson (nolan.lawson@gmail.com)
|
||||
- Calvin Metcalf (calvin.metcalf@gmail.com)
|
||||
- Koki Takahashi (hakatasiloving@gmail.com)
|
||||
- Guy Bedford (guybedford@gmail.com)
|
||||
- Jan Schär (jscissr@gmail.com)
|
||||
- RaulTsc (tomescu.raul@gmail.com)
|
||||
- Matthieu Monsch (monsch@alum.mit.edu)
|
||||
- Dan Ehrenberg (littledan@chromium.org)
|
||||
- Kirill Fomichev (fanatid@ya.ru)
|
||||
- Yusuke Kawasaki (u-suke@kawa.net)
|
||||
- DC (dcposch@dcpos.ch)
|
||||
- John-David Dalton (john.david.dalton@gmail.com)
|
||||
- adventure-yunfei (adventure030@gmail.com)
|
||||
- Emil Bay (github@tixz.dk)
|
||||
- Sam Sudar (sudar.sam@gmail.com)
|
||||
- Volker Mische (volker.mische@gmail.com)
|
||||
- David Walton (support@geekstocks.com)
|
||||
- Сковорода Никита Андреевич (chalkerx@gmail.com)
|
||||
- greenkeeper[bot] (greenkeeper[bot]@users.noreply.github.com)
|
||||
- ukstv (sergey.ukustov@machinomy.com)
|
||||
- Renée Kooi (renee@kooi.me)
|
||||
- ranbochen (ranbochen@qq.com)
|
||||
- Vladimir Borovik (bobahbdb@gmail.com)
|
||||
- greenkeeper[bot] (23040076+greenkeeper[bot]@users.noreply.github.com)
|
||||
- kumavis (aaron@kumavis.me)
|
||||
- Sergey Ukustov (sergey.ukustov@machinomy.com)
|
||||
- Fei Liu (liu.feiwood@gmail.com)
|
||||
- Blaine Bublitz (blaine.bublitz@gmail.com)
|
||||
- Niklas Mischkulnig (mischnic@users.noreply.github.com)
|
||||
|
||||
#### Generated by bin/update-authors.sh.
|
||||
Generated
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) Feross Aboukhadijeh, and other contributors.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
Generated
Vendored
+416
@@ -0,0 +1,416 @@
|
||||
# buffer [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url]
|
||||
|
||||
[travis-image]: https://img.shields.io/travis/feross/buffer/master.svg
|
||||
[travis-url]: https://travis-ci.org/feross/buffer
|
||||
[npm-image]: https://img.shields.io/npm/v/buffer.svg
|
||||
[npm-url]: https://npmjs.org/package/buffer
|
||||
[downloads-image]: https://img.shields.io/npm/dm/buffer.svg
|
||||
[downloads-url]: https://npmjs.org/package/buffer
|
||||
[standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg
|
||||
[standard-url]: https://standardjs.com
|
||||
|
||||
#### The buffer module from [node.js](https://nodejs.org/), for the browser.
|
||||
|
||||
[![saucelabs][saucelabs-image]][saucelabs-url]
|
||||
|
||||
[saucelabs-image]: https://saucelabs.com/browser-matrix/buffer.svg
|
||||
[saucelabs-url]: https://saucelabs.com/u/buffer
|
||||
|
||||
With [browserify](http://browserify.org), simply `require('buffer')` or use the `Buffer` global and you will get this module.
|
||||
|
||||
The goal is to provide an API that is 100% identical to
|
||||
[node's Buffer API](https://nodejs.org/api/buffer.html). Read the
|
||||
[official docs](https://nodejs.org/api/buffer.html) for the full list of properties,
|
||||
instance methods, and class methods that are supported.
|
||||
|
||||
## features
|
||||
|
||||
- Manipulate binary data like a boss, in all browsers!
|
||||
- Super fast. Backed by Typed Arrays (`Uint8Array`/`ArrayBuffer`, not `Object`)
|
||||
- Extremely small bundle size (**6.75KB minified + gzipped**, 51.9KB with comments)
|
||||
- Excellent browser support (Chrome, Firefox, Edge, Safari 9+, IE 11, iOS 9+, Android, etc.)
|
||||
- Preserves Node API exactly, with one minor difference (see below)
|
||||
- Square-bracket `buf[4]` notation works!
|
||||
- Does not modify any browser prototypes or put anything on `window`
|
||||
- Comprehensive test suite (including all buffer tests from node.js core)
|
||||
|
||||
## `buffer` for enterprise
|
||||
|
||||
Available as part of the Tidelift Subscription.
|
||||
|
||||
The maintainers of `buffer` and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-buffer?utm_source=npm-buffer&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
|
||||
|
||||
## install
|
||||
|
||||
To use this module directly (without browserify), install it:
|
||||
|
||||
```bash
|
||||
npm install buffer
|
||||
```
|
||||
|
||||
This module was previously called **native-buffer-browserify**, but please use **buffer**
|
||||
from now on.
|
||||
|
||||
If you do not use a bundler, you can use the [standalone script](https://bundle.run/buffer).
|
||||
|
||||
## usage
|
||||
|
||||
The module's API is identical to node's `Buffer` API. Read the
|
||||
[official docs](https://nodejs.org/api/buffer.html) for the full list of properties,
|
||||
instance methods, and class methods that are supported.
|
||||
|
||||
As mentioned above, `require('buffer')` or use the `Buffer` global with
|
||||
[browserify](http://browserify.org) and this module will automatically be included
|
||||
in your bundle. Almost any npm module will work in the browser, even if it assumes that
|
||||
the node `Buffer` API will be available.
|
||||
|
||||
To depend on this module explicitly (without browserify), require it like this:
|
||||
|
||||
```js
|
||||
var Buffer = require('buffer/').Buffer // note: the trailing slash is important!
|
||||
```
|
||||
|
||||
To require this module explicitly, use `require('buffer/')` which tells the node.js module
|
||||
lookup algorithm (also used by browserify) to use the **npm module** named `buffer`
|
||||
instead of the **node.js core** module named `buffer`!
|
||||
|
||||
|
||||
## how does it work?
|
||||
|
||||
The Buffer constructor returns instances of `Uint8Array` that have their prototype
|
||||
changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of `Uint8Array`,
|
||||
so the returned instances will have all the node `Buffer` methods and the
|
||||
`Uint8Array` methods. Square bracket notation works as expected -- it returns a
|
||||
single octet.
|
||||
|
||||
The `Uint8Array` prototype remains unmodified.
|
||||
|
||||
|
||||
## tracking the latest node api
|
||||
|
||||
This module tracks the Buffer API in the latest (unstable) version of node.js. The Buffer
|
||||
API is considered **stable** in the
|
||||
[node stability index](https://nodejs.org/docs/latest/api/documentation.html#documentation_stability_index),
|
||||
so it is unlikely that there will ever be breaking changes.
|
||||
Nonetheless, when/if the Buffer API changes in node, this module's API will change
|
||||
accordingly.
|
||||
|
||||
## related packages
|
||||
|
||||
- [`buffer-reverse`](https://www.npmjs.com/package/buffer-reverse) - Reverse a buffer
|
||||
- [`buffer-xor`](https://www.npmjs.com/package/buffer-xor) - Bitwise xor a buffer
|
||||
- [`is-buffer`](https://www.npmjs.com/package/is-buffer) - Determine if an object is a Buffer without including the whole `Buffer` package
|
||||
|
||||
## conversion packages
|
||||
|
||||
### convert typed array to buffer
|
||||
|
||||
Use [`typedarray-to-buffer`](https://www.npmjs.com/package/typedarray-to-buffer) to convert any kind of typed array to a `Buffer`. Does not perform a copy, so it's super fast.
|
||||
|
||||
### convert buffer to typed array
|
||||
|
||||
`Buffer` is a subclass of `Uint8Array` (which is a typed array). So there is no need to explicitly convert to typed array. Just use the buffer as a `Uint8Array`.
|
||||
|
||||
### convert blob to buffer
|
||||
|
||||
Use [`blob-to-buffer`](https://www.npmjs.com/package/blob-to-buffer) to convert a `Blob` to a `Buffer`.
|
||||
|
||||
### convert buffer to blob
|
||||
|
||||
To convert a `Buffer` to a `Blob`, use the `Blob` constructor:
|
||||
|
||||
```js
|
||||
var blob = new Blob([ buffer ])
|
||||
```
|
||||
|
||||
Optionally, specify a mimetype:
|
||||
|
||||
```js
|
||||
var blob = new Blob([ buffer ], { type: 'text/html' })
|
||||
```
|
||||
|
||||
### convert arraybuffer to buffer
|
||||
|
||||
To convert an `ArrayBuffer` to a `Buffer`, use the `Buffer.from` function. Does not perform a copy, so it's super fast.
|
||||
|
||||
```js
|
||||
var buffer = Buffer.from(arrayBuffer)
|
||||
```
|
||||
|
||||
### convert buffer to arraybuffer
|
||||
|
||||
To convert a `Buffer` to an `ArrayBuffer`, use the `.buffer` property (which is present on all `Uint8Array` objects):
|
||||
|
||||
```js
|
||||
var arrayBuffer = buffer.buffer.slice(
|
||||
buffer.byteOffset, buffer.byteOffset + buffer.byteLength
|
||||
)
|
||||
```
|
||||
|
||||
Alternatively, use the [`to-arraybuffer`](https://www.npmjs.com/package/to-arraybuffer) module.
|
||||
|
||||
## performance
|
||||
|
||||
See perf tests in `/perf`.
|
||||
|
||||
`BrowserBuffer` is the browser `buffer` module (this repo). `Uint8Array` is included as a
|
||||
sanity check (since `BrowserBuffer` uses `Uint8Array` under the hood, `Uint8Array` will
|
||||
always be at least a bit faster). Finally, `NodeBuffer` is the node.js buffer module,
|
||||
which is included to compare against.
|
||||
|
||||
NOTE: Performance has improved since these benchmarks were taken. PR welcome to update the README.
|
||||
|
||||
### Chrome 38
|
||||
|
||||
| Method | Operations | Accuracy | Sampled | Fastest |
|
||||
|:-------|:-----------|:---------|:--------|:-------:|
|
||||
| BrowserBuffer#bracket-notation | 11,457,464 ops/sec | ±0.86% | 66 | ✓ |
|
||||
| Uint8Array#bracket-notation | 10,824,332 ops/sec | ±0.74% | 65 | |
|
||||
| | | | |
|
||||
| BrowserBuffer#concat | 450,532 ops/sec | ±0.76% | 68 | |
|
||||
| Uint8Array#concat | 1,368,911 ops/sec | ±1.50% | 62 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#copy(16000) | 903,001 ops/sec | ±0.96% | 67 | |
|
||||
| Uint8Array#copy(16000) | 1,422,441 ops/sec | ±1.04% | 66 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#copy(16) | 11,431,358 ops/sec | ±0.46% | 69 | |
|
||||
| Uint8Array#copy(16) | 13,944,163 ops/sec | ±1.12% | 68 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#new(16000) | 106,329 ops/sec | ±6.70% | 44 | |
|
||||
| Uint8Array#new(16000) | 131,001 ops/sec | ±2.85% | 31 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#new(16) | 1,554,491 ops/sec | ±1.60% | 65 | |
|
||||
| Uint8Array#new(16) | 6,623,930 ops/sec | ±1.66% | 65 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#readDoubleBE | 112,830 ops/sec | ±0.51% | 69 | ✓ |
|
||||
| DataView#getFloat64 | 93,500 ops/sec | ±0.57% | 68 | |
|
||||
| | | | |
|
||||
| BrowserBuffer#readFloatBE | 146,678 ops/sec | ±0.95% | 68 | ✓ |
|
||||
| DataView#getFloat32 | 99,311 ops/sec | ±0.41% | 67 | |
|
||||
| | | | |
|
||||
| BrowserBuffer#readUInt32LE | 843,214 ops/sec | ±0.70% | 69 | ✓ |
|
||||
| DataView#getUint32 | 103,024 ops/sec | ±0.64% | 67 | |
|
||||
| | | | |
|
||||
| BrowserBuffer#slice | 1,013,941 ops/sec | ±0.75% | 67 | |
|
||||
| Uint8Array#subarray | 1,903,928 ops/sec | ±0.53% | 67 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#writeFloatBE | 61,387 ops/sec | ±0.90% | 67 | |
|
||||
| DataView#setFloat32 | 141,249 ops/sec | ±0.40% | 66 | ✓ |
|
||||
|
||||
|
||||
### Firefox 33
|
||||
|
||||
| Method | Operations | Accuracy | Sampled | Fastest |
|
||||
|:-------|:-----------|:---------|:--------|:-------:|
|
||||
| BrowserBuffer#bracket-notation | 20,800,421 ops/sec | ±1.84% | 60 | |
|
||||
| Uint8Array#bracket-notation | 20,826,235 ops/sec | ±2.02% | 61 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#concat | 153,076 ops/sec | ±2.32% | 61 | |
|
||||
| Uint8Array#concat | 1,255,674 ops/sec | ±8.65% | 52 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#copy(16000) | 1,105,312 ops/sec | ±1.16% | 63 | |
|
||||
| Uint8Array#copy(16000) | 1,615,911 ops/sec | ±0.55% | 66 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#copy(16) | 16,357,599 ops/sec | ±0.73% | 68 | |
|
||||
| Uint8Array#copy(16) | 31,436,281 ops/sec | ±1.05% | 68 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#new(16000) | 52,995 ops/sec | ±6.01% | 35 | |
|
||||
| Uint8Array#new(16000) | 87,686 ops/sec | ±5.68% | 45 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#new(16) | 252,031 ops/sec | ±1.61% | 66 | |
|
||||
| Uint8Array#new(16) | 8,477,026 ops/sec | ±0.49% | 68 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#readDoubleBE | 99,871 ops/sec | ±0.41% | 69 | |
|
||||
| DataView#getFloat64 | 285,663 ops/sec | ±0.70% | 68 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#readFloatBE | 115,540 ops/sec | ±0.42% | 69 | |
|
||||
| DataView#getFloat32 | 288,722 ops/sec | ±0.82% | 68 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#readUInt32LE | 633,926 ops/sec | ±1.08% | 67 | ✓ |
|
||||
| DataView#getUint32 | 294,808 ops/sec | ±0.79% | 64 | |
|
||||
| | | | |
|
||||
| BrowserBuffer#slice | 349,425 ops/sec | ±0.46% | 69 | |
|
||||
| Uint8Array#subarray | 5,965,819 ops/sec | ±0.60% | 65 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#writeFloatBE | 59,980 ops/sec | ±0.41% | 67 | |
|
||||
| DataView#setFloat32 | 317,634 ops/sec | ±0.63% | 68 | ✓ |
|
||||
|
||||
### Safari 8
|
||||
|
||||
| Method | Operations | Accuracy | Sampled | Fastest |
|
||||
|:-------|:-----------|:---------|:--------|:-------:|
|
||||
| BrowserBuffer#bracket-notation | 10,279,729 ops/sec | ±2.25% | 56 | ✓ |
|
||||
| Uint8Array#bracket-notation | 10,030,767 ops/sec | ±2.23% | 59 | |
|
||||
| | | | |
|
||||
| BrowserBuffer#concat | 144,138 ops/sec | ±1.38% | 65 | |
|
||||
| Uint8Array#concat | 4,950,764 ops/sec | ±1.70% | 63 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#copy(16000) | 1,058,548 ops/sec | ±1.51% | 64 | |
|
||||
| Uint8Array#copy(16000) | 1,409,666 ops/sec | ±1.17% | 65 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#copy(16) | 6,282,529 ops/sec | ±1.88% | 58 | |
|
||||
| Uint8Array#copy(16) | 11,907,128 ops/sec | ±2.87% | 58 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#new(16000) | 101,663 ops/sec | ±3.89% | 57 | |
|
||||
| Uint8Array#new(16000) | 22,050,818 ops/sec | ±6.51% | 46 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#new(16) | 176,072 ops/sec | ±2.13% | 64 | |
|
||||
| Uint8Array#new(16) | 24,385,731 ops/sec | ±5.01% | 51 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#readDoubleBE | 41,341 ops/sec | ±1.06% | 67 | |
|
||||
| DataView#getFloat64 | 322,280 ops/sec | ±0.84% | 68 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#readFloatBE | 46,141 ops/sec | ±1.06% | 65 | |
|
||||
| DataView#getFloat32 | 337,025 ops/sec | ±0.43% | 69 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#readUInt32LE | 151,551 ops/sec | ±1.02% | 66 | |
|
||||
| DataView#getUint32 | 308,278 ops/sec | ±0.94% | 67 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#slice | 197,365 ops/sec | ±0.95% | 66 | |
|
||||
| Uint8Array#subarray | 9,558,024 ops/sec | ±3.08% | 58 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#writeFloatBE | 17,518 ops/sec | ±1.03% | 63 | |
|
||||
| DataView#setFloat32 | 319,751 ops/sec | ±0.48% | 68 | ✓ |
|
||||
|
||||
|
||||
### Node 0.11.14
|
||||
|
||||
| Method | Operations | Accuracy | Sampled | Fastest |
|
||||
|:-------|:-----------|:---------|:--------|:-------:|
|
||||
| BrowserBuffer#bracket-notation | 10,489,828 ops/sec | ±3.25% | 90 | |
|
||||
| Uint8Array#bracket-notation | 10,534,884 ops/sec | ±0.81% | 92 | ✓ |
|
||||
| NodeBuffer#bracket-notation | 10,389,910 ops/sec | ±0.97% | 87 | |
|
||||
| | | | |
|
||||
| BrowserBuffer#concat | 487,830 ops/sec | ±2.58% | 88 | |
|
||||
| Uint8Array#concat | 1,814,327 ops/sec | ±1.28% | 88 | ✓ |
|
||||
| NodeBuffer#concat | 1,636,523 ops/sec | ±1.88% | 73 | |
|
||||
| | | | |
|
||||
| BrowserBuffer#copy(16000) | 1,073,665 ops/sec | ±0.77% | 90 | |
|
||||
| Uint8Array#copy(16000) | 1,348,517 ops/sec | ±0.84% | 89 | ✓ |
|
||||
| NodeBuffer#copy(16000) | 1,289,533 ops/sec | ±0.82% | 93 | |
|
||||
| | | | |
|
||||
| BrowserBuffer#copy(16) | 12,782,706 ops/sec | ±0.74% | 85 | |
|
||||
| Uint8Array#copy(16) | 14,180,427 ops/sec | ±0.93% | 92 | ✓ |
|
||||
| NodeBuffer#copy(16) | 11,083,134 ops/sec | ±1.06% | 89 | |
|
||||
| | | | |
|
||||
| BrowserBuffer#new(16000) | 141,678 ops/sec | ±3.30% | 67 | |
|
||||
| Uint8Array#new(16000) | 161,491 ops/sec | ±2.96% | 60 | |
|
||||
| NodeBuffer#new(16000) | 292,699 ops/sec | ±3.20% | 55 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#new(16) | 1,655,466 ops/sec | ±2.41% | 82 | |
|
||||
| Uint8Array#new(16) | 14,399,926 ops/sec | ±0.91% | 94 | ✓ |
|
||||
| NodeBuffer#new(16) | 3,894,696 ops/sec | ±0.88% | 92 | |
|
||||
| | | | |
|
||||
| BrowserBuffer#readDoubleBE | 109,582 ops/sec | ±0.75% | 93 | ✓ |
|
||||
| DataView#getFloat64 | 91,235 ops/sec | ±0.81% | 90 | |
|
||||
| NodeBuffer#readDoubleBE | 88,593 ops/sec | ±0.96% | 81 | |
|
||||
| | | | |
|
||||
| BrowserBuffer#readFloatBE | 139,854 ops/sec | ±1.03% | 85 | ✓ |
|
||||
| DataView#getFloat32 | 98,744 ops/sec | ±0.80% | 89 | |
|
||||
| NodeBuffer#readFloatBE | 92,769 ops/sec | ±0.94% | 93 | |
|
||||
| | | | |
|
||||
| BrowserBuffer#readUInt32LE | 710,861 ops/sec | ±0.82% | 92 | |
|
||||
| DataView#getUint32 | 117,893 ops/sec | ±0.84% | 91 | |
|
||||
| NodeBuffer#readUInt32LE | 851,412 ops/sec | ±0.72% | 93 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#slice | 1,673,877 ops/sec | ±0.73% | 94 | |
|
||||
| Uint8Array#subarray | 6,919,243 ops/sec | ±0.67% | 90 | ✓ |
|
||||
| NodeBuffer#slice | 4,617,604 ops/sec | ±0.79% | 93 | |
|
||||
| | | | |
|
||||
| BrowserBuffer#writeFloatBE | 66,011 ops/sec | ±0.75% | 93 | |
|
||||
| DataView#setFloat32 | 127,760 ops/sec | ±0.72% | 93 | ✓ |
|
||||
| NodeBuffer#writeFloatBE | 103,352 ops/sec | ±0.83% | 93 | |
|
||||
|
||||
### iojs 1.8.1
|
||||
|
||||
| Method | Operations | Accuracy | Sampled | Fastest |
|
||||
|:-------|:-----------|:---------|:--------|:-------:|
|
||||
| BrowserBuffer#bracket-notation | 10,990,488 ops/sec | ±1.11% | 91 | |
|
||||
| Uint8Array#bracket-notation | 11,268,757 ops/sec | ±0.65% | 97 | |
|
||||
| NodeBuffer#bracket-notation | 11,353,260 ops/sec | ±0.83% | 94 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#concat | 378,954 ops/sec | ±0.74% | 94 | |
|
||||
| Uint8Array#concat | 1,358,288 ops/sec | ±0.97% | 87 | |
|
||||
| NodeBuffer#concat | 1,934,050 ops/sec | ±1.11% | 78 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#copy(16000) | 894,538 ops/sec | ±0.56% | 84 | |
|
||||
| Uint8Array#copy(16000) | 1,442,656 ops/sec | ±0.71% | 96 | |
|
||||
| NodeBuffer#copy(16000) | 1,457,898 ops/sec | ±0.53% | 92 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#copy(16) | 12,870,457 ops/sec | ±0.67% | 95 | |
|
||||
| Uint8Array#copy(16) | 16,643,989 ops/sec | ±0.61% | 93 | ✓ |
|
||||
| NodeBuffer#copy(16) | 14,885,848 ops/sec | ±0.74% | 94 | |
|
||||
| | | | |
|
||||
| BrowserBuffer#new(16000) | 109,264 ops/sec | ±4.21% | 63 | |
|
||||
| Uint8Array#new(16000) | 138,916 ops/sec | ±1.87% | 61 | |
|
||||
| NodeBuffer#new(16000) | 281,449 ops/sec | ±3.58% | 51 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#new(16) | 1,362,935 ops/sec | ±0.56% | 99 | |
|
||||
| Uint8Array#new(16) | 6,193,090 ops/sec | ±0.64% | 95 | ✓ |
|
||||
| NodeBuffer#new(16) | 4,745,425 ops/sec | ±1.56% | 90 | |
|
||||
| | | | |
|
||||
| BrowserBuffer#readDoubleBE | 118,127 ops/sec | ±0.59% | 93 | ✓ |
|
||||
| DataView#getFloat64 | 107,332 ops/sec | ±0.65% | 91 | |
|
||||
| NodeBuffer#readDoubleBE | 116,274 ops/sec | ±0.94% | 95 | |
|
||||
| | | | |
|
||||
| BrowserBuffer#readFloatBE | 150,326 ops/sec | ±0.58% | 95 | ✓ |
|
||||
| DataView#getFloat32 | 110,541 ops/sec | ±0.57% | 98 | |
|
||||
| NodeBuffer#readFloatBE | 121,599 ops/sec | ±0.60% | 87 | |
|
||||
| | | | |
|
||||
| BrowserBuffer#readUInt32LE | 814,147 ops/sec | ±0.62% | 93 | |
|
||||
| DataView#getUint32 | 137,592 ops/sec | ±0.64% | 90 | |
|
||||
| NodeBuffer#readUInt32LE | 931,650 ops/sec | ±0.71% | 96 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#slice | 878,590 ops/sec | ±0.68% | 93 | |
|
||||
| Uint8Array#subarray | 2,843,308 ops/sec | ±1.02% | 90 | |
|
||||
| NodeBuffer#slice | 4,998,316 ops/sec | ±0.68% | 90 | ✓ |
|
||||
| | | | |
|
||||
| BrowserBuffer#writeFloatBE | 65,927 ops/sec | ±0.74% | 93 | |
|
||||
| DataView#setFloat32 | 139,823 ops/sec | ±0.97% | 89 | ✓ |
|
||||
| NodeBuffer#writeFloatBE | 135,763 ops/sec | ±0.65% | 96 | |
|
||||
| | | | |
|
||||
|
||||
## Testing the project
|
||||
|
||||
First, install the project:
|
||||
|
||||
npm install
|
||||
|
||||
Then, to run tests in Node.js, run:
|
||||
|
||||
npm run test-node
|
||||
|
||||
To test locally in a browser, you can run:
|
||||
|
||||
npm run test-browser-es5-local # For ES5 browsers that don't support ES6
|
||||
npm run test-browser-es6-local # For ES6 compliant browsers
|
||||
|
||||
This will print out a URL that you can then open in a browser to run the tests, using [airtap](https://www.npmjs.com/package/airtap).
|
||||
|
||||
To run automated browser tests using Saucelabs, ensure that your `SAUCE_USERNAME` and `SAUCE_ACCESS_KEY` environment variables are set, then run:
|
||||
|
||||
npm test
|
||||
|
||||
This is what's run in Travis, to check against various browsers. The list of browsers is kept in the `bin/airtap-es5.yml` and `bin/airtap-es6.yml` files.
|
||||
|
||||
## JavaScript Standard Style
|
||||
|
||||
This module uses [JavaScript Standard Style](https://github.com/feross/standard).
|
||||
|
||||
[](https://github.com/feross/standard)
|
||||
|
||||
To test that the code conforms to the style, `npm install` and run:
|
||||
|
||||
./node_modules/.bin/standard
|
||||
|
||||
## credit
|
||||
|
||||
This was originally forked from [buffer-browserify](https://github.com/toots/buffer-browserify).
|
||||
|
||||
## Security Policies and Procedures
|
||||
|
||||
The `buffer` team and community take all security bugs in `buffer` seriously. Please see our [security policies and procedures](https://github.com/feross/security) document to learn how to report issues.
|
||||
|
||||
## license
|
||||
|
||||
MIT. Copyright (C) [Feross Aboukhadijeh](http://feross.org), and other contributors. Originally forked from an MIT-licensed module by Romain Beauxis.
|
||||
Generated
Vendored
+186
@@ -0,0 +1,186 @@
|
||||
export class Buffer extends Uint8Array {
|
||||
length: number
|
||||
write(string: string, offset?: number, length?: number, encoding?: string): number;
|
||||
toString(encoding?: string, start?: number, end?: number): string;
|
||||
toJSON(): { type: 'Buffer', data: any[] };
|
||||
equals(otherBuffer: Buffer): boolean;
|
||||
compare(otherBuffer: Buffer, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): number;
|
||||
copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number;
|
||||
slice(start?: number, end?: number): Buffer;
|
||||
writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
|
||||
writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
|
||||
writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
|
||||
writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
|
||||
readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number;
|
||||
readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number;
|
||||
readIntLE(offset: number, byteLength: number, noAssert?: boolean): number;
|
||||
readIntBE(offset: number, byteLength: number, noAssert?: boolean): number;
|
||||
readUInt8(offset: number, noAssert?: boolean): number;
|
||||
readUInt16LE(offset: number, noAssert?: boolean): number;
|
||||
readUInt16BE(offset: number, noAssert?: boolean): number;
|
||||
readUInt32LE(offset: number, noAssert?: boolean): number;
|
||||
readUInt32BE(offset: number, noAssert?: boolean): number;
|
||||
readInt8(offset: number, noAssert?: boolean): number;
|
||||
readInt16LE(offset: number, noAssert?: boolean): number;
|
||||
readInt16BE(offset: number, noAssert?: boolean): number;
|
||||
readInt32LE(offset: number, noAssert?: boolean): number;
|
||||
readInt32BE(offset: number, noAssert?: boolean): number;
|
||||
readFloatLE(offset: number, noAssert?: boolean): number;
|
||||
readFloatBE(offset: number, noAssert?: boolean): number;
|
||||
readDoubleLE(offset: number, noAssert?: boolean): number;
|
||||
readDoubleBE(offset: number, noAssert?: boolean): number;
|
||||
reverse(): this;
|
||||
swap16(): Buffer;
|
||||
swap32(): Buffer;
|
||||
swap64(): Buffer;
|
||||
writeUInt8(value: number, offset: number, noAssert?: boolean): number;
|
||||
writeUInt16LE(value: number, offset: number, noAssert?: boolean): number;
|
||||
writeUInt16BE(value: number, offset: number, noAssert?: boolean): number;
|
||||
writeUInt32LE(value: number, offset: number, noAssert?: boolean): number;
|
||||
writeUInt32BE(value: number, offset: number, noAssert?: boolean): number;
|
||||
writeInt8(value: number, offset: number, noAssert?: boolean): number;
|
||||
writeInt16LE(value: number, offset: number, noAssert?: boolean): number;
|
||||
writeInt16BE(value: number, offset: number, noAssert?: boolean): number;
|
||||
writeInt32LE(value: number, offset: number, noAssert?: boolean): number;
|
||||
writeInt32BE(value: number, offset: number, noAssert?: boolean): number;
|
||||
writeFloatLE(value: number, offset: number, noAssert?: boolean): number;
|
||||
writeFloatBE(value: number, offset: number, noAssert?: boolean): number;
|
||||
writeDoubleLE(value: number, offset: number, noAssert?: boolean): number;
|
||||
writeDoubleBE(value: number, offset: number, noAssert?: boolean): number;
|
||||
fill(value: any, offset?: number, end?: number): this;
|
||||
indexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number;
|
||||
lastIndexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number;
|
||||
includes(value: string | number | Buffer, byteOffset?: number, encoding?: string): boolean;
|
||||
|
||||
/**
|
||||
* Allocates a new buffer containing the given {str}.
|
||||
*
|
||||
* @param str String to store in buffer.
|
||||
* @param encoding encoding to use, optional. Default is 'utf8'
|
||||
*/
|
||||
constructor (str: string, encoding?: string);
|
||||
/**
|
||||
* Allocates a new buffer of {size} octets.
|
||||
*
|
||||
* @param size count of octets to allocate.
|
||||
*/
|
||||
constructor (size: number);
|
||||
/**
|
||||
* Allocates a new buffer containing the given {array} of octets.
|
||||
*
|
||||
* @param array The octets to store.
|
||||
*/
|
||||
constructor (array: Uint8Array);
|
||||
/**
|
||||
* Produces a Buffer backed by the same allocated memory as
|
||||
* the given {ArrayBuffer}.
|
||||
*
|
||||
*
|
||||
* @param arrayBuffer The ArrayBuffer with which to share memory.
|
||||
*/
|
||||
constructor (arrayBuffer: ArrayBuffer);
|
||||
/**
|
||||
* Allocates a new buffer containing the given {array} of octets.
|
||||
*
|
||||
* @param array The octets to store.
|
||||
*/
|
||||
constructor (array: any[]);
|
||||
/**
|
||||
* Copies the passed {buffer} data onto a new {Buffer} instance.
|
||||
*
|
||||
* @param buffer The buffer to copy.
|
||||
*/
|
||||
constructor (buffer: Buffer);
|
||||
prototype: Buffer;
|
||||
/**
|
||||
* Allocates a new Buffer using an {array} of octets.
|
||||
*
|
||||
* @param array
|
||||
*/
|
||||
static from(array: any[]): Buffer;
|
||||
/**
|
||||
* When passed a reference to the .buffer property of a TypedArray instance,
|
||||
* the newly created Buffer will share the same allocated memory as the TypedArray.
|
||||
* The optional {byteOffset} and {length} arguments specify a memory range
|
||||
* within the {arrayBuffer} that will be shared by the Buffer.
|
||||
*
|
||||
* @param arrayBuffer The .buffer property of a TypedArray or a new ArrayBuffer()
|
||||
* @param byteOffset
|
||||
* @param length
|
||||
*/
|
||||
static from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer;
|
||||
/**
|
||||
* Copies the passed {buffer} data onto a new Buffer instance.
|
||||
*
|
||||
* @param buffer
|
||||
*/
|
||||
static from(buffer: Buffer | Uint8Array): Buffer;
|
||||
/**
|
||||
* Creates a new Buffer containing the given JavaScript string {str}.
|
||||
* If provided, the {encoding} parameter identifies the character encoding.
|
||||
* If not provided, {encoding} defaults to 'utf8'.
|
||||
*
|
||||
* @param str
|
||||
*/
|
||||
static from(str: string, encoding?: string): Buffer;
|
||||
/**
|
||||
* Returns true if {obj} is a Buffer
|
||||
*
|
||||
* @param obj object to test.
|
||||
*/
|
||||
static isBuffer(obj: any): obj is Buffer;
|
||||
/**
|
||||
* Returns true if {encoding} is a valid encoding argument.
|
||||
* Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex'
|
||||
*
|
||||
* @param encoding string to test.
|
||||
*/
|
||||
static isEncoding(encoding: string): boolean;
|
||||
/**
|
||||
* Gives the actual byte length of a string. encoding defaults to 'utf8'.
|
||||
* This is not the same as String.prototype.length since that returns the number of characters in a string.
|
||||
*
|
||||
* @param string string to test.
|
||||
* @param encoding encoding used to evaluate (defaults to 'utf8')
|
||||
*/
|
||||
static byteLength(string: string, encoding?: string): number;
|
||||
/**
|
||||
* Returns a buffer which is the result of concatenating all the buffers in the list together.
|
||||
*
|
||||
* If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer.
|
||||
* If the list has exactly one item, then the first item of the list is returned.
|
||||
* If the list has more than one item, then a new Buffer is created.
|
||||
*
|
||||
* @param list An array of Buffer objects to concatenate
|
||||
* @param totalLength Total length of the buffers when concatenated.
|
||||
* If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly.
|
||||
*/
|
||||
static concat(list: Buffer[], totalLength?: number): Buffer;
|
||||
/**
|
||||
* The same as buf1.compare(buf2).
|
||||
*/
|
||||
static compare(buf1: Buffer, buf2: Buffer): number;
|
||||
/**
|
||||
* Allocates a new buffer of {size} octets.
|
||||
*
|
||||
* @param size count of octets to allocate.
|
||||
* @param fill if specified, buffer will be initialized by calling buf.fill(fill).
|
||||
* If parameter is omitted, buffer will be filled with zeros.
|
||||
* @param encoding encoding used for call to buf.fill while initalizing
|
||||
*/
|
||||
static alloc(size: number, fill?: string | Buffer | number, encoding?: string): Buffer;
|
||||
/**
|
||||
* Allocates a new buffer of {size} octets, leaving memory not initialized, so the contents
|
||||
* of the newly created Buffer are unknown and may contain sensitive data.
|
||||
*
|
||||
* @param size count of octets to allocate
|
||||
*/
|
||||
static allocUnsafe(size: number): Buffer;
|
||||
/**
|
||||
* Allocates a new non-pooled buffer of {size} octets, leaving memory not initialized, so the contents
|
||||
* of the newly created Buffer are unknown and may contain sensitive data.
|
||||
*
|
||||
* @param size count of octets to allocate
|
||||
*/
|
||||
static allocUnsafeSlow(size: number): Buffer;
|
||||
}
|
||||
Generated
Vendored
+1794
File diff suppressed because it is too large
Load Diff
Generated
Vendored
+82
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"name": "buffer",
|
||||
"description": "Node.js Buffer API, for the browser",
|
||||
"version": "5.6.0",
|
||||
"author": {
|
||||
"name": "Feross Aboukhadijeh",
|
||||
"email": "feross@feross.org",
|
||||
"url": "http://feross.org"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/feross/buffer/issues"
|
||||
},
|
||||
"contributors": [
|
||||
"Romain Beauxis <toots@rastageeks.org>",
|
||||
"James Halliday <mail@substack.net>"
|
||||
],
|
||||
"dependencies": {
|
||||
"base64-js": "^1.0.2",
|
||||
"ieee754": "^1.1.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"airtap": "^3.0.0",
|
||||
"benchmark": "^2.0.0",
|
||||
"browserify": "^16.1.0",
|
||||
"concat-stream": "^2.0.0",
|
||||
"hyperquest": "^2.0.0",
|
||||
"is-buffer": "^2.0.0",
|
||||
"is-nan": "^1.0.1",
|
||||
"split": "^1.0.0",
|
||||
"standard": "*",
|
||||
"tape": "^4.0.0",
|
||||
"through2": "^3.0.1",
|
||||
"uglify-js": "^3.4.5"
|
||||
},
|
||||
"homepage": "https://github.com/feross/buffer",
|
||||
"jspm": {
|
||||
"map": {
|
||||
"./index.js": {
|
||||
"node": "@node/buffer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"keywords": [
|
||||
"arraybuffer",
|
||||
"browser",
|
||||
"browserify",
|
||||
"buffer",
|
||||
"compatible",
|
||||
"dataview",
|
||||
"uint8array"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/feross/buffer.git"
|
||||
},
|
||||
"scripts": {
|
||||
"perf": "browserify --debug perf/bracket-notation.js > perf/bundle.js && open perf/index.html",
|
||||
"perf-node": "node perf/bracket-notation.js && node perf/concat.js && node perf/copy-big.js && node perf/copy.js && node perf/new-big.js && node perf/new.js && node perf/readDoubleBE.js && node perf/readFloatBE.js && node perf/readUInt32LE.js && node perf/slice.js && node perf/writeFloatBE.js",
|
||||
"size": "browserify -r ./ | uglifyjs -c -m | gzip | wc -c",
|
||||
"test": "standard && node ./bin/test.js",
|
||||
"test-browser-es5": "airtap -- test/*.js",
|
||||
"test-browser-es5-local": "airtap --local -- test/*.js",
|
||||
"test-browser-es6": "airtap -- test/*.js test/node/*.js",
|
||||
"test-browser-es6-local": "airtap --local -- test/*.js test/node/*.js",
|
||||
"test-node": "tape test/*.js test/node/*.js",
|
||||
"update-authors": "./bin/update-authors.sh"
|
||||
},
|
||||
"standard": {
|
||||
"ignore": [
|
||||
"test/node/**/*.js",
|
||||
"test/common.js",
|
||||
"test/_polyfill.js",
|
||||
"perf/**/*.js"
|
||||
],
|
||||
"globals": [
|
||||
"SharedArrayBuffer"
|
||||
]
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
sauce_connect: true
|
||||
loopback: airtap.local
|
||||
browsers:
|
||||
- name: chrome
|
||||
version: latest
|
||||
- name: firefox
|
||||
version: latest
|
||||
- name: safari
|
||||
version: 9..latest
|
||||
- name: iphone
|
||||
version: latest
|
||||
- name: ie
|
||||
version: 9..latest
|
||||
- name: microsoftedge
|
||||
version: 13..latest
|
||||
Generated
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: npm/events
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
Generated
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
dist: xenial
|
||||
os: linux
|
||||
language: node_js
|
||||
node_js:
|
||||
- 'stable'
|
||||
- 'lts/*'
|
||||
- '0.12'
|
||||
script:
|
||||
- npm test
|
||||
- if [ "${TRAVIS_PULL_REQUEST}" = "false" ] && [ "${TRAVIS_NODE_VERSION}" = "stable" ]; then npm run test:browsers; fi
|
||||
addons:
|
||||
sauce_connect: true
|
||||
hosts:
|
||||
- airtap.local
|
||||
env:
|
||||
global:
|
||||
- secure: XcBiD8yReflut9q7leKsigDZ0mI3qTKH+QrNVY8DaqlomJOZw8aOrVuX9Jz12l86ZJ41nbxmKnRNkFzcVr9mbP9YaeTb3DpeOBWmvaoSfud9Wnc16VfXtc1FCcwDhSVcSiM3UtnrmFU5cH+Dw1LPh5PbfylYOS/nJxUvG0FFLqI=
|
||||
- secure: jNWtEbqhUdQ0xXDHvCYfUbKYeJCi6a7B4LsrcxYCyWWn4NIgncE5x2YbB+FSUUFVYfz0dsn5RKP1oHB99f0laUEo18HBNkrAS/rtyOdVzcpJjbQ6kgSILGjnJD/Ty1B57Rcz3iyev5Y7bLZ6Y1FbDnk/i9/l0faOGz8vTC3Vdkc=
|
||||
Generated
Vendored
+118
@@ -0,0 +1,118 @@
|
||||
# 3.3.0
|
||||
|
||||
- Support EventTarget emitters in `events.once` from Node.js 12.11.0.
|
||||
|
||||
Now you can use the `events.once` function with objects that implement the EventTarget interface. This interface is used widely in
|
||||
the DOM and other web APIs.
|
||||
|
||||
```js
|
||||
var events = require('events');
|
||||
var assert = require('assert');
|
||||
|
||||
async function connect() {
|
||||
var ws = new WebSocket('wss://example.com');
|
||||
await events.once(ws, 'open');
|
||||
assert(ws.readyState === WebSocket.OPEN);
|
||||
}
|
||||
|
||||
async function onClick() {
|
||||
await events.once(document.body, 'click');
|
||||
alert('you clicked the page!');
|
||||
}
|
||||
```
|
||||
|
||||
# 3.2.0
|
||||
|
||||
- Add `events.once` from Node.js 11.13.0.
|
||||
|
||||
To use this function, Promises must be supported in the environment. Use a polyfill like `es6-promise` if you support older browsers.
|
||||
|
||||
# 3.1.0 (2020-01-08)
|
||||
|
||||
`events` now matches the Node.js 11.12.0 API.
|
||||
|
||||
- pass through return value in wrapped `emitter.once()` listeners
|
||||
|
||||
Now, this works:
|
||||
```js
|
||||
emitter.once('myevent', function () { return 1; });
|
||||
var listener = emitter.rawListeners('myevent')[0]
|
||||
assert(listener() === 1);
|
||||
```
|
||||
Previously, `listener()` would return undefined regardless of the implementation.
|
||||
|
||||
Ported from https://github.com/nodejs/node/commit/acc506c2d2771dab8d7bba6d3452bc5180dff7cf
|
||||
|
||||
- Reduce code duplication in listener type check ([#67](https://github.com/Gozala/events/pull/67) by [@friederbluemle](https://github.com/friederbluemle)).
|
||||
- Improve `emitter.once()` performance in some engines
|
||||
|
||||
# 3.0.0 (2018-05-25)
|
||||
|
||||
**This version drops support for IE8.** `events` no longer includes polyfills
|
||||
for ES5 features. If you need to support older environments, use an ES5 shim
|
||||
like [es5-shim](https://npmjs.com/package/es5-shim). Both the shim and sham
|
||||
versions of es5-shim are necessary.
|
||||
|
||||
- Update to events code from Node.js 10.x
|
||||
- (semver major) Adds `off()` method
|
||||
- Port more tests from Node.js
|
||||
- Switch browser tests to airtap, making things more reliable
|
||||
|
||||
# 2.1.0 (2018-05-25)
|
||||
|
||||
- add Emitter#rawListeners from Node.js v9.4
|
||||
|
||||
# 2.0.0 (2018-02-02)
|
||||
|
||||
- Update to events code from node.js 8.x
|
||||
- Adds `prependListener()` and `prependOnceListener()`
|
||||
- Adds `eventNames()` method
|
||||
- (semver major) Unwrap `once()` listeners in `listeners()`
|
||||
- copy tests from node.js
|
||||
|
||||
Note that this version doubles the gzipped size, jumping from 1.1KB to 2.1KB,
|
||||
due to new methods and runtime performance improvements. Be aware of that when
|
||||
upgrading.
|
||||
|
||||
# 1.1.1 (2016-06-22)
|
||||
|
||||
- add more context to errors if they are not instanceof Error
|
||||
|
||||
# 1.1.0 (2015-09-29)
|
||||
|
||||
- add Emitter#listerCount (to match node v4 api)
|
||||
|
||||
# 1.0.2 (2014-08-28)
|
||||
|
||||
- remove un-reachable code
|
||||
- update devDeps
|
||||
|
||||
## 1.0.1 / 2014-05-11
|
||||
|
||||
- check for console.trace before using it
|
||||
|
||||
## 1.0.0 / 2013-12-10
|
||||
|
||||
- Update to latest events code from node.js 0.10
|
||||
- copy tests from node.js
|
||||
|
||||
## 0.4.0 / 2011-07-03 ##
|
||||
|
||||
- Switching to graphquire@0.8.0
|
||||
|
||||
## 0.3.0 / 2011-07-03 ##
|
||||
|
||||
- Switching to URL based module require.
|
||||
|
||||
## 0.2.0 / 2011-06-10 ##
|
||||
|
||||
- Simplified package structure.
|
||||
- Graphquire for dependency management.
|
||||
|
||||
## 0.1.1 / 2011-05-16 ##
|
||||
|
||||
- Unhandled errors are logged via console.error
|
||||
|
||||
## 0.1.0 / 2011-04-22 ##
|
||||
|
||||
- Initial release
|
||||
Generated
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
MIT
|
||||
|
||||
Copyright Joyent, Inc. and other Node contributors.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
Generated
Vendored
+50
@@ -0,0 +1,50 @@
|
||||
# events [](https://travis-ci.org/Gozala/events)
|
||||
|
||||
> Node's event emitter for all engines.
|
||||
|
||||
This implements the Node.js [`events`][node.js docs] module for environments that do not have it, like browsers.
|
||||
|
||||
> `events` currently matches the **Node.js 11.13.0** API.
|
||||
|
||||
Note that the `events` module uses ES5 features. If you need to support very old browsers like IE8, use a shim like [`es5-shim`](https://www.npmjs.com/package/es5-shim). You need both the shim and the sham versions of `es5-shim`.
|
||||
|
||||
This module is maintained, but only by very few people. If you'd like to help, let us know in the [Maintainer Needed](https://github.com/Gozala/events/issues/43) issue!
|
||||
|
||||
## Install
|
||||
|
||||
You usually do not have to install `events` yourself! If your code runs in Node.js, `events` is built in. If your code runs in the browser, bundlers like [browserify](https://github.com/browserify/browserify) or [webpack](https://github.com/webpack/webpack) also include the `events` module.
|
||||
|
||||
But if none of those apply, with npm do:
|
||||
|
||||
```
|
||||
npm install events
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
var EventEmitter = require('events')
|
||||
|
||||
var ee = new EventEmitter()
|
||||
ee.on('message', function (text) {
|
||||
console.log(text)
|
||||
})
|
||||
ee.emit('message', 'hello world')
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
See the [Node.js EventEmitter docs][node.js docs]. `events` currently matches the Node.js 11.13.0 API.
|
||||
|
||||
## Contributing
|
||||
|
||||
PRs are very welcome! The main way to contribute to `events` is by porting features, bugfixes and tests from Node.js. Ideally, code contributions to this module are copy-pasted from Node.js and transpiled to ES5, rather than reimplemented from scratch. Matching the Node.js code as closely as possible makes maintenance simpler when new changes land in Node.js.
|
||||
This module intends to provide exactly the same API as Node.js, so features that are not available in the core `events` module will not be accepted. Feature requests should instead be directed at [nodejs/node](https://github.com/nodejs/node) and will be added to this module once they are implemented in Node.js.
|
||||
|
||||
If there is a difference in behaviour between Node.js's `events` module and this module, please open an issue!
|
||||
|
||||
## License
|
||||
|
||||
[MIT](./LICENSE)
|
||||
|
||||
[node.js docs]: https://nodejs.org/dist/v11.13.0/docs/api/events.html
|
||||
Generated
Vendored
+497
@@ -0,0 +1,497 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
|
||||
var R = typeof Reflect === 'object' ? Reflect : null
|
||||
var ReflectApply = R && typeof R.apply === 'function'
|
||||
? R.apply
|
||||
: function ReflectApply(target, receiver, args) {
|
||||
return Function.prototype.apply.call(target, receiver, args);
|
||||
}
|
||||
|
||||
var ReflectOwnKeys
|
||||
if (R && typeof R.ownKeys === 'function') {
|
||||
ReflectOwnKeys = R.ownKeys
|
||||
} else if (Object.getOwnPropertySymbols) {
|
||||
ReflectOwnKeys = function ReflectOwnKeys(target) {
|
||||
return Object.getOwnPropertyNames(target)
|
||||
.concat(Object.getOwnPropertySymbols(target));
|
||||
};
|
||||
} else {
|
||||
ReflectOwnKeys = function ReflectOwnKeys(target) {
|
||||
return Object.getOwnPropertyNames(target);
|
||||
};
|
||||
}
|
||||
|
||||
function ProcessEmitWarning(warning) {
|
||||
if (console && console.warn) console.warn(warning);
|
||||
}
|
||||
|
||||
var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
|
||||
return value !== value;
|
||||
}
|
||||
|
||||
function EventEmitter() {
|
||||
EventEmitter.init.call(this);
|
||||
}
|
||||
module.exports = EventEmitter;
|
||||
module.exports.once = once;
|
||||
|
||||
// Backwards-compat with node 0.10.x
|
||||
EventEmitter.EventEmitter = EventEmitter;
|
||||
|
||||
EventEmitter.prototype._events = undefined;
|
||||
EventEmitter.prototype._eventsCount = 0;
|
||||
EventEmitter.prototype._maxListeners = undefined;
|
||||
|
||||
// By default EventEmitters will print a warning if more than 10 listeners are
|
||||
// added to it. This is a useful default which helps finding memory leaks.
|
||||
var defaultMaxListeners = 10;
|
||||
|
||||
function checkListener(listener) {
|
||||
if (typeof listener !== 'function') {
|
||||
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return defaultMaxListeners;
|
||||
},
|
||||
set: function(arg) {
|
||||
if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
|
||||
throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
|
||||
}
|
||||
defaultMaxListeners = arg;
|
||||
}
|
||||
});
|
||||
|
||||
EventEmitter.init = function() {
|
||||
|
||||
if (this._events === undefined ||
|
||||
this._events === Object.getPrototypeOf(this)._events) {
|
||||
this._events = Object.create(null);
|
||||
this._eventsCount = 0;
|
||||
}
|
||||
|
||||
this._maxListeners = this._maxListeners || undefined;
|
||||
};
|
||||
|
||||
// Obviously not all Emitters should be limited to 10. This function allows
|
||||
// that to be increased. Set to zero for unlimited.
|
||||
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
|
||||
if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
|
||||
throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
|
||||
}
|
||||
this._maxListeners = n;
|
||||
return this;
|
||||
};
|
||||
|
||||
function _getMaxListeners(that) {
|
||||
if (that._maxListeners === undefined)
|
||||
return EventEmitter.defaultMaxListeners;
|
||||
return that._maxListeners;
|
||||
}
|
||||
|
||||
EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
|
||||
return _getMaxListeners(this);
|
||||
};
|
||||
|
||||
EventEmitter.prototype.emit = function emit(type) {
|
||||
var args = [];
|
||||
for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
|
||||
var doError = (type === 'error');
|
||||
|
||||
var events = this._events;
|
||||
if (events !== undefined)
|
||||
doError = (doError && events.error === undefined);
|
||||
else if (!doError)
|
||||
return false;
|
||||
|
||||
// If there is no 'error' event listener then throw.
|
||||
if (doError) {
|
||||
var er;
|
||||
if (args.length > 0)
|
||||
er = args[0];
|
||||
if (er instanceof Error) {
|
||||
// Note: The comments on the `throw` lines are intentional, they show
|
||||
// up in Node's output if this results in an unhandled exception.
|
||||
throw er; // Unhandled 'error' event
|
||||
}
|
||||
// At least give some kind of context to the user
|
||||
var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
|
||||
err.context = er;
|
||||
throw err; // Unhandled 'error' event
|
||||
}
|
||||
|
||||
var handler = events[type];
|
||||
|
||||
if (handler === undefined)
|
||||
return false;
|
||||
|
||||
if (typeof handler === 'function') {
|
||||
ReflectApply(handler, this, args);
|
||||
} else {
|
||||
var len = handler.length;
|
||||
var listeners = arrayClone(handler, len);
|
||||
for (var i = 0; i < len; ++i)
|
||||
ReflectApply(listeners[i], this, args);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
function _addListener(target, type, listener, prepend) {
|
||||
var m;
|
||||
var events;
|
||||
var existing;
|
||||
|
||||
checkListener(listener);
|
||||
|
||||
events = target._events;
|
||||
if (events === undefined) {
|
||||
events = target._events = Object.create(null);
|
||||
target._eventsCount = 0;
|
||||
} else {
|
||||
// To avoid recursion in the case that type === "newListener"! Before
|
||||
// adding it to the listeners, first emit "newListener".
|
||||
if (events.newListener !== undefined) {
|
||||
target.emit('newListener', type,
|
||||
listener.listener ? listener.listener : listener);
|
||||
|
||||
// Re-assign `events` because a newListener handler could have caused the
|
||||
// this._events to be assigned to a new object
|
||||
events = target._events;
|
||||
}
|
||||
existing = events[type];
|
||||
}
|
||||
|
||||
if (existing === undefined) {
|
||||
// Optimize the case of one listener. Don't need the extra array object.
|
||||
existing = events[type] = listener;
|
||||
++target._eventsCount;
|
||||
} else {
|
||||
if (typeof existing === 'function') {
|
||||
// Adding the second element, need to change to array.
|
||||
existing = events[type] =
|
||||
prepend ? [listener, existing] : [existing, listener];
|
||||
// If we've already got an array, just append.
|
||||
} else if (prepend) {
|
||||
existing.unshift(listener);
|
||||
} else {
|
||||
existing.push(listener);
|
||||
}
|
||||
|
||||
// Check for listener leak
|
||||
m = _getMaxListeners(target);
|
||||
if (m > 0 && existing.length > m && !existing.warned) {
|
||||
existing.warned = true;
|
||||
// No error code for this since it is a Warning
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
var w = new Error('Possible EventEmitter memory leak detected. ' +
|
||||
existing.length + ' ' + String(type) + ' listeners ' +
|
||||
'added. Use emitter.setMaxListeners() to ' +
|
||||
'increase limit');
|
||||
w.name = 'MaxListenersExceededWarning';
|
||||
w.emitter = target;
|
||||
w.type = type;
|
||||
w.count = existing.length;
|
||||
ProcessEmitWarning(w);
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
EventEmitter.prototype.addListener = function addListener(type, listener) {
|
||||
return _addListener(this, type, listener, false);
|
||||
};
|
||||
|
||||
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
|
||||
|
||||
EventEmitter.prototype.prependListener =
|
||||
function prependListener(type, listener) {
|
||||
return _addListener(this, type, listener, true);
|
||||
};
|
||||
|
||||
function onceWrapper() {
|
||||
if (!this.fired) {
|
||||
this.target.removeListener(this.type, this.wrapFn);
|
||||
this.fired = true;
|
||||
if (arguments.length === 0)
|
||||
return this.listener.call(this.target);
|
||||
return this.listener.apply(this.target, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
function _onceWrap(target, type, listener) {
|
||||
var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
|
||||
var wrapped = onceWrapper.bind(state);
|
||||
wrapped.listener = listener;
|
||||
state.wrapFn = wrapped;
|
||||
return wrapped;
|
||||
}
|
||||
|
||||
EventEmitter.prototype.once = function once(type, listener) {
|
||||
checkListener(listener);
|
||||
this.on(type, _onceWrap(this, type, listener));
|
||||
return this;
|
||||
};
|
||||
|
||||
EventEmitter.prototype.prependOnceListener =
|
||||
function prependOnceListener(type, listener) {
|
||||
checkListener(listener);
|
||||
this.prependListener(type, _onceWrap(this, type, listener));
|
||||
return this;
|
||||
};
|
||||
|
||||
// Emits a 'removeListener' event if and only if the listener was removed.
|
||||
EventEmitter.prototype.removeListener =
|
||||
function removeListener(type, listener) {
|
||||
var list, events, position, i, originalListener;
|
||||
|
||||
checkListener(listener);
|
||||
|
||||
events = this._events;
|
||||
if (events === undefined)
|
||||
return this;
|
||||
|
||||
list = events[type];
|
||||
if (list === undefined)
|
||||
return this;
|
||||
|
||||
if (list === listener || list.listener === listener) {
|
||||
if (--this._eventsCount === 0)
|
||||
this._events = Object.create(null);
|
||||
else {
|
||||
delete events[type];
|
||||
if (events.removeListener)
|
||||
this.emit('removeListener', type, list.listener || listener);
|
||||
}
|
||||
} else if (typeof list !== 'function') {
|
||||
position = -1;
|
||||
|
||||
for (i = list.length - 1; i >= 0; i--) {
|
||||
if (list[i] === listener || list[i].listener === listener) {
|
||||
originalListener = list[i].listener;
|
||||
position = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (position < 0)
|
||||
return this;
|
||||
|
||||
if (position === 0)
|
||||
list.shift();
|
||||
else {
|
||||
spliceOne(list, position);
|
||||
}
|
||||
|
||||
if (list.length === 1)
|
||||
events[type] = list[0];
|
||||
|
||||
if (events.removeListener !== undefined)
|
||||
this.emit('removeListener', type, originalListener || listener);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
|
||||
|
||||
EventEmitter.prototype.removeAllListeners =
|
||||
function removeAllListeners(type) {
|
||||
var listeners, events, i;
|
||||
|
||||
events = this._events;
|
||||
if (events === undefined)
|
||||
return this;
|
||||
|
||||
// not listening for removeListener, no need to emit
|
||||
if (events.removeListener === undefined) {
|
||||
if (arguments.length === 0) {
|
||||
this._events = Object.create(null);
|
||||
this._eventsCount = 0;
|
||||
} else if (events[type] !== undefined) {
|
||||
if (--this._eventsCount === 0)
|
||||
this._events = Object.create(null);
|
||||
else
|
||||
delete events[type];
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
// emit removeListener for all listeners on all events
|
||||
if (arguments.length === 0) {
|
||||
var keys = Object.keys(events);
|
||||
var key;
|
||||
for (i = 0; i < keys.length; ++i) {
|
||||
key = keys[i];
|
||||
if (key === 'removeListener') continue;
|
||||
this.removeAllListeners(key);
|
||||
}
|
||||
this.removeAllListeners('removeListener');
|
||||
this._events = Object.create(null);
|
||||
this._eventsCount = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
listeners = events[type];
|
||||
|
||||
if (typeof listeners === 'function') {
|
||||
this.removeListener(type, listeners);
|
||||
} else if (listeners !== undefined) {
|
||||
// LIFO order
|
||||
for (i = listeners.length - 1; i >= 0; i--) {
|
||||
this.removeListener(type, listeners[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
function _listeners(target, type, unwrap) {
|
||||
var events = target._events;
|
||||
|
||||
if (events === undefined)
|
||||
return [];
|
||||
|
||||
var evlistener = events[type];
|
||||
if (evlistener === undefined)
|
||||
return [];
|
||||
|
||||
if (typeof evlistener === 'function')
|
||||
return unwrap ? [evlistener.listener || evlistener] : [evlistener];
|
||||
|
||||
return unwrap ?
|
||||
unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
|
||||
}
|
||||
|
||||
EventEmitter.prototype.listeners = function listeners(type) {
|
||||
return _listeners(this, type, true);
|
||||
};
|
||||
|
||||
EventEmitter.prototype.rawListeners = function rawListeners(type) {
|
||||
return _listeners(this, type, false);
|
||||
};
|
||||
|
||||
EventEmitter.listenerCount = function(emitter, type) {
|
||||
if (typeof emitter.listenerCount === 'function') {
|
||||
return emitter.listenerCount(type);
|
||||
} else {
|
||||
return listenerCount.call(emitter, type);
|
||||
}
|
||||
};
|
||||
|
||||
EventEmitter.prototype.listenerCount = listenerCount;
|
||||
function listenerCount(type) {
|
||||
var events = this._events;
|
||||
|
||||
if (events !== undefined) {
|
||||
var evlistener = events[type];
|
||||
|
||||
if (typeof evlistener === 'function') {
|
||||
return 1;
|
||||
} else if (evlistener !== undefined) {
|
||||
return evlistener.length;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EventEmitter.prototype.eventNames = function eventNames() {
|
||||
return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
|
||||
};
|
||||
|
||||
function arrayClone(arr, n) {
|
||||
var copy = new Array(n);
|
||||
for (var i = 0; i < n; ++i)
|
||||
copy[i] = arr[i];
|
||||
return copy;
|
||||
}
|
||||
|
||||
function spliceOne(list, index) {
|
||||
for (; index + 1 < list.length; index++)
|
||||
list[index] = list[index + 1];
|
||||
list.pop();
|
||||
}
|
||||
|
||||
function unwrapListeners(arr) {
|
||||
var ret = new Array(arr.length);
|
||||
for (var i = 0; i < ret.length; ++i) {
|
||||
ret[i] = arr[i].listener || arr[i];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
function once(emitter, name) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
function errorListener(err) {
|
||||
emitter.removeListener(name, resolver);
|
||||
reject(err);
|
||||
}
|
||||
|
||||
function resolver() {
|
||||
if (typeof emitter.removeListener === 'function') {
|
||||
emitter.removeListener('error', errorListener);
|
||||
}
|
||||
resolve([].slice.call(arguments));
|
||||
};
|
||||
|
||||
eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });
|
||||
if (name !== 'error') {
|
||||
addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
|
||||
if (typeof emitter.on === 'function') {
|
||||
eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
|
||||
}
|
||||
}
|
||||
|
||||
function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
|
||||
if (typeof emitter.on === 'function') {
|
||||
if (flags.once) {
|
||||
emitter.once(name, listener);
|
||||
} else {
|
||||
emitter.on(name, listener);
|
||||
}
|
||||
} else if (typeof emitter.addEventListener === 'function') {
|
||||
// EventTarget does not have `error` event semantics like Node
|
||||
// EventEmitters, we do not listen for `error` events here.
|
||||
emitter.addEventListener(name, function wrapListener(arg) {
|
||||
// IE does not have builtin `{ once: true }` support so we
|
||||
// have to do it manually.
|
||||
if (flags.once) {
|
||||
emitter.removeEventListener(name, wrapListener);
|
||||
}
|
||||
listener(arg);
|
||||
});
|
||||
} else {
|
||||
throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+37
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "events",
|
||||
"version": "3.3.0",
|
||||
"description": "Node's event emitter for all engines.",
|
||||
"keywords": [
|
||||
"events",
|
||||
"eventEmitter",
|
||||
"eventDispatcher",
|
||||
"listeners"
|
||||
],
|
||||
"author": "Irakli Gozalishvili <rfobic@gmail.com> (http://jeditoolkit.com)",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/Gozala/events.git",
|
||||
"web": "https://github.com/Gozala/events"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "http://github.com/Gozala/events/issues/"
|
||||
},
|
||||
"main": "./events.js",
|
||||
"engines": {
|
||||
"node": ">=0.8.x"
|
||||
},
|
||||
"devDependencies": {
|
||||
"airtap": "^1.0.0",
|
||||
"functions-have-names": "^1.2.1",
|
||||
"has": "^1.0.3",
|
||||
"has-symbols": "^1.0.1",
|
||||
"isarray": "^2.0.5",
|
||||
"tape": "^5.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node tests/index.js",
|
||||
"test:browsers": "airtap -- tests/index.js"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
Generated
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
Only the latest major version is supported at any given time.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
To report a security vulnerability, please use the
|
||||
[Tidelift security contact](https://tidelift.com/security).
|
||||
Tidelift will coordinate the fix and disclosure.
|
||||
Generated
Vendored
+111
@@ -0,0 +1,111 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
var common = require('./common');
|
||||
var assert = require('assert');
|
||||
var EventEmitter = require('../');
|
||||
|
||||
{
|
||||
var ee = new EventEmitter();
|
||||
var events_new_listener_emitted = [];
|
||||
var listeners_new_listener_emitted = [];
|
||||
|
||||
// Sanity check
|
||||
assert.strictEqual(ee.addListener, ee.on);
|
||||
|
||||
ee.on('newListener', function(event, listener) {
|
||||
// Don't track newListener listeners.
|
||||
if (event === 'newListener')
|
||||
return;
|
||||
|
||||
events_new_listener_emitted.push(event);
|
||||
listeners_new_listener_emitted.push(listener);
|
||||
});
|
||||
|
||||
var hello = common.mustCall(function(a, b) {
|
||||
assert.strictEqual('a', a);
|
||||
assert.strictEqual('b', b);
|
||||
});
|
||||
|
||||
ee.once('newListener', function(name, listener) {
|
||||
assert.strictEqual(name, 'hello');
|
||||
assert.strictEqual(listener, hello);
|
||||
|
||||
var listeners = this.listeners('hello');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 0);
|
||||
});
|
||||
|
||||
ee.on('hello', hello);
|
||||
ee.once('foo', assert.fail);
|
||||
|
||||
assert.ok(Array.isArray(events_new_listener_emitted));
|
||||
assert.strictEqual(events_new_listener_emitted.length, 2);
|
||||
assert.strictEqual(events_new_listener_emitted[0], 'hello');
|
||||
assert.strictEqual(events_new_listener_emitted[1], 'foo');
|
||||
|
||||
assert.ok(Array.isArray(listeners_new_listener_emitted));
|
||||
assert.strictEqual(listeners_new_listener_emitted.length, 2);
|
||||
assert.strictEqual(listeners_new_listener_emitted[0], hello);
|
||||
assert.strictEqual(listeners_new_listener_emitted[1], assert.fail);
|
||||
|
||||
ee.emit('hello', 'a', 'b');
|
||||
}
|
||||
|
||||
// just make sure that this doesn't throw:
|
||||
{
|
||||
var f = new EventEmitter();
|
||||
|
||||
f.setMaxListeners(0);
|
||||
}
|
||||
|
||||
{
|
||||
var listen1 = function() {};
|
||||
var listen2 = function() {};
|
||||
var ee = new EventEmitter();
|
||||
|
||||
ee.once('newListener', function() {
|
||||
var listeners = ee.listeners('hello');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 0);
|
||||
ee.once('newListener', function() {
|
||||
var listeners = ee.listeners('hello');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 0);
|
||||
});
|
||||
ee.on('hello', listen2);
|
||||
});
|
||||
ee.on('hello', listen1);
|
||||
// The order of listeners on an event is not always the order in which the
|
||||
// listeners were added.
|
||||
var listeners = ee.listeners('hello');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 2);
|
||||
assert.strictEqual(listeners[0], listen2);
|
||||
assert.strictEqual(listeners[1], listen1);
|
||||
}
|
||||
|
||||
// Verify that the listener must be a function
|
||||
assert.throws(function() {
|
||||
var ee = new EventEmitter();
|
||||
|
||||
ee.on('foo', null);
|
||||
}, /^TypeError: The "listener" argument must be of type Function. Received type object$/);
|
||||
Generated
Vendored
+101
@@ -0,0 +1,101 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
var common = require('./common');
|
||||
var assert = require('assert');
|
||||
var events = require('../');
|
||||
|
||||
// Redirect warning output to tape.
|
||||
var consoleWarn = console.warn;
|
||||
console.warn = common.test.comment;
|
||||
|
||||
common.test.on('end', function () {
|
||||
console.warn = consoleWarn;
|
||||
});
|
||||
|
||||
// default
|
||||
{
|
||||
var e = new events.EventEmitter();
|
||||
|
||||
for (var i = 0; i < 10; i++) {
|
||||
e.on('default', common.mustNotCall());
|
||||
}
|
||||
assert.ok(!e._events['default'].hasOwnProperty('warned'));
|
||||
e.on('default', common.mustNotCall());
|
||||
assert.ok(e._events['default'].warned);
|
||||
|
||||
// specific
|
||||
e.setMaxListeners(5);
|
||||
for (var i = 0; i < 5; i++) {
|
||||
e.on('specific', common.mustNotCall());
|
||||
}
|
||||
assert.ok(!e._events['specific'].hasOwnProperty('warned'));
|
||||
e.on('specific', common.mustNotCall());
|
||||
assert.ok(e._events['specific'].warned);
|
||||
|
||||
// only one
|
||||
e.setMaxListeners(1);
|
||||
e.on('only one', common.mustNotCall());
|
||||
assert.ok(!e._events['only one'].hasOwnProperty('warned'));
|
||||
e.on('only one', common.mustNotCall());
|
||||
assert.ok(e._events['only one'].hasOwnProperty('warned'));
|
||||
|
||||
// unlimited
|
||||
e.setMaxListeners(0);
|
||||
for (var i = 0; i < 1000; i++) {
|
||||
e.on('unlimited', common.mustNotCall());
|
||||
}
|
||||
assert.ok(!e._events['unlimited'].hasOwnProperty('warned'));
|
||||
}
|
||||
|
||||
// process-wide
|
||||
{
|
||||
events.EventEmitter.defaultMaxListeners = 42;
|
||||
var e = new events.EventEmitter();
|
||||
|
||||
for (var i = 0; i < 42; ++i) {
|
||||
e.on('fortytwo', common.mustNotCall());
|
||||
}
|
||||
assert.ok(!e._events['fortytwo'].hasOwnProperty('warned'));
|
||||
e.on('fortytwo', common.mustNotCall());
|
||||
assert.ok(e._events['fortytwo'].hasOwnProperty('warned'));
|
||||
delete e._events['fortytwo'].warned;
|
||||
|
||||
events.EventEmitter.defaultMaxListeners = 44;
|
||||
e.on('fortytwo', common.mustNotCall());
|
||||
assert.ok(!e._events['fortytwo'].hasOwnProperty('warned'));
|
||||
e.on('fortytwo', common.mustNotCall());
|
||||
assert.ok(e._events['fortytwo'].hasOwnProperty('warned'));
|
||||
}
|
||||
|
||||
// but _maxListeners still has precedence over defaultMaxListeners
|
||||
{
|
||||
events.EventEmitter.defaultMaxListeners = 42;
|
||||
var e = new events.EventEmitter();
|
||||
e.setMaxListeners(1);
|
||||
e.on('uno', common.mustNotCall());
|
||||
assert.ok(!e._events['uno'].hasOwnProperty('warned'));
|
||||
e.on('uno', common.mustNotCall());
|
||||
assert.ok(e._events['uno'].hasOwnProperty('warned'));
|
||||
|
||||
// chainable
|
||||
assert.strictEqual(e, e.setMaxListeners(1));
|
||||
}
|
||||
Generated
Vendored
+104
@@ -0,0 +1,104 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
var test = require('tape');
|
||||
var assert = require('assert');
|
||||
|
||||
var noop = function() {};
|
||||
|
||||
var mustCallChecks = [];
|
||||
|
||||
function runCallChecks(exitCode) {
|
||||
if (exitCode !== 0) return;
|
||||
|
||||
var failed = filter(mustCallChecks, function(context) {
|
||||
if ('minimum' in context) {
|
||||
context.messageSegment = 'at least ' + context.minimum;
|
||||
return context.actual < context.minimum;
|
||||
} else {
|
||||
context.messageSegment = 'exactly ' + context.exact;
|
||||
return context.actual !== context.exact;
|
||||
}
|
||||
});
|
||||
|
||||
for (var i = 0; i < failed.length; i++) {
|
||||
var context = failed[i];
|
||||
console.log('Mismatched %s function calls. Expected %s, actual %d.',
|
||||
context.name,
|
||||
context.messageSegment,
|
||||
context.actual);
|
||||
// IE8 has no .stack
|
||||
if (context.stack) console.log(context.stack.split('\n').slice(2).join('\n'));
|
||||
}
|
||||
|
||||
assert.strictEqual(failed.length, 0);
|
||||
}
|
||||
|
||||
exports.mustCall = function(fn, exact) {
|
||||
return _mustCallInner(fn, exact, 'exact');
|
||||
};
|
||||
|
||||
function _mustCallInner(fn, criteria, field) {
|
||||
if (typeof criteria == 'undefined') criteria = 1;
|
||||
|
||||
if (typeof fn === 'number') {
|
||||
criteria = fn;
|
||||
fn = noop;
|
||||
} else if (fn === undefined) {
|
||||
fn = noop;
|
||||
}
|
||||
|
||||
if (typeof criteria !== 'number')
|
||||
throw new TypeError('Invalid ' + field + ' value: ' + criteria);
|
||||
|
||||
var context = {
|
||||
actual: 0,
|
||||
stack: (new Error()).stack,
|
||||
name: fn.name || '<anonymous>'
|
||||
};
|
||||
|
||||
context[field] = criteria;
|
||||
|
||||
// add the exit listener only once to avoid listener leak warnings
|
||||
if (mustCallChecks.length === 0) test.onFinish(function() { runCallChecks(0); });
|
||||
|
||||
mustCallChecks.push(context);
|
||||
|
||||
return function() {
|
||||
context.actual++;
|
||||
return fn.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
exports.mustNotCall = function(msg) {
|
||||
return function mustNotCall() {
|
||||
assert.fail(msg || 'function should not have been called');
|
||||
};
|
||||
};
|
||||
|
||||
function filter(arr, fn) {
|
||||
if (arr.filter) return arr.filter(fn);
|
||||
var filtered = [];
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if (fn(arr[i], i, arr)) filtered.push(arr[i]);
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
Generated
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
'use strict';
|
||||
var assert = require('assert');
|
||||
var EventEmitter = require('../');
|
||||
|
||||
var EE = new EventEmitter();
|
||||
|
||||
assert.throws(function () {
|
||||
EE.emit('error', 'Accepts a string');
|
||||
}, 'Error: Unhandled error. (Accepts a string)');
|
||||
|
||||
assert.throws(function () {
|
||||
EE.emit('error', { message: 'Error!' });
|
||||
}, 'Unhandled error. ([object Object])');
|
||||
Generated
Vendored
+28
@@ -0,0 +1,28 @@
|
||||
'use strict';
|
||||
|
||||
var EventEmitter = require('../');
|
||||
var assert = require('assert');
|
||||
|
||||
var EE = new EventEmitter();
|
||||
var m = function() {};
|
||||
EE.on('foo', function() {});
|
||||
assert.equal(1, EE.eventNames().length);
|
||||
assert.equal('foo', EE.eventNames()[0]);
|
||||
EE.on('bar', m);
|
||||
assert.equal(2, EE.eventNames().length);
|
||||
assert.equal('foo', EE.eventNames()[0]);
|
||||
assert.equal('bar', EE.eventNames()[1]);
|
||||
EE.removeListener('bar', m);
|
||||
assert.equal(1, EE.eventNames().length);
|
||||
assert.equal('foo', EE.eventNames()[0]);
|
||||
|
||||
if (typeof Symbol !== 'undefined') {
|
||||
var s = Symbol('s');
|
||||
EE.on(s, m);
|
||||
assert.equal(2, EE.eventNames().length);
|
||||
assert.equal('foo', EE.eventNames()[0]);
|
||||
assert.equal(s, EE.eventNames()[1]);
|
||||
EE.removeListener(s, m);
|
||||
assert.equal(1, EE.eventNames().length);
|
||||
assert.equal('foo', EE.eventNames()[0]);
|
||||
}
|
||||
Generated
Vendored
+234
@@ -0,0 +1,234 @@
|
||||
'use strict';
|
||||
|
||||
var common = require('./common');
|
||||
var EventEmitter = require('../').EventEmitter;
|
||||
var once = require('../').once;
|
||||
var has = require('has');
|
||||
var assert = require('assert');
|
||||
|
||||
function Event(type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
function EventTargetMock() {
|
||||
this.events = {};
|
||||
|
||||
this.addEventListener = common.mustCall(this.addEventListener);
|
||||
this.removeEventListener = common.mustCall(this.removeEventListener);
|
||||
}
|
||||
|
||||
EventTargetMock.prototype.addEventListener = function addEventListener(name, listener, options) {
|
||||
if (!(name in this.events)) {
|
||||
this.events[name] = { listeners: [], options: options || {} }
|
||||
}
|
||||
this.events[name].listeners.push(listener);
|
||||
};
|
||||
|
||||
EventTargetMock.prototype.removeEventListener = function removeEventListener(name, callback) {
|
||||
if (!(name in this.events)) {
|
||||
return;
|
||||
}
|
||||
var event = this.events[name];
|
||||
var stack = event.listeners;
|
||||
|
||||
for (var i = 0, l = stack.length; i < l; i++) {
|
||||
if (stack[i] === callback) {
|
||||
stack.splice(i, 1);
|
||||
if (stack.length === 0) {
|
||||
delete this.events[name];
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
EventTargetMock.prototype.dispatchEvent = function dispatchEvent(arg) {
|
||||
if (!(arg.type in this.events)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var event = this.events[arg.type];
|
||||
var stack = event.listeners.slice();
|
||||
|
||||
for (var i = 0, l = stack.length; i < l; i++) {
|
||||
stack[i].call(null, arg);
|
||||
if (event.options.once) {
|
||||
this.removeEventListener(arg.type, stack[i]);
|
||||
}
|
||||
}
|
||||
return !arg.defaultPrevented;
|
||||
};
|
||||
|
||||
function onceAnEvent() {
|
||||
var ee = new EventEmitter();
|
||||
|
||||
process.nextTick(function () {
|
||||
ee.emit('myevent', 42);
|
||||
});
|
||||
|
||||
return once(ee, 'myevent').then(function (args) {
|
||||
var value = args[0]
|
||||
assert.strictEqual(value, 42);
|
||||
assert.strictEqual(ee.listenerCount('error'), 0);
|
||||
assert.strictEqual(ee.listenerCount('myevent'), 0);
|
||||
});
|
||||
}
|
||||
|
||||
function onceAnEventWithTwoArgs() {
|
||||
var ee = new EventEmitter();
|
||||
|
||||
process.nextTick(function () {
|
||||
ee.emit('myevent', 42, 24);
|
||||
});
|
||||
|
||||
return once(ee, 'myevent').then(function (value) {
|
||||
assert.strictEqual(value.length, 2);
|
||||
assert.strictEqual(value[0], 42);
|
||||
assert.strictEqual(value[1], 24);
|
||||
});
|
||||
}
|
||||
|
||||
function catchesErrors() {
|
||||
var ee = new EventEmitter();
|
||||
|
||||
var expected = new Error('kaboom');
|
||||
var err;
|
||||
process.nextTick(function () {
|
||||
ee.emit('error', expected);
|
||||
});
|
||||
|
||||
return once(ee, 'myevent').then(function () {
|
||||
throw new Error('should reject')
|
||||
}, function (err) {
|
||||
assert.strictEqual(err, expected);
|
||||
assert.strictEqual(ee.listenerCount('error'), 0);
|
||||
assert.strictEqual(ee.listenerCount('myevent'), 0);
|
||||
});
|
||||
}
|
||||
|
||||
function stopListeningAfterCatchingError() {
|
||||
var ee = new EventEmitter();
|
||||
|
||||
var expected = new Error('kaboom');
|
||||
var err;
|
||||
process.nextTick(function () {
|
||||
ee.emit('error', expected);
|
||||
ee.emit('myevent', 42, 24);
|
||||
});
|
||||
|
||||
// process.on('multipleResolves', common.mustNotCall());
|
||||
|
||||
return once(ee, 'myevent').then(common.mustNotCall, function (err) {
|
||||
// process.removeAllListeners('multipleResolves');
|
||||
assert.strictEqual(err, expected);
|
||||
assert.strictEqual(ee.listenerCount('error'), 0);
|
||||
assert.strictEqual(ee.listenerCount('myevent'), 0);
|
||||
});
|
||||
}
|
||||
|
||||
function onceError() {
|
||||
var ee = new EventEmitter();
|
||||
|
||||
var expected = new Error('kaboom');
|
||||
process.nextTick(function () {
|
||||
ee.emit('error', expected);
|
||||
});
|
||||
|
||||
var promise = once(ee, 'error');
|
||||
assert.strictEqual(ee.listenerCount('error'), 1);
|
||||
return promise.then(function (args) {
|
||||
var err = args[0]
|
||||
assert.strictEqual(err, expected);
|
||||
assert.strictEqual(ee.listenerCount('error'), 0);
|
||||
assert.strictEqual(ee.listenerCount('myevent'), 0);
|
||||
});
|
||||
}
|
||||
|
||||
function onceWithEventTarget() {
|
||||
var et = new EventTargetMock();
|
||||
var event = new Event('myevent');
|
||||
process.nextTick(function () {
|
||||
et.dispatchEvent(event);
|
||||
});
|
||||
return once(et, 'myevent').then(function (args) {
|
||||
var value = args[0];
|
||||
assert.strictEqual(value, event);
|
||||
assert.strictEqual(has(et.events, 'myevent'), false);
|
||||
});
|
||||
}
|
||||
|
||||
function onceWithEventTargetError() {
|
||||
var et = new EventTargetMock();
|
||||
var error = new Event('error');
|
||||
process.nextTick(function () {
|
||||
et.dispatchEvent(error);
|
||||
});
|
||||
return once(et, 'error').then(function (args) {
|
||||
var err = args[0];
|
||||
assert.strictEqual(err, error);
|
||||
assert.strictEqual(has(et.events, 'error'), false);
|
||||
});
|
||||
}
|
||||
|
||||
function prioritizesEventEmitter() {
|
||||
var ee = new EventEmitter();
|
||||
ee.addEventListener = assert.fail;
|
||||
ee.removeAllListeners = assert.fail;
|
||||
process.nextTick(function () {
|
||||
ee.emit('foo');
|
||||
});
|
||||
return once(ee, 'foo');
|
||||
}
|
||||
|
||||
var allTests = [
|
||||
onceAnEvent(),
|
||||
onceAnEventWithTwoArgs(),
|
||||
catchesErrors(),
|
||||
stopListeningAfterCatchingError(),
|
||||
onceError(),
|
||||
onceWithEventTarget(),
|
||||
onceWithEventTargetError(),
|
||||
prioritizesEventEmitter()
|
||||
];
|
||||
|
||||
var hasBrowserEventTarget = false;
|
||||
try {
|
||||
hasBrowserEventTarget = typeof (new window.EventTarget().addEventListener) === 'function' &&
|
||||
new window.Event('xyz').type === 'xyz';
|
||||
} catch (err) {}
|
||||
|
||||
if (hasBrowserEventTarget) {
|
||||
var onceWithBrowserEventTarget = function onceWithBrowserEventTarget() {
|
||||
var et = new window.EventTarget();
|
||||
var event = new window.Event('myevent');
|
||||
process.nextTick(function () {
|
||||
et.dispatchEvent(event);
|
||||
});
|
||||
return once(et, 'myevent').then(function (args) {
|
||||
var value = args[0];
|
||||
assert.strictEqual(value, event);
|
||||
assert.strictEqual(has(et.events, 'myevent'), false);
|
||||
});
|
||||
}
|
||||
|
||||
var onceWithBrowserEventTargetError = function onceWithBrowserEventTargetError() {
|
||||
var et = new window.EventTarget();
|
||||
var error = new window.Event('error');
|
||||
process.nextTick(function () {
|
||||
et.dispatchEvent(error);
|
||||
});
|
||||
return once(et, 'error').then(function (args) {
|
||||
var err = args[0];
|
||||
assert.strictEqual(err, error);
|
||||
assert.strictEqual(has(et.events, 'error'), false);
|
||||
});
|
||||
}
|
||||
|
||||
common.test.comment('Testing with browser built-in EventTarget');
|
||||
allTests.push([
|
||||
onceWithBrowserEventTarget(),
|
||||
onceWithBrowserEventTargetError()
|
||||
]);
|
||||
}
|
||||
|
||||
module.exports = Promise.all(allTests);
|
||||
Generated
Vendored
+64
@@ -0,0 +1,64 @@
|
||||
var test = require('tape');
|
||||
var functionsHaveNames = require('functions-have-names');
|
||||
var hasSymbols = require('has-symbols');
|
||||
|
||||
require('./legacy-compat');
|
||||
var common = require('./common');
|
||||
|
||||
// we do this to easily wrap each file in a mocha test
|
||||
// and also have browserify be able to statically analyze this file
|
||||
var orig_require = require;
|
||||
var require = function(file) {
|
||||
test(file, function(t) {
|
||||
// Store the tape object so tests can access it.
|
||||
t.on('end', function () { delete common.test; });
|
||||
common.test = t;
|
||||
|
||||
try {
|
||||
var exp = orig_require(file);
|
||||
if (exp && exp.then) {
|
||||
exp.then(function () { t.end(); }, t.fail);
|
||||
return;
|
||||
}
|
||||
} catch (err) {
|
||||
t.fail(err);
|
||||
}
|
||||
t.end();
|
||||
});
|
||||
};
|
||||
|
||||
require('./add-listeners.js');
|
||||
require('./check-listener-leaks.js');
|
||||
require('./errors.js');
|
||||
require('./events-list.js');
|
||||
if (typeof Promise === 'function') {
|
||||
require('./events-once.js');
|
||||
} else {
|
||||
// Promise support is not available.
|
||||
test('./events-once.js', { skip: true }, function () {});
|
||||
}
|
||||
require('./listener-count.js');
|
||||
require('./listeners-side-effects.js');
|
||||
require('./listeners.js');
|
||||
require('./max-listeners.js');
|
||||
if (functionsHaveNames()) {
|
||||
require('./method-names.js');
|
||||
} else {
|
||||
// Function.name is not supported in IE
|
||||
test('./method-names.js', { skip: true }, function () {});
|
||||
}
|
||||
require('./modify-in-emit.js');
|
||||
require('./num-args.js');
|
||||
require('./once.js');
|
||||
require('./prepend.js');
|
||||
require('./set-max-listeners-side-effects.js');
|
||||
require('./special-event-names.js');
|
||||
require('./subclass.js');
|
||||
if (hasSymbols()) {
|
||||
require('./symbols.js');
|
||||
} else {
|
||||
// Symbol is not available.
|
||||
test('./symbols.js', { skip: true }, function () {});
|
||||
}
|
||||
require('./remove-all-listeners.js');
|
||||
require('./remove-listeners.js');
|
||||
Generated
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
// sigh... life is hard
|
||||
if (!global.console) {
|
||||
console = {}
|
||||
}
|
||||
|
||||
var fns = ['log', 'error', 'trace'];
|
||||
for (var i=0 ; i<fns.length ; ++i) {
|
||||
var fn = fns[i];
|
||||
if (!console[fn]) {
|
||||
console[fn] = function() {};
|
||||
}
|
||||
}
|
||||
|
||||
if (!Array.isArray) {
|
||||
Array.isArray = require('isarray');
|
||||
}
|
||||
Generated
Vendored
+37
@@ -0,0 +1,37 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
require('./common');
|
||||
var assert = require('assert');
|
||||
var EventEmitter = require('../');
|
||||
|
||||
var emitter = new EventEmitter();
|
||||
emitter.on('foo', function() {});
|
||||
emitter.on('foo', function() {});
|
||||
emitter.on('baz', function() {});
|
||||
// Allow any type
|
||||
emitter.on(123, function() {});
|
||||
|
||||
assert.strictEqual(EventEmitter.listenerCount(emitter, 'foo'), 2);
|
||||
assert.strictEqual(emitter.listenerCount('foo'), 2);
|
||||
assert.strictEqual(emitter.listenerCount('bar'), 0);
|
||||
assert.strictEqual(emitter.listenerCount('baz'), 1);
|
||||
assert.strictEqual(emitter.listenerCount(123), 1);
|
||||
Generated
Vendored
+56
@@ -0,0 +1,56 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
require('./common');
|
||||
var assert = require('assert');
|
||||
|
||||
var EventEmitter = require('../').EventEmitter;
|
||||
|
||||
var e = new EventEmitter();
|
||||
var fl; // foo listeners
|
||||
|
||||
fl = e.listeners('foo');
|
||||
assert.ok(Array.isArray(fl));
|
||||
assert.strictEqual(fl.length, 0);
|
||||
if (Object.create) assert.ok(!(e._events instanceof Object));
|
||||
assert.strictEqual(Object.keys(e._events).length, 0);
|
||||
|
||||
e.on('foo', assert.fail);
|
||||
fl = e.listeners('foo');
|
||||
assert.strictEqual(e._events.foo, assert.fail);
|
||||
assert.ok(Array.isArray(fl));
|
||||
assert.strictEqual(fl.length, 1);
|
||||
assert.strictEqual(fl[0], assert.fail);
|
||||
|
||||
e.listeners('bar');
|
||||
|
||||
e.on('foo', assert.ok);
|
||||
fl = e.listeners('foo');
|
||||
|
||||
assert.ok(Array.isArray(e._events.foo));
|
||||
assert.strictEqual(e._events.foo.length, 2);
|
||||
assert.strictEqual(e._events.foo[0], assert.fail);
|
||||
assert.strictEqual(e._events.foo[1], assert.ok);
|
||||
|
||||
assert.ok(Array.isArray(fl));
|
||||
assert.strictEqual(fl.length, 2);
|
||||
assert.strictEqual(fl[0], assert.fail);
|
||||
assert.strictEqual(fl[1], assert.ok);
|
||||
Generated
Vendored
+168
@@ -0,0 +1,168 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
require('./common');
|
||||
var assert = require('assert');
|
||||
var events = require('../');
|
||||
var util = require('util');
|
||||
|
||||
function listener() {}
|
||||
function listener2() {}
|
||||
function listener3() {
|
||||
return 0;
|
||||
}
|
||||
function listener4() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
function TestStream() {}
|
||||
util.inherits(TestStream, events.EventEmitter);
|
||||
|
||||
{
|
||||
var ee = new events.EventEmitter();
|
||||
ee.on('foo', listener);
|
||||
var fooListeners = ee.listeners('foo');
|
||||
|
||||
var listeners = ee.listeners('foo');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 1);
|
||||
assert.strictEqual(listeners[0], listener);
|
||||
|
||||
ee.removeAllListeners('foo');
|
||||
listeners = ee.listeners('foo');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 0);
|
||||
|
||||
assert.ok(Array.isArray(fooListeners));
|
||||
assert.strictEqual(fooListeners.length, 1);
|
||||
assert.strictEqual(fooListeners[0], listener);
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new events.EventEmitter();
|
||||
ee.on('foo', listener);
|
||||
|
||||
var eeListenersCopy = ee.listeners('foo');
|
||||
assert.ok(Array.isArray(eeListenersCopy));
|
||||
assert.strictEqual(eeListenersCopy.length, 1);
|
||||
assert.strictEqual(eeListenersCopy[0], listener);
|
||||
|
||||
var listeners = ee.listeners('foo');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 1);
|
||||
assert.strictEqual(listeners[0], listener);
|
||||
|
||||
eeListenersCopy.push(listener2);
|
||||
listeners = ee.listeners('foo');
|
||||
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 1);
|
||||
assert.strictEqual(listeners[0], listener);
|
||||
|
||||
assert.strictEqual(eeListenersCopy.length, 2);
|
||||
assert.strictEqual(eeListenersCopy[0], listener);
|
||||
assert.strictEqual(eeListenersCopy[1], listener2);
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new events.EventEmitter();
|
||||
ee.on('foo', listener);
|
||||
var eeListenersCopy = ee.listeners('foo');
|
||||
ee.on('foo', listener2);
|
||||
|
||||
var listeners = ee.listeners('foo');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 2);
|
||||
assert.strictEqual(listeners[0], listener);
|
||||
assert.strictEqual(listeners[1], listener2);
|
||||
|
||||
assert.ok(Array.isArray(eeListenersCopy));
|
||||
assert.strictEqual(eeListenersCopy.length, 1);
|
||||
assert.strictEqual(eeListenersCopy[0], listener);
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new events.EventEmitter();
|
||||
ee.once('foo', listener);
|
||||
var listeners = ee.listeners('foo');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 1);
|
||||
assert.strictEqual(listeners[0], listener);
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new events.EventEmitter();
|
||||
ee.on('foo', listener);
|
||||
ee.once('foo', listener2);
|
||||
|
||||
var listeners = ee.listeners('foo');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 2);
|
||||
assert.strictEqual(listeners[0], listener);
|
||||
assert.strictEqual(listeners[1], listener2);
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new events.EventEmitter();
|
||||
ee._events = undefined;
|
||||
var listeners = ee.listeners('foo');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 0);
|
||||
}
|
||||
|
||||
{
|
||||
var s = new TestStream();
|
||||
var listeners = s.listeners('foo');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 0);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
var ee = new events.EventEmitter();
|
||||
ee.on('foo', listener);
|
||||
var wrappedListener = ee.rawListeners('foo');
|
||||
assert.strictEqual(wrappedListener.length, 1);
|
||||
assert.strictEqual(wrappedListener[0], listener);
|
||||
assert.notStrictEqual(wrappedListener, ee.rawListeners('foo'));
|
||||
ee.once('foo', listener);
|
||||
var wrappedListeners = ee.rawListeners('foo');
|
||||
assert.strictEqual(wrappedListeners.length, 2);
|
||||
assert.strictEqual(wrappedListeners[0], listener);
|
||||
assert.notStrictEqual(wrappedListeners[1], listener);
|
||||
assert.strictEqual(wrappedListeners[1].listener, listener);
|
||||
assert.notStrictEqual(wrappedListeners, ee.rawListeners('foo'));
|
||||
ee.emit('foo');
|
||||
assert.strictEqual(wrappedListeners.length, 2);
|
||||
assert.strictEqual(wrappedListeners[1].listener, listener);
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new events.EventEmitter();
|
||||
ee.once('foo', listener3);
|
||||
ee.on('foo', listener4);
|
||||
var rawListeners = ee.rawListeners('foo');
|
||||
assert.strictEqual(rawListeners.length, 2);
|
||||
assert.strictEqual(rawListeners[0](), 0);
|
||||
var rawListener = ee.rawListeners('foo');
|
||||
assert.strictEqual(rawListener.length, 1);
|
||||
assert.strictEqual(rawListener[0](), 1);
|
||||
}
|
||||
Generated
Vendored
+47
@@ -0,0 +1,47 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
var common = require('./common');
|
||||
var assert = require('assert');
|
||||
var events = require('../');
|
||||
var e = new events.EventEmitter();
|
||||
|
||||
var hasDefineProperty = !!Object.defineProperty;
|
||||
try { Object.defineProperty({}, 'x', { value: 0 }); } catch (err) { hasDefineProperty = false }
|
||||
|
||||
e.on('maxListeners', common.mustCall());
|
||||
|
||||
// Should not corrupt the 'maxListeners' queue.
|
||||
e.setMaxListeners(42);
|
||||
|
||||
var throwsObjs = [NaN, -1, 'and even this'];
|
||||
var maxError = /^RangeError: The value of "n" is out of range\. It must be a non-negative number\./;
|
||||
var defError = /^RangeError: The value of "defaultMaxListeners" is out of range\. It must be a non-negative number\./;
|
||||
|
||||
for (var i = 0; i < throwsObjs.length; i++) {
|
||||
var obj = throwsObjs[i];
|
||||
assert.throws(function() { e.setMaxListeners(obj); }, maxError);
|
||||
if (hasDefineProperty) {
|
||||
assert.throws(function() { events.defaultMaxListeners = obj; }, defError);
|
||||
}
|
||||
}
|
||||
|
||||
e.emit('maxListeners');
|
||||
Generated
Vendored
+35
@@ -0,0 +1,35 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
require('./common');
|
||||
var assert = require('assert');
|
||||
var events = require('../');
|
||||
|
||||
var E = events.EventEmitter.prototype;
|
||||
assert.strictEqual(E.constructor.name, 'EventEmitter');
|
||||
assert.strictEqual(E.on, E.addListener); // Same method.
|
||||
assert.strictEqual(E.off, E.removeListener); // Same method.
|
||||
Object.getOwnPropertyNames(E).forEach(function(name) {
|
||||
if (name === 'constructor' || name === 'on' || name === 'off') return;
|
||||
if (typeof E[name] !== 'function') return;
|
||||
assert.strictEqual(E[name].name, name);
|
||||
});
|
||||
Generated
Vendored
+90
@@ -0,0 +1,90 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
require('./common');
|
||||
var assert = require('assert');
|
||||
var events = require('../');
|
||||
|
||||
var callbacks_called = [];
|
||||
|
||||
var e = new events.EventEmitter();
|
||||
|
||||
function callback1() {
|
||||
callbacks_called.push('callback1');
|
||||
e.on('foo', callback2);
|
||||
e.on('foo', callback3);
|
||||
e.removeListener('foo', callback1);
|
||||
}
|
||||
|
||||
function callback2() {
|
||||
callbacks_called.push('callback2');
|
||||
e.removeListener('foo', callback2);
|
||||
}
|
||||
|
||||
function callback3() {
|
||||
callbacks_called.push('callback3');
|
||||
e.removeListener('foo', callback3);
|
||||
}
|
||||
|
||||
e.on('foo', callback1);
|
||||
assert.strictEqual(e.listeners('foo').length, 1);
|
||||
|
||||
e.emit('foo');
|
||||
assert.strictEqual(e.listeners('foo').length, 2);
|
||||
assert.ok(Array.isArray(callbacks_called));
|
||||
assert.strictEqual(callbacks_called.length, 1);
|
||||
assert.strictEqual(callbacks_called[0], 'callback1');
|
||||
|
||||
e.emit('foo');
|
||||
assert.strictEqual(e.listeners('foo').length, 0);
|
||||
assert.ok(Array.isArray(callbacks_called));
|
||||
assert.strictEqual(callbacks_called.length, 3);
|
||||
assert.strictEqual(callbacks_called[0], 'callback1');
|
||||
assert.strictEqual(callbacks_called[1], 'callback2');
|
||||
assert.strictEqual(callbacks_called[2], 'callback3');
|
||||
|
||||
e.emit('foo');
|
||||
assert.strictEqual(e.listeners('foo').length, 0);
|
||||
assert.ok(Array.isArray(callbacks_called));
|
||||
assert.strictEqual(callbacks_called.length, 3);
|
||||
assert.strictEqual(callbacks_called[0], 'callback1');
|
||||
assert.strictEqual(callbacks_called[1], 'callback2');
|
||||
assert.strictEqual(callbacks_called[2], 'callback3');
|
||||
|
||||
e.on('foo', callback1);
|
||||
e.on('foo', callback2);
|
||||
assert.strictEqual(e.listeners('foo').length, 2);
|
||||
e.removeAllListeners('foo');
|
||||
assert.strictEqual(e.listeners('foo').length, 0);
|
||||
|
||||
// Verify that removing callbacks while in emit allows emits to propagate to
|
||||
// all listeners
|
||||
callbacks_called = [];
|
||||
|
||||
e.on('foo', callback2);
|
||||
e.on('foo', callback3);
|
||||
assert.strictEqual(2, e.listeners('foo').length);
|
||||
e.emit('foo');
|
||||
assert.ok(Array.isArray(callbacks_called));
|
||||
assert.strictEqual(callbacks_called.length, 2);
|
||||
assert.strictEqual(callbacks_called[0], 'callback2');
|
||||
assert.strictEqual(callbacks_called[1], 'callback3');
|
||||
assert.strictEqual(0, e.listeners('foo').length);
|
||||
Generated
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
require('./common');
|
||||
var assert = require('assert');
|
||||
var events = require('../');
|
||||
|
||||
var e = new events.EventEmitter();
|
||||
var num_args_emitted = [];
|
||||
|
||||
e.on('numArgs', function() {
|
||||
var numArgs = arguments.length;
|
||||
num_args_emitted.push(numArgs);
|
||||
});
|
||||
|
||||
e.on('foo', function() {
|
||||
num_args_emitted.push(arguments.length);
|
||||
});
|
||||
|
||||
e.on('foo', function() {
|
||||
num_args_emitted.push(arguments.length);
|
||||
});
|
||||
|
||||
e.emit('numArgs');
|
||||
e.emit('numArgs', null);
|
||||
e.emit('numArgs', null, null);
|
||||
e.emit('numArgs', null, null, null);
|
||||
e.emit('numArgs', null, null, null, null);
|
||||
e.emit('numArgs', null, null, null, null, null);
|
||||
|
||||
e.emit('foo', null, null, null, null);
|
||||
|
||||
assert.ok(Array.isArray(num_args_emitted));
|
||||
assert.strictEqual(num_args_emitted.length, 8);
|
||||
assert.strictEqual(num_args_emitted[0], 0);
|
||||
assert.strictEqual(num_args_emitted[1], 1);
|
||||
assert.strictEqual(num_args_emitted[2], 2);
|
||||
assert.strictEqual(num_args_emitted[3], 3);
|
||||
assert.strictEqual(num_args_emitted[4], 4);
|
||||
assert.strictEqual(num_args_emitted[5], 5);
|
||||
assert.strictEqual(num_args_emitted[6], 4);
|
||||
assert.strictEqual(num_args_emitted[6], 4);
|
||||
Generated
Vendored
+83
@@ -0,0 +1,83 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
var common = require('./common');
|
||||
var assert = require('assert');
|
||||
var EventEmitter = require('../');
|
||||
|
||||
var e = new EventEmitter();
|
||||
|
||||
e.once('hello', common.mustCall());
|
||||
|
||||
e.emit('hello', 'a', 'b');
|
||||
e.emit('hello', 'a', 'b');
|
||||
e.emit('hello', 'a', 'b');
|
||||
e.emit('hello', 'a', 'b');
|
||||
|
||||
function remove() {
|
||||
assert.fail('once->foo should not be emitted');
|
||||
}
|
||||
|
||||
e.once('foo', remove);
|
||||
e.removeListener('foo', remove);
|
||||
e.emit('foo');
|
||||
|
||||
e.once('e', common.mustCall(function() {
|
||||
e.emit('e');
|
||||
}));
|
||||
|
||||
e.once('e', common.mustCall());
|
||||
|
||||
e.emit('e');
|
||||
|
||||
// Verify that the listener must be a function
|
||||
assert.throws(function() {
|
||||
var ee = new EventEmitter();
|
||||
|
||||
ee.once('foo', null);
|
||||
}, /^TypeError: The "listener" argument must be of type Function. Received type object$/);
|
||||
|
||||
{
|
||||
// once() has different code paths based on the number of arguments being
|
||||
// emitted. Verify that all of the cases are covered.
|
||||
var maxArgs = 4;
|
||||
|
||||
for (var i = 0; i <= maxArgs; ++i) {
|
||||
var ee = new EventEmitter();
|
||||
var args = ['foo'];
|
||||
|
||||
for (var j = 0; j < i; ++j)
|
||||
args.push(j);
|
||||
|
||||
ee.once('foo', common.mustCall(function() {
|
||||
var params = Array.prototype.slice.call(arguments);
|
||||
var restArgs = args.slice(1);
|
||||
assert.ok(Array.isArray(params));
|
||||
assert.strictEqual(params.length, restArgs.length);
|
||||
for (var index = 0; index < params.length; index++) {
|
||||
var param = params[index];
|
||||
assert.strictEqual(param, restArgs[index]);
|
||||
}
|
||||
}));
|
||||
|
||||
EventEmitter.prototype.emit.apply(ee, args);
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+31
@@ -0,0 +1,31 @@
|
||||
'use strict';
|
||||
|
||||
var common = require('./common');
|
||||
var EventEmitter = require('../');
|
||||
var assert = require('assert');
|
||||
|
||||
var myEE = new EventEmitter();
|
||||
var m = 0;
|
||||
// This one comes last.
|
||||
myEE.on('foo', common.mustCall(function () {
|
||||
assert.strictEqual(m, 2);
|
||||
}));
|
||||
|
||||
// This one comes second.
|
||||
myEE.prependListener('foo', common.mustCall(function () {
|
||||
assert.strictEqual(m++, 1);
|
||||
}));
|
||||
|
||||
// This one comes first.
|
||||
myEE.prependOnceListener('foo',
|
||||
common.mustCall(function () {
|
||||
assert.strictEqual(m++, 0);
|
||||
}));
|
||||
|
||||
myEE.emit('foo');
|
||||
|
||||
// Verify that the listener must be a function
|
||||
assert.throws(function () {
|
||||
var ee = new EventEmitter();
|
||||
ee.prependOnceListener('foo', null);
|
||||
}, 'TypeError: The "listener" argument must be of type Function. Received type object');
|
||||
Generated
Vendored
+133
@@ -0,0 +1,133 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
var common = require('./common');
|
||||
var assert = require('assert');
|
||||
var events = require('../');
|
||||
var test = require('tape');
|
||||
|
||||
function expect(expected) {
|
||||
var actual = [];
|
||||
test.onFinish(function() {
|
||||
var sortedActual = actual.sort();
|
||||
var sortedExpected = expected.sort();
|
||||
assert.strictEqual(sortedActual.length, sortedExpected.length);
|
||||
for (var index = 0; index < sortedActual.length; index++) {
|
||||
var value = sortedActual[index];
|
||||
assert.strictEqual(value, sortedExpected[index]);
|
||||
}
|
||||
});
|
||||
function listener(name) {
|
||||
actual.push(name);
|
||||
}
|
||||
return common.mustCall(listener, expected.length);
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new events.EventEmitter();
|
||||
var noop = common.mustNotCall();
|
||||
ee.on('foo', noop);
|
||||
ee.on('bar', noop);
|
||||
ee.on('baz', noop);
|
||||
ee.on('baz', noop);
|
||||
var fooListeners = ee.listeners('foo');
|
||||
var barListeners = ee.listeners('bar');
|
||||
var bazListeners = ee.listeners('baz');
|
||||
ee.on('removeListener', expect(['bar', 'baz', 'baz']));
|
||||
ee.removeAllListeners('bar');
|
||||
ee.removeAllListeners('baz');
|
||||
|
||||
var listeners = ee.listeners('foo');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 1);
|
||||
assert.strictEqual(listeners[0], noop);
|
||||
|
||||
listeners = ee.listeners('bar');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 0);
|
||||
listeners = ee.listeners('baz');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 0);
|
||||
// After calling removeAllListeners(),
|
||||
// the old listeners array should stay unchanged.
|
||||
assert.strictEqual(fooListeners.length, 1);
|
||||
assert.strictEqual(fooListeners[0], noop);
|
||||
assert.strictEqual(barListeners.length, 1);
|
||||
assert.strictEqual(barListeners[0], noop);
|
||||
assert.strictEqual(bazListeners.length, 2);
|
||||
assert.strictEqual(bazListeners[0], noop);
|
||||
assert.strictEqual(bazListeners[1], noop);
|
||||
// After calling removeAllListeners(),
|
||||
// new listeners arrays is different from the old.
|
||||
assert.notStrictEqual(ee.listeners('bar'), barListeners);
|
||||
assert.notStrictEqual(ee.listeners('baz'), bazListeners);
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new events.EventEmitter();
|
||||
ee.on('foo', common.mustNotCall());
|
||||
ee.on('bar', common.mustNotCall());
|
||||
// Expect LIFO order
|
||||
ee.on('removeListener', expect(['foo', 'bar', 'removeListener']));
|
||||
ee.on('removeListener', expect(['foo', 'bar']));
|
||||
ee.removeAllListeners();
|
||||
|
||||
var listeners = ee.listeners('foo');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 0);
|
||||
listeners = ee.listeners('bar');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 0);
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new events.EventEmitter();
|
||||
ee.on('removeListener', common.mustNotCall());
|
||||
// Check for regression where removeAllListeners() throws when
|
||||
// there exists a 'removeListener' listener, but there exists
|
||||
// no listeners for the provided event type.
|
||||
assert.doesNotThrow(function () { ee.removeAllListeners(ee, 'foo') });
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new events.EventEmitter();
|
||||
var expectLength = 2;
|
||||
ee.on('removeListener', function() {
|
||||
assert.strictEqual(expectLength--, this.listeners('baz').length);
|
||||
});
|
||||
ee.on('baz', common.mustNotCall());
|
||||
ee.on('baz', common.mustNotCall());
|
||||
ee.on('baz', common.mustNotCall());
|
||||
assert.strictEqual(ee.listeners('baz').length, expectLength + 1);
|
||||
ee.removeAllListeners('baz');
|
||||
assert.strictEqual(ee.listeners('baz').length, 0);
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new events.EventEmitter();
|
||||
assert.strictEqual(ee, ee.removeAllListeners());
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new events.EventEmitter();
|
||||
ee._events = undefined;
|
||||
assert.strictEqual(ee, ee.removeAllListeners());
|
||||
}
|
||||
Generated
Vendored
+212
@@ -0,0 +1,212 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
var common = require('./common');
|
||||
var assert = require('assert');
|
||||
var EventEmitter = require('../');
|
||||
|
||||
var listener1 = function listener1() {};
|
||||
var listener2 = function listener2() {};
|
||||
|
||||
{
|
||||
var ee = new EventEmitter();
|
||||
ee.on('hello', listener1);
|
||||
ee.on('removeListener', common.mustCall(function(name, cb) {
|
||||
assert.strictEqual(name, 'hello');
|
||||
assert.strictEqual(cb, listener1);
|
||||
}));
|
||||
ee.removeListener('hello', listener1);
|
||||
var listeners = ee.listeners('hello');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 0);
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new EventEmitter();
|
||||
ee.on('hello', listener1);
|
||||
ee.on('removeListener', common.mustNotCall());
|
||||
ee.removeListener('hello', listener2);
|
||||
|
||||
var listeners = ee.listeners('hello');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 1);
|
||||
assert.strictEqual(listeners[0], listener1);
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new EventEmitter();
|
||||
ee.on('hello', listener1);
|
||||
ee.on('hello', listener2);
|
||||
|
||||
var listeners;
|
||||
ee.once('removeListener', common.mustCall(function(name, cb) {
|
||||
assert.strictEqual(name, 'hello');
|
||||
assert.strictEqual(cb, listener1);
|
||||
listeners = ee.listeners('hello');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 1);
|
||||
assert.strictEqual(listeners[0], listener2);
|
||||
}));
|
||||
ee.removeListener('hello', listener1);
|
||||
listeners = ee.listeners('hello');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 1);
|
||||
assert.strictEqual(listeners[0], listener2);
|
||||
ee.once('removeListener', common.mustCall(function(name, cb) {
|
||||
assert.strictEqual(name, 'hello');
|
||||
assert.strictEqual(cb, listener2);
|
||||
listeners = ee.listeners('hello');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 0);
|
||||
}));
|
||||
ee.removeListener('hello', listener2);
|
||||
listeners = ee.listeners('hello');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 0);
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new EventEmitter();
|
||||
|
||||
function remove1() {
|
||||
assert.fail('remove1 should not have been called');
|
||||
}
|
||||
|
||||
function remove2() {
|
||||
assert.fail('remove2 should not have been called');
|
||||
}
|
||||
|
||||
ee.on('removeListener', common.mustCall(function(name, cb) {
|
||||
if (cb !== remove1) return;
|
||||
this.removeListener('quux', remove2);
|
||||
this.emit('quux');
|
||||
}, 2));
|
||||
ee.on('quux', remove1);
|
||||
ee.on('quux', remove2);
|
||||
ee.removeListener('quux', remove1);
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new EventEmitter();
|
||||
ee.on('hello', listener1);
|
||||
ee.on('hello', listener2);
|
||||
|
||||
var listeners;
|
||||
ee.once('removeListener', common.mustCall(function(name, cb) {
|
||||
assert.strictEqual(name, 'hello');
|
||||
assert.strictEqual(cb, listener1);
|
||||
listeners = ee.listeners('hello');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 1);
|
||||
assert.strictEqual(listeners[0], listener2);
|
||||
ee.once('removeListener', common.mustCall(function(name, cb) {
|
||||
assert.strictEqual(name, 'hello');
|
||||
assert.strictEqual(cb, listener2);
|
||||
listeners = ee.listeners('hello');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 0);
|
||||
}));
|
||||
ee.removeListener('hello', listener2);
|
||||
listeners = ee.listeners('hello');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 0);
|
||||
}));
|
||||
ee.removeListener('hello', listener1);
|
||||
listeners = ee.listeners('hello');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 0);
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new EventEmitter();
|
||||
var listener3 = common.mustCall(function() {
|
||||
ee.removeListener('hello', listener4);
|
||||
}, 2);
|
||||
var listener4 = common.mustCall();
|
||||
|
||||
ee.on('hello', listener3);
|
||||
ee.on('hello', listener4);
|
||||
|
||||
// listener4 will still be called although it is removed by listener 3.
|
||||
ee.emit('hello');
|
||||
// This is so because the interal listener array at time of emit
|
||||
// was [listener3,listener4]
|
||||
|
||||
// Interal listener array [listener3]
|
||||
ee.emit('hello');
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new EventEmitter();
|
||||
|
||||
ee.once('hello', listener1);
|
||||
ee.on('removeListener', common.mustCall(function(eventName, listener) {
|
||||
assert.strictEqual(eventName, 'hello');
|
||||
assert.strictEqual(listener, listener1);
|
||||
}));
|
||||
ee.emit('hello');
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new EventEmitter();
|
||||
|
||||
assert.strictEqual(ee, ee.removeListener('foo', function() {}));
|
||||
}
|
||||
|
||||
// Verify that the removed listener must be a function
|
||||
assert.throws(function() {
|
||||
var ee = new EventEmitter();
|
||||
|
||||
ee.removeListener('foo', null);
|
||||
}, /^TypeError: The "listener" argument must be of type Function\. Received type object$/);
|
||||
|
||||
{
|
||||
var ee = new EventEmitter();
|
||||
var listener = function() {};
|
||||
ee._events = undefined;
|
||||
var e = ee.removeListener('foo', listener);
|
||||
assert.strictEqual(e, ee);
|
||||
}
|
||||
|
||||
{
|
||||
var ee = new EventEmitter();
|
||||
|
||||
ee.on('foo', listener1);
|
||||
ee.on('foo', listener2);
|
||||
var listeners = ee.listeners('foo');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 2);
|
||||
assert.strictEqual(listeners[0], listener1);
|
||||
assert.strictEqual(listeners[1], listener2);
|
||||
|
||||
ee.removeListener('foo', listener1);
|
||||
assert.strictEqual(ee._events.foo, listener2);
|
||||
|
||||
ee.on('foo', listener1);
|
||||
listeners = ee.listeners('foo');
|
||||
assert.ok(Array.isArray(listeners));
|
||||
assert.strictEqual(listeners.length, 2);
|
||||
assert.strictEqual(listeners[0], listener2);
|
||||
assert.strictEqual(listeners[1], listener1);
|
||||
|
||||
ee.removeListener('foo', listener1);
|
||||
assert.strictEqual(ee._events.foo, listener2);
|
||||
}
|
||||
Generated
Vendored
+31
@@ -0,0 +1,31 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
require('./common');
|
||||
var assert = require('assert');
|
||||
var events = require('../');
|
||||
|
||||
var e = new events.EventEmitter();
|
||||
|
||||
if (Object.create) assert.ok(!(e._events instanceof Object));
|
||||
assert.strictEqual(Object.keys(e._events).length, 0);
|
||||
e.setMaxListeners(5);
|
||||
assert.strictEqual(Object.keys(e._events).length, 0);
|
||||
Generated
Vendored
+45
@@ -0,0 +1,45 @@
|
||||
'use strict';
|
||||
|
||||
var common = require('./common');
|
||||
var EventEmitter = require('../');
|
||||
var assert = require('assert');
|
||||
|
||||
var ee = new EventEmitter();
|
||||
var handler = function() {};
|
||||
|
||||
assert.strictEqual(ee.eventNames().length, 0);
|
||||
|
||||
assert.strictEqual(ee._events.hasOwnProperty, undefined);
|
||||
assert.strictEqual(ee._events.toString, undefined);
|
||||
|
||||
ee.on('__defineGetter__', handler);
|
||||
ee.on('toString', handler);
|
||||
ee.on('__proto__', handler);
|
||||
|
||||
assert.strictEqual(ee.eventNames()[0], '__defineGetter__');
|
||||
assert.strictEqual(ee.eventNames()[1], 'toString');
|
||||
|
||||
assert.strictEqual(ee.listeners('__defineGetter__').length, 1);
|
||||
assert.strictEqual(ee.listeners('__defineGetter__')[0], handler);
|
||||
assert.strictEqual(ee.listeners('toString').length, 1);
|
||||
assert.strictEqual(ee.listeners('toString')[0], handler);
|
||||
|
||||
// Only run __proto__ tests if that property can actually be set
|
||||
if ({ __proto__: 'ok' }.__proto__ === 'ok') {
|
||||
assert.strictEqual(ee.eventNames().length, 3);
|
||||
assert.strictEqual(ee.eventNames()[2], '__proto__');
|
||||
assert.strictEqual(ee.listeners('__proto__').length, 1);
|
||||
assert.strictEqual(ee.listeners('__proto__')[0], handler);
|
||||
|
||||
ee.on('__proto__', common.mustCall(function(val) {
|
||||
assert.strictEqual(val, 1);
|
||||
}));
|
||||
ee.emit('__proto__', 1);
|
||||
|
||||
process.on('__proto__', common.mustCall(function(val) {
|
||||
assert.strictEqual(val, 1);
|
||||
}));
|
||||
process.emit('__proto__', 1);
|
||||
} else {
|
||||
console.log('# skipped __proto__')
|
||||
}
|
||||
Generated
Vendored
+66
@@ -0,0 +1,66 @@
|
||||
// Copyright Joyent, Inc. and other Node contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the
|
||||
// "Software"), to deal in the Software without restriction, including
|
||||
// without limitation the rights to use, copy, modify, merge, publish,
|
||||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
// persons to whom the Software is furnished to do so, subject to the
|
||||
// following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
var common = require('./common');
|
||||
var test = require('tape');
|
||||
var assert = require('assert');
|
||||
var EventEmitter = require('../').EventEmitter;
|
||||
var util = require('util');
|
||||
|
||||
util.inherits(MyEE, EventEmitter);
|
||||
|
||||
function MyEE(cb) {
|
||||
this.once(1, cb);
|
||||
this.emit(1);
|
||||
this.removeAllListeners();
|
||||
EventEmitter.call(this);
|
||||
}
|
||||
|
||||
var myee = new MyEE(common.mustCall());
|
||||
|
||||
|
||||
util.inherits(ErrorEE, EventEmitter);
|
||||
function ErrorEE() {
|
||||
this.emit('error', new Error('blerg'));
|
||||
}
|
||||
|
||||
assert.throws(function() {
|
||||
new ErrorEE();
|
||||
}, /blerg/);
|
||||
|
||||
test.onFinish(function() {
|
||||
assert.ok(!(myee._events instanceof Object));
|
||||
assert.strictEqual(Object.keys(myee._events).length, 0);
|
||||
});
|
||||
|
||||
|
||||
function MyEE2() {
|
||||
EventEmitter.call(this);
|
||||
}
|
||||
|
||||
MyEE2.prototype = new EventEmitter();
|
||||
|
||||
var ee1 = new MyEE2();
|
||||
var ee2 = new MyEE2();
|
||||
|
||||
ee1.on('x', function() {});
|
||||
|
||||
assert.strictEqual(ee2.listenerCount('x'), 0);
|
||||
Generated
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
var common = require('./common');
|
||||
var EventEmitter = require('../');
|
||||
var assert = require('assert');
|
||||
|
||||
var ee = new EventEmitter();
|
||||
var foo = Symbol('foo');
|
||||
var listener = common.mustCall();
|
||||
|
||||
ee.on(foo, listener);
|
||||
assert.strictEqual(ee.listeners(foo).length, 1);
|
||||
assert.strictEqual(ee.listeners(foo)[0], listener);
|
||||
|
||||
ee.emit(foo);
|
||||
|
||||
ee.removeAllListeners();
|
||||
assert.strictEqual(ee.listeners(foo).length, 0);
|
||||
|
||||
ee.on(foo, listener);
|
||||
assert.strictEqual(ee.listeners(foo).length, 1);
|
||||
assert.strictEqual(ee.listeners(foo)[0], listener);
|
||||
|
||||
ee.removeListener(foo, listener);
|
||||
assert.strictEqual(ee.listeners(foo).length, 0);
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"name": "@aws-sdk/lib-storage",
|
||||
"version": "3.842.0",
|
||||
"description": "Storage higher order operation",
|
||||
"main": "./dist-cjs/index.js",
|
||||
"module": "./dist-es/index.js",
|
||||
"types": "./dist-types/index.d.ts",
|
||||
"scripts": {
|
||||
"build": "concurrently 'yarn:build:cjs' 'yarn:build:es' 'yarn:build:types'",
|
||||
"build:cjs": "node ../../scripts/compilation/inline lib-storage",
|
||||
"build:es": "tsc -p tsconfig.es.json",
|
||||
"build:include:deps": "lerna run --scope $npm_package_name --include-dependencies build",
|
||||
"build:types": "tsc -p tsconfig.types.json",
|
||||
"build:types:downlevel": "downlevel-dts dist-types dist-types/ts3.4",
|
||||
"clean": "rimraf ./dist-* && rimraf *.tsbuildinfo",
|
||||
"extract:docs": "api-extractor run --local",
|
||||
"test": "yarn g:vitest run",
|
||||
"test:e2e": "yarn g:vitest run -c vitest.config.e2e.ts --mode development",
|
||||
"test:watch": "yarn g:vitest watch",
|
||||
"test:e2e:watch": "yarn g:vitest watch -c vitest.config.e2e.ts"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"author": {
|
||||
"name": "AWS SDK for JavaScript Team",
|
||||
"url": "https://aws.amazon.com/javascript/"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@smithy/abort-controller": "^4.0.4",
|
||||
"@smithy/middleware-endpoint": "^4.1.13",
|
||||
"@smithy/smithy-client": "^4.4.5",
|
||||
"buffer": "5.6.0",
|
||||
"events": "3.3.0",
|
||||
"stream-browserify": "3.0.0",
|
||||
"tslib": "^2.6.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@aws-sdk/client-s3": "^3.842.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@aws-sdk/client-s3": "3.842.0",
|
||||
"@smithy/types": "^4.3.1",
|
||||
"@tsconfig/recommended": "1.0.1",
|
||||
"@types/node": "^18.19.69",
|
||||
"concurrently": "7.0.0",
|
||||
"downlevel-dts": "0.10.1",
|
||||
"rimraf": "3.0.2",
|
||||
"typescript": "~5.8.3",
|
||||
"web-streams-polyfill": "3.2.1"
|
||||
},
|
||||
"typesVersions": {
|
||||
"<4.0": {
|
||||
"dist-types/*": [
|
||||
"dist-types/ts3.4/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"browser": {
|
||||
"./dist-es/runtimeConfig": "./dist-es/runtimeConfig.browser",
|
||||
"fs": false,
|
||||
"stream": "stream-browserify"
|
||||
},
|
||||
"react-native": {
|
||||
"./dist-es/runtimeConfig": "./dist-es/runtimeConfig.native"
|
||||
},
|
||||
"files": [
|
||||
"dist-*/**"
|
||||
],
|
||||
"homepage": "https://github.com/aws/aws-sdk-js-v3/tree/main/lib/lib-storage",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/aws/aws-sdk-js-v3.git",
|
||||
"directory": "lib/lib-storage"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user