rosinterface 1.3.0 → 1.3.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.
Files changed (78) hide show
  1. package/dist/cli/Generate.js +20 -1
  2. package/dist/cli/Generate.js.map +1 -1
  3. package/dist/cli/SchemaInferrer.d.ts +9 -0
  4. package/dist/cli/SchemaInferrer.js +22 -3
  5. package/dist/cli/SchemaInferrer.js.map +1 -1
  6. package/dist/client/CommandBuilder.d.ts +337 -2
  7. package/dist/client/CommandBuilder.js +483 -15
  8. package/dist/client/CommandBuilder.js.map +1 -1
  9. package/dist/client/MikrotikClient.d.ts +349 -1
  10. package/dist/client/MikrotikClient.js +364 -1
  11. package/dist/client/MikrotikClient.js.map +1 -1
  12. package/dist/client/MikrotikPool.d.ts +30 -0
  13. package/dist/client/MikrotikPool.js +31 -1
  14. package/dist/client/MikrotikPool.js.map +1 -1
  15. package/dist/client/MikrotikSwarm.d.ts +167 -0
  16. package/dist/client/MikrotikSwarm.js +178 -1
  17. package/dist/client/MikrotikSwarm.js.map +1 -1
  18. package/dist/client/MikrotikTransaction.d.ts +27 -0
  19. package/dist/client/MikrotikTransaction.js +28 -0
  20. package/dist/client/MikrotikTransaction.js.map +1 -1
  21. package/dist/client/ResultParser.d.ts +19 -0
  22. package/dist/client/ResultParser.js +31 -0
  23. package/dist/client/ResultParser.js.map +1 -1
  24. package/dist/client/SnapshotSubscription.d.ts +139 -0
  25. package/dist/client/SnapshotSubscription.js +169 -0
  26. package/dist/client/SnapshotSubscription.js.map +1 -1
  27. package/dist/core/Auth.d.ts +31 -0
  28. package/dist/core/Auth.js +46 -1
  29. package/dist/core/Auth.js.map +1 -1
  30. package/dist/core/CircuitBreaker.d.ts +26 -0
  31. package/dist/core/CircuitBreaker.js +26 -0
  32. package/dist/core/CircuitBreaker.js.map +1 -1
  33. package/dist/core/HttpConstants.d.ts +29 -16
  34. package/dist/core/HttpConstants.js +23 -7
  35. package/dist/core/HttpConstants.js.map +1 -1
  36. package/dist/core/OfflineQueue.d.ts +16 -0
  37. package/dist/core/OfflineQueue.js +10 -0
  38. package/dist/core/OfflineQueue.js.map +1 -1
  39. package/dist/core/RateLimiter.d.ts +24 -0
  40. package/dist/core/RateLimiter.js +43 -7
  41. package/dist/core/RateLimiter.js.map +1 -1
  42. package/dist/core/RestProtocol.d.ts +9 -0
  43. package/dist/core/RestProtocol.js +16 -1
  44. package/dist/core/RestProtocol.js.map +1 -1
  45. package/dist/core/RosError.d.ts +15 -0
  46. package/dist/core/RosError.js +36 -1
  47. package/dist/core/RosError.js.map +1 -1
  48. package/dist/core/RosProtocol.d.ts +21 -0
  49. package/dist/core/RosProtocol.js +40 -1
  50. package/dist/core/RosProtocol.js.map +1 -1
  51. package/dist/core/SchemaMapper.d.ts +41 -0
  52. package/dist/core/SchemaMapper.js +57 -2
  53. package/dist/core/SchemaMapper.js.map +1 -1
  54. package/dist/core/SocketClient.d.ts +34 -0
  55. package/dist/core/SocketClient.js +51 -3
  56. package/dist/core/SocketClient.js.map +1 -1
  57. package/dist/features/FileManager.d.ts +50 -0
  58. package/dist/features/FileManager.js +72 -6
  59. package/dist/features/FileManager.js.map +1 -1
  60. package/dist/features/LiveCollection.d.ts +51 -0
  61. package/dist/features/LiveCollection.js +69 -0
  62. package/dist/features/LiveCollection.js.map +1 -1
  63. package/dist/features/PrometheusExporter.d.ts +18 -1
  64. package/dist/features/PrometheusExporter.js +21 -1
  65. package/dist/features/PrometheusExporter.js.map +1 -1
  66. package/dist/index.d.ts +66 -0
  67. package/dist/index.js +78 -0
  68. package/dist/index.js.map +1 -1
  69. package/dist/types/index.d.ts +4 -0
  70. package/dist/types/index.js +24 -0
  71. package/dist/types/index.js.map +1 -1
  72. package/dist/utils/Helpers.d.ts +16 -0
  73. package/dist/utils/Helpers.js +17 -1
  74. package/dist/utils/Helpers.js.map +1 -1
  75. package/dist/utils/MikrotikCollection.d.ts +85 -0
  76. package/dist/utils/MikrotikCollection.js +97 -1
  77. package/dist/utils/MikrotikCollection.js.map +1 -1
  78. package/package.json +2 -2
