pipenet 1.4.0 → 1.4.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 +33 -1
- package/dist/Tunnel.d.ts.map +1 -1
- package/dist/Tunnel.js +12 -1
- package/dist/Tunnel.js.map +1 -1
- package/dist/TunnelCluster.js +2 -2
- package/dist/TunnelCluster.js.map +1 -1
- package/dist/pipenet.spec.js +17 -0
- package/dist/pipenet.spec.js.map +1 -1
- package/package.json +2 -2
- package/src/Tunnel.ts +16 -2
- package/src/TunnelCluster.ts +2 -2
- package/src/pipenet.spec.ts +21 -0
package/README.md
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
# pipenet
|
|
2
2
|
|
|
3
|
-
Expose your local server to the public internet instantly
|
|
3
|
+
Expose your local server to the public internet instantly.
|
|
4
|
+
|
|
5
|
+
## Supported Protocols
|
|
6
|
+
|
|
7
|
+
pipenet tunnels any HTTP-based traffic to your local server:
|
|
8
|
+
|
|
9
|
+
| Protocol | Supported | Notes |
|
|
10
|
+
| -------- | --------- | ----- |
|
|
11
|
+
| HTTP/HTTPS | ✅ | Standard request/response |
|
|
12
|
+
| WebSocket | ✅ | Full duplex communication via HTTP upgrade |
|
|
13
|
+
| SSE (Server-Sent Events) | ✅ | Long-lived HTTP connections |
|
|
14
|
+
| HTTP Streaming | ✅ | Chunked transfer encoding |
|
|
4
15
|
|
|
5
16
|
## Installation
|
|
6
17
|
|
|
@@ -212,6 +223,27 @@ pipenet is a modernized fork of [localtunnel](https://github.com/localtunnel/loc
|
|
|
212
223
|
|
|
213
224
|
**Modern JavaScript**: pipenet uses ES modules and is written in TypeScript, providing better IDE support, type safety, and compatibility with modern JavaScript tooling.
|
|
214
225
|
|
|
226
|
+
## pipenet vs zrok
|
|
227
|
+
|
|
228
|
+
[zrok](https://zrok.io/) is a powerful tunneling solution with SDK support for Go, Python, and Node.js. However, zrok SDKs require the environment to be initialized via the CLI first - you can't just `npm install` and start tunneling.
|
|
229
|
+
|
|
230
|
+
pipenet is designed for zero-setup embedding:
|
|
231
|
+
|
|
232
|
+
```js
|
|
233
|
+
import { pipenet } from 'pipenet';
|
|
234
|
+
|
|
235
|
+
const tunnel = await pipenet({ port: 3000 });
|
|
236
|
+
console.log(tunnel.url);
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
No CLI initialization, no external processes, no daemon - just a pure JavaScript library that works out of the box. This makes pipenet ideal for:
|
|
240
|
+
|
|
241
|
+
- **CLI tools** that need tunneling as a feature (e.g., `mcp-proxy --tunnel`)
|
|
242
|
+
- **Test suites** that need ephemeral public URLs
|
|
243
|
+
- **Scripts** that should "just work" without setup steps
|
|
244
|
+
|
|
245
|
+
If you need advanced features like TCP/UDP tunneling, identity management, or a managed SaaS, zrok is an excellent choice.
|
|
246
|
+
|
|
215
247
|
## Acknowledgments
|
|
216
248
|
|
|
217
249
|
pipenet is based on [localtunnel](https://github.com/localtunnel/localtunnel).
|
package/dist/Tunnel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tunnel.d.ts","sourceRoot":"","sources":["../src/Tunnel.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"Tunnel.d.ts","sourceRoot":"","sources":["../src/Tunnel.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC,OAAO,EAAE,aAAa,EAAwB,MAAM,oBAAoB,CAAC;AAIzE,MAAM,WAAW,aAAa;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA+BD,qBAAa,MAAO,SAAQ,YAAY;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,aAAa,CAAC;IACpB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;gBAER,IAAI,GAAE,aAAkB;IASpC,KAAK,IAAI,IAAI;IAKb,IAAI,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAmBrC,OAAO,CAAC,UAAU;IAkElB,OAAO,CAAC,QAAQ;IAwBhB,OAAO,CAAC,KAAK;CAmCd"}
|
package/dist/Tunnel.js
CHANGED
|
@@ -48,6 +48,7 @@ export class Tunnel extends EventEmitter {
|
|
|
48
48
|
this.emit('error', err);
|
|
49
49
|
});
|
|
50
50
|
let tunnelCount = 0;
|
|
51
|
+
const tunnelHandlers = new Map();
|
|
51
52
|
this.tunnelCluster.on('open', (tunnel) => {
|
|
52
53
|
tunnelCount++;
|
|
53
54
|
log('tunnel open [total: %d]', tunnelCount);
|
|
@@ -58,14 +59,24 @@ export class Tunnel extends EventEmitter {
|
|
|
58
59
|
closeHandler();
|
|
59
60
|
return;
|
|
60
61
|
}
|
|
62
|
+
tunnelHandlers.set(tunnel, closeHandler);
|
|
61
63
|
this.once('close', closeHandler);
|
|
62
64
|
tunnel.once('close', () => {
|
|
65
|
+
tunnelHandlers.delete(tunnel);
|
|
63
66
|
this.removeListener('close', closeHandler);
|
|
64
67
|
});
|
|
65
68
|
});
|
|
66
|
-
this.tunnelCluster.on('dead', () => {
|
|
69
|
+
this.tunnelCluster.on('dead', (deadSocket) => {
|
|
67
70
|
tunnelCount--;
|
|
68
71
|
log('tunnel dead [total: %d]', tunnelCount);
|
|
72
|
+
// Eagerly remove the close handler for the dead tunnel.
|
|
73
|
+
// Without this, the handler lingers until the socket's async
|
|
74
|
+
// 'close' event fires, causing listener accumulation.
|
|
75
|
+
if (deadSocket && tunnelHandlers.has(deadSocket)) {
|
|
76
|
+
const handler = tunnelHandlers.get(deadSocket);
|
|
77
|
+
tunnelHandlers.delete(deadSocket);
|
|
78
|
+
this.removeListener('close', handler);
|
|
79
|
+
}
|
|
69
80
|
if (this.closed) {
|
|
70
81
|
return;
|
|
71
82
|
}
|
package/dist/Tunnel.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tunnel.js","sourceRoot":"","sources":["../src/Tunnel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"Tunnel.js","sourceRoot":"","sources":["../src/Tunnel.ts"],"names":[],"mappings":"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"}
|
package/dist/TunnelCluster.js
CHANGED
|
@@ -35,7 +35,7 @@ export class TunnelCluster extends EventEmitter {
|
|
|
35
35
|
const connLocal = () => {
|
|
36
36
|
if (remote.destroyed) {
|
|
37
37
|
log('remote destroyed');
|
|
38
|
-
this.emit('dead');
|
|
38
|
+
this.emit('dead', remote);
|
|
39
39
|
return;
|
|
40
40
|
}
|
|
41
41
|
log('connecting locally to %s://%s:%d', localProtocol, localHost, localPort);
|
|
@@ -55,7 +55,7 @@ export class TunnelCluster extends EventEmitter {
|
|
|
55
55
|
: net.connect({ host: localHost, port: localPort });
|
|
56
56
|
const remoteClose = () => {
|
|
57
57
|
log('remote close');
|
|
58
|
-
this.emit('dead');
|
|
58
|
+
this.emit('dead', remote);
|
|
59
59
|
local.end();
|
|
60
60
|
};
|
|
61
61
|
remote.once('close', remoteClose);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TunnelCluster.js","sourceRoot":"","sources":["../src/TunnelCluster.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,MAAM,GAAG,GAAG,KAAK,CAAC,gBAAgB,CAAC,CAAC;AAyBpC,MAAM,OAAO,aAAc,SAAQ,YAAY;IACrC,IAAI,CAAuB;IAEnC,YAAY,OAA6B,EAAE;QACzC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,IAAI;QACF,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC;QAEtB,MAAM,cAAc,GAAG,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,UAAU,CAAC;QACtD,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC;QAClC,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,IAAI,WAAW,CAAC;QAC/C,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;QAChC,MAAM,aAAa,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QACxD,MAAM,gBAAgB,GAAG,GAAG,CAAC,gBAAgB,CAAC;QAE9C,GAAG,CACD,yCAAyC,EACzC,aAAa,EACb,SAAS,EACT,SAAS,EACT,cAAc,EACd,UAAU,CACX,CAAC;QAEF,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC;YACzB,IAAI,EAAE,cAAc;YACpB,IAAI,EAAE,UAAW;SAClB,CAAC,CAAC;QAEH,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAE1B,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAA0B,EAAE,EAAE;YAChD,GAAG,CAAC,6BAA6B,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YAEhD,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;gBAChC,IAAI,CAAC,IAAI,CACP,OAAO,EACP,IAAI,KAAK,CACP,uBAAuB,cAAc,IAAI,UAAU,iCAAiC,CACrF,CACF,CAAC;YACJ,CAAC;YAED,MAAM,CAAC,GAAG,EAAE,CAAC;QACf,CAAC,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,GAAS,EAAE;YAC3B,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;gBACrB,GAAG,CAAC,kBAAkB,CAAC,CAAC;gBACxB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"TunnelCluster.js","sourceRoot":"","sources":["../src/TunnelCluster.ts"],"names":[],"mappings":"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"}
|
package/dist/pipenet.spec.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
2
3
|
import http from 'http';
|
|
3
4
|
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
|
4
5
|
import { pipenet } from './pipenet.js';
|
|
@@ -78,5 +79,21 @@ describe('pipenet', () => {
|
|
|
78
79
|
tunnel.close();
|
|
79
80
|
});
|
|
80
81
|
});
|
|
82
|
+
it('does not leak close listeners across tunnel reconnections', async () => {
|
|
83
|
+
const tunnel = await pipenet(fakePort, { host });
|
|
84
|
+
const cluster = tunnel.tunnelCluster;
|
|
85
|
+
const before = tunnel.listenerCount('close');
|
|
86
|
+
// Force rapid reconnection cycles by emitting open→dead on the cluster.
|
|
87
|
+
for (let i = 0; i < 20; i++) {
|
|
88
|
+
const fakeSocket = new EventEmitter();
|
|
89
|
+
fakeSocket.destroy = () => { };
|
|
90
|
+
cluster.emit('open', fakeSocket);
|
|
91
|
+
cluster.emit('dead', fakeSocket);
|
|
92
|
+
}
|
|
93
|
+
// Without the fix, 20 close handlers would accumulate.
|
|
94
|
+
// With eager cleanup, count should not grow.
|
|
95
|
+
expect(tunnel.listenerCount('close')).toBe(before);
|
|
96
|
+
tunnel.close();
|
|
97
|
+
});
|
|
81
98
|
});
|
|
82
99
|
//# sourceMappingURL=pipenet.spec.js.map
|
package/dist/pipenet.spec.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipenet.spec.js","sourceRoot":"","sources":["../src/pipenet.spec.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pipenet.spec.js","sourceRoot":"","sources":["../src/pipenet.spec.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pipenet",
|
|
3
3
|
"description": "Expose your local server to the public internet instantly",
|
|
4
|
-
"version": "1.4.
|
|
4
|
+
"version": "1.4.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/pipenet.js",
|
|
7
7
|
"types": "./dist/pipenet.d.ts",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"eslint-config-prettier": "^10.1.8",
|
|
71
71
|
"eslint-plugin-perfectionist": "^5.3.1",
|
|
72
72
|
"jiti": "^2.6.1",
|
|
73
|
-
"knip": "^
|
|
73
|
+
"knip": "^6.13.1",
|
|
74
74
|
"semantic-release": "^25.0.2",
|
|
75
75
|
"supertest": "^7.2.2",
|
|
76
76
|
"typescript": "^5.9.3",
|
package/src/Tunnel.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
2
|
import debug from 'debug';
|
|
3
3
|
import { EventEmitter } from 'events';
|
|
4
|
+
import net from 'net';
|
|
4
5
|
|
|
5
6
|
import { TunnelCluster, TunnelClusterOptions } from './TunnelCluster.js';
|
|
6
7
|
|
|
@@ -104,8 +105,9 @@ export class Tunnel extends EventEmitter {
|
|
|
104
105
|
});
|
|
105
106
|
|
|
106
107
|
let tunnelCount = 0;
|
|
108
|
+
const tunnelHandlers = new Map<net.Socket, () => void>();
|
|
107
109
|
|
|
108
|
-
this.tunnelCluster.on('open', (tunnel:
|
|
110
|
+
this.tunnelCluster.on('open', (tunnel: net.Socket) => {
|
|
109
111
|
tunnelCount++;
|
|
110
112
|
log('tunnel open [total: %d]', tunnelCount);
|
|
111
113
|
|
|
@@ -118,15 +120,27 @@ export class Tunnel extends EventEmitter {
|
|
|
118
120
|
return;
|
|
119
121
|
}
|
|
120
122
|
|
|
123
|
+
tunnelHandlers.set(tunnel, closeHandler);
|
|
121
124
|
this.once('close', closeHandler);
|
|
122
125
|
tunnel.once('close', () => {
|
|
126
|
+
tunnelHandlers.delete(tunnel);
|
|
123
127
|
this.removeListener('close', closeHandler);
|
|
124
128
|
});
|
|
125
129
|
});
|
|
126
130
|
|
|
127
|
-
this.tunnelCluster.on('dead', () => {
|
|
131
|
+
this.tunnelCluster.on('dead', (deadSocket?: net.Socket) => {
|
|
128
132
|
tunnelCount--;
|
|
129
133
|
log('tunnel dead [total: %d]', tunnelCount);
|
|
134
|
+
|
|
135
|
+
// Eagerly remove the close handler for the dead tunnel.
|
|
136
|
+
// Without this, the handler lingers until the socket's async
|
|
137
|
+
// 'close' event fires, causing listener accumulation.
|
|
138
|
+
if (deadSocket && tunnelHandlers.has(deadSocket)) {
|
|
139
|
+
const handler = tunnelHandlers.get(deadSocket)!;
|
|
140
|
+
tunnelHandlers.delete(deadSocket);
|
|
141
|
+
this.removeListener('close', handler);
|
|
142
|
+
}
|
|
143
|
+
|
|
130
144
|
if (this.closed) {
|
|
131
145
|
return;
|
|
132
146
|
}
|
package/src/TunnelCluster.ts
CHANGED
|
@@ -83,7 +83,7 @@ export class TunnelCluster extends EventEmitter {
|
|
|
83
83
|
const connLocal = (): void => {
|
|
84
84
|
if (remote.destroyed) {
|
|
85
85
|
log('remote destroyed');
|
|
86
|
-
this.emit('dead');
|
|
86
|
+
this.emit('dead', remote);
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
89
89
|
|
|
@@ -109,7 +109,7 @@ export class TunnelCluster extends EventEmitter {
|
|
|
109
109
|
|
|
110
110
|
const remoteClose = (): void => {
|
|
111
111
|
log('remote close');
|
|
112
|
-
this.emit('dead');
|
|
112
|
+
this.emit('dead', remote);
|
|
113
113
|
local.end();
|
|
114
114
|
};
|
|
115
115
|
|
package/src/pipenet.spec.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AddressInfo } from 'net';
|
|
2
2
|
|
|
3
3
|
import axios from 'axios';
|
|
4
|
+
import { EventEmitter } from 'events';
|
|
4
5
|
import http from 'http';
|
|
5
6
|
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
|
6
7
|
|
|
@@ -96,4 +97,24 @@ describe('custom headers', () => {
|
|
|
96
97
|
});
|
|
97
98
|
});
|
|
98
99
|
|
|
100
|
+
it('does not leak close listeners across tunnel reconnections', async () => {
|
|
101
|
+
const tunnel = await pipenet(fakePort, { host });
|
|
102
|
+
const cluster = tunnel.tunnelCluster!;
|
|
103
|
+
|
|
104
|
+
const before = tunnel.listenerCount('close');
|
|
105
|
+
|
|
106
|
+
// Force rapid reconnection cycles by emitting open→dead on the cluster.
|
|
107
|
+
for (let i = 0; i < 20; i++) {
|
|
108
|
+
const fakeSocket = new EventEmitter() as { destroy: () => void } & EventEmitter;
|
|
109
|
+
fakeSocket.destroy = () => {};
|
|
110
|
+
cluster.emit('open', fakeSocket);
|
|
111
|
+
cluster.emit('dead', fakeSocket);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Without the fix, 20 close handlers would accumulate.
|
|
115
|
+
// With eager cleanup, count should not grow.
|
|
116
|
+
expect(tunnel.listenerCount('close')).toBe(before);
|
|
117
|
+
tunnel.close();
|
|
118
|
+
});
|
|
119
|
+
|
|
99
120
|
});
|