@tolokoban/p2p 0.1.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/dist/peer.js ADDED
@@ -0,0 +1,201 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { isType } from "@tolokoban/type-guards";
11
+ import { GenericEvent } from "./event.js";
12
+ import { Message } from "./message.js";
13
+ const SIZES = {
14
+ Uint8: 1,
15
+ Uint16: 2,
16
+ Uint32: 4,
17
+ Int8: 1,
18
+ Int16: 2,
19
+ Int32: 4,
20
+ Float32: 4,
21
+ Float64: 8,
22
+ };
23
+ export class Peer {
24
+ /**
25
+ * @param iceServers By default the connection works only on local network.
26
+ * But you can specify a list of STUN servers to overcome this issue.
27
+ *
28
+ * Example:
29
+ *
30
+ * ```js
31
+ * [
32
+ * { urls: "stun:stun.l.google.com:19302" },
33
+ * { urls: "stun:stun1.l.google.com:19302" },
34
+ * { urls: "stun:stun2.l.google.com:19302" },
35
+ * { urls: "stun:stun3.l.google.com:19302" },
36
+ * ]
37
+ * ```
38
+ */
39
+ constructor(signalServerURL, iceServers = []) {
40
+ this.signalServerURL = signalServerURL;
41
+ this.eventConnected = new GenericEvent();
42
+ this.eventMessage = new GenericEvent();
43
+ this.eventClose = new GenericEvent();
44
+ this.remoteChannel = null;
45
+ this.messageToBeSent = [];
46
+ this.handleMessage = (evt) => {
47
+ const { data } = evt;
48
+ console.log("RECEIVED:", data); // @FIXME: Remove this line written on 2026-01-09 at 11:02
49
+ const message = new Message(data);
50
+ this.eventMessage.dispatch(message);
51
+ };
52
+ this.onMessage = (data) => {
53
+ console.log("🐞 [peer@187] data =", data); // @FIXME: Remove this line written on 2026-01-09 at 12:07
54
+ if (data instanceof ArrayBuffer) {
55
+ this.eventMessage.dispatch(new Message(data));
56
+ }
57
+ else {
58
+ throw new Error("Unexpected message type!");
59
+ }
60
+ };
61
+ this.peerConnection = new RTCPeerConnection({ iceServers });
62
+ this.dataChannel = this.peerConnection.createDataChannel("p2p");
63
+ this.peerConnection.ondatachannel = (evt) => {
64
+ const { channel } = evt;
65
+ this.remoteChannel = channel;
66
+ channel.onmessage = this.handleMessage;
67
+ channel.onclose = () => this.eventClose.dispatch(this);
68
+ };
69
+ this.peerConnection.oniceconnectionstatechange = () => {
70
+ if (this.peerConnection.iceConnectionState === "failed") {
71
+ this.peerConnection.restartIce();
72
+ }
73
+ };
74
+ }
75
+ close() {
76
+ var _a;
77
+ (_a = this.remoteChannel) === null || _a === void 0 ? void 0 : _a.close();
78
+ this.dataChannel.close();
79
+ }
80
+ clear() {
81
+ this.messageToBeSent.splice(0);
82
+ return this;
83
+ }
84
+ putString(message) {
85
+ this.messageToBeSent.push(message);
86
+ return this;
87
+ }
88
+ putArrayBuffer(arrayBuffer) {
89
+ this.messageToBeSent.push(arrayBuffer);
90
+ return this;
91
+ }
92
+ putNumber(type, value) {
93
+ this.messageToBeSent.push({ type, value });
94
+ return this;
95
+ }
96
+ send() {
97
+ var _a;
98
+ const { messageToBeSent } = this;
99
+ if (messageToBeSent.length === 0)
100
+ return;
101
+ let byteLength = 0;
102
+ const chunks = [];
103
+ for (const item of messageToBeSent) {
104
+ if (typeof item === "string") {
105
+ byteLength += 4;
106
+ const chunk = new TextEncoder().encode(item);
107
+ chunks.push(chunk);
108
+ byteLength += chunk.byteLength;
109
+ }
110
+ else if (item instanceof ArrayBuffer) {
111
+ byteLength += 4;
112
+ const chunk = new Uint8Array(item);
113
+ chunks.push(chunk);
114
+ byteLength += chunk.byteLength;
115
+ }
116
+ else {
117
+ byteLength += SIZES[item.type];
118
+ }
119
+ }
120
+ const array = new Uint8Array(byteLength);
121
+ const view = new DataView(array.buffer);
122
+ let byteOffset = 0;
123
+ for (const item of messageToBeSent) {
124
+ if (typeof item === "string" || item instanceof ArrayBuffer) {
125
+ const chunk = chunks.shift();
126
+ if (!chunk)
127
+ throw new Error("Missing chunk!");
128
+ view.setUint32(byteOffset, chunk.byteLength);
129
+ byteOffset += 4;
130
+ array.set(chunk, byteOffset);
131
+ byteOffset += chunk.byteLength;
132
+ }
133
+ else {
134
+ switch (item.type) {
135
+ case "Float32":
136
+ view.setFloat32(byteOffset, item.value);
137
+ break;
138
+ case "Float64":
139
+ view.setFloat64(byteOffset, item.value);
140
+ break;
141
+ case "Int16":
142
+ view.setInt16(byteOffset, item.value);
143
+ break;
144
+ case "Int32":
145
+ view.setInt32(byteOffset, item.value);
146
+ break;
147
+ case "Int8":
148
+ view.setInt8(byteOffset, item.value);
149
+ break;
150
+ case "Uint16":
151
+ view.setUint16(byteOffset, item.value);
152
+ break;
153
+ case "Uint32":
154
+ view.setUint16(byteOffset, item.value);
155
+ break;
156
+ case "Uint8":
157
+ view.setUint16(byteOffset, item.value);
158
+ break;
159
+ default:
160
+ throw new Error(`Unknown type "${item.type}"!`);
161
+ }
162
+ byteOffset += SIZES[item.type];
163
+ }
164
+ }
165
+ (_a = this.remoteChannel) === null || _a === void 0 ? void 0 : _a.send(array);
166
+ }
167
+ sendString(message) {
168
+ this.clear().putString(message).send();
169
+ }
170
+ signal(args) {
171
+ return __awaiter(this, void 0, void 0, function* () {
172
+ const data = {
173
+ s: args.service,
174
+ };
175
+ if (hasInput(args))
176
+ data.i = args.input;
177
+ if (hasKey(args))
178
+ data.k = args.key;
179
+ const headers = new Headers({
180
+ "Content-Type": "application/json",
181
+ });
182
+ const resp = yield fetch(this.signalServerURL, {
183
+ method: "POST",
184
+ headers,
185
+ mode: "cors",
186
+ cache: "no-cache",
187
+ redirect: "follow",
188
+ referrerPolicy: "no-referrer",
189
+ body: JSON.stringify(data),
190
+ });
191
+ return yield resp.json();
192
+ });
193
+ }
194
+ }
195
+ function hasInput(args) {
196
+ return isType(args, { input: "string" });
197
+ }
198
+ function hasKey(args) {
199
+ return isType(args, { key: "string" });
200
+ }
201
+ //# sourceMappingURL=peer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer.js","sourceRoot":"","sources":["../library/src/peer.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "@tolokoban/p2p",
3
+ "version": "0.1.0",
4
+ "description": "Peer to peer library for local network",
5
+ "homepage": "https://tolokoban.github.io/p2p",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "private": false,
9
+ "files": [
10
+ "./dist"
11
+ ],
12
+ "dependencies": {
13
+ "@tolokoban/type-guards": "^0.9.0"
14
+ },
15
+ "devDependencies": {
16
+ "prettier": "^3.7.4"
17
+ }
18
+ }