green-screen-react 1.1.3 → 1.2.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 +57 -0
- package/dist/index.d.mts +29 -5
- package/dist/index.d.ts +29 -5
- package/dist/index.js +557 -78
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +557 -78
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +72 -27
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@ Multi-protocol legacy terminal React component. Connects to **TN5250** (IBM i /
|
|
|
4
4
|
|
|
5
5
|
[**Live Preview**](https://visionbridge-solutions.github.io/green-screen-react/)
|
|
6
6
|
|
|
7
|
+
> **v1.2.0**: per-field MDT state, `readMdt()` for cheap post-write verification, pluggable session store with `session.lost`/`session.resumed` lifecycle events, lower-level sign-on primitives. See the feature section below. Python integrators can use the new [`green-screen-client`](https://pypi.org/project/green-screen-client/) PyPI package.
|
|
8
|
+
|
|
7
9
|
## Install
|
|
8
10
|
|
|
9
11
|
```bash
|
|
@@ -83,12 +85,64 @@ class MyAdapter implements TerminalAdapter {
|
|
|
83
85
|
async getStatus() { /* ... */ }
|
|
84
86
|
async sendText(text: string) { /* ... */ }
|
|
85
87
|
async sendKey(key: string) { /* ... */ }
|
|
88
|
+
async setCursor?(row: number, col: number) { /* ... */ }
|
|
89
|
+
async readMdt?(modifiedOnly?: boolean) { /* ... */ } // v1.2.0
|
|
86
90
|
async connect(config?) { /* ... */ }
|
|
87
91
|
async disconnect() { /* ... */ }
|
|
88
92
|
async reconnect() { /* ... */ }
|
|
89
93
|
}
|
|
90
94
|
```
|
|
91
95
|
|
|
96
|
+
## v1.2.0 features
|
|
97
|
+
|
|
98
|
+
### Post-write verification with `readMdt()`
|
|
99
|
+
|
|
100
|
+
Instead of diffing the entire screen after a batch of writes, ask the proxy which fields actually captured input:
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
import { WebSocketAdapter } from 'green-screen-react';
|
|
104
|
+
|
|
105
|
+
const adapter = new WebSocketAdapter({ workerUrl: 'http://localhost:3001' });
|
|
106
|
+
|
|
107
|
+
// ... after typing into several fields ...
|
|
108
|
+
const modified = await adapter.readMdt(); // only fields with MDT bit set
|
|
109
|
+
const all = await adapter.readMdt(false); // all input fields
|
|
110
|
+
|
|
111
|
+
for (const f of modified) {
|
|
112
|
+
console.log(`row ${f.row} col ${f.col}: "${f.value}"`);
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`readMdt` is optional on the `TerminalAdapter` contract — protocols without a per-field modified concept (VT, HP6530) return `[]`.
|
|
117
|
+
|
|
118
|
+
### Session lifecycle events
|
|
119
|
+
|
|
120
|
+
`WebSocketAdapter` now exposes hooks for session-level transitions. Use them to prompt reconnect UX or surface a clean "session expired" state without string-matching errors:
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
const adapter = new WebSocketAdapter({ workerUrl: 'http://localhost:3001' });
|
|
124
|
+
|
|
125
|
+
adapter.onSessionLost((sessionId, status) => {
|
|
126
|
+
console.log('lost:', sessionId, status.error);
|
|
127
|
+
// show "Session expired, click to reconnect" UI
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
adapter.onSessionResumed((sessionId) => {
|
|
131
|
+
console.log('reattached:', sessionId);
|
|
132
|
+
});
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
On page reload, reattach to a session that survived the refresh:
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
const sessionId = localStorage.getItem('tn5250-session-id');
|
|
139
|
+
if (sessionId) {
|
|
140
|
+
await adapter.reattach(sessionId);
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The proxy keeps the TCP connection alive across WebSocket drops within its idle timeout — `reattach` reconnects the WS and replays the current screen.
|
|
145
|
+
|
|
92
146
|
## Props
|
|
93
147
|
|
|
94
148
|
| Prop | Type | Default | Description |
|
|
@@ -106,6 +160,9 @@ class MyAdapter implements TerminalAdapter {
|
|
|
106
160
|
| `bootLoader` | `ReactNode \| false` | default | Custom boot loader |
|
|
107
161
|
| `onSignIn` | `(config) => void` | - | Sign-in callback |
|
|
108
162
|
| `onScreenChange` | `(screen) => void` | - | Screen change callback |
|
|
163
|
+
| `bootLoaderReady` | `boolean` | - | Explicit boot-loader dismissal (overrides default "dismiss on first screen"). |
|
|
164
|
+
| `headerRight` | `ReactNode` | - | Custom content in the header's right slot. |
|
|
165
|
+
| `statusActions` | `ReactNode` | - | Custom buttons rendered after connection status groups (e.g. disconnect button). |
|
|
109
166
|
| `className` | `string` | - | CSS class |
|
|
110
167
|
| `style` | `CSSProperties` | - | Inline styles |
|
|
111
168
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { ScreenData, ConnectionStatus, ConnectConfig, ProtocolType } from 'green-screen-types';
|
|
4
|
-
export { ConnectConfig, ConnectionStatus, Field, ScreenData, ProtocolType as TerminalProtocol } from 'green-screen-types';
|
|
3
|
+
import { ScreenData, ConnectionStatus, FieldValue, ConnectConfig, ProtocolType } from 'green-screen-types';
|
|
4
|
+
export { ConnectConfig, ConnectionStatus, Field, FieldValue, ScreenData, ProtocolType as TerminalProtocol } from 'green-screen-types';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Protocol-specific color/rendering conventions.
|
|
@@ -67,6 +67,15 @@ interface TerminalAdapter {
|
|
|
67
67
|
sendKey(key: string): Promise<SendResult>;
|
|
68
68
|
/** Set cursor position (click-to-position) */
|
|
69
69
|
setCursor?(row: number, col: number): Promise<SendResult>;
|
|
70
|
+
/**
|
|
71
|
+
* Read the current values of input fields, optionally restricted to the
|
|
72
|
+
* ones whose per-field modified-data-tag (MDT) bit is set. Used for cheap
|
|
73
|
+
* post-write verification: after entering a batch of field values, the
|
|
74
|
+
* caller can confirm what actually landed without re-reading the entire
|
|
75
|
+
* screen. Protocols without per-field MDT (VT, HP6530) return an empty
|
|
76
|
+
* array. Optional — adapters without this capability may omit it.
|
|
77
|
+
*/
|
|
78
|
+
readMdt?(modifiedOnly?: boolean): Promise<FieldValue[]>;
|
|
70
79
|
/** Establish a connection, optionally with sign-in config */
|
|
71
80
|
connect(config?: ConnectConfig): Promise<SendResult>;
|
|
72
81
|
/** Close the connection */
|
|
@@ -112,8 +121,6 @@ interface GreenScreenTerminalProps {
|
|
|
112
121
|
defaultProtocol?: ProtocolType;
|
|
113
122
|
/** Callback when sign-in form is submitted */
|
|
114
123
|
onSignIn?: (config: ConnectConfig) => void;
|
|
115
|
-
/** Show "press Enter to continue" hint after auto sign-in (for external adapter flows) */
|
|
116
|
-
autoSignedIn?: boolean;
|
|
117
124
|
/** Disable auto-focus on the terminal after connecting (default false) */
|
|
118
125
|
autoFocusDisabled?: boolean;
|
|
119
126
|
/** Custom boot loader element, or false to disable */
|
|
@@ -134,6 +141,8 @@ interface GreenScreenTerminalProps {
|
|
|
134
141
|
onScreenChange?: (screen: ScreenData) => void;
|
|
135
142
|
/** Callback for minimize action (embedded mode) */
|
|
136
143
|
onMinimize?: () => void;
|
|
144
|
+
/** Show the keyboard-shortcuts button in the header (default true) */
|
|
145
|
+
showShortcutsButton?: boolean;
|
|
137
146
|
/** Additional CSS class name */
|
|
138
147
|
className?: string;
|
|
139
148
|
/** Inline styles */
|
|
@@ -152,7 +161,7 @@ interface GreenScreenTerminalProps {
|
|
|
152
161
|
*
|
|
153
162
|
* Supports: TN5250 (IBM i), TN3270 (z/OS), VT (OpenVMS/Pick), HP 6530 (NonStop)
|
|
154
163
|
*/
|
|
155
|
-
declare function GreenScreenTerminal({ adapter: externalAdapter, baseUrl, workerUrl, protocol, protocolProfile: customProfile, screenData: externalScreenData, connectionStatus: externalStatus, readOnly, pollInterval, autoReconnect: autoReconnectEnabled, maxReconnectAttempts: maxAttempts, embedded, showHeader, typingAnimation, typingBudgetMs, inlineSignIn, defaultProtocol: signInDefaultProtocol, onSignIn,
|
|
164
|
+
declare function GreenScreenTerminal({ adapter: externalAdapter, baseUrl, workerUrl, protocol, protocolProfile: customProfile, screenData: externalScreenData, connectionStatus: externalStatus, readOnly, pollInterval, autoReconnect: autoReconnectEnabled, maxReconnectAttempts: maxAttempts, embedded, showHeader, typingAnimation, typingBudgetMs, inlineSignIn, defaultProtocol: signInDefaultProtocol, onSignIn, autoFocusDisabled, bootLoader, bootLoaderReady, headerRight, statusActions, overlay, onNotification, onScreenChange, onMinimize, showShortcutsButton, className, style, }: GreenScreenTerminalProps): react_jsx_runtime.JSX.Element;
|
|
156
165
|
|
|
157
166
|
interface TerminalBootLoaderProps {
|
|
158
167
|
/** Text to display during boot animation */
|
|
@@ -236,6 +245,7 @@ declare class RestAdapter implements TerminalAdapter {
|
|
|
236
245
|
sendText(text: string): Promise<SendResult>;
|
|
237
246
|
sendKey(key: string): Promise<SendResult>;
|
|
238
247
|
setCursor(row: number, col: number): Promise<SendResult>;
|
|
248
|
+
readMdt(modifiedOnly?: boolean): Promise<FieldValue[]>;
|
|
239
249
|
connect(config?: ConnectConfig): Promise<SendResult>;
|
|
240
250
|
disconnect(): Promise<SendResult>;
|
|
241
251
|
reconnect(): Promise<SendResult>;
|
|
@@ -266,9 +276,12 @@ declare class WebSocketAdapter implements TerminalAdapter {
|
|
|
266
276
|
private status;
|
|
267
277
|
private pendingScreenResolver;
|
|
268
278
|
private pendingConnectResolver;
|
|
279
|
+
private pendingMdtResolver;
|
|
269
280
|
private connectingPromise;
|
|
270
281
|
private screenListeners;
|
|
271
282
|
private statusListeners;
|
|
283
|
+
private sessionLostListeners;
|
|
284
|
+
private sessionResumedListeners;
|
|
272
285
|
private _sessionId;
|
|
273
286
|
constructor(options?: WebSocketAdapterOptions);
|
|
274
287
|
private static detectEnvUrl;
|
|
@@ -278,11 +291,22 @@ declare class WebSocketAdapter implements TerminalAdapter {
|
|
|
278
291
|
onScreen(listener: (screen: ScreenData) => void): () => void;
|
|
279
292
|
/** Subscribe to status changes */
|
|
280
293
|
onStatus(listener: (status: ConnectionStatus) => void): () => void;
|
|
294
|
+
/**
|
|
295
|
+
* Subscribe to session-lost notifications. Fires when the proxy detects
|
|
296
|
+
* that the server-side session has terminated (host TCP drop, idle
|
|
297
|
+
* timeout, explicit destroy). Integrators use this to prompt a reconnect
|
|
298
|
+
* or swap to a "session expired" UI without relying on error-string
|
|
299
|
+
* matching.
|
|
300
|
+
*/
|
|
301
|
+
onSessionLost(listener: (sessionId: string, status: ConnectionStatus) => void): () => void;
|
|
302
|
+
/** Subscribe to session-resumed notifications (fires after a successful `reattach`). */
|
|
303
|
+
onSessionResumed(listener: (sessionId: string) => void): () => void;
|
|
281
304
|
getScreen(): Promise<ScreenData | null>;
|
|
282
305
|
getStatus(): Promise<ConnectionStatus>;
|
|
283
306
|
sendText(text: string): Promise<SendResult>;
|
|
284
307
|
sendKey(key: string): Promise<SendResult>;
|
|
285
308
|
setCursor(row: number, col: number): Promise<SendResult>;
|
|
309
|
+
readMdt(modifiedOnly?: boolean): Promise<FieldValue[]>;
|
|
286
310
|
connect(config?: ConnectConfig): Promise<SendResult>;
|
|
287
311
|
/**
|
|
288
312
|
* Reattach to an existing proxy session (e.g. after page reload).
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { ScreenData, ConnectionStatus, ConnectConfig, ProtocolType } from 'green-screen-types';
|
|
4
|
-
export { ConnectConfig, ConnectionStatus, Field, ScreenData, ProtocolType as TerminalProtocol } from 'green-screen-types';
|
|
3
|
+
import { ScreenData, ConnectionStatus, FieldValue, ConnectConfig, ProtocolType } from 'green-screen-types';
|
|
4
|
+
export { ConnectConfig, ConnectionStatus, Field, FieldValue, ScreenData, ProtocolType as TerminalProtocol } from 'green-screen-types';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Protocol-specific color/rendering conventions.
|
|
@@ -67,6 +67,15 @@ interface TerminalAdapter {
|
|
|
67
67
|
sendKey(key: string): Promise<SendResult>;
|
|
68
68
|
/** Set cursor position (click-to-position) */
|
|
69
69
|
setCursor?(row: number, col: number): Promise<SendResult>;
|
|
70
|
+
/**
|
|
71
|
+
* Read the current values of input fields, optionally restricted to the
|
|
72
|
+
* ones whose per-field modified-data-tag (MDT) bit is set. Used for cheap
|
|
73
|
+
* post-write verification: after entering a batch of field values, the
|
|
74
|
+
* caller can confirm what actually landed without re-reading the entire
|
|
75
|
+
* screen. Protocols without per-field MDT (VT, HP6530) return an empty
|
|
76
|
+
* array. Optional — adapters without this capability may omit it.
|
|
77
|
+
*/
|
|
78
|
+
readMdt?(modifiedOnly?: boolean): Promise<FieldValue[]>;
|
|
70
79
|
/** Establish a connection, optionally with sign-in config */
|
|
71
80
|
connect(config?: ConnectConfig): Promise<SendResult>;
|
|
72
81
|
/** Close the connection */
|
|
@@ -112,8 +121,6 @@ interface GreenScreenTerminalProps {
|
|
|
112
121
|
defaultProtocol?: ProtocolType;
|
|
113
122
|
/** Callback when sign-in form is submitted */
|
|
114
123
|
onSignIn?: (config: ConnectConfig) => void;
|
|
115
|
-
/** Show "press Enter to continue" hint after auto sign-in (for external adapter flows) */
|
|
116
|
-
autoSignedIn?: boolean;
|
|
117
124
|
/** Disable auto-focus on the terminal after connecting (default false) */
|
|
118
125
|
autoFocusDisabled?: boolean;
|
|
119
126
|
/** Custom boot loader element, or false to disable */
|
|
@@ -134,6 +141,8 @@ interface GreenScreenTerminalProps {
|
|
|
134
141
|
onScreenChange?: (screen: ScreenData) => void;
|
|
135
142
|
/** Callback for minimize action (embedded mode) */
|
|
136
143
|
onMinimize?: () => void;
|
|
144
|
+
/** Show the keyboard-shortcuts button in the header (default true) */
|
|
145
|
+
showShortcutsButton?: boolean;
|
|
137
146
|
/** Additional CSS class name */
|
|
138
147
|
className?: string;
|
|
139
148
|
/** Inline styles */
|
|
@@ -152,7 +161,7 @@ interface GreenScreenTerminalProps {
|
|
|
152
161
|
*
|
|
153
162
|
* Supports: TN5250 (IBM i), TN3270 (z/OS), VT (OpenVMS/Pick), HP 6530 (NonStop)
|
|
154
163
|
*/
|
|
155
|
-
declare function GreenScreenTerminal({ adapter: externalAdapter, baseUrl, workerUrl, protocol, protocolProfile: customProfile, screenData: externalScreenData, connectionStatus: externalStatus, readOnly, pollInterval, autoReconnect: autoReconnectEnabled, maxReconnectAttempts: maxAttempts, embedded, showHeader, typingAnimation, typingBudgetMs, inlineSignIn, defaultProtocol: signInDefaultProtocol, onSignIn,
|
|
164
|
+
declare function GreenScreenTerminal({ adapter: externalAdapter, baseUrl, workerUrl, protocol, protocolProfile: customProfile, screenData: externalScreenData, connectionStatus: externalStatus, readOnly, pollInterval, autoReconnect: autoReconnectEnabled, maxReconnectAttempts: maxAttempts, embedded, showHeader, typingAnimation, typingBudgetMs, inlineSignIn, defaultProtocol: signInDefaultProtocol, onSignIn, autoFocusDisabled, bootLoader, bootLoaderReady, headerRight, statusActions, overlay, onNotification, onScreenChange, onMinimize, showShortcutsButton, className, style, }: GreenScreenTerminalProps): react_jsx_runtime.JSX.Element;
|
|
156
165
|
|
|
157
166
|
interface TerminalBootLoaderProps {
|
|
158
167
|
/** Text to display during boot animation */
|
|
@@ -236,6 +245,7 @@ declare class RestAdapter implements TerminalAdapter {
|
|
|
236
245
|
sendText(text: string): Promise<SendResult>;
|
|
237
246
|
sendKey(key: string): Promise<SendResult>;
|
|
238
247
|
setCursor(row: number, col: number): Promise<SendResult>;
|
|
248
|
+
readMdt(modifiedOnly?: boolean): Promise<FieldValue[]>;
|
|
239
249
|
connect(config?: ConnectConfig): Promise<SendResult>;
|
|
240
250
|
disconnect(): Promise<SendResult>;
|
|
241
251
|
reconnect(): Promise<SendResult>;
|
|
@@ -266,9 +276,12 @@ declare class WebSocketAdapter implements TerminalAdapter {
|
|
|
266
276
|
private status;
|
|
267
277
|
private pendingScreenResolver;
|
|
268
278
|
private pendingConnectResolver;
|
|
279
|
+
private pendingMdtResolver;
|
|
269
280
|
private connectingPromise;
|
|
270
281
|
private screenListeners;
|
|
271
282
|
private statusListeners;
|
|
283
|
+
private sessionLostListeners;
|
|
284
|
+
private sessionResumedListeners;
|
|
272
285
|
private _sessionId;
|
|
273
286
|
constructor(options?: WebSocketAdapterOptions);
|
|
274
287
|
private static detectEnvUrl;
|
|
@@ -278,11 +291,22 @@ declare class WebSocketAdapter implements TerminalAdapter {
|
|
|
278
291
|
onScreen(listener: (screen: ScreenData) => void): () => void;
|
|
279
292
|
/** Subscribe to status changes */
|
|
280
293
|
onStatus(listener: (status: ConnectionStatus) => void): () => void;
|
|
294
|
+
/**
|
|
295
|
+
* Subscribe to session-lost notifications. Fires when the proxy detects
|
|
296
|
+
* that the server-side session has terminated (host TCP drop, idle
|
|
297
|
+
* timeout, explicit destroy). Integrators use this to prompt a reconnect
|
|
298
|
+
* or swap to a "session expired" UI without relying on error-string
|
|
299
|
+
* matching.
|
|
300
|
+
*/
|
|
301
|
+
onSessionLost(listener: (sessionId: string, status: ConnectionStatus) => void): () => void;
|
|
302
|
+
/** Subscribe to session-resumed notifications (fires after a successful `reattach`). */
|
|
303
|
+
onSessionResumed(listener: (sessionId: string) => void): () => void;
|
|
281
304
|
getScreen(): Promise<ScreenData | null>;
|
|
282
305
|
getStatus(): Promise<ConnectionStatus>;
|
|
283
306
|
sendText(text: string): Promise<SendResult>;
|
|
284
307
|
sendKey(key: string): Promise<SendResult>;
|
|
285
308
|
setCursor(row: number, col: number): Promise<SendResult>;
|
|
309
|
+
readMdt(modifiedOnly?: boolean): Promise<FieldValue[]>;
|
|
286
310
|
connect(config?: ConnectConfig): Promise<SendResult>;
|
|
287
311
|
/**
|
|
288
312
|
* Reattach to an existing proxy session (e.g. after page reload).
|