green-screen-proxy 1.1.2 → 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.
Files changed (79) hide show
  1. package/README.md +93 -8
  2. package/dist/cli.js +0 -6
  3. package/dist/cli.js.map +1 -1
  4. package/dist/controller.d.ts +3 -0
  5. package/dist/controller.d.ts.map +1 -1
  6. package/dist/controller.js +13 -2
  7. package/dist/controller.js.map +1 -1
  8. package/dist/index.d.ts +1 -2
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +11 -16
  11. package/dist/index.js.map +1 -1
  12. package/dist/protocols/tn5250-handler.d.ts +3 -2
  13. package/dist/protocols/tn5250-handler.d.ts.map +1 -1
  14. package/dist/protocols/tn5250-handler.js +83 -25
  15. package/dist/protocols/tn5250-handler.js.map +1 -1
  16. package/dist/protocols/types.d.ts +28 -2
  17. package/dist/protocols/types.d.ts.map +1 -1
  18. package/dist/protocols/types.js +28 -0
  19. package/dist/protocols/types.js.map +1 -1
  20. package/dist/routes.d.ts.map +1 -1
  21. package/dist/routes.js +160 -34
  22. package/dist/routes.js.map +1 -1
  23. package/dist/server.js +1 -5
  24. package/dist/server.js.map +1 -1
  25. package/dist/session-store.d.ts +68 -0
  26. package/dist/session-store.d.ts.map +1 -0
  27. package/dist/session-store.js +40 -0
  28. package/dist/session-store.js.map +1 -0
  29. package/dist/session.d.ts +26 -3
  30. package/dist/session.d.ts.map +1 -1
  31. package/dist/session.js +83 -11
  32. package/dist/session.js.map +1 -1
  33. package/dist/standalone.d.ts +3 -0
  34. package/dist/standalone.d.ts.map +1 -0
  35. package/dist/standalone.js +6 -0
  36. package/dist/standalone.js.map +1 -0
  37. package/dist/tn5250/connection.d.ts +5 -0
  38. package/dist/tn5250/connection.d.ts.map +1 -1
  39. package/dist/tn5250/connection.js +25 -1
  40. package/dist/tn5250/connection.js.map +1 -1
  41. package/dist/tn5250/constants.d.ts +39 -3
  42. package/dist/tn5250/constants.d.ts.map +1 -1
  43. package/dist/tn5250/constants.js +51 -3
  44. package/dist/tn5250/constants.js.map +1 -1
  45. package/dist/tn5250/ebcdic-jp-builtin.d.ts +45 -0
  46. package/dist/tn5250/ebcdic-jp-builtin.d.ts.map +1 -0
  47. package/dist/tn5250/ebcdic-jp-builtin.js +124 -0
  48. package/dist/tn5250/ebcdic-jp-builtin.js.map +1 -0
  49. package/dist/tn5250/ebcdic-jp.d.ts +61 -0
  50. package/dist/tn5250/ebcdic-jp.d.ts.map +1 -0
  51. package/dist/tn5250/ebcdic-jp.js +188 -0
  52. package/dist/tn5250/ebcdic-jp.js.map +1 -0
  53. package/dist/tn5250/ebcdic.d.ts +13 -4
  54. package/dist/tn5250/ebcdic.d.ts.map +1 -1
  55. package/dist/tn5250/ebcdic.js +30 -8
  56. package/dist/tn5250/ebcdic.js.map +1 -1
  57. package/dist/tn5250/encoder.d.ts +41 -9
  58. package/dist/tn5250/encoder.d.ts.map +1 -1
  59. package/dist/tn5250/encoder.js +228 -41
  60. package/dist/tn5250/encoder.js.map +1 -1
  61. package/dist/tn5250/parser.d.ts +14 -0
  62. package/dist/tn5250/parser.d.ts.map +1 -1
  63. package/dist/tn5250/parser.js +428 -53
  64. package/dist/tn5250/parser.js.map +1 -1
  65. package/dist/tn5250/screen.d.ts +144 -24
  66. package/dist/tn5250/screen.d.ts.map +1 -1
  67. package/dist/tn5250/screen.js +244 -13
  68. package/dist/tn5250/screen.js.map +1 -1
  69. package/dist/ui/assets/index-B51sr7HL.js +56 -0
  70. package/dist/ui/assets/index-B9wpEWAh.css +1 -0
  71. package/dist/ui/assets/index-BrUnECmE.css +1 -0
  72. package/dist/ui/assets/index-CDBbEXbH.js +56 -0
  73. package/dist/ui/index.html +16 -0
  74. package/dist/websocket.d.ts +3 -0
  75. package/dist/websocket.d.ts.map +1 -1
  76. package/dist/websocket.js +90 -1
  77. package/dist/websocket.js.map +1 -1
  78. package/dist/worker/index.js +5573 -0
  79. package/package.json +1 -1
@@ -1,12 +1,20 @@
1
1
  import { EventEmitter } from 'events';
