xterm-input-panel 1.2.1 → 1.2.2

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 CHANGED
@@ -1,5 +1,15 @@
1
1
  # xterm-input-panel
2
2
 
3
+ ## 1.2.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 143b916: Add hosted app distribution support across the CLI, server, and web runtime.
8
+ - add `openspecui --app` with configurable hosted app base URLs and local hosted-app dev mode
9
+ - expose hosted session/bootstrap helpers so versioned frontend entries can reconnect to the correct backend
10
+ - include hosted-app settings and faster dashboard overview loading for the web UI
11
+ - scope xterm input-panel persisted state by hosted session to avoid cross-tab leakage
12
+
3
13
  ## 1.2.1
4
14
 
5
15
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xterm-input-panel",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "dependencies": {
@@ -0,0 +1,22 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { getSessionScopedStorageKey } from './storage-namespace'
3
+
4
+ describe('storage namespace helpers', () => {
5
+ it('scopes hosted version entries by session', () => {
6
+ expect(
7
+ getSessionScopedStorageKey('xtermInputPanelState', {
8
+ pathname: '/versions/v2.1/index.html',
9
+ search: '?session=session-a',
10
+ })
11
+ ).toBe('hosted-session:session-a:xtermInputPanelState')
12
+ })
13
+
14
+ it('keeps non-hosted keys unchanged', () => {
15
+ expect(
16
+ getSessionScopedStorageKey('xtermInputPanelState', {
17
+ pathname: '/dashboard',
18
+ search: '?session=session-a',
19
+ })
20
+ ).toBe('xtermInputPanelState')
21
+ })
22
+ })
@@ -0,0 +1,17 @@
1
+ const HOSTED_VERSION_PATH_RE = /^\/versions\/[^/]+(?:\/|$)/
2
+
3
+ function getHostedSessionId(locationLike: Pick<Location, 'pathname' | 'search'>): string | null {
4
+ if (!HOSTED_VERSION_PATH_RE.test(locationLike.pathname)) {
5
+ return null
6
+ }
7
+ const value = new URLSearchParams(locationLike.search).get('session')?.trim()
8
+ return value ? value : null
9
+ }
10
+
11
+ export function getSessionScopedStorageKey(
12
+ baseKey: string,
13
+ locationLike: Pick<Location, 'pathname' | 'search'> = window.location
14
+ ): string {
15
+ const sessionId = getHostedSessionId(locationLike)
16
+ return sessionId ? `hosted-session:${sessionId}:${baseKey}` : baseKey
17
+ }
@@ -2,12 +2,12 @@ import type { ITerminalAddon, Terminal } from '@xterm/xterm'
2
2
  import { iconKeyboard, iconMousePointer2 } from './icons.js'
3
3
  import type { InputPanelLayout, InputPanelTab } from './input-panel.js'
4
4
  import type { HostPlatform } from './platform.js'
5
+ import { getSessionScopedStorageKey } from './storage-namespace.js'
5
6
 
6
7
  const SENSITIVITY = 1.5
7
8
  const EDGE_SCROLL_ZONE = 30
8
9
  const EDGE_SCROLL_INTERVAL = 50
9
10
  const EDGE_SCROLL_OVERSHOOT = 15
10
- const STATE_STORAGE_KEY = 'xtermInputPanelState'
11
11
 
12
12
  function isTouchDevice(): boolean {
13
13
  return 'ontouchstart' in window || navigator.maxTouchPoints > 0
@@ -60,7 +60,7 @@ function isRecord(value: unknown): value is Record<string, unknown> {
60
60
 
61
61
  function loadPanelStateStore(): InputPanelStateStore {
62
62
  try {
63
- const raw = localStorage.getItem(STATE_STORAGE_KEY)
63
+ const raw = localStorage.getItem(getSessionScopedStorageKey('xtermInputPanelState'))
64
64
  if (!raw) return {}
65
65
  const parsed = JSON.parse(raw)
66
66
  return isRecord(parsed) ? (parsed as InputPanelStateStore) : {}
@@ -71,7 +71,7 @@ function loadPanelStateStore(): InputPanelStateStore {
71
71
 
72
72
  function savePanelStateStore(store: InputPanelStateStore): void {
73
73
  try {
74
- localStorage.setItem(STATE_STORAGE_KEY, JSON.stringify(store))
74
+ localStorage.setItem(getSessionScopedStorageKey('xtermInputPanelState'), JSON.stringify(store))
75
75
  } catch {
76
76
  /* ignore */
77
77
  }