From 9d6fd160c283590cefa6d1170b4724d04c1c3bb4 Mon Sep 17 00:00:00 2001 From: afrokick Date: Sun, 20 Feb 2022 00:28:40 +0300 Subject: [PATCH 01/27] init --- .gitignore | 3 +- .prettierignore | 2 + .prettierrc | 7 + changelog.md => CHANGELOG.md | 67 +- dist/peerjs.js | 10318 -------------- dist/peerjs.js.map | 1 - dist/peerjs.min.js | 70 - dist/peerjs.min.js.map | 1 - index.d.ts | 2 - lib/adapter.ts | 3 - lib/api.ts | 52 +- lib/baseconnection.ts | 14 +- lib/dataconnection.ts | 70 +- lib/encodingQueue.ts | 12 +- lib/enums.ts | 89 +- lib/exports.ts | 13 - lib/index.ts | 15 + lib/logger.ts | 79 +- lib/mediaconnection.ts | 38 +- lib/negotiator.ts | 163 +- lib/peer.ts | 107 +- lib/servermessage.ts | 2 +- lib/socket.ts | 28 +- lib/supports.ts | 55 +- lib/util.ts | 44 +- package-lock.json | 23827 ++++----------------------------- package.json | 16 +- tsconfig.json | 4 +- webrtc-adapter.d.ts | 15 - 29 files changed, 3064 insertions(+), 32053 deletions(-) create mode 100644 .prettierignore create mode 100644 .prettierrc rename changelog.md => CHANGELOG.md (82%) delete mode 100644 dist/peerjs.js delete mode 100644 dist/peerjs.js.map delete mode 100644 dist/peerjs.min.js delete mode 100644 dist/peerjs.min.js.map delete mode 100644 lib/adapter.ts delete mode 100644 lib/exports.ts create mode 100644 lib/index.ts delete mode 100644 webrtc-adapter.d.ts diff --git a/.gitignore b/.gitignore index baa2d2f1d..1366e77d4 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,5 @@ npm-debug.log test/output .tscache test/public -.vscode/ \ No newline at end of file +.vscode/ +dist diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..c18d9d665 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +node_modules/ +*.html diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..2aca597ba --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "trailingComma": "es5", + "singleQuote": true, + "printWidth": 120, + "arrowParens": "avoid", + "endOfLine": "auto" +} diff --git a/changelog.md b/CHANGELOG.md similarity index 82% rename from changelog.md rename to CHANGELOG.md index 2e692570c..8cdbae9c4 100644 --- a/changelog.md +++ b/CHANGELOG.md @@ -2,10 +2,72 @@ All notable changes will be documented in this file. -## vNEXT +## vNext ... + + +## v2.0.0 (upcoming) + +The main goals of the second version: + +- modernize the code base: use `es6` and latest tools +- target to the latest browsers API(you can use webrtc adapter to shim old browsers) + +### Breaking changes + +#### Drop ES5 supports + +If you need to support es5, you can recompile the lib from the sources or use the latest version from the v1 branch like `npm i peerjs@1`. + +#### Remove `webrtc-adapter` package from `dependencies` + +The modern browsers mostly works good without any additional libs like webrtc-adapter. + +You can increase cross browsers support by manually add `webrtc-adapter` package to your project: + +`npm install webrtc-adapter` + +Then import it as soon as possible. For example, you have an entry point for your application in the file `index.tsx`. So, lets add the import: + +``` +import 'webrtc-adapter'; // as soon as possible + +// +//... your startup code +// + +``` + +See more: https://github.com/webrtcHacks/adapter + +#### Remove browser detection features from the library. + +The `browser` field was removed from the `util` class +and the `OFFER` packet. + +#### The `main` field of `package.json` now points to the non minified version. + +Today, most projects use bundlers with a minification step. Sometimes, double minification can lead to issues. + +If you want to use the minified version, use it directly from the `dist` folder like: + +``` +import Peer from 'peerjs/dist/peerjs.min.js'; + +... +``` + +#### Use `ESBuild` as bundler. + +Parcel 1 was a good choice years ago, but now esbuild seems like simple and good solution! + +### Another changes + +- update `devDependencies` +- apply `Prettier` for the code style + ## 1.3.2 (2021-03-11) @@ -61,7 +123,7 @@ All notable changes will be documented in this file. ## 1.0.3 (2019-08-21) - add pingInterval option - + ## 1.0.2 (2019-07-20) @@ -97,6 +159,7 @@ Almost all project was refactored!!! - changed: fetch api instead of xhr ### Features + - added: heartbeat #502 ### Bug Fixes diff --git a/dist/peerjs.js b/dist/peerjs.js deleted file mode 100644 index b902845f0..000000000 --- a/dist/peerjs.js +++ /dev/null @@ -1,10318 +0,0 @@ -// modules are defined as an array -// [ module function, map of requires ] -// -// map of requires is short require name -> numeric require -// -// anything defined in a previous bundle is accessed via the -// orig method which is the require for previous bundles -parcelRequire = (function (modules, cache, entry, globalName) { - // Save the require from previous bundle to this closure if any - var previousRequire = typeof parcelRequire === 'function' && parcelRequire; - var nodeRequire = typeof require === 'function' && require; - - function newRequire(name, jumped) { - if (!cache[name]) { - if (!modules[name]) { - // if we cannot find the module within our internal map or - // cache jump to the current global require ie. the last bundle - // that was added to the page. - var currentRequire = typeof parcelRequire === 'function' && parcelRequire; - if (!jumped && currentRequire) { - return currentRequire(name, true); - } - - // If there are other bundles on this page the require from the - // previous one is saved to 'previousRequire'. Repeat this as - // many times as there are bundles until the module is found or - // we exhaust the require chain. - if (previousRequire) { - return previousRequire(name, true); - } - - // Try the node require function if it exists. - if (nodeRequire && typeof name === 'string') { - return nodeRequire(name); - } - - var err = new Error('Cannot find module \'' + name + '\''); - err.code = 'MODULE_NOT_FOUND'; - throw err; - } - - localRequire.resolve = resolve; - localRequire.cache = {}; - - var module = cache[name] = new newRequire.Module(name); - - modules[name][0].call(module.exports, localRequire, module, module.exports, this); - } - - return cache[name].exports; - - function localRequire(x){ - return newRequire(localRequire.resolve(x)); - } - - function resolve(x){ - return modules[name][1][x] || x; - } - } - - function Module(moduleName) { - this.id = moduleName; - this.bundle = newRequire; - this.exports = {}; - } - - newRequire.isParcelRequire = true; - newRequire.Module = Module; - newRequire.modules = modules; - newRequire.cache = cache; - newRequire.parent = previousRequire; - newRequire.register = function (id, exports) { - modules[id] = [function (require, module) { - module.exports = exports; - }, {}]; - }; - - var error; - for (var i = 0; i < entry.length; i++) { - try { - newRequire(entry[i]); - } catch (e) { - // Save first error but execute all entries - if (!error) { - error = e; - } - } - } - - if (entry.length) { - // Expose entry point to Node, AMD or browser globals - // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js - var mainExports = newRequire(entry[entry.length - 1]); - - // CommonJS - if (typeof exports === "object" && typeof module !== "undefined") { - module.exports = mainExports; - - // RequireJS - } else if (typeof define === "function" && define.amd) { - define(function () { - return mainExports; - }); - - // +``` + #### Use `ESBuild` as bundler. Parcel 1 was a good choice years ago, but now esbuild seems like simple and good solution! diff --git a/package.json b/package.json index d82320384..e2443e8c0 100644 --- a/package.json +++ b/package.json @@ -31,8 +31,9 @@ "dev": "", "esbuild": "esbuild lib/index.ts --bundle --sourcemap --target=es6", "build": "npm run esbuild -- --outfile=dist/peerjs.js && npm run esbuild -- --minify --outfile=dist/peerjs.min.js", - "prepublishOnly": "npm run test && npm run build", - "test": "mocha -r ts-node/register -r jsdom-global/register test/**/*.ts" + "prepublishOnly": "npm run tsc-check && npm run test && npm run build", + "test": "mocha -r ts-node/register -r jsdom-global/register test/**/*.ts", + "tsc-check": "tsc --noEmit" }, "release": { "branch": "master" From a930635980e69838ee5f54d93a6d196becf99c3d Mon Sep 17 00:00:00 2001 From: afrokick Date: Sun, 20 Feb 2022 01:27:39 +0300 Subject: [PATCH 03/27] rename util to Utils --- CHANGELOG.md | 2 + index.d.ts | 35 ++-- lib/api.ts | 6 +- lib/dataconnection.ts | 24 +-- lib/index.ts | 14 +- lib/mediaconnection.ts | 4 +- lib/negotiator.ts | 5 +- lib/peer.ts | 20 +-- lib/servermessage.ts | 2 +- lib/supports.ts | 6 +- lib/{util.ts => utils.ts} | 16 +- package-lock.json | 63 +------- package.json | 5 +- test/faker.ts | 93 +++++------ test/logger.ts | 80 +++++----- test/peer.ts | 328 +++++++++++++++++++------------------- test/setup.ts | 10 +- test/util.ts | 14 +- 18 files changed, 337 insertions(+), 390 deletions(-) rename lib/{util.ts => utils.ts} (88%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18b64b137..4993ed22e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,6 +78,8 @@ Parcel 1 was a good choice years ago, but now esbuild seems like simple and good - update `devDependencies` - apply `Prettier` for the code style +- rename `util` to `Utils` +- remove `peerjs` export. diff --git a/index.d.ts b/index.d.ts index 7509223e8..7d8490a24 100644 --- a/index.d.ts +++ b/index.d.ts @@ -45,40 +45,37 @@ declare class Peer { * @param event Event name * @param cb id is the brokering ID of the peer */ - on(event: "open", cb: (id: string) => void): void; + on(event: 'open', cb: (id: string) => void): void; /** * Emitted when a new data connection is established from a remote peer. * @param event Event name * @param cb Callback Function */ - on( - event: "connection", - cb: (dataConnection: Peer.DataConnection) => void - ): void; + on(event: 'connection', cb: (dataConnection: Peer.DataConnection) => void): void; /** * Emitted when a remote peer attempts to call you. * @param event Event name * @param cb Callback Function */ - on(event: "call", cb: (mediaConnection: Peer.MediaConnection) => void): void; + on(event: 'call', cb: (mediaConnection: Peer.MediaConnection) => void): void; /** * Emitted when the peer is destroyed and can no longer accept or create any new connections. * @param event Event name * @param cb Callback Function */ - on(event: "close", cb: () => void): void; + on(event: 'close', cb: () => void): void; /** * Emitted when the peer is disconnected from the signalling server * @param event Event name * @param cb Callback Function */ - on(event: "disconnected", cb: () => void): void; + on(event: 'disconnected', cb: () => void): void; /** * Errors on the peer are almost always fatal and will destroy the peer. * @param event Event name * @param cb Callback Function */ - on(event: "error", cb: (err: any) => void): void; + on(event: 'error', cb: (err: any) => void): void; /** * Remove event listeners.(EventEmitter3) * @param {String} event The event we want to remove. @@ -161,10 +158,10 @@ declare namespace Peer { send(data: any): void; close(): void; on(event: string, cb: () => void): void; - on(event: "data", cb: (data: any) => void): void; - on(event: "open", cb: () => void): void; - on(event: "close", cb: () => void): void; - on(event: "error", cb: (err: any) => void): void; + on(event: 'data', cb: (data: any) => void): void; + on(event: 'open', cb: () => void): void; + on(event: 'close', cb: () => void): void; + on(event: 'error', cb: (err: any) => void): void; off(event: string, fn: Function, once?: boolean): void; dataChannel: RTCDataChannel; label: string; @@ -184,9 +181,9 @@ declare namespace Peer { answer(stream?: MediaStream, options?: AnswerOption): void; close(): void; on(event: string, cb: () => void): void; - on(event: "stream", cb: (stream: MediaStream) => void): void; - on(event: "close", cb: () => void): void; - on(event: "error", cb: (err: any) => void): void; + on(event: 'stream', cb: (stream: MediaStream) => void): void; + on(event: 'close', cb: () => void): void; + on(event: 'error', cb: (err: any) => void): void; off(event: string, fn: Function, once?: boolean): void; open: boolean; metadata: any; @@ -195,7 +192,7 @@ declare namespace Peer { type: string; } - interface UtilSupportsObj { + interface Features { webRTC: boolean; audioVideo: boolean; data: boolean; @@ -203,7 +200,7 @@ declare namespace Peer { reliable: boolean; } - interface util { - supports: UtilSupportsObj; + interface Utils { + readonly features: Features; } } diff --git a/lib/api.ts b/lib/api.ts index 94c78cb47..890efe4af 100644 --- a/lib/api.ts +++ b/lib/api.ts @@ -1,4 +1,4 @@ -import { util } from './util'; +import { Utils } from './utils'; import logger from './logger'; export class API { @@ -31,7 +31,7 @@ export class API { let pathError = ''; - if (this._options.path === '/' && this._options.host !== util.CLOUD_HOST) { + if (this._options.path === '/' && this._options.host !== Utils.CLOUD_HOST) { pathError = ' If you passed in a `path` to your self-hosted PeerServer, ' + "you'll also need to pass in that same path when creating a new " + @@ -53,7 +53,7 @@ export class API { if (response.status === 401) { let helpfulError = ''; - if (this._options.host === util.CLOUD_HOST) { + if (this._options.host === Utils.CLOUD_HOST) { helpfulError = "It looks like you're using the cloud server. You can email " + 'team@peerjs.com to enable peer listing for your API key.'; diff --git a/lib/dataconnection.ts b/lib/dataconnection.ts index ae49288e9..802231df8 100644 --- a/lib/dataconnection.ts +++ b/lib/dataconnection.ts @@ -1,4 +1,4 @@ -import { util } from './util'; +import { Utils } from './utils'; import logger from './logger'; import { Negotiator } from './negotiator'; import { ConnectionType, ConnectionEventType, SerializationType, ServerMessageType } from './enums'; @@ -51,7 +51,7 @@ export class DataConnection extends BaseConnection implements IDataConnection { constructor(peerId: string, provider: Peer, options: any) { super(peerId, provider, options); - this.connectionId = this.options.connectionId || DataConnection.ID_PREFIX + util.randomToken(); + this.connectionId = this.options.connectionId || DataConnection.ID_PREFIX + Utils.randomToken(); this.label = this.options.label || this.connectionId; this.serialization = this.options.serialization || SerializationType.Binary; @@ -82,7 +82,7 @@ export class DataConnection extends BaseConnection implements IDataConnection { } private _configureDataChannel(): void { - if (!util.supports.binaryBlob || util.supports.reliable) { + if (!Utils.supports.binaryBlob || Utils.supports.reliable) { this.dataChannel.binaryType = 'arraybuffer'; } @@ -115,17 +115,17 @@ export class DataConnection extends BaseConnection implements IDataConnection { if (isBinarySerialization) { if (datatype === Blob) { // Datatype should never be blob - util.blobToArrayBuffer(data as Blob, ab => { - const unpackedData = util.unpack(ab); + Utils.blobToArrayBuffer(data as Blob, ab => { + const unpackedData = Utils.unpack(ab); this.emit(ConnectionEventType.Data, unpackedData); }); return; } else if (datatype === ArrayBuffer) { - deserializedData = util.unpack(data as ArrayBuffer); + deserializedData = Utils.unpack(data as ArrayBuffer); } else if (datatype === String) { // String fallback for binary data for browsers that don't support binary yet - const ab = util.binaryStringToArrayBuffer(data as string); - deserializedData = util.unpack(ab); + const ab = Utils.binaryStringToArrayBuffer(data as string); + deserializedData = Utils.unpack(ab); } } else if (this.serialization === SerializationType.JSON) { deserializedData = this.parse(data as string); @@ -219,14 +219,14 @@ export class DataConnection extends BaseConnection implements IDataConnection { if (this.serialization === SerializationType.JSON) { this._bufferedSend(this.stringify(data)); } else if (this.serialization === SerializationType.Binary || this.serialization === SerializationType.BinaryUTF8) { - const blob = util.pack(data); + const blob = Utils.pack(data); - if (!chunked && blob.size > util.chunkedMTU) { + if (!chunked && blob.size > Utils.chunkedMTU) { this._sendChunks(blob); return; } - if (!util.supports.binaryBlob) { + if (!Utils.supports.binaryBlob) { // We only do this if we really need to (e.g. blobs are not supported), // because this conversion is costly. this._encodingQueue.enque(blob); @@ -295,7 +295,7 @@ export class DataConnection extends BaseConnection implements IDataConnection { } private _sendChunks(blob: Blob): void { - const blobs = util.chunk(blob); + const blobs = Utils.chunk(blob); logger.log(`DC#${this.connectionId} Try to send ${blobs.length} chunks...`); for (let blob of blobs) { diff --git a/lib/index.ts b/lib/index.ts index f79035056..38409847b 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,15 +1,11 @@ -import { util } from './util'; +import { Utils } from './utils'; import { Peer } from './peer'; -export const peerjs = { - Peer, - util, -}; +export { Peer, Utils }; export default Peer; -if (typeof window !== 'undefined') { - (window as any).peerjs = peerjs; - /** @deprecated Should use peerjs namespace */ - (window as any).Peer = Peer; +if (typeof window === 'object') { + // @ts-expect-error + window.Peer = Peer; } diff --git a/lib/mediaconnection.ts b/lib/mediaconnection.ts index 3eab4e7df..81a53e394 100644 --- a/lib/mediaconnection.ts +++ b/lib/mediaconnection.ts @@ -1,4 +1,4 @@ -import { util } from './util'; +import { Utils } from './utils'; import logger from './logger'; import { Negotiator } from './negotiator'; import { ConnectionType, ConnectionEventType, ServerMessageType } from './enums'; @@ -32,7 +32,7 @@ export class MediaConnection extends BaseConnection { super(peerId, provider, options); this._localStream = this.options._stream; - this.connectionId = this.options.connectionId || MediaConnection.ID_PREFIX + util.randomToken(); + this.connectionId = this.options.connectionId || MediaConnection.ID_PREFIX + Utils.randomToken(); this._negotiator = new Negotiator(this); diff --git a/lib/negotiator.ts b/lib/negotiator.ts index c9af56b62..448b19f24 100644 --- a/lib/negotiator.ts +++ b/lib/negotiator.ts @@ -1,10 +1,11 @@ -import { util } from './util'; import logger from './logger'; import type { MediaConnection } from './mediaconnection'; import type { DataConnection } from './dataconnection'; import { ConnectionType, PeerErrorType, ConnectionEventType, ServerMessageType } from './enums'; import { BaseConnection } from './baseconnection'; +function noop(): void {} + /** * Manages all negotiations between Peers. */ @@ -95,7 +96,7 @@ export class Negotiator { logger.log('iceConnectionState changed to disconnected on the connection with ' + peerId); break; case 'completed': - peerConnection.onicecandidate = util.noop; + peerConnection.onicecandidate = noop; break; } diff --git a/lib/peer.ts b/lib/peer.ts index 3c4c81f9b..e5727899b 100644 --- a/lib/peer.ts +++ b/lib/peer.ts @@ -1,5 +1,5 @@ import { EventEmitter } from 'eventemitter3'; -import { util } from './util'; +import { Utils } from './utils'; import logger, { LogLevel } from './logger'; import { Socket } from './socket'; import { MediaConnection } from './mediaconnection'; @@ -95,12 +95,12 @@ export class Peer extends EventEmitter { // Configurize options options = { debug: 0, // 1: Errors, 2: Warnings, 3: All logs - host: util.CLOUD_HOST, - port: util.CLOUD_PORT, + host: Utils.CLOUD_HOST, + port: Utils.CLOUD_PORT, path: '/', key: Peer.DEFAULT_KEY, - token: util.randomToken(), - config: util.defaultConfig, + token: Utils.randomToken(), + config: Utils.defaultConfig, ...options, }; this._options = options; @@ -121,9 +121,9 @@ export class Peer extends EventEmitter { } // Set whether we use SSL to same as current host - if (this._options.secure === undefined && this._options.host !== util.CLOUD_HOST) { - this._options.secure = util.isSecure(); - } else if (this._options.host == util.CLOUD_HOST) { + if (this._options.secure === undefined && this._options.host !== Utils.CLOUD_HOST) { + this._options.secure = Utils.isSecure(); + } else if (this._options.host == Utils.CLOUD_HOST) { this._options.secure = true; } // Set a custom log function if present @@ -138,13 +138,13 @@ export class Peer extends EventEmitter { // Sanity checks // Ensure WebRTC supported - if (!util.supports.audioVideo && !util.supports.data) { + if (!Utils.supports.audioVideo && !Utils.supports.data) { this._delayedAbort(PeerErrorType.BrowserIncompatible, 'The current browser does not support WebRTC'); return; } // Ensure alphanumeric id - if (!!userId && !util.validateId(userId)) { + if (!!userId && !Utils.validateId(userId)) { this._delayedAbort(PeerErrorType.InvalidID, `ID "${userId}" is invalid`); return; } diff --git a/lib/servermessage.ts b/lib/servermessage.ts index 56c4117ec..8385438d3 100644 --- a/lib/servermessage.ts +++ b/lib/servermessage.ts @@ -1,6 +1,6 @@ import type { ServerMessageType } from './enums'; -export class ServerMessage { +export interface ServerMessage { type: ServerMessageType; payload: any; src: string; diff --git a/lib/supports.ts b/lib/supports.ts index d385c72a8..db9df9bd2 100644 --- a/lib/supports.ts +++ b/lib/supports.ts @@ -4,7 +4,11 @@ export const Supports = new (class { } isUnifiedPlanSupported(): boolean { - if (!window.RTCRtpTransceiver || !('currentDirection' in RTCRtpTransceiver.prototype)) return false; + if ( + (typeof window !== 'undefined' && !window.RTCRtpTransceiver) || + !('currentDirection' in RTCRtpTransceiver.prototype) + ) + return false; let tempPc: RTCPeerConnection; let supported = false; diff --git a/lib/util.ts b/lib/utils.ts similarity index 88% rename from lib/util.ts rename to lib/utils.ts index 90cca1b33..5f4561f02 100644 --- a/lib/util.ts +++ b/lib/utils.ts @@ -1,6 +1,6 @@ import * as BinaryPack from 'peerjs-js-binarypack'; import { Supports } from './supports'; -import type { UtilSupportsObj } from '..'; +import type { Features } from '..'; const DEFAULT_CONFIG = { iceServers: [ @@ -10,22 +10,18 @@ const DEFAULT_CONFIG = { sdpSemantics: 'unified-plan', }; -export const util = new (class { - noop(): void {} - +export const Utils = new (class { readonly CLOUD_HOST = '0.peerjs.com'; readonly CLOUD_PORT = 443; - // Browsers that need chunking: - readonly chunkedBrowsers = { Chrome: 1, chrome: 1 }; readonly chunkedMTU = 16300; // The original 60000 bytes setting does not work when sending data from Firefox to Chrome, which is "cut off" after 16384 bytes and delivered individually. // Returns browser-agnostic default config readonly defaultConfig = DEFAULT_CONFIG; // Lists which features are supported - readonly supports = (function () { - const supported: UtilSupportsObj = { + readonly supports: Features = (function () { + const supported: Features = { webRTC: Supports.isWebRTCSupported(), audioVideo: true, data: false, @@ -83,13 +79,13 @@ export const util = new (class { chunk(blob: Blob): { __peerData: number; n: number; total: number; data: Blob }[] { const chunks = []; const size = blob.size; - const total = Math.ceil(size / util.chunkedMTU); + const total = Math.ceil(size / Utils.chunkedMTU); let index = 0; let start = 0; while (start < size) { - const end = Math.min(size, start + util.chunkedMTU); + const end = Math.min(size, start + Utils.chunkedMTU); const b = blob.slice(start, end); const chunk = { diff --git a/package-lock.json b/package-lock.json index 5295b289b..140160bf7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,14 +9,13 @@ "version": "1.3.2", "license": "MIT", "dependencies": { - "@types/node": "^17.0.18", "eventemitter3": "^3.1.2", - "peerjs-js-binarypack": "1.0.1", - "webrtc-adapter": "^7.7.1" + "peerjs-js-binarypack": "1.0.1" }, "devDependencies": { "@types/chai": "^4.3.0", "@types/mocha": "^9.1.0", + "@types/node": "^17.0.18", "chai": "^4.3.6", "esbuild": "^0.14.23", "jsdom": "^19.0.0", @@ -97,7 +96,8 @@ "node_modules/@types/node": { "version": "17.0.18", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.18.tgz", - "integrity": "sha512-eKj4f/BsN/qcculZiRSujogjvp5O/k4lOW5m35NopjZM/QwLOR075a8pJW5hD+Rtdm2DaCVPENS6KtSQnUD6BA==" + "integrity": "sha512-eKj4f/BsN/qcculZiRSujogjvp5O/k4lOW5m35NopjZM/QwLOR075a8pJW5hD+Rtdm2DaCVPENS6KtSQnUD6BA==", + "dev": true }, "node_modules/@ungap/promise-all-settled": { "version": "1.1.2", @@ -1883,18 +1883,6 @@ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, - "node_modules/rtcpeerconnection-shim": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/rtcpeerconnection-shim/-/rtcpeerconnection-shim-1.2.15.tgz", - "integrity": "sha512-C6DxhXt7bssQ1nHb154lqeL0SXz5Dx4RczXZu2Aa/L1NJFnEVDxFwCBo3fqtuljhHIGceg5JKBV4XJ0gW5JKyw==", - "dependencies": { - "sdp": "^2.6.0" - }, - "engines": { - "node": ">=6.0.0", - "npm": ">=3.10.0" - } - }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -1907,11 +1895,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "node_modules/sdp": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/sdp/-/sdp-2.12.0.tgz", - "integrity": "sha512-jhXqQAQVM+8Xj5EjJGVweuEzgtGWb3tmEEpl3CLP3cStInSbVHSg0QWOGQzNq8pSID4JkpeV2mPqlMDLrm0/Vw==" - }, "node_modules/serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -2133,19 +2116,6 @@ "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", "dev": true }, - "node_modules/webrtc-adapter": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-7.7.1.tgz", - "integrity": "sha512-TbrbBmiQBL9n0/5bvDdORc6ZfRY/Z7JnEj+EYOD1ghseZdpJ+nF2yx14k3LgQKc7JZnG7HAcL+zHnY25So9d7A==", - "dependencies": { - "rtcpeerconnection-shim": "^1.2.15", - "sdp": "^2.12.0" - }, - "engines": { - "node": ">=6.0.0", - "npm": ">=3.10.0" - } - }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -2393,7 +2363,8 @@ "@types/node": { "version": "17.0.18", "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.18.tgz", - "integrity": "sha512-eKj4f/BsN/qcculZiRSujogjvp5O/k4lOW5m35NopjZM/QwLOR075a8pJW5hD+Rtdm2DaCVPENS6KtSQnUD6BA==" + "integrity": "sha512-eKj4f/BsN/qcculZiRSujogjvp5O/k4lOW5m35NopjZM/QwLOR075a8pJW5hD+Rtdm2DaCVPENS6KtSQnUD6BA==", + "dev": true }, "@ungap/promise-all-settled": { "version": "1.1.2", @@ -3640,14 +3611,6 @@ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", "dev": true }, - "rtcpeerconnection-shim": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/rtcpeerconnection-shim/-/rtcpeerconnection-shim-1.2.15.tgz", - "integrity": "sha512-C6DxhXt7bssQ1nHb154lqeL0SXz5Dx4RczXZu2Aa/L1NJFnEVDxFwCBo3fqtuljhHIGceg5JKBV4XJ0gW5JKyw==", - "requires": { - "sdp": "^2.6.0" - } - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -3660,11 +3623,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "sdp": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/sdp/-/sdp-2.12.0.tgz", - "integrity": "sha512-jhXqQAQVM+8Xj5EjJGVweuEzgtGWb3tmEEpl3CLP3cStInSbVHSg0QWOGQzNq8pSID4JkpeV2mPqlMDLrm0/Vw==" - }, "serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -3816,15 +3774,6 @@ "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", "dev": true }, - "webrtc-adapter": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-7.7.1.tgz", - "integrity": "sha512-TbrbBmiQBL9n0/5bvDdORc6ZfRY/Z7JnEj+EYOD1ghseZdpJ+nF2yx14k3LgQKc7JZnG7HAcL+zHnY25So9d7A==", - "requires": { - "rtcpeerconnection-shim": "^1.2.15", - "sdp": "^2.12.0" - } - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", diff --git a/package.json b/package.json index e2443e8c0..2407918e9 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "devDependencies": { "@types/chai": "^4.3.0", "@types/mocha": "^9.1.0", + "@types/node": "^17.0.18", "chai": "^4.3.6", "esbuild": "^0.14.23", "jsdom": "^19.0.0", @@ -53,10 +54,8 @@ "typescript": "^4.5.5" }, "dependencies": { - "@types/node": "^17.0.18", "eventemitter3": "^3.1.2", - "peerjs-js-binarypack": "1.0.1", - "webrtc-adapter": "^7.7.1" + "peerjs-js-binarypack": "1.0.1" }, "collective": { "type": "opencollective", diff --git a/test/faker.ts b/test/faker.ts index e5772e631..7767997d4 100644 --- a/test/faker.ts +++ b/test/faker.ts @@ -1,66 +1,67 @@ import { WebSocket } from 'mock-socket'; -import 'webrtc-adapter'; const fakeGlobals = { - WebSocket, - MediaStream: class MediaStream { - private _tracks: MediaStreamTrack[] = []; + WebSocket, + MediaStream: class MediaStream { + private _tracks: MediaStreamTrack[] = []; - constructor(tracks?: MediaStreamTrack[]) { - if (tracks) { - this._tracks = tracks; - } - } + constructor(tracks?: MediaStreamTrack[]) { + if (tracks) { + this._tracks = tracks; + } + } - getTracks(): MediaStreamTrack[] { - return this._tracks; - } + getTracks(): MediaStreamTrack[] { + return this._tracks; + } - addTrack(track: MediaStreamTrack) { - this._tracks.push(track); - } - }, - MediaStreamTrack: class MediaStreamTrack { - kind: string; - id: string; + addTrack(track: MediaStreamTrack) { + this._tracks.push(track); + } + }, + MediaStreamTrack: class MediaStreamTrack { + kind: string; + id: string; - private static _idCounter = 0; + private static _idCounter = 0; - constructor() { - this.id = `track#${fakeGlobals.MediaStreamTrack._idCounter++}`; - } - }, - RTCPeerConnection: class RTCPeerConnection { - private _senders: RTCRtpSender[] = []; + constructor() { + this.id = `track#${fakeGlobals.MediaStreamTrack._idCounter++}`; + } + }, + RTCPeerConnection: class RTCPeerConnection { + private _senders: RTCRtpSender[] = []; - close() { } + close() {} - addTrack(track: MediaStreamTrack, ..._stream: MediaStream[]): RTCRtpSender { - const newSender = new RTCRtpSender(); - newSender.replaceTrack(track); + addTrack(track: MediaStreamTrack, ..._stream: MediaStream[]): RTCRtpSender { + const newSender = new RTCRtpSender(); + newSender.replaceTrack(track); - this._senders.push(newSender); + this._senders.push(newSender); - return newSender; - } + return newSender; + } - // removeTrack(_: RTCRtpSender): void { } + // removeTrack(_: RTCRtpSender): void { } - getSenders(): RTCRtpSender[] { return this._senders; } - }, - RTCRtpSender: class RTCRtpSender { - readonly dtmf: RTCDTMFSender | null; - readonly rtcpTransport: RTCDtlsTransport | null; - track: MediaStreamTrack | null; - readonly transport: RTCDtlsTransport | null; + getSenders(): RTCRtpSender[] { + return this._senders; + } + }, + RTCRtpSender: class RTCRtpSender { + readonly dtmf: RTCDTMFSender | null; + readonly rtcpTransport: RTCDtlsTransport | null; + track: MediaStreamTrack | null; + readonly transport: RTCDtlsTransport | null; - replaceTrack(withTrack: MediaStreamTrack | null): Promise { - this.track = withTrack; + replaceTrack(withTrack: MediaStreamTrack | null): Promise { + this.track = withTrack; - return Promise.resolve(); - } + return Promise.resolve(); } -} + }, +}; Object.assign(global, fakeGlobals); Object.assign(window, fakeGlobals); diff --git a/test/logger.ts b/test/logger.ts index 812d58933..379bbdd90 100644 --- a/test/logger.ts +++ b/test/logger.ts @@ -1,55 +1,55 @@ -import { expect } from "chai"; -import Logger, { LogLevel } from "../lib/logger"; - -describe("Logger", function () { - let oldLoggerPrint; - before(() => { - //@ts-ignore - oldLoggerPrint = Logger._print; - }); +import { expect } from 'chai'; +import Logger, { LogLevel } from '../lib/logger'; - it("should be disabled by default", function () { - expect(Logger.logLevel).to.eq(LogLevel.Disabled); - }); +describe('Logger', function () { + let oldLoggerPrint; + before(() => { + //@ts-ignore + oldLoggerPrint = Logger._print; + }); - it("should be accept new log level", function () { - const checkedLevels = []; + it('should be disabled by default', function () { + expect(Logger.logLevel).to.eq(LogLevel.Disabled); + }); - Logger.setLogFunction((logLevel) => { - checkedLevels.push(logLevel); - }); + it('should be accept new log level', function () { + const checkedLevels = []; - Logger.logLevel = LogLevel.Warnings; + Logger.setLogFunction(logLevel => { + checkedLevels.push(logLevel); + }); - expect(Logger.logLevel).to.eq(LogLevel.Warnings); + Logger.logLevel = LogLevel.Warnings; - Logger.log(''); - Logger.warn(''); - Logger.error(''); + expect(Logger.logLevel).to.eq(LogLevel.Warnings); - expect(checkedLevels).to.deep.eq([LogLevel.Warnings, LogLevel.Errors]); - }); + Logger.log(''); + Logger.warn(''); + Logger.error(''); - it("should accept new log function", function () { - Logger.logLevel = LogLevel.All; + expect(checkedLevels).to.deep.eq([LogLevel.Warnings, LogLevel.Errors]); + }); - const checkedLevels = []; - const testMessage = 'test it'; + it('should accept new log function', function () { + Logger.logLevel = LogLevel.All; - Logger.setLogFunction((logLevel, ...args) => { - checkedLevels.push(logLevel); + const checkedLevels = []; + const testMessage = 'test it'; - expect(args[0]).to.eq(testMessage); - }); + Logger.setLogFunction((logLevel, ...args) => { + checkedLevels.push(logLevel); - Logger.log(testMessage); - Logger.warn(testMessage); - Logger.error(testMessage); - - expect(checkedLevels).to.deep.eq([LogLevel.All, LogLevel.Warnings, LogLevel.Errors]); + expect(args[0]).to.eq(testMessage); }); - after(() => { - Logger.setLogFunction(oldLoggerPrint); - }) + Logger.log(testMessage); + Logger.warn(testMessage); + Logger.error(testMessage); + + expect(checkedLevels).to.deep.eq([LogLevel.All, LogLevel.Warnings, LogLevel.Errors]); + }); + + after(() => { + Logger.setLogFunction(oldLoggerPrint); + }); }); diff --git a/test/peer.ts b/test/peer.ts index b6dbf715c..4d328c722 100644 --- a/test/peer.ts +++ b/test/peer.ts @@ -1,217 +1,217 @@ -import "./setup"; -import { expect } from "chai"; -import { Peer } from "../lib/peer"; +import './setup'; +import { expect } from 'chai'; +import { Peer } from '../lib'; import { Server } from 'mock-socket'; -import { ConnectionType, ServerMessageType, PeerErrorType, PeerEventType } from "../lib/enums"; +import { ConnectionType, ServerMessageType, PeerErrorType, PeerEventType } from '../lib/enums'; const createMockServer = (): Server => { - const fakeURL = 'ws://localhost:8080/peerjs?key=peerjs&id=1&token=testToken'; - const mockServer = new Server(fakeURL); + const fakeURL = 'ws://localhost:8080/peerjs?key=peerjs&id=1&token=testToken'; + const mockServer = new Server(fakeURL); - mockServer.on('connection', socket => { - //@ts-ignore - socket.on('message', data => { - socket.send('test message from mock server'); - }); - - socket.send(JSON.stringify({ type: ServerMessageType.Open })); + mockServer.on('connection', socket => { + //@ts-ignore + socket.on('message', data => { + socket.send('test message from mock server'); }); - return mockServer; -} -describe("Peer", function () { - describe("after construct without parameters", function () { - it("shouldn't contains any connection", function () { - const peer = new Peer(); + socket.send(JSON.stringify({ type: ServerMessageType.Open })); + }); - expect(peer.open).to.be.false; - expect(peer.connections).to.be.empty; - expect(peer.id).to.be.null; - expect(peer.disconnected).to.be.false; - expect(peer.destroyed).to.be.false; + return mockServer; +}; +describe('Peer', function () { + describe('after construct without parameters', function () { + it("shouldn't contains any connection", function () { + const peer = new Peer(); - peer.destroy(); - }); + expect(peer.open).to.be.false; + expect(peer.connections).to.be.empty; + expect(peer.id).to.be.null; + expect(peer.disconnected).to.be.false; + expect(peer.destroyed).to.be.false; + + peer.destroy(); }); + }); - describe("after construct with parameters", function () { - it("should contains id and key", function () { - const peer = new Peer('1', { key: 'anotherKey' }); + describe('after construct with parameters', function () { + it('should contains id and key', function () { + const peer = new Peer('1', { key: 'anotherKey' }); - expect(peer.id).to.eq('1'); - expect(peer.options.key).to.eq('anotherKey'); + expect(peer.id).to.eq('1'); + expect(peer.options.key).to.eq('anotherKey'); - peer.destroy(); - }); + peer.destroy(); }); + }); - describe("after call to peer #2", function () { - let mockServer; - - before(function () { - mockServer = createMockServer(); - }); + describe('after call to peer #2', function () { + let mockServer; - it("Peer#1 should has id #1", function (done) { - const peer1 = new Peer('1', { port: 8080, host: 'localhost' }); - expect(peer1.open).to.be.false; + before(function () { + mockServer = createMockServer(); + }); - const mediaOptions = { - metadata: { var: '123' }, - constraints: { - mandatory: { - OfferToReceiveAudio: true, - OfferToReceiveVideo: true - } - } - }; - - const track = new MediaStreamTrack(); - const mediaStream = new MediaStream([track]); - - const mediaConnection = peer1.call('2', mediaStream, { ...mediaOptions }); - - expect(mediaConnection.connectionId).to.be.a('string'); - expect(mediaConnection.type).to.eq(ConnectionType.Media); - expect(mediaConnection.peer).to.eq('2'); - expect(mediaConnection.options).to.include(mediaOptions); - expect(mediaConnection.metadata).to.deep.eq(mediaOptions.metadata); - expect(mediaConnection.peerConnection.getSenders()[0].track.id).to.eq(track.id); - - peer1.once('open', (id) => { - expect(id).to.be.eq('1'); - //@ts-ignore - expect(peer1._lastServerId).to.be.eq('1'); - expect(peer1.disconnected).to.be.false; - expect(peer1.destroyed).to.be.false; - expect(peer1.open).to.be.true; - - peer1.destroy(); + it('Peer#1 should has id #1', function (done) { + const peer1 = new Peer('1', { port: 8080, host: 'localhost' }); + expect(peer1.open).to.be.false; + + const mediaOptions = { + metadata: { var: '123' }, + constraints: { + mandatory: { + OfferToReceiveAudio: true, + OfferToReceiveVideo: true, + }, + }, + }; + + const track = new MediaStreamTrack(); + const mediaStream = new MediaStream([track]); + + const mediaConnection = peer1.call('2', mediaStream, { ...mediaOptions }); + + expect(mediaConnection.connectionId).to.be.a('string'); + expect(mediaConnection.type).to.eq(ConnectionType.Media); + expect(mediaConnection.peer).to.eq('2'); + expect(mediaConnection.options).to.include(mediaOptions); + expect(mediaConnection.metadata).to.deep.eq(mediaOptions.metadata); + expect(mediaConnection.peerConnection.getSenders()[0].track.id).to.eq(track.id); + + peer1.once('open', id => { + expect(id).to.be.eq('1'); + //@ts-ignore + expect(peer1._lastServerId).to.be.eq('1'); + expect(peer1.disconnected).to.be.false; + expect(peer1.destroyed).to.be.false; + expect(peer1.open).to.be.true; - expect(peer1.disconnected).to.be.true; - expect(peer1.destroyed).to.be.true; - expect(peer1.open).to.be.false; - expect(peer1.connections).to.be.empty; + peer1.destroy(); - done(); - }); - }); + expect(peer1.disconnected).to.be.true; + expect(peer1.destroyed).to.be.true; + expect(peer1.open).to.be.false; + expect(peer1.connections).to.be.empty; - after(function () { - mockServer.stop(); - }); + done(); + }); }); - describe("reconnect", function () { - let mockServer; - - before(function () { - mockServer = createMockServer(); - }); - - it("connect to server => disconnect => reconnect => destroy", function (done) { - const peer1 = new Peer('1', { port: 8080, host: 'localhost' }); + after(function () { + mockServer.stop(); + }); + }); - peer1.once('open', () => { - expect(peer1.open).to.be.true; + describe('reconnect', function () { + let mockServer; - peer1.once('disconnected', () => { - expect(peer1.disconnected).to.be.true; - expect(peer1.destroyed).to.be.false; - expect(peer1.open).to.be.false; + before(function () { + mockServer = createMockServer(); + }); - peer1.once('open', (id) => { - expect(id).to.be.eq('1'); - expect(peer1.disconnected).to.be.false; - expect(peer1.destroyed).to.be.false; - expect(peer1.open).to.be.true; + it('connect to server => disconnect => reconnect => destroy', function (done) { + const peer1 = new Peer('1', { port: 8080, host: 'localhost' }); - peer1.once('disconnected', () => { - expect(peer1.disconnected).to.be.true; - expect(peer1.destroyed).to.be.false; - expect(peer1.open).to.be.false; + peer1.once('open', () => { + expect(peer1.open).to.be.true; - peer1.once('close', () => { - expect(peer1.disconnected).to.be.true; - expect(peer1.destroyed).to.be.true; - expect(peer1.open).to.be.false; + peer1.once('disconnected', () => { + expect(peer1.disconnected).to.be.true; + expect(peer1.destroyed).to.be.false; + expect(peer1.open).to.be.false; - done(); - }); - }); + peer1.once('open', id => { + expect(id).to.be.eq('1'); + expect(peer1.disconnected).to.be.false; + expect(peer1.destroyed).to.be.false; + expect(peer1.open).to.be.true; - peer1.destroy(); - }); + peer1.once('disconnected', () => { + expect(peer1.disconnected).to.be.true; + expect(peer1.destroyed).to.be.false; + expect(peer1.open).to.be.false; - peer1.reconnect(); - }); + peer1.once('close', () => { + expect(peer1.disconnected).to.be.true; + expect(peer1.destroyed).to.be.true; + expect(peer1.open).to.be.false; - peer1.disconnect(); + done(); + }); }); - }); - it("disconnect => reconnect => destroy", function (done) { - mockServer.stop(); + peer1.destroy(); + }); - const peer1 = new Peer('1', { port: 8080, host: 'localhost' }); + peer1.reconnect(); + }); - peer1.once('disconnected', (id) => { - expect(id).to.be.eq('1'); - expect(peer1.disconnected).to.be.true; - expect(peer1.destroyed).to.be.false; - expect(peer1.open).to.be.false; + peer1.disconnect(); + }); + }); - peer1.once('open', (id) => { - expect(id).to.be.eq('1'); - expect(peer1.disconnected).to.be.false; - expect(peer1.destroyed).to.be.false; - expect(peer1.open).to.be.true; + it('disconnect => reconnect => destroy', function (done) { + mockServer.stop(); - peer1.once('disconnected', () => { - expect(peer1.disconnected).to.be.true; - expect(peer1.destroyed).to.be.false; - expect(peer1.open).to.be.false; + const peer1 = new Peer('1', { port: 8080, host: 'localhost' }); - peer1.once('close', () => { - expect(peer1.disconnected).to.be.true; - expect(peer1.destroyed).to.be.true; - expect(peer1.open).to.be.false; + peer1.once('disconnected', id => { + expect(id).to.be.eq('1'); + expect(peer1.disconnected).to.be.true; + expect(peer1.destroyed).to.be.false; + expect(peer1.open).to.be.false; - done(); - }); - }); + peer1.once('open', id => { + expect(id).to.be.eq('1'); + expect(peer1.disconnected).to.be.false; + expect(peer1.destroyed).to.be.false; + expect(peer1.open).to.be.true; - peer1.destroy(); - }); + peer1.once('disconnected', () => { + expect(peer1.disconnected).to.be.true; + expect(peer1.destroyed).to.be.false; + expect(peer1.open).to.be.false; - mockServer = createMockServer(); + peer1.once('close', () => { + expect(peer1.disconnected).to.be.true; + expect(peer1.destroyed).to.be.true; + expect(peer1.open).to.be.false; - peer1.reconnect(); + done(); }); + }); + + peer1.destroy(); }); - it("destroy peer if no id and no connection", function (done) { - mockServer.stop(); + mockServer = createMockServer(); + + peer1.reconnect(); + }); + }); - const peer1 = new Peer({ port: 8080, host: 'localhost' }); + it('destroy peer if no id and no connection', function (done) { + mockServer.stop(); - peer1.once(PeerEventType.Error, (error) => { - expect(error.type).to.be.eq(PeerErrorType.ServerError); + const peer1 = new Peer({ port: 8080, host: 'localhost' }); - peer1.once(PeerEventType.Close, () => { - expect(peer1.disconnected).to.be.true; - expect(peer1.destroyed).to.be.true; - expect(peer1.open).to.be.false; + peer1.once(PeerEventType.Error, error => { + expect(error.type).to.be.eq(PeerErrorType.ServerError); - done(); - }); + peer1.once(PeerEventType.Close, () => { + expect(peer1.disconnected).to.be.true; + expect(peer1.destroyed).to.be.true; + expect(peer1.open).to.be.false; - mockServer = createMockServer(); - }); + done(); }); - after(function () { - mockServer.stop(); - }); + mockServer = createMockServer(); + }); + }); + + after(function () { + mockServer.stop(); }); + }); }); diff --git a/test/setup.ts b/test/setup.ts index 4abe9d28a..986fc82b5 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -1,6 +1,8 @@ -import "./faker"; -import { util } from '../lib/util'; +import './faker'; +import { Utils } from '../lib'; //enable support for WebRTC -util.supports.audioVideo = true; -util.randomToken = () => 'testToken'; +// @ts-ignore +Utils.supports.audioVideo = true; + +Utils.randomToken = () => 'testToken'; diff --git a/test/util.ts b/test/util.ts index 0a9851c66..3f4656ba9 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,11 +1,11 @@ -import "./setup"; -import { expect } from "chai"; -import { util } from "../lib/util"; +import './setup'; +import { expect } from 'chai'; +import { Utils } from '../lib'; -describe("util", function () { - describe("#chunkedMTU", function () { - it("should be 16300", function () { - expect(util.chunkedMTU).to.eq(16300); +describe('util', function () { + describe('#chunkedMTU', function () { + it('should be 16300', function () { + expect(Utils.chunkedMTU).to.eq(16300); }); }); }); From e4de8dd99312302c19ed5550c672cf8e4b7662d1 Mon Sep 17 00:00:00 2001 From: afrokick Date: Sun, 20 Feb 2022 04:09:03 +0300 Subject: [PATCH 04/27] separate dist files to esm, cjs and iife refactoring supports --- examples/nodejs/.gitignore | 24 + examples/nodejs/index.js | 44 + examples/nodejs/package-lock.json | 1300 +++++++++++++++++++++++++++++ examples/nodejs/package.json | 19 + index.d.ts | 250 +++--- lib/api.ts | 11 +- lib/dataconnection.ts | 16 +- lib/encodingQueue.ts | 4 +- lib/index.ts | 2 +- lib/negotiator.ts | 25 +- lib/peer.ts | 97 ++- lib/socket.ts | 18 +- lib/supports.ts | 29 +- lib/utils.ts | 50 +- package.json | 8 +- test/setup.ts | 4 - tsconfig.json | 3 +- 17 files changed, 1659 insertions(+), 245 deletions(-) create mode 100644 examples/nodejs/.gitignore create mode 100644 examples/nodejs/index.js create mode 100644 examples/nodejs/package-lock.json create mode 100644 examples/nodejs/package.json diff --git a/examples/nodejs/.gitignore b/examples/nodejs/.gitignore new file mode 100644 index 000000000..1366e77d4 --- /dev/null +++ b/examples/nodejs/.gitignore @@ -0,0 +1,24 @@ +lib-cov +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.[t]gz + +pids +logs +results +demo +bower.json +node_modules +.cache +.idea +npm-debug.log + +test/output +.tscache +test/public +.vscode/ +dist diff --git a/examples/nodejs/index.js b/examples/nodejs/index.js new file mode 100644 index 000000000..c75172814 --- /dev/null +++ b/examples/nodejs/index.js @@ -0,0 +1,44 @@ +const peerjs = require('peerjs'); +const fetch = require('node-fetch'); +const WebSocket = require('ws'); +const WebRTC = require('wrtc'); +const FileReader = require('filereader'); + +const { Peer } = peerjs; + +const polyfills = { fetch, WebSocket, WebRTC, FileReader }; + +const peer = new Peer({ polyfills, debug: 3 }); + +peer.on('open', id => { + console.log('Server: peer id ', id); + const peer2 = new Peer({ polyfills, debug: 3 }); + + peer2.on('open', id2 => { + console.log('Client: peer id ', id2); + const conn = peer2.connect(id, { serialization: 'json' }); + + conn.on('open', () => { + console.log('Client: connection open'); + setInterval(() => { + conn.send('hi!'); + }, 1000); + + conn.on('data', data => { + console.log('Client: ', data); + }); + }); + }); +}); + +peer.on('connection', conn => { + conn.on('data', data => { + console.log('Server: ', data); + + conn.send(`now time is ${Date.now()}`); + }); + + conn.on('open', () => { + conn.send('hello!'); + }); +}); diff --git a/examples/nodejs/package-lock.json b/examples/nodejs/package-lock.json new file mode 100644 index 000000000..f4d7eddb4 --- /dev/null +++ b/examples/nodejs/package-lock.json @@ -0,0 +1,1300 @@ +{ + "name": "peerjs-nodejs-example", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "peerjs-nodejs-example", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "filereader": "^0.10.3", + "node-fetch": "^2.6.7", + "peerjs": "file:../../", + "wrtc": "^0.4.7", + "ws": "^8.5.0" + } + }, + "../..": { + "version": "1.3.2", + "integrity": "sha512-+PHfmsC7QGUU8Ye3OLi6tKQZGPCNy7QatUVNw4JtE8alkguF3+DdO5W0bzepqP2OtE9FqH/ltXt37qyvHw2CqA==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^3.1.2", + "peerjs-js-binarypack": "1.0.1" + }, + "devDependencies": { + "@types/chai": "^4.3.0", + "@types/mocha": "^9.1.0", + "@types/node": "^17.0.18", + "chai": "^4.3.6", + "esbuild": "^0.14.23", + "jsdom": "^19.0.0", + "jsdom-global": "^3.0.2", + "mocha": "^9.2.0", + "mock-socket": "8.0.5", + "prettier": "^2.5.1", + "ts-node": "^10.5.0", + "typescript": "^4.5.5" + } + }, + "../../node_modules/eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" + }, + "../../node_modules/peerjs-js-binarypack": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/peerjs-js-binarypack/-/peerjs-js-binarypack-1.0.1.tgz", + "integrity": "sha512-N6aeia3NhdpV7kiGxJV5xQiZZCVEEVjRz2T2C6UZQiBkHWHzUv/oWA4myQLcwBwO8LUoR1KWW5oStvwVesmfCg==" + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "node_modules/are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "optional": true, + "dependencies": { + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/filereader": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/filereader/-/filereader-0.10.3.tgz", + "integrity": "sha1-x0fUos2PYeVBinwH/hJXpD8KzbE=" + }, + "node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore-walk": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", + "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/needle": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz", + "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==", + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-pre-gyp": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz", + "integrity": "sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ==", + "deprecated": "Please upgrade to @mapbox/node-pre-gyp: the non-scoped node-pre-gyp package is deprecated and only the @mapbox scoped package will recieve updates in the future", + "dependencies": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/npm-bundled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", + "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", + "dependencies": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" + }, + "node_modules/npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "dependencies": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/peerjs": { + "resolved": "../..", + "link": true + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "dependencies": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/tar/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "optional": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/whatwg-url/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/wrtc": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/wrtc/-/wrtc-0.4.7.tgz", + "integrity": "sha512-P6Hn7VT4lfSH49HxLHcHhDq+aFf/jd9dPY7lDHeFhZ22N3858EKuwm2jmnlPzpsRGEPaoF6XwkcxY5SYnt4f/g==", + "bundleDependencies": [ + "node-pre-gyp" + ], + "hasInstallScript": true, + "dependencies": { + "node-pre-gyp": "^0.13.0" + }, + "engines": { + "node": "^8.11.2 || >=10.0.0" + }, + "optionalDependencies": { + "domexception": "^1.0.1" + } + }, + "node_modules/ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + } + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "optional": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "filereader": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/filereader/-/filereader-0.10.3.tgz", + "integrity": "sha1-x0fUos2PYeVBinwH/hJXpD8KzbE=" + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", + "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "needle": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz", + "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==", + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "node-pre-gyp": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz", + "integrity": "sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ==", + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", + "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" + }, + "npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "peerjs": { + "version": "file:../..", + "requires": { + "@types/chai": "^4.3.0", + "@types/mocha": "^9.1.0", + "@types/node": "^17.0.18", + "chai": "^4.3.6", + "esbuild": "^0.14.23", + "eventemitter3": "^3.1.2", + "jsdom": "^19.0.0", + "jsdom-global": "^3.0.2", + "mocha": "^9.2.0", + "mock-socket": "8.0.5", + "peerjs-js-binarypack": "1.0.1", + "prettier": "^2.5.1", + "ts-node": "^10.5.0", + "typescript": "^4.5.5" + }, + "dependencies": { + "eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" + }, + "peerjs-js-binarypack": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/peerjs-js-binarypack/-/peerjs-js-binarypack-1.0.1.tgz", + "integrity": "sha512-N6aeia3NhdpV7kiGxJV5xQiZZCVEEVjRz2T2C6UZQiBkHWHzUv/oWA4myQLcwBwO8LUoR1KWW5oStvwVesmfCg==" + } + } + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "requires": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "optional": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + } + } + }, + "wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "wrtc": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/wrtc/-/wrtc-0.4.7.tgz", + "integrity": "sha512-P6Hn7VT4lfSH49HxLHcHhDq+aFf/jd9dPY7lDHeFhZ22N3858EKuwm2jmnlPzpsRGEPaoF6XwkcxY5SYnt4f/g==", + "requires": { + "domexception": "^1.0.1", + "node-pre-gyp": "^0.13.0" + } + }, + "ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "requires": {} + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + } + } +} diff --git a/examples/nodejs/package.json b/examples/nodejs/package.json new file mode 100644 index 000000000..f797cf7fb --- /dev/null +++ b/examples/nodejs/package.json @@ -0,0 +1,19 @@ +{ + "name": "peerjs-nodejs-example", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node index.js" + }, + "author": "Alex So", + "license": "MIT", + "dependencies": { + "filereader": "^0.10.3", + "node-fetch": "^2.6.7", + "peerjs": "file:../../", + "wrtc": "^0.4.7", + "ws": "^8.5.0" + } +} diff --git a/index.d.ts b/index.d.ts index 7d8490a24..c2ae87121 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,132 +1,133 @@ // Type definitions for the PeerJS class module // Original definitions by Toshiya Nakakura // at https://github.com/DefinitelyTyped/DefinitelyTyped - export = Peer; -declare class Peer { - prototype: RTCIceServer; +declare namespace Peer { + class Peer { + prototype: RTCIceServer; + + readonly features: Features; - /** - * A peer can connect to other peers and listen for connections. - * @param id Other peers can connect to this peer using the provided ID. - * If no ID is given, one will be generated by the brokering server. - * @param options for specifying details about PeerServer - */ - constructor(id?: string, options?: Peer.PeerJSOption); + /** + * A peer can connect to other peers and listen for connections. + * @param id Other peers can connect to this peer using the provided ID. + * If no ID is given, one will be generated by the brokering server. + * @param options for specifying details about PeerServer + */ + constructor(id?: string, options?: Peer.PeerJSOption); - /** - * A peer can connect to other peers and listen for connections. - * @param options for specifying details about PeerServer - */ - constructor(options: Peer.PeerJSOption); + /** + * A peer can connect to other peers and listen for connections. + * @param options for specifying details about PeerServer + */ + constructor(options: Peer.PeerJSOption); - /** - * Connects to the remote peer specified by id and returns a data connection. - * @param id The brokering ID of the remote peer (their peer.id). - * @param options for specifying details about Peer Connection - */ - connect(id: string, options?: Peer.PeerConnectOption): Peer.DataConnection; - /** - * Calls the remote peer specified by id and returns a media connection. - * @param id The brokering ID of the remote peer (their peer.id). - * @param stream The caller's media stream - * @param options Metadata associated with the connection, passed in by whoever initiated the connection. - */ - call(id: string, stream: MediaStream, options?: Peer.CallOption): Peer.MediaConnection; - /** - * Set listeners for peer events. - * @param event Event name - * @param cb Callback Function - */ - on(event: string, cb: () => void): void; - /** - * Emitted when a connection to the PeerServer is established. - * @param event Event name - * @param cb id is the brokering ID of the peer - */ - on(event: 'open', cb: (id: string) => void): void; - /** - * Emitted when a new data connection is established from a remote peer. - * @param event Event name - * @param cb Callback Function - */ - on(event: 'connection', cb: (dataConnection: Peer.DataConnection) => void): void; - /** - * Emitted when a remote peer attempts to call you. - * @param event Event name - * @param cb Callback Function - */ - on(event: 'call', cb: (mediaConnection: Peer.MediaConnection) => void): void; - /** - * Emitted when the peer is destroyed and can no longer accept or create any new connections. - * @param event Event name - * @param cb Callback Function - */ - on(event: 'close', cb: () => void): void; - /** - * Emitted when the peer is disconnected from the signalling server - * @param event Event name - * @param cb Callback Function - */ - on(event: 'disconnected', cb: () => void): void; - /** - * Errors on the peer are almost always fatal and will destroy the peer. - * @param event Event name - * @param cb Callback Function - */ - on(event: 'error', cb: (err: any) => void): void; - /** - * Remove event listeners.(EventEmitter3) - * @param {String} event The event we want to remove. - * @param {Function} fn The listener that we need to find. - * @param {Boolean} once Only remove once listeners. - */ - off(event: string, fn: Function, once?: boolean): void; - /** - * Close the connection to the server, leaving all existing data and media connections intact. - */ - disconnect(): void; - /** - * Attempt to reconnect to the server with the peer's old ID - */ - reconnect(): void; - /** - * Close the connection to the server and terminate all existing connections. - */ - destroy(): void; + /** + * Connects to the remote peer specified by id and returns a data connection. + * @param id The brokering ID of the remote peer (their peer.id). + * @param options for specifying details about Peer Connection + */ + connect(id: string, options?: Peer.PeerConnectOption): Peer.DataConnection; + /** + * Calls the remote peer specified by id and returns a media connection. + * @param id The brokering ID of the remote peer (their peer.id). + * @param stream The caller's media stream + * @param options Metadata associated with the connection, passed in by whoever initiated the connection. + */ + call(id: string, stream: MediaStream, options?: Peer.CallOption): Peer.MediaConnection; + /** + * Set listeners for peer events. + * @param event Event name + * @param cb Callback Function + */ + on(event: string, cb: () => void): void; + /** + * Emitted when a connection to the PeerServer is established. + * @param event Event name + * @param cb id is the brokering ID of the peer + */ + on(event: 'open', cb: (id: string) => void): void; + /** + * Emitted when a new data connection is established from a remote peer. + * @param event Event name + * @param cb Callback Function + */ + on(event: 'connection', cb: (dataConnection: Peer.DataConnection) => void): void; + /** + * Emitted when a remote peer attempts to call you. + * @param event Event name + * @param cb Callback Function + */ + on(event: 'call', cb: (mediaConnection: Peer.MediaConnection) => void): void; + /** + * Emitted when the peer is destroyed and can no longer accept or create any new connections. + * @param event Event name + * @param cb Callback Function + */ + on(event: 'close', cb: () => void): void; + /** + * Emitted when the peer is disconnected from the signalling server + * @param event Event name + * @param cb Callback Function + */ + on(event: 'disconnected', cb: () => void): void; + /** + * Errors on the peer are almost always fatal and will destroy the peer. + * @param event Event name + * @param cb Callback Function + */ + on(event: 'error', cb: (err: any) => void): void; + /** + * Remove event listeners.(EventEmitter3) + * @param {String} event The event we want to remove. + * @param {Function} fn The listener that we need to find. + * @param {Boolean} once Only remove once listeners. + */ + off(event: string, fn: Function, once?: boolean): void; + /** + * Close the connection to the server, leaving all existing data and media connections intact. + */ + disconnect(): void; + /** + * Attempt to reconnect to the server with the peer's old ID + */ + reconnect(): void; + /** + * Close the connection to the server and terminate all existing connections. + */ + destroy(): void; - /** - * Retrieve a data/media connection for this peer. - * @param peerId - * @param connectionId - */ - getConnection(peerId: string, connectionId: string): Peer.MediaConnection | Peer.DataConnection | null; + /** + * Retrieve a data/media connection for this peer. + * @param peerId + * @param connectionId + */ + getConnection(peerId: string, connectionId: string): Peer.MediaConnection | Peer.DataConnection | null; - /** - * Get a list of available peer IDs - * @param callback - */ - listAllPeers(callback: (peerIds: Array) => void): void; - /** - * The brokering ID of this peer - */ - id: string; - /** - * A hash of all connections associated with this peer, keyed by the remote peer's ID. - */ - connections: any; - /** - * false if there is an active connection to the PeerServer. - */ - disconnected: boolean; - /** - * true if this peer and all of its connections can no longer be used. - */ - destroyed: boolean; -} + /** + * Get a list of available peer IDs + * @param callback + */ + listAllPeers(callback: (peerIds: Array) => void): void; + /** + * The brokering ID of this peer + */ + id: string; + /** + * A hash of all connections associated with this peer, keyed by the remote peer's ID. + */ + connections: any; + /** + * false if there is an active connection to the PeerServer. + */ + disconnected: boolean; + /** + * true if this peer and all of its connections can no longer be used. + */ + destroyed: boolean; + } -declare namespace Peer { interface PeerJSOption { key?: string; host?: string; @@ -136,6 +137,14 @@ declare namespace Peer { token?: string; config?: RTCConfiguration; debug?: number; + pingInterval?: number; + logFunction?: (logLevel: number, ...rest: any[]) => void; + polyfills?: { + WebSocket?: any; + fetch?: any; + WebRTC?: any; + FileReader?: any; + }; } interface PeerConnectOption { @@ -198,9 +207,6 @@ declare namespace Peer { data: boolean; binaryBlob: boolean; reliable: boolean; - } - - interface Utils { - readonly features: Features; + unifiedPlan: boolean; } } diff --git a/lib/api.ts b/lib/api.ts index 890efe4af..fb029c7c5 100644 --- a/lib/api.ts +++ b/lib/api.ts @@ -1,8 +1,13 @@ import { Utils } from './utils'; import logger from './logger'; +import { PeerJSOption } from '..'; export class API { - constructor(private readonly _options: any) {} + private readonly fetch: typeof fetch; + + constructor(private readonly _options: PeerJSOption) { + this.fetch = _options.polyfills?.fetch ?? window.fetch; + } private _buildUrl(method: string): string { const protocol = this._options.secure ? 'https://' : 'http://'; @@ -19,7 +24,7 @@ export class API { const url = this._buildUrl('id'); try { - const response = await fetch(url); + const response = await this.fetch(url); if (response.status !== 200) { throw new Error(`Error. Status:${response.status}`); @@ -47,7 +52,7 @@ export class API { const url = this._buildUrl('peers'); try { - const response = await fetch(url); + const response = await this.fetch(url); if (response.status !== 200) { if (response.status === 401) { diff --git a/lib/dataconnection.ts b/lib/dataconnection.ts index 802231df8..286e89914 100644 --- a/lib/dataconnection.ts +++ b/lib/dataconnection.ts @@ -38,7 +38,7 @@ export class DataConnection extends BaseConnection implements IDataConnection { } = {}; private _dc: RTCDataChannel; - private _encodingQueue = new EncodingQueue(); + private _encodingQueue: EncodingQueue; get dataChannel(): RTCDataChannel { return this._dc; @@ -48,6 +48,8 @@ export class DataConnection extends BaseConnection implements IDataConnection { return this._bufferSize; } + private readonly FileReaderCtr: typeof FileReader; + constructor(peerId: string, provider: Peer, options: any) { super(peerId, provider, options); @@ -57,6 +59,10 @@ export class DataConnection extends BaseConnection implements IDataConnection { this.serialization = this.options.serialization || SerializationType.Binary; this.reliable = !!this.options.reliable; + this.FileReaderCtr = provider.options.polyfills?.FileReader ?? window.FileReader; + + this._encodingQueue = new EncodingQueue(new this.FileReaderCtr()); + this._encodingQueue.on('done', (ab: ArrayBuffer) => { this._bufferedSend(ab); }); @@ -82,7 +88,7 @@ export class DataConnection extends BaseConnection implements IDataConnection { } private _configureDataChannel(): void { - if (!Utils.supports.binaryBlob || Utils.supports.reliable) { + if (!this.provider.features.binaryBlob || this.provider.features.reliable) { this.dataChannel.binaryType = 'arraybuffer'; } @@ -114,8 +120,8 @@ export class DataConnection extends BaseConnection implements IDataConnection { if (isBinarySerialization) { if (datatype === Blob) { - // Datatype should never be blob - Utils.blobToArrayBuffer(data as Blob, ab => { + // Datatype should never be Blob + Utils.blobToArrayBuffer(this.FileReaderCtr, data as Blob, ab => { const unpackedData = Utils.unpack(ab); this.emit(ConnectionEventType.Data, unpackedData); }); @@ -226,7 +232,7 @@ export class DataConnection extends BaseConnection implements IDataConnection { return; } - if (!Utils.supports.binaryBlob) { + if (!this.provider.features.binaryBlob) { // We only do this if we really need to (e.g. blobs are not supported), // because this conversion is costly. this._encodingQueue.enque(blob); diff --git a/lib/encodingQueue.ts b/lib/encodingQueue.ts index 7f94aee31..9a9de727d 100644 --- a/lib/encodingQueue.ts +++ b/lib/encodingQueue.ts @@ -2,12 +2,10 @@ import { EventEmitter } from 'eventemitter3'; import logger from './logger'; export class EncodingQueue extends EventEmitter { - readonly fileReader: FileReader = new FileReader(); - private _queue: Blob[] = []; private _processing: boolean = false; - constructor() { + constructor(private readonly fileReader: FileReader) { super(); this.fileReader.onload = evt => { diff --git a/lib/index.ts b/lib/index.ts index 38409847b..eab475575 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -5,7 +5,7 @@ export { Peer, Utils }; export default Peer; -if (typeof window === 'object') { +if (typeof window !== 'undefined') { // @ts-expect-error window.Peer = Peer; } diff --git a/lib/negotiator.ts b/lib/negotiator.ts index 448b19f24..5146aaff3 100644 --- a/lib/negotiator.ts +++ b/lib/negotiator.ts @@ -5,13 +5,16 @@ import { ConnectionType, PeerErrorType, ConnectionEventType, ServerMessageType } import { BaseConnection } from './baseconnection'; function noop(): void {} - /** * Manages all negotiations between Peers. */ export class Negotiator { constructor(readonly connection: BaseConnection) {} + private get webRtc() { + return this.connection.provider.options.polyfills?.WebRTC ?? window; + } + /** Returns a PeerConnection object set up correctly (for data, media). */ startConnection(options: any) { const peerConnection = this._startPeerConnection(); @@ -44,7 +47,9 @@ export class Negotiator { private _startPeerConnection(): RTCPeerConnection { logger.log('Creating RTCPeerConnection.'); - const peerConnection = new RTCPeerConnection(this.connection.provider.options.config); + const ctr: typeof RTCPeerConnection = this.webRtc.RTCPeerConnection; + + const peerConnection = new ctr(this.connection.provider.options.config); this._setupListeners(peerConnection); @@ -111,7 +116,7 @@ export class Negotiator { logger.log('Received data channel'); const dataChannel = evt.channel; - const connection = provider.getConnection(peerId, connectionId); + const connection = provider.getConnection(peerId, connectionId) as DataConnection; connection.initialize(dataChannel); }; @@ -149,13 +154,13 @@ export class Negotiator { peerConnection.oniceconnectionstatechange = peerConnection.ondatachannel = peerConnection.ontrack = - () => {}; + noop; const peerConnectionNotClosed = peerConnection.signalingState !== 'closed'; let dataChannelNotClosed = false; if (this.connection.type === ConnectionType.Data) { - const dataConnection = this.connection; + const dataConnection = this.connection as DataConnection; const dataChannel = dataConnection.dataChannel; if (dataChannel) { @@ -194,7 +199,7 @@ export class Negotiator { }; if (this.connection.type === ConnectionType.Data) { - const dataConnection = this.connection; + const dataConnection = this.connection as DataConnection; payload = { ...payload, @@ -260,7 +265,9 @@ export class Negotiator { /** Handle an SDP. */ async handleSDP(type: string, sdp: any): Promise { - sdp = new RTCSessionDescription(sdp); + const ctr: typeof RTCSessionDescription = this.webRtc.RTCSessionDescription; + + sdp = new ctr(sdp); const peerConnection = this.connection.peerConnection; const provider = this.connection.provider; @@ -291,8 +298,10 @@ export class Negotiator { const provider = this.connection.provider; try { + const ctr: typeof RTCIceCandidate = this.webRtc.RTCIceCandidate; + await peerConnection.addIceCandidate( - new RTCIceCandidate({ + new ctr({ sdpMid: sdpMid, sdpMLineIndex: sdpMLineIndex, candidate: candidate, diff --git a/lib/peer.ts b/lib/peer.ts index e5727899b..bacd5fb47 100644 --- a/lib/peer.ts +++ b/lib/peer.ts @@ -8,18 +8,11 @@ import { ConnectionType, PeerErrorType, PeerEventType, SocketEventType, ServerMe import { BaseConnection } from './baseconnection'; import { ServerMessage } from './servermessage'; import { API } from './api'; -import type { PeerConnectOption, PeerJSOption } from '..'; +import type { PeerConnectOption, PeerJSOption, Features } from '..'; +import { Supports } from './supports'; -class PeerOptions implements PeerJSOption { +interface PeerOptions extends PeerJSOption { debug?: LogLevel; // 1: Errors, 2: Warnings, 3: All logs - host?: string; - port?: number; - path?: string; - key?: string; - token?: string; - config?: any; - secure?: boolean; - pingInterval?: number; logFunction?: (logLevel: LogLevel, ...rest: any[]) => void; } @@ -80,6 +73,8 @@ export class Peer extends EventEmitter { return this._disconnected; } + readonly features: Features; + constructor(id?: string | PeerOptions, options?: PeerOptions) { super(); @@ -92,7 +87,7 @@ export class Peer extends EventEmitter { userId = id.toString(); } - // Configurize options + // Configure options options = { debug: 0, // 1: Errors, 2: Warnings, 3: All logs host: Utils.CLOUD_HOST, @@ -106,7 +101,7 @@ export class Peer extends EventEmitter { this._options = options; // Detect relative URL host. - if (this._options.host === '/') { + if (typeof window !== 'undefined' && this._options.host === '/') { this._options.host = window.location.hostname; } @@ -136,9 +131,11 @@ export class Peer extends EventEmitter { this._api = new API(options); this._socket = this._createServerConnection(); + this.features = Peer.getFeatures(this._options.polyfills?.WebRTC); + // Sanity checks // Ensure WebRTC supported - if (!Utils.supports.audioVideo && !Utils.supports.data) { + if (!this.features.audioVideo && !this.features.data) { this._delayedAbort(PeerErrorType.BrowserIncompatible, 'The current browser does not support WebRTC'); return; } @@ -160,14 +157,7 @@ export class Peer extends EventEmitter { } private _createServerConnection(): Socket { - const socket = new Socket( - this._options.secure, - this._options.host!, - this._options.port!, - this._options.path!, - this._options.key!, - this._options.pingInterval - ); + const socket = new Socket(this._options); socket.on(SocketEventType.Message, (data: ServerMessage) => { this._handleMessage(data); @@ -546,4 +536,69 @@ export class Peer extends EventEmitter { .then(peers => cb(peers)) .catch(error => this._abort(PeerErrorType.ServerError, error)); } + + static getFeatures(webRtc: any): Features { + if (!webRtc && typeof window !== 'undefined') { + webRtc = window; + } + + if (!Peer._features) { + Peer._features = Peer.checkFeatures(webRtc); + } + + return Peer._features; + } + + private static _features?: Features; + + // Lists which features are supported + private static checkFeatures(webRtc: any): Features { + if (!webRtc && typeof window !== 'undefined') { + webRtc = window; + } + + const supported: Features = { + webRTC: typeof webRtc.RTCPeerConnection !== 'undefined', + audioVideo: true, + data: false, + binaryBlob: false, + reliable: false, + unifiedPlan: false, + }; + + if (!supported.webRTC) return supported; + + let pc: RTCPeerConnection; + + try { + pc = new webRtc.RTCPeerConnection(Utils.defaultConfig); + let dc: RTCDataChannel; + + try { + dc = pc.createDataChannel('_PEERJSTEST', { ordered: true }); + supported.data = true; + supported.reliable = !!dc.ordered; + + // Binary test + try { + dc.binaryType = 'blob'; + supported.binaryBlob = true; //not works for iOS? + } catch (e) {} + } catch (e) { + } finally { + if (dc) { + dc.close(); + } + } + } catch (e) { + } finally { + if (pc) { + pc.close(); + } + } + + supported.unifiedPlan = Supports.isUnifiedPlanSupported(webRtc); + + return supported; + } } diff --git a/lib/socket.ts b/lib/socket.ts index 0accf78ac..fe4c8d2c3 100644 --- a/lib/socket.ts +++ b/lib/socket.ts @@ -1,6 +1,7 @@ import { EventEmitter } from 'eventemitter3'; import logger from './logger'; import { SocketEventType, ServerMessageType } from './enums'; +import type { PeerJSOption } from '../index'; /** * An abstraction on top of WebSockets to provide the fastest @@ -14,19 +15,18 @@ export class Socket extends EventEmitter { private _wsPingTimer?: any; private readonly _baseUrl: string; - constructor( - secure: any, - host: string, - port: number, - path: string, - key: string, - private readonly pingInterval: number = 5000 - ) { + private readonly pingInterval: number; + private readonly WebSocketConstructor: typeof WebSocket; + + constructor({ secure, host, port, path, key, pingInterval = 5000, polyfills }: PeerJSOption) { super(); + this.pingInterval = pingInterval; + const wsProtocol = secure ? 'wss://' : 'ws://'; this._baseUrl = wsProtocol + host + ':' + port + path + 'peerjs?key=' + key; + this.WebSocketConstructor = polyfills?.WebSocket ?? window.WebSocket; } start(id: string, token: string): void { @@ -38,7 +38,7 @@ export class Socket extends EventEmitter { return; } - this._socket = new WebSocket(wsUrl); + this._socket = new this.WebSocketConstructor(wsUrl); this._disconnected = false; this._socket.onmessage = event => { diff --git a/lib/supports.ts b/lib/supports.ts index db9df9bd2..212fea079 100644 --- a/lib/supports.ts +++ b/lib/supports.ts @@ -1,20 +1,21 @@ -export const Supports = new (class { - isWebRTCSupported(): boolean { - return typeof RTCPeerConnection !== 'undefined'; - } +export const Supports = { + isUnifiedPlanSupported(webRtc: any): boolean { + if (!webRtc && typeof window !== 'undefined') { + webRtc = window; + } - isUnifiedPlanSupported(): boolean { if ( - (typeof window !== 'undefined' && !window.RTCRtpTransceiver) || - !('currentDirection' in RTCRtpTransceiver.prototype) - ) + typeof webRtc.RTCRtpTransceiver === 'undefined' || + !('currentDirection' in webRtc.RTCRtpTransceiver.prototype) + ) { return false; + } let tempPc: RTCPeerConnection; let supported = false; try { - tempPc = new RTCPeerConnection(); + tempPc = new webRtc.RTCPeerConnection(); tempPc.addTransceiver('audio'); supported = true; } catch (e) { @@ -25,11 +26,5 @@ export const Supports = new (class { } return supported; - } - - toString(): string { - return `Supports: -isWebRTCSupported:${this.isWebRTCSupported()} -isUnifiedPlanSupported:${this.isUnifiedPlanSupported()}`; - } -})(); + }, +} as const; diff --git a/lib/utils.ts b/lib/utils.ts index 5f4561f02..492fceb36 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -1,6 +1,4 @@ import * as BinaryPack from 'peerjs-js-binarypack'; -import { Supports } from './supports'; -import type { Features } from '..'; const DEFAULT_CONFIG = { iceServers: [ @@ -19,50 +17,6 @@ export const Utils = new (class { // Returns browser-agnostic default config readonly defaultConfig = DEFAULT_CONFIG; - // Lists which features are supported - readonly supports: Features = (function () { - const supported: Features = { - webRTC: Supports.isWebRTCSupported(), - audioVideo: true, - data: false, - binaryBlob: false, - reliable: false, - }; - - if (!supported.webRTC) return supported; - - let pc: RTCPeerConnection; - - try { - pc = new RTCPeerConnection(DEFAULT_CONFIG); - let dc: RTCDataChannel; - - try { - dc = pc.createDataChannel('_PEERJSTEST', { ordered: true }); - supported.data = true; - supported.reliable = !!dc.ordered; - - // Binary test - try { - dc.binaryType = 'blob'; - supported.binaryBlob = true; //not works for iOS? - } catch (e) {} - } catch (e) { - } finally { - if (dc) { - dc.close(); - } - } - } catch (e) { - } finally { - if (pc) { - pc.close(); - } - } - - return supported; - })(); - // Ensure alphanumeric ids validateId(id: string): boolean { // Allow empty ids @@ -106,8 +60,8 @@ export const Utils = new (class { return chunks; } - blobToArrayBuffer(blob: Blob, cb: (arg: ArrayBuffer | null) => void): FileReader { - const fr = new FileReader(); + blobToArrayBuffer(FileReaderCtr: typeof FileReader, blob: Blob, cb: (arg: ArrayBuffer | null) => void): FileReader { + const fr = new FileReaderCtr(); fr.onload = function (evt) { if (evt.target) { diff --git a/package.json b/package.json index 2407918e9..31a2e925f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,9 @@ "name": "peerjs", "version": "1.3.2", "description": "PeerJS client", - "main": "./dist/peerjs.js", + "main": "./dist/peerjs.cjs.js", + "module": "./dist/peerjs.esm.js", + "browser": "./dist/peerjs.js", "homepage": "https://github.com/peers/peerjs#readme", "keywords": [ "peerjs", @@ -29,8 +31,8 @@ "license": "MIT", "scripts": { "dev": "", - "esbuild": "esbuild lib/index.ts --bundle --sourcemap --target=es6", - "build": "npm run esbuild -- --outfile=dist/peerjs.js && npm run esbuild -- --minify --outfile=dist/peerjs.min.js", + "esbuild": "esbuild lib/index.ts --bundle --target=es6 --global-name=Peer", + "build": "npm run esbuild -- --outfile=dist/peerjs.js --sourcemap && npm run esbuild -- --minify --outfile=dist/peerjs.min.js --sourcemap && npm run esbuild -- --outfile=dist/peerjs.esm.js --format=esm && npm run esbuild -- --outfile=dist/peerjs.cjs.js --format=cjs", "prepublishOnly": "npm run tsc-check && npm run test && npm run build", "test": "mocha -r ts-node/register -r jsdom-global/register test/**/*.ts", "tsc-check": "tsc --noEmit" diff --git a/test/setup.ts b/test/setup.ts index 986fc82b5..cdffd9f5b 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -1,8 +1,4 @@ import './faker'; import { Utils } from '../lib'; -//enable support for WebRTC -// @ts-ignore -Utils.supports.audioVideo = true; - Utils.randomToken = () => 'testToken'; diff --git a/tsconfig.json b/tsconfig.json index 2cc40d573..44004cf81 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,7 @@ "downlevelIteration": true, "noUnusedLocals": true, "noUnusedParameters": true, - "skipLibCheck": true + "skipLibCheck": true, + "allowSyntheticDefaultImports": true } } From 12e3a6810041b6b8fbccf2ab0bdb4c974ed58ea8 Mon Sep 17 00:00:00 2001 From: afrokick Date: Sun, 20 Feb 2022 04:30:39 +0300 Subject: [PATCH 05/27] simplify import --- examples/nodejs/index.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/nodejs/index.js b/examples/nodejs/index.js index c75172814..979482109 100644 --- a/examples/nodejs/index.js +++ b/examples/nodejs/index.js @@ -1,11 +1,9 @@ -const peerjs = require('peerjs'); +const { Peer } = require('peerjs'); const fetch = require('node-fetch'); const WebSocket = require('ws'); const WebRTC = require('wrtc'); const FileReader = require('filereader'); -const { Peer } = peerjs; - const polyfills = { fetch, WebSocket, WebRTC, FileReader }; const peer = new Peer({ polyfills, debug: 3 }); From 28a84aea95c454503a2b378bbfb022c3b9e034a3 Mon Sep 17 00:00:00 2001 From: afrokick Date: Sun, 20 Feb 2022 05:03:49 +0300 Subject: [PATCH 06/27] 2.0.0-beta.0 --- CHANGELOG.md | 11 ++++++++++- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4993ed22e..700e4a8a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,8 @@ The main goals of the second version: - modernize the code base: use `es6` and latest tools; - target to the latest browsers API(you can use webrtc adapter to shim old browsers); -- shrink the package size. +- shrink the package size; +- NodeJS support. ### Breaking changes @@ -74,6 +75,14 @@ In any case, you can use a CDN like `unpkg.com`: Parcel 1 was a good choice years ago, but now esbuild seems like simple and good solution! +### New + +#### NodeJS support + +Yeah! You can use `peerjs` in NodeJS! + +See details in https://github.com/peers/peerjs/pull/928 + ### Another changes - update `devDependencies` diff --git a/package-lock.json b/package-lock.json index 140160bf7..e24ee32f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "peerjs", - "version": "1.3.2", + "version": "2.0.0-beta.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "peerjs", - "version": "1.3.2", + "version": "2.0.0-beta.0", "license": "MIT", "dependencies": { "eventemitter3": "^3.1.2", diff --git a/package.json b/package.json index 31a2e925f..c2c4e477b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "peerjs", - "version": "1.3.2", + "version": "2.0.0-beta.0", "description": "PeerJS client", "main": "./dist/peerjs.cjs.js", "module": "./dist/peerjs.esm.js", From b58ae5f7cc5c3897edfe0a37dcc761f67f441346 Mon Sep 17 00:00:00 2001 From: afrokick Date: Sun, 20 Feb 2022 05:19:14 +0300 Subject: [PATCH 07/27] update readme --- README.md | 105 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index ecf2576ab..247946d2e 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,65 @@ -# PeerJS: Simple peer-to-peer with WebRTC # +# PeerJS: Simple peer-to-peer with WebRTC ### https://t.me/joinchat/VWI0UBxnG7f7_DV7 [![Backers on Open Collective](https://opencollective.com/peer/backers/badge.svg)](#backers) - [![Sponsors on Open Collective](https://opencollective.com/peer/sponsors/badge.svg)](#sponsors) +[![Sponsors on Open Collective](https://opencollective.com/peer/sponsors/badge.svg)](#sponsors) PeerJS provides a complete, configurable, and easy-to-use peer-to-peer API built on top of WebRTC, supporting both data channels and media streams. +## Features + +- TypeScript 100% +- respects CommonJS, ES Module +- NodeJS support +- Simple API +- DataChannel + MediaStream + ## Live Example Here's an example application that uses both media and data connections: https://glitch.com/~peerjs-video. The example also uses its own [PeerServer](https://github.com/peers/peerjs-server). ## Setup +**Install a dependency** + +with npm: + +`npm install peerjs` + +with yarn: + +`yarn add peerjs` **Include the library** - with npm: - `npm install peerjs` - - with yarn: - `yarn add peerjs` - ```js - // The usage - - import Peer from 'peerjs'; - ``` +```js +import { Peer } from 'peerjs'; +``` +**Create a Peer** -**Create a Peer** ```javascript -const peer = new Peer('pick-an-id'); +const peer = new Peer('pick-an-id'); // You can pick your own id or omit the id if you want to get a random one from the server. ``` ## Data connections + **Connect** + ```javascript const conn = peer.connect('another-peers-id'); conn.on('open', () => { conn.send('hi!'); }); ``` + **Receive** + ```javascript -peer.on('connection', (conn) => { - conn.on('data', (data) => { +peer.on('connection', conn => { + conn.on('data', data => { // Will print 'hi!' console.log(data); }); @@ -55,29 +70,40 @@ peer.on('connection', (conn) => { ``` ## Media calls + **Call** -```javascript -navigator.mediaDevices.getUserMedia({video: true, audio: true}, (stream) => { - const call = peer.call('another-peers-id', stream); - call.on('stream', (remoteStream) => { - // Show stream in some