highrise.bot 1.1.3 → 1.1.5

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.
@@ -0,0 +1,20 @@
1
+ {
2
+ "owner": [
3
+ "68a7dd5eecae68acca580f41"
4
+ ],
5
+ "moderator": [
6
+ "68a7dd5eecae68acca580f41",
7
+ "670a8989fe3aacf3cac98423",
8
+ "685a15a318f7be3f9e1e861d"
9
+ ],
10
+ "designer": [
11
+ "68a7dd5eecae68acca580f41",
12
+ "670a8989fe3aacf3cac98423",
13
+ "685a15a318f7be3f9e1e861d"
14
+ ],
15
+ "_meta": {
16
+ "savedAt": "2026-02-14T22:49:31.104Z",
17
+ "totalRoles": 3,
18
+ "totalUsers": 7
19
+ }
20
+ }
package/index.js CHANGED
@@ -1,11 +1,16 @@
1
1
  /// <reference types="./typings/index.d.ts" />
2
2
  'use strict';
3
3
 
4
+ const { checkVersion } = require('highrise.bot/src/utils/versionCheck');
5
+ (async () => {
6
+ await checkVersion()
7
+ })()
8
+
9
+
4
10
  /**
5
- * Highrise Bot SDK
6
- * A HIghrise WebSocket SDK for Highrise bots
11
+ * A Highrise WebSocket SDK for Highrise bots
7
12
  *
8
- * @copyright 2025 Yahya Ahmed
13
+ * @copyright 2026 Yahya Ahmed
9
14
  * @license MIT
10
15
  */