@@ -38,29 +38,48 @@ const net = __importStar(require("net"));
38
38
  const tls = __importStar(require("tls"));
39
39
  const events_1 = require("events");
40
40
  const buffer_1 = require("buffer");
41
- const RosProtocol_1 = require("./RosProtocol");
41
+ const RosProtocol_1 = require("./RosProtocol"); // Asegúrate de tener este archivo
42
+ /**
43
+ * Low-level TCP/TLS Client.
44
+ * Responsibilities:
45
+ * 1. Transport Layer: Decides between 'net' (Plain) and 'tls' (Secure).
46
+ * 2. Event Handling: Manages socket errors, closures, and timeouts.
47
+ * 3. Framing: Buffers incoming raw bytes and splits them into valid MikroTik words.
48
+ */
42
49
  class SocketClient extends events_1.EventEmitter {
43
50
  constructor(options) {
44
51
  super();
52
+ // Union type to support both standard and secure sockets
45
53
  this.socket = null;
54
+ // State tracking
46
55
  this.connected = false;
56
+ // Buffer accumulator for handling TCP packet fragmentation
47
57
  this.receiveBuffer = buffer_1.Buffer.alloc(0);
48
58
  this.options = {
49
59
  timeout: 10,
50
- rejectUnauthorized: false,
60
+ rejectUnauthorized: false, // For development usually
51
61
  keepAlive: true,
52
62
  useTLS: false,
53
63
  ...options
54
64
  };
55
65
  }
66
+ /**
67
+ * Establishes the connection to the router.
68
+ * Supports both Plain TCP and TLS based on configuration.
69
+ * @returns Promise that resolves when the connection is fully established.
70
+ */
56
71
  connect() {
57
72
  return new Promise((resolve, reject) => {
58
73
  if (this.connected)
59
74
  return resolve();
75
+ // 1. Clean up any previous socket instance
60
76
  this.cleanup();
77
+ // 2. Calculate timeout in milliseconds
61
78
  const timeoutMs = (this.options.timeout || 10) * 1000;
79
+ // 3. LOGIC DECISION: TLS vs PLAIN TCP
62
80
  try {
63
81
  if (this.options.useTLS) {
82
+ // --- SECURE MODE (TLS) ---
64
83
  const tlsOptions = {
65
84
  host: this.options.host,
66
85
  port: this.options.port,
@@ -70,6 +89,7 @@ class SocketClient extends events_1.EventEmitter {
70
89
  this.socket = tls.connect(tlsOptions);
71
90
  }
72
91
  else {
92
+ // --- PLAIN MODE (TCP) ---
73
93
  this.socket = new net.Socket();
74
94
  this.socket.setTimeout(timeoutMs);
75
95
  this.socket.connect(this.options.port, this.options.host);
@@ -78,24 +98,30 @@ class SocketClient extends events_1.EventEmitter {
78
98
  catch (err) {
79
99
  return reject(err);
80
100
  }
101
+ // 4. Handle Connection Timeout (Handshake phase)
81
102
  this.socket.once('timeout', () => {
82
103
  const err = new Error(`Connection timed out after ${this.options.timeout} seconds`);
83
104
  this.destroy();
84
105
  reject(err);
85
106
  });
107
+ // 5. Optimization: Disable Nagle's Algorithm (Lower latency for small packets)
86
108
  this.socket.setNoDelay(true);
109
+ // 6. Keep-Alive
87
110
  if (this.options.keepAlive && this.socket instanceof net.Socket) {
88
111
  this.socket.setKeepAlive(true, 10000);
89
112
  }
113
+ // --- EVENT BINDING ---
90
114
  const connectEvent = this.options.useTLS ? 'secureConnect' : 'connect';
91
115
  this.socket.once(connectEvent, () => {
92
116
  this.connected = true;
117
+ // Clear initial timeout so we don't disconnect during operation
93
118
  if (this.socket)
94
119
  this.socket.setTimeout(0);
95
- this.emit('connect');
120
+ this.emit('connect'); // Notify MikrotikClient
96
121
  resolve();
97
122
  });
98
123
  this.socket.on('error', (err) => {
124
+ // If error happens during connection phase, reject the promise
99
125
  if (!this.connected) {
100
126
  reject(err);
101
127
  }
@@ -107,7 +133,9 @@ class SocketClient extends events_1.EventEmitter {
107
133
  this.connected = false;
108
134
  this.emit('close', hadError);
109
135
  });
136
+ // DATA RECEIVING LOOP
110
137
  this.socket.on('data', (chunk) => {
138
+ // Defensive programming
111
139
  const bufferChunk = buffer_1.Buffer.isBuffer(chunk)
112
140
  ? chunk
113
141
  : buffer_1.Buffer.from(chunk, 'utf8');
@@ -115,18 +143,29 @@ class SocketClient extends events_1.EventEmitter {
115
143
  });
116
144
  });
117
145
  }
146
+ /**
147
+ * Writes raw bytes to the socket stream.
148
+ */
118
149
  write(data) {
119
150
  if (!this.connected || !this.socket) {
120
151
  throw new Error('Socket is not connected. Call connect() first.');
121
152
  }
153
+ // Uncomment to see OUTGOING raw bytes
154
+ // console.log('>>> OUT [Buffer]:', data);
122
155
  this.socket.write(data);
123
156
  }
157
+ /**
158
+ * Gracefully closes the connection.
159
+ */
124
160
  close() {
125
161
  if (this.socket && !this.socket.destroyed) {
126
162
  this.socket.end();
127
163
  this.connected = false;
128
164
  }
129
165
  }
166
+ /**
167
+ * Forcefully destroys the connection.
168
+ */
130
169
  destroy() {
131
170
  if (this.socket && !this.socket.destroyed) {
132
171
  this.socket.destroy();
@@ -141,15 +180,24 @@ class SocketClient extends events_1.EventEmitter {
141
180
  }
142
181
  this.receiveBuffer = buffer_1.Buffer.alloc(0);
143
182
  }
183
+ /**
184
+ * CORE LOGIC: TCP Framing.
185
+ * Extracts valid MikroTik "Words" from the TCP stream.
186
+ */
144
187
  handleDataChunk(chunk) {
188
+ // Append new data
145
189
  this.receiveBuffer = buffer_1.Buffer.concat([this.receiveBuffer, chunk]);
190
+ // Loop to process as many words as possible
146
191
  while (this.receiveBuffer.length > 0) {
192
+ // Decode length using RosProtocol utility
147
193
  const lengthInfo = RosProtocol_1.RosProtocol.decodeLength(this.receiveBuffer);
194
+ // If we don't have enough bytes for the length header, wait for next packet
148
195
  if (!lengthInfo) {
149
196
  break;
150
197
  }
151
198
  const { length, byteLength } = lengthInfo;
152
199
  const totalPacketSize = byteLength + length;
200
+ // If we have the header but not the full body, wait.
153
201
  if (this.receiveBuffer.length < totalPacketSize) {
154
202
  break;
155
203
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SocketClient.js","sourceRoot":"","sources":["../../src/core/SocketClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SocketClient.js","sourceRoot":"","sources":["../../src/core/SocketClient.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,7 @@
1
1
  import { MikrotikClient } from '../client/MikrotikClient';
2
+ /**
3
+ * Represents a file object from RouterOS /file/print
4
+ */
2
5
  export interface IFileEntry {
3
6
  '.id': string;
4
7
  name: string;
@@ -7,16 +10,63 @@ export interface IFileEntry {
7
10
  'creation-time': string;
8
11
  contents?: string;
9
12
  }
13
+ /**
14
+ * **FileManager**
15
+ * * Advanced abstraction layer for file operations on RouterOS.
16
+ * Features:
17
+ * - Text File I/O (Read/Write scripts/logs).
18
+ * - System Backup & Restore management.
19
+ * - RSC Script Execution (Import).
20
+ * - Directory listing and cleaning.
21
+ */
10
22
  export declare class FileManager {
11
23
  private client;
12
24
  constructor(client: MikrotikClient);
25
+ /**
26
+ * Lists files on the router, optionally filtering by name.
27
+ * @param filterName Optional substring to filter files (e.g., ".backup")
28
+ */
13
29
  list(filterName?: string): Promise<IFileEntry[]>;
30
+ /**
31
+ * Checks if a file exists on the router.
32
+ */
14
33
  exists(fileName: string): Promise<boolean>;
34
+ /**
35
+ * Deletes a file or multiple files.
36
+ * @param fileName Name of the file (or array of names).
37
+ */
15
38
  delete(fileName: string | string[]): Promise<void>;
39
+ /**
40
+ * Writes text content to a file.
41
+ * Handles creation if it doesn't exist.
42
+ * * WARNING: RouterOS API has a limit for property values (~4MB in v7, less in v6).
43
+ * Do not use this for binary files (.npk) or massive logs.
44
+ */
16
45
  writeText(fileName: string, content: string): Promise<void>;
46
+ /**
47
+ * Reads text content from a file.
48
+ * @returns string content, or throws error if file is binary/too large.
49
+ */
17
50
  readText(fileName: string): Promise<string>;
51
+ /**
52
+ * Creates a System Backup (.backup) file.
53
+ * @param name Backup name (without extension).
54
+ * @param password Optional encryption password.
55
+ */
18
56
  createSystemBackup(name: string, password?: string): Promise<string>;
57
+ /**
58
+ * Restores a System Backup.
59
+ * DANGER: This will reboot the router.
60
+ */
19
61
  restoreSystemBackup(name: string, password?: string): Promise<void>;
62
+ /**
63
+ * Exports configuration to an RSC script file.
64
+ * @param name File name (e.g., "daily_export")
65
+ */
20
66
  createExport(name: string): Promise<string>;
67
+ /**
68
+ * Uploads a script (.rsc) and immediately executes it.
69
+ * Great for provisioning or mass updates.
70
+ */
21
71
  runScript(content: string, scriptName?: string): Promise<void>;
22
72
  }
@@ -1,10 +1,26 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FileManager = void 0;
4
+ /**
5
+ * **FileManager**
6
+ * * Advanced abstraction layer for file operations on RouterOS.
7
+ * Features:
8
+ * - Text File I/O (Read/Write scripts/logs).
9
+ * - System Backup & Restore management.
10
+ * - RSC Script Execution (Import).
11
+ * - Directory listing and cleaning.
12
+ */
4
13
  class FileManager {
5
14
  constructor(client) {
6
15
  this.client = client;
7
16
  }
17
+ // ==========================================
18
+ // CORE FILE OPERATIONS
19
+ // ==========================================
20
+ /**
21
+ * Lists files on the router, optionally filtering by name.
22
+ * @param filterName Optional substring to filter files (e.g., ".backup")
23
+ */
8
24
  async list(filterName) {
9
25
  const cmd = this.client.command('/file');
10
26
  const result = await cmd.print();
@@ -14,14 +30,23 @@ class FileManager {
14
30
  }
15
31
  return files;
16
32
  }
33
+ /**
34
+ * Checks if a file exists on the router.
35
+ */
17
36
  async exists(fileName) {
18
37
  const file = await this.client.command('/file')
19
38
  .where('name', fileName)
20
39
  .first();
21
40
  return !!file;
22
41
  }
42
+ /**
43
+ * Deletes a file or multiple files.
44
+ * @param fileName Name of the file (or array of names).
45
+ */
23
46
  async delete(fileName) {
24
47
  const targets = Array.isArray(fileName) ? fileName : [fileName];
48
+ // We need IDs to remove safely, or use 'remove [find where name=X]' logic
49
+ // But the API supports removing by ID mostly.
25
50
  for (const name of targets) {
26
51
  const file = await this.client.command('/file').where('name', name).first();
27
52
  if (file) {
@@ -30,37 +55,62 @@ class FileManager {
30
55
  }
31
56
  }
32
57
  }
58
+ // ==========================================
59
+ // TEXT I/O (Scripts, Configs, Hotspot)
60
+ // ==========================================
61
+ /**
62
+ * Writes text content to a file.
63
+ * Handles creation if it doesn't exist.
64
+ * * WARNING: RouterOS API has a limit for property values (~4MB in v7, less in v6).
65
+ * Do not use this for binary files (.npk) or massive logs.
66
+ */
33
67
  async writeText(fileName, content) {
34
- if (content.length > 1024 * 1024) {
68
+ if (content.length > 1024 * 1024) { // 1MB Guard
35
69
  console.warn(`[FileManager] Warning: Uploading ${content.length} bytes via API is risky.`);
36
70
  }
37
71
  const exists = await this.exists(fileName);
38
72
  if (!exists) {
73
+ // Trick: 'print file=name' creates an empty file
39
74
  await this.client.write('/file/print', {
40
75
  file: fileName,
41
- where: 'false'
42
- }).catch(() => { });
76
+ where: 'false' // Suppress output
77
+ }).catch(() => { }); // Ignore "interrupted" or empty return errors
78
+ // Wait a tiny bit for FS sync
43
79
  await new Promise(r => setTimeout(r, 200));
44
80
  }
81
+ // Update content
45
82
  await this.client.write('/file/set', {
46
- 'numbers': fileName,
83
+ 'numbers': fileName, // API allows name in numbers for some versions, but IDs are safer.
47
84
  'contents': content
48
85
  });
49
86
  console.log(`[FileManager] Saved: ${fileName}`);
50
87
  }
88
+ /**
89
+ * Reads text content from a file.
90
+ * @returns string content, or throws error if file is binary/too large.
91
+ */
51
92
  async readText(fileName) {
52
93
  const file = await this.client.command('/file').where('name', fileName).first();
53
94
  if (!file)
54
95
  throw new Error(`File '${fileName}' not found.`);
96
+ // RouterOS logic: If 'contents' is missing, the file is too big or binary.
55
97
  if (file.contents === undefined) {
56
98
  const size = Number(file.size);
57
- if (size > 4096) {
99
+ if (size > 4096) { // Heuristic: API often hides contents > 4KB (v6) or 64KB (v7)
58
100
  throw new Error(`File '${fileName}' is too large (${size} bytes) or binary to read via API. Use SFTP.`);
59
101
  }
60
- return '';
102
+ return ''; // Empty file
61
103
  }
62
104
  return file.contents;
63
105
  }
106
+ // ==========================================
107
+ // SYSTEM & AUTOMATION
108
+ // ==========================================
109
+ /**
110
+ * Creates a System Backup (.backup) file.
111
+ * @param name Backup name (without extension).
112
+ * @param password Optional encryption password.
113
+ */
64
114
  async createSystemBackup(name, password) {
65
115
  const fullName = `${name}.backup`;
66
116
  const params = { name: name };
@@ -70,6 +120,10 @@ class FileManager {
70
120
  await this.client.write('/system/backup/save', params);
71
121
  return fullName;
72
122
  }
123
+ /**
124
+ * Restores a System Backup.
125
+ * DANGER: This will reboot the router.
126
+ */
73
127
  async restoreSystemBackup(name, password) {
74
128
  console.warn(`[FileManager] RESTORING BACKUP ${name}. ROUTER WILL REBOOT.`);
75
129
  const params = { name: name };
@@ -77,15 +131,26 @@ class FileManager {
77
131
  params.password = password;
78
132
  await this.client.write('/system/backup/load', params);
79
133
  }
134
+ /**
135
+ * Exports configuration to an RSC script file.
136
+ * @param name File name (e.g., "daily_export")
137
+ */
80
138
  async createExport(name) {
81
139
  const fullName = name.endsWith('.rsc') ? name : `${name}.rsc`;
82
140
  console.log(`[FileManager] Exporting config to ${fullName}...`);
141
+ // /export file=name
83
142
  await this.client.write('/export', { file: name });
84
143
  return fullName;
85
144
  }
145
+ /**
146
+ * Uploads a script (.rsc) and immediately executes it.
147
+ * Great for provisioning or mass updates.
148
+ */
86
149
  async runScript(content, scriptName = 'temp_worker.rsc') {
87
150
  try {
151
+ // Upload
88
152
  await this.writeText(scriptName, content);
153
+ // Execute (/import)
89
154
  console.log(`[FileManager] Executing script: ${scriptName}...`);
90
155
  await this.client.write('/import', { 'file-name': scriptName });
91
156
  console.log(`[FileManager] Script executed successfully.`);
@@ -95,6 +160,7 @@ class FileManager {
95
160
  throw error;
96
161
  }
97
162
  finally {
163
+ // Cleanup (Optional: remove script after run)
98
164
  await this.delete(scriptName);
99
165
  }
100
166
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FileManager.js","sourceRoot":"","sources":["../../src/features/FileManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FileManager.js","sourceRoot":"","sources":["../../src/features/FileManager.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,69 @@
1
1
  import { MikrotikClient } from "../client/MikrotikClient";
2
2
  import { SnapshotSubscription, SnapshotDiff } from "../client/SnapshotSubscription";
3
+ /**
4
+ * Flexible callback definition.
5
+ * Can receive a standard Array OR a Diff object depending on configuration.
6
+ */
3
7
  export type SnapshotCallback<T> = (data: T[] | SnapshotDiff<T>) => void;
8
+ /**
9
+ * LiveCollection
10
+ * ==========================================
11
+ * Manages a real-time synchronized collection of items from the router.
12
+ *
13
+ * Instead of firing simple callbacks, it manages 'SnapshotSubscription' instances.
14
+ * This allows each subscriber to have their own Throttle settings and Diff modes.
15
+ *
16
+ * @template T The type of the items in the collection.
17
+ */
4
18
  export declare class LiveCollection<T extends Record<string, any>> {
5
19
  private client;
6
20
  private path;
7
21
  private query;
22
+ /** Internal storage mapped by item ID (e.g., "*1A") */
8
23
  private localCache;
24
+ /** The active low-level subscription object returned by the Client/Socket */
9
25
  private subscription;
26
+ /**
27
+ * CHANGED: List of active "Smart Subscriptions" instead of simple functions.
28
+ * This allows us to call .processUpdate() on each one.
29
+ */
10
30
  private subscriptions;
31
+ /** Flag to prevent double initialization */
11
32
  private isInitializing;
33
+ /**
34
+ * Creates an instance of LiveCollection.
35
+ * @param client The main MikrotikClient instance.
36
+ * @param path The menu path to listen to (e.g., '/ppp/active').
37
+ * @param query Optional filter object (e.g. { name: 'admin' }).
38
+ */
12
39
  constructor(client: MikrotikClient, path: string, query?: Record<string, string | number | boolean>);
40
+ /**
41
+ * Subscribes to real-time updates.
42
+ *
43
+ * v1.2.0 Change:
44
+ * Returns a `SnapshotSubscription` object instead of a cleanup function.
45
+ * This enables chaining methods like `.onDiff()`, `.throttle()`, and `.join()`.
46
+ *
47
+ * @param callback Function to execute when data changes.
48
+ * @returns The Subscription object for chaining configuration.
49
+ */
13
50
  onSnapshot(callback: SnapshotCallback<T>): SnapshotSubscription<T>;
51
+ /**
52
+ * Internal method to establish the connection via the client.
53
+ */
14
54
  private startListening;
55
+ /**
56
+ * Processes incoming raw packets from RouterOS.
57
+ * Handles creation, updates, and deletion based on packet flags.
58
+ * @param packet Raw data from the router.
59
+ */
15
60
  private processPacket;
61
+ /**
62
+ * Broadcasts the current array of items to all smart subscriptions.
63
+ */
16
64
  private emit;
65
+ /**
66
+ * Stops the low-level connection to the router.
67
+ */
17
68
  private stopListening;
18
69
  }
@@ -2,28 +2,67 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LiveCollection = void 0;
4
4
  const SnapshotSubscription_1 = require("../client/SnapshotSubscription");
5
+ /**
6
+ * LiveCollection
7
+ * ==========================================
8
+ * Manages a real-time synchronized collection of items from the router.
9
+ *
10
+ * Instead of firing simple callbacks, it manages 'SnapshotSubscription' instances.
11
+ * This allows each subscriber to have their own Throttle settings and Diff modes.
12
+ *
13
+ * @template T The type of the items in the collection.
14
+ */
5
15
  class LiveCollection {
16
+ /**
17
+ * Creates an instance of LiveCollection.
18
+ * @param client The main MikrotikClient instance.
19
+ * @param path The menu path to listen to (e.g., '/ppp/active').
20
+ * @param query Optional filter object (e.g. { name: 'admin' }).
21
+ */
6
22
  constructor(client, path, query = {}) {
7
23
  this.client = client;
8
24
  this.path = path;
9
25
  this.query = query;
26
+ /** Internal storage mapped by item ID (e.g., "*1A") */
10
27
  this.localCache = new Map();
28
+ /** The active low-level subscription object returned by the Client/Socket */
11
29
  this.subscription = null;
30
+ /**
31
+ * CHANGED: List of active "Smart Subscriptions" instead of simple functions.
32
+ * This allows us to call .processUpdate() on each one.
33
+ */
12
34
  this.subscriptions = [];
35
+ /** Flag to prevent double initialization */
13
36
  this.isInitializing = false;
14
37
  }
38
+ /**
39
+ * Subscribes to real-time updates.
40
+ *
41
+ * v1.2.0 Change:
42
+ * Returns a `SnapshotSubscription` object instead of a cleanup function.
43
+ * This enables chaining methods like `.onDiff()`, `.throttle()`, and `.join()`.
44
+ *
45
+ * @param callback Function to execute when data changes.
46
+ * @returns The Subscription object for chaining configuration.
47
+ */
15
48
  onSnapshot(callback) {
49
+ // Define the cleanup logic for this specific subscriber
16
50
  const unsubscribeLogic = () => {
17
51
  this.subscriptions = this.subscriptions.filter(s => s !== sub);
52
+ // If no one is listening anymore, stop the router connection to save bandwidth
18
53
  if (this.subscriptions.length === 0) {
19
54
  this.stopListening();
20
55
  }
21
56
  };
57
+ // Create the Smart Subscription
22
58
  const sub = new SnapshotSubscription_1.SnapshotSubscription(this.client, callback, unsubscribeLogic);
23
59
  this.subscriptions.push(sub);
60
+ // Send immediate data if we already have cache (Hot Observable behavior)
24
61
  if (this.localCache.size > 0) {
62
+ // We use processUpdate so logic like Join or Diff runs even on the first data
25
63
  sub.processUpdate(Array.from(this.localCache.values()));
26
64
  }
65
+ // Start Router connection if this is the first listener
27
66
  if (!this.subscription && !this.isInitializing) {
28
67
  this.startListening().catch(err => {
29
68
  console.error("RosInterface: Error starting live listener", err);
@@ -31,13 +70,20 @@ class LiveCollection {
31
70
  }
32
71
  return sub;
33
72
  }
73
+ /**
74
+ * Internal method to establish the connection via the client.
75
+ */
34
76
  async startListening() {
35
77
  if (this.isInitializing)
36
78
  return;
37
79
  this.isInitializing = true;
38
80
  try {
81
+ // Initialize Command
39
82
  const cmd = this.client.command(this.path);
83
+ // Optimization: Request specific fields to reduce CPU load on Router.
84
+ // CRITICAL: We MUST include '.dead' to detect deletions.
40
85
  cmd.where('.proplist', '.id,.dead,name,comment,disabled,profile,service,user,password,address,uptime,mac-address,caller-id,bytes-in,bytes-out,radius');
86
+ // Apply Filters from Query
41
87
  if (this.query) {
42
88
  Object.keys(this.query).forEach(key => {
43
89
  const value = this.query[key];
@@ -46,6 +92,7 @@ class LiveCollection {
46
92
  }
47
93
  });
48
94
  }
95
+ // Start Streaming
49
96
  this.subscription = cmd.listen((packet) => {
50
97
  this.processPacket(packet);
51
98
  });
@@ -55,31 +102,53 @@ class LiveCollection {
55
102
  this.isInitializing = false;
56
103
  }
57
104
  }
105
+ /**
106
+ * Processes incoming raw packets from RouterOS.
107
+ * Handles creation, updates, and deletion based on packet flags.
108
+ * @param packet Raw data from the router.
109
+ */
58
110
  processPacket(packet) {
111
+ // RouterOS raw packets use '.id', but sometimes it might be parsed as 'id'
59
112
  const rawId = packet['.id'] || packet['id'];
113
+ // Ignore status packets (!done, !fatal)
60
114
  if (!rawId)
61
115
  return;
116
+ // HANDLE DELETION
62
117
  if (packet['.dead'] === true || packet['dead'] === true) {
63
118
  this.localCache.delete(rawId);
64
119
  }
120
+ // HANDLE UPDATE / INSERT
65
121
  else {
66
122
  const existing = this.localCache.get(rawId) || {};
123
+ // Normalize keys: Remove leading dots
67
124
  const cleanPacket = {};
68
125
  for (const key of Object.keys(packet)) {
69
126
  const cleanKey = key.startsWith('.') ? key.substring(1) : key;
70
127
  cleanPacket[cleanKey] = packet[key];
71
128
  }
129
+ // Merge with existing data to support partial updates
72
130
  const updated = { ...existing, ...cleanPacket };
73
131
  this.localCache.set(rawId, updated);
74
132
  }
133
+ // BROADCAST TO SMART SUBSCRIPTIONS
134
+ // Instead of sending the array directly, we let the Subscription object
135
+ // decide IF and WHEN to send it (Throttle) and HOW (Diff/Join).
75
136
  this.emit();
76
137
  }
138
+ /**
139
+ * Broadcasts the current array of items to all smart subscriptions.
140
+ */
77
141
  emit() {
78
142
  const fullList = Array.from(this.localCache.values());
143
+ // We delegate the logic to each subscription.
144
+ // One user might want Diffs, another might want the full list throttled.
79
145
  this.subscriptions.forEach(sub => {
80
146
  sub.processUpdate(fullList);
81
147
  });
82
148
  }
149
+ /**
150
+ * Stops the low-level connection to the router.
151
+ */
83
152
  stopListening() {
84
153
  if (this.subscription) {
85
154
  try {