@actana/sdk 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +66 -0
- package/dist/core-client.d.ts +616 -0
- package/dist/core-client.d.ts.map +1 -0
- package/dist/core-client.js +1036 -0
- package/dist/core-client.js.map +1 -0
- package/dist/core-link-cursor-storage.d.ts +32 -0
- package/dist/core-link-cursor-storage.d.ts.map +1 -0
- package/dist/core-link-cursor-storage.js +66 -0
- package/dist/core-link-cursor-storage.js.map +1 -0
- package/dist/core-link-frames.d.ts +1123 -0
- package/dist/core-link-frames.d.ts.map +1 -0
- package/dist/core-link-frames.js +349 -0
- package/dist/core-link-frames.js.map +1 -0
- package/dist/core-link-socket.d.ts +54 -0
- package/dist/core-link-socket.d.ts.map +1 -0
- package/dist/core-link-socket.js +74 -0
- package/dist/core-link-socket.js.map +1 -0
- package/dist/core-link-transport.d.ts +177 -0
- package/dist/core-link-transport.d.ts.map +1 -0
- package/dist/core-link-transport.js +432 -0
- package/dist/core-link-transport.js.map +1 -0
- package/dist/core-registration-blob.d.ts +52 -0
- package/dist/core-registration-blob.d.ts.map +1 -0
- package/dist/core-registration-blob.js +61 -0
- package/dist/core-registration-blob.js.map +1 -0
- package/dist/core-session.d.ts +321 -0
- package/dist/core-session.d.ts.map +1 -0
- package/dist/core-session.js +660 -0
- package/dist/core-session.js.map +1 -0
- package/dist/durable-core-client.d.ts +172 -0
- package/dist/durable-core-client.d.ts.map +1 -0
- package/dist/durable-core-client.js +264 -0
- package/dist/durable-core-client.js.map +1 -0
- package/dist/terminal-screen.d.ts +139 -0
- package/dist/terminal-screen.d.ts.map +1 -0
- package/dist/terminal-screen.js +807 -0
- package/dist/terminal-screen.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-session.js","sourceRoot":"","sources":["../src/core-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import type { CoreLinkEvent } from "./core-link-frames.ts";
|
|
2
|
+
import { CoreClient, type CoreClientOptions } from "./core-client.ts";
|
|
3
|
+
import type { CoreRegistrationBlob } from "./core-registration-blob.ts";
|
|
4
|
+
import { type CoreLinkCursorStorage } from "./core-link-cursor-storage.ts";
|
|
5
|
+
import type { CoreLinkHeartbeatOptions } from "./core-link-transport.ts";
|
|
6
|
+
/** Reconnect backoff floor: the delay after the first unexpected drop. */
|
|
7
|
+
export declare const DEFAULT_RECONNECT_INITIAL_MS = 500;
|
|
8
|
+
/** Reconnect backoff ceiling. Doubling stops here and keeps trying at this rate. */
|
|
9
|
+
export declare const DEFAULT_RECONNECT_MAX_MS = 5000;
|
|
10
|
+
export type DurableCoreClientOptions = CoreClientOptions & {
|
|
11
|
+
/** Reconnect backoff floor in ms. Default 500. */
|
|
12
|
+
reconnectInitialMs?: number;
|
|
13
|
+
/** Reconnect backoff ceiling in ms. Default 5000. */
|
|
14
|
+
reconnectMaxMs?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Where the per-Core `lastEventId` cursor is kept. Default:
|
|
17
|
+
* {@link InMemoryCoreLinkCursorStorage} — replay across every reconnect within
|
|
18
|
+
* this process, but not across a restart. **Inject a durable store to get the
|
|
19
|
+
* restart too; never let this package import one** (see
|
|
20
|
+
* `core-link-cursor-storage.ts`).
|
|
21
|
+
*/
|
|
22
|
+
storage?: CoreLinkCursorStorage;
|
|
23
|
+
/** The key the cursor is stored under. Default: derived from the Core's URL. */
|
|
24
|
+
cursorStorageKey?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Arm the heartbeat. On by default here, which is the difference between this
|
|
27
|
+
* entry point and {@link CoreClient}: a link nobody is watching is exactly the
|
|
28
|
+
* one that has to notice it died.
|
|
29
|
+
*/
|
|
30
|
+
heartbeat?: CoreLinkHeartbeatOptions | false;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* A Core client that keeps its link up.
|
|
34
|
+
*
|
|
35
|
+
* `await connect()` resolves when the first connection is established and does
|
|
36
|
+
* not reject when a later one drops — a drop is what this class is for. From then
|
|
37
|
+
* on the link re-establishes itself: `onDisconnected` fires on every failed or
|
|
38
|
+
* lost connection, `onReady` on every one that comes back, and requests made in
|
|
39
|
+
* between are queued rather than refused.
|
|
40
|
+
*/
|
|
41
|
+
export declare class DurableCoreClient extends CoreClient {
|
|
42
|
+
private readonly reconnectInitialMs;
|
|
43
|
+
private readonly reconnectMaxMs;
|
|
44
|
+
private readonly storage;
|
|
45
|
+
private readonly cursorStorageKey;
|
|
46
|
+
private reconnectAttempt;
|
|
47
|
+
private reconnectTimer;
|
|
48
|
+
/** In-memory mirror of the persisted cursor; advanced by every event and marker. */
|
|
49
|
+
private lastEventId;
|
|
50
|
+
/** True between this connection's `eventsReplayed` and its drop. */
|
|
51
|
+
private caughtUp;
|
|
52
|
+
/**
|
|
53
|
+
* The PTYs this client has asked the Core for (ADR 0024 D2). PTY output fans
|
|
54
|
+
* out by subscription, so this set is the difference between a pane that
|
|
55
|
+
* renders and one that sits blank — and it is connection state on the Core,
|
|
56
|
+
* which means it does not survive a reconnect. This client re-sends it on every
|
|
57
|
+
* connection; nothing above it has to know the socket ever dropped.
|
|
58
|
+
*
|
|
59
|
+
* It records what this client *wants*, not what the Core holds: every
|
|
60
|
+
* connection re-derives its frames from this set against *that* connection's
|
|
61
|
+
* announced capability. Drop the want when no frame goes out and a Core that
|
|
62
|
+
* gains the capability across a restart comes back fanning out to subscribers
|
|
63
|
+
* only, with nothing left anywhere that remembers to subscribe.
|
|
64
|
+
*/
|
|
65
|
+
private readonly subscribedPtys;
|
|
66
|
+
constructor(opts: DurableCoreClientOptions);
|
|
67
|
+
/** Build a durable client straight off a registration blob (#129 D1). */
|
|
68
|
+
static fromRegistrationBlob(blob: CoreRegistrationBlob, opts?: Omit<DurableCoreClientOptions, "blob" | "url" | "tls" | "bearer">): DurableCoreClient;
|
|
69
|
+
/**
|
|
70
|
+
* The connect promise a durable client hands back does not fail on a lost
|
|
71
|
+
* socket: the supervisor is already dialing again, so rejecting would report a
|
|
72
|
+
* connection as unrecoverable at the exact moment it is being recovered. What
|
|
73
|
+
* still rejects it is a refused bearer (retrying an expired one is futile until
|
|
74
|
+
* a fresh blob is pasted — ADR 0003) and the connect deadline.
|
|
75
|
+
*/
|
|
76
|
+
protected onConnectionClosed(): void;
|
|
77
|
+
/**
|
|
78
|
+
* The supervisor is the only thing that dials here once the first connection
|
|
79
|
+
* has been asked for, so a `connect()` made during the backoff waits for the
|
|
80
|
+
* dial that is already coming rather than racing one of its own.
|
|
81
|
+
*/
|
|
82
|
+
protected reconnectScheduled(): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* What this client owes the Core on every connection, in the one order that
|
|
85
|
+
* works.
|
|
86
|
+
*
|
|
87
|
+
* `reclaim` first (via `super`): it is the only frame on this path with a clock
|
|
88
|
+
* on it (ADR 0024 D9). Until it lands, the socket this connection replaces is
|
|
89
|
+
* still holding this client's Sessions and the Core cannot tell it from a live
|
|
90
|
+
* one. `subscribe` and the PTY re-subscription are catching up on what happened
|
|
91
|
+
* while we were away and lose nothing by going second.
|
|
92
|
+
*
|
|
93
|
+
* Then `subscribe`, carrying the cursor — the Core streams the tail past it and
|
|
94
|
+
* ends with `eventsReplayed`. Then the PTY subscriptions, which died with the
|
|
95
|
+
* previous socket.
|
|
96
|
+
*
|
|
97
|
+
* Everything here runs after `auth` has been accepted, because the Core refuses
|
|
98
|
+
* all three before authentication, and after `ready`, because all three are
|
|
99
|
+
* gated on the capability that frame announces. That ordering is load-bearing
|
|
100
|
+
* rather than incidental, and the transport is what guarantees it: it does not
|
|
101
|
+
* call this until the connection is both open and authenticated.
|
|
102
|
+
*/
|
|
103
|
+
protected onConnectionEstablished(): void;
|
|
104
|
+
/**
|
|
105
|
+
* Ask the Core for the event-log tail past this client's cursor.
|
|
106
|
+
*
|
|
107
|
+
* Fire-and-forget: the answer is the `event` stream and the `eventsReplayed`
|
|
108
|
+
* marker, not a reqId-correlated response, so there is nothing here to await.
|
|
109
|
+
* A send that fails is a socket that just died, and the next connection sends
|
|
110
|
+
* this again with the same cursor.
|
|
111
|
+
*/
|
|
112
|
+
private sendSubscribe;
|
|
113
|
+
/**
|
|
114
|
+
* Re-ask for every PTY this client had, on a connection that has just come up.
|
|
115
|
+
*
|
|
116
|
+
* `catchUp` is deliberately not set. A hold is released by a `replay` from the
|
|
117
|
+
* same client, and nothing here is going to send one — the surfaces that replay
|
|
118
|
+
* do it off their own reconnect, one layer up, and a hold nobody releases is a
|
|
119
|
+
* pane that stays blank forever. Going live immediately is also exactly what
|
|
120
|
+
* this path did before subscriptions existed.
|
|
121
|
+
*/
|
|
122
|
+
private resendPtySubscriptions;
|
|
123
|
+
/**
|
|
124
|
+
* Ask for one PTY's stream and remember the want, so a reconnect restores it.
|
|
125
|
+
*
|
|
126
|
+
* Idempotent on both sides: a second call for a PTY already held is a no-op
|
|
127
|
+
* here and an ack there. The capability fallback is
|
|
128
|
+
* {@link CoreClient.ptySubscribe}'s, unchanged — and the want is recorded
|
|
129
|
+
* either way, for the reason given on {@link subscribedPtys}.
|
|
130
|
+
*/
|
|
131
|
+
ptySubscribe(ptyId: string, opts?: {
|
|
132
|
+
catchUp?: boolean;
|
|
133
|
+
}): Promise<void>;
|
|
134
|
+
/** Stop receiving one PTY's stream, and stop re-asking for it on reconnect. */
|
|
135
|
+
ptyUnsubscribe(ptyId: string): Promise<void>;
|
|
136
|
+
/**
|
|
137
|
+
* One event off the log — replayed or live, the same frame either way.
|
|
138
|
+
*
|
|
139
|
+
* Deduped against the cursor before anything above sees it: a replay overlaps
|
|
140
|
+
* by design (the Core streams everything *past* a cursor, and a re-delivery
|
|
141
|
+
* after a reconnect is ordinary), so a listener that received the same event
|
|
142
|
+
* twice would double-count a status change or paint a question menu twice. The
|
|
143
|
+
* cursor advances and is persisted on every event that gets through, which is
|
|
144
|
+
* what makes the *next* reconnect's tail start in the right place.
|
|
145
|
+
*/
|
|
146
|
+
protected deliverEvent(event: CoreLinkEvent): void;
|
|
147
|
+
/**
|
|
148
|
+
* End of the replay tail. The marker is authoritative for the caught-up cursor
|
|
149
|
+
* — it advances even when no `event` frame preceded it, which is the empty-tail
|
|
150
|
+
* case and the common one for a client that dropped and came straight back.
|
|
151
|
+
*/
|
|
152
|
+
protected deliverEventsReplayed(lastEventId: number): void;
|
|
153
|
+
/** The highest eventId this client has seen. Mirrors the persisted cursor. */
|
|
154
|
+
getLastEventId(): number;
|
|
155
|
+
/** True once this connection's replay tail has been fully delivered. */
|
|
156
|
+
isCaughtUp(): boolean;
|
|
157
|
+
private readPersistedCursor;
|
|
158
|
+
private persistCursor;
|
|
159
|
+
/**
|
|
160
|
+
* Exponential backoff from {@link DEFAULT_RECONNECT_INITIAL_MS} up to
|
|
161
|
+
* {@link DEFAULT_RECONNECT_MAX_MS}, reset by a connection that comes up.
|
|
162
|
+
*
|
|
163
|
+
* The ceiling is low on purpose: a Core is a machine an operator restarts, so
|
|
164
|
+
* the common case is a gap of a few seconds and the right behaviour is to keep
|
|
165
|
+
* knocking at a steady rate rather than to back off into minutes and leave a
|
|
166
|
+
* pane blank long after the Core came back.
|
|
167
|
+
*/
|
|
168
|
+
private scheduleReconnect;
|
|
169
|
+
/** Hang up for good: stop the backoff, then everything {@link CoreClient.close} does. */
|
|
170
|
+
close(): void;
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=durable-core-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"durable-core-client.d.ts","sourceRoot":"","sources":["../src/durable-core-client.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAEzE,0EAA0E;AAC1E,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAChD,oFAAoF;AACpF,eAAO,MAAM,wBAAwB,OAAQ,CAAC;AAE9C,MAAM,MAAM,wBAAwB,GAAG,iBAAiB,GAAG;IACzD,kDAAkD;IAClD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAChC,gFAAgF;IAChF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,SAAS,CAAC,EAAE,wBAAwB,GAAG,KAAK,CAAC;CAC9C,CAAC;AAEF;;;;;;;;GAQG;AACH,qBAAa,iBAAkB,SAAQ,UAAU;IAC/C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAE1C,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,cAAc,CAA8C;IAEpE,oFAAoF;IACpF,OAAO,CAAC,WAAW,CAAK;IACxB,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAAS;IAEzB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;gBAExC,IAAI,EAAE,wBAAwB;IAS1C,yEAAyE;WACzD,oBAAoB,CAClC,IAAI,EAAE,oBAAoB,EAC1B,IAAI,GAAE,IAAI,CAAC,wBAAwB,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAM,GAC3E,iBAAiB;IAIpB;;;;;;OAMG;cACgB,kBAAkB,IAAI,IAAI;IAK7C;;;;OAIG;cACgB,kBAAkB,IAAI,OAAO;IAIhD;;;;;;;;;;;;;;;;;;;OAmBG;cACgB,uBAAuB,IAAI,IAAI;IAOlD;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;IAKrB;;;;;;;;OAQG;IACH,OAAO,CAAC,sBAAsB;IAW9B;;;;;;;OAOG;IACM,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAMrF,+EAA+E;IACtE,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOrD;;;;;;;;;OASG;cACgB,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAO3D;;;;OAIG;cACgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IASnE,8EAA8E;IAC9E,cAAc,IAAI,MAAM;IAIxB,wEAAwE;IACxE,UAAU,IAAI,OAAO;IAIrB,OAAO,CAAC,mBAAmB;IAY3B,OAAO,CAAC,aAAa;IAUrB;;;;;;;;OAQG;IACH,OAAO,CAAC,iBAAiB;IAezB,yFAAyF;IAChF,KAAK,IAAI,IAAI;CAOvB"}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
// `DurableCoreClient` — the entry point for a program that stays up.
|
|
2
|
+
//
|
|
3
|
+
// The second of the two entry points on one transport (#129 D6). It is
|
|
4
|
+
// {@link CoreClient} plus the four things a link that must survive a night of
|
|
5
|
+
// idleness needs and a one-shot dial has no use for:
|
|
6
|
+
//
|
|
7
|
+
// - a **heartbeat**, because an idle core link is what a NAT reaps silently;
|
|
8
|
+
// - **reconnection with backoff**, because a Core restarts, a machine sleeps,
|
|
9
|
+
// and a laptop lid closes;
|
|
10
|
+
// - an **event cursor** in an injected {@link CoreLinkCursorStorage}, because a
|
|
11
|
+
// client that was away has to be told what it missed rather than guess;
|
|
12
|
+
// - **subscribe-then-replay**, because that is the order in which a gap is
|
|
13
|
+
// closed without a hole and without a double.
|
|
14
|
+
//
|
|
15
|
+
// This is what the Panel will use (#156). Nothing here is Panel-specific: there
|
|
16
|
+
// is no `Fleet` type, no Core registry, and no notion of a second Core — one
|
|
17
|
+
// client is one socket to one machine (#129 D5), and holding several of these is
|
|
18
|
+
// the Panel's business.
|
|
19
|
+
//
|
|
20
|
+
// Extracted from `PtyCoreLinkClient` (issue 153), whose reconnect loop, cursor
|
|
21
|
+
// handling and PTY re-subscription are the four sections below. That class was
|
|
22
|
+
// deleted in #156: this is the Panel's client now, not a copy of it.
|
|
23
|
+
import { CoreClient } from "./core-client.js";
|
|
24
|
+
import { coreLinkCursorStorageKey, InMemoryCoreLinkCursorStorage, } from "./core-link-cursor-storage.js";
|
|
25
|
+
/** Reconnect backoff floor: the delay after the first unexpected drop. */
|
|
26
|
+
export const DEFAULT_RECONNECT_INITIAL_MS = 500;
|
|
27
|
+
/** Reconnect backoff ceiling. Doubling stops here and keeps trying at this rate. */
|
|
28
|
+
export const DEFAULT_RECONNECT_MAX_MS = 5_000;
|
|
29
|
+
/**
|
|
30
|
+
* A Core client that keeps its link up.
|
|
31
|
+
*
|
|
32
|
+
* `await connect()` resolves when the first connection is established and does
|
|
33
|
+
* not reject when a later one drops — a drop is what this class is for. From then
|
|
34
|
+
* on the link re-establishes itself: `onDisconnected` fires on every failed or
|
|
35
|
+
* lost connection, `onReady` on every one that comes back, and requests made in
|
|
36
|
+
* between are queued rather than refused.
|
|
37
|
+
*/
|
|
38
|
+
export class DurableCoreClient extends CoreClient {
|
|
39
|
+
reconnectInitialMs;
|
|
40
|
+
reconnectMaxMs;
|
|
41
|
+
storage;
|
|
42
|
+
cursorStorageKey;
|
|
43
|
+
reconnectAttempt = 0;
|
|
44
|
+
reconnectTimer = null;
|
|
45
|
+
/** In-memory mirror of the persisted cursor; advanced by every event and marker. */
|
|
46
|
+
lastEventId = 0;
|
|
47
|
+
/** True between this connection's `eventsReplayed` and its drop. */
|
|
48
|
+
caughtUp = false;
|
|
49
|
+
/**
|
|
50
|
+
* The PTYs this client has asked the Core for (ADR 0024 D2). PTY output fans
|
|
51
|
+
* out by subscription, so this set is the difference between a pane that
|
|
52
|
+
* renders and one that sits blank — and it is connection state on the Core,
|
|
53
|
+
* which means it does not survive a reconnect. This client re-sends it on every
|
|
54
|
+
* connection; nothing above it has to know the socket ever dropped.
|
|
55
|
+
*
|
|
56
|
+
* It records what this client *wants*, not what the Core holds: every
|
|
57
|
+
* connection re-derives its frames from this set against *that* connection's
|
|
58
|
+
* announced capability. Drop the want when no frame goes out and a Core that
|
|
59
|
+
* gains the capability across a restart comes back fanning out to subscribers
|
|
60
|
+
* only, with nothing left anywhere that remembers to subscribe.
|
|
61
|
+
*/
|
|
62
|
+
subscribedPtys = new Set();
|
|
63
|
+
constructor(opts) {
|
|
64
|
+
super({ ...opts, heartbeat: opts.heartbeat ?? {} });
|
|
65
|
+
this.reconnectInitialMs = opts.reconnectInitialMs ?? DEFAULT_RECONNECT_INITIAL_MS;
|
|
66
|
+
this.reconnectMaxMs = opts.reconnectMaxMs ?? DEFAULT_RECONNECT_MAX_MS;
|
|
67
|
+
this.storage = opts.storage ?? new InMemoryCoreLinkCursorStorage();
|
|
68
|
+
this.cursorStorageKey = opts.cursorStorageKey ?? coreLinkCursorStorageKey(this.url);
|
|
69
|
+
this.lastEventId = this.readPersistedCursor();
|
|
70
|
+
}
|
|
71
|
+
/** Build a durable client straight off a registration blob (#129 D1). */
|
|
72
|
+
static fromRegistrationBlob(blob, opts = {}) {
|
|
73
|
+
return new DurableCoreClient({ ...opts, blob });
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The connect promise a durable client hands back does not fail on a lost
|
|
77
|
+
* socket: the supervisor is already dialing again, so rejecting would report a
|
|
78
|
+
* connection as unrecoverable at the exact moment it is being recovered. What
|
|
79
|
+
* still rejects it is a refused bearer (retrying an expired one is futile until
|
|
80
|
+
* a fresh blob is pasted — ADR 0003) and the connect deadline.
|
|
81
|
+
*/
|
|
82
|
+
onConnectionClosed() {
|
|
83
|
+
this.caughtUp = false;
|
|
84
|
+
this.scheduleReconnect();
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* The supervisor is the only thing that dials here once the first connection
|
|
88
|
+
* has been asked for, so a `connect()` made during the backoff waits for the
|
|
89
|
+
* dial that is already coming rather than racing one of its own.
|
|
90
|
+
*/
|
|
91
|
+
reconnectScheduled() {
|
|
92
|
+
return this.reconnectTimer !== null;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* What this client owes the Core on every connection, in the one order that
|
|
96
|
+
* works.
|
|
97
|
+
*
|
|
98
|
+
* `reclaim` first (via `super`): it is the only frame on this path with a clock
|
|
99
|
+
* on it (ADR 0024 D9). Until it lands, the socket this connection replaces is
|
|
100
|
+
* still holding this client's Sessions and the Core cannot tell it from a live
|
|
101
|
+
* one. `subscribe` and the PTY re-subscription are catching up on what happened
|
|
102
|
+
* while we were away and lose nothing by going second.
|
|
103
|
+
*
|
|
104
|
+
* Then `subscribe`, carrying the cursor — the Core streams the tail past it and
|
|
105
|
+
* ends with `eventsReplayed`. Then the PTY subscriptions, which died with the
|
|
106
|
+
* previous socket.
|
|
107
|
+
*
|
|
108
|
+
* Everything here runs after `auth` has been accepted, because the Core refuses
|
|
109
|
+
* all three before authentication, and after `ready`, because all three are
|
|
110
|
+
* gated on the capability that frame announces. That ordering is load-bearing
|
|
111
|
+
* rather than incidental, and the transport is what guarantees it: it does not
|
|
112
|
+
* call this until the connection is both open and authenticated.
|
|
113
|
+
*/
|
|
114
|
+
onConnectionEstablished() {
|
|
115
|
+
this.reconnectAttempt = 0;
|
|
116
|
+
super.onConnectionEstablished();
|
|
117
|
+
this.sendSubscribe();
|
|
118
|
+
this.resendPtySubscriptions();
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Ask the Core for the event-log tail past this client's cursor.
|
|
122
|
+
*
|
|
123
|
+
* Fire-and-forget: the answer is the `event` stream and the `eventsReplayed`
|
|
124
|
+
* marker, not a reqId-correlated response, so there is nothing here to await.
|
|
125
|
+
* A send that fails is a socket that just died, and the next connection sends
|
|
126
|
+
* this again with the same cursor.
|
|
127
|
+
*/
|
|
128
|
+
sendSubscribe() {
|
|
129
|
+
this.caughtUp = false;
|
|
130
|
+
this.subscribeEvents(this.lastEventId);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Re-ask for every PTY this client had, on a connection that has just come up.
|
|
134
|
+
*
|
|
135
|
+
* `catchUp` is deliberately not set. A hold is released by a `replay` from the
|
|
136
|
+
* same client, and nothing here is going to send one — the surfaces that replay
|
|
137
|
+
* do it off their own reconnect, one layer up, and a hold nobody releases is a
|
|
138
|
+
* pane that stays blank forever. Going live immediately is also exactly what
|
|
139
|
+
* this path did before subscriptions existed.
|
|
140
|
+
*/
|
|
141
|
+
resendPtySubscriptions() {
|
|
142
|
+
// The same deliberate single-connection fallback `ptySubscribe` takes: a Core
|
|
143
|
+
// without the capability is already sending these PTYs to every connection.
|
|
144
|
+
if (!this.canSendMultiConnectionFrames())
|
|
145
|
+
return;
|
|
146
|
+
for (const ptyId of this.subscribedPtys) {
|
|
147
|
+
void this.rpc({ type: "ptySubscribe", reqId: "", ptyId, catchUp: false }).catch(() => {
|
|
148
|
+
/* the socket died again; the next connection re-sends the whole set */
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Ask for one PTY's stream and remember the want, so a reconnect restores it.
|
|
154
|
+
*
|
|
155
|
+
* Idempotent on both sides: a second call for a PTY already held is a no-op
|
|
156
|
+
* here and an ack there. The capability fallback is
|
|
157
|
+
* {@link CoreClient.ptySubscribe}'s, unchanged — and the want is recorded
|
|
158
|
+
* either way, for the reason given on {@link subscribedPtys}.
|
|
159
|
+
*/
|
|
160
|
+
ptySubscribe(ptyId, opts = {}) {
|
|
161
|
+
if (this.subscribedPtys.has(ptyId))
|
|
162
|
+
return Promise.resolve();
|
|
163
|
+
this.subscribedPtys.add(ptyId);
|
|
164
|
+
return super.ptySubscribe(ptyId, opts);
|
|
165
|
+
}
|
|
166
|
+
/** Stop receiving one PTY's stream, and stop re-asking for it on reconnect. */
|
|
167
|
+
ptyUnsubscribe(ptyId) {
|
|
168
|
+
if (!this.subscribedPtys.delete(ptyId))
|
|
169
|
+
return Promise.resolve();
|
|
170
|
+
return super.ptyUnsubscribe(ptyId);
|
|
171
|
+
}
|
|
172
|
+
// ─── The event cursor ──────────────────────────────────────────────────────
|
|
173
|
+
/**
|
|
174
|
+
* One event off the log — replayed or live, the same frame either way.
|
|
175
|
+
*
|
|
176
|
+
* Deduped against the cursor before anything above sees it: a replay overlaps
|
|
177
|
+
* by design (the Core streams everything *past* a cursor, and a re-delivery
|
|
178
|
+
* after a reconnect is ordinary), so a listener that received the same event
|
|
179
|
+
* twice would double-count a status change or paint a question menu twice. The
|
|
180
|
+
* cursor advances and is persisted on every event that gets through, which is
|
|
181
|
+
* what makes the *next* reconnect's tail start in the right place.
|
|
182
|
+
*/
|
|
183
|
+
deliverEvent(event) {
|
|
184
|
+
if (event.eventId <= this.lastEventId)
|
|
185
|
+
return;
|
|
186
|
+
this.lastEventId = event.eventId;
|
|
187
|
+
this.persistCursor();
|
|
188
|
+
super.deliverEvent(event);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* End of the replay tail. The marker is authoritative for the caught-up cursor
|
|
192
|
+
* — it advances even when no `event` frame preceded it, which is the empty-tail
|
|
193
|
+
* case and the common one for a client that dropped and came straight back.
|
|
194
|
+
*/
|
|
195
|
+
deliverEventsReplayed(lastEventId) {
|
|
196
|
+
if (lastEventId > this.lastEventId) {
|
|
197
|
+
this.lastEventId = lastEventId;
|
|
198
|
+
this.persistCursor();
|
|
199
|
+
}
|
|
200
|
+
this.caughtUp = true;
|
|
201
|
+
super.deliverEventsReplayed(this.lastEventId);
|
|
202
|
+
}
|
|
203
|
+
/** The highest eventId this client has seen. Mirrors the persisted cursor. */
|
|
204
|
+
getLastEventId() {
|
|
205
|
+
return this.lastEventId;
|
|
206
|
+
}
|
|
207
|
+
/** True once this connection's replay tail has been fully delivered. */
|
|
208
|
+
isCaughtUp() {
|
|
209
|
+
return this.caughtUp;
|
|
210
|
+
}
|
|
211
|
+
readPersistedCursor() {
|
|
212
|
+
try {
|
|
213
|
+
const raw = this.storage.getItem(this.cursorStorageKey);
|
|
214
|
+
const n = raw == null ? NaN : Number(raw);
|
|
215
|
+
return Number.isFinite(n) && n >= 0 ? n : 0;
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
// A store that throws on read is a store this client can still run without
|
|
219
|
+
// — it replays from 0 once, which is correct, if slower.
|
|
220
|
+
return 0;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
persistCursor() {
|
|
224
|
+
try {
|
|
225
|
+
this.storage.setItem(this.cursorStorageKey, String(this.lastEventId));
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
/* storage unavailable — the in-memory cursor still carries the reconnect */
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// ─── Reconnection ──────────────────────────────────────────────────────────
|
|
232
|
+
/**
|
|
233
|
+
* Exponential backoff from {@link DEFAULT_RECONNECT_INITIAL_MS} up to
|
|
234
|
+
* {@link DEFAULT_RECONNECT_MAX_MS}, reset by a connection that comes up.
|
|
235
|
+
*
|
|
236
|
+
* The ceiling is low on purpose: a Core is a machine an operator restarts, so
|
|
237
|
+
* the common case is a gap of a few seconds and the right behaviour is to keep
|
|
238
|
+
* knocking at a steady rate rather than to back off into minutes and leave a
|
|
239
|
+
* pane blank long after the Core came back.
|
|
240
|
+
*/
|
|
241
|
+
scheduleReconnect() {
|
|
242
|
+
if (this.closed)
|
|
243
|
+
return;
|
|
244
|
+
if (this.reconnectTimer)
|
|
245
|
+
return;
|
|
246
|
+
const delay = Math.min(this.reconnectInitialMs * Math.pow(2, this.reconnectAttempt), this.reconnectMaxMs);
|
|
247
|
+
this.reconnectAttempt++;
|
|
248
|
+
this.reconnectTimer = setTimeout(() => {
|
|
249
|
+
this.reconnectTimer = null;
|
|
250
|
+
if (this.closed)
|
|
251
|
+
return;
|
|
252
|
+
this.openTransport();
|
|
253
|
+
}, delay);
|
|
254
|
+
}
|
|
255
|
+
/** Hang up for good: stop the backoff, then everything {@link CoreClient.close} does. */
|
|
256
|
+
close() {
|
|
257
|
+
if (this.reconnectTimer) {
|
|
258
|
+
clearTimeout(this.reconnectTimer);
|
|
259
|
+
this.reconnectTimer = null;
|
|
260
|
+
}
|
|
261
|
+
super.close();
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=durable-core-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"durable-core-client.js","sourceRoot":"","sources":["../src/durable-core-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/** How many scrolled-off lines are kept by default. */
|
|
2
|
+
export declare const DEFAULT_SCROLLBACK_LINES = 5000;
|
|
3
|
+
/** Grid width used when a caller names none — the Core's own PTY default. */
|
|
4
|
+
export declare const DEFAULT_COLS = 100;
|
|
5
|
+
/** Grid height used when a caller names none — the Core's own PTY default. */
|
|
6
|
+
export declare const DEFAULT_ROWS = 30;
|
|
7
|
+
export type TerminalScreenOptions = {
|
|
8
|
+
/** Grid width. Must match the PTY's, or wrapping here disagrees with there. */
|
|
9
|
+
cols?: number;
|
|
10
|
+
/** Grid height. Same. */
|
|
11
|
+
rows?: number;
|
|
12
|
+
/**
|
|
13
|
+
* How many scrolled-off lines to keep. The oldest are dropped past this.
|
|
14
|
+
* Zero keeps none — a caller that only ever reads the viewport.
|
|
15
|
+
*/
|
|
16
|
+
scrollback?: number;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* A terminal screen fed one PTY's bytes.
|
|
20
|
+
*
|
|
21
|
+
* Feed it every chunk in order with {@link write} and read {@link lines},
|
|
22
|
+
* {@link text} or {@link viewportText}. Chunk boundaries are not respected by
|
|
23
|
+
* the stream — an escape sequence is routinely split across two `data` frames —
|
|
24
|
+
* so the parser is a state machine that carries its position between calls
|
|
25
|
+
* rather than anything that re-scans a buffer.
|
|
26
|
+
*/
|
|
27
|
+
export declare class TerminalScreen {
|
|
28
|
+
private colsValue;
|
|
29
|
+
private rowsValue;
|
|
30
|
+
private readonly scrollbackLimit;
|
|
31
|
+
private main;
|
|
32
|
+
private alt;
|
|
33
|
+
private buffer;
|
|
34
|
+
private onAlt;
|
|
35
|
+
private row;
|
|
36
|
+
private col;
|
|
37
|
+
/**
|
|
38
|
+
* The cursor is parked on the last column with a character already written
|
|
39
|
+
* there, and the *next* printable wraps before it lands (DEC's deferred wrap).
|
|
40
|
+
* Without this, a line exactly `cols` wide scrolls one line too early and
|
|
41
|
+
* every subsequent row is off by one.
|
|
42
|
+
*/
|
|
43
|
+
private pendingWrap;
|
|
44
|
+
/** Scroll region, inclusive, 0-based. Set by DECSTBM; full screen by default. */
|
|
45
|
+
private scrollTop;
|
|
46
|
+
private scrollBottom;
|
|
47
|
+
private state;
|
|
48
|
+
private csiBuf;
|
|
49
|
+
constructor(opts?: TerminalScreenOptions);
|
|
50
|
+
get cols(): number;
|
|
51
|
+
get rows(): number;
|
|
52
|
+
/** Where the cursor is, 0-based, for a caller that needs to know. */
|
|
53
|
+
get cursor(): {
|
|
54
|
+
row: number;
|
|
55
|
+
col: number;
|
|
56
|
+
};
|
|
57
|
+
/** True while a full-screen TUI has switched to the alternate buffer. */
|
|
58
|
+
get alternateScreen(): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Write one chunk of PTY output. Call it with every chunk, in order.
|
|
61
|
+
*
|
|
62
|
+
* Iterated by code point rather than by UTF-16 unit, so an astral character
|
|
63
|
+
* (an emoji, and harnesses print plenty) occupies one cell rather than two
|
|
64
|
+
* halves of a surrogate pair in two.
|
|
65
|
+
*/
|
|
66
|
+
write(data: string): void;
|
|
67
|
+
/**
|
|
68
|
+
* Change the grid's size. A caller that resizes the PTY resizes this too, or
|
|
69
|
+
* the two disagree about where every line wraps.
|
|
70
|
+
*
|
|
71
|
+
* Rows are added at the bottom and removed from the bottom; lines that a
|
|
72
|
+
* shrink pushes off the top go to the scrollback, exactly as scrolling would.
|
|
73
|
+
* Reflowing the existing text to a new width is deliberately not attempted —
|
|
74
|
+
* a real terminal's reflow is its own subsystem, and a harness repaints on
|
|
75
|
+
* `SIGWINCH` anyway, so the next frame is correct either way.
|
|
76
|
+
*/
|
|
77
|
+
resize(cols: number, rows: number): void;
|
|
78
|
+
/** The rows a terminal would be displaying now, top to bottom, right-trimmed. */
|
|
79
|
+
viewportLines(): string[];
|
|
80
|
+
/** Every line that has scrolled off the top, oldest first. The transcript. */
|
|
81
|
+
scrollbackLines(): string[];
|
|
82
|
+
/** Scrollback then viewport: everything this terminal has been shown. */
|
|
83
|
+
lines(): string[];
|
|
84
|
+
/**
|
|
85
|
+
* {@link lines} as one string, with the blank rows below the last written one
|
|
86
|
+
* trimmed off — a viewport is 30 rows whether or not a harness filled them,
|
|
87
|
+
* and a caller reading a screen wants what is on it, not the padding.
|
|
88
|
+
*/
|
|
89
|
+
text(): string;
|
|
90
|
+
/** The visible rows only, as one string. Same trailing-blank trim. */
|
|
91
|
+
viewportText(): string;
|
|
92
|
+
private ground;
|
|
93
|
+
private escape;
|
|
94
|
+
private csi;
|
|
95
|
+
private osc;
|
|
96
|
+
private stringSequence;
|
|
97
|
+
private dispatchCsi;
|
|
98
|
+
private putChar;
|
|
99
|
+
private lineFeed;
|
|
100
|
+
private reverseIndex;
|
|
101
|
+
/**
|
|
102
|
+
* Scroll the region up by `n`, which is where the scrollback comes from.
|
|
103
|
+
*
|
|
104
|
+
* A line only reaches the scrollback when the *whole screen* scrolls: a TUI
|
|
105
|
+
* scrolling a three-row region in the middle of its layout is animating a
|
|
106
|
+
* pane, not producing history, and a terminal keeps none of it either. Which
|
|
107
|
+
* buffer it scrolled on does not matter — see the header on why the alternate
|
|
108
|
+
* screen keeps its history here when a terminal would not.
|
|
109
|
+
*/
|
|
110
|
+
private scrollUp;
|
|
111
|
+
private scrollDown;
|
|
112
|
+
private insertLines;
|
|
113
|
+
private deleteLines;
|
|
114
|
+
private insertChars;
|
|
115
|
+
private deleteChars;
|
|
116
|
+
private eraseChars;
|
|
117
|
+
private eraseInLine;
|
|
118
|
+
private eraseInDisplay;
|
|
119
|
+
private setAlternateScreen;
|
|
120
|
+
private saveCursor;
|
|
121
|
+
private restoreCursor;
|
|
122
|
+
private reset;
|
|
123
|
+
private pushScrollback;
|
|
124
|
+
private blankLine;
|
|
125
|
+
private freshBuffer;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* How many columns one character occupies: 0, 1 or 2.
|
|
129
|
+
*
|
|
130
|
+
* Not a full Unicode width table — that is a data file, and this is an SDK. It
|
|
131
|
+
* is the three cases a harness's output actually contains: combining marks and
|
|
132
|
+
* the zero-width joiners that build emoji sequences take no column, the East
|
|
133
|
+
* Asian wide blocks and the emoji planes take two, and everything else takes
|
|
134
|
+
* one. Getting this wrong does not corrupt the text, it shifts a line by a
|
|
135
|
+
* column — which is why a box-drawing character (narrow, and everywhere in a
|
|
136
|
+
* TUI) matters more here than a rare script does.
|
|
137
|
+
*/
|
|
138
|
+
export declare function charWidth(ch: string): 0 | 1 | 2;
|
|
139
|
+
//# sourceMappingURL=terminal-screen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-screen.d.ts","sourceRoot":"","sources":["../src/terminal-screen.ts"],"names":[],"mappings":"AA0FA,uDAAuD;AACvD,eAAO,MAAM,wBAAwB,OAAQ,CAAC;AAC9C,6EAA6E;AAC7E,eAAO,MAAM,YAAY,MAAM,CAAC;AAChC,8EAA8E;AAC9E,eAAO,MAAM,YAAY,KAAK,CAAC;AAE/B,MAAM,MAAM,qBAAqB,GAAG;IAClC,+EAA+E;IAC/E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAeF;;;;;;;;GAQG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IAEzC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;IAEtB,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,GAAG,CAAK;IAChB;;;;;OAKG;IACH,OAAO,CAAC,WAAW,CAAS;IAE5B,iFAAiF;IACjF,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,YAAY,CAAS;IAE7B,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,MAAM,CAAM;gBAER,IAAI,GAAE,qBAA0B;IAU5C,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,qEAAqE;IACrE,IAAI,MAAM,IAAI;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAEzC;IAED,yEAAyE;IACzE,IAAI,eAAe,IAAI,OAAO,CAE7B;IAID;;;;;;OAMG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA2BzB;;;;;;;;;OASG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAwCxC,iFAAiF;IACjF,aAAa,IAAI,MAAM,EAAE;IAIzB,8EAA8E;IAC9E,eAAe,IAAI,MAAM,EAAE;IAI3B,yEAAyE;IACzE,KAAK,IAAI,MAAM,EAAE;IAIjB;;;;OAIG;IACH,IAAI,IAAI,MAAM;IAId,sEAAsE;IACtE,YAAY,IAAI,MAAM;IAMtB,OAAO,CAAC,MAAM;IAiCd,OAAO,CAAC,MAAM;IA4Dd,OAAO,CAAC,GAAG;IAiBX,OAAO,CAAC,GAAG;IAaX,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,WAAW;IA+HnB,OAAO,CAAC,OAAO;IAkCf,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,YAAY;IAQpB;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,cAAc;IA2BtB,OAAO,CAAC,kBAAkB;IAmB1B,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,KAAK;IAYb,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,WAAW;CAQpB;AAqBD;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CA+B/C"}
|