or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

host-client.mdindex.mdinstance-client.mdmanager-client.mdsequence-client.mdtopics.md

manager-client.mddocs/

0

# Manager Operations

1

2

The ManagerClient provides advanced operations for multi-hub environments including hub management, distributed store operations, and cross-hub monitoring.

3

4

## Capabilities

5

6

### Manager Client Creation

7

8

Create a ManagerClient for advanced Hub management operations.

9

10

```typescript { .api }

11

/**

12

* Creates a new ManagerClient instance for advanced Hub management

13

* @param apiBase - Base URL for the Manager API (e.g., "http://localhost:8001/api/v1")

14

* @param utils - Optional custom ClientUtils instance for advanced configuration

15

*/

16

class ManagerClient implements ClientProvider {

17

constructor(apiBase: string, utils?: ClientUtils);

18

19

readonly apiBase: string;

20

readonly client: ClientUtils;

21

}

22

```

23

24

**Usage Example:**

25

26

```typescript

27

import { ManagerClient } from "@scramjet/api-client";

28

29

const manager = new ManagerClient("http://localhost:8001/api/v1");

30

```

31

32

### Hub Management

33

34

Manage multiple Transform Hub instances in a distributed environment.

35

36

```typescript { .api }

37

/**

38

* Gets information about all connected Hubs

39

* @returns Promise resolving to array of Hub information

40

*/

41

getHosts(): Promise<MRestAPI.GetHostInfoResponse[]>;

42

43

/**

44

* Creates a HostClient for a specific Hub

45

* @param id - Hub identifier

46

* @param hostApiBase - Optional API base path for the Hub (defaults to "/api/v1")

47

* @returns HostClient instance configured for the specified Hub

48

*/

49

getHostClient(id: string, hostApiBase?: string): HostClient;

50

51

/**

52

* Deletes a Hub from the Manager

53

* @param id - Hub identifier

54

* @param force - Whether to force deletion even if Hub has running instances

55

* @returns Promise resolving to deletion result

56

*/

57

deleteHub(id: string, force: boolean): Promise<MRestAPI.HubDeleteResponse>;

58

59

/**

60

* Disconnects Hubs based on specified criteria

61

* @param opts - Disconnection options and criteria

62

* @returns Promise resolving to disconnection results

63

*/

64

disconnectHubs(opts: MRestAPI.PostDisconnectPayload): Promise<MRestAPI.PostDisconnectResponse>;

65

```

66

67

**Usage Examples:**

68

69

```typescript

70

// List all connected Hubs

71

const hubs = await manager.getHosts();

72

console.log(`Connected to ${hubs.length} Hubs:`);

73

hubs.forEach(hub => {

74

console.log(`- ${hub.id}: ${hub.address} (${hub.status})`);

75

});

76

77

// Get a client for a specific Hub

78

const specificHub = manager.getHostClient("hub-001");

79

const sequences = await specificHub.listSequences();

80

81

// Remove a disconnected Hub

82

await manager.deleteHub("hub-002", true);

83

```

84

85

### Cross-Hub Operations

86

87

Query and manage resources across all connected Hubs.

88

89

```typescript { .api }

90

/**

91

* Gets all sequences across all connected Hubs

92

* @returns Promise resolving to comprehensive sequence list

93

*/

94

getAllSequences(): Promise<MRestAPI.GetSequencesResponse>;

95

96

/**

97

* Gets sequences from the Manager's perspective

98

* @returns Promise resolving to Manager-tracked sequences

99

*/

100

getSequences(): Promise<MRestAPI.GetSequencesResponse>;

101

102

/**

103

* Gets all instances across all connected Hubs

104

* @returns Promise resolving to comprehensive instance list

105

*/

106

getInstances(): Promise<MRestAPI.GetInstancesResponse>;

107

108

/**

109

* Gets all topics across all connected Hubs

110

* @returns Promise resolving to comprehensive topics list

111

*/

112

getTopics(): Promise<MRestAPI.GetTopicsResponse>;

113

```

114

115

**Usage Examples:**

116

117

```typescript

118

// Get global view of all resources

119

const allSequences = await manager.getAllSequences();

120

console.log(`Total sequences across all Hubs: ${allSequences.length}`);

121

122

const allInstances = await manager.getInstances();

123

const runningInstances = allInstances.filter(i => i.status === "running");

124

console.log(`Running instances: ${runningInstances.length}/${allInstances.length}`);

125

126

// Find instances by sequence name across all Hubs

127

const targetSequences = allSequences.filter(s => s.config.name === "data-processor");

128

for (const seq of targetSequences) {

129

console.log(`Hub ${seq.hubId}: sequence ${seq.id} has ${seq.instances.length} instances`);

130

}

131

```

132

133

### Distributed Store Operations

134

135

Manage shared storage across the Hub network.

136

137

