green-screen-react 0.3.0 → 0.4.0
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 +245 -50
- package/dist/index.d.mts +81 -17
- package/dist/index.d.ts +81 -17
- package/dist/index.js +405 -194
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +374 -168
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
#
|
|
1
|
+
# GREEN SCREEN REACT (EMULATOR FOR WEB)
|
|
2
2
|
|
|
3
|
-
Multi-protocol legacy terminal React
|
|
3
|
+
Multi-protocol legacy terminal emulator for React. Connects to **TN5250** (IBM i / AS/400), **TN3270** (z/OS mainframe), **VT220** (OpenVMS, Unix), and **HP 6530** (NonStop) hosts.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **Multi-protocol** — TN5250
|
|
7
|
+
- **Multi-protocol** — TN5250, TN3270, VT220, HP 6530
|
|
8
|
+
- **Real-time WebSocket** — instant screen updates
|
|
8
9
|
- Protocol-specific color conventions and screen dimensions
|
|
9
10
|
- Keyboard input: text, function keys (F1-F24), tab, arrow keys
|
|
10
11
|
- Field-aware rendering with input field underlines
|
|
@@ -12,32 +13,222 @@ Multi-protocol legacy terminal React component supporting TN5250, TN3270, VT220,
|
|
|
12
13
|
- Auto-reconnect with exponential backoff
|
|
13
14
|
- Fully themeable via CSS custom properties
|
|
14
15
|
- Zero runtime dependencies (peer deps: React 18+)
|
|
15
|
-
-
|
|
16
|
+
- Togglable inline sign-in form (host, credentials, protocol picker)
|
|
16
17
|
- Pluggable adapter interface for any backend
|
|
18
|
+
- Mock mode for instant evaluation without a real host
|
|
17
19
|
|
|
18
|
-
##
|
|
20
|
+
## How It Works
|
|
21
|
+
|
|
22
|
+
Browsers cannot open raw TCP sockets to telnet hosts. You need a backend that bridges WebSocket to TCP. Choose one:
|
|
23
|
+
|
|
24
|
+
**Option A — Run locally (development):**
|
|
25
|
+
```
|
|
26
|
+
Your React App green-screen-proxy Legacy Host
|
|
27
|
+
┌──────────────┐ ┌──────────────────┐ ┌──────────────┐
|
|
28
|
+
│ <GreenScreen│ WS │ Node.js proxy │ TCP │ IBM i │
|
|
29
|
+
│ Terminal/> │◄──────►│ localhost:3001 │◄──────►│ Mainframe │
|
|
30
|
+
│ │ │ │ │ VMS / etc. │
|
|
31
|
+
└──────────────┘ └──────────────────┘ └──────────────┘
|
|
32
|
+
npm install npx green-screen-proxy
|
|
33
|
+
green-screen-react
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Option B — Deploy to Cloudflare (production):**
|
|
37
|
+
```
|
|
38
|
+
Your React App Cloudflare Worker Legacy Host
|
|
39
|
+
┌──────────────┐ ┌──────────────────┐ ┌──────────────┐
|
|
40
|
+
│ <GreenScreen│ WS │ Durable Object │ TCP │ IBM i │
|
|
41
|
+
│ Terminal/> │◄──────►│ holds TCP conn │◄──────►│ Mainframe │
|
|
42
|
+
│ │ │ │ │ VMS / etc. │
|
|
43
|
+
└──────────────┘ └──────────────────┘ └──────────────┘
|
|
44
|
+
npm install npx green-screen-proxy deploy
|
|
45
|
+
green-screen-react
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
| | Node.js Proxy | Cloudflare Worker |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| Run with | `npx green-screen-proxy` | `npx green-screen-proxy deploy` |
|
|
51
|
+
| Transport | WebSocket (real-time) | WebSocket (real-time) |
|
|
52
|
+
| Best for | Local dev, self-hosted infra | Production, static sites |
|
|
53
|
+
| Cost | Free (your server) | Free (Cloudflare free tier) |
|
|
54
|
+
|
|
55
|
+
Both use the same WebSocket protocol, so `WebSocketAdapter` works with either.
|
|
56
|
+
|
|
57
|
+
## Quick Start
|
|
58
|
+
|
|
59
|
+
**Step 1 — Install the component:**
|
|
19
60
|
|
|
20
61
|
```bash
|
|
21
62
|
npm install green-screen-react
|
|
22
63
|
```
|
|
23
64
|
|
|
24
|
-
|
|
65
|
+
**Step 2 — Start the proxy** (in a separate terminal):
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npx green-screen-proxy --mock
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
This starts the proxy on `http://localhost:3001` with mock screens — no real host needed to try it out.
|
|
72
|
+
|
|
73
|
+
**Step 3 — Render the terminal:**
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
import { GreenScreenTerminal } from 'green-screen-react';
|
|
77
|
+
import 'green-screen-react/styles.css';
|
|
78
|
+
|
|
79
|
+
function App() {
|
|
80
|
+
return <GreenScreenTerminal />;
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
That's it — the component connects to `localhost:3001` automatically. Remove `--mock` and use the inline sign-in form to connect to a real host.
|
|
85
|
+
|
|
86
|
+
## Production Deployment (Cloudflare Worker)
|
|
87
|
+
|
|
88
|
+
Deploy a serverless backend with one command — no server to manage:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npx green-screen-proxy deploy
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
This will:
|
|
95
|
+
1. Install Wrangler (Cloudflare CLI) if not present
|
|
96
|
+
2. Log you in to Cloudflare if needed
|
|
97
|
+
3. Deploy the worker and print the URL
|
|
98
|
+
4. Save the URL to `.env.local` (auto-detects Vite, Next.js, CRA)
|
|
99
|
+
|
|
100
|
+
Then use it in your app:
|
|
25
101
|
|
|
26
102
|
```tsx
|
|
27
|
-
import { GreenScreenTerminal,
|
|
103
|
+
import { GreenScreenTerminal, WebSocketAdapter } from 'green-screen-react';
|
|
28
104
|
import 'green-screen-react/styles.css';
|
|
29
105
|
|
|
106
|
+
// Reads from VITE_GREEN_SCREEN_URL / NEXT_PUBLIC_GREEN_SCREEN_URL / REACT_APP_GREEN_SCREEN_URL
|
|
107
|
+
const adapter = new WebSocketAdapter({
|
|
108
|
+
workerUrl: import.meta.env.VITE_GREEN_SCREEN_URL
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
<GreenScreenTerminal adapter={adapter} />
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
If no `workerUrl` is provided, the adapter defaults to `http://localhost:3001` (the local proxy).
|
|
115
|
+
|
|
116
|
+
### Deploy options
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
npx green-screen-proxy deploy # Default settings
|
|
120
|
+
npx green-screen-proxy deploy --name my-terminal # Custom worker name
|
|
121
|
+
npx green-screen-proxy deploy --origins https://myapp.com # Lock CORS to your domain
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
User-deployed workers have no restrictions. The shared demo worker (GitHub Pages) has rate limiting and SSRF protection.
|
|
125
|
+
|
|
126
|
+
## Proxy Server
|
|
127
|
+
|
|
128
|
+
The Node.js proxy is ideal for local development and self-hosted environments.
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npx green-screen-proxy # Start on port 3001
|
|
132
|
+
npx green-screen-proxy --mock # Mock mode (no real host needed)
|
|
133
|
+
npx green-screen-proxy --port 8080 # Custom port
|
|
134
|
+
PORT=8080 npx green-screen-proxy # Port via environment variable
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
If you prefer to install it:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
npm install -g green-screen-proxy
|
|
141
|
+
green-screen-proxy
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Connecting to a real host
|
|
145
|
+
|
|
146
|
+
Without `--mock`, the proxy opens real TCP connections. The sign-in form in the terminal collects host, port, protocol, and credentials — the proxy handles the rest.
|
|
147
|
+
|
|
148
|
+
Example: connecting to the public IBM i system at `pub400.com`:
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
<GreenScreenTerminal defaultProtocol="tn5250" />
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Enter `pub400.com` as the host in the sign-in form. The component connects to the local proxy automatically.
|
|
155
|
+
|
|
156
|
+
## Adapters
|
|
157
|
+
|
|
158
|
+
### WebSocketAdapter (recommended)
|
|
159
|
+
|
|
160
|
+
Real-time bidirectional WebSocket. Works with both the Node.js proxy and the Cloudflare Worker.
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
import { WebSocketAdapter } from 'green-screen-react';
|
|
164
|
+
|
|
165
|
+
// Local proxy
|
|
166
|
+
const adapter = new WebSocketAdapter({ workerUrl: 'http://localhost:3001' });
|
|
167
|
+
|
|
168
|
+
// Cloudflare Worker
|
|
169
|
+
const adapter = new WebSocketAdapter({
|
|
170
|
+
workerUrl: 'https://green-screen-worker.your-subdomain.workers.dev'
|
|
171
|
+
});
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Screen updates are pushed instantly — no polling delay.
|
|
175
|
+
|
|
176
|
+
### RestAdapter (HTTP polling)
|
|
177
|
+
|
|
178
|
+
For backends that expose a REST API:
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
import { RestAdapter } from 'green-screen-react';
|
|
182
|
+
|
|
30
183
|
const adapter = new RestAdapter({
|
|
31
184
|
baseUrl: 'https://your-server.com/api/terminal',
|
|
32
185
|
headers: { Authorization: 'Bearer your-token' },
|
|
33
186
|
});
|
|
187
|
+
```
|
|
34
188
|
|
|
35
|
-
|
|
36
|
-
|
|
189
|
+
Maps adapter methods to HTTP endpoints (relative to `baseUrl`):
|
|
190
|
+
|
|
191
|
+
| Method | Path | Request Body |
|
|
192
|
+
|--------|------|-------------|
|
|
193
|
+
| GET | `/screen` | - |
|
|
194
|
+
| GET | `/status` | - |
|
|
195
|
+
| POST | `/connect` | `{ host, port, protocol }` |
|
|
196
|
+
| POST | `/send-text` | `{ text }` |
|
|
197
|
+
| POST | `/send-key` | `{ key }` |
|
|
198
|
+
| POST | `/disconnect` | - |
|
|
199
|
+
| POST | `/reconnect` | - |
|
|
200
|
+
|
|
201
|
+
### Custom Adapters
|
|
202
|
+
|
|
203
|
+
Implement `TerminalAdapter` to connect to any backend:
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
import type { TerminalAdapter, ScreenData, ConnectionStatus, SendResult, ConnectConfig } from 'green-screen-react';
|
|
207
|
+
|
|
208
|
+
class MyAdapter implements TerminalAdapter {
|
|
209
|
+
async getScreen(): Promise<ScreenData | null> { /* ... */ }
|
|
210
|
+
async getStatus(): Promise<ConnectionStatus> { /* ... */ }
|
|
211
|
+
async sendText(text: string): Promise<SendResult> { /* ... */ }
|
|
212
|
+
async sendKey(key: string): Promise<SendResult> { /* ... */ }
|
|
213
|
+
async connect(config?: ConnectConfig): Promise<SendResult> { /* ... */ }
|
|
214
|
+
async disconnect(): Promise<SendResult> { /* ... */ }
|
|
215
|
+
async reconnect(): Promise<SendResult> { /* ... */ }
|
|
37
216
|
}
|
|
38
217
|
```
|
|
39
218
|
|
|
40
|
-
|
|
219
|
+
## Component Usage
|
|
220
|
+
|
|
221
|
+
### Minimal (inline sign-in)
|
|
222
|
+
|
|
223
|
+
```tsx
|
|
224
|
+
import { GreenScreenTerminal } from 'green-screen-react';
|
|
225
|
+
import 'green-screen-react/styles.css';
|
|
226
|
+
|
|
227
|
+
// Connects to localhost:3001 by default. Sign-in form collects host and credentials.
|
|
228
|
+
<GreenScreenTerminal />
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Switching protocols
|
|
41
232
|
|
|
42
233
|
```tsx
|
|
43
234
|
<GreenScreenTerminal adapter={adapter} protocol="tn3270" />
|
|
@@ -47,63 +238,35 @@ function App() {
|
|
|
47
238
|
|
|
48
239
|
### Inline Sign-In
|
|
49
240
|
|
|
50
|
-
|
|
241
|
+
The sign-in form appears by default when disconnected. It collects host, port, protocol, and credentials.
|
|
51
242
|
|
|
52
243
|
```tsx
|
|
244
|
+
// Disable the form (use when you manage connections yourself)
|
|
245
|
+
<GreenScreenTerminal adapter={adapter} inlineSignIn={false} />
|
|
246
|
+
|
|
247
|
+
// Pre-select a protocol
|
|
53
248
|
<GreenScreenTerminal
|
|
54
249
|
adapter={adapter}
|
|
55
|
-
|
|
56
|
-
defaultProtocol="tn5250"
|
|
250
|
+
defaultProtocol="tn3270"
|
|
57
251
|
onSignIn={(config) => console.log('Connecting to', config.host)}
|
|
58
252
|
/>
|
|
59
253
|
```
|
|
60
254
|
|
|
61
|
-
The form renders inside the terminal when disconnected. On submit, it calls `adapter.connect(config)` with `{ host, port, protocol, username, password }`.
|
|
62
|
-
|
|
63
|
-
## Adapter Interface
|
|
64
|
-
|
|
65
|
-
The terminal communicates with your backend through an adapter. Implement the `TerminalAdapter` interface or use the built-in `RestAdapter`.
|
|
66
|
-
|
|
67
|
-
```typescript
|
|
68
|
-
interface TerminalAdapter {
|
|
69
|
-
getScreen(): Promise<ScreenData | null>;
|
|
70
|
-
getStatus(): Promise<ConnectionStatus>;
|
|
71
|
-
sendText(text: string): Promise<SendResult>;
|
|
72
|
-
sendKey(key: string): Promise<SendResult>;
|
|
73
|
-
connect(config?: ConnectConfig): Promise<SendResult>;
|
|
74
|
-
disconnect(): Promise<SendResult>;
|
|
75
|
-
reconnect(): Promise<SendResult>;
|
|
76
|
-
}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### RestAdapter
|
|
80
|
-
|
|
81
|
-
For HTTP-based backends with these endpoints (relative to `baseUrl`):
|
|
82
|
-
|
|
83
|
-
| Method | Path | Description |
|
|
84
|
-
|--------|------|-------------|
|
|
85
|
-
| GET | `/screen` | Get current screen content |
|
|
86
|
-
| GET | `/status` | Get connection status |
|
|
87
|
-
| POST | `/send-text` | Send text input `{ text }` |
|
|
88
|
-
| POST | `/send-key` | Send special key `{ key }` |
|
|
89
|
-
| POST | `/connect` | Establish connection |
|
|
90
|
-
| POST | `/disconnect` | Close connection |
|
|
91
|
-
| POST | `/reconnect` | Reconnect |
|
|
92
|
-
|
|
93
255
|
## Props
|
|
94
256
|
|
|
95
257
|
| Prop | Type | Default | Description |
|
|
96
258
|
|------|------|---------|-------------|
|
|
97
|
-
| `adapter` | `TerminalAdapter` |
|
|
259
|
+
| `adapter` | `TerminalAdapter` | - | Backend communication adapter |
|
|
260
|
+
| `baseUrl` | `string` | - | Shorthand — auto-creates a RestAdapter |
|
|
98
261
|
| `protocol` | `'tn5250' \| 'tn3270' \| 'vt' \| 'hp6530'` | `'tn5250'` | Terminal protocol |
|
|
99
262
|
| `protocolProfile` | `ProtocolProfile` | - | Custom protocol profile (overrides `protocol`) |
|
|
100
263
|
| `screenData` | `ScreenData` | - | Direct screen data injection (bypasses polling) |
|
|
101
264
|
| `connectionStatus` | `ConnectionStatus` | - | Direct status injection |
|
|
102
|
-
| `inlineSignIn` | `boolean` | `
|
|
265
|
+
| `inlineSignIn` | `boolean` | `true` | Show sign-in form when disconnected |
|
|
103
266
|
| `defaultProtocol` | `TerminalProtocol` | `'tn5250'` | Pre-selected protocol in sign-in form |
|
|
104
267
|
| `onSignIn` | `(config) => void` | - | Sign-in submit callback |
|
|
105
268
|
| `readOnly` | `boolean` | `false` | Disable keyboard input |
|
|
106
|
-
| `pollInterval` | `number` | `2000` |
|
|
269
|
+
| `pollInterval` | `number` | `2000` | Screen polling interval in ms (0 to disable) |
|
|
107
270
|
| `autoReconnect` | `boolean` | `true` | Auto-reconnect on disconnect |
|
|
108
271
|
| `maxReconnectAttempts` | `number` | `5` | Max reconnect attempts |
|
|
109
272
|
| `embedded` | `boolean` | `false` | Compact embedded mode |
|
|
@@ -117,6 +280,35 @@ For HTTP-based backends with these endpoints (relative to `baseUrl`):
|
|
|
117
280
|
| `className` | `string` | - | Additional CSS class |
|
|
118
281
|
| `style` | `CSSProperties` | - | Inline styles |
|
|
119
282
|
|
|
283
|
+
## Key Types
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
interface ScreenData {
|
|
287
|
+
content: string; // Newline-separated text (24 lines of 80 chars)
|
|
288
|
+
cursor_row: number; // 0-based cursor row
|
|
289
|
+
cursor_col: number; // 0-based cursor column
|
|
290
|
+
rows?: number; // Terminal rows (default 24)
|
|
291
|
+
cols?: number; // Terminal columns (default 80)
|
|
292
|
+
fields?: Field[]; // Input/protected field definitions
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
interface ConnectionStatus {
|
|
296
|
+
connected: boolean;
|
|
297
|
+
status: 'disconnected' | 'connecting' | 'connected' | 'authenticated' | 'error';
|
|
298
|
+
protocol?: TerminalProtocol;
|
|
299
|
+
host?: string;
|
|
300
|
+
error?: string;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
interface Field {
|
|
304
|
+
row: number; // 0-based row
|
|
305
|
+
col: number; // 0-based column
|
|
306
|
+
length: number; // Field length in characters
|
|
307
|
+
is_input: boolean; // Accepts user input
|
|
308
|
+
is_protected: boolean; // Read-only
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
120
312
|
## Theming
|
|
121
313
|
|
|
122
314
|
Override CSS custom properties to customize the look:
|
|
@@ -136,6 +328,11 @@ Override CSS custom properties to customize the look:
|
|
|
136
328
|
|
|
137
329
|
## Exports
|
|
138
330
|
|
|
331
|
+
### Adapters
|
|
332
|
+
|
|
333
|
+
- `WebSocketAdapter` — Real-time WebSocket (works with proxy and worker)
|
|
334
|
+
- `RestAdapter` — HTTP polling
|
|
335
|
+
|
|
139
336
|
### Hooks
|
|
140
337
|
|
|
141
338
|
- `useTerminalConnection(adapter)` — Connection lifecycle
|
|
@@ -152,8 +349,6 @@ Override CSS custom properties to customize the look:
|
|
|
152
349
|
|
|
153
350
|
- `positionToRowCol(content, position)` — Convert linear position to row/col
|
|
154
351
|
- `isFieldEntry(prev, next)` — Detect field entry vs screen transition
|
|
155
|
-
- `getRowColorClass(rowIndex, content)` — Row color convention
|
|
156
|
-
- `parseHeaderRow(line)` — Parse header row into colored segments
|
|
157
352
|
|
|
158
353
|
## License
|
|
159
354
|
|
package/dist/index.d.mts
CHANGED
|
@@ -148,12 +148,12 @@ interface ConnectConfig {
|
|
|
148
148
|
/** Password for authentication */
|
|
149
149
|
password: string;
|
|
150
150
|
}
|
|
151
|
-
/** @deprecated Use `TerminalAdapter` instead */
|
|
152
|
-
type TN5250Adapter = TerminalAdapter;
|
|
153
151
|
|
|
154
152
|
interface GreenScreenTerminalProps {
|
|
155
|
-
/** Adapter for communicating with the terminal backend */
|
|
156
|
-
adapter
|
|
153
|
+
/** Adapter for communicating with the terminal backend (optional — auto-created from sign-in form or baseUrl) */
|
|
154
|
+
adapter?: TerminalAdapter;
|
|
155
|
+
/** Base URL for the terminal API — convenience shorthand that auto-creates a RestAdapter */
|
|
156
|
+
baseUrl?: string;
|
|
157
157
|
/** Terminal protocol (determines color conventions, header label, etc.) */
|
|
158
158
|
protocol?: TerminalProtocol;
|
|
159
159
|
/** Custom protocol profile (overrides protocol param) */
|
|
@@ -178,7 +178,7 @@ interface GreenScreenTerminalProps {
|
|
|
178
178
|
typingAnimation?: boolean;
|
|
179
179
|
/** Typing animation budget in ms (default 60) */
|
|
180
180
|
typingBudgetMs?: number;
|
|
181
|
-
/** Show inline sign-in form when disconnected (default
|
|
181
|
+
/** Show inline sign-in form when disconnected (default true) */
|
|
182
182
|
inlineSignIn?: boolean;
|
|
183
183
|
/** Default protocol for the sign-in form dropdown (default 'tn5250') */
|
|
184
184
|
defaultProtocol?: TerminalProtocol;
|
|
@@ -201,8 +201,6 @@ interface GreenScreenTerminalProps {
|
|
|
201
201
|
/** Inline styles */
|
|
202
202
|
style?: React.CSSProperties;
|
|
203
203
|
}
|
|
204
|
-
/** @deprecated Use GreenScreenTerminalProps instead */
|
|
205
|
-
type TN5250TerminalProps = GreenScreenTerminalProps;
|
|
206
204
|
/**
|
|
207
205
|
* GreenScreenTerminal — Multi-protocol legacy terminal emulator component.
|
|
208
206
|
*
|
|
@@ -216,9 +214,7 @@ type TN5250TerminalProps = GreenScreenTerminalProps;
|
|
|
216
214
|
*
|
|
217
215
|
* Supports: TN5250 (IBM i), TN3270 (z/OS), VT (OpenVMS/Pick), HP 6530 (NonStop)
|
|
218
216
|
*/
|
|
219
|
-
declare function GreenScreenTerminal({ adapter, protocol, protocolProfile: customProfile, screenData: externalScreenData, connectionStatus: externalStatus, readOnly, pollInterval, autoReconnect: autoReconnectEnabled, maxReconnectAttempts: maxAttempts, embedded, showHeader, typingAnimation, typingBudgetMs, inlineSignIn, defaultProtocol: signInDefaultProtocol, onSignIn, bootLoader, headerRight, overlay, onNotification, onScreenChange, onMinimize, className, style, }: GreenScreenTerminalProps): react_jsx_runtime.JSX.Element;
|
|
220
|
-
/** @deprecated Use GreenScreenTerminal instead */
|
|
221
|
-
declare const TN5250Terminal: typeof GreenScreenTerminal;
|
|
217
|
+
declare function GreenScreenTerminal({ adapter: externalAdapter, baseUrl, protocol, protocolProfile: customProfile, screenData: externalScreenData, connectionStatus: externalStatus, readOnly, pollInterval, autoReconnect: autoReconnectEnabled, maxReconnectAttempts: maxAttempts, embedded, showHeader, typingAnimation, typingBudgetMs, inlineSignIn, defaultProtocol: signInDefaultProtocol, onSignIn, bootLoader, headerRight, overlay, onNotification, onScreenChange, onMinimize, className, style, }: GreenScreenTerminalProps): react_jsx_runtime.JSX.Element;
|
|
222
218
|
|
|
223
219
|
interface TerminalBootLoaderProps {
|
|
224
220
|
/** Text to display during boot animation */
|
|
@@ -236,6 +232,40 @@ interface TerminalBootLoaderProps {
|
|
|
236
232
|
*/
|
|
237
233
|
declare function TerminalBootLoader({ brandText, charSpeed, logo, height, }: TerminalBootLoaderProps): react_jsx_runtime.JSX.Element;
|
|
238
234
|
|
|
235
|
+
interface InlineSignInProps {
|
|
236
|
+
defaultProtocol: TerminalProtocol;
|
|
237
|
+
loading: boolean;
|
|
238
|
+
error: string | null;
|
|
239
|
+
onConnect: (config: ConnectConfig) => void;
|
|
240
|
+
}
|
|
241
|
+
declare function InlineSignIn({ defaultProtocol, loading, error, onConnect }: InlineSignInProps): react_jsx_runtime.JSX.Element;
|
|
242
|
+
|
|
243
|
+
declare const TerminalIcon: ({ size }: {
|
|
244
|
+
size?: number;
|
|
245
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
246
|
+
declare const WifiIcon: ({ size, className, style: s }: {
|
|
247
|
+
size?: number;
|
|
248
|
+
className?: string;
|
|
249
|
+
style?: React.CSSProperties;
|
|
250
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
251
|
+
declare const WifiOffIcon: ({ size, className, style: s }: {
|
|
252
|
+
size?: number;
|
|
253
|
+
className?: string;
|
|
254
|
+
style?: React.CSSProperties;
|
|
255
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
256
|
+
declare const AlertTriangleIcon: ({ size }: {
|
|
257
|
+
size?: number;
|
|
258
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
259
|
+
declare const RefreshIcon: ({ size, className }: {
|
|
260
|
+
size?: number;
|
|
261
|
+
className?: string;
|
|
262
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
263
|
+
declare const KeyIcon: ({ size, style: s }: {
|
|
264
|
+
size?: number;
|
|
265
|
+
style?: React.CSSProperties;
|
|
266
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
267
|
+
declare const MinimizeIcon: () => react_jsx_runtime.JSX.Element;
|
|
268
|
+
|
|
239
269
|
interface RestAdapterOptions {
|
|
240
270
|
/** Base URL for the terminal API (e.g. "https://myhost.com/api/terminal") */
|
|
241
271
|
baseUrl: string;
|
|
@@ -272,6 +302,46 @@ declare class RestAdapter implements TerminalAdapter {
|
|
|
272
302
|
reconnect(): Promise<SendResult>;
|
|
273
303
|
}
|
|
274
304
|
|
|
305
|
+
interface WebSocketAdapterOptions {
|
|
306
|
+
/** URL of the green-screen proxy or worker. Defaults to http://localhost:3001 */
|
|
307
|
+
workerUrl?: string;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* WebSocket adapter that connects to a Cloudflare Worker running green-screen-worker.
|
|
311
|
+
* The Worker holds the TCP connection to the legacy host and relays protocol data.
|
|
312
|
+
*
|
|
313
|
+
* Unlike RestAdapter (which polls over HTTP), this adapter receives real-time
|
|
314
|
+
* screen updates via WebSocket push.
|
|
315
|
+
*/
|
|
316
|
+
declare class WebSocketAdapter implements TerminalAdapter {
|
|
317
|
+
private workerUrl;
|
|
318
|
+
private ws;
|
|
319
|
+
private screen;
|
|
320
|
+
private status;
|
|
321
|
+
private pendingResolvers;
|
|
322
|
+
private screenListeners;
|
|
323
|
+
private statusListeners;
|
|
324
|
+
constructor(options?: WebSocketAdapterOptions);
|
|
325
|
+
/** Subscribe to real-time screen updates */
|
|
326
|
+
onScreen(listener: (screen: ScreenData) => void): () => void;
|
|
327
|
+
/** Subscribe to status changes */
|
|
328
|
+
onStatus(listener: (status: ConnectionStatus) => void): () => void;
|
|
329
|
+
getScreen(): Promise<ScreenData | null>;
|
|
330
|
+
getStatus(): Promise<ConnectionStatus>;
|
|
331
|
+
sendText(text: string): Promise<SendResult>;
|
|
332
|
+
sendKey(key: string): Promise<SendResult>;
|
|
333
|
+
connect(config?: ConnectConfig): Promise<SendResult>;
|
|
334
|
+
disconnect(): Promise<SendResult>;
|
|
335
|
+
reconnect(): Promise<SendResult>;
|
|
336
|
+
/** Close the WebSocket without sending disconnect */
|
|
337
|
+
dispose(): void;
|
|
338
|
+
private ensureWebSocket;
|
|
339
|
+
private handleMessage;
|
|
340
|
+
private sendAndWaitForScreen;
|
|
341
|
+
private screenToResult;
|
|
342
|
+
private wsSend;
|
|
343
|
+
}
|
|
344
|
+
|
|
275
345
|
/**
|
|
276
346
|
* Hook for typing animation effect on terminal screen content.
|
|
277
347
|
* Reveals characters progressively when screen content changes.
|
|
@@ -342,12 +412,6 @@ declare function useTerminalInput(adapter: TerminalAdapter): {
|
|
|
342
412
|
sendText: (text: string) => Promise<SendResult>;
|
|
343
413
|
sendKey: (key: string) => Promise<SendResult>;
|
|
344
414
|
};
|
|
345
|
-
/** @deprecated Use `useTerminalConnection` instead */
|
|
346
|
-
declare const useTN5250Connection: typeof useTerminalConnection;
|
|
347
|
-
/** @deprecated Use `useTerminalScreen` instead */
|
|
348
|
-
declare const useTN5250Screen: typeof useTerminalScreen;
|
|
349
|
-
/** @deprecated Use `useTerminalInput` instead */
|
|
350
|
-
declare const useTN5250Terminal: typeof useTerminalInput;
|
|
351
415
|
|
|
352
416
|
/**
|
|
353
417
|
* Get a protocol profile by type. Defaults to TN5250 for backward compatibility.
|
|
@@ -397,4 +461,4 @@ declare function parseHeaderRow(line: string): {
|
|
|
397
461
|
colorClass: string;
|
|
398
462
|
}[] | null;
|
|
399
463
|
|
|
400
|
-
export { type ConnectConfig, type ConnectionStatus, type Field, GreenScreenTerminal, type GreenScreenTerminalProps, type ProtocolColorProfile, type ProtocolProfile, RestAdapter, type RestAdapterOptions, type ScreenData, type SendResult, type
|
|
464
|
+
export { AlertTriangleIcon, type ConnectConfig, type ConnectionStatus, type Field, GreenScreenTerminal, type GreenScreenTerminalProps, InlineSignIn, type InlineSignInProps, KeyIcon, MinimizeIcon, type ProtocolColorProfile, type ProtocolProfile, RefreshIcon, RestAdapter, type RestAdapterOptions, type ScreenData, type SendResult, type TerminalAdapter, TerminalBootLoader, type TerminalBootLoaderProps, TerminalIcon, type TerminalProtocol, WebSocketAdapter, type WebSocketAdapterOptions, WifiIcon, WifiOffIcon, getProtocolProfile, getRowColorClass, hp6530Profile, isFieldEntry, parseHeaderRow, positionToRowCol, tn3270Profile, tn5250Profile, useTerminalConnection, useTerminalInput, useTerminalScreen, useTypingAnimation, vtProfile };
|
package/dist/index.d.ts
CHANGED
|
@@ -148,12 +148,12 @@ interface ConnectConfig {
|
|
|
148
148
|
/** Password for authentication */
|
|
149
149
|
password: string;
|
|
150
150
|
}
|
|
151
|
-
/** @deprecated Use `TerminalAdapter` instead */
|
|
152
|
-
type TN5250Adapter = TerminalAdapter;
|
|
153
151
|
|
|
154
152
|
interface GreenScreenTerminalProps {
|
|
155
|
-
/** Adapter for communicating with the terminal backend */
|
|
156
|
-
adapter
|
|
153
|
+
/** Adapter for communicating with the terminal backend (optional — auto-created from sign-in form or baseUrl) */
|
|
154
|
+
adapter?: TerminalAdapter;
|
|
155
|
+
/** Base URL for the terminal API — convenience shorthand that auto-creates a RestAdapter */
|
|
156
|
+
baseUrl?: string;
|
|
157
157
|
/** Terminal protocol (determines color conventions, header label, etc.) */
|
|
158
158
|
protocol?: TerminalProtocol;
|
|
159
159
|
/** Custom protocol profile (overrides protocol param) */
|
|
@@ -178,7 +178,7 @@ interface GreenScreenTerminalProps {
|
|
|
178
178
|
typingAnimation?: boolean;
|
|
179
179
|
/** Typing animation budget in ms (default 60) */
|
|
180
180
|
typingBudgetMs?: number;
|
|
181
|
-
/** Show inline sign-in form when disconnected (default
|
|
181
|
+
/** Show inline sign-in form when disconnected (default true) */
|
|
182
182
|
inlineSignIn?: boolean;
|
|
183
183
|
/** Default protocol for the sign-in form dropdown (default 'tn5250') */
|
|
184
184
|
defaultProtocol?: TerminalProtocol;
|
|
@@ -201,8 +201,6 @@ interface GreenScreenTerminalProps {
|
|
|
201
201
|
/** Inline styles */
|
|
202
202
|
style?: React.CSSProperties;
|
|
203
203
|
}
|
|
204
|
-
/** @deprecated Use GreenScreenTerminalProps instead */
|
|
205
|
-
type TN5250TerminalProps = GreenScreenTerminalProps;
|
|
206
204
|
/**
|
|
207
205
|
* GreenScreenTerminal — Multi-protocol legacy terminal emulator component.
|
|
208
206
|
*
|
|
@@ -216,9 +214,7 @@ type TN5250TerminalProps = GreenScreenTerminalProps;
|
|
|
216
214
|
*
|
|
217
215
|
* Supports: TN5250 (IBM i), TN3270 (z/OS), VT (OpenVMS/Pick), HP 6530 (NonStop)
|
|
218
216
|
*/
|
|
219
|
-
declare function GreenScreenTerminal({ adapter, protocol, protocolProfile: customProfile, screenData: externalScreenData, connectionStatus: externalStatus, readOnly, pollInterval, autoReconnect: autoReconnectEnabled, maxReconnectAttempts: maxAttempts, embedded, showHeader, typingAnimation, typingBudgetMs, inlineSignIn, defaultProtocol: signInDefaultProtocol, onSignIn, bootLoader, headerRight, overlay, onNotification, onScreenChange, onMinimize, className, style, }: GreenScreenTerminalProps): react_jsx_runtime.JSX.Element;
|
|
220
|
-
/** @deprecated Use GreenScreenTerminal instead */
|
|
221
|
-
declare const TN5250Terminal: typeof GreenScreenTerminal;
|
|
217
|
+
declare function GreenScreenTerminal({ adapter: externalAdapter, baseUrl, protocol, protocolProfile: customProfile, screenData: externalScreenData, connectionStatus: externalStatus, readOnly, pollInterval, autoReconnect: autoReconnectEnabled, maxReconnectAttempts: maxAttempts, embedded, showHeader, typingAnimation, typingBudgetMs, inlineSignIn, defaultProtocol: signInDefaultProtocol, onSignIn, bootLoader, headerRight, overlay, onNotification, onScreenChange, onMinimize, className, style, }: GreenScreenTerminalProps): react_jsx_runtime.JSX.Element;
|
|
222
218
|
|
|
223
219
|
interface TerminalBootLoaderProps {
|
|
224
220
|
/** Text to display during boot animation */
|
|
@@ -236,6 +232,40 @@ interface TerminalBootLoaderProps {
|
|
|
236
232
|
*/
|
|
237
233
|
declare function TerminalBootLoader({ brandText, charSpeed, logo, height, }: TerminalBootLoaderProps): react_jsx_runtime.JSX.Element;
|
|
238
234
|
|
|
235
|
+
interface InlineSignInProps {
|
|
236
|
+
defaultProtocol: TerminalProtocol;
|
|
237
|
+
loading: boolean;
|
|
238
|
+
error: string | null;
|
|
239
|
+
onConnect: (config: ConnectConfig) => void;
|
|
240
|
+
}
|
|
241
|
+
declare function InlineSignIn({ defaultProtocol, loading, error, onConnect }: InlineSignInProps): react_jsx_runtime.JSX.Element;
|
|
242
|
+
|
|
243
|
+
declare const TerminalIcon: ({ size }: {
|
|
244
|
+
size?: number;
|
|
245
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
246
|
+
declare const WifiIcon: ({ size, className, style: s }: {
|
|
247
|
+
size?: number;
|
|
248
|
+
className?: string;
|
|
249
|
+
style?: React.CSSProperties;
|
|
250
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
251
|
+
declare const WifiOffIcon: ({ size, className, style: s }: {
|
|
252
|
+
size?: number;
|
|
253
|
+
className?: string;
|
|
254
|
+
style?: React.CSSProperties;
|
|
255
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
256
|
+
declare const AlertTriangleIcon: ({ size }: {
|
|
257
|
+
size?: number;
|
|
258
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
259
|
+
declare const RefreshIcon: ({ size, className }: {
|
|
260
|
+
size?: number;
|
|
261
|
+
className?: string;
|
|
262
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
263
|
+
declare const KeyIcon: ({ size, style: s }: {
|
|
264
|
+
size?: number;
|
|
265
|
+
style?: React.CSSProperties;
|
|
266
|
+
}) => react_jsx_runtime.JSX.Element;
|
|
267
|
+
declare const MinimizeIcon: () => react_jsx_runtime.JSX.Element;
|
|
268
|
+
|
|
239
269
|
interface RestAdapterOptions {
|
|
240
270
|
/** Base URL for the terminal API (e.g. "https://myhost.com/api/terminal") */
|
|
241
271
|
baseUrl: string;
|
|
@@ -272,6 +302,46 @@ declare class RestAdapter implements TerminalAdapter {
|
|
|
272
302
|
reconnect(): Promise<SendResult>;
|
|
273
303
|
}
|
|
274
304
|
|
|
305
|
+
interface WebSocketAdapterOptions {
|
|
306
|
+
/** URL of the green-screen proxy or worker. Defaults to http://localhost:3001 */
|
|
307
|
+
workerUrl?: string;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* WebSocket adapter that connects to a Cloudflare Worker running green-screen-worker.
|
|
311
|
+
* The Worker holds the TCP connection to the legacy host and relays protocol data.
|
|
312
|
+
*
|
|
313
|
+
* Unlike RestAdapter (which polls over HTTP), this adapter receives real-time
|
|
314
|
+
* screen updates via WebSocket push.
|
|
315
|
+
*/
|
|
316
|
+
declare class WebSocketAdapter implements TerminalAdapter {
|
|
317
|
+
private workerUrl;
|
|
318
|
+
private ws;
|
|
319
|
+
private screen;
|
|
320
|
+
private status;
|
|
321
|
+
private pendingResolvers;
|
|
322
|
+
private screenListeners;
|
|
323
|
+
private statusListeners;
|
|
324
|
+
constructor(options?: WebSocketAdapterOptions);
|
|
325
|
+
/** Subscribe to real-time screen updates */
|
|
326
|
+
onScreen(listener: (screen: ScreenData) => void): () => void;
|
|
327
|
+
/** Subscribe to status changes */
|
|
328
|
+
onStatus(listener: (status: ConnectionStatus) => void): () => void;
|
|
329
|
+
getScreen(): Promise<ScreenData | null>;
|
|
330
|
+
getStatus(): Promise<ConnectionStatus>;
|
|
331
|
+
sendText(text: string): Promise<SendResult>;
|
|
332
|
+
sendKey(key: string): Promise<SendResult>;
|
|
333
|
+
connect(config?: ConnectConfig): Promise<SendResult>;
|
|
334
|
+
disconnect(): Promise<SendResult>;
|
|
335
|
+
reconnect(): Promise<SendResult>;
|
|
336
|
+
/** Close the WebSocket without sending disconnect */
|
|
337
|
+
dispose(): void;
|
|
338
|
+
private ensureWebSocket;
|
|
339
|
+
private handleMessage;
|
|
340
|
+
private sendAndWaitForScreen;
|
|
341
|
+
private screenToResult;
|
|
342
|
+
private wsSend;
|
|
343
|
+
}
|
|
344
|
+
|
|
275
345
|
/**
|
|
276
346
|
* Hook for typing animation effect on terminal screen content.
|
|
277
347
|
* Reveals characters progressively when screen content changes.
|
|
@@ -342,12 +412,6 @@ declare function useTerminalInput(adapter: TerminalAdapter): {
|
|
|
342
412
|
sendText: (text: string) => Promise<SendResult>;
|
|
343
413
|
sendKey: (key: string) => Promise<SendResult>;
|
|
344
414
|
};
|
|
345
|
-
/** @deprecated Use `useTerminalConnection` instead */
|
|
346
|
-
declare const useTN5250Connection: typeof useTerminalConnection;
|
|
347
|
-
/** @deprecated Use `useTerminalScreen` instead */
|
|
348
|
-
declare const useTN5250Screen: typeof useTerminalScreen;
|
|
349
|
-
/** @deprecated Use `useTerminalInput` instead */
|
|
350
|
-
declare const useTN5250Terminal: typeof useTerminalInput;
|
|
351
415
|
|
|
352
416
|
/**
|
|
353
417
|
* Get a protocol profile by type. Defaults to TN5250 for backward compatibility.
|
|
@@ -397,4 +461,4 @@ declare function parseHeaderRow(line: string): {
|
|
|
397
461
|
colorClass: string;
|
|
398
462
|
}[] | null;
|
|
399
463
|
|
|
400
|
-
export { type ConnectConfig, type ConnectionStatus, type Field, GreenScreenTerminal, type GreenScreenTerminalProps, type ProtocolColorProfile, type ProtocolProfile, RestAdapter, type RestAdapterOptions, type ScreenData, type SendResult, type
|
|
464
|
+
export { AlertTriangleIcon, type ConnectConfig, type ConnectionStatus, type Field, GreenScreenTerminal, type GreenScreenTerminalProps, InlineSignIn, type InlineSignInProps, KeyIcon, MinimizeIcon, type ProtocolColorProfile, type ProtocolProfile, RefreshIcon, RestAdapter, type RestAdapterOptions, type ScreenData, type SendResult, type TerminalAdapter, TerminalBootLoader, type TerminalBootLoaderProps, TerminalIcon, type TerminalProtocol, WebSocketAdapter, type WebSocketAdapterOptions, WifiIcon, WifiOffIcon, getProtocolProfile, getRowColorClass, hp6530Profile, isFieldEntry, parseHeaderRow, positionToRowCol, tn3270Profile, tn5250Profile, useTerminalConnection, useTerminalInput, useTerminalScreen, useTypingAnimation, vtProfile };
|