Skip to content

Commit

Permalink
feat: await peer.connect(...)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonasgloning committed Sep 3, 2023
1 parent 2cba46d commit bee2bdb
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 3 deletions.
2 changes: 1 addition & 1 deletion e2e/peer/id-taken.await.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ <h1>ID-TAKEN</h1>
<script type="application/javascript">
(async () => {
/**
* @type {typeof import("../..").Peer}
* @type {typeof import("../../lib/exports.ts").Peer}
*/
const Peer = window.peerjs.Peer;

Expand Down
41 changes: 41 additions & 0 deletions e2e/peer/peer-unavailable.async.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title></title>
<link rel="stylesheet" href="../style.css" />
</head>
<body>
<h1>PEER-UNAVAILABLE</h1>
<div id="messages"></div>
<div id="error-message"></div>
<script src="/dist/peerjs.js"></script>
<script type="application/javascript">
(async () => {
/**
* @type {typeof import("../../lib/exports.ts").Peer}
*/
const Peer = window.peerjs.Peer;

const messages = document.getElementById("messages");
const errors = document.getElementById("error-message");

const not_existing_peer = crypto
.getRandomValues(new Uint8Array(16))
.join("");

try {
const peer = await new Peer();
await peer.connect(not_existing_peer);
} catch (error) {
if (error.type === "peer-unavailable") {
messages.textContent = "Success: Peer unavailable";
} else {
errors.textContent += JSON.stringify(error);
}
}
})();
</script>
</body>
</html>
5 changes: 5 additions & 0 deletions e2e/peer/peer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,9 @@ describe("Peer:async", () => {
await P.waitForMessage("No ID takeover");
expect(await P.errorMessage.getText()).toBe("");
});
it("should emit an error, when the remote peer is unavailable", async () => {
await P.open("peer-unavailable.async");
await P.waitForMessage("Success: Peer unavailable");
expect(await P.errorMessage.getText()).toBe("");
});
});
29 changes: 27 additions & 2 deletions lib/dataconnection/DataConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { BaseConnection, type BaseConnectionEvents } from "../baseconnection";
import type { ServerMessage } from "../servermessage";
import type { EventsWithError } from "../peerError";
import { randomToken } from "../utils/randomToken";
import { PeerError } from "../peerError";

export interface DataConnectionEvents
extends EventsWithError<DataConnectionErrorType | BaseConnectionErrorType>,
Expand All @@ -25,6 +26,14 @@ export interface DataConnectionEvents
open: () => void;
}

export interface IDataConnection
extends BaseConnection<DataConnectionEvents, DataConnectionErrorType> {
/** Allows user to close connection. */
close(options?: { flush?: boolean }): void;
/** Allows user to send data. */
send(data: any, chunked?: boolean): void;
}

/**
* Wraps a DataChannel between two Peers.
*/
Expand All @@ -38,6 +47,10 @@ export abstract class DataConnection extends BaseConnection<
private _negotiator: Negotiator<DataConnectionEvents, this>;
abstract readonly serialization: string;
readonly reliable: boolean;
private then: (
onfulfilled?: (value: IDataConnection) => any,
onrejected?: (reason: PeerError<DataConnectionErrorType>) => any,
) => void;

public get type() {
return ConnectionType.Data;
Expand All @@ -46,6 +59,20 @@ export abstract class DataConnection extends BaseConnection<
constructor(peerId: string, provider: Peer, options: any) {
super(peerId, provider, options);

this.then = (
onfulfilled?: (value: IDataConnection) => any,
onrejected?: (reason: PeerError<DataConnectionErrorType>) => any,
) => {
// Remove 'then' to prevent potential recursion issues
// `await` will wait for a Promise-like to resolve recursively
delete this.then;

// We don’t need to worry about cleaning up listeners here
// `await`ing a Promise will make sure only one of the paths executes
this.once("open", () => onfulfilled(this));
this.once("error", onrejected);
};

this.connectionId =
this.options.connectionId || DataConnection.ID_PREFIX + randomToken();

Expand Down Expand Up @@ -87,7 +114,6 @@ export abstract class DataConnection extends BaseConnection<
* Exposed functionality for users.
*/

/** Allows user to close connection. */
close(options?: { flush?: boolean }): void {
if (options?.flush) {
this.send({
Expand Down Expand Up @@ -126,7 +152,6 @@ export abstract class DataConnection extends BaseConnection<

protected abstract _send(data: any, chunked: boolean): void;

/** Allows user to send data. */
public send(data: any, chunked = false) {
if (!this.open) {
this.emitError(
Expand Down

0 comments on commit bee2bdb

Please sign in to comment.