nport 2.0.6 → 2.0.7
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/CHANGELOG.md +101 -0
- package/LICENSE +21 -0
- package/README.md +16 -1
- package/package.json +3 -3
- package/src/api.js +15 -0
- package/src/binary.js +39 -1
- package/src/config.js +18 -0
- package/src/lang.js +31 -1
- package/src/state.js +36 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,82 @@ All notable changes to NPort will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.0.7] - 2026-01-14
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- 🌐 **Smart Network Warning System**: Intelligent handling of QUIC/network connectivity issues
|
|
12
|
+
- Automatic detection and filtering of QUIC protocol errors
|
|
13
|
+
- User-friendly warning messages instead of scary red error spam
|
|
14
|
+
- Bilingual support (English & Vietnamese)
|
|
15
|
+
- Smart throttling: Shows warning only after 5 errors, max once per 30 seconds
|
|
16
|
+
- Clear explanations of what's happening and how to fix it
|
|
17
|
+
- Automatic reset when connection is restored
|
|
18
|
+
- 🔒 **Protected Subdomain Support**: Enhanced error handling for reserved subdomains
|
|
19
|
+
- User-friendly error message when trying to create protected subdomains (like `api`)
|
|
20
|
+
- Formatted error output matching existing error style
|
|
21
|
+
- Helpful suggestions to use alternative subdomain names
|
|
22
|
+
- Prevents accidental use of backend service subdomains
|
|
23
|
+
|
|
24
|
+
### Improved
|
|
25
|
+
- 🔇 **Cleaner Terminal Output**: No more error spam from cloudflared
|
|
26
|
+
- QUIC timeout errors are now silently tracked instead of displayed
|
|
27
|
+
- Network warnings filtered: "failed to accept QUIC stream", "timeout: no recent network activity", etc.
|
|
28
|
+
- Only shows meaningful warnings when there's an actual persistent issue
|
|
29
|
+
- Terminal stays clean and readable during normal operation
|
|
30
|
+
- 📡 **Better User Communication**: Context-aware network issue reporting
|
|
31
|
+
- Explains that QUIC failures are usually not critical
|
|
32
|
+
- Tunnel continues working via HTTP/2 fallback
|
|
33
|
+
- Provides actionable troubleshooting steps
|
|
34
|
+
- Reassures users that the tunnel is still functional
|
|
35
|
+
- ✨ **Better Error Messages**: Enhanced user feedback for protected subdomains
|
|
36
|
+
- Catches `SUBDOMAIN_PROTECTED` errors from backend
|
|
37
|
+
- Formats error messages consistently with other error types
|
|
38
|
+
- Shows actionable options when subdomain is reserved
|
|
39
|
+
|
|
40
|
+
### Technical Details
|
|
41
|
+
- **Network Error Patterns**: Added detection for 7 common QUIC/network error patterns
|
|
42
|
+
- **State Management**: New network issue tracking in application state
|
|
43
|
+
- `networkIssueCount`: Counter for network errors
|
|
44
|
+
- `lastNetworkWarningTime`: Timestamp tracking for cooldown
|
|
45
|
+
- `shouldShowNetworkWarning()`: Smart decision logic
|
|
46
|
+
- **Configuration**: New `NETWORK_CONFIG` with threshold and cooldown settings
|
|
47
|
+
- **Bilingual Messages**: Complete translations for all network warning messages
|
|
48
|
+
- **Protected Subdomain Handling**: Enhanced error handling in `src/api.js`
|
|
49
|
+
- Added check for `SUBDOMAIN_PROTECTED` error type
|
|
50
|
+
- Consistent formatting with existing error messages
|
|
51
|
+
- Clear user guidance for alternative subdomain choices
|
|
52
|
+
|
|
53
|
+
### User Experience
|
|
54
|
+
**Before:**
|
|
55
|
+
```
|
|
56
|
+
[Cloudflared] 2026-01-14T04:33:02Z ERR failed to accept QUIC stream...
|
|
57
|
+
[Cloudflared] 2026-01-14T04:33:03Z ERR failed to accept QUIC stream...
|
|
58
|
+
[Cloudflared] 2026-01-14T04:33:04Z ERR failed to accept QUIC stream...
|
|
59
|
+
[Cloudflared] 2026-01-14T04:33:05Z ERR failed to accept QUIC stream...
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**After:**
|
|
63
|
+
```
|
|
64
|
+
✔ [1/2] Connection established...
|
|
65
|
+
✔ [2/2] Compression enabled...
|
|
66
|
+
|
|
67
|
+
⚠️ NETWORK CONNECTIVITY ISSUE DETECTED
|
|
68
|
+
Cloudflared is having trouble maintaining a stable connection...
|
|
69
|
+
📡 Your tunnel is still working, but connection quality may be affected.
|
|
70
|
+
|
|
71
|
+
💡 Possible reasons:
|
|
72
|
+
• Unstable internet connection or high packet loss
|
|
73
|
+
• Firewall/Router blocking UDP traffic (QUIC protocol)
|
|
74
|
+
• ISP throttling or network congestion
|
|
75
|
+
|
|
76
|
+
🔧 What to try:
|
|
77
|
+
• Check your internet connection stability
|
|
78
|
+
• Try connecting from a different network
|
|
79
|
+
• Disable VPN/Proxy if you're using one
|
|
80
|
+
|
|
81
|
+
ℹ️ This is usually not critical - your tunnel should continue working normally.
|
|
82
|
+
```
|
|
83
|
+
|
|
8
84
|
## [2.0.6] - 2026-01-13
|
|
9
85
|
|
|
10
86
|
### Added
|
|
@@ -110,6 +186,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
110
186
|
|
|
111
187
|
## Version Upgrade Guide
|
|
112
188
|
|
|
189
|
+
### From 2.0.6 to 2.0.7
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
npm install -g nport@latest
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**What's New:**
|
|
196
|
+
|
|
197
|
+
1. **Cleaner Terminal Experience**
|
|
198
|
+
- No more scary red QUIC error spam
|
|
199
|
+
- Smart network warnings when needed
|
|
200
|
+
- Automatic fallback to HTTP/2 when QUIC fails
|
|
201
|
+
|
|
202
|
+
2. **Better Error Communication**
|
|
203
|
+
- Understand what's happening with your connection
|
|
204
|
+
- Clear explanations in your language (EN/VI)
|
|
205
|
+
- Actionable troubleshooting steps
|
|
206
|
+
|
|
207
|
+
3. **When You'll See Warnings**
|
|
208
|
+
- Only after multiple network issues (not just one)
|
|
209
|
+
- Maximum once every 30 seconds (no spam)
|
|
210
|
+
- Automatically disappears when connection improves
|
|
211
|
+
|
|
212
|
+
**Breaking Changes:** None - fully backward compatible!
|
|
213
|
+
|
|
113
214
|
### From 2.0.5 to 2.0.6
|
|
114
215
|
|
|
115
216
|
```bash
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nick Pham
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -35,6 +35,17 @@ Perfect for:
|
|
|
35
35
|
|
|
36
36
|
## 📦 Installation
|
|
37
37
|
|
|
38
|
+
### Requirements
|
|
39
|
+
|
|
40
|
+
- **Node.js** >= 20.0.0
|
|
41
|
+
- **npm** >= 10.0.0
|
|
42
|
+
|
|
43
|
+
Check your versions:
|
|
44
|
+
```bash
|
|
45
|
+
node --version
|
|
46
|
+
npm --version
|
|
47
|
+
```
|
|
48
|
+
|
|
38
49
|
### NPM (Recommended)
|
|
39
50
|
|
|
40
51
|
```bash
|
|
@@ -406,8 +417,12 @@ If you find NPort useful, please consider supporting the project:
|
|
|
406
417
|
## 🙏 Credits
|
|
407
418
|
|
|
408
419
|
- Created by [Nick Pham](https://github.com/tuanngocptn) from Vietnam
|
|
409
|
-
- Powered by [Cloudflare Tunnels](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/)
|
|
410
420
|
- Inspired by [ngrok](https://ngrok.com) and [localtunnel](https://github.com/localtunnel/localtunnel)
|
|
421
|
+
- Powered by [Cloudflare Tunnels](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/)
|
|
422
|
+
|
|
423
|
+
<a href="https://www.cloudflare.com" target="_blank">
|
|
424
|
+
<img src="https://nport.link/assets/webp/cloudflare-logo-black.webp" alt="Cloudflare" height="60">
|
|
425
|
+
</a>
|
|
411
426
|
|
|
412
427
|
## 🔗 Links
|
|
413
428
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nport",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.7",
|
|
4
4
|
"description": "Free & open source ngrok alternative - Tunnel HTTP/HTTPS connections via Cloudflare Edge with custom subdomains",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
"nport": "index.js"
|
|
9
9
|
},
|
|
10
10
|
"engines": {
|
|
11
|
-
"node": ">=
|
|
12
|
-
"npm": ">=
|
|
11
|
+
"node": ">=20.0.0",
|
|
12
|
+
"npm": ">=10.0.0"
|
|
13
13
|
},
|
|
14
14
|
"keywords": [
|
|
15
15
|
"ngrok",
|
package/src/api.js
CHANGED
|
@@ -38,6 +38,21 @@ export class APIClient {
|
|
|
38
38
|
if (error.response?.data?.error) {
|
|
39
39
|
const errorMsg = error.response.data.error;
|
|
40
40
|
|
|
41
|
+
// Check for protected subdomain (reserved for production services)
|
|
42
|
+
if (errorMsg.includes("SUBDOMAIN_PROTECTED:")) {
|
|
43
|
+
return new Error(
|
|
44
|
+
`Subdomain "${subdomain}" is already taken or in use.\n\n` +
|
|
45
|
+
chalk.yellow(`💡 Try one of these options:\n`) +
|
|
46
|
+
chalk.gray(` 1. Choose a different subdomain: `) +
|
|
47
|
+
chalk.cyan(`nport ${state.port || CONFIG.DEFAULT_PORT} -s ${subdomain}-v2\n`) +
|
|
48
|
+
chalk.gray(` 2. Use a random subdomain: `) +
|
|
49
|
+
chalk.cyan(`nport ${state.port || CONFIG.DEFAULT_PORT}\n`) +
|
|
50
|
+
chalk.gray(
|
|
51
|
+
` 3. Wait a few minutes and retry if you just stopped a tunnel with this name`
|
|
52
|
+
)
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
41
56
|
// Check for subdomain in use (active tunnel)
|
|
42
57
|
if (
|
|
43
58
|
errorMsg.includes("SUBDOMAIN_IN_USE:") ||
|
package/src/binary.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { spawn } from "child_process";
|
|
2
2
|
import chalk from "chalk";
|
|
3
3
|
import fs from "fs";
|
|
4
|
-
import { LOG_PATTERNS } from "./config.js";
|
|
4
|
+
import { LOG_PATTERNS, NETWORK_CONFIG } from "./config.js";
|
|
5
5
|
import { state } from "./state.js";
|
|
6
6
|
import { UI } from "./ui.js";
|
|
7
7
|
import { lang } from "./lang.js";
|
|
@@ -52,11 +52,19 @@ export class BinaryManager {
|
|
|
52
52
|
return;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
// Check for network warnings (QUIC/connectivity issues)
|
|
56
|
+
if (LOG_PATTERNS.NETWORK_WARNING.some((pattern) => msg.includes(pattern))) {
|
|
57
|
+
this.handleNetworkWarning(msg);
|
|
58
|
+
return; // Don't show the raw error to user
|
|
59
|
+
}
|
|
60
|
+
|
|
55
61
|
// Show success messages with connection count
|
|
56
62
|
if (LOG_PATTERNS.SUCCESS.some((pattern) => msg.includes(pattern))) {
|
|
57
63
|
const count = state.incrementConnection();
|
|
58
64
|
|
|
65
|
+
// Reset network issue count when connection succeeds
|
|
59
66
|
if (count === 1) {
|
|
67
|
+
state.resetNetworkIssues();
|
|
60
68
|
console.log(chalk.green(lang.t("connection1")));
|
|
61
69
|
} else if (count === 4) {
|
|
62
70
|
console.log(chalk.green(lang.t("connection2")));
|
|
@@ -72,6 +80,36 @@ export class BinaryManager {
|
|
|
72
80
|
}
|
|
73
81
|
}
|
|
74
82
|
|
|
83
|
+
static handleNetworkWarning(msg) {
|
|
84
|
+
const count = state.incrementNetworkIssue();
|
|
85
|
+
|
|
86
|
+
// Show user-friendly warning after threshold is reached
|
|
87
|
+
if (
|
|
88
|
+
state.shouldShowNetworkWarning(
|
|
89
|
+
NETWORK_CONFIG.WARNING_THRESHOLD,
|
|
90
|
+
NETWORK_CONFIG.WARNING_COOLDOWN
|
|
91
|
+
)
|
|
92
|
+
) {
|
|
93
|
+
this.displayNetworkWarning();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
static displayNetworkWarning() {
|
|
98
|
+
console.log(chalk.yellow(lang.t("networkIssueTitle")));
|
|
99
|
+
console.log(chalk.gray(lang.t("networkIssueDesc")));
|
|
100
|
+
console.log(chalk.cyan(lang.t("networkIssueTunnel")));
|
|
101
|
+
console.log(chalk.yellow(lang.t("networkIssueReasons")));
|
|
102
|
+
console.log(chalk.gray(lang.t("networkIssueReason1")));
|
|
103
|
+
console.log(chalk.gray(lang.t("networkIssueReason2")));
|
|
104
|
+
console.log(chalk.gray(lang.t("networkIssueReason3")));
|
|
105
|
+
console.log(chalk.yellow(lang.t("networkIssueFix")));
|
|
106
|
+
console.log(chalk.gray(lang.t("networkIssueFix1")));
|
|
107
|
+
console.log(chalk.gray(lang.t("networkIssueFix2")));
|
|
108
|
+
console.log(chalk.gray(lang.t("networkIssueFix3")));
|
|
109
|
+
console.log(chalk.gray(lang.t("networkIssueFix4")));
|
|
110
|
+
console.log(chalk.blue(lang.t("networkIssueIgnore")));
|
|
111
|
+
}
|
|
112
|
+
|
|
75
113
|
static handleError(err, spinner) {
|
|
76
114
|
if (spinner) {
|
|
77
115
|
spinner.fail("Failed to spawn cloudflared process.");
|
package/src/config.js
CHANGED
|
@@ -46,6 +46,18 @@ export const PATHS = {
|
|
|
46
46
|
export const LOG_PATTERNS = {
|
|
47
47
|
SUCCESS: ["Registered tunnel connection"],
|
|
48
48
|
ERROR: ["ERR", "error"],
|
|
49
|
+
|
|
50
|
+
// Network-related warnings (not critical errors)
|
|
51
|
+
NETWORK_WARNING: [
|
|
52
|
+
"failed to accept QUIC stream",
|
|
53
|
+
"failed to dial to edge with quic",
|
|
54
|
+
"failed to accept incoming stream requests",
|
|
55
|
+
"Failed to dial a quic connection",
|
|
56
|
+
"timeout: no recent network activity",
|
|
57
|
+
"failed to dial to edge",
|
|
58
|
+
"quic:",
|
|
59
|
+
],
|
|
60
|
+
|
|
49
61
|
IGNORE: [
|
|
50
62
|
"Cannot determine default origin certificate path",
|
|
51
63
|
"No file cert.pem",
|
|
@@ -65,6 +77,12 @@ export const LOG_PATTERNS = {
|
|
|
65
77
|
],
|
|
66
78
|
};
|
|
67
79
|
|
|
80
|
+
// Network warning configuration
|
|
81
|
+
export const NETWORK_CONFIG = {
|
|
82
|
+
WARNING_THRESHOLD: 5, // Show warning after 5 network errors
|
|
83
|
+
WARNING_COOLDOWN: 30000, // Only show warning every 30 seconds
|
|
84
|
+
};
|
|
85
|
+
|
|
68
86
|
// Computed constants
|
|
69
87
|
export const TUNNEL_TIMEOUT_MS = CONFIG.TUNNEL_TIMEOUT_HOURS * 60 * 60 * 1000;
|
|
70
88
|
|
package/src/lang.js
CHANGED
|
@@ -62,6 +62,21 @@ const TRANSLATIONS = {
|
|
|
62
62
|
languageVietnamese: "2. Tiếng Việt (Vietnamese)",
|
|
63
63
|
languageInvalid: "Invalid choice. Using English by default.",
|
|
64
64
|
languageSaved: "✔ Language preference saved!",
|
|
65
|
+
|
|
66
|
+
// Network warnings
|
|
67
|
+
networkIssueTitle: "\n⚠️ NETWORK CONNECTIVITY ISSUE DETECTED",
|
|
68
|
+
networkIssueDesc: " Cloudflared is having trouble maintaining a stable connection to Cloudflare's edge servers.",
|
|
69
|
+
networkIssueTunnel: " 📡 Your tunnel is still working, but connection quality may be affected.",
|
|
70
|
+
networkIssueReasons: "\n 💡 Possible reasons:",
|
|
71
|
+
networkIssueReason1: " • Unstable internet connection or high packet loss",
|
|
72
|
+
networkIssueReason2: " • Firewall/Router blocking UDP traffic (QUIC protocol)",
|
|
73
|
+
networkIssueReason3: " • ISP throttling or network congestion",
|
|
74
|
+
networkIssueFix: "\n 🔧 What to try:",
|
|
75
|
+
networkIssueFix1: " • Check your internet connection stability",
|
|
76
|
+
networkIssueFix2: " • Try connecting from a different network",
|
|
77
|
+
networkIssueFix3: " • Disable VPN/Proxy if you're using one",
|
|
78
|
+
networkIssueFix4: " • The tunnel will automatically fallback to HTTP/2 if QUIC fails",
|
|
79
|
+
networkIssueIgnore: "\n ℹ️ This is usually not critical - your tunnel should continue working normally.\n",
|
|
65
80
|
},
|
|
66
81
|
|
|
67
82
|
vi: {
|
|
@@ -104,7 +119,7 @@ const TRANSLATIONS = {
|
|
|
104
119
|
|
|
105
120
|
// Version
|
|
106
121
|
versionTitle: "NPort v{version}",
|
|
107
|
-
versionSubtitle: "Hơn cả Ngrok - Ma-de in
|
|
122
|
+
versionSubtitle: "Hơn cả Ngrok - Ma-de in Việt Nam",
|
|
108
123
|
versionLatest: "🎉 Chúc mừng! Đang cùng server với bản mới nhất!",
|
|
109
124
|
versionAvailable: "🌟 Vèo vèo: Có bản mới v{version} vừa cập bến!",
|
|
110
125
|
versionUpdate: "Update khẩn trương lẹ làng: ",
|
|
@@ -117,6 +132,21 @@ const TRANSLATIONS = {
|
|
|
117
132
|
languageVietnamese: "2. Tiếng Việt (Đỉnh của chóp)",
|
|
118
133
|
languageInvalid: "Ơ hơ, chọn sai rồi! Mặc định Tiếng Việt luôn cho nóng.",
|
|
119
134
|
languageSaved: "🎯 Xong rồi! Lưu ngôn ngữ thành công!",
|
|
135
|
+
|
|
136
|
+
// Network warnings
|
|
137
|
+
networkIssueTitle: "\n⚠️ PHÁT HIỆN VẤN ĐỀ MẠNG",
|
|
138
|
+
networkIssueDesc: " Cloudflared đang gặp khó khăn khi giữ kết nối ổn định tới Cloudflare edge servers.",
|
|
139
|
+
networkIssueTunnel: " 📡 Tunnel của bạn vẫn hoạt động, nhưng chất lượng kết nối có thể bị ảnh hưởng.",
|
|
140
|
+
networkIssueReasons: "\n 💡 Có thể do:",
|
|
141
|
+
networkIssueReason1: " • Mạng internet không ổn định hoặc mất gói tin",
|
|
142
|
+
networkIssueReason2: " • Firewall/Router chặn UDP traffic (giao thức QUIC)",
|
|
143
|
+
networkIssueReason3: " • Nhà mạng throttle hoặc tắc nghẽn mạng",
|
|
144
|
+
networkIssueFix: "\n 🔧 Thử các cách sau:",
|
|
145
|
+
networkIssueFix1: " • Kiểm tra kết nối internet của bạn",
|
|
146
|
+
networkIssueFix2: " • Thử đổi sang mạng khác (ví dụ: 4G/5G)",
|
|
147
|
+
networkIssueFix3: " • Tắt VPN/Proxy nếu đang bật",
|
|
148
|
+
networkIssueFix4: " • Tunnel sẽ tự động chuyển sang HTTP/2 nếu QUIC fail",
|
|
149
|
+
networkIssueIgnore: "\n ℹ️ Lỗi này thường không nghiêm trọng - tunnel vẫn hoạt động bình thường.\n",
|
|
120
150
|
}
|
|
121
151
|
};
|
|
122
152
|
|
package/src/state.js
CHANGED
|
@@ -13,6 +13,11 @@ class TunnelState {
|
|
|
13
13
|
this.connectionCount = 0;
|
|
14
14
|
this.startTime = null;
|
|
15
15
|
this.updateInfo = null;
|
|
16
|
+
|
|
17
|
+
// Network issue tracking
|
|
18
|
+
this.networkIssueCount = 0;
|
|
19
|
+
this.lastNetworkWarningTime = 0;
|
|
20
|
+
this.networkWarningShown = false;
|
|
16
21
|
}
|
|
17
22
|
|
|
18
23
|
setTunnel(tunnelId, subdomain, port, backendUrl = null) {
|
|
@@ -62,6 +67,32 @@ class TunnelState {
|
|
|
62
67
|
return (Date.now() - this.startTime) / 1000;
|
|
63
68
|
}
|
|
64
69
|
|
|
70
|
+
// Network issue tracking methods
|
|
71
|
+
incrementNetworkIssue() {
|
|
72
|
+
this.networkIssueCount++;
|
|
73
|
+
return this.networkIssueCount;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
resetNetworkIssues() {
|
|
77
|
+
this.networkIssueCount = 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
shouldShowNetworkWarning(threshold, cooldown) {
|
|
81
|
+
const now = Date.now();
|
|
82
|
+
if (
|
|
83
|
+
this.networkIssueCount >= threshold &&
|
|
84
|
+
now - this.lastNetworkWarningTime > cooldown
|
|
85
|
+
) {
|
|
86
|
+
this.lastNetworkWarningTime = now;
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
setNetworkWarningShown(value) {
|
|
93
|
+
this.networkWarningShown = value;
|
|
94
|
+
}
|
|
95
|
+
|
|
65
96
|
reset() {
|
|
66
97
|
this.clearTimeout();
|
|
67
98
|
this.tunnelId = null;
|
|
@@ -72,6 +103,11 @@ class TunnelState {
|
|
|
72
103
|
this.connectionCount = 0;
|
|
73
104
|
this.startTime = null;
|
|
74
105
|
this.updateInfo = null;
|
|
106
|
+
|
|
107
|
+
// Reset network tracking
|
|
108
|
+
this.networkIssueCount = 0;
|
|
109
|
+
this.lastNetworkWarningTime = 0;
|
|
110
|
+
this.networkWarningShown = false;
|
|
75
111
|
}
|
|
76
112
|
}
|
|
77
113
|
|