@trystero-p2p/torrent 0.23.0-beta.1
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 +22 -0
- package/dist/index.d.mts +11 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +184 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +39 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2021 Dan Motzenbecker
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
|
4
|
+
obtaining a copy of this software and associated documentation
|
|
5
|
+
files (the "Software"), to deal in the Software without
|
|
6
|
+
restriction, including without limitation the rights to use,
|
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the
|
|
9
|
+
Software is furnished to do so, subject to the following
|
|
10
|
+
conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be
|
|
13
|
+
included in all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BaseRoomConfig, JoinRoom, RelayConfig, pauseRelayReconnection, resumeRelayReconnection, selfId } from "@trystero-p2p/core";
|
|
2
|
+
export * from "@trystero-p2p/core";
|
|
3
|
+
|
|
4
|
+
//#region src/index.d.ts
|
|
5
|
+
type TorrentRoomConfig = BaseRoomConfig & RelayConfig;
|
|
6
|
+
declare const joinRoom: JoinRoom<TorrentRoomConfig>;
|
|
7
|
+
declare const getRelaySockets: any;
|
|
8
|
+
declare const defaultRelayUrls: string[];
|
|
9
|
+
//#endregion
|
|
10
|
+
export { TorrentRoomConfig, defaultRelayUrls, getRelaySockets, joinRoom, pauseRelayReconnection, resumeRelayReconnection, selfId };
|
|
11
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;KAgDY,iBAAA,GAAoB,cAAA,GAAiB,WAAA;AAAA,cAuRpC,QAAA,EAAU,QAAA,CAAS,iBAAA;AAAA,cAWnB,eAAA;AAAA,cAIA,gBAAA"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { createStrategy, entries, fromJson, genId, getRelays, libName, makeSocket, pauseRelayReconnection, resumeRelayReconnection, selfId, sha1, socketGetter, toJson } from "@trystero-p2p/core";
|
|
2
|
+
//#region src/index.ts
|
|
3
|
+
const clients = {};
|
|
4
|
+
const topicToInfoHash = {};
|
|
5
|
+
const infoHashToTopic = {};
|
|
6
|
+
const announceIntervals = {};
|
|
7
|
+
const announceFns = {};
|
|
8
|
+
const subscriptionTokens = {};
|
|
9
|
+
const trackerAnnounceMs = {};
|
|
10
|
+
const handledSignals = {};
|
|
11
|
+
const msgHandlers = {};
|
|
12
|
+
const trackerAction = "announce";
|
|
13
|
+
const hashLimit = 20;
|
|
14
|
+
const offerPoolSize = 10;
|
|
15
|
+
const defaultAnnounceMs = 1e4;
|
|
16
|
+
const maxAnnounceMs = 2e4;
|
|
17
|
+
const offerRetentionMs = 12e4;
|
|
18
|
+
const signalDedupeWindowMs = 4e3;
|
|
19
|
+
const defaultRedundancy = 3;
|
|
20
|
+
const getInfoHash = async (topic) => {
|
|
21
|
+
if (topicToInfoHash[topic]) return topicToInfoHash[topic];
|
|
22
|
+
const hash = (await sha1(topic)).slice(0, hashLimit);
|
|
23
|
+
topicToInfoHash[topic] = hash;
|
|
24
|
+
infoHashToTopic[hash] = topic;
|
|
25
|
+
return hash;
|
|
26
|
+
};
|
|
27
|
+
const send = async (client, topic, payload) => {
|
|
28
|
+
client.send(toJson({
|
|
29
|
+
action: trackerAction,
|
|
30
|
+
info_hash: await getInfoHash(topic),
|
|
31
|
+
peer_id: selfId,
|
|
32
|
+
...payload
|
|
33
|
+
}));
|
|
34
|
+
};
|
|
35
|
+
const warn = (url, msg, didFail = false) => console.warn(`${libName}: torrent tracker ${didFail ? "failure" : "warning"} from ${url} - ${msg}`);
|
|
36
|
+
const joinRoomStrategy = createStrategy({
|
|
37
|
+
init: (config) => getRelays(config, defaultRelayUrls, defaultRedundancy).map((rawUrl) => {
|
|
38
|
+
const client = makeSocket(rawUrl, (rawData) => {
|
|
39
|
+
const data = fromJson(rawData);
|
|
40
|
+
const errMsg = data["failure reason"];
|
|
41
|
+
const warnMsg = data["warning message"];
|
|
42
|
+
const { interval } = data;
|
|
43
|
+
const topic = data.info_hash ? infoHashToTopic[data.info_hash] : void 0;
|
|
44
|
+
if (errMsg) {
|
|
45
|
+
warn(client.url, errMsg, true);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (warnMsg) warn(client.url, warnMsg);
|
|
49
|
+
if (interval && interval * 1e3 > (trackerAnnounceMs[client.url] ?? defaultAnnounceMs) && topic && announceFns[client.url]?.[topic]) {
|
|
50
|
+
const nextInterval = Math.min(interval * 1e3, maxAnnounceMs);
|
|
51
|
+
const relayIntervals = announceIntervals[client.url] ??= {};
|
|
52
|
+
const relayFns = announceFns[client.url] ??= {};
|
|
53
|
+
if (relayIntervals[topic]) clearInterval(relayIntervals[topic]);
|
|
54
|
+
trackerAnnounceMs[client.url] = nextInterval;
|
|
55
|
+
const relayFn = relayFns[topic];
|
|
56
|
+
if (relayFn) relayIntervals[topic] = setInterval(relayFn, nextInterval);
|
|
57
|
+
}
|
|
58
|
+
if ((data.offer || data.answer) && topic && data.offer_id) {
|
|
59
|
+
if (data.peer_id === selfId) return;
|
|
60
|
+
const signalKey = `${topic}:${data.offer ? "offer" : "answer"}:${data.offer_id}:${data.peer_id ?? ""}`;
|
|
61
|
+
const nowMs = Date.now();
|
|
62
|
+
const lastHandledMs = handledSignals[signalKey];
|
|
63
|
+
if (typeof lastHandledMs === "number" && nowMs - lastHandledMs < signalDedupeWindowMs) return;
|
|
64
|
+
handledSignals[signalKey] = nowMs;
|
|
65
|
+
entries(handledSignals).forEach(([key, handledAtMs]) => {
|
|
66
|
+
if (nowMs - handledAtMs > signalDedupeWindowMs * 6) delete handledSignals[key];
|
|
67
|
+
});
|
|
68
|
+
msgHandlers[client.url]?.[topic]?.(data);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
const { url } = client;
|
|
72
|
+
clients[url] = client;
|
|
73
|
+
msgHandlers[url] = {};
|
|
74
|
+
return client.ready;
|
|
75
|
+
}),
|
|
76
|
+
subscribe: (client, rootTopic, _, onMessage, getOffers) => {
|
|
77
|
+
const { url } = client;
|
|
78
|
+
const handlers = msgHandlers[url] ??= {};
|
|
79
|
+
const relayFns = announceFns[url] ??= {};
|
|
80
|
+
const relayIntervals = announceIntervals[url] ??= {};
|
|
81
|
+
const activeTokens = subscriptionTokens[url] ??= {};
|
|
82
|
+
const subscriptionToken = Symbol(rootTopic);
|
|
83
|
+
const outstandingOffers = {};
|
|
84
|
+
activeTokens[rootTopic] = subscriptionToken;
|
|
85
|
+
const claimOutstandingOffer = (offerId) => {
|
|
86
|
+
const offer = outstandingOffers[offerId];
|
|
87
|
+
if (!offer) return;
|
|
88
|
+
delete outstandingOffers[offerId];
|
|
89
|
+
offer.claim?.();
|
|
90
|
+
return offer;
|
|
91
|
+
};
|
|
92
|
+
const reclaimOutstandingOffer = (offerId) => {
|
|
93
|
+
const offer = outstandingOffers[offerId];
|
|
94
|
+
if (!offer) return;
|
|
95
|
+
delete outstandingOffers[offerId];
|
|
96
|
+
offer.reclaim?.();
|
|
97
|
+
};
|
|
98
|
+
const reclaimAllOutstandingOffers = () => {
|
|
99
|
+
entries(outstandingOffers).forEach(([offerId]) => {
|
|
100
|
+
reclaimOutstandingOffer(offerId);
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
const pruneOutstandingOffers = () => {
|
|
104
|
+
const now = Date.now();
|
|
105
|
+
entries(outstandingOffers).forEach(([offerId, offer]) => {
|
|
106
|
+
if (now - offer.createdAt > offerRetentionMs) reclaimOutstandingOffer(offerId);
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
const topicHandler = (data) => {
|
|
110
|
+
if (data.offer && data.peer_id && data.offer_id) onMessage(rootTopic, {
|
|
111
|
+
offer: data.offer,
|
|
112
|
+
peerId: data.peer_id,
|
|
113
|
+
hasOutgoingOffer: entries(outstandingOffers).length > 0
|
|
114
|
+
}, (_, signal) => void send(client, rootTopic, {
|
|
115
|
+
answer: fromJson(signal)["answer"],
|
|
116
|
+
offer_id: data.offer_id,
|
|
117
|
+
to_peer_id: data.peer_id
|
|
118
|
+
}));
|
|
119
|
+
else if (data.answer && data.offer_id && data.peer_id) {
|
|
120
|
+
const offer = claimOutstandingOffer(data.offer_id);
|
|
121
|
+
if (offer) onMessage(rootTopic, {
|
|
122
|
+
answer: data.answer,
|
|
123
|
+
peerId: data.peer_id,
|
|
124
|
+
peer: offer.peer
|
|
125
|
+
}, () => {});
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
handlers[rootTopic] = topicHandler;
|
|
129
|
+
const announce = async () => {
|
|
130
|
+
if (activeTokens[rootTopic] !== subscriptionToken) return;
|
|
131
|
+
pruneOutstandingOffers();
|
|
132
|
+
const outstandingCount = entries(outstandingOffers).length;
|
|
133
|
+
const missingOffers = Math.max(0, offerPoolSize - outstandingCount);
|
|
134
|
+
if (missingOffers > 0) (await getOffers(missingOffers)).forEach((peerAndOffer) => {
|
|
135
|
+
outstandingOffers[genId(hashLimit)] = {
|
|
136
|
+
...peerAndOffer,
|
|
137
|
+
createdAt: Date.now()
|
|
138
|
+
};
|
|
139
|
+
});
|
|
140
|
+
send(client, rootTopic, {
|
|
141
|
+
numwant: offerPoolSize,
|
|
142
|
+
offers: entries(outstandingOffers).map(([id, { offer }]) => ({
|
|
143
|
+
offer_id: id,
|
|
144
|
+
offer
|
|
145
|
+
}))
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
trackerAnnounceMs[url] = defaultAnnounceMs;
|
|
149
|
+
relayFns[rootTopic] = announce;
|
|
150
|
+
relayIntervals[rootTopic] = setInterval(announce, trackerAnnounceMs[url]);
|
|
151
|
+
announce();
|
|
152
|
+
return () => {
|
|
153
|
+
if (activeTokens[rootTopic] !== subscriptionToken) {
|
|
154
|
+
reclaimAllOutstandingOffers();
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const interval = relayIntervals[rootTopic];
|
|
158
|
+
if (interval) {
|
|
159
|
+
clearInterval(interval);
|
|
160
|
+
delete relayIntervals[rootTopic];
|
|
161
|
+
}
|
|
162
|
+
if (handlers[rootTopic] === topicHandler) delete handlers[rootTopic];
|
|
163
|
+
if (relayFns[rootTopic] === announce) delete relayFns[rootTopic];
|
|
164
|
+
delete activeTokens[rootTopic];
|
|
165
|
+
reclaimAllOutstandingOffers();
|
|
166
|
+
};
|
|
167
|
+
},
|
|
168
|
+
announce: (client) => trackerAnnounceMs[client.url]
|
|
169
|
+
});
|
|
170
|
+
const joinRoom = (config, roomId, callbacks) => joinRoomStrategy({
|
|
171
|
+
...config,
|
|
172
|
+
trickleIce: config.trickleIce ?? false
|
|
173
|
+
}, roomId, callbacks);
|
|
174
|
+
const getRelaySockets = socketGetter(clients);
|
|
175
|
+
const defaultRelayUrls = [
|
|
176
|
+
"tracker.webtorrent.dev",
|
|
177
|
+
"tracker.openwebtorrent.com",
|
|
178
|
+
"tracker.btorrent.xyz",
|
|
179
|
+
"tracker.files.fm:7073/announce"
|
|
180
|
+
].map((url) => "wss://" + url);
|
|
181
|
+
//#endregion
|
|
182
|
+
export { defaultRelayUrls, getRelaySockets, joinRoom, pauseRelayReconnection, resumeRelayReconnection, selfId };
|
|
183
|
+
|
|
184
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import {\n createStrategy,\n entries,\n fromJson,\n genId,\n getRelays,\n libName,\n makeSocket,\n pauseRelayReconnection,\n resumeRelayReconnection,\n selfId,\n sha1,\n socketGetter,\n toJson,\n type BaseRoomConfig,\n type JoinRoom,\n type OfferRecord,\n type RelayConfig,\n type SocketClient\n} from '@trystero-p2p/core'\n\nconst clients: Record<string, SocketClient> = {}\nconst topicToInfoHash: Record<string, string> = {}\nconst infoHashToTopic: Record<string, string> = {}\nconst announceIntervals: Record<\n string,\n Record<string, ReturnType<typeof setInterval>>\n> = {}\nconst announceFns: Record<\n string,\n Record<string, () => void | Promise<void>>\n> = {}\nconst subscriptionTokens: Record<string, Record<string, symbol>> = {}\nconst trackerAnnounceMs: Record<string, number> = {}\nconst handledSignals: Record<string, number> = {}\nconst msgHandlers: Record<\n string,\n Record<string, ((data: TrackerMessage) => void) | undefined>\n> = {}\nconst trackerAction = 'announce'\nconst hashLimit = 20\nconst offerPoolSize = 10\nconst defaultAnnounceMs = 10_000\nconst maxAnnounceMs = 20_000\nconst offerRetentionMs = 120_000\nconst signalDedupeWindowMs = 4_000\nconst defaultRedundancy = 3\n\nexport type TorrentRoomConfig = BaseRoomConfig & RelayConfig\n\ntype TrackerMessage = {\n offer?: unknown\n answer?: unknown\n offer_id?: string\n peer_id?: string\n info_hash?: string\n interval?: number\n ['failure reason']?: string\n ['warning message']?: string\n}\n\nconst getInfoHash = async (topic: string): Promise<string> => {\n if (topicToInfoHash[topic]) {\n return topicToInfoHash[topic]\n }\n\n const hash = (await sha1(topic)).slice(0, hashLimit)\n topicToInfoHash[topic] = hash\n infoHashToTopic[hash] = topic\n\n return hash\n}\n\nconst send = async (\n client: SocketClient,\n topic: string,\n payload: Record<string, unknown>\n): Promise<void> => {\n client.send(\n toJson({\n action: trackerAction,\n info_hash: await getInfoHash(topic),\n peer_id: selfId,\n ...payload\n })\n )\n}\n\nconst warn = (url: string, msg: string, didFail = false): void =>\n console.warn(\n `${libName}: torrent tracker ${didFail ? 'failure' : 'warning'} from ${url} - ${msg}`\n )\n\nconst joinRoomStrategy: JoinRoom<TorrentRoomConfig> = createStrategy({\n init: config =>\n getRelays(config, defaultRelayUrls, defaultRedundancy).map(rawUrl => {\n const client = makeSocket(rawUrl, rawData => {\n const data = fromJson<TrackerMessage>(rawData)\n const errMsg = data['failure reason']\n const warnMsg = data['warning message']\n const {interval} = data\n const topic = data.info_hash\n ? infoHashToTopic[data.info_hash]\n : undefined\n\n if (errMsg) {\n warn(client.url, errMsg, true)\n return\n }\n\n if (warnMsg) {\n warn(client.url, warnMsg)\n }\n\n if (\n interval &&\n interval * 1000 >\n (trackerAnnounceMs[client.url] ?? defaultAnnounceMs) &&\n topic &&\n announceFns[client.url]?.[topic]\n ) {\n const nextInterval = Math.min(interval * 1000, maxAnnounceMs)\n const relayIntervals = (announceIntervals[client.url] ??= {})\n const relayFns = (announceFns[client.url] ??= {})\n\n if (relayIntervals[topic]) {\n clearInterval(relayIntervals[topic])\n }\n trackerAnnounceMs[client.url] = nextInterval\n const relayFn = relayFns[topic]\n\n if (relayFn) {\n relayIntervals[topic] = setInterval(relayFn, nextInterval)\n }\n }\n\n if ((data.offer || data.answer) && topic && data.offer_id) {\n if (data.peer_id === selfId) {\n return\n }\n\n const signalType = data.offer ? 'offer' : 'answer'\n const signalKey = `${topic}:${signalType}:${data.offer_id}:${data.peer_id ?? ''}`\n const nowMs = Date.now()\n const lastHandledMs = handledSignals[signalKey]\n\n if (\n typeof lastHandledMs === 'number' &&\n nowMs - lastHandledMs < signalDedupeWindowMs\n ) {\n return\n }\n\n handledSignals[signalKey] = nowMs\n\n entries(handledSignals).forEach(([key, handledAtMs]) => {\n if (nowMs - handledAtMs > signalDedupeWindowMs * 6) {\n delete handledSignals[key]\n }\n })\n\n msgHandlers[client.url]?.[topic]?.(data)\n }\n })\n\n const {url} = client\n\n clients[url] = client\n msgHandlers[url] = {}\n\n return client.ready\n }),\n\n subscribe: (client, rootTopic, _, onMessage, getOffers) => {\n const {url} = client\n const handlers = (msgHandlers[url] ??= {})\n const relayFns = (announceFns[url] ??= {})\n const relayIntervals = (announceIntervals[url] ??= {})\n const activeTokens = (subscriptionTokens[url] ??= {})\n const subscriptionToken = Symbol(rootTopic)\n const outstandingOffers: Record<string, OfferRecord & {createdAt: number}> =\n {}\n\n activeTokens[rootTopic] = subscriptionToken\n\n const claimOutstandingOffer = (\n offerId: string\n ): OfferRecord | undefined => {\n const offer = outstandingOffers[offerId]\n\n if (!offer) {\n return\n }\n\n delete outstandingOffers[offerId]\n offer.claim?.()\n\n return offer\n }\n\n const reclaimOutstandingOffer = (offerId: string): void => {\n const offer = outstandingOffers[offerId]\n\n if (!offer) {\n return\n }\n\n delete outstandingOffers[offerId]\n offer.reclaim?.()\n }\n\n const reclaimAllOutstandingOffers = (): void => {\n entries(outstandingOffers).forEach(([offerId]) => {\n reclaimOutstandingOffer(offerId)\n })\n }\n\n const pruneOutstandingOffers = (): void => {\n const now = Date.now()\n\n entries(outstandingOffers).forEach(([offerId, offer]) => {\n if (now - offer.createdAt > offerRetentionMs) {\n reclaimOutstandingOffer(offerId)\n }\n })\n }\n\n const topicHandler = (data: TrackerMessage): void => {\n if (data.offer && data.peer_id && data.offer_id) {\n void onMessage(\n rootTopic,\n {\n offer: data.offer,\n peerId: data.peer_id,\n hasOutgoingOffer: entries(outstandingOffers).length > 0\n },\n (_, signal) =>\n void send(client, rootTopic, {\n answer: fromJson<Record<string, unknown>>(signal)['answer'],\n offer_id: data.offer_id,\n to_peer_id: data.peer_id\n })\n )\n } else if (data.answer && data.offer_id && data.peer_id) {\n const offer = claimOutstandingOffer(data.offer_id)\n\n if (offer) {\n void onMessage(\n rootTopic,\n {\n answer: data.answer,\n peerId: data.peer_id,\n peer: offer.peer\n },\n () => {}\n )\n }\n }\n }\n\n handlers[rootTopic] = topicHandler\n\n const announce = async (): Promise<void> => {\n if (activeTokens[rootTopic] !== subscriptionToken) {\n return\n }\n\n pruneOutstandingOffers()\n\n const outstandingCount = entries(outstandingOffers).length\n const missingOffers = Math.max(0, offerPoolSize - outstandingCount)\n\n if (missingOffers > 0) {\n ;(await getOffers(missingOffers)).forEach(peerAndOffer => {\n outstandingOffers[genId(hashLimit)] = {\n ...peerAndOffer,\n createdAt: Date.now()\n }\n })\n }\n\n const offers = entries(outstandingOffers).map(([id, {offer}]) => ({\n offer_id: id,\n offer\n }))\n\n void send(client, rootTopic, {\n numwant: offerPoolSize,\n offers\n })\n }\n\n trackerAnnounceMs[url] = defaultAnnounceMs\n relayFns[rootTopic] = announce\n relayIntervals[rootTopic] = setInterval(announce, trackerAnnounceMs[url])\n void announce()\n\n return () => {\n if (activeTokens[rootTopic] !== subscriptionToken) {\n reclaimAllOutstandingOffers()\n\n return\n }\n\n const interval = relayIntervals[rootTopic]\n if (interval) {\n clearInterval(interval)\n delete relayIntervals[rootTopic]\n }\n\n if (handlers[rootTopic] === topicHandler) {\n delete handlers[rootTopic]\n }\n\n if (relayFns[rootTopic] === announce) {\n delete relayFns[rootTopic]\n }\n\n delete activeTokens[rootTopic]\n\n reclaimAllOutstandingOffers()\n }\n },\n\n announce: client => trackerAnnounceMs[client.url]\n})\n\nexport const joinRoom: JoinRoom<TorrentRoomConfig> = (\n config,\n roomId,\n callbacks\n) =>\n joinRoomStrategy(\n {...config, trickleIce: config.trickleIce ?? false},\n roomId,\n callbacks\n )\n\nexport const getRelaySockets = socketGetter(clients)\n\nexport {pauseRelayReconnection, resumeRelayReconnection, selfId}\n\nexport const defaultRelayUrls = [\n 'tracker.webtorrent.dev',\n 'tracker.openwebtorrent.com',\n 'tracker.btorrent.xyz',\n 'tracker.files.fm:7073/announce'\n].map(url => 'wss://' + url)\n\nexport type * from '@trystero-p2p/core'\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@trystero-p2p/torrent",
|
|
3
|
+
"version": "0.23.0-beta.1",
|
|
4
|
+
"description": "Torrent tracker strategy for Trystero",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"bittorrent",
|
|
7
|
+
"chat",
|
|
8
|
+
"decentralized",
|
|
9
|
+
"matchmaking",
|
|
10
|
+
"p2p",
|
|
11
|
+
"pairing",
|
|
12
|
+
"peer to peer",
|
|
13
|
+
"react",
|
|
14
|
+
"realtime",
|
|
15
|
+
"serverless",
|
|
16
|
+
"signaling",
|
|
17
|
+
"torrent",
|
|
18
|
+
"webrtc",
|
|
19
|
+
"webtorrent"
|
|
20
|
+
],
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"author": {
|
|
23
|
+
"name": "Dan Motzenbecker",
|
|
24
|
+
"email": "dan@oxism.com",
|
|
25
|
+
"url": "https://oxism.com"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist"
|
|
29
|
+
],
|
|
30
|
+
"type": "module",
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"exports": {
|
|
33
|
+
".": "./dist/index.mjs",
|
|
34
|
+
"./package.json": "./package.json"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@trystero-p2p/core": "0.23.0-beta.1"
|
|
38
|
+
}
|
|
39
|
+
}
|