11
16
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "highrise.bot",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "Unofficial JavaScript SDK for the Highrise platform. Feature-complete WebSocket client with TypeScript support, built for production environments.",
5
5
  "keywords": [
6
6
  "highrise.bot",
@@ -1,327 +1,56 @@
1
- const crypto = require('crypto');
2
1
  const ErrorConstants = require('highrise.bot/src/constants/ErrorConstants');
3
2
 
4
3
  class ChannelClass {
5
4
  constructor(bot) {
6
5
  this.bot = bot;
7
6
  this.logger = bot.logger;
8
-
9
- this._messageHistory = [];
10
- this._maxHistory = 500;
11
- this._listeners = new Map();
12
- this._tagIndex = new Map();
13
7
 
14
8
  this.HighriseError = bot.HighriseError;
15
9
  this.HighriseResponse = bot.HighriseResponse;
10
+
16
11
  }
17
-
12
+
18
13
  async send(message, tags = []) {
19
- let storedMessage
20
-
21
14
  try {
22
15
  if (typeof message !== 'string' || message.trim().length === 0) {
23
16
  return this.HighriseError.invalidMessage(message).toResult();
24
17
  }
25
-
26
- const normalizedTags = this._normalizeTags(tags);
27
-
18
+
19
+ if (!Array.isArray(tags) || !tags.every(tag => typeof tag === 'string')) {
20
+ return new this.HighriseError(
21
+ ErrorConstants.CHANNEL.INVALID_TAGS,
22
+ `tags must be a valid strings array`,
23
+ { tags }
24
+ ).toResult();
25
+ }
26
+
27
+ const normalizedTags = tags;
28
+
28
29
  const payload = {
29
30
  _type: 'ChannelRequest',
30
31
  message: message,
31
- tags: normalizedTags,
32
- rid: crypto.randomUUID()
32
+ tags: normalizedTags
33
33
  };
34
-
34
+
35
35
  const response = await this.bot.fireAndForget.send(payload);
36
-
36
+
37
37
  if (response.success) {
38
- storedMessage = {
39
- id: crypto.randomUUID(),
38
+ const ChannelMessage = {
40
39
  message,
41
40
  tags: normalizedTags,
42
41
  timestamp: Date.now(),
43
- senderId: this.bot.info.user?.id || 'unknown',
44
42
  sent: true
45
43
  };
46
-
47
- this._storeMessage(storedMessage);
48
-
49
- return this.HighriseResponse.success('message', storedMessage);
50
-
44
+ return this.HighriseResponse.success('message', ChannelMessage);
51
45
  }
52
-
53
46
  } catch (error) {
54
47
  return new this.HighriseError(
55
- ErrorConstants.CHANNEL.LISTENER_ERROR,
48
+ ErrorConstants.HIGHRISE_API.MESSAGE_SEND_FAILED,
56
49
  `Failed to send channel message: ${error.message}`,
57
- { storedMessage }
50
+ { message, tags }
58
51
  ).toResult();
59
52
  }
60
53
  }
61
-
62
- on(tags, callback, options = {}) {
63
- let listener
64
-
65
- try {
66
- if (!callback || typeof callback !== 'function') {
67
- return new this.HighriseError(
68
- ErrorConstants.VALIDATION.INVALID_CHANNEL_CALLBACK,
69
- `callback must be a function`
70
- ).toResult();
71
- }
72
-
73
- const normalizedTags = this._normalizeTags(Array.isArray(tags) ? tags : [tags]);
74
-
75
- const listenerId = crypto.randomUUID();
76
- listener = {
77
- id: listenerId,
78
- callback,
79
- tags: normalizedTags,
80
- options: {
81
- once: options.once || false,
82
- }
83
- };
84
-
85
- this._listeners.set(listenerId, listener);
86
-
87
- normalizedTags.forEach(tag => {
88
- if (!this._tagIndex.has(tag)) {
89
- this._tagIndex.set(tag, new Set());
90
- }
91
- this._tagIndex.get(tag).add(listenerId);
92
- });
93
-
94
- return this.HighriseResponse.success('listener', {
95
- id: listenerId,
96
- tags: normalizedTags}
97
- );
98
-
99
- } catch (error) {
100
- return new this.HighriseError(
101
- ErrorConstants.CHANNEL.LISTENER_ERROR,
102
- `Failed to register listener: ${error.message}`,
103
- { listener }
104
- ).toResult();
105
- }
106
- }
107
-
108
- once(tags, callback) {
109
- return this.on(tags, callback, { once: true });
110
- }
111
-
112
- off(listenerId) {
113
-
114
- try {
115
- const listener = this._listeners.get(listenerId);
116
- if (!listener) {
117
- return new this.HighriseError(
118
- ErrorConstants.NOT_FOUND.LISTENER_NOT_FOUND,
119
- `Listener '${listenerId ? `${listenerId.substring(0, 12)}...` : 'EMPTY'}' Not found to be removed.`
120
- ).toResult();
121
- }
122
-
123
- listener.tags.forEach(tag => {
124
- const set = this._tagIndex.get(tag);
125
- if (set) {
126
- set.delete(listenerId);
127
- if (set.size === 0) {
128
- this._tagIndex.delete(tag);
129
- }
130
- }
131
- });
132
-
133
- this._listeners.delete(listenerId);
134
-
135
- return this.HighriseResponse.success('listenerId', listenerId);
136
-
137
- } catch (error) {
138
- return new this.HighriseError(
139
- ErrorConstants.CHANNEL.LISTENER_ERROR,
140
- `Failed to remove listener: ${error.message}`,
141
- { listenerId }
142
- ).toResult();
143
- }
144
- }
145
-
146
- offAll(tags) {
147
- const normalizedTags = this._normalizeTags(Array.isArray(tags) ? tags : [tags]);
148
-
149
- const listenersToRemove = new Set();
150
-
151
- normalizedTags.forEach(tag => {
152
- const listeners = this._tagIndex.get(tag);
153
- if (listeners) {
154
- listeners.forEach(listenerId => listenersToRemove.add(listenerId));
155
- }
156
- });
157
-
158
- let removed = 0;
159
- let failed = {
160
- count: 0,
161
- errors: []
162
- }
163
- listenersToRemove.forEach(listenerId => {
164
- const result = this.off(listenerId);
165
- if (result.success) {
166
- removed++;
167
- } else {
168
- failed.errors.push(result.error)
169
- failed.count++
170
- }
171
- });
172
-
173
- return this.HighriseResponse.success('removed', {
174
- count: removed,
175
- failed,
176
- tags: normalizedTags
177
- });
178
- }
179
-
180
- query(filter = {}) {
181
- const {
182
- tags = [],
183
- since = 0,
184
- until = Date.now(),
185
- limit = 50
186
- } = filter;
187
-
188
- const normalizedTags = this._normalizeTags(Array.isArray(tags) ? tags : [tags]);
189
-
190
- const results = [];
191
-
192
- for (const msg of this._messageHistory) {
193
- if (this._matchesFilter(msg, { tags: normalizedTags, since, until })) {
194
- results.push(msg);
195
- if (results.length >= limit) break;
196
- }
197
- }
198
-
199
- return this.HighriseResponse.success('query', {
200
- count: results.length,
201
- messages: results,
202
- filter
203
- });
204
- }
205
-
206
- stats() {
207
- return this.HighriseResponse.success('stats', {
208
- totalMessages: this._messageHistory.length,
209
- activeListeners: this._listeners.size,
210
- indexedTags: this._tagIndex.size
211
- });
212
- }
213
-
214
- storeIncomingMessage(senderId, message, tags) {
215
- try {
216
- const normalizedTags = this._normalizeTags(tags);
217
-
218
- const storedMsg = {
219
- id: crypto.randomUUID(),
220
- message,
221
- tags: normalizedTags,
222
- timestamp: Date.now(),
223
- senderId,
224
- sent: false
225
- };
226
-
227
- this._storeMessage(storedMsg);
228
- this._triggerListeners(storedMsg);
229
-
230
- return this.HighriseResponse.success('stored', {
231
- id: storedMsg.id,
232
- senderId: storedMsg.senderId,
233
- tags: storedMsg.tags,
234
- timestamp: storedMsg.timestamp
235
- });
236
-
237
- } catch (error) {
238
- this.logger.error('ChannelManager', 'Failed to store incoming message', { error: error.message });
239
-
240
- return new this.HighriseError(
241
- ErrorConstants.CHANNEL.LISTENER_ERROR,
242
- 'Failed to store incoming message',
243
- { error: error.message }
244
- ).toResult();
245
- }
246
- }
247
-
248
- _triggerListeners(message) {
249
- const matchedListeners = new Map();
250
-
251
- message.tags.forEach(tag => {
252
- const listeners = this._tagIndex.get(tag);
253
- if (listeners) {
254
- listeners.forEach(listenerId => {
255
- const listener = this._listeners.get(listenerId);
256
- if (listener && !matchedListeners.has(listenerId)) {
257
- const hasAllTags = listener.tags.every(t => message.tags.includes(t));
258
- if (hasAllTags) {
259
- matchedListeners.set(listenerId, listener);
260
- }
261
- }
262
- });
263
- }
264
- });
265
-
266
- matchedListeners.forEach((listener, listenerId) => {
267
- try {
268
- listener.callback(message);
269
-
270
- if (listener.options.once) {
271
- this.off(listenerId);
272
- }
273
-
274
- } catch (error) {
275
- this.logger.error('ChannelManager', 'Listener callback error', { listenerId, error: error.message });
276
- }
277
- });
278
- }
279
-
280
- _normalizeTags(tags) {
281
- const normalized = tags
282
- .map(tag => {
283
- if (typeof tag !== 'string') return '';
284
- return tag.toLowerCase()
285
- .trim()
286
- .replace(/[^a-z0-9_:.-]/g, '-')
287
- .replace(/-+/g, '-')
288
- .substring(0, 50);
289
- })
290
- .filter(tag => tag.length > 0)
291
- .filter((tag, index, self) => self.indexOf(tag) === index)
292
- .sort();
293
-
294
- return normalized.length > 0 ? normalized : ['global'];
295
- }
296
-
297
- _storeMessage(message) {
298
- this._messageHistory.unshift(message);
299
-
300
- if (this._messageHistory.length > this._maxHistory) {
301
- this._messageHistory.splice(this._maxHistory);
302
- }
303
- }
304
-
305
- _matchesFilter(message, filter) {
306
- const { tags = [], since = 0, until = Date.now() } = filter;
307
-
308
- if (message.timestamp < since || message.timestamp > until) {
309
- return false;
310
- }
311
-
312
- if (tags.length > 0) {
313
- const hasAllTags = tags.every(tag => message.tags.includes(tag));
314
- if (!hasAllTags) return false;
315
- }
316
-
317
- return true;
318
- }
319
-
320
- clear() {
321
- this._messageHistory = [];
322
- this._listeners.clear();
323
- this._tagIndex.clear();
324
- }
325
54
  }
326
55
 
327
56
  module.exports = { ChannelClass };
@@ -1,13 +1,13 @@
1
1
  const RoleManager = require("highrise.bot/src/classes/Managers/RoleManager");
2
2
  const CooldownManager = require("highrise.bot/src/classes/Managers/CooldownManager");
3
3
  const DanceFloor = require("highrise.bot/src/classes/Managers/DanceFloorManagers");
4
- const { Logger } = require("highrise.bot/src/classes/Managers/Helpers/LoggerManager");
4
+ const { Logger } = require("highrise.bot/src/classes/Helpers/LoggerManager");
5
5
  const CommandHandler = require("highrise.bot/src/classes/Handlers/CommandHandler");
6
6
 
7
7
  class Utils {
8
8
  constructor(bot, options) {
9
9
  this.bot = bot
10
- this.logger = new Logger(this, options)
10
+ this.logger = new Logger(options)
11
11
  this.dancefloor = new DanceFloor(this.bot)
12
12
  this.cooldown = new CooldownManager()
13
13
 
@@ -73,8 +73,8 @@ class Utils {
73
73
  return result;
74
74
  }
75
75
 
76
- command(relativeDir, options = {}) {
77
- return new CommandHandler(this.bot, relativeDir, options);
76
+ command(relativeDir) {
77
+ return CommandHandler.create(this.bot, relativeDir)
78
78
  };
79
79
 
80
80
  }