@meowpanel/api 0.13.0 → 0.15.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/esm/mod.d.ts +1 -1
- package/esm/mod.d.ts.map +1 -1
- package/esm/src/resources/servers/backups.d.ts +7 -7
- package/esm/src/resources/servers/backups.d.ts.map +1 -1
- package/esm/src/resources/servers/backups.js +8 -8
- package/esm/src/resources/servers/connection.d.ts +34 -7
- package/esm/src/resources/servers/connection.d.ts.map +1 -1
- package/esm/src/resources/servers/connection.js +109 -36
- package/esm/src/resources/servers/server.js +1 -1
- package/esm/src/sse.d.ts +63 -11
- package/esm/src/sse.d.ts.map +1 -1
- package/esm/src/sse.js +112 -31
- package/package.json +1 -1
- package/script/mod.d.ts +1 -1
- package/script/mod.d.ts.map +1 -1
- package/script/src/resources/servers/backups.d.ts +7 -7
- package/script/src/resources/servers/backups.d.ts.map +1 -1
- package/script/src/resources/servers/backups.js +8 -8
- package/script/src/resources/servers/connection.d.ts +34 -7
- package/script/src/resources/servers/connection.d.ts.map +1 -1
- package/script/src/resources/servers/connection.js +109 -36
- package/script/src/resources/servers/server.js +1 -1
- package/script/src/sse.d.ts +63 -11
- package/script/src/sse.d.ts.map +1 -1
- package/script/src/sse.js +112 -31
package/esm/mod.d.ts
CHANGED
|
@@ -54,7 +54,7 @@ export type { HttpClientOptions, HttpLogCode, HttpLogEvent, HttpLogger, HttpRequ
|
|
|
54
54
|
export { TypedEmitter } from './src/emitter.js';
|
|
55
55
|
export type { EventHandler } from './src/emitter.js';
|
|
56
56
|
export { SseConnection } from './src/sse.js';
|
|
57
|
-
export type { SseState } from './src/sse.js';
|
|
57
|
+
export type { SseConnectionEvents, SseOptions, SseState } from './src/sse.js';
|
|
58
58
|
export { joinIncludes, parseIssuerRef, toNanoID } from './src/types.js';
|
|
59
59
|
export type { DeletedListOptions, DeletedVisibility, IncludeOptions, ISODate, IssuerRef, ListOptions, NanoID, Paginated, ParsedIssuer, PowerAction, PowerState, ResourceColor, ResourceWith, ServerRestrictedState, SftpPermission, UnionToIntersection, } from './src/types.js';
|
|
60
60
|
export { Account, AccountResource, AccountSshKeysManager, ApiKeyAccount, SshKey, UserAccount, } from './src/resources/account.js';
|
package/esm/mod.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAG3D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,YAAY,EACX,QAAQ,EACR,YAAY,EACZ,qBAAqB,EACrB,cAAc,EACd,WAAW,EACX,aAAa,GACb,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGrD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,YAAY,EACX,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,UAAU,EACV,wBAAwB,EACxB,wBAAwB,EACxB,0BAA0B,EAC1B,cAAc,GACd,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,YAAY,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,YAAY,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,8 +6,8 @@ export type BackupAdapter = 'whisker' | 's3';
|
|
|
6
6
|
export interface CreateBackupOptions {
|
|
7
7
|
/** Storage adapter to write the backup to. */
|
|
8
8
|
adapter: BackupAdapter;
|
|
9
|
-
/** Client-chosen
|
|
10
|
-
|
|
9
|
+
/** Client-chosen 12-character nanoid identifying the backup. */
|
|
10
|
+
id: string;
|
|
11
11
|
/** Newline- or glob-separated ignore patterns. */
|
|
12
12
|
ignore?: string;
|
|
13
13
|
}
|
|
@@ -28,7 +28,7 @@ export interface RestoreBackupOptions {
|
|
|
28
28
|
*
|
|
29
29
|
* @example
|
|
30
30
|
* ```ts ignore
|
|
31
|
-
* const job = await server.backups.create({ adapter: 'whisker',
|
|
31
|
+
* const job = await server.backups.create({ adapter: 'whisker', id });
|
|
32
32
|
* await job.wait();
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
@@ -38,9 +38,9 @@ export declare class ServerBackupsManager {
|
|
|
38
38
|
constructor(node: NodeClient);
|
|
39
39
|
/** Start a backup. Returns the job to track. */
|
|
40
40
|
create(opts: CreateBackupOptions): Promise<ServerJob>;
|
|
41
|
-
/** Restore a backup by its
|
|
42
|
-
restore(
|
|
43
|
-
/** Delete a backup by its
|
|
44
|
-
delete(
|
|
41
|
+
/** Restore a backup by its nanoid. Returns the job to track. */
|
|
42
|
+
restore(backupId: string, opts: RestoreBackupOptions): Promise<ServerJob>;
|
|
43
|
+
/** Delete a backup by its nanoid. Treats an already-missing backup as success. */
|
|
44
|
+
delete(backupId: string): Promise<void>;
|
|
45
45
|
}
|
|
46
46
|
//# sourceMappingURL=backups.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backups.d.ts","sourceRoot":"","sources":["../../../../src/src/resources/servers/backups.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,+EAA+E;AAC/E,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,IAAI,CAAC;AAE7C,qCAAqC;AACrC,MAAM,WAAW,mBAAmB;IACnC,8CAA8C;IAC9C,OAAO,EAAE,aAAa,CAAC;IACvB,
|
|
1
|
+
{"version":3,"file":"backups.d.ts","sourceRoot":"","sources":["../../../../src/src/resources/servers/backups.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,+EAA+E;AAC/E,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,IAAI,CAAC;AAE7C,qCAAqC;AACrC,MAAM,WAAW,mBAAmB;IACnC,8CAA8C;IAC9C,OAAO,EAAE,aAAa,CAAC;IACvB,gEAAgE;IAChE,EAAE,EAAE,MAAM,CAAC;IACX,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,sCAAsC;AACtC,MAAM,WAAW,oBAAoB;IACpC,2CAA2C;IAC3C,OAAO,EAAE,aAAa,CAAC;IACvB,yDAAyD;IACzD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,oBAAoB;IAEb,OAAO,CAAC,QAAQ,CAAC,IAAI;IADxC,gBAAgB;gBACoB,IAAI,EAAE,UAAU;IAEpD,gDAAgD;IACnC,MAAM,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,SAAS,CAAC;IASlE,gEAAgE;IACnD,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,CAAC;IAStF,kFAAkF;IACrE,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGpD"}
|
|
@@ -7,7 +7,7 @@ import { ServerJob } from './jobs.js';
|
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
9
|
* ```ts ignore
|
|
10
|
-
* const job = await server.backups.create({ adapter: 'whisker',
|
|
10
|
+
* const job = await server.backups.create({ adapter: 'whisker', id });
|
|
11
11
|
* await job.wait();
|
|
12
12
|
* ```
|
|
13
13
|
*/
|
|
@@ -21,23 +21,23 @@ export class ServerBackupsManager {
|
|
|
21
21
|
async create(opts) {
|
|
22
22
|
const { data } = await this.node.postJson('/backup', {
|
|
23
23
|
adapter: opts.adapter,
|
|
24
|
-
|
|
24
|
+
id: opts.id,
|
|
25
25
|
ignore: opts.ignore ?? '',
|
|
26
26
|
});
|
|
27
27
|
return new ServerJob({ id: data.job_id }, this.node);
|
|
28
28
|
}
|
|
29
|
-
/** Restore a backup by its
|
|
30
|
-
async restore(
|
|
29
|
+
/** Restore a backup by its nanoid. Returns the job to track. */
|
|
30
|
+
async restore(backupId, opts) {
|
|
31
31
|
const body = { adapter: opts.adapter };
|
|
32
32
|
if (opts.truncateDirectory !== undefined)
|
|
33
33
|
body['truncate_directory'] = opts.truncateDirectory;
|
|
34
34
|
if (opts.downloadUrl !== undefined)
|
|
35
35
|
body['download_url'] = opts.downloadUrl;
|
|
36
|
-
const { data } = await this.node.postJson(`/backup/${
|
|
36
|
+
const { data } = await this.node.postJson(`/backup/${backupId}/restore`, body);
|
|
37
37
|
return new ServerJob({ id: data.job_id }, this.node);
|
|
38
38
|
}
|
|
39
|
-
/** Delete a backup by its
|
|
40
|
-
async delete(
|
|
41
|
-
await this.node.fetch(`/backup/${
|
|
39
|
+
/** Delete a backup by its nanoid. Treats an already-missing backup as success. */
|
|
40
|
+
async delete(backupId) {
|
|
41
|
+
await this.node.fetch(`/backup/${backupId}`, { method: 'DELETE' });
|
|
42
42
|
}
|
|
43
43
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ReactiveResource } from '../../reactive.js';
|
|
2
|
+
import { type SseState } from '../../sse.js';
|
|
2
3
|
import type { NanoID, PowerState } from '../../types.js';
|
|
3
4
|
import type { JobStatus } from './jobs.js';
|
|
4
5
|
/** Real-time resource utilization reported by the node. */
|
|
@@ -38,7 +39,7 @@ export interface JobLogEvent {
|
|
|
38
39
|
/** Payload for the `backup_completed` event. */
|
|
39
40
|
export interface BackupCompletedEvent {
|
|
40
41
|
/** The completed backup's id. */
|
|
41
|
-
|
|
42
|
+
id: string;
|
|
42
43
|
isSuccessful: boolean;
|
|
43
44
|
checksum: string;
|
|
44
45
|
checksumType: string;
|
|
@@ -72,7 +73,7 @@ export interface ServerConnectionEvents {
|
|
|
72
73
|
install_output: string;
|
|
73
74
|
/** An out-of-band status message from the daemon. */
|
|
74
75
|
daemon_message: string;
|
|
75
|
-
/** A backup finished; the payload's `
|
|
76
|
+
/** A backup finished; the payload's `id` identifies which one. */
|
|
76
77
|
backup_completed: BackupCompletedEvent;
|
|
77
78
|
/** A backup restore finished. */
|
|
78
79
|
backup_restore_completed: '';
|
|
@@ -83,13 +84,19 @@ export interface ServerConnectionEvents {
|
|
|
83
84
|
* Gated on `server.transfer.log`, so it never arrives for a viewer who lacks it.
|
|
84
85
|
*/
|
|
85
86
|
transfer_logs: string;
|
|
87
|
+
/** The stream to the daemon changed state. Emitted locally by the client, not by the daemon. */
|
|
88
|
+
connection_state: SseState;
|
|
86
89
|
}
|
|
87
90
|
/**
|
|
88
91
|
* A real-time SSE connection to a specific server on its Whisker node daemon.
|
|
89
92
|
*
|
|
90
93
|
* Emits typed events for console output, power state changes, and resource utilization.
|
|
91
94
|
* Also maintains a rolling buffer of console output lines in {@link output}, pre-populated
|
|
92
|
-
* with recent history fetched from the node on {@link
|
|
95
|
+
* with recent history fetched from the node on {@link open}.
|
|
96
|
+
*
|
|
97
|
+
* The stream reconnects on its own after the daemon restarts or the network drops. Track it
|
|
98
|
+
* through {@link state} or the `connection_state` event. After a reconnect, console lines the
|
|
99
|
+
* daemon still holds from the gap are appended to {@link output} and emitted as `console_output`.
|
|
93
100
|
*
|
|
94
101
|
* Obtain a connection via `Server.createConnection`.
|
|
95
102
|
*
|
|
@@ -112,12 +119,20 @@ export interface ServerConnectionEvents {
|
|
|
112
119
|
export declare class ServerConnection extends ReactiveResource {
|
|
113
120
|
private readonly serverId;
|
|
114
121
|
private readonly nodeUrl;
|
|
115
|
-
private readonly
|
|
122
|
+
private readonly getToken;
|
|
116
123
|
/** Maximum number of console output lines retained in {@link ServerConnection.output}. */
|
|
117
124
|
private static readonly maxOutputLines;
|
|
125
|
+
/** Console history lines fetched from the node on open and after each reconnect. */
|
|
126
|
+
private static readonly historyLines;
|
|
127
|
+
/**
|
|
128
|
+
* Whisker sends a keepalive every 20 seconds, so a stream silent for this long is dead even
|
|
129
|
+
* if the socket never closed.
|
|
130
|
+
*/
|
|
131
|
+
private static readonly idleTimeoutMs;
|
|
118
132
|
private readonly listeners;
|
|
119
133
|
private sse?;
|
|
120
|
-
|
|
134
|
+
/** Live console lines held back while the post-reconnect history is merged in. */
|
|
135
|
+
private pendingOutput?;
|
|
121
136
|
/**
|
|
122
137
|
* Rolling buffer of console output lines, capped at {@link ServerConnection.maxOutputLines}.
|
|
123
138
|
*
|
|
@@ -128,7 +143,9 @@ export declare class ServerConnection extends ReactiveResource {
|
|
|
128
143
|
*/
|
|
129
144
|
output: string[];
|
|
130
145
|
/** @internal */
|
|
131
|
-
constructor(serverId: NanoID, nodeUrl: string,
|
|
146
|
+
constructor(serverId: NanoID, nodeUrl: string, getToken: () => string);
|
|
147
|
+
/** State of the stream to the daemon. */
|
|
148
|
+
get state(): SseState;
|
|
132
149
|
/** `true` if the SSE connection is currently open. */
|
|
133
150
|
get isConnected(): boolean;
|
|
134
151
|
/**
|
|
@@ -139,7 +156,7 @@ export declare class ServerConnection extends ReactiveResource {
|
|
|
139
156
|
*
|
|
140
157
|
* Only one stream is maintained at a time.
|
|
141
158
|
*
|
|
142
|
-
* @param onError Optional callback invoked
|
|
159
|
+
* @param onError Optional callback invoked each time the stream drops or a connection attempt fails.
|
|
143
160
|
*/
|
|
144
161
|
open(onError?: (error: Error) => void): Promise<void>;
|
|
145
162
|
/** Close the SSE stream and stop receiving events. */
|
|
@@ -160,6 +177,16 @@ export declare class ServerConnection extends ReactiveResource {
|
|
|
160
177
|
off<K extends keyof ServerConnectionEvents>(event: K, handler: (payload: ServerConnectionEvents[K]) => void): void;
|
|
161
178
|
/** Remove all event handlers for all event types. */
|
|
162
179
|
removeAllListeners(): void;
|
|
180
|
+
private fetchHistory;
|
|
181
|
+
/**
|
|
182
|
+
* Fill in the console lines printed while the stream was down.
|
|
183
|
+
*
|
|
184
|
+
* Live lines are held back until the history arrives, because the history snapshot may
|
|
185
|
+
* already contain them. Lines that fell out of the daemon's history window are lost.
|
|
186
|
+
*/
|
|
187
|
+
private resyncOutput;
|
|
188
|
+
private appendOutput;
|
|
189
|
+
private emit;
|
|
163
190
|
/** Parse and dispatch a raw SSE event to registered handlers. */
|
|
164
191
|
private dispatch;
|
|
165
192
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../../src/src/resources/servers/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../../src/src/resources/servers/connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,11 @@ import { SseConnection } from '../../sse.js';
|
|
|
5
5
|
*
|
|
6
6
|
* Emits typed events for console output, power state changes, and resource utilization.
|
|
7
7
|
* Also maintains a rolling buffer of console output lines in {@link output}, pre-populated
|
|
8
|
-
* with recent history fetched from the node on {@link
|
|
8
|
+
* with recent history fetched from the node on {@link open}.
|
|
9
|
+
*
|
|
10
|
+
* The stream reconnects on its own after the daemon restarts or the network drops. Track it
|
|
11
|
+
* through {@link state} or the `connection_state` event. After a reconnect, console lines the
|
|
12
|
+
* daemon still holds from the gap are appended to {@link output} and emitted as `console_output`.
|
|
9
13
|
*
|
|
10
14
|
* Obtain a connection via `Server.createConnection`.
|
|
11
15
|
*
|
|
@@ -28,12 +32,20 @@ import { SseConnection } from '../../sse.js';
|
|
|
28
32
|
export class ServerConnection extends ReactiveResource {
|
|
29
33
|
serverId;
|
|
30
34
|
nodeUrl;
|
|
31
|
-
|
|
35
|
+
getToken;
|
|
32
36
|
/** Maximum number of console output lines retained in {@link ServerConnection.output}. */
|
|
33
37
|
static maxOutputLines = 1024;
|
|
38
|
+
/** Console history lines fetched from the node on open and after each reconnect. */
|
|
39
|
+
static historyLines = 100;
|
|
40
|
+
/**
|
|
41
|
+
* Whisker sends a keepalive every 20 seconds, so a stream silent for this long is dead even
|
|
42
|
+
* if the socket never closed.
|
|
43
|
+
*/
|
|
44
|
+
static idleTimeoutMs = 45_000;
|
|
34
45
|
listeners = new Map();
|
|
35
46
|
sse;
|
|
36
|
-
|
|
47
|
+
/** Live console lines held back while the post-reconnect history is merged in. */
|
|
48
|
+
pendingOutput;
|
|
37
49
|
/**
|
|
38
50
|
* Rolling buffer of console output lines, capped at {@link ServerConnection.maxOutputLines}.
|
|
39
51
|
*
|
|
@@ -44,15 +56,19 @@ export class ServerConnection extends ReactiveResource {
|
|
|
44
56
|
*/
|
|
45
57
|
output = [];
|
|
46
58
|
/** @internal */
|
|
47
|
-
constructor(serverId, nodeUrl,
|
|
59
|
+
constructor(serverId, nodeUrl, getToken) {
|
|
48
60
|
super();
|
|
49
61
|
this.serverId = serverId;
|
|
50
62
|
this.nodeUrl = nodeUrl;
|
|
51
|
-
this.
|
|
63
|
+
this.getToken = getToken;
|
|
64
|
+
}
|
|
65
|
+
/** State of the stream to the daemon. */
|
|
66
|
+
get state() {
|
|
67
|
+
return this.sse?.state ?? 'disconnected';
|
|
52
68
|
}
|
|
53
69
|
/** `true` if the SSE connection is currently open. */
|
|
54
70
|
get isConnected() {
|
|
55
|
-
return this.connected;
|
|
71
|
+
return this.state === 'connected';
|
|
56
72
|
}
|
|
57
73
|
/**
|
|
58
74
|
* Fetch console history and open the SSE stream.
|
|
@@ -62,36 +78,35 @@ export class ServerConnection extends ReactiveResource {
|
|
|
62
78
|
*
|
|
63
79
|
* Only one stream is maintained at a time.
|
|
64
80
|
*
|
|
65
|
-
* @param onError Optional callback invoked
|
|
81
|
+
* @param onError Optional callback invoked each time the stream drops or a connection attempt fails.
|
|
66
82
|
*/
|
|
67
83
|
async open(onError) {
|
|
68
|
-
this.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
this.output = json.data ?? [];
|
|
74
|
-
this.notify();
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
catch {
|
|
78
|
-
// History is best-effort - don't block the SSE connection
|
|
84
|
+
this.close();
|
|
85
|
+
const history = await this.fetchHistory();
|
|
86
|
+
if (history) {
|
|
87
|
+
this.output = history;
|
|
88
|
+
this.notify();
|
|
79
89
|
}
|
|
80
90
|
const url = `${this.nodeUrl}/api/servers/${this.serverId}/sse`;
|
|
81
|
-
|
|
82
|
-
this.
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
91
|
+
const sse = new SseConnection(url, this.getToken, { idleTimeoutMs: ServerConnection.idleTimeoutMs });
|
|
92
|
+
this.sse = sse;
|
|
93
|
+
let previous = sse.state;
|
|
94
|
+
sse.on('state', (state) => {
|
|
95
|
+
if (state === 'connected' && previous === 'reconnecting')
|
|
96
|
+
this.resyncOutput(sse);
|
|
97
|
+
previous = state;
|
|
87
98
|
this.notify();
|
|
88
|
-
|
|
99
|
+
this.emit('connection_state', state);
|
|
89
100
|
});
|
|
101
|
+
sse.connect((event, data) => this.dispatch(event, data), onError);
|
|
90
102
|
}
|
|
91
103
|
/** Close the SSE stream and stop receiving events. */
|
|
92
104
|
close() {
|
|
93
|
-
this.sse
|
|
94
|
-
this.
|
|
105
|
+
const sse = this.sse;
|
|
106
|
+
this.sse = undefined;
|
|
107
|
+
this.pendingOutput = undefined;
|
|
108
|
+
sse?.disconnect();
|
|
109
|
+
sse?.removeAllListeners();
|
|
95
110
|
}
|
|
96
111
|
/**
|
|
97
112
|
* Register a handler for a typed server event.
|
|
@@ -121,6 +136,47 @@ export class ServerConnection extends ReactiveResource {
|
|
|
121
136
|
removeAllListeners() {
|
|
122
137
|
this.listeners.clear();
|
|
123
138
|
}
|
|
139
|
+
async fetchHistory() {
|
|
140
|
+
try {
|
|
141
|
+
const res = await fetch(`${this.nodeUrl}/api/servers/${this.serverId}/logs?size=${ServerConnection.historyLines}`, { headers: { Authorization: `Bearer ${this.getToken()}` } });
|
|
142
|
+
if (!res.ok)
|
|
143
|
+
return undefined;
|
|
144
|
+
const json = (await res.json());
|
|
145
|
+
return json.data ?? [];
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Fill in the console lines printed while the stream was down.
|
|
153
|
+
*
|
|
154
|
+
* Live lines are held back until the history arrives, because the history snapshot may
|
|
155
|
+
* already contain them. Lines that fell out of the daemon's history window are lost.
|
|
156
|
+
*/
|
|
157
|
+
async resyncOutput(sse) {
|
|
158
|
+
const pending = [];
|
|
159
|
+
this.pendingOutput = pending;
|
|
160
|
+
const history = await this.fetchHistory();
|
|
161
|
+
if (this.sse !== sse || this.pendingOutput !== pending)
|
|
162
|
+
return;
|
|
163
|
+
this.pendingOutput = undefined;
|
|
164
|
+
const missed = history ? history.slice(overlapLength(this.output, history)) : [];
|
|
165
|
+
const live = history ? pending.slice(overlapLength(history, pending)) : pending;
|
|
166
|
+
for (const line of [...missed, ...live])
|
|
167
|
+
this.appendOutput(line);
|
|
168
|
+
}
|
|
169
|
+
appendOutput(line) {
|
|
170
|
+
this.output.push(line);
|
|
171
|
+
if (this.output.length > ServerConnection.maxOutputLines) {
|
|
172
|
+
this.output.shift();
|
|
173
|
+
}
|
|
174
|
+
this.notify();
|
|
175
|
+
this.emit('console_output', line);
|
|
176
|
+
}
|
|
177
|
+
emit(event, payload) {
|
|
178
|
+
this.listeners.get(event)?.forEach((h) => h(payload));
|
|
179
|
+
}
|
|
124
180
|
/** Parse and dispatch a raw SSE event to registered handlers. */
|
|
125
181
|
dispatch(rawEvent, rawData) {
|
|
126
182
|
// backup_completed is emitted per backup as `backup_completed:<id>`; the id is also in
|
|
@@ -136,11 +192,6 @@ export class ServerConnection extends ReactiveResource {
|
|
|
136
192
|
if (typeof parsed !== 'string')
|
|
137
193
|
return;
|
|
138
194
|
payload = parsed;
|
|
139
|
-
this.output.push(payload);
|
|
140
|
-
if (this.output.length > ServerConnection.maxOutputLines) {
|
|
141
|
-
this.output.shift();
|
|
142
|
-
}
|
|
143
|
-
this.notify();
|
|
144
195
|
break;
|
|
145
196
|
}
|
|
146
197
|
case 'status': {
|
|
@@ -210,10 +261,10 @@ export class ServerConnection extends ReactiveResource {
|
|
|
210
261
|
break;
|
|
211
262
|
}
|
|
212
263
|
case 'backup_completed': {
|
|
213
|
-
if (typeof parsed?.
|
|
264
|
+
if (typeof parsed?.id !== 'string')
|
|
214
265
|
return;
|
|
215
266
|
payload = {
|
|
216
|
-
|
|
267
|
+
id: parsed.id,
|
|
217
268
|
isSuccessful: Boolean(parsed.is_successful),
|
|
218
269
|
checksum: typeof parsed.checksum === 'string' ? parsed.checksum : '',
|
|
219
270
|
checksumType: typeof parsed.checksum_type === 'string' ? parsed.checksum_type : '',
|
|
@@ -228,7 +279,29 @@ export class ServerConnection extends ReactiveResource {
|
|
|
228
279
|
catch {
|
|
229
280
|
return;
|
|
230
281
|
}
|
|
231
|
-
|
|
232
|
-
|
|
282
|
+
if (event === 'console_output') {
|
|
283
|
+
const line = payload;
|
|
284
|
+
if (this.pendingOutput)
|
|
285
|
+
this.pendingOutput.push(line);
|
|
286
|
+
else
|
|
287
|
+
this.appendOutput(line);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
this.emit(event, payload);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
/** Length of the longest suffix of `head` that is also a prefix of `tail`. */
|
|
294
|
+
function overlapLength(head, tail) {
|
|
295
|
+
for (let k = Math.min(head.length, tail.length); k > 0; k--) {
|
|
296
|
+
let match = true;
|
|
297
|
+
for (let i = 0; i < k; i++) {
|
|
298
|
+
if (head[head.length - k + i] !== tail[i]) {
|
|
299
|
+
match = false;
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
if (match)
|
|
304
|
+
return k;
|
|
233
305
|
}
|
|
306
|
+
return 0;
|
|
234
307
|
}
|
|
@@ -172,7 +172,7 @@ export class Server extends ReactiveResource {
|
|
|
172
172
|
*/
|
|
173
173
|
async createConnection() {
|
|
174
174
|
const nodeUrl = await this.resolveNodeUrl();
|
|
175
|
-
return new ServerConnection(this.id, nodeUrl, this.http.getToken());
|
|
175
|
+
return new ServerConnection(this.id, nodeUrl, () => this.http.getToken());
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
function parseStatus(data) {
|
package/esm/src/sse.d.ts
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { TypedEmitter } from './emitter.js';
|
|
2
|
+
/**
|
|
3
|
+
* State of an {@link SseConnection}.
|
|
4
|
+
*
|
|
5
|
+
* `reconnecting` covers both the backoff wait and the retry request. `error` is terminal: the
|
|
6
|
+
* stream was refused with a status a retry cannot fix, or reconnecting is turned off.
|
|
7
|
+
*/
|
|
8
|
+
export type SseState = 'disconnected' | 'connecting' | 'connected' | 'reconnecting' | 'error';
|
|
9
|
+
/** Events emitted by {@link SseConnection}. */
|
|
10
|
+
export interface SseConnectionEvents {
|
|
11
|
+
/** The connection state changed. */
|
|
12
|
+
state: SseState;
|
|
13
|
+
}
|
|
14
|
+
/** Options for {@link SseConnection}. */
|
|
15
|
+
export interface SseOptions {
|
|
16
|
+
/** Reconnect after the stream drops or a connection attempt fails. Defaults to `true`. */
|
|
17
|
+
reconnect?: boolean;
|
|
18
|
+
/** Delay before the first reconnect attempt. Doubles per failed attempt. Defaults to 1 second. */
|
|
19
|
+
minReconnectDelayMs?: number;
|
|
20
|
+
/** Upper bound for the reconnect delay. Defaults to 30 seconds. */
|
|
21
|
+
maxReconnectDelayMs?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Treat the stream as dead after this long without receiving any bytes, and reconnect.
|
|
24
|
+
*
|
|
25
|
+
* A connection that dies without closing (lost network, dropped NAT entry) otherwise stays
|
|
26
|
+
* `connected` forever. Only set this against a server that sends periodic keepalives,
|
|
27
|
+
* comfortably above their interval. `0` disables it, which is the default.
|
|
28
|
+
*/
|
|
29
|
+
idleTimeoutMs?: number;
|
|
30
|
+
}
|
|
3
31
|
/**
|
|
4
32
|
* A generic, `fetch`-based Server-Sent Events client.
|
|
5
33
|
*
|
|
@@ -7,9 +35,13 @@ export type SseState = 'disconnected' | 'connecting' | 'connected' | 'error';
|
|
|
7
35
|
* header, making it compatible with bearer token auth in all environments
|
|
8
36
|
* (browser, Deno, Node.js).
|
|
9
37
|
*
|
|
38
|
+
* Like `EventSource`, it reconnects with exponential backoff whenever the stream ends without
|
|
39
|
+
* {@link disconnect} being called, including a clean close by the server.
|
|
40
|
+
*
|
|
10
41
|
* @example
|
|
11
42
|
* ```ts ignore
|
|
12
43
|
* const sse = new SseConnection('https://panel.example.com/v1/sse', token);
|
|
44
|
+
* sse.on('state', (state) => console.log('SSE is', state));
|
|
13
45
|
* sse.connect(
|
|
14
46
|
* (event, data) => console.log(event, data),
|
|
15
47
|
* (err) => console.error('SSE error:', err),
|
|
@@ -18,16 +50,22 @@ export type SseState = 'disconnected' | 'connecting' | 'connected' | 'error';
|
|
|
18
50
|
* sse.disconnect();
|
|
19
51
|
* ```
|
|
20
52
|
*/
|
|
21
|
-
export declare class SseConnection {
|
|
53
|
+
export declare class SseConnection extends TypedEmitter<SseConnectionEvents> {
|
|
22
54
|
private readonly url;
|
|
23
55
|
private token;
|
|
24
56
|
private abortController?;
|
|
57
|
+
private reconnectTimer?;
|
|
25
58
|
private _state;
|
|
59
|
+
private attempt;
|
|
60
|
+
private readonly options;
|
|
26
61
|
/**
|
|
27
|
-
* @param url
|
|
28
|
-
* @param token
|
|
62
|
+
* @param url The full URL to connect to.
|
|
63
|
+
* @param token Bearer token used in the `Authorization` header, or a function returning the
|
|
64
|
+
* current one. A function is read on every attempt, so reconnects pick up a
|
|
65
|
+
* refreshed token.
|
|
66
|
+
* @param options Reconnect and idle-timeout behavior.
|
|
29
67
|
*/
|
|
30
|
-
constructor(url: string, token: string);
|
|
68
|
+
constructor(url: string, token: string | (() => string), options?: SseOptions);
|
|
31
69
|
/** Update the bearer token for subsequent reconnections. */
|
|
32
70
|
updateToken(token: string): void;
|
|
33
71
|
/** Current connection state. */
|
|
@@ -37,16 +75,30 @@ export declare class SseConnection {
|
|
|
37
75
|
/**
|
|
38
76
|
* Open the SSE connection and begin streaming events.
|
|
39
77
|
*
|
|
40
|
-
* This method is **non-blocking**: it starts the connection and returns immediately
|
|
41
|
-
*
|
|
42
|
-
*
|
|
78
|
+
* This method is **non-blocking**: it starts the connection and returns immediately.
|
|
79
|
+
* Events are delivered asynchronously via the `onEvent` callback, and state changes via the
|
|
80
|
+
* `state` event.
|
|
43
81
|
*
|
|
44
82
|
* @param onEvent Callback invoked for each received SSE event, with the event name and raw data string.
|
|
45
|
-
* @param onError Optional callback invoked
|
|
83
|
+
* @param onError Optional callback invoked each time a connection attempt fails or an open stream
|
|
84
|
+
* is lost (not called on intentional disconnect). Reconnecting continues unless
|
|
85
|
+
* {@link state} is `error`.
|
|
46
86
|
*/
|
|
47
87
|
connect(onEvent: (event: string, data: string) => void, onError?: (error: Error) => void): void;
|
|
48
|
-
/** Close the SSE connection and stop receiving events. */
|
|
88
|
+
/** Close the SSE connection, cancel any pending reconnect, and stop receiving events. */
|
|
49
89
|
disconnect(): void;
|
|
90
|
+
private open;
|
|
91
|
+
/**
|
|
92
|
+
* Exponential backoff with jitter, so clients that lost the same server do not all retry at
|
|
93
|
+
* the same instant when it comes back.
|
|
94
|
+
*/
|
|
95
|
+
private nextReconnectDelay;
|
|
96
|
+
/**
|
|
97
|
+
* 401 is retryable because the token is re-read on every attempt and may have been refreshed
|
|
98
|
+
* in the meantime. Other client errors (403, 404, ...) will not change on their own.
|
|
99
|
+
*/
|
|
100
|
+
private static isRetryableStatus;
|
|
101
|
+
private setState;
|
|
50
102
|
/** Parse the raw `ReadableStream` body into SSE frames, calling `onEvent` for each complete frame. */
|
|
51
103
|
private readStream;
|
|
52
104
|
}
|
package/esm/src/sse.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/src/sse.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/src/sse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,GAAG,cAAc,GAAG,OAAO,CAAC;AAE9F,+CAA+C;AAC/C,MAAM,WAAW,mBAAmB;IACnC,oCAAoC;IACpC,KAAK,EAAE,QAAQ,CAAC;CAChB;AAED,yCAAyC;AACzC,MAAM,WAAW,UAAU;IAC1B,0FAA0F;IAC1F,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kGAAkG;IAClG,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mEAAmE;IACnE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,aAAc,SAAQ,YAAY,CAAC,mBAAmB,CAAC;IAelE,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,KAAK;IAfd,OAAO,CAAC,eAAe,CAAC,CAAkB;IAC1C,OAAO,CAAC,cAAc,CAAC,CAAgC;IACvD,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAE/C;;;;;;OAMG;gBAEe,GAAG,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,EACtC,OAAO,GAAE,UAAe;IAYzB,4DAA4D;IACrD,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIvC,gCAAgC;IAChC,IAAW,KAAK,IAAI,QAAQ,CAE3B;IAED,mDAAmD;IACnD,IAAW,WAAW,IAAI,OAAO,CAEhC;IAED;;;;;;;;;;;OAWG;IACI,OAAO,CACb,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,EAC9C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAC9B,IAAI;IAMP,yFAAyF;IAClF,UAAU,IAAI,IAAI;IAQzB,OAAO,CAAC,IAAI;IA2EZ;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAO1B;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAIhC,OAAO,CAAC,QAAQ;IAMhB,sGAAsG;YACxF,UAAU;CAqCxB"}
|