quikchat 1.1.13 → 1.1.15

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.
@@ -82,11 +82,55 @@ function _unsupportedIterableToArray(r, a) {
82
82
  }
83
83
  }
84
84
 
85
+ // Auto-generated version file - DO NOT EDIT MANUALLY
86
+ // This file is automatically updated by tools/updateVersion.js
87
+
88
+ var quikchatVersion = {
89
+ version: "1.1.15",
90
+ license: "BSD-2",
91
+ url: "https://github/deftio/quikchat",
92
+ fun: true
93
+ };
94
+
95
+ /**
96
+ * QuikChat - A zero-dependency JavaScript chat widget for modern web applications
97
+ * @class quikchat
98
+ * @version 1.1.15
99
+ */
85
100
  var quikchat = /*#__PURE__*/function () {
86
101
  /**
102
+ * Creates a new QuikChat instance
103
+ * @constructor
104
+ * @param {string|HTMLElement} parentElement - CSS selector or DOM element to attach the chat widget to
105
+ * @param {Function} [onSend] - Callback function triggered when user sends a message
106
+ * @param {Object} [options] - Configuration options
107
+ * @param {string} [options.theme='quikchat-theme-light'] - CSS theme class name
108
+ * @param {boolean} [options.trackHistory=true] - Whether to track message history
109
+ * @param {Object} [options.titleArea] - Title area configuration
110
+ * @param {string} [options.titleArea.title='Chat'] - Title text/HTML
111
+ * @param {boolean} [options.titleArea.show=false] - Whether to show title area initially
112
+ * @param {'left'|'center'|'right'} [options.titleArea.align='center'] - Title alignment
113
+ * @param {Object} [options.messagesArea] - Messages area configuration
114
+ * @param {boolean} [options.messagesArea.alternating=true] - Alternate message colors
115
+ * @param {Object} [options.inputArea] - Input area configuration
116
+ * @param {boolean} [options.inputArea.show=true] - Whether to show input area initially
117
+ * @param {boolean} [options.sendOnEnter=true] - Send message on Enter key
118
+ * @param {boolean} [options.sendOnShiftEnter=false] - Send message on Shift+Enter
119
+ * @param {string} [options.instanceClass=''] - Additional CSS class for the widget instance
120
+ * @example
121
+ * // Basic usage
122
+ * const chat = new quikchat('#chat-container', (instance, message) => {
123
+ * console.log('User sent:', message);
124
+ * });
87
125
  *
88
- * @param string or DOM element parentElement
89
- * @param {*} meta
126
+ * @example
127
+ * // With options
128
+ * const chat = new quikchat('#chat', handleMessage, {
129
+ * theme: 'quikchat-theme-dark',
130
+ * titleArea: { title: 'Support Chat', show: true },
131
+ * sendOnEnter: false,
132
+ * sendOnShiftEnter: true
133
+ * });
90
134
  */
91
135
  function quikchat(parentElement) {
92
136
  var onSend = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
@@ -107,7 +151,8 @@ var quikchat = /*#__PURE__*/function () {
107
151
  show: true
108
152
  },
109
153
  sendOnEnter: true,
110
- sendOnShiftEnter: false
154
+ sendOnShiftEnter: false,
155
+ instanceClass: ''
111
156
  };
112
157
  var meta = _objectSpread2(_objectSpread2({}, defaultOpts), options); // merge options with defaults
113
158
 
@@ -119,6 +164,10 @@ var quikchat = /*#__PURE__*/function () {
119
164
  this._theme = meta.theme;
120
165
  this._onSend = onSend ? onSend : function () {}; // call back function for onSend
121
166
  this._createWidget();
167
+ if (meta.instanceClass) {
168
+ this._chatWidget.classList.add(meta.instanceClass);
169
+ }
170
+
122
171
  // title area
123
172
  if (meta.titleArea) {
124
173
  this.titleAreaSetContents(meta.titleArea.title, meta.titleArea.align);
@@ -142,6 +191,7 @@ var quikchat = /*#__PURE__*/function () {
142
191
  this.trackHistory = meta.trackHistory || true;
143
192
  this._historyLimit = 10000000;
144
193
  this._history = [];
194
+ this._activeTags = new Set();
145
195
 
146
196
  // send on enter / shift enter
147
197
  this.sendOnEnter = meta.sendOnEnter;
@@ -216,24 +266,100 @@ var quikchat = /*#__PURE__*/function () {
216
266
  this._onMessageAdded = callback;
217
267
  }
218
268
 
269
+ /**
270
+ * Sets the callback function for when content is appended to a message
271
+ * @param {Function} callback - Function to call when content is appended
272
+ * @param {quikchat} callback.instance - The QuikChat instance
273
+ * @param {number} callback.msgId - The ID of the message being appended to
274
+ * @param {string} callback.content - The content being appended
275
+ * @since 1.1.15
276
+ * @example
277
+ * chat.setCallbackonMessageAppend((instance, msgId, content) => {
278
+ * console.log(`Appended "${content}" to message ${msgId}`);
279
+ * });
280
+ */
281
+ }, {
282
+ key: "setCallbackonMessageAppend",
283
+ value: function setCallbackonMessageAppend(callback) {
284
+ this._onMessageAppend = callback;
285
+ }
286
+
287
+ /**
288
+ * Sets the callback function for when a message's content is replaced
289
+ * @param {Function} callback - Function to call when content is replaced
290
+ * @param {quikchat} callback.instance - The QuikChat instance
291
+ * @param {number} callback.msgId - The ID of the message being replaced
292
+ * @param {string} callback.content - The new content
293
+ * @since 1.1.15
294
+ * @example
295
+ * chat.setCallbackonMessageReplace((instance, msgId, content) => {
296
+ * console.log(`Message ${msgId} replaced with: ${content}`);
297
+ * });
298
+ */
299
+ }, {
300
+ key: "setCallbackonMessageReplace",
301
+ value: function setCallbackonMessageReplace(callback) {
302
+ this._onMessageReplace = callback;
303
+ }
304
+
305
+ /**
306
+ * Sets the callback function for when a message is deleted
307
+ * @param {Function} callback - Function to call when a message is deleted
308
+ * @param {quikchat} callback.instance - The QuikChat instance
309
+ * @param {number} callback.msgId - The ID of the deleted message
310
+ * @since 1.1.15
311
+ * @example
312
+ * chat.setCallbackonMessageDelete((instance, msgId) => {
313
+ * console.log(`Message ${msgId} was deleted`);
314
+ * });
315
+ */
316
+ }, {
317
+ key: "setCallbackonMessageDelete",
318
+ value: function setCallbackonMessageDelete(callback) {
319
+ this._onMessageDelete = callback;
320
+ }
321
+
219
322
  // Public methods
323
+ /**
324
+ * Toggles the visibility of the title area
325
+ * @returns {void}
326
+ */
220
327
  }, {
221
328
  key: "titleAreaToggle",
222
329
  value: function titleAreaToggle() {
223
330
  this._titleArea.style.display === 'none' ? this.titleAreaShow() : this.titleAreaHide();
224
331
  }
332
+
333
+ /**
334
+ * Shows the title area
335
+ * @returns {void}
336
+ */
225
337
  }, {
226
338
  key: "titleAreaShow",
227
339
  value: function titleAreaShow() {
228
340
  this._titleArea.style.display = '';
229
341
  this._adjustMessagesAreaHeight();
230
342
  }
343
+
344
+ /**
345
+ * Hides the title area
346
+ * @returns {void}
347
+ */
231
348
  }, {
232
349
  key: "titleAreaHide",
233
350
  value: function titleAreaHide() {
234
351
  this._titleArea.style.display = 'none';
235
352
  this._adjustMessagesAreaHeight();
236
353
  }
354
+
355
+ /**
356
+ * Sets the contents of the title area
357
+ * @param {string} title - HTML content to display in the title area
358
+ * @param {'left'|'center'|'right'} [align='center'] - Text alignment
359
+ * @returns {void}
360
+ * @example
361
+ * chat.titleAreaSetContents('<h2>Support Chat</h2>', 'center');
362
+ */
237
363
  }, {
238
364
  key: "titleAreaSetContents",
239
365
  value: function titleAreaSetContents(title) {
@@ -241,6 +367,11 @@ var quikchat = /*#__PURE__*/function () {
241
367
  this._titleArea.innerHTML = title;
242
368
  this._titleArea.style.textAlign = align;
243
369
  }
370
+
371
+ /**
372
+ * Gets the current contents of the title area
373
+ * @returns {string} The HTML content of the title area
374
+ */
244
375
  }, {
245
376
  key: "titleAreaGetContents",
246
377
  value: function titleAreaGetContents() {
@@ -315,10 +446,33 @@ var quikchat = /*#__PURE__*/function () {
315
446
  value: function messagesAreaAlternateColorsGet() {
316
447
  return this._messagesArea.classList.contains('quikchat-messages-area-alt');
317
448
  }
318
- // message functions
449
+ /**
450
+ * Adds a new message to the chat with full configuration options
451
+ * @param {Object} input - Message configuration object
452
+ * @param {string} [input.content=''] - Message content (HTML allowed)
453
+ * @param {string} [input.userString='user'] - Display name for the message sender
454
+ * @param {'left'|'right'|'center'} [input.align='right'] - Message alignment
455
+ * @param {string} [input.role='user'] - Role identifier (user, assistant, system)
456
+ * @param {number} [input.userID=-1] - User ID for the message
457
+ * @param {string|false} [input.timestamp=false] - ISO timestamp or false for auto
458
+ * @param {string|false} [input.updatedtime=false] - Last updated timestamp
459
+ * @param {boolean|'smart'} [input.scrollIntoView=true] - Scroll behavior (true/false/'smart')
460
+ * @param {boolean} [input.visible=true] - Whether message is initially visible
461
+ * @param {string[]} [input.tags=[]] - Tags for message categorization
462
+ * @returns {number} Message ID for the newly added message
463
+ * @example
464
+ * const msgId = chat.messageAddFull({
465
+ * content: 'Hello!',
466
+ * userString: 'Bot',
467
+ * align: 'left',
468
+ * scrollIntoView: 'smart',
469
+ * tags: ['greeting']
470
+ * });
471
+ */
319
472
  }, {
320
473
  key: "messageAddFull",
321
474
  value: function messageAddFull() {
475
+ var _this2 = this;
322
476
  var input = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
323
477
  content: "",
324
478
  userString: "user",
@@ -328,13 +482,22 @@ var quikchat = /*#__PURE__*/function () {
328
482
  timestamp: false,
329
483
  updatedtime: false,
330
484
  scrollIntoView: true,
331
- visible: true
485
+ visible: true,
486
+ tags: []
332
487
  };
333
488
  var msgid = this.msgid;
334
489
  var messageDiv = document.createElement('div');
335
490
  var msgidClass = 'quikchat-msgid-' + String(msgid).padStart(10, '0');
336
491
  'quikchat-userid-' + String(input.userString).padStart(10, '0'); // hash this..
337
492
  messageDiv.classList.add('quikchat-message', msgidClass, 'quikchat-structure');
493
+ if (Array.isArray(input.tags)) {
494
+ input.tags.forEach(function (tag) {
495
+ if (typeof tag === 'string' && /^[a-zA-Z0-9-]+$/.test(tag)) {
496
+ messageDiv.classList.add("quikchat-tag-".concat(tag));
497
+ _this2._activeTags.add(tag);
498
+ }
499
+ });
500
+ }
338
501
  this.msgid++;
339
502
  var userDiv = document.createElement('div');
340
503
  userDiv.innerHTML = input.userString;
@@ -363,10 +526,15 @@ var quikchat = /*#__PURE__*/function () {
363
526
  messageDiv.style.display = 'none';
364
527
  }
365
528
 
366
- // Scroll to the last message only if the user is not actively scrolling up
367
- if (!this.userScrolledUp || input.scrollIntoView) {
529
+ // Handle scroll behavior based on scrollIntoView parameter
530
+ // 'smart' = only scroll if near bottom, true = always scroll, false = never scroll
531
+ if (input.scrollIntoView === true) {
532
+ this.messageScrollToBottom();
533
+ } else if (input.scrollIntoView === 'smart' && !this.userScrolledUp) {
368
534
  this.messageScrollToBottom();
369
535
  }
536
+ // If scrollIntoView is false, don't scroll at all
537
+
370
538
  this._textEntry.value = '';
371
539
  this._adjustMessagesAreaHeight();
372
540
  this._handleShortLongMessageCSS(messageDiv, input.align); // Handle CSS for short/long messages
@@ -393,6 +561,24 @@ var quikchat = /*#__PURE__*/function () {
393
561
  }
394
562
  return msgid;
395
563
  }
564
+
565
+ /**
566
+ * Adds a new message to the chat (simplified version of messageAddFull)
567
+ * @param {string} [content=''] - Message content (HTML allowed)
568
+ * @param {string} [userString='user'] - Display name for the message sender
569
+ * @param {'left'|'right'|'center'} [align='right'] - Message alignment
570
+ * @param {string} [role='user'] - Role identifier (user, assistant, system)
571
+ * @param {boolean|'smart'} [scrollIntoView=true] - Scroll behavior
572
+ * @param {boolean} [visible=true] - Whether message is initially visible
573
+ * @param {string[]} [tags=[]] - Tags for message categorization
574
+ * @returns {number} Message ID for the newly added message
575
+ * @example
576
+ * // Simple message
577
+ * chat.messageAddNew('Hello!', 'User', 'right');
578
+ *
579
+ * // Bot message with smart scroll
580
+ * chat.messageAddNew('Hi there!', 'Bot', 'left', 'assistant', 'smart');
581
+ */
396
582
  }, {
397
583
  key: "messageAddNew",
398
584
  value: function messageAddNew() {
@@ -402,17 +588,27 @@ var quikchat = /*#__PURE__*/function () {
402
588
  var role = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : "user";
403
589
  var scrollIntoView = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
404
590
  var visible = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;
591
+ var tags = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : [];
405
592
  var retvalue = this.messageAddFull({
406
593
  content: content,
407
594
  userString: userString,
408
595
  align: align,
409
596
  role: role,
410
597
  scrollIntoView: scrollIntoView,
411
- visible: visible
598
+ visible: visible,
599
+ tags: tags
412
600
  });
413
601
  // this.messageScrollToBottom();
414
602
  return retvalue;
415
603
  }
604
+
605
+ /**
606
+ * Removes a message from the chat by its ID
607
+ * @param {number} n - Message ID to remove
608
+ * @returns {boolean} True if message was removed, false if not found
609
+ * @example
610
+ * const success = chat.messageRemove(5);
611
+ */
416
612
  }, {
417
613
  key: "messageRemove",
418
614
  value: function messageRemove(n) {
@@ -432,11 +628,21 @@ var quikchat = /*#__PURE__*/function () {
432
628
  this._history.splice(this._history.findIndex(function (item) {
433
629
  return item.msgid === n;
434
630
  }), 1);
631
+
632
+ // Call the onMessageDelete callback if it exists
633
+ if (this._onMessageDelete) {
634
+ this._onMessageDelete(this, n);
635
+ }
435
636
  }
436
637
  return sucess;
437
638
  }
438
639
  /* returns the message html object from the DOM
439
640
  */
641
+ /**
642
+ * Gets the DOM element for a message by its ID
643
+ * @param {number} n - Message ID
644
+ * @returns {HTMLElement|null} The message DOM element or null if not found
645
+ */
440
646
  }, {
441
647
  key: "messageGetDOMObject",
442
648
  value: function messageGetDOMObject(n) {
@@ -451,6 +657,11 @@ var quikchat = /*#__PURE__*/function () {
451
657
  }
452
658
  /* returns the message content only
453
659
  */
660
+ /**
661
+ * Gets the content of a message by its ID
662
+ * @param {number} n - Message ID
663
+ * @returns {string} The message content or empty string if not found
664
+ */
454
665
  }, {
455
666
  key: "messageGetContent",
456
667
  value: function messageGetContent(n) {
@@ -502,10 +713,13 @@ var quikchat = /*#__PURE__*/function () {
502
713
  item.updatedtime = new Date().toISOString();
503
714
  success = true;
504
715
 
505
- // Scroll to the last message only if the user is not actively scrolling up
506
- if (!this.userScrolledUp) {
507
- this._messagesArea.lastElementChild.scrollIntoView();
716
+ // Call the onMessageAppend callback if it exists
717
+ if (this._onMessageAppend) {
718
+ this._onMessageAppend(this, n, content);
508
719
  }
720
+
721
+ // Don't auto-scroll on append - let user control this
722
+ // Users can call messageScrollToBottom() if they want to scroll
509
723
  } catch (error) {
510
724
  console.log("".concat(String(n), " : Message ID not found"));
511
725
  }
@@ -528,10 +742,13 @@ var quikchat = /*#__PURE__*/function () {
528
742
  item.updatedtime = new Date().toISOString();
529
743
  success = true;
530
744
 
531
- // Scroll to the last message only if the user is not actively scrolling up
532
- if (!this.userScrolledUp) {
533
- this._messagesArea.lastElementChild.scrollIntoView();
745
+ // Call the onMessageReplace callback if it exists
746
+ if (this._onMessageReplace) {
747
+ this._onMessageReplace(this, n, content);
534
748
  }
749
+
750
+ // Don't auto-scroll on append - let user control this
751
+ // Users can call messageScrollToBottom() if they want to scroll
535
752
  } catch (error) {
536
753
  console.log("".concat(String(n), " : Message ID not found"));
537
754
  }
@@ -667,6 +884,18 @@ var quikchat = /*#__PURE__*/function () {
667
884
  * @param {*} m
668
885
  * @returns array of history messages
669
886
  */
887
+ /**
888
+ * Gets a slice of message history
889
+ * @param {number} [n] - Start index (defaults to 0)
890
+ * @param {number} [m] - End index (defaults to history length)
891
+ * @returns {Array} Array of message objects
892
+ * @example
893
+ * // Get first 10 messages
894
+ * const messages = chat.historyGet(0, 10);
895
+ *
896
+ * // Get all messages
897
+ * const allMessages = chat.historyGet();
898
+ */
670
899
  }, {
671
900
  key: "historyGet",
672
901
  value: function historyGet(n, m) {
@@ -682,17 +911,204 @@ var quikchat = /*#__PURE__*/function () {
682
911
 
683
912
  return this._history.slice(n, m);
684
913
  }
914
+
915
+ /**
916
+ * Gets a copy of the entire message history
917
+ * @returns {Array} Complete array of all message objects
918
+ * @example
919
+ * const history = chat.historyGetAllCopy();
920
+ * console.log(`Total messages: ${history.length}`);
921
+ */
685
922
  }, {
686
923
  key: "historyGetAllCopy",
687
924
  value: function historyGetAllCopy() {
688
925
  return this._history.slice();
689
926
  }
927
+
928
+ /**
929
+ * Get a page of history messages with pagination support
930
+ * @param {number} page - Page number (1-based)
931
+ * @param {number} pageSize - Number of messages per page (default 50)
932
+ * @param {string} order - 'asc' for oldest first, 'desc' for newest first (default 'asc')
933
+ * @returns {object} Object with messages array, pagination info
934
+ */
935
+ }, {
936
+ key: "historyGetPage",
937
+ value: function historyGetPage() {
938
+ var page = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
939
+ var pageSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 50;
940
+ var order = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'asc';
941
+ var totalMessages = this._history.length;
942
+ var totalPages = Math.ceil(totalMessages / pageSize);
943
+ var currentPage = Math.max(1, Math.min(page, totalPages || 1));
944
+ var start, end;
945
+ if (order === 'desc') {
946
+ // For descending order, page 1 shows the newest messages
947
+ start = Math.max(0, totalMessages - currentPage * pageSize);
948
+ end = totalMessages - (currentPage - 1) * pageSize;
949
+ } else {
950
+ // For ascending order, page 1 shows the oldest messages
951
+ start = (currentPage - 1) * pageSize;
952
+ end = Math.min(start + pageSize, totalMessages);
953
+ }
954
+ var messages = this._history.slice(start, end);
955
+
956
+ // Reverse messages array if descending order requested
957
+ if (order === 'desc') {
958
+ messages.reverse();
959
+ }
960
+ return {
961
+ messages: messages,
962
+ pagination: {
963
+ currentPage: currentPage,
964
+ pageSize: pageSize,
965
+ totalPages: totalPages,
966
+ totalMessages: totalMessages,
967
+ hasNext: currentPage < totalPages,
968
+ hasPrevious: currentPage > 1,
969
+ order: order
970
+ }
971
+ };
972
+ }
973
+
974
+ /**
975
+ * Get information about history size and pagination
976
+ * @param {number} pageSize - Size to calculate pages for (default 50)
977
+ * @returns {object} History metadata
978
+ */
979
+ /**
980
+ * Search history for messages matching criteria
981
+ * @param {object} criteria - Search criteria object
982
+ * @param {string} criteria.text - Text to search for in message content
983
+ * @param {string} criteria.userString - Filter by user name
984
+ * @param {string} criteria.role - Filter by role
985
+ * @param {array} criteria.tags - Filter by tags (messages with any of these tags)
986
+ * @param {number} criteria.limit - Maximum results to return (default 100)
987
+ * @returns {array} Array of matching messages
988
+ */
989
+ /**
990
+ * Searches through message history with various filters
991
+ * @param {Object} [criteria={}] - Search criteria
992
+ * @param {string} [criteria.text] - Text to search for in message content
993
+ * @param {string} [criteria.userString] - Filter by specific user
994
+ * @param {string} [criteria.role] - Filter by role (user, assistant, system)
995
+ * @param {string[]} [criteria.tags] - Filter by tags (messages must have at least one)
996
+ * @param {number} [criteria.limit=100] - Maximum number of results
997
+ * @returns {Array} Array of matching messages
998
+ * @since 1.1.15
999
+ * @example
1000
+ * // Search for messages containing 'error'
1001
+ * const errors = chat.historySearch({ text: 'error' });
1002
+ *
1003
+ * // Find all bot messages
1004
+ * const botMessages = chat.historySearch({ role: 'assistant' });
1005
+ *
1006
+ * // Complex search
1007
+ * const results = chat.historySearch({
1008
+ * text: 'help',
1009
+ * userString: 'Support',
1010
+ * tags: ['urgent'],
1011
+ * limit: 20
1012
+ * });
1013
+ */
1014
+ }, {
1015
+ key: "historySearch",
1016
+ value: function historySearch() {
1017
+ var criteria = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1018
+ var results = this._history;
1019
+
1020
+ // Filter by text content (case-insensitive)
1021
+ if (criteria.text) {
1022
+ var searchText = criteria.text.toLowerCase();
1023
+ results = results.filter(function (msg) {
1024
+ return msg.content.toLowerCase().includes(searchText);
1025
+ });
1026
+ }
1027
+
1028
+ // Filter by user
1029
+ if (criteria.userString) {
1030
+ results = results.filter(function (msg) {
1031
+ return msg.userString === criteria.userString;
1032
+ });
1033
+ }
1034
+
1035
+ // Filter by role
1036
+ if (criteria.role) {
1037
+ results = results.filter(function (msg) {
1038
+ return msg.role === criteria.role;
1039
+ });
1040
+ }
1041
+
1042
+ // Filter by tags (match any tag)
1043
+ if (criteria.tags && criteria.tags.length > 0) {
1044
+ results = results.filter(function (msg) {
1045
+ return msg.tags && msg.tags.some(function (tag) {
1046
+ return criteria.tags.includes(tag);
1047
+ });
1048
+ });
1049
+ }
1050
+
1051
+ // Limit results
1052
+ var limit = criteria.limit || 100;
1053
+ if (results.length > limit) {
1054
+ results = results.slice(0, limit);
1055
+ }
1056
+ return results;
1057
+ }
1058
+
1059
+ /**
1060
+ * Gets metadata and statistics about the message history
1061
+ * @param {number} [pageSize=50] - Page size for calculating total pages
1062
+ * @returns {Object} History information object
1063
+ * @returns {number} returns.totalMessages - Total number of messages
1064
+ * @returns {number} returns.totalPages - Total pages based on page size
1065
+ * @returns {Object|null} returns.oldestMessage - First message info
1066
+ * @returns {Object|null} returns.newestMessage - Last message info
1067
+ * @returns {Object} returns.memoryUsage - Memory usage statistics
1068
+ * @since 1.1.15
1069
+ * @example
1070
+ * const info = chat.historyGetInfo();
1071
+ * console.log(`Messages: ${info.totalMessages}`);
1072
+ * console.log(`Memory: ${info.memoryUsage.estimatedSize} bytes`);
1073
+ */
1074
+ }, {
1075
+ key: "historyGetInfo",
1076
+ value: function historyGetInfo() {
1077
+ var pageSize = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 50;
1078
+ var totalMessages = this._history.length;
1079
+ return {
1080
+ totalMessages: totalMessages,
1081
+ totalPages: Math.ceil(totalMessages / pageSize),
1082
+ oldestMessage: totalMessages > 0 ? {
1083
+ msgid: this._history[0].msgid,
1084
+ timestamp: this._history[0].timestamp,
1085
+ userString: this._history[0].userString
1086
+ } : null,
1087
+ newestMessage: totalMessages > 0 ? {
1088
+ msgid: this._history[totalMessages - 1].msgid,
1089
+ timestamp: this._history[totalMessages - 1].timestamp,
1090
+ userString: this._history[totalMessages - 1].userString
1091
+ } : null,
1092
+ memoryUsage: {
1093
+ estimatedSize: JSON.stringify(this._history).length,
1094
+ averageMessageSize: totalMessages > 0 ? Math.round(JSON.stringify(this._history).length / totalMessages) : 0
1095
+ }
1096
+ };
1097
+ }
1098
+
1099
+ /**
1100
+ * Clears all messages and resets the chat
1101
+ * @returns {void}
1102
+ * @example
1103
+ * chat.historyClear(); // Removes all messages
1104
+ */
690
1105
  }, {
691
1106
  key: "historyClear",
692
1107
  value: function historyClear() {
693
1108
  this.msgid = 0;
694
1109
  this._messagesArea.innerHTML = "";
695
1110
  this._history = [];
1111
+ this._activeTags.clear();
696
1112
  }
697
1113
  }, {
698
1114
  key: "historyGetLength",
@@ -717,7 +1133,7 @@ var quikchat = /*#__PURE__*/function () {
717
1133
  }, {
718
1134
  key: "historyRestoreAll",
719
1135
  value: function historyRestoreAll(messageList) {
720
- var _this2 = this;
1136
+ var _this3 = this;
721
1137
  // clear all messages and history
722
1138
  this.historyClear();
723
1139
 
@@ -726,7 +1142,7 @@ var quikchat = /*#__PURE__*/function () {
726
1142
 
727
1143
  // add all messages
728
1144
  messageList.forEach(function (message) {
729
- _this2.messageAddFull(message);
1145
+ _this3.messageAddFull(message);
730
1146
  });
731
1147
  }
732
1148
  /**
@@ -755,15 +1171,82 @@ var quikchat = /*#__PURE__*/function () {
755
1171
  *
756
1172
  * @returns {object} - Returns the version and license information for the library.
757
1173
  */
1174
+ /**
1175
+ * Gets the QuikChat version information
1176
+ * @static
1177
+ * @returns {Object} Version information object
1178
+ * @returns {string} returns.version - Version number (e.g., '1.1.15')
1179
+ * @returns {string} returns.license - License type (e.g., 'BSD-2')
1180
+ * @returns {string} returns.url - Project URL
1181
+ * @returns {boolean} returns.fun - Easter egg flag
1182
+ * @example
1183
+ * const version = quikchat.version();
1184
+ * console.log(`QuikChat v${version.version}`);
1185
+ */
1186
+ }, {
1187
+ key: "setTagVisibility",
1188
+ value:
1189
+ /**
1190
+ * Sets visibility for all messages with a specific tag
1191
+ * @param {string} tagName - Tag name to control
1192
+ * @param {boolean} isVisible - Whether to show or hide messages with this tag
1193
+ * @returns {boolean} True if successful, false if invalid tag name
1194
+ * @since 1.1.14
1195
+ * @example
1196
+ * // Hide all system messages
1197
+ * chat.setTagVisibility('system', false);
1198
+ *
1199
+ * // Show urgent messages
1200
+ * chat.setTagVisibility('urgent', true);
1201
+ */
1202
+ function setTagVisibility(tagName, isVisible) {
1203
+ if (typeof tagName !== 'string' || !/^[a-zA-Z0-9-]+$/.test(tagName)) {
1204
+ return false;
1205
+ }
1206
+ var className = "quikchat-show-tag-".concat(tagName);
1207
+ if (isVisible) {
1208
+ this._chatWidget.classList.add(className);
1209
+ } else {
1210
+ this._chatWidget.classList.remove(className);
1211
+ }
1212
+ this._updateMessageStyles();
1213
+ return true;
1214
+ }
1215
+
1216
+ /**
1217
+ * Gets the visibility state of a tag
1218
+ * @param {string} tagName - Tag name to check
1219
+ * @returns {boolean} True if tag is visible, false otherwise
1220
+ * @since 1.1.14
1221
+ * @example
1222
+ * const isVisible = chat.getTagVisibility('system');
1223
+ */
1224
+ }, {
1225
+ key: "getTagVisibility",
1226
+ value: function getTagVisibility(tagName) {
1227
+ if (typeof tagName !== 'string' || !/^[a-zA-Z0-9-]+$/.test(tagName)) {
1228
+ return false;
1229
+ }
1230
+ return this._chatWidget.classList.contains("quikchat-show-tag-".concat(tagName));
1231
+ }
1232
+
1233
+ /**
1234
+ * Gets all active tags in the chat
1235
+ * @returns {string[]} Array of all tags currently in use
1236
+ * @since 1.1.14
1237
+ * @example
1238
+ * const tags = chat.getActiveTags();
1239
+ * console.log('Active tags:', tags);
1240
+ */
1241
+ }, {
1242
+ key: "getActiveTags",
1243
+ value: function getActiveTags() {
1244
+ return Array.from(this._activeTags);
1245
+ }
758
1246
  }], [{
759
1247
  key: "version",
760
1248
  value: function version() {
761
- return {
762
- "version": "1.1.13",
763
- "license": "BSD-2",
764
- "url": "https://github/deftio/quikchat",
765
- "fun": true
766
- };
1249
+ return quikchatVersion;
767
1250
  }
768
1251
 
769
1252
  /**
@@ -783,6 +1266,21 @@ var quikchat = /*#__PURE__*/function () {
783
1266
  * //Returns a 200 Lorem Ipsum characters starting from a random index
784
1267
  * loremIpsum(200);
785
1268
  */
1269
+
1270
+ /**
1271
+ * Generates Lorem Ipsum placeholder text
1272
+ * @static
1273
+ * @param {number} [numChars] - Length of text to generate (random if not specified)
1274
+ * @param {number} [startSpot] - Starting offset in Lorem text (random if not specified)
1275
+ * @param {boolean} [startWithCapitalLetter=true] - Whether to capitalize first letter
1276
+ * @returns {string} Generated Lorem Ipsum text
1277
+ * @example
1278
+ * // Generate 100 characters
1279
+ * const text = quikchat.loremIpsum(100);
1280
+ *
1281
+ * // Generate random length
1282
+ * const randomText = quikchat.loremIpsum();
1283
+ */
786
1284
  }, {
787
1285
  key: "loremIpsum",
788
1286
  value: function loremIpsum(numChars) {
@@ -822,7 +1320,27 @@ var quikchat = /*#__PURE__*/function () {
822
1320
  }
823
1321
  }, {
824
1322
  key: "tempMessageGenerator",
825
- value: function tempMessageGenerator(domElement, content, interval) {
1323
+ value:
1324
+ /**
1325
+ * Creates a temporary message that updates periodically
1326
+ * @static
1327
+ * @param {string|HTMLElement} domElement - Element selector or DOM element
1328
+ * @param {string} content - Initial message content
1329
+ * @param {number} interval - Update interval in milliseconds (min 100ms)
1330
+ * @param {Function} [cb=null] - Callback to generate new content
1331
+ * @param {string} cb.message - Current message
1332
+ * @param {number} cb.count - Update count
1333
+ * @returns {void}
1334
+ * @example
1335
+ * // Simple loading indicator
1336
+ * quikchat.tempMessageGenerator('#loading', 'Loading', 500);
1337
+ *
1338
+ * // Custom update function
1339
+ * quikchat.tempMessageGenerator('#status', 'Processing', 1000, (msg, count) => {
1340
+ * return `Processing... ${count}%`;
1341
+ * });
1342
+ */
1343
+ function tempMessageGenerator(domElement, content, interval) {
826
1344
  var cb = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
827
1345
  interval = Math.max(interval, 100); // Ensure at least 100ms interval
828
1346