2
- export type { ScreenData, ProtocolType, Field } from 'green-screen-types';
3
- import type { ScreenData, ProtocolType } from 'green-screen-types';
2
+ export type { ScreenData, ProtocolType, Field, FieldValue } from 'green-screen-types';
3
+ import type { ScreenData, ProtocolType, FieldValue } from 'green-screen-types';
4
4
  export interface ProtocolOptions {
5
5
  /** Terminal type string for negotiation */
6
6
  terminalType?: string;
7
7
  /** Screen dimensions */
8
8
  rows?: number;
9
9
  cols?: number;
10
+ /**
11
+ * EBCDIC single-byte code page for character translation. For IBM i:
12
+ * - 'cp37' — US/Canada/Brazil/AU/NZ (default)
13
+ * - 'cp290' — Japan Katakana (use with SO/SI DBCS for full Kanji support)
14
+ * If omitted, the handler derives it from the terminal-type string
15
+ * (e.g. 'IBM-5555-C01' for Japanese) or defaults to 'cp37'.
16
+ */
17
+ codePage?: 'cp37' | 'cp290';
10
18
  /** Protocol-specific options */
11
19
  [key: string]: unknown;
12
20
  }
@@ -33,6 +41,24 @@ export declare abstract class ProtocolHandler extends EventEmitter {
33
41
  abstract sendKey(keyName: string): boolean;
34
42
  /** Set cursor position. Returns true if successful. */
35
43
  setCursor(row: number, col: number): boolean;
44
+ /**
45
+ * Read the current text content of input fields on the screen, optionally
46
+ * restricted to fields whose per-field modified-data-tag (MDT) bit is set.
47
+ * Used by the `/read-mdt` primitive as a cheap post-write verification
48
+ * path — much smaller payload than `getScreenData()` when only a few
49
+ * fields were modified. Protocols without a per-field modified concept
50
+ * (VT, HP6530) return an empty array.
51
+ */
52
+ readFieldValues(_modifiedOnly?: boolean): FieldValue[];
53
+ /**
54
+ * Wait until the next screen change satisfies `minFields` input fields,
55
+ * or the timeout elapses. Used by integrators building robust sign-on
56
+ * cascades (or any flow that first needs to see a form). Default
57
+ * implementation falls back to a plain timed wait for one `screenChange`
58
+ * event — protocol handlers with richer semantics (e.g. TN5250) should
59
+ * override to short-circuit when the current screen already satisfies.
60
+ */
61
+ waitForScreenWithFields(_minFields: number, timeoutMs: number): Promise<ScreenData>;
36
62
  /** Send raw bytes over the connection */
37
63
  abstract sendRaw(data: Buffer): void;
38
64
  /** Clean up resources */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/protocols/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAG1E,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEnE,MAAM,WAAW,eAAe;IAC9B,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wBAAwB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,8BAAsB,eAAgB,SAAQ,YAAY;IACxD,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAEzC,+BAA+B;IAC/B,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAEtF,+BAA+B;IAC/B,QAAQ,CAAC,UAAU,IAAI,IAAI;IAE3B,uCAAuC;IACvC,QAAQ,KAAK,WAAW,IAAI,OAAO,CAAC;IAEpC,mCAAmC;IACnC,QAAQ,CAAC,aAAa,IAAI,UAAU;IAEpC,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAExC;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAE1C,uDAAuD;IACvD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAI5C,yCAAyC;IACzC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAEpC,yBAAyB;IACzB,QAAQ,CAAC,OAAO,IAAI,IAAI;CACzB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/protocols/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGtF,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAE/E,MAAM,WAAW,eAAe;IAC9B,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wBAAwB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,gCAAgC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,8BAAsB,eAAgB,SAAQ,YAAY;IACxD,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAEzC,+BAA+B;IAC/B,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAEtF,+BAA+B;IAC/B,QAAQ,CAAC,UAAU,IAAI,IAAI;IAE3B,uCAAuC;IACvC,QAAQ,KAAK,WAAW,IAAI,OAAO,CAAC;IAEpC,mCAAmC;IACnC,QAAQ,CAAC,aAAa,IAAI,UAAU;IAEpC,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAExC;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAE1C,uDAAuD;IACvD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAI5C;;;;;;;OAOG;IACH,eAAe,CAAC,aAAa,GAAE,OAAc,GAAG,UAAU,EAAE;IAI5D;;;;;;;OAOG;IACH,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAUnF,yCAAyC;IACzC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAEpC,yBAAyB;IACzB,QAAQ,CAAC,OAAO,IAAI,IAAI;CACzB"}
@@ -8,5 +8,33 @@ export class ProtocolHandler extends EventEmitter {
8
8
  setCursor(row, col) {
9
9
  return false;
10
10
  }
11
+ /**
12
+ * Read the current text content of input fields on the screen, optionally
13
+ * restricted to fields whose per-field modified-data-tag (MDT) bit is set.
14
+ * Used by the `/read-mdt` primitive as a cheap post-write verification
15
+ * path — much smaller payload than `getScreenData()` when only a few
16
+ * fields were modified. Protocols without a per-field modified concept
17
+ * (VT, HP6530) return an empty array.
18
+ */
19
+ readFieldValues(_modifiedOnly = true) {
20
+ return [];
21
+ }
22
+ /**
23
+ * Wait until the next screen change satisfies `minFields` input fields,
24
+ * or the timeout elapses. Used by integrators building robust sign-on
25
+ * cascades (or any flow that first needs to see a form). Default
26
+ * implementation falls back to a plain timed wait for one `screenChange`
27
+ * event — protocol handlers with richer semantics (e.g. TN5250) should
28
+ * override to short-circuit when the current screen already satisfies.
29
+ */
30
+ waitForScreenWithFields(_minFields, timeoutMs) {
31
+ return new Promise((resolve) => {
32
+ const timer = setTimeout(() => resolve(this.getScreenData()), timeoutMs);
33
+ this.once('screenChange', (data) => {
34
+ clearTimeout(timer);
35
+ resolve(data);
36
+ });
37
+ });
38
+ }
11
39
  }
12
40
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/protocols/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAkBtC;;;GAGG;AACH,MAAM,OAAgB,eAAgB,SAAQ,YAAY;IAwBxD,uDAAuD;IACvD,SAAS,CAAC,GAAW,EAAE,GAAW;QAChC,OAAO,KAAK,CAAC;IACf,CAAC;CAOF"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/protocols/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AA0BtC;;;GAGG;AACH,MAAM,OAAgB,eAAgB,SAAQ,YAAY;IAwBxD,uDAAuD;IACvD,SAAS,CAAC,GAAW,EAAE,GAAW;QAChC,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;OAOG;IACH,eAAe,CAAC,gBAAyB,IAAI;QAC3C,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;;;;;OAOG;IACH,uBAAuB,CAAC,UAAkB,EAAE,SAAiB;QAC3D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;YACzE,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,IAAgB,EAAE,EAAE;gBAC7C,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,OAAO,CAAC,IAAI,CAAC,CAAC;YAChB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CAOF"}
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AASA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAuRxB,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAWA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA0ZxB,eAAe,MAAM,CAAC"}
package/dist/routes.js CHANGED
@@ -1,21 +1,34 @@
1
1
  import { Router } from 'express';
