@libp2p/webrtc 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +4 -0
- package/README.md +210 -0
- package/dist/index.min.js +54 -0
- package/dist/index.min.js.map +7 -0
- package/dist/proto_ts/message.d.ts +56 -0
- package/dist/proto_ts/message.d.ts.map +1 -0
- package/dist/proto_ts/message.js +86 -0
- package/dist/proto_ts/message.js.map +1 -0
- package/dist/src/error.d.ts +54 -0
- package/dist/src/error.d.ts.map +1 -0
- package/dist/src/error.js +105 -0
- package/dist/src/error.js.map +1 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +6 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/maconn.d.ts +43 -0
- package/dist/src/maconn.d.ts.map +1 -0
- package/dist/src/maconn.js +29 -0
- package/dist/src/maconn.js.map +1 -0
- package/dist/src/muxer.d.ts +55 -0
- package/dist/src/muxer.d.ts.map +1 -0
- package/dist/src/muxer.js +92 -0
- package/dist/src/muxer.js.map +1 -0
- package/dist/src/options.d.ts +6 -0
- package/dist/src/options.d.ts.map +1 -0
- package/dist/src/options.js +2 -0
- package/dist/src/options.js.map +1 -0
- package/dist/src/sdp.d.ts +33 -0
- package/dist/src/sdp.d.ts.map +1 -0
- package/dist/src/sdp.js +118 -0
- package/dist/src/sdp.js.map +1 -0
- package/dist/src/stream.d.ts +141 -0
- package/dist/src/stream.d.ts.map +1 -0
- package/dist/src/stream.js +290 -0
- package/dist/src/stream.js.map +1 -0
- package/dist/src/transport.d.ts +60 -0
- package/dist/src/transport.d.ts.map +1 -0
- package/dist/src/transport.js +193 -0
- package/dist/src/transport.js.map +1 -0
- package/dist/src/util.d.ts +5 -0
- package/dist/src/util.d.ts.map +1 -0
- package/dist/src/util.js +5 -0
- package/dist/src/util.js.map +1 -0
- package/dist/stats.json +1 -0
- package/package.json +170 -0
- package/proto_ts/message.ts +105 -0
- package/src/error.ts +123 -0
- package/src/index.ts +6 -0
- package/src/maconn.ts +67 -0
- package/src/message.proto +22 -0
- package/src/muxer.ts +120 -0
- package/src/options.ts +4 -0
- package/src/sdp.ts +136 -0
- package/src/stream.ts +422 -0
- package/src/transport.ts +243 -0
- package/src/util.ts +5 -0
package/package.json
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@libp2p/webrtc",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "A libp2p transport using WebRTC connections",
|
|
5
|
+
"author": "",
|
|
6
|
+
"license": "Apache-2.0 OR MIT",
|
|
7
|
+
"homepage": "https://github.com/libp2p/js-libp2p-webrtc#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/libp2p/js-libp2p-webrtc.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/libp2p/js-libp2p-webrtc/issues"
|
|
14
|
+
},
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=16.0.0",
|
|
17
|
+
"npm": ">=7.0.0"
|
|
18
|
+
},
|
|
19
|
+
"type": "module",
|
|
20
|
+
"types": "./dist/src/index.d.ts",
|
|
21
|
+
"files": [
|
|
22
|
+
"src",
|
|
23
|
+
"dist",
|
|
24
|
+
"!dist/test",
|
|
25
|
+
"!**/*.tsbuildinfo",
|
|
26
|
+
"proto_ts"
|
|
27
|
+
],
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./src/index.d.ts",
|
|
31
|
+
"import": "./dist/src/index.js"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"eslintConfig": {
|
|
35
|
+
"extends": "ipfs",
|
|
36
|
+
"parserOptions": {
|
|
37
|
+
"sourceType": "module"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"release": {
|
|
41
|
+
"branches": [
|
|
42
|
+
"main"
|
|
43
|
+
],
|
|
44
|
+
"plugins": [
|
|
45
|
+
[
|
|
46
|
+
"@semantic-release/commit-analyzer",
|
|
47
|
+
{
|
|
48
|
+
"preset": "conventionalcommits",
|
|
49
|
+
"releaseRules": [
|
|
50
|
+
{
|
|
51
|
+
"breaking": true,
|
|
52
|
+
"release": "major"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"revert": true,
|
|
56
|
+
"release": "patch"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"type": "feat",
|
|
60
|
+
"release": "minor"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"type": "fix",
|
|
64
|
+
"release": "patch"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"type": "docs",
|
|
68
|
+
"release": "patch"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"type": "test",
|
|
72
|
+
"release": "patch"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"type": "deps",
|
|
76
|
+
"release": "patch"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"scope": "no-release",
|
|
80
|
+
"release": false
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
[
|
|
86
|
+
"@semantic-release/release-notes-generator",
|
|
87
|
+
{
|
|
88
|
+
"preset": "conventionalcommits",
|
|
89
|
+
"presetConfig": {
|
|
90
|
+
"types": [
|
|
91
|
+
{
|
|
92
|
+
"type": "feat",
|
|
93
|
+
"section": "Features"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"type": "fix",
|
|
97
|
+
"section": "Bug Fixes"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"type": "chore",
|
|
101
|
+
"section": "Trivial Changes"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"type": "docs",
|
|
105
|
+
"section": "Documentation"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"type": "deps",
|
|
109
|
+
"section": "Dependencies"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"type": "test",
|
|
113
|
+
"section": "Tests"
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
],
|
|
119
|
+
"@semantic-release/changelog",
|
|
120
|
+
"@semantic-release/npm",
|
|
121
|
+
"@semantic-release/github",
|
|
122
|
+
"@semantic-release/git"
|
|
123
|
+
]
|
|
124
|
+
},
|
|
125
|
+
"scripts": {
|
|
126
|
+
"generate:proto": "npx protoc --ts_out proto_ts --proto_path src src/*.proto",
|
|
127
|
+
"build": "aegir build",
|
|
128
|
+
"test": "aegir test -t browser",
|
|
129
|
+
"test:chrome": "aegir test -t browser -f \"./dist/test/**/*.spec.js\" --cov",
|
|
130
|
+
"test:firefox": "aegir test -t browser -f \"./dist/test/**/*.spec.js\" -- --browser firefox",
|
|
131
|
+
"lint": "aegir lint",
|
|
132
|
+
"lint:fix": "aegir lint --fix",
|
|
133
|
+
"clean": "aegir clean",
|
|
134
|
+
"dep-check": "aegir dep-check",
|
|
135
|
+
"release": "aegir release"
|
|
136
|
+
},
|
|
137
|
+
"dependencies": {
|
|
138
|
+
"@chainsafe/libp2p-noise": "^10.0.0",
|
|
139
|
+
"@libp2p/interface-connection": "^3.0.2",
|
|
140
|
+
"@libp2p/interface-peer-id": "^1.0.5",
|
|
141
|
+
"@libp2p/interface-stream-muxer": "^3.0.0",
|
|
142
|
+
"@libp2p/interface-transport": "^2.0.0",
|
|
143
|
+
"@libp2p/logger": "^2.0.0",
|
|
144
|
+
"@libp2p/peer-id": "^1.1.15",
|
|
145
|
+
"@multiformats/multiaddr": "^11.0.3",
|
|
146
|
+
"@protobuf-ts/runtime": "^2.8.0",
|
|
147
|
+
"err-code": "^3.0.1",
|
|
148
|
+
"it-length-prefixed": "^8.0.3",
|
|
149
|
+
"it-merge": "^2.0.0",
|
|
150
|
+
"it-pipe": "^2.0.4",
|
|
151
|
+
"it-pushable": "^3.1.0",
|
|
152
|
+
"it-stream-types": "^1.0.4",
|
|
153
|
+
"multiformats": "^10.0.0",
|
|
154
|
+
"multihashes": "^4.0.3",
|
|
155
|
+
"p-defer": "^4.0.0",
|
|
156
|
+
"uint8arraylist": "^2.3.3",
|
|
157
|
+
"uint8arrays": "^4.0.2",
|
|
158
|
+
"uuid": "^9.0.0"
|
|
159
|
+
},
|
|
160
|
+
"devDependencies": {
|
|
161
|
+
"@libp2p/interface-mocks": "^8.0.1",
|
|
162
|
+
"@libp2p/peer-id-factory": "^1.0.19",
|
|
163
|
+
"@protobuf-ts/plugin": "^2.8.0",
|
|
164
|
+
"@protobuf-ts/protoc": "^2.8.0",
|
|
165
|
+
"@types/uuid": "^8.3.4",
|
|
166
|
+
"aegir": "^37.4.6",
|
|
167
|
+
"it-first": "^2.0.0",
|
|
168
|
+
"libp2p": "^0.40.0"
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// @generated by protobuf-ts 2.8.1
|
|
2
|
+
// @generated from protobuf file "message.proto" (package "webrtc.pb", syntax proto2)
|
|
3
|
+
// tslint:disable
|
|
4
|
+
import type { BinaryWriteOptions } from "@protobuf-ts/runtime";
|
|
5
|
+
import type { IBinaryWriter } from "@protobuf-ts/runtime";
|
|
6
|
+
import { WireType } from "@protobuf-ts/runtime";
|
|
7
|
+
import type { BinaryReadOptions } from "@protobuf-ts/runtime";
|
|
8
|
+
import type { IBinaryReader } from "@protobuf-ts/runtime";
|
|
9
|
+
import { UnknownFieldHandler } from "@protobuf-ts/runtime";
|
|
10
|
+
import type { PartialMessage } from "@protobuf-ts/runtime";
|
|
11
|
+
import { reflectionMergePartial } from "@protobuf-ts/runtime";
|
|
12
|
+
import { MESSAGE_TYPE } from "@protobuf-ts/runtime";
|
|
13
|
+
import { MessageType } from "@protobuf-ts/runtime";
|
|
14
|
+
/**
|
|
15
|
+
* @generated from protobuf message webrtc.pb.Message
|
|
16
|
+
*/
|
|
17
|
+
export interface Message {
|
|
18
|
+
/**
|
|
19
|
+
* @generated from protobuf field: optional webrtc.pb.Message.Flag flag = 1;
|
|
20
|
+
*/
|
|
21
|
+
flag?: Message_Flag;
|
|
22
|
+
/**
|
|
23
|
+
* @generated from protobuf field: optional bytes message = 2;
|
|
24
|
+
*/
|
|
25
|
+
message?: Uint8Array;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* @generated from protobuf enum webrtc.pb.Message.Flag
|
|
29
|
+
*/
|
|
30
|
+
export enum Message_Flag {
|
|
31
|
+
/**
|
|
32
|
+
* The sender will no longer send messages on the stream.
|
|
33
|
+
*
|
|
34
|
+
* @generated from protobuf enum value: FIN = 0;
|
|
35
|
+
*/
|
|
36
|
+
FIN = 0,
|
|
37
|
+
/**
|
|
38
|
+
* The sender will no longer read messages on the stream. Incoming data is
|
|
39
|
+
* being discarded on receipt.
|
|
40
|
+
*
|
|
41
|
+
* @generated from protobuf enum value: STOP_SENDING = 1;
|
|
42
|
+
*/
|
|
43
|
+
STOP_SENDING = 1,
|
|
44
|
+
/**
|
|
45
|
+
* The sender abruptly terminates the sending part of the stream. The
|
|
46
|
+
* receiver can discard any data that it already received on that stream.
|
|
47
|
+
*
|
|
48
|
+
* @generated from protobuf enum value: RESET = 2;
|
|
49
|
+
*/
|
|
50
|
+
RESET = 2
|
|
51
|
+
}
|
|
52
|
+
// @generated message type with reflection information, may provide speed optimized methods
|
|
53
|
+
class Message$Type extends MessageType<Message> {
|
|
54
|
+
constructor() {
|
|
55
|
+
super("webrtc.pb.Message", [
|
|
56
|
+
{ no: 1, name: "flag", kind: "enum", opt: true, T: () => ["webrtc.pb.Message.Flag", Message_Flag] },
|
|
57
|
+
{ no: 2, name: "message", kind: "scalar", opt: true, T: 12 /*ScalarType.BYTES*/ }
|
|
58
|
+
]);
|
|
59
|
+
}
|
|
60
|
+
create(value?: PartialMessage<Message>): Message {
|
|
61
|
+
const message = {};
|
|
62
|
+
globalThis.Object.defineProperty(message, MESSAGE_TYPE, { enumerable: false, value: this });
|
|
63
|
+
if (value !== undefined)
|
|
64
|
+
reflectionMergePartial<Message>(this, message, value);
|
|
65
|
+
return message;
|
|
66
|
+
}
|
|
67
|
+
internalBinaryRead(reader: IBinaryReader, length: number, options: BinaryReadOptions, target?: Message): Message {
|
|
68
|
+
let message = target ?? this.create(), end = reader.pos + length;
|
|
69
|
+
while (reader.pos < end) {
|
|
70
|
+
let [fieldNo, wireType] = reader.tag();
|
|
71
|
+
switch (fieldNo) {
|
|
72
|
+
case /* optional webrtc.pb.Message.Flag flag */ 1:
|
|
73
|
+
message.flag = reader.int32();
|
|
74
|
+
break;
|
|
75
|
+
case /* optional bytes message */ 2:
|
|
76
|
+
message.message = reader.bytes();
|
|
77
|
+
break;
|
|
78
|
+
default:
|
|
79
|
+
let u = options.readUnknownField;
|
|
80
|
+
if (u === "throw")
|
|
81
|
+
throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
|
|
82
|
+
let d = reader.skip(wireType);
|
|
83
|
+
if (u !== false)
|
|
84
|
+
(u === true ? UnknownFieldHandler.onRead : u)(this.typeName, message, fieldNo, wireType, d);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return message;
|
|
88
|
+
}
|
|
89
|
+
internalBinaryWrite(message: Message, writer: IBinaryWriter, options: BinaryWriteOptions): IBinaryWriter {
|
|
90
|
+
/* optional webrtc.pb.Message.Flag flag = 1; */
|
|
91
|
+
if (message.flag !== undefined)
|
|
92
|
+
writer.tag(1, WireType.Varint).int32(message.flag);
|
|
93
|
+
/* optional bytes message = 2; */
|
|
94
|
+
if (message.message !== undefined)
|
|
95
|
+
writer.tag(2, WireType.LengthDelimited).bytes(message.message);
|
|
96
|
+
let u = options.writeUnknownFields;
|
|
97
|
+
if (u !== false)
|
|
98
|
+
(u == true ? UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
|
|
99
|
+
return writer;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* @generated MessageType for protobuf message webrtc.pb.Message
|
|
104
|
+
*/
|
|
105
|
+
export const Message = new Message$Type();
|
package/src/error.ts
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import errCode from 'err-code'
|
|
2
|
+
import { Direction } from '@libp2p/interface-connection'
|
|
3
|
+
|
|
4
|
+
export enum codes {
|
|
5
|
+
ERR_ALREADY_ABORTED = 'ERR_ALREADY_ABORTED',
|
|
6
|
+
ERR_DATA_CHANNEL = 'ERR_DATA_CHANNEL',
|
|
7
|
+
ERR_CONNECTION_CLOSED = 'ERR_CONNECTION_CLOSED',
|
|
8
|
+
ERR_HASH_NOT_SUPPORTED = 'ERR_HASH_NOT_SUPPORTED',
|
|
9
|
+
ERR_INVALID_MULTIADDR = 'ERR_INVALID_MULTIADDR',
|
|
10
|
+
ERR_INVALID_FINGERPRINT = 'ERR_INVALID_FINGERPRINT',
|
|
11
|
+
ERR_INVALID_PARAMETERS = 'ERR_INVALID_PARAMETERS',
|
|
12
|
+
ERR_NOT_IMPLEMENTED = 'ERR_NOT_IMPLEMENTED',
|
|
13
|
+
ERR_TOO_MANY_INBOUND_PROTOCOL_STREAMS = 'ERR_TOO_MANY_INBOUND_PROTOCOL_STREAMS',
|
|
14
|
+
ERR_TOO_MANY_OUTBOUND_PROTOCOL_STREAMS = 'ERR_TOO_MANY_OUTBOUND_PROTOCOL_STREAMS',
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class WebRTCTransportError extends Error {
|
|
18
|
+
constructor (msg: string) {
|
|
19
|
+
super(`WebRTC transport error: ${msg}`)
|
|
20
|
+
this.name = 'WebRTCTransportError'
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export class ConnectionClosedError extends WebRTCTransportError {
|
|
25
|
+
constructor (state: RTCPeerConnectionState, msg: string) {
|
|
26
|
+
super(`peerconnection moved to state: ${state}: ${msg}`)
|
|
27
|
+
this.name = 'WebRTC/ConnectionClosed'
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function connectionClosedError (state: RTCPeerConnectionState, msg: string) {
|
|
32
|
+
return errCode(new ConnectionClosedError(state, msg), codes.ERR_CONNECTION_CLOSED)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class DataChannelError extends WebRTCTransportError {
|
|
36
|
+
constructor (streamLabel: string, msg: string) {
|
|
37
|
+
super(`[stream: ${streamLabel}] data channel error: ${msg}`)
|
|
38
|
+
this.name = 'WebRTC/DataChannelError'
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function dataChannelError (streamLabel: string, msg: string) {
|
|
43
|
+
return errCode(new DataChannelError(streamLabel, msg), codes.ERR_DATA_CHANNEL)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export class InappropriateMultiaddrError extends WebRTCTransportError {
|
|
47
|
+
constructor (msg: string) {
|
|
48
|
+
super(`There was a problem with the Multiaddr which was passed in: ${msg}`)
|
|
49
|
+
this.name = 'WebRTC/InappropriateMultiaddrError'
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function inappropriateMultiaddr (msg: string) {
|
|
54
|
+
return errCode(new InappropriateMultiaddrError(msg), codes.ERR_INVALID_MULTIADDR)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export class InvalidArgumentError extends WebRTCTransportError {
|
|
58
|
+
constructor (msg: string) {
|
|
59
|
+
super(`There was a problem with a provided argument: ${msg}`)
|
|
60
|
+
this.name = 'WebRTC/InvalidArgumentError'
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function invalidArgument (msg: string) {
|
|
65
|
+
return errCode(new InvalidArgumentError(msg), codes.ERR_INVALID_PARAMETERS)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export class InvalidFingerprintError extends WebRTCTransportError {
|
|
69
|
+
constructor (fingerprint: string, source: string) {
|
|
70
|
+
super(`Invalid fingerprint "${fingerprint}" within ${source}`)
|
|
71
|
+
this.name = 'WebRTC/InvalidFingerprintError'
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function invalidFingerprint (fingerprint: string, source: string) {
|
|
76
|
+
return errCode(new InvalidFingerprintError(fingerprint, source), codes.ERR_INVALID_FINGERPRINT)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export class OperationAbortedError extends WebRTCTransportError {
|
|
80
|
+
constructor (context: string, abortReason: string) {
|
|
81
|
+
super(`Signalled to abort because (${abortReason}}) ${context}`)
|
|
82
|
+
this.name = 'WebRTC/OperationAbortedError'
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function operationAborted (context: string, reason: string) {
|
|
87
|
+
return errCode(new OperationAbortedError(context, reason), codes.ERR_ALREADY_ABORTED)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export class OverStreamLimitError extends WebRTCTransportError {
|
|
91
|
+
constructor (msg: string) {
|
|
92
|
+
super(msg)
|
|
93
|
+
this.name = 'WebRTC/OverStreamLimitError'
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function overStreamLimit (dir: Direction, proto: string) {
|
|
98
|
+
const code = dir === 'inbound' ? codes.ERR_TOO_MANY_INBOUND_PROTOCOL_STREAMS : codes.ERR_TOO_MANY_OUTBOUND_PROTOCOL_STREAMS
|
|
99
|
+
return errCode(new OverStreamLimitError(`${dir} stream limit reached for protocol - ${proto}`), code)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export class UnimplementedError extends WebRTCTransportError {
|
|
103
|
+
constructor (methodName: string) {
|
|
104
|
+
super(`A method (${methodName}) was called though it has been intentionally left unimplemented.`)
|
|
105
|
+
this.name = 'WebRTC/UnimplementedError'
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function unimplemented (methodName: string) {
|
|
110
|
+
return errCode(new UnimplementedError(methodName), codes.ERR_NOT_IMPLEMENTED)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export class UnsupportedHashAlgorithmError extends WebRTCTransportError {
|
|
114
|
+
constructor (algo: string) {
|
|
115
|
+
const msg = `unsupported hash algorithm: ${algo}`
|
|
116
|
+
super(msg)
|
|
117
|
+
this.name = 'WebRTC/UnsupportedHashAlgorithmError'
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function unsupportedHashAlgorithm (algorithm: string) {
|
|
122
|
+
return errCode(new UnsupportedHashAlgorithmError(algorithm), codes.ERR_HASH_NOT_SUPPORTED)
|
|
123
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Transport } from '@libp2p/interface-transport'
|
|
2
|
+
import { WebRTCTransport, WebRTCTransportComponents } from './transport.js'
|
|
3
|
+
|
|
4
|
+
export function webRTC (): (components: WebRTCTransportComponents) => Transport {
|
|
5
|
+
return (components: WebRTCTransportComponents) => new WebRTCTransport(components)
|
|
6
|
+
}
|
package/src/maconn.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { MultiaddrConnection, MultiaddrConnectionTimeline } from '@libp2p/interface-connection'
|
|
2
|
+
import { logger } from '@libp2p/logger'
|
|
3
|
+
import { Multiaddr } from '@multiformats/multiaddr'
|
|
4
|
+
import { Source, Sink } from 'it-stream-types'
|
|
5
|
+
|
|
6
|
+
import { nopSink, nopSource } from './util.js'
|
|
7
|
+
|
|
8
|
+
const log = logger('libp2p:webrtc:connection')
|
|
9
|
+
|
|
10
|
+
interface WebRTCMultiaddrConnectionInit {
|
|
11
|
+
/**
|
|
12
|
+
* WebRTC Peer Connection
|
|
13
|
+
*/
|
|
14
|
+
peerConnection: RTCPeerConnection
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The multiaddr address used to communicate with the remote peer
|
|
18
|
+
*/
|
|
19
|
+
remoteAddr: Multiaddr
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Holds the relevant events timestamps of the connection
|
|
23
|
+
*/
|
|
24
|
+
timeline: MultiaddrConnectionTimeline
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class WebRTCMultiaddrConnection implements MultiaddrConnection {
|
|
28
|
+
/**
|
|
29
|
+
* WebRTC Peer Connection
|
|
30
|
+
*/
|
|
31
|
+
readonly peerConnection: RTCPeerConnection;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The multiaddr address used to communicate with the remote peer
|
|
35
|
+
*/
|
|
36
|
+
remoteAddr: Multiaddr;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Holds the lifecycle times of the connection
|
|
40
|
+
*/
|
|
41
|
+
timeline: MultiaddrConnectionTimeline;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The stream source, a no-op as the transport natively supports multiplexing
|
|
45
|
+
*/
|
|
46
|
+
source: Source<Uint8Array> = nopSource
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The stream destination, a no-op as the transport natively supports multiplexing
|
|
50
|
+
*/
|
|
51
|
+
sink: Sink<Uint8Array, Promise<void>> = nopSink;
|
|
52
|
+
|
|
53
|
+
constructor (init: WebRTCMultiaddrConnectionInit) {
|
|
54
|
+
this.remoteAddr = init.remoteAddr
|
|
55
|
+
this.timeline = init.timeline
|
|
56
|
+
this.peerConnection = init.peerConnection
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async close (err?: Error | undefined): Promise<void> {
|
|
60
|
+
if (err !== undefined) {
|
|
61
|
+
log.error('error closing connection', err)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
this.timeline.close = new Date().getTime()
|
|
65
|
+
this.peerConnection.close()
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
syntax = "proto2";
|
|
2
|
+
|
|
3
|
+
package webrtc.pb;
|
|
4
|
+
|
|
5
|
+
message Message {
|
|
6
|
+
enum Flag {
|
|
7
|
+
// The sender will no longer send messages on the stream.
|
|
8
|
+
FIN = 0;
|
|
9
|
+
|
|
10
|
+
// The sender will no longer read messages on the stream. Incoming data is
|
|
11
|
+
// being discarded on receipt.
|
|
12
|
+
STOP_SENDING = 1;
|
|
13
|
+
|
|
14
|
+
// The sender abruptly terminates the sending part of the stream. The
|
|
15
|
+
// receiver can discard any data that it already received on that stream.
|
|
16
|
+
RESET = 2;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
optional Flag flag = 1;
|
|
20
|
+
|
|
21
|
+
optional bytes message = 2;
|
|
22
|
+
}
|
package/src/muxer.ts
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { Stream } from '@libp2p/interface-connection'
|
|
2
|
+
import { StreamMuxer, StreamMuxerFactory, StreamMuxerInit } from '@libp2p/interface-stream-muxer'
|
|
3
|
+
import { Source, Sink } from 'it-stream-types'
|
|
4
|
+
|
|
5
|
+
import { WebRTCStream } from './stream.js'
|
|
6
|
+
import { nopSink, nopSource } from './util.js'
|
|
7
|
+
|
|
8
|
+
export class DataChannelMuxerFactory implements StreamMuxerFactory {
|
|
9
|
+
/**
|
|
10
|
+
* WebRTC Peer Connection
|
|
11
|
+
*/
|
|
12
|
+
private readonly peerConnection: RTCPeerConnection
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The string representation of the protocol, required by `StreamMuxerFactory`
|
|
16
|
+
*/
|
|
17
|
+
protocol: string = '/webrtc'
|
|
18
|
+
|
|
19
|
+
constructor (peerConnection: RTCPeerConnection) {
|
|
20
|
+
this.peerConnection = peerConnection
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
createStreamMuxer (init?: StreamMuxerInit | undefined): StreamMuxer {
|
|
24
|
+
return new DataChannelMuxer(this.peerConnection, init)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* A libp2p data channel stream muxer
|
|
30
|
+
*/
|
|
31
|
+
export class DataChannelMuxer implements StreamMuxer {
|
|
32
|
+
/**
|
|
33
|
+
* WebRTC Peer Connection
|
|
34
|
+
*/
|
|
35
|
+
private readonly peerConnection: RTCPeerConnection
|
|
36
|
+
/**
|
|
37
|
+
* The protocol as represented in the multiaddress
|
|
38
|
+
*/
|
|
39
|
+
readonly protocol: string = '/webrtc'
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Array of streams in the data channel
|
|
43
|
+
*/
|
|
44
|
+
streams: Stream[] = []
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Initialized stream muxer
|
|
48
|
+
*/
|
|
49
|
+
init?: StreamMuxerInit
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Close or abort all tracked streams and stop the muxer
|
|
53
|
+
*/
|
|
54
|
+
close: (err?: Error | undefined) => void = () => {}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The stream source, a no-op as the transport natively supports multiplexing
|
|
58
|
+
*/
|
|
59
|
+
source: Source<Uint8Array> = nopSource;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The stream destination, a no-op as the transport natively supports multiplexing
|
|
63
|
+
*/
|
|
64
|
+
sink: Sink<Uint8Array, Promise<void>> = nopSink;
|
|
65
|
+
|
|
66
|
+
constructor (peerConnection: RTCPeerConnection, init?: StreamMuxerInit) {
|
|
67
|
+
/**
|
|
68
|
+
* Initialized stream muxer
|
|
69
|
+
*/
|
|
70
|
+
this.init = init
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* WebRTC Peer Connection
|
|
74
|
+
*/
|
|
75
|
+
this.peerConnection = peerConnection
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Fired when a data channel has been added to the connection has been
|
|
79
|
+
* added by the remote peer.
|
|
80
|
+
*
|
|
81
|
+
* {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/datachannel_event}
|
|
82
|
+
*/
|
|
83
|
+
this.peerConnection.ondatachannel = ({ channel }) => {
|
|
84
|
+
const stream = new WebRTCStream({
|
|
85
|
+
channel,
|
|
86
|
+
stat: {
|
|
87
|
+
direction: 'inbound',
|
|
88
|
+
timeline: {
|
|
89
|
+
open: 0
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
closeCb: init?.onStreamEnd
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
if ((init?.onIncomingStream) != null) {
|
|
96
|
+
init.onIncomingStream(stream)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Initiate a new stream with the given name. If no name is
|
|
103
|
+
* provided, the id of the stream will be used.
|
|
104
|
+
*/
|
|
105
|
+
newStream (name: string = ''): Stream {
|
|
106
|
+
const channel = this.peerConnection.createDataChannel(name)
|
|
107
|
+
const stream = new WebRTCStream({
|
|
108
|
+
channel,
|
|
109
|
+
stat: {
|
|
110
|
+
direction: 'outbound',
|
|
111
|
+
timeline: {
|
|
112
|
+
open: 0
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
closeCb: this.init?.onStreamEnd
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
return stream
|
|
119
|
+
}
|
|
120
|
+
}
|
package/src/options.ts
ADDED