@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.
Files changed (57) hide show
  1. package/LICENSE +4 -0
  2. package/README.md +210 -0
  3. package/dist/index.min.js +54 -0
  4. package/dist/index.min.js.map +7 -0
  5. package/dist/proto_ts/message.d.ts +56 -0
  6. package/dist/proto_ts/message.d.ts.map +1 -0
  7. package/dist/proto_ts/message.js +86 -0
  8. package/dist/proto_ts/message.js.map +1 -0
  9. package/dist/src/error.d.ts +54 -0
  10. package/dist/src/error.d.ts.map +1 -0
  11. package/dist/src/error.js +105 -0
  12. package/dist/src/error.js.map +1 -0
  13. package/dist/src/index.d.ts +4 -0
  14. package/dist/src/index.d.ts.map +1 -0
  15. package/dist/src/index.js +6 -0
  16. package/dist/src/index.js.map +1 -0
  17. package/dist/src/maconn.d.ts +43 -0
  18. package/dist/src/maconn.d.ts.map +1 -0
  19. package/dist/src/maconn.js +29 -0
  20. package/dist/src/maconn.js.map +1 -0
  21. package/dist/src/muxer.d.ts +55 -0
  22. package/dist/src/muxer.d.ts.map +1 -0
  23. package/dist/src/muxer.js +92 -0
  24. package/dist/src/muxer.js.map +1 -0
  25. package/dist/src/options.d.ts +6 -0
  26. package/dist/src/options.d.ts.map +1 -0
  27. package/dist/src/options.js +2 -0
  28. package/dist/src/options.js.map +1 -0
  29. package/dist/src/sdp.d.ts +33 -0
  30. package/dist/src/sdp.d.ts.map +1 -0
  31. package/dist/src/sdp.js +118 -0
  32. package/dist/src/sdp.js.map +1 -0
  33. package/dist/src/stream.d.ts +141 -0
  34. package/dist/src/stream.d.ts.map +1 -0
  35. package/dist/src/stream.js +290 -0
  36. package/dist/src/stream.js.map +1 -0
  37. package/dist/src/transport.d.ts +60 -0
  38. package/dist/src/transport.d.ts.map +1 -0
  39. package/dist/src/transport.js +193 -0
  40. package/dist/src/transport.js.map +1 -0
  41. package/dist/src/util.d.ts +5 -0
  42. package/dist/src/util.d.ts.map +1 -0
  43. package/dist/src/util.js +5 -0
  44. package/dist/src/util.js.map +1 -0
  45. package/dist/stats.json +1 -0
  46. package/package.json +170 -0
  47. package/proto_ts/message.ts +105 -0
  48. package/src/error.ts +123 -0
  49. package/src/index.ts +6 -0
  50. package/src/maconn.ts +67 -0
  51. package/src/message.proto +22 -0
  52. package/src/muxer.ts +120 -0
  53. package/src/options.ts +4 -0
  54. package/src/sdp.ts +136 -0
  55. package/src/stream.ts +422 -0
  56. package/src/transport.ts +243 -0
  57. 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
@@ -0,0 +1,4 @@
1
+ import { CreateListenerOptions, DialOptions } from '@libp2p/interface-transport'
2
+
3
+ export interface WebRTCListenerOptions extends CreateListenerOptions {}
4
+ export interface WebRTCDialOptions extends DialOptions {}