```typescript { .api }

138

/**

139

* Gets all items from the distributed store

140

* @returns Promise resolving to store items list

141

*/

142

getStoreItems(): Promise<MRestAPI.GetStoreItemsResponse>;

143

144

/**

145

* Uploads an item to the distributed store

146

* @param sequencePackage - Stream containing the data to store

147

* @param id - Optional identifier for the stored item

148

* @returns Promise resolving to store operation result

149

*/

150

putStoreItem(

151

sequencePackage: Readable,

152

id?: string

153

): Promise<MRestAPI.PutStoreItemResponse>;

154

155

/**

156

* Deletes an item from the distributed store

157

* @param id - Identifier of the item to delete

158

* @returns Promise resolving when deletion is complete

159

*/

160

deleteStoreItem(id: string): Promise<void>;

161

162

/**

163

* Clears all items from the distributed store

164

* @returns Promise resolving when store is cleared

165

*/

166

clearStore(): Promise<void>;

167

```

168

169

**Usage Examples:**

170

171

```typescript

172

import fs from "fs";

173

174

// Upload a sequence package to shared store

175

const packageStream = fs.createReadStream("./shared-utility.tar.gz");

176

const storeResult = await manager.putStoreItem(packageStream, "shared-utility-v1.0");

177

console.log(`Stored item: ${storeResult.id}`);

178

179

// List all stored items

180

const storeItems = await manager.getStoreItems();

181

storeItems.forEach(item => {

182

console.log(`- ${item.id}: ${item.size} bytes, uploaded ${item.created}`);

183

});

184

185

// Clean up old items

186

const oldItems = storeItems.filter(item =>

187

new Date(item.created) < new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) // 30 days

188

);

189

for (const item of oldItems) {

190

await manager.deleteStoreItem(item.id);

191

console.log(`Removed old item: ${item.id}`);

192

}

193

```

194

195

### System Monitoring

196

197

Monitor system-wide metrics and health across all Hubs.

198

199

```typescript { .api }

200

/**

201

* Gets Manager version information

202

* @returns Promise resolving to version details

203

*/

204

getVersion(): Promise<MRestAPI.GetVersionResponse>;

205

206

/**

207

* Gets aggregate load statistics across all Hubs

208

* @returns Promise resolving to load statistics

209

*/

210

getLoad(): Promise<LoadCheckStat>;

211

212

/**

213

* Gets Manager configuration

214

* @returns Promise resolving to configuration data

215

*/

216

getConfig(): Promise<any>;

217

```

218

219

### Streaming Operations

220

221

Access aggregated log and audit streams from all Hubs.

222

223

```typescript { .api }

224

/**

225

* Gets aggregated log stream from all connected Hubs

226

* @param requestInit - Optional request configuration

227

* @returns Promise resolving to aggregated log stream

228

*/

229

getLogStream(requestInit?: RequestInit): Promise<Readable>;

230

231

/**

232

* Gets aggregated audit stream from all connected Hubs

233

* @param requestInit - Optional request configuration

234

* @returns Promise resolving to aggregated audit stream

235

*/

236

getAuditStream(requestInit?: RequestInit): Promise<Readable>;

237

238

/**

239

* Sends data to a named topic across the Hub network

240

* @param topic - Topic name

241

* @param stream - Data stream to send

242

* @param requestInit - Optional request configuration

243

* @param contentType - Content type

244

* @param end - Whether to signal end of stream

245

* @returns Promise resolving to send result

246

*/

247

sendNamedData<T>(

248

topic: string,

249

stream: Parameters<HttpClient["sendStream"]>[1],

250

requestInit?: RequestInit,

251

contentType?: string,

252

end?: boolean

253

): Promise<T>;

254

255

/**

256

* Gets data stream from a named topic across the Hub network

257

* @param topic - Topic name

258

* @param requestInit - Optional request configuration

259

* @returns Promise resolving to topic data stream

260

*/

261

getNamedData(topic: string, requestInit?: RequestInit): Promise<Readable>;

262

```

263

264

**Usage Examples:**

265

266

```typescript

267

// Monitor aggregate system logs

268

const logStream = await manager.getLogStream();

269

logStream.on('data', (chunk) => {

270

const logEntry = JSON.parse(chunk.toString());

271

console.log(`[${logEntry.hubId}] ${logEntry.level}: ${logEntry.message}`);

272

});

273

274

// Broadcast configuration updates

275

const configStream = Readable.from([JSON.stringify({

276

action: "update-config",

277

config: { logLevel: "debug" }

278

})]);

279

await manager.sendNamedData("system-config", configStream);

280

```

281

282

## Response Types

283

284

