@linxin666/dsh-remote-web-ui 0.2.0 → 0.2.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.
Files changed (68) hide show
  1. package/README.i18n.yaml +2 -2
  2. package/README.md +15 -7
  3. package/README.zh.md +4 -4
  4. package/lib/client.js +235 -37
  5. package/lib/client.js.map +1 -1
  6. package/lib/index.js +26 -7
  7. package/lib/mobile.js +209 -39
  8. package/lib/mobile.js.map +1 -1
  9. package/lib/types/client/PluginSettingsCard.d.ts +22 -0
  10. package/lib/types/client/PluginSettingsCard.d.ts.map +1 -1
  11. package/lib/types/client/PluginSettingsCard.js +142 -3
  12. package/lib/types/client/RemoteEntry.d.ts.map +1 -1
  13. package/lib/types/client/RemoteEntry.js +11 -0
  14. package/lib/types/client/RemoteSettingsCard.d.ts +2 -2
  15. package/lib/types/client/UpdatePanel.d.ts.map +1 -1
  16. package/lib/types/client/UpdatePanel.js +2 -2
  17. package/lib/types/client/locales.d.ts +2 -0
  18. package/lib/types/client/locales.d.ts.map +1 -1
  19. package/lib/types/client/locales.js +2 -0
  20. package/lib/types/gate.d.ts.map +1 -1
  21. package/lib/types/gate.js +2 -0
  22. package/lib/types/mobile/api.d.ts +10 -0
  23. package/lib/types/mobile/api.d.ts.map +1 -1
  24. package/lib/types/mobile/api.js +4 -0
  25. package/lib/types/mobile/messages.d.ts +24 -0
  26. package/lib/types/mobile/messages.d.ts.map +1 -1
  27. package/lib/types/mobile/messages.js +60 -23
  28. package/lib/types/mobile/messages.test.js +49 -1
  29. package/lib/types/mobile/mobile-styles.d.ts +1 -1
  30. package/lib/types/mobile/mobile-styles.d.ts.map +1 -1
  31. package/lib/types/mobile/mobile-styles.js +38 -0
  32. package/lib/types/mobile/views/ChatView.d.ts.map +1 -1
  33. package/lib/types/mobile/views/ChatView.js +34 -11
  34. package/lib/types/mobile/views/SessionListView.d.ts.map +1 -1
  35. package/lib/types/mobile/views/SessionListView.js +30 -4
  36. package/lib/types/mobile/views/SessionListView.test.js +58 -1
  37. package/lib/types/mobile/views/WorkspaceView.d.ts.map +1 -1
  38. package/lib/types/mobile/views/WorkspaceView.js +4 -2
  39. package/lib/types/mobile-api.d.ts.map +1 -1
  40. package/lib/types/mobile-api.js +10 -1
  41. package/lib/types/routes.d.ts.map +1 -1
  42. package/lib/types/routes.js +22 -2
  43. package/lib/types/tunnel.d.ts +1 -0
  44. package/lib/types/tunnel.d.ts.map +1 -1
  45. package/lib/types/tunnel.js +7 -2
  46. package/lib/types/update.d.ts +1 -1
  47. package/lib/types/update.d.ts.map +1 -1
  48. package/lib/types/update.js +1 -1
  49. package/package.json +1 -1
  50. package/src/client/PluginSettingsCard.tsx +219 -18
  51. package/src/client/RemoteEntry.tsx +10 -0
  52. package/src/client/RemoteSettingsCard.tsx +2 -2
  53. package/src/client/UpdatePanel.tsx +2 -0
  54. package/src/client/locales.ts +2 -0
  55. package/src/client/settings-card.module.css +90 -1
  56. package/src/gate.ts +2 -0
  57. package/src/mobile/api.ts +14 -1
  58. package/src/mobile/messages.test.ts +52 -1
  59. package/src/mobile/messages.ts +65 -22
  60. package/src/mobile/mobile-styles.ts +38 -0
  61. package/src/mobile/views/ChatView.tsx +33 -10
  62. package/src/mobile/views/SessionListView.test.tsx +69 -1
  63. package/src/mobile/views/SessionListView.tsx +58 -5
  64. package/src/mobile/views/WorkspaceView.tsx +4 -2
  65. package/src/mobile-api.ts +9 -1
  66. package/src/routes.ts +22 -2
  67. package/src/tunnel.ts +7 -2
  68. package/src/update.ts +2 -2
package/src/tunnel.ts CHANGED
@@ -86,6 +86,9 @@ export class TunnelManager {
86
86
  private urlTimer: unknown | undefined
87
87
  private restartTimer: unknown | undefined
88
88
  private attempts = 0
89
+ // Generation counter: a stale ensureBinary resolution from an earlier
90
+ // start() must not spawn a second handle after a stop/start cycle.
91
+ private generation = 0
89
92
  private stopping = false
90
93
  private readonly urlListeners = new Set<(url: string) => void>()
91
94
  private readonly phaseListeners = new Set<(info: TunnelInfo) => void>()
@@ -123,6 +126,7 @@ export class TunnelManager {
123
126
  this.stopping = false
124
127
  this.targetUrl = targetUrl
125
128
  this.attempts = 0
129
+ this.generation += 1
126
130
  this.attempt()
127
131
  }
128
132
 
@@ -153,12 +157,13 @@ export class TunnelManager {
153
157
 
154
158
  private attempt(): void {
155
159
  if (this.stopping || this.targetUrl === undefined) return
160
+ const gen = this.generation
156
161
  this.setPhase('starting')
157
162
  this.handle = undefined
158
163
  this.url = undefined
159
164
  this.error = undefined
160
165
  void this.ensureBinary().then(() => {
161
- if (this.stopping || this.targetUrl === undefined) return
166
+ if (this.stopping || this.targetUrl === undefined || gen !== this.generation) return
162
167
  const handle = this.factory(this.targetUrl)
163
168
  this.handle = handle
164
169
  this.urlTimer = this.timer.setTimeout(() => {
@@ -181,7 +186,7 @@ export class TunnelManager {
181
186
  })
182
187
  }).catch((value: unknown) => {
183
188
  // Binary install failed (no network, no platform build): report it.
184
- if (this.stopping || this.targetUrl === undefined) return
189
+ if (this.stopping || this.targetUrl === undefined || gen !== this.generation) return
185
190
  const message = value instanceof Error ? value.message : String(value)
186
191
  this.fail(`could not obtain the cloudflared binary: ${message}`)
187
192
  })
package/src/update.ts CHANGED
@@ -280,14 +280,14 @@ function familyUpdatePackages(
280
280
  */
281
281
  export async function fetchLatestVersion(
282
282
  name: string,
283
- fetchImpl: (url: string) => Promise<{ ok: boolean; json(): Promise<unknown> }>,
283
+ fetchImpl: (url: string, init?: RequestInit) => Promise<{ ok: boolean; json(): Promise<unknown> }>,
284
284
  timeoutMs = 10_000,
285
285
  ): Promise<string | undefined> {
286
286
  try {
287
287
  const controller = new AbortController()
288
288
  const timer = setTimeout(() => { controller.abort() }, timeoutMs)
289
289
  try {
290
- const response = await fetchImpl(NPM_REGISTRY + '/' + name.replace('/', '%2F') + '/latest')
290
+ const response = await fetchImpl(NPM_REGISTRY + '/' + name.replace('/', '%2F') + '/latest', { signal: controller.signal })
291
291
  if (!response.ok) return undefined
292
292
  const body = await response.json()
293
293
  if (typeof body !== 'object' || body === null) return undefined