filepizza-client 2.1.0 → 2.1.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/README.md CHANGED
@@ -74,7 +74,7 @@ By default, the client:
74
74
  - Fetches ICE server configuration from the FilePizza server
75
75
  - Attempts to discover a PeerJS signaling server from:
76
76
  ```
77
- /api/peerjs-servers
77
+ /api/ice
78
78
  ```
79
79
  - Falls back to PeerJS defaults if no signaling server is configured
80
80
 
package/dist/peerjs.js CHANGED
@@ -8,26 +8,39 @@ function normalizeBaseUrl(url) {
8
8
  }
9
9
  function parsePeerJSServerUrl(serverUrlString) {
10
10
  const serverUrl = new URL(serverUrlString);
11
+ const secure = serverUrl.protocol === 'https:';
11
12
  return {
12
13
  host: serverUrl.hostname,
13
14
  port: serverUrl.port
14
15
  ? Number.parseInt(serverUrl.port, 10)
15
- : serverUrl.protocol === 'https:'
16
+ : secure
16
17
  ? 443
17
18
  : 80,
18
19
  path: serverUrl.pathname,
19
- secure: serverUrl.protocol === 'https:',
20
+ secure,
20
21
  };
21
22
  }
22
- export async function getIceServers(filePizzaServerUrl) {
23
- try {
24
- const response = await fetch(`${normalizeBaseUrl(filePizzaServerUrl)}/api/ice`, {
25
- method: 'POST',
26
- });
23
+ const iceCache = new Map();
24
+ function fetchIceEndpoint(filePizzaServerUrl) {
25
+ const baseUrl = normalizeBaseUrl(filePizzaServerUrl);
26
+ const cached = iceCache.get(baseUrl);
27
+ if (cached) {
28
+ return cached;
29
+ }
30
+ const promise = (async () => {
31
+ const response = await fetch(`${baseUrl}/api/ice`, { method: 'POST' });
27
32
  if (!response.ok) {
28
- throw new Error(`Failed to get ICE servers: ${response.status}`);
33
+ throw new Error(`Failed to fetch /api/ice: ${response.status}`);
29
34
  }
30
- const data = await response.json();
35
+ return (await response.json());
36
+ })();
37
+ promise.catch(() => iceCache.delete(baseUrl));
38
+ iceCache.set(baseUrl, promise);
39
+ return promise;
40
+ }
41
+ export async function getIceServers(filePizzaServerUrl) {
42
+ try {
43
+ const data = await fetchIceEndpoint(filePizzaServerUrl);
31
44
  return data.iceServers || DEFAULT_ICE_SERVERS;
32
45
  }
33
46
  catch (error) {
@@ -37,11 +50,15 @@ export async function getIceServers(filePizzaServerUrl) {
37
50
  }
38
51
  export async function discoverPeerJSSignalingServer(filePizzaServerUrl) {
39
52
  try {
40
- const response = await fetch(`${normalizeBaseUrl(filePizzaServerUrl)}/api/peerjs-servers`);
41
- if (!response.ok) {
42
- return undefined;
53
+ const data = await fetchIceEndpoint(filePizzaServerUrl);
54
+ if (data.host) {
55
+ return {
56
+ host: data.host,
57
+ path: data.path,
58
+ port: data.port,
59
+ secure: data.secure,
60
+ };
43
61
  }
44
- const data = await response.json();
45
62
  const firstServer = data.servers?.[0];
46
63
  if (!firstServer) {
47
64
  return undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"peerjs.js","sourceRoot":"","sources":["../src/peerjs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"peerjs.js","sourceRoot":"","sources":["../src/peerjs.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "filepizza-client",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "Client API for FilePizza, a free peer-to-peer file transfer service.",
5
5
  "author": "Fares Abawi <fares@abawi.me> (https://abawi.me)",
6
6
  "license": "MIT",
@@ -512,4 +512,4 @@ export class FilePizzaUploader extends EventEmitter {
512
512
  totalBytes: context.totalBytes,
513
513
  }
514
514
  }
515
- }
515
+ }
package/src/peerjs.ts CHANGED
@@ -13,38 +13,63 @@ export type PeerJSConfigOptions = {
13
13
  discoverPeerJSSignalingServer?: boolean
14
14
  }
15
15
 
16
+ type IceEndpointResponse = {
17
+ host?: string
18
+ path?: string
19
+ port?: number
20
+ secure?: boolean
21
+ servers?: string[]
22
+ iceServers?: RTCIceServer[]
23
+ }
24
+
16
25
  function normalizeBaseUrl(url: string): string {
17
26
  return url.replace(/\/+$/, '')
18
27
  }
19
28
 
20
29
  function parsePeerJSServerUrl(serverUrlString: string): PeerJSSignalingServer {
21
30
  const serverUrl = new URL(serverUrlString)
22
-
31
+ const secure = serverUrl.protocol === 'https:'
23
32
  return {
24
33
  host: serverUrl.hostname,
25
34
  port: serverUrl.port
26
35
  ? Number.parseInt(serverUrl.port, 10)
27
- : serverUrl.protocol === 'https:'
36
+ : secure
28
37
  ? 443
29
38
  : 80,
30
39
  path: serverUrl.pathname,
31
- secure: serverUrl.protocol === 'https:',
40
+ secure,
32
41
  }
33
42
  }
34
43
 
35
- export async function getIceServers(
44
+ const iceCache = new Map<string, Promise<IceEndpointResponse>>()
45
+
46
+ function fetchIceEndpoint(
36
47
  filePizzaServerUrl: string,
37
- ): Promise<RTCIceServer[]> {
38
- try {
39
- const response = await fetch(`${normalizeBaseUrl(filePizzaServerUrl)}/api/ice`, {
40
- method: 'POST',
41
- })
48
+ ): Promise<IceEndpointResponse> {
49
+ const baseUrl = normalizeBaseUrl(filePizzaServerUrl)
50
+ const cached = iceCache.get(baseUrl)
51
+ if (cached) {
52
+ return cached
53
+ }
42
54
 
55
+ const promise = (async () => {
56
+ const response = await fetch(`${baseUrl}/api/ice`, { method: 'POST' })
43
57
  if (!response.ok) {
44
- throw new Error(`Failed to get ICE servers: ${response.status}`)
58
+ throw new Error(`Failed to fetch /api/ice: ${response.status}`)
45
59
  }
60
+ return (await response.json()) as IceEndpointResponse
61
+ })()
62
+
63
+ promise.catch(() => iceCache.delete(baseUrl))
64
+ iceCache.set(baseUrl, promise)
65
+ return promise
66
+ }
46
67
 
47
- const data = await response.json()
68
+ export async function getIceServers(
69
+ filePizzaServerUrl: string,
70
+ ): Promise<RTCIceServer[]> {
71
+ try {
72
+ const data = await fetchIceEndpoint(filePizzaServerUrl)
48
73
  return data.iceServers || DEFAULT_ICE_SERVERS
49
74
  } catch (error) {
50
75
  console.error('Error getting ICE servers:', error)
@@ -56,21 +81,21 @@ export async function discoverPeerJSSignalingServer(
56
81
  filePizzaServerUrl: string,
57
82
  ): Promise<PeerJSSignalingServer | undefined> {
58
83
  try {
59
- const response = await fetch(
60
- `${normalizeBaseUrl(filePizzaServerUrl)}/api/peerjs-servers`,
61
- )
62
-
63
- if (!response.ok) {
64
- return undefined
84
+ const data = await fetchIceEndpoint(filePizzaServerUrl)
85
+
86
+ if (data.host) {
87
+ return {
88
+ host: data.host,
89
+ path: data.path,
90
+ port: data.port,
91
+ secure: data.secure,
92
+ }
65
93
  }
66
94
 
67
- const data = await response.json()
68
95
  const firstServer = data.servers?.[0]
69
-
70
96
  if (!firstServer) {
71
97
  return undefined
72
98
  }
73
-
74
99
  return parsePeerJSServerUrl(firstServer)
75
100
  } catch (error) {
76
101
  console.error('Error discovering PeerJS signaling server:', error)
@@ -102,9 +127,7 @@ export async function buildPeerOptions({
102
127
  }
103
128
  }
104
129
 
105
- export async function createPeer(
106
- options: PeerJSConfigOptions,
107
- ): Promise<Peer> {
130
+ export async function createPeer(options: PeerJSConfigOptions): Promise<Peer> {
108
131
  const peerOptions = await buildPeerOptions(options)
109
132
  const peer = new Peer(peerOptions)
110
133
 
@@ -117,9 +140,8 @@ export async function createPeer(
117
140
  peer.off('open', onOpen)
118
141
  resolve()
119
142
  }
120
-
121
143
  peer.on('open', onOpen)
122
144
  })
123
145
 
124
146
  return peer
125
- }
147
+ }