2
2
  import { createSession, getSession, getDefaultSession, destroySession, } from './session.js';
3
3
  import { TN5250Handler } from './protocols/index.js';
4
+ import { broadcastScreenToSession } from './websocket.js';
4
5
  const router = Router();
5
- /** Resolve session from header, query param, or default */
6
+ /** Resolve session from header, query param, or default. Resets idle timer on access. */
6
7
  function resolveSession(req) {
7
8
  const sessionId = req.headers['x-session-id'] ||
8
9
  req.query.sessionId;
9
- if (sessionId) {
10
- return getSession(sessionId);
11
- }
12
- return getDefaultSession();
10
+ const session = sessionId ? getSession(sessionId) : getDefaultSession();
11
+ if (session)
12
+ session.touch();
13
+ return session;
13
14
  }
14
15
  // POST /connect
15
16
  router.post('/connect', async (req, res) => {
16
17
  try {
17
18
  const { host = 'pub400.com', port = 23, protocol = 'tn5250', terminalType, screenTimeout, connectTimeout, username, password } = req.body || {};
19
+ // Destroy only the caller's previous session (identified by X-Session-Id),
20
+ // NOT all sessions for the same host:port. Multiple agents may legitimately
21
+ // maintain concurrent sessions to the same host.
22
+ const previousSessionId = req.headers['x-session-id'];
23
+ if (previousSessionId) {
24
+ const prev = getSession(previousSessionId);
25
+ if (prev) {
26
+ console.log(`[connect] Destroying caller's previous session ${previousSessionId.slice(0, 8)} for ${host}:${port} before new connect`);
27
+ destroySession(previousSessionId);
28
+ }
29
+ }
18
30
  const session = createSession(protocol);
31
+ console.log(`[connect] Created session ${session.id.slice(0, 8)} for ${host}:${port}`);
19
32
  if (typeof screenTimeout === 'number' && screenTimeout > 0) {
20
33
  session.screenTimeout = screenTimeout;
21
34
  }
@@ -45,10 +58,7 @@ router.post('/connect', async (req, res) => {
45
58
  res.json({
46
59
  success: true,
47
60
  sessionId: session.id,
48
- cursor_row: screenData.cursor_row,
49
- cursor_col: screenData.cursor_col,
50
- content: screenData.content,
51
- screen_signature: screenData.screen_signature,
61
+ ...screenData,
52
62
  });
53
63
  }
54
64
  catch (err) {
@@ -60,10 +70,13 @@ router.post('/connect', async (req, res) => {
60
70
  });
61
71
  // POST /disconnect
62
72
  router.post('/disconnect', (req, res) => {
73
+ const requestedId = req.headers['x-session-id'] || '(none)';
63
74
  const session = resolveSession(req);
64
75
  if (!session) {
76
+ console.log(`[disconnect] No session found for id=${requestedId.slice(0, 8)}`);
65
77
  return res.json({ success: true }); // Already disconnected
66
78
  }
79
+ console.log(`[disconnect] Destroying session ${session.id.slice(0, 8)} (requested=${requestedId.slice(0, 8)})`);
67
80
  destroySession(session.id);
68
81
  res.json({ success: true });
69
82
  });
@@ -79,10 +92,7 @@ router.post('/reconnect', async (req, res) => {
79
92
  const screenData = session.getScreenData();
80
93
  res.json({
81
94
  success: true,
82
- cursor_row: screenData.cursor_row,
83
- cursor_col: screenData.cursor_col,
84
- content: screenData.content,
85
- screen_signature: screenData.screen_signature,
95
+ ...screenData,
86
96
  });
87
97
  }
88
98
  catch (err) {
@@ -111,6 +121,105 @@ router.get('/screen', (req, res) => {
111
121
  }
112
122
  res.json(session.getScreenData());
113
123
  });
124
+ // POST /session/resume — idempotent session-alive probe for REST clients.
125
+ //
126
+ // Given a session id (body or X-Session-Id header), checks whether the
127
+ // session still exists on the proxy and is connected. Returns the current
128
+ // screen + connection status on success, 404 otherwise. REST-only
129
+ // integrations use this on page reload to decide between "reattach the UI
130
+ // to existing state" vs "start a fresh /connect flow".
131
+ //
132
+ // The corresponding WebSocket mechanism is the `reattach` command plus the
133
+ // `session.resumed` / `session.lost` lifecycle events.
134
+ router.post('/session/resume', (req, res) => {
135
+ const sessionId = (req.body && req.body.sessionId) ||
136
+ req.headers['x-session-id'] ||
137
+ req.query.sessionId;
138
+ if (!sessionId || typeof sessionId !== 'string') {
139
+ return res.status(400).json({ success: false, error: 'sessionId is required' });
140
+ }
141
+ const session = getSession(sessionId);
142
+ if (!session) {
143
+ return res.status(404).json({ success: false, error: 'Session not found' });
144
+ }
145
+ session.touch();
146
+ res.setHeader('X-Session-Id', session.id);
147
+ const screenData = session.status.connected ? session.getScreenData() : null;
148
+ res.json({
149
+ success: true,
150
+ sessionId: session.id,
151
+ status: session.status,
152
+ ...(screenData ? { screen: screenData } : {}),
153
+ });
154
+ });
155
+ // POST /session/authenticated — flip the session status to 'authenticated'.
156
+ //
157
+ // Integrators that implement their own sign-on cascade (e.g. LegacyBridge,
158
+ // which needs to dismiss IBM i post-sign-on screens like QDSPSGNINF and
159
+ // legal notices) use this to notify the proxy when sign-on has completed.
160
+ // The proxy has no protocol-specific knowledge of what "signed-on" means,
161
+ // so the caller owns the decision. Emits a status event to all WS clients
162
+ // watching this session.
163
+ router.post('/session/authenticated', (req, res) => {
164
+ const session = resolveSession(req);
165
+ if (!session) {
166
+ return res.status(404).json({ success: false, error: 'No active session' });
167
+ }
168
+ const { username } = req.body || {};
169
+ if (!username || typeof username !== 'string') {
170
+ return res.status(400).json({ success: false, error: 'username is required' });
171
+ }
172
+ session.markAuthenticated(username);
173
+ res.json({ success: true, status: session.status });
174
+ });
175
+ // POST /wait-for-fields — wait until the current screen has at least N
176
+ // input fields (or timeout). Generic primitive that sign-on cascades use
177
+ // to robustly wait for a form to appear before typing credentials. Short-
178
+ // circuits when the screen already satisfies.
179
+ //
180
+ // Body:
181
+ // { minFields: number, timeoutMs?: number (default 5000) }
182
+ router.post('/wait-for-fields', async (req, res) => {
183
+ const session = resolveSession(req);
184
+ if (!session) {
185
+ return res.status(404).json({ success: false, error: 'No active session' });
186
+ }
187
+ const { minFields, timeoutMs = 5000 } = req.body || {};
188
+ if (typeof minFields !== 'number' || minFields < 0) {
189
+ return res.status(400).json({ success: false, error: 'minFields (number) is required' });
190
+ }
191
+ const screen = await session.waitForScreenWithFields(minFields, timeoutMs);
192
+ const inputCount = (screen.fields || []).filter((f) => f.is_input).length;
193
+ res.json({
194
+ success: inputCount >= minFields,
195
+ matched: inputCount >= minFields,
196
+ inputFieldCount: inputCount,
197
+ ...screen,
198
+ });
199
+ });
200
+ // GET /read-mdt — cheap post-write verification primitive
201
+ //
202
+ // Returns just the input fields whose per-field modified-data-tag (MDT) bit
203
+ // is set, with their current cell values. Use case: after a batch of
204
+ // sendText/sendKey writes, the client wants to verify what actually landed
205
+ // without diffing the entire screen payload.
206
+ //
207
+ // Query params:
208
+ // includeUnmodified=1 — also return input fields whose MDT bit is clear
209
+ // (useful when you want a snapshot of all input
210
+ // fields regardless of modification state).
211
+ //
212
+ // Protocols that don't track a per-field modified concept (VT, HP6530) will
213
+ // return an empty array — this is a TN5250-first primitive.
214
+ router.get('/read-mdt', (req, res) => {
215
+ const session = resolveSession(req);
216
+ if (!session) {
217
+ return res.status(404).json({ success: false, error: 'No active session' });
218
+ }
219
+ const modifiedOnly = req.query.includeUnmodified !== '1';
220
+ const values = session.readFieldValues(modifiedOnly);
221
+ res.json({ success: true, modifiedOnly, fields: values });
222
+ });
114
223
  // POST /set-cursor
115
224
  router.post('/set-cursor', (req, res) => {
116
225
  const session = resolveSession(req);
@@ -177,18 +286,19 @@ router.post('/batch', async (req, res) => {
177
286
  return res.json({ success: false, error: `Unknown operation type: ${op.type}` });
178
287
  }
179
288
  }
289
+ let screenData;
180
290
  if (readScreen && lastRemoteKey) {
181
- // Wait for host response after remote key
182
- const screenData = await session.waitForScreen(3000);
183
- return res.json({ success: true, ...screenData });
291
+ // Wait for host response after last remote key
292
+ screenData = await session.waitForScreen(session.screenTimeout);
184
293
  }
185
- const screenData = session.getScreenData();
294
+ else {
295
+ screenData = session.getScreenData();
296
+ }
297
+ // Broadcast to WebSocket clients so dashboard stays in sync
298
+ broadcastScreenToSession(session.id, screenData);
186
299
  res.json({
187
300
  success: true,
188
- cursor_row: screenData.cursor_row,
189
- cursor_col: screenData.cursor_col,
190
- content: screenData.content,
191
- screen_signature: screenData.screen_signature,
301
+ ...screenData,
192
302
  });
193
303
  }
194
304
  catch (err) {
@@ -207,15 +317,28 @@ router.post('/send-text', (req, res) => {
207
317
  }
208
318
  const ok = session.sendText(text);
209
319
  const screenData = session.getScreenData();
320
+ // Broadcast to WebSocket clients so dashboard stays in sync
321
+ if (ok) {
322
+ broadcastScreenToSession(session.id, screenData);
323
+ }
210
324
  res.json({
211
325
  success: ok,
212
- cursor_row: screenData.cursor_row,
213
- cursor_col: screenData.cursor_col,
214
- content: screenData.content,
215
- screen_signature: screenData.screen_signature,
326
+ ...screenData,
216
327
  error: ok ? undefined : 'Cannot type at current cursor position',
217
328
  });
218
329
  });
330
+ // Keys that are handled locally in the screen buffer (no host roundtrip needed).
331
+ // Must match the set in controller.ts handleKey() for consistent behavior.
332
+ const LOCAL_KEYS = new Set([
333
+ 'Tab', 'Backtab', 'TAB', 'BACKTAB',
334
+ 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown',
335
+ 'LEFT', 'RIGHT', 'UP', 'DOWN',
336
+ 'Home', 'HOME', 'End', 'END',
337
+ 'Backspace', 'BACKSPACE', 'Delete', 'DELETE',
338
+ 'Insert', 'INSERT',
339
+ 'Reset', 'RESET',
340
+ 'FieldExit', 'FIELD_EXIT', 'FIELDEXIT',
341
+ ]);
219
342
  // POST /send-key
220
343
  router.post('/send-key', async (req, res) => {
221
344
  const session = resolveSession(req);
@@ -226,20 +349,23 @@ router.post('/send-key', async (req, res) => {
226
349
  if (typeof key !== 'string') {
227
350
  return res.status(400).json({ success: false, error: 'key is required' });
228
351
  }
352
+ if (!LOCAL_KEYS.has(key)) {
353
+ // Remote key: race-free send + wait (listener set up before sendKey)
354
+ const { ok, screen } = await session.sendKeyAndWait(key, session.screenTimeout);
355
+ if (!ok) {
356
+ return res.json({ success: false, error: `Unknown key: ${key}` });
357
+ }
358
+ // Broadcast to WebSocket clients so dashboard stays in sync
359
+ broadcastScreenToSession(session.id, screen);
360
+ return res.json({ success: true, ...screen });
361
+ }
362
+ // Local key: immediate response, no host round-trip
229
363
  const ok = session.sendKey(key);
230
364
  if (!ok) {
231
365
  return res.json({ success: false, error: `Unknown key: ${key}` });
232
366
  }
233
- // Wait for the host to respond with a new screen
234
- await new Promise(resolve => setTimeout(resolve, session.screenTimeout));
235
367
  const screenData = session.getScreenData();
236
- res.json({
237
- success: true,
238
- cursor_row: screenData.cursor_row,
239
- cursor_col: screenData.cursor_col,
240
- content: screenData.content,
241
- screen_signature: screenData.screen_signature,
242
- });
368
+ res.json({ success: true, ...screenData });
243
369
  });
244
370
  export default router;
245
371
  //# sourceMappingURL=routes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"routes.js","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -1,11 +1,7 @@
1
1
  import { createProxy } from './index.js';
2
- const isMock = process.argv.includes('--mock');
3
2
  const PORT = parseInt(process.env.PORT || '3001', 10);
4
- const proxy = await createProxy({ port: PORT, mock: isMock });
3
+ const proxy = await createProxy({ port: PORT });
5
4
  console.log(`Green Screen proxy server running on http://localhost:${proxy.port}`);
6
- if (isMock) {
7
- console.log('Running in MOCK mode (no real IBM i connection)');
8
- }
9
5
  function shutdown() {
10
6
  proxy.close().then(() => process.exit(0));
11
7
  setTimeout(() => process.exit(0), 1000);
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAEtD,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;AAE9D,OAAO,CAAC,GAAG,CAAC,yDAAyD,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AACnF,IAAI,MAAM,EAAE,CAAC;IACX,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,QAAQ;IACf,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,EAAE,EAAE,CAAC,CAAC;AAEtD,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AAEhD,OAAO,CAAC,GAAG,CAAC,yDAAyD,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AAEnF,SAAS,QAAQ;IACf,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC"}
@@ -0,0 +1,68 @@
1
+ import { EventEmitter } from 'events';
2
+ import type { Session } from './session.js';
3
+ import type { ConnectionStatus } from 'green-screen-types';
4
+ /**
5
+ * Pluggable session store. The proxy keeps live Session instances (each
6
+ * holding a TCP connection + parser state) keyed by session id. By default
7
+ * sessions live in an in-memory Map, which works for single-process
8
+ * deployments. For multi-process or HA deployments, integrators can plug a
9
+ * custom store (e.g. Redis-backed process routing) by calling
10
+ * {@link setSessionStore} before the HTTP/WS server starts accepting
11
+ * traffic.
12
+ *
13
+ * IMPORTANT: Live Session objects can not themselves be serialised across
14
+ * processes — they own TCP sockets and parser state. A Redis-backed store
15
+ * therefore works at the *routing* layer: it records which process owns a
16
+ * given session id, and remote processes forward requests to the owning
17
+ * process (out of scope for this interface — store authors handle it).
18
+ * For typical single-process deployments, use the default in-memory store.
19
+ */
20
+ export interface SessionStore {
21
+ /** Insert a session (fresh or just-reattached). */
22
+ set(id: string, session: Session): void;
23
+ /** Look up a session by id; returns undefined when not present or expired. */
24
+ get(id: string): Session | undefined;
25
+ /** Remove a session from the store (does NOT call `destroy()`). */
26
+ delete(id: string): void;
27
+ /** Fast existence check. */
28
+ has(id: string): boolean;
29
+ /** Iterate over all currently-stored sessions. */
30
+ values(): IterableIterator<Session>;
31
+ /** Total number of stored sessions. */
32
+ size(): number;
33
+ }
34
+ /** Default in-memory session store — process-local Map. */
35
+ export declare class InMemorySessionStore implements SessionStore {
36
+ private readonly map;
37
+ set(id: string, session: Session): void;
38
+ get(id: string): Session | undefined;
39
+ delete(id: string): void;
40
+ has(id: string): boolean;
41
+ values(): IterableIterator<Session>;
42
+ size(): number;
43
+ }
44
+ /**
45
+ * Replace the active session store. Call this once at startup, before the
46
+ * HTTP/WS server accepts connections. Switching stores mid-flight will
47
+ * orphan any sessions already held in the previous store.
48
+ */
49
+ export declare function setSessionStore(store: SessionStore): void;
50
+ /** Get the active session store (for internal proxy code + tests). */
51
+ export declare function getSessionStore(): SessionStore;
52
+ /**
53
+ * Global lifecycle event bus. Emits:
54
+ * - 'session.lost' (sessionId: string, status: ConnectionStatus)
55
+ * - 'session.resumed' (sessionId: string, clientWs?: unknown)
56
+ *
57
+ * Use this from layers that need to observe session lifecycle without
58
+ * importing the websocket module directly (avoids circular imports).
59
+ */
60
+ export type SessionLifecycleEvents = {
61
+ 'session.lost': (sessionId: string, status: ConnectionStatus) => void;
62
+ 'session.resumed': (sessionId: string) => void;
63
+ };
64
+ declare class SessionLifecycleEmitter extends EventEmitter {
65
+ }
66
+ export declare const sessionLifecycle: SessionLifecycleEmitter;
67
+ export {};
68
+ //# sourceMappingURL=session-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-store.d.ts","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,YAAY;IAC3B,mDAAmD;IACnD,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxC,8EAA8E;IAC9E,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IACrC,mEAAmE;IACnE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,4BAA4B;IAC5B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IACzB,kDAAkD;IAClD,MAAM,IAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACpC,uCAAuC;IACvC,IAAI,IAAI,MAAM,CAAC;CAChB;AAED,2DAA2D;AAC3D,qBAAa,oBAAqB,YAAW,YAAY;IACvD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA8B;IAElD,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAGvC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAGpC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAGxB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAGxB,MAAM,IAAI,gBAAgB,CAAC,OAAO,CAAC;IAGnC,IAAI,IAAI,MAAM;CAGf;AAID;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAEzD;AAED,sEAAsE;AACtE,wBAAgB,eAAe,IAAI,YAAY,CAE9C;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACtE,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAChD,CAAC;AAEF,cAAM,uBAAwB,SAAQ,YAAY;CAAG;AACrD,eAAO,MAAM,gBAAgB,yBAAgC,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { EventEmitter } from 'events';
2
+ /** Default in-memory session store — process-local Map. */
3
+ export class InMemorySessionStore {
4
+ map = new Map();
5
+ set(id, session) {
6
+ this.map.set(id, session);
7
+ }
8
+ get(id) {
9
+ return this.map.get(id);
10
+ }
11
+ delete(id) {
12
+ this.map.delete(id);
13
+ }
14
+ has(id) {
15
+ return this.map.has(id);
16
+ }
17
+ values() {
18
+ return this.map.values();
19
+ }
20
+ size() {
21
+ return this.map.size;
22
+ }
23
+ }
24
+ let activeStore = new InMemorySessionStore();
25
+ /**
26
+ * Replace the active session store. Call this once at startup, before the
27
+ * HTTP/WS server accepts connections. Switching stores mid-flight will
28
+ * orphan any sessions already held in the previous store.
29
+ */
30
+ export function setSessionStore(store) {
31
+ activeStore = store;
32
+ }
33
+ /** Get the active session store (for internal proxy code + tests). */
34
+ export function getSessionStore() {
35
+ return activeStore;
36
+ }
37
+ class SessionLifecycleEmitter extends EventEmitter {
38
+ }
39
+ export const sessionLifecycle = new SessionLifecycleEmitter();
40
+ //# sourceMappingURL=session-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-store.js","sourceRoot":"","sources":["../src/session-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAmCtC,2DAA2D;AAC3D,MAAM,OAAO,oBAAoB;IACd,GAAG,GAAG,IAAI,GAAG,EAAmB,CAAC;IAElD,GAAG,CAAC,EAAU,EAAE,OAAgB;QAC9B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAC5B,CAAC;IACD,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC;IACD,MAAM,CAAC,EAAU;QACf,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC;IACD,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC;IACD,MAAM;QACJ,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;IAC3B,CAAC;IACD,IAAI;QACF,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;IACvB,CAAC;CACF;AAED,IAAI,WAAW,GAAiB,IAAI,oBAAoB,EAAE,CAAC;AAE3D;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,KAAmB;IACjD,WAAW,GAAG,KAAK,CAAC;AACtB,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,eAAe;IAC7B,OAAO,WAAW,CAAC;AACrB,CAAC;AAeD,MAAM,uBAAwB,SAAQ,YAAY;CAAG;AACrD,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,uBAAuB,EAAE,CAAC"}
package/dist/session.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { EventEmitter } from 'events';
2
2
  import { ProtocolHandler } from './protocols/index.js';
3
3
  import type { ProtocolType, ProtocolOptions, ScreenData } from './protocols/index.js';
4
- import type { ConnectionStatus } from 'green-screen-types';
4
+ import type { ConnectionStatus, FieldValue } from 'green-screen-types';
5
5
  export declare class Session extends EventEmitter {
6
6
  readonly id: string;
7
7
  readonly handler: ProtocolHandler;
@@ -9,9 +9,20 @@ export declare class Session extends EventEmitter {
9
9
  private _status;
10
10
  private _host;
11
11
  private _port;
12
- /** Timeout (ms) to wait for screen data after connect or key send (default 2000) */
12
+ private _idleTimer;
13
+ private _lastActivity;
14
+ /** Timeout (ms) to wait for screen data after connect or key send (default 5000) */
13
15
  screenTimeout: number;
16
+ /** Idle timeout (ms) — session auto-destroys if no activity. Default 5 min.
17
+ * Prevents stale TCP sessions when the backend crashes or misses a disconnect call. */
18
+ static IDLE_TIMEOUT: number;
14
19
  constructor(protocol?: ProtocolType);
20
+ /** Reset idle timer — called on any API activity (screen read, key send, etc.) */
21
+ touch(): void;
22
+ /** Start the idle timer. Call after connection is established. */
23
+ startIdleTimer(): void;
24
+ /** Stop the idle timer. */
25
+ stopIdleTimer(): void;
15
26
  get status(): ConnectionStatus;
16
27
  /** Mark this session as authenticated after a successful auto-sign-in */
17
28
  markAuthenticated(username: string): void;
@@ -22,13 +33,25 @@ export declare class Session extends EventEmitter {
22
33
  sendKey(keyName: string): boolean;
23
34
  setCursor(row: number, col: number): boolean;
24
35
  getScreenData(): ScreenData;
36
+ /** Read input field values from the current screen.
37
+ * @param modifiedOnly — when true (default), only fields with MDT bit set. */
38
+ readFieldValues(modifiedOnly?: boolean): FieldValue[];
39
+ /** Wait until the next screen has at least `minFields` input fields (or timeout). */
40
+ waitForScreenWithFields(minFields: number, timeoutMs: number): Promise<ScreenData>;
25
41
  /** Wait for the next screenChange event, or return current screen after timeout */
26
42
  waitForScreen(timeoutMs: number): Promise<ScreenData>;
43
+ /** Send a remote key and wait for the host response — race-free.
44
+ * Sets up the screenChange listener BEFORE sending the key so fast
45
+ * host responses are never missed. */
46
+ sendKeyAndWait(keyName: string, timeoutMs: number): Promise<{
47
+ ok: boolean;
48
+ screen: ScreenData;
49
+ }>;
27
50
  destroy(): void;
28
51
  }
29
52
  export declare function createSession(protocol?: ProtocolType): Session;
30
53
  export declare function getSession(id: string): Session | undefined;
31
54
  export declare function destroySession(id: string): void;
32
55
  export declare function getDefaultSession(): Session | undefined;
33
- export declare function getAllSessions(): Map<string, Session>;
56
+ export declare function getAllSessions(): Session[];
34
57
  //# sourceMappingURL=session.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,eAAe,EAAyB,MAAM,sBAAsB,CAAC;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACtF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,qBAAa,OAAQ,SAAQ,YAAY;IACvC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAEhC,OAAO,CAAC,OAAO,CAAkE;IACjF,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,KAAK,CAAc;IAE3B,oFAAoF;IACpF,aAAa,EAAE,MAAM,CAAQ;gBAEjB,QAAQ,GAAE,YAAuB;IAmB7C,IAAI,MAAM,IAAI,gBAAgB,CAE7B;IAED,yEAAyE;IACzE,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IASnC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAYnF,UAAU,IAAI,IAAI;IAMZ,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAKhC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI/B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIjC,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAI5C,aAAa;IAIb,mFAAmF;IACnF,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAUrD,OAAO,IAAI,IAAI;CAIhB;AAKD,wBAAgB,aAAa,CAAC,QAAQ,GAAE,YAAuB,GAAG,OAAO,CAIxE;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAE1D;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAM/C;AAED,wBAAgB,iBAAiB,IAAI,OAAO,GAAG,SAAS,CAKvD;AAED,wBAAgB,cAAc,IAAI,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAErD"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,eAAe,EAAyB,MAAM,sBAAsB,CAAC;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACtF,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGvE,qBAAa,OAAQ,SAAQ,YAAY;IACvC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAEhC,OAAO,CAAC,OAAO,CAAkE;IACjF,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,aAAa,CAAsB;IAE3C,oFAAoF;IACpF,aAAa,EAAE,MAAM,CAAQ;IAE7B;4FACwF;IACxF,MAAM,CAAC,YAAY,SAAiB;gBAExB,QAAQ,GAAE,YAAuB;IAuB7C,kFAAkF;IAClF,KAAK,IAAI,IAAI;IAIb,kEAAkE;IAClE,cAAc,IAAI,IAAI;IAUtB,2BAA2B;IAC3B,aAAa,IAAI,IAAI;IAOrB,IAAI,MAAM,IAAI,gBAAgB,CAE7B;IAED,yEAAyE;IACzE,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IASnC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAcnF,UAAU,IAAI,IAAI;IAOZ,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAKhC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI/B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAIjC,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;IAI5C,aAAa;IAIb;mFAC+E;IAC/E,eAAe,CAAC,YAAY,GAAE,OAAc,GAAG,UAAU,EAAE;IAK3D,qFAAqF;IACrF,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAKlF,mFAAmF;IACnF,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAUrD;;2CAEuC;IACvC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,CAAC;IAwBhG,OAAO,IAAI,IAAI;CAKhB;AAMD,wBAAgB,aAAa,CAAC,QAAQ,GAAE,YAAuB,GAAG,OAAO,CAIxE;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAE1D;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAO/C;AAED,wBAAgB,iBAAiB,IAAI,OAAO,GAAG,SAAS,CAMvD;AAED,wBAAgB,cAAc,IAAI,OAAO,EAAE,CAE1C"}