```typescript { .api }

285

interface MRestAPI {

286

GetHostInfoResponse: {

287

id: string;

288

address: string;

289

status: "connected" | "disconnected" | "error";

290

version: string;

291

load: {

292

avgLoad: number[];

293

currentLoad: number;

294

memUsage: number;

295

};

296

sequences: number;

297

instances: number;

298

uptime: number;

299

[key: string]: any;

300

};

301

302

GetSequencesResponse: Array<{

303

id: string;

304

hubId: string;

305

config: {

306

name: string;

307

version: string;

308

[key: string]: any;

309

};

310

instances: string[];

311

}>;

312

313

GetInstancesResponse: Array<{

314

id: string;

315

hubId: string;

316

sequenceId: string;

317

status: "starting" | "running" | "stopping" | "stopped" | "crashed";

318

created: string;

319

[key: string]: any;

320

}>;

321

322

GetTopicsResponse: Array<{

323

id: string;

324

hubId: string;

325

contentType: string;

326

subscribers: number;

327

[key: string]: any;

328

}>;

329

330

GetStoreItemsResponse: Array<{

331

id: string;

332

size: number;

333

created: string;

334

checksum: string;

335

[key: string]: any;

336

}>;

337

338

PutStoreItemResponse: {

339

id: string;

340

size: number;

341

checksum: string;

342

};

343

344

HubDeleteResponse: {

345

id: string;

346

message: string;

347

deleted: boolean;

348

};

349

350

PostDisconnectPayload: {

351

criteria: {

352

status?: "disconnected" | "error";

353

olderThan?: string; // ISO date string

354

hubIds?: string[];

355

};

356

force?: boolean;

357

};

358

359

PostDisconnectResponse: {

360

disconnected: string[];

361

errors: Array<{

362

hubId: string;

363

error: string;

364

}>;

365

};

366

367

GetVersionResponse: {

368

version: string;

369

build?: string;

370

components: {

371

[componentName: string]: string;

372

};

373

};

374

}

375

```

376

377

## Advanced Patterns

378

379

### Multi-Hub Deployment Management

380

381

```typescript

382

class MultiHubDeployment {

383

constructor(private manager: ManagerClient) {}

384

385

async deployToAllHubs(packagePath: string, config: any) {

386

const hubs = await this.manager.getHosts();

387

const deployments = [];

388

389

for (const hub of hubs.filter(h => h.status === "connected")) {

390

try {

391

const hostClient = this.manager.getHostClient(hub.id);

392

const packageStream = fs.createReadStream(packagePath);

393

const sequence = await hostClient.sendSequence(packageStream);

394

const instance = await sequence.start(config);

395

396

deployments.push({

397

hubId: hub.id,

398

sequenceId: sequence.id,

399

instanceId: instance.id

400

});

401

} catch (error) {

402

console.error(`Failed to deploy to hub ${hub.id}:`, error.message);

403

}

404

}

405

406

return deployments;

407

}

408

409

async scaleAcrossHubs(sequenceName: string, targetInstances: number) {

410

const sequences = await this.manager.getAllSequences();

411

const targetSequences = sequences.filter(s => s.config.name === sequenceName);

412

413

for (const seq of targetSequences) {

414

const currentInstances = seq.instances.length;

415

const needed = Math.max(0, targetInstances - currentInstances);

416

417

if (needed > 0) {

418

const hubClient = this.manager.getHostClient(seq.hubId);

419

const sequenceClient = hubClient.getSequenceClient(seq.id);

420

421

for (let i = 0; i < needed; i++) {

422

await sequenceClient.start({});

423

}

424

}

425

}

426

}

427

}

428

```

429

430

### Distributed Load Monitoring

431

432

```typescript

433

async function monitorClusterHealth(manager: ManagerClient) {

434

const hubs = await manager.getHosts();

435

const aggregateLoad = await manager.getLoad();

436

437

console.log(`Cluster Overview:`);

438

console.log(`- Total Hubs: ${hubs.length}`);

439

console.log(`- Aggregate Load: ${aggregateLoad.currentLoad.toFixed(2)}`);

440

console.log(`- Memory Usage: ${aggregateLoad.memUsage.toFixed(1)}%`);

441

442

// Check for overloaded hubs

443

const overloadedHubs = hubs.filter(hub => hub.load.currentLoad > 0.8);

444

if (overloadedHubs.length > 0) {

445

console.log(`⚠️ Overloaded Hubs (>80% CPU):`);

446

overloadedHubs.forEach(hub => {

447

console.log(` - ${hub.id}: ${(hub.load.currentLoad * 100).toFixed(1)}% CPU`);

448

});

449

}

450

451

// Check for disconnected hubs

452

const disconnectedHubs = hubs.filter(hub => hub.status !== "connected");

453

if (disconnectedHubs.length > 0) {

454

console.log(`❌ Disconnected Hubs:`);

455

disconnectedHubs.forEach(hub => {

456

console.log(` - ${hub.id}: ${hub.status}`);

457

});

458

}

459

}

460

```