From 328be7ed7551a3be3f8f20b3c8f9c4575e99a04f Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Mon, 13 Sep 2021 14:08:10 +0200 Subject: [PATCH] 2.0.0 --- dist/build.js | 2 +- dist/build.js.map | 2 +- package-lock.json | 2 +- package.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dist/build.js b/dist/build.js index 69099be..05cc629 100644 --- a/dist/build.js +++ b/dist/build.js @@ -1,2 +1,2 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ChatMessages=e():t.ChatMessages=e()}(self,(function(){return(()=>{"use strict";var t={d:(e,n)=>{for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};function n(t){return function(t){if(Array.isArray(t))return r(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(t){if("string"==typeof t)return r(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(t,e):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function r(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);no});const o={name:"chat-messages",builder:function(t,e){var r={type:"object",properties:{"@context":{type:"string",default:"https://kosmos.org/ns/v1",enum:["https://kosmos.org/ns/v1"]},"@id":{type:"string",required:!0},"@type":{type:"string",default:"ChatChannel",enum:["ChatChannel"]},service:{type:"object",properties:{domain:{type:"string",required:!0},protocol:{type:"string",required:!0}}},name:{type:"string",required:!0},type:{type:"string",required:!0,enum:["room","person"]},today:{type:"object",properties:{"@id":{type:"string",pattern:"^[0-9]{4}/[0-9]{2}/[0-9]{2}$",required:!0},"@type":{type:"string",default:"ChatLog",pattern:"^ChatLog$"},messageType:{type:"string",default:"InstantMessage",pattern:"^InstantMessage$"},previous:{type:"string",pattern:"^[0-9]{4}/[0-9]{2}/[0-9]{2}$"},next:{type:"string",pattern:"^[0-9]{4}/[0-9]{2}/[0-9]{2}$"},messages:{type:"array",required:!0,items:{type:"object",properties:{date:{type:"string",format:"date-time"},user:{type:"string"},text:{type:"string"},type:"string",default:"text",enum:["text","join","leave","action"]}}}}}},required:[]};return t.declareType("daily-archive","https://kosmos.org/ns/v1",r),e.declareType("daily-archive","https://kosmos.org/ns/v1",r),{exports:{DailyArchive:function(){function r(n){if(function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,r),n.isPublic=n.isPublic||!1,n.channelType=n.channelType||"room","object"!==a(n))throw"options must be an object";if("object"!==a(n.service)||"string"!=typeof n.service.protocol||"string"!=typeof n.service.domain)throw'service must be an object containing at least service "protocol" and "domain"';if("string"!=typeof n.channelName)throw"channelName must be a string";if(!(n.date instanceof Date))throw"date must be a date object";if("boolean"!=typeof n.isPublic)throw"isPublic must be a boolean value";var i;if(this.service=n.service,this.channelName=n.channelName,this.channelType=n.channelType,this.date=n.date,this.isPublic=n.isPublic||!1,this.parsedDate={year:(i=this.date).getUTCFullYear(),month:s(i.getUTCMonth()+1),day:s(i.getUTCDate())},this.dateId=this.parsedDate.year+"/"+this.parsedDate.month+"/"+this.parsedDate.day,"room"===this.channelType){var o=this.channelName.replace(/#/,"");this.path="".concat(this.service.domain,"/channels/").concat(o,"/").concat(this.dateId)}else this.path="".concat(this.service.domain,"/users/").concat(this.channelName,"/").concat(this.dateId);this.client=this.isPublic?e:t,this.previous=n.previous,this.next=n.next}var o,c;return o=r,(c=[{key:"addMessage",value:function(t){var e=this;return this.isPublic&&!this.channelName.match(/^#/)?Promise.resolve(!1):(t.type=t.type||"text",this.client.getObject(this.path).then((function(n){return"object"===a(n)?e._updateDocument(n,t):e._createDocument(t)})))}},{key:"addMessages",value:function(t,e){var n=this;return this.isPublic&&!this.channelName.match(/^#/)?Promise.resolve(!1):(e=e||!1,t.forEach((function(t){t.type=t.type||"text"})),e?this._createDocument(t):this.client.getObject(this.path).then((function(e){return"object"===a(e)?n._updateDocument(e,t):n._createDocument(t)})))}},{key:"remove",value:function(){return this.client.remove(this.path)}},{key:"_updateDocument",value:function(t,e){return console.debug("[chat-messages] Updating archive document",t),Array.isArray(e)?e.forEach((function(e){t.today.messages.push(e)})):t.today.messages.push(e),this._sync(t)}},{key:"_createDocument",value:function(t){var e=this;console.debug("[chat-messages] Creating new archive document");var n=this._buildArchiveObject();return Array.isArray(t)?t.forEach((function(t){n.today.messages.push(t)})):n.today.messages.push(t),this.previous||this.next?(this.previous&&(n.today.previous=this.previous),this.next&&(n.today.next=this.next),this._sync(n)):this._updatePreviousArchive().then((function(t){return"object"===a(t)&&(n.today.previous=t.today["@id"]),e._sync(n)}))}},{key:"_buildArchiveObject",value:function(){var t=this.channelName.replace(/#/,""),e={"@id":"chat-messages/"+this.service.domain+"/channels/"+t+"/","@type":"ChatChannel",service:this.service,name:this.channelName,type:this.channelType,today:{"@id":this.dateId,"@type":"ChatLog",messageType:"InstantMessage",messages:[]}};switch(this.service.protocol){case"IRC":this.channelName.match(/^#/)||(e["@id"]="chat-messages/"+this.service.domain+"/users/"+this.channelName+"/")}return e}},{key:"_updatePreviousArchive",value:function(){var t=this;return this._findPreviousArchive().then((function(e){if("object"===a(e)&&e.today){e.today.next=t.dateId;var n=t.path.substring(0,t.path.length-t.dateId.length)+e.today["@id"];return t.client.storeObject("daily-archive",n,e).then((function(){return console.debug("[chat-messages] Previous archive written to remote storage",n,e),e}))}return console.debug("[chat-messages] Previous archive not found"),!1}))}},{key:"_findPreviousArchive",value:function(){var t=this,e=this.path.substring(0,this.path.length-2),r=this.path.substring(0,this.path.length-5),a=this.path.substring(0,this.path.length-10);return this.client.getListing(e).then((function(i){var o=Object.keys(i).map((function(t){return parseInt(t)})).map((function(e){return e0){var c=s(Math.max.apply(Math,n(o)).toString());return t.client.getObject(e+c)}return t.client.getListing(r).then((function(e){var i=Object.keys(e).map((function(t){return parseInt(t.substr(0,2))})).map((function(e){return e0){var o=s(Math.max.apply(Math,n(i)).toString());return t.client.getListing(r+o+"/").then((function(e){var a=Object.keys(e).map((function(t){return parseInt(t)})),i=s(Math.max.apply(Math,n(a)).toString());return t.client.getObject(r+o+"/"+i)}))}return t.client.getListing(a).then((function(e){var r=Object.keys(e).map((function(t){return parseInt(t.substr(0,4))})).map((function(e){return e0){var i=Math.max.apply(Math,n(r)).toString();return t.client.getListing(a+i+"/").then((function(e){var r=Object.keys(e).map((function(t){return parseInt(t.substr(0,2))})),o=s(Math.max.apply(Math,n(r)).toString());return t.client.getListing(a+i+"/"+o+"/").then((function(e){var r=Object.keys(e).map((function(t){return parseInt(t)})),c=s(Math.max.apply(Math,n(r)).toString());return t.client.getObject(a+i+"/"+o+"/"+c)}))}))}return!1}))}))}))}},{key:"_sync",value:function(t){return console.debug("[chat-messages] Writing archive object",t),this.client.storeObject("daily-archive",this.path,t).then((function(){return console.debug("[chat-messages] Archive written to remote storage"),!0}),(function(t){return console.warn("[chat-messages] Error trying to store object",t),t}))}}])&&i(o.prototype,c),r}(),privateClient:t,publicClient:e}}}};return e.default})()})); +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("ChatMessages",[],e):"object"==typeof exports?exports.ChatMessages=e():t.ChatMessages=e()}(this,(function(){return(()=>{"use strict";var t={d:(e,n)=>{for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};function n(t){return function(t){if(Array.isArray(t))return r(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(t){if("string"==typeof t)return r(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(t,e):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function r(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);no});const o={name:"chat-messages",builder:function(t,e){var r={type:"object",properties:{"@context":{type:"string",default:"https://kosmos.org/ns/v2",enum:["https://kosmos.org/ns/v2"]},"@id":{type:"string",required:!0},"@type":{type:"string",default:"ChatChannel",enum:["ChatChannel"]},service:{type:"object",properties:{domain:{type:"string",required:!0},protocol:{type:"string",required:!0}}},name:{type:"string",required:!0},type:{type:"string",required:!0,enum:["room","person"]},today:{type:"object",properties:{"@id":{type:"string",pattern:"^[0-9]{4}/[0-9]{2}/[0-9]{2}$",required:!0},"@type":{type:"string",default:"ChatLog",pattern:"^ChatLog$"},messageType:{type:"string",default:"InstantMessage",pattern:"^InstantMessage$"},previous:{type:"string",pattern:"^[0-9]{4}/[0-9]{2}/[0-9]{2}$"},next:{type:"string",pattern:"^[0-9]{4}/[0-9]{2}/[0-9]{2}$"},messages:{type:"array",required:!0,items:{type:"object",properties:{date:{type:"string",format:"date-time"},user:{type:"string"},text:{type:"string"},type:"string",default:"text",enum:["text","join","leave","action"]}}}}}},required:[]};return t.declareType("daily-archive","https://kosmos.org/ns/v2",r),e.declareType("daily-archive","https://kosmos.org/ns/v2",r),{exports:{DailyArchive:function(){function r(n){if(function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,r),n.isPublic=n.isPublic||!1,n.channelType=n.channelType||"room","object"!==a(n))throw"options must be an object";if("object"!==a(n.service)||"string"!=typeof n.service.protocol||"string"!=typeof n.service.domain)throw'service must be an object containing at least service "protocol" and "domain"';if("string"!=typeof n.channelName)throw"channelName must be a string";if(!(n.date instanceof Date))throw"date must be a date object";if("boolean"!=typeof n.isPublic)throw"isPublic must be a boolean value";var i;if(this.service=n.service,this.channelName=n.channelName,this.channelType=n.channelType,this.date=n.date,this.isPublic=n.isPublic||!1,this.parsedDate={year:(i=this.date).getUTCFullYear(),month:s(i.getUTCMonth()+1),day:s(i.getUTCDate())},this.dateId=this.parsedDate.year+"/"+this.parsedDate.month+"/"+this.parsedDate.day,"room"===this.channelType){var o=this.channelName.replace(/#/,"");this.path="".concat(this.service.domain,"/channels/").concat(o,"/").concat(this.dateId)}else this.path="".concat(this.service.domain,"/users/").concat(this.channelName,"/").concat(this.dateId);this.client=this.isPublic?e:t,this.previous=n.previous,this.next=n.next}var o,c;return o=r,(c=[{key:"addMessage",value:function(t){var e=this;return this.isPublic&&!this.channelName.match(/^#/)?Promise.resolve(!1):(t.type=t.type||"text",this.client.getObject(this.path).then((function(n){return"object"===a(n)?e._updateDocument(n,t):e._createDocument(t)})))}},{key:"addMessages",value:function(t,e){var n=this;return this.isPublic&&!this.channelName.match(/^#/)?Promise.resolve(!1):(e=e||!1,t.forEach((function(t){t.type=t.type||"text"})),e?this._createDocument(t):this.client.getObject(this.path).then((function(e){return"object"===a(e)?n._updateDocument(e,t):n._createDocument(t)})))}},{key:"remove",value:function(){return this.client.remove(this.path)}},{key:"_updateDocument",value:function(t,e){return console.debug("[chat-messages] Updating archive document"),Array.isArray(e)?e.forEach((function(e){t.today.messages.push(e)})):t.today.messages.push(e),this._sync(t)}},{key:"_createDocument",value:function(t){var e=this;console.debug("[chat-messages] Creating new archive document");var n=this._buildArchiveObject();return Array.isArray(t)?t.forEach((function(t){n.today.messages.push(t)})):n.today.messages.push(t),this.previous||this.next?(this.previous&&(n.today.previous=this.previous),this.next&&(n.today.next=this.next),this._sync(n)):this._updatePreviousArchive().then((function(t){return"object"===a(t)&&(n.today.previous=t.today["@id"]),e._sync(n)}))}},{key:"_buildArchiveObject",value:function(){var t=this.channelName.replace(/#/,""),e={"@id":"chat-messages/"+this.service.domain+"/channels/"+t+"/","@type":"ChatChannel",service:this.service,name:this.channelName,type:this.channelType,today:{"@id":this.dateId,"@type":"ChatLog",messageType:"InstantMessage",messages:[]}};switch(this.service.protocol){case"IRC":this.channelName.match(/^#/)||(e["@id"]="chat-messages/"+this.service.domain+"/users/"+this.channelName+"/")}return e}},{key:"_updatePreviousArchive",value:function(){var t=this;return this._findPreviousArchive().then((function(e){if("object"===a(e)&&e.today){e.today.next=t.dateId;var n=t.path.substring(0,t.path.length-t.dateId.length)+e.today["@id"];return t.client.storeObject("daily-archive",n,e).then((function(){return console.debug("[chat-messages] Previous archive written to remote storage",n,e),e}))}return console.debug("[chat-messages] Previous archive not found"),!1}))}},{key:"_findPreviousArchive",value:function(){var t=this,e=this.path.substring(0,this.path.length-2),r=this.path.substring(0,this.path.length-5),a=this.path.substring(0,this.path.length-10);return this.client.getListing(e).then((function(i){var o=Object.keys(i).map((function(t){return parseInt(t)})).map((function(e){return e0){var c=s(Math.max.apply(Math,n(o)).toString());return t.client.getObject(e+c)}return t.client.getListing(r).then((function(e){var i=Object.keys(e).map((function(t){return parseInt(t.substr(0,2))})).map((function(e){return e0){var o=s(Math.max.apply(Math,n(i)).toString());return t.client.getListing(r+o+"/").then((function(e){var a=Object.keys(e).map((function(t){return parseInt(t)})),i=s(Math.max.apply(Math,n(a)).toString());return t.client.getObject(r+o+"/"+i)}))}return t.client.getListing(a).then((function(e){var r=Object.keys(e).map((function(t){return parseInt(t.substr(0,4))})).map((function(e){return e0){var i=Math.max.apply(Math,n(r)).toString();return t.client.getListing(a+i+"/").then((function(e){var r=Object.keys(e).map((function(t){return parseInt(t.substr(0,2))})),o=s(Math.max.apply(Math,n(r)).toString());return t.client.getListing(a+i+"/"+o+"/").then((function(e){var r=Object.keys(e).map((function(t){return parseInt(t)})),c=s(Math.max.apply(Math,n(r)).toString());return t.client.getObject(a+i+"/"+o+"/"+c)}))}))}return!1}))}))}))}},{key:"_sync",value:function(t){return console.debug("[chat-messages] Writing archive object with ".concat(t.today.messages.length," messages")),this.client.storeObject("daily-archive",this.path,t).then((function(){return console.debug("[chat-messages] Archive written to remote storage"),!0}),(function(t){return console.warn("[chat-messages] Error trying to store object",t),t}))}}])&&i(o.prototype,c),r}(),privateClient:t,publicClient:e}}}};return e.default})()})); //# sourceMappingURL=build.js.map \ No newline at end of file diff --git a/dist/build.js.map b/dist/build.js.map index 52df3d8..e8cdf35 100644 --- a/dist/build.js.map +++ b/dist/build.js.map @@ -1 +1 @@ -{"version":3,"file":"build.js","mappings":"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","sources":["webpack://ChatMessages/webpack/universalModuleDefinition","webpack://ChatMessages/webpack/bootstrap","webpack://ChatMessages/webpack/runtime/define property getters","webpack://ChatMessages/webpack/runtime/hasOwnProperty shorthand","webpack://ChatMessages/./src/chat-messages.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ChatMessages\"] = factory();\n\telse\n\t\troot[\"ChatMessages\"] = factory();\n})(self, function() {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","function pad (num) {\n num = String(num);\n if (num.length === 1) { num = \"0\" + num; }\n return num;\n};\n\nfunction parseDate (date) {\n return {\n year: date.getUTCFullYear(),\n month: pad( date.getUTCMonth() + 1 ),\n day: pad( date.getUTCDate() )\n };\n};\n\nconst ChatMessages = function (privateClient, publicClient) {\n /**\n * Schema: chat-messages/daily\n *\n * Represents one calendar day of chat messages\n *\n * @example\n * {\n * \"@context\": \"https://kosmos.org/ns/v1\",\n * \"@id\": \"chat-messages/irc.libera.chat/channels/kosmos/\",\n * \"@type\": \"ChatChannel\",\n * \"service\": {\n * \"domain\": \"irc.libera.chat\",\n * \"protocol\": \"IRC\",\n * },\n * \"name\": \"#kosmos\",\n * \"type\": \"room\",\n * \"today\": {\n * \"@id\": \"2015/01/01\",\n * \"@type\": \"ChatLog\",\n * \"messageType\": \"InstantMessage\",\n * \"previous\": \"2014/12/31\",\n * \"next\": \"2015/01/02\",\n * \"messages\": [\n * { \"date\": \"2015-06-05T17:35:28.454Z\", \"user\": \"hal8000\", \"text\": \"knock knock\" },\n * { \"date\": \"2015-06-05T17:37:42.123Z\", \"user\": \"raucao\", \"text\": \"who's there?\" },\n * { \"date\": \"2015-06-05T17:55:01.235Z\", \"user\": \"hal8000\", \"text\": \"HAL\" }\n * ]\n * }\n * }\n */\n const archiveSchema = {\n \"type\": \"object\",\n \"properties\": {\n \"@context\": {\n \"type\": \"string\",\n \"default\": \"https://kosmos.org/ns/v1\",\n \"enum\": [\"https://kosmos.org/ns/v1\"]\n },\n \"@id\": {\n \"type\": \"string\",\n \"required\": true\n },\n \"@type\": {\n \"type\": \"string\",\n \"default\": \"ChatChannel\",\n \"enum\": [\"ChatChannel\"]\n },\n \"service\": {\n \"type\": \"object\",\n \"properties\": {\n \"domain\": {\n \"type\": \"string\",\n \"required\": true\n },\n \"protocol\": {\n \"type\": \"string\",\n \"required\": true\n }\n }\n },\n \"name\": {\n \"type\": \"string\",\n \"required\": true\n },\n \"type\": {\n \"type\": \"string\",\n \"required\": true,\n \"enum\": [ \"room\", \"person\" ]\n },\n \"today\": {\n \"type\": \"object\",\n \"properties\": {\n \"@id\": {\n \"type\": \"string\",\n \"pattern\": \"^[0-9]{4}\\/[0-9]{2}\\/[0-9]{2}$\",\n \"required\": true\n },\n \"@type\": {\n \"type\": \"string\",\n \"default\": \"ChatLog\",\n \"pattern\": \"^ChatLog$\"\n },\n \"messageType\": {\n \"type\": \"string\",\n \"default\": \"InstantMessage\",\n \"pattern\": \"^InstantMessage$\"\n },\n \"previous\": {\n \"type\": \"string\",\n \"pattern\": \"^[0-9]{4}\\/[0-9]{2}\\/[0-9]{2}$\"\n },\n \"next\": {\n \"type\": \"string\",\n \"pattern\": \"^[0-9]{4}\\/[0-9]{2}\\/[0-9]{2}$\"\n },\n \"messages\": {\n \"type\": \"array\",\n \"required\": true,\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"date\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"user\": {\n \"type\": \"string\"\n },\n \"text\": {\n \"type\": \"string\"\n },\n \"type\": \"string\",\n \"default\": \"text\",\n \"enum\": [\n \"text\",\n \"join\",\n \"leave\",\n \"action\"\n ]\n }\n }\n }\n }\n }\n },\n \"required\": []\n };\n\n privateClient.declareType(\"daily-archive\", \"https://kosmos.org/ns/v1\", archiveSchema);\n publicClient.declareType(\"daily-archive\", \"https://kosmos.org/ns/v1\", archiveSchema);\n\n /**\n * A daily archive stores chat messages by calendar day.\n *\n * @class\n */\n class DailyArchive {\n /**\n * @param {object} options\n * @param {object} options.service\n * @param {string} options.service.protocol - Type of chat service/protocol (e.g. \"IRC\", \"XMPP\", \"Campfire\", \"Slack\")\n * @param {string} options.service.domain - Domain of the chat service (e.g. \"irc.libera.chat\", \"kosmos.chat\")\n * @param {string} options.channelName - Name of room/channel (e.g. \"#kosmos\")\n * @param {string} [options.channelType] - Type of channel (\"room\" or \"person\")\n * @param {date} options.date - Date of archive day\n * @param {boolean} options.isPublic - Store logs in public folder (defaults to false)\n * @param {string} [options.previous] - Date of previous log file as `YYYY/MM/DD`. Looked up automatically when not given\n * @param {string} [options.next] - Date of next log file as `YYYY/MM/DD`. looked up automatically when not given\n *\n * @example\n * // IRC archive:\n * const archive = new chatMessages.DailyArchive({\n * service: {\n * protocol: 'IRC',\n * domain: 'irc.libera.chat',\n * },\n * channelName: '#kosmos-dev',\n * channelType: 'room',\n * date: new Date(),\n * isPublic: true\n * });\n *\n * // XMPP archive:\n * const archive = new chatMessages.DailyArchive({\n * service: {\n * protocol: 'XMPP',\n * domain: 'kosmos.chat',\n * },\n * channelName: 'kosmos-dev',\n * channelType: 'room',\n * date: new Date(),\n * isPublic: false\n * });\n *\n */\n constructor (options) {\n //\n // Defaults\n //\n options.isPublic = options.isPublic || false;\n options.channelType = options.channelType || \"room\";\n\n //\n // Validate options\n //\n if (typeof options !== \"object\") {\n throw \"options must be an object\";\n }\n if (typeof options.service !== \"object\" ||\n typeof options.service.protocol !== \"string\" ||\n typeof options.service.domain !== \"string\") {\n throw \"service must be an object containing at least service \\\"protocol\\\" and \\\"domain\\\"\";\n }\n if (typeof options.channelName !== \"string\") {\n throw \"channelName must be a string\";\n }\n if (!(options.date instanceof Date)) {\n throw \"date must be a date object\";\n }\n if (typeof options.isPublic !== \"boolean\") {\n throw \"isPublic must be a boolean value\";\n }\n\n /**\n * @property {object} service\n * @property {string} service.protocol - Type of chat service/protocol (e.g. \"IRC\", \"XMPP\", \"campfire\", \"slack\")\n * @property {string} service.domain - Domain of the chat service (e.g. \"irc.libera.chat\", \"kosmos.chat\")\n */\n this.service = options.service;\n\n /**\n * @property {string} channelName - Name of channel (e.g. \"#kosmos\")\n */\n this.channelName = options.channelName;\n\n /**\n * @property {string} channelType - Type of channel (\"room\" or \"person\")\n */\n this.channelType = options.channelType;\n\n /**\n * @property {string} date - Gregorian calendar date of the archive's content\n */\n this.date = options.date;\n\n /**\n * @property {boolean} isPublic - `true` for public archives, `false` for private ones\n */\n this.isPublic = options.isPublic || false;\n\n /**\n * @property {object} parsedDate - Contains padded year, month and day of date\n * @property {string} year\n * @property {string} month\n * @property {string} day\n */\n this.parsedDate = parseDate(this.date);\n\n /**\n * @property {string} dateId - Date string in the form of YYYY/MM/DD\n */\n this.dateId = this.parsedDate.year+'/'+this.parsedDate.month+'/'+this.parsedDate.day;\n\n /**\n * @property {string} path - Document path of the archive file\n */\n if (this.channelType === \"room\") {\n // Normal chatroom\n const channelName = this.channelName.replace(/#/,'');\n this.path = `${this.service.domain}/channels/${channelName}/${this.dateId}`;\n } else {\n // User direct message\n this.path = `${this.service.domain}/users/${this.channelName}/${this.dateId}`;\n }\n\n /**\n * @property {object} client - Public or private remoteStorgage.js BaseClient\n */\n this.client = this.isPublic ? publicClient : privateClient;\n\n /**\n * @property {string} previous - Date of previous log file as YYYY/MM/DD\n */\n this.previous = options.previous;\n\n /**\n * @property {string} next - Date of next log file as YYYY/MM/DD\n */\n this.next = options.next;\n }\n\n /*\n * @param {object} message\n * @param {string} message.timestamp - Timestamp of the message\n * @param {string} message.from - The sender of the message\n * @param {string} message.text - The message itself\n * @param {string} message.type - Type of message (one of text, join, leave, action)\n * @param {string} [message.id] - Unique ID of message. TODO implement\n *\n * @returns {Promise}\n */\n addMessage (message) {\n if (this.isPublic && !this.channelName.match(/^#/)) {\n return Promise.resolve(false);\n }\n\n message.type = message.type || 'text';\n\n return this.client.getObject(this.path).then((archive) => {\n if (typeof archive === 'object') {\n return this._updateDocument(archive, message);\n } else {\n return this._createDocument(message);\n }\n });\n }\n\n /*\n * Like , but for multiple messages at once. Useful for bulk\n * imports of messages.\n *\n * @param {Array} messages - Array of message objects (see params for addMessage)\n * @param {boolean} overwrite - If true, creates a new archive file and overwrites the old one. Defaults to false.\n *\n * @returns {Promise}\n */\n addMessages (messages, overwrite) {\n if (this.isPublic && !this.channelName.match(/^#/)) {\n return Promise.resolve(false);\n }\n\n overwrite = overwrite || false;\n\n messages.forEach(function(message) {\n message.type = message.type || 'text';\n });\n\n if (overwrite) {\n return this._createDocument(messages);\n } else {\n return this.client.getObject(this.path).then((archive) => {\n if (typeof archive === 'object') {\n return this._updateDocument(archive, messages);\n } else {\n return this._createDocument(messages);\n }\n });\n }\n }\n\n /*\n * Deletes the entire archive document from storage\n *\n * @returns {Promise}\n */\n remove () {\n return this.client.remove(this.path);\n }\n\n /*\n * Updates and writes an existing archive document\n *\n * @returns {Promise}\n *\n * @private\n */\n _updateDocument (archive, messages) {\n console.debug('[chat-messages] Updating archive document', archive);\n\n if (Array.isArray(messages)) {\n messages.forEach(function(message) {\n archive.today.messages.push(message);\n });\n } else {\n archive.today.messages.push(messages);\n }\n\n return this._sync(archive);\n }\n\n /*\n * Creates and writes a new archive document\n *\n * @returns {Promise}\n *\n * @private\n */\n _createDocument (messages) {\n console.debug('[chat-messages] Creating new archive document');\n const archive = this._buildArchiveObject();\n\n if (Array.isArray(messages)) {\n messages.forEach((message) => {\n archive.today.messages.push(message);\n });\n } else {\n archive.today.messages.push(messages);\n }\n\n if (this.previous || this.next) {\n // The app is handling previous/next keys itself\n // That includes setting 'next' in the previous log file\n if (this.previous) { archive.today.previous = this.previous; }\n if (this.next) { archive.today.next = this.next; }\n return this._sync(archive);\n } else {\n // Find and update previous archive, set 'previous' on this one\n return this._updatePreviousArchive().then((previous) => {\n if (typeof previous === 'object') {\n archive.today.previous = previous.today['@id'];\n }\n return this._sync(archive);\n });\n }\n }\n\n /*\n * Builds the object to be stored in remote storage\n *\n * @returns {object}\n *\n * @private\n */\n _buildArchiveObject () {\n const roomName = this.channelName.replace(/#/,'');\n\n const archive = {\n \"@id\": \"chat-messages/\"+this.service.domain+\"/channels/\"+roomName+\"/\",\n \"@type\": \"ChatChannel\",\n \"service\": this.service,\n \"name\": this.channelName,\n \"type\": this.channelType,\n \"today\": {\n \"@id\": this.dateId,\n \"@type\": \"ChatLog\",\n \"messageType\": \"InstantMessage\",\n \"messages\": []\n }\n };\n\n switch (this.service.protocol) {\n case 'IRC':\n if (!this.channelName.match(/^#/)) {\n archive[\"@id\"] = \"chat-messages/\"+this.service.domain+\"/users/\"+this.channelName+\"/\";\n }\n break;\n case 'XMPP':\n // XMPP-specific adjustments\n break;\n }\n\n return archive;\n }\n\n /*\n * Finds the previous archive document and updates its today.next value\n *\n * @returns {boolean|Promise}\n *\n * @private\n */\n _updatePreviousArchive () {\n return this._findPreviousArchive().then((archive) => {\n if (typeof archive === 'object' && archive.today) {\n archive.today.next = this.dateId;\n const path = this.path.substring(0, this.path.length-this.dateId.length)+archive.today['@id'];\n\n return this.client.storeObject('daily-archive', path, archive).then(() => {\n console.debug('[chat-messages] Previous archive written to remote storage', path, archive);\n return archive;\n });\n } else {\n console.debug('[chat-messages] Previous archive not found');\n return false;\n }\n });\n }\n\n /*\n * Returns the previous archive document\n *\n * @returns {Promise}\n *\n * @private\n */\n _findPreviousArchive () {\n const monthPath = this.path.substring(0, this.path.length-2);\n const yearPath = this.path.substring(0, this.path.length-5);\n const basePath = this.path.substring(0, this.path.length-10);\n\n return this.client.getListing(monthPath).then((listing) => {\n const days = Object.keys(listing).map((i) => parseInt(i)).map((i) => {\n return (i < parseInt(this.parsedDate.day)) ? i : null;\n }).filter(function(i){ return i != null; });\n\n if (days.length > 0) {\n const day = pad(Math.max(...days).toString());\n return this.client.getObject(monthPath+day);\n }\n\n // Find last day in previous month\n return this.client.getListing(yearPath).then((listing) => {\n const months = Object.keys(listing).map((i) => parseInt(i.substr(0,2))).map((i) => {\n return (i < parseInt(this.parsedDate.month)) ? i : null;\n }).filter(function(i){ return i != null; });\n\n if (months.length > 0) {\n const month = pad(Math.max(...months).toString());\n\n return this.client.getListing(yearPath+month+'/').then((listing) => {\n const days = Object.keys(listing).map((i) => parseInt(i));\n const day = pad(Math.max(...days).toString());\n return this.client.getObject(yearPath+month+'/'+day);\n });\n } else {\n // Find last month and day in previous year\n return this.client.getListing(basePath).then((listing) => {\n\n const years = Object.keys(listing).map((i) => parseInt(i.substr(0,4))).map((i) => {\n return (i < parseInt(this.parsedDate.year)) ? i : null;\n }).filter(function(i){ return i != null; });\n\n if (years.length > 0) {\n const year = Math.max(...years).toString();\n\n return this.client.getListing(basePath+year+'/').then((listing) => {\n const months = Object.keys(listing).map((i) => parseInt(i.substr(0,2)));\n const month = pad(Math.max(...months).toString());\n\n return this.client.getListing(basePath+year+'/'+month+'/').then((listing) => {\n const days = Object.keys(listing).map((i) => parseInt(i));\n const day = pad(Math.max(...days).toString());\n return this.client.getObject(basePath+year+'/'+month+'/'+day);\n });\n });\n } else {\n return false;\n }\n });\n }\n });\n });\n }\n\n /*\n * Write archive document\n *\n * @returns {Promise}\n *\n * @private\n */\n _sync (obj) {\n console.debug('[chat-messages] Writing archive object', obj);\n\n return this.client.storeObject('daily-archive', this.path, obj).then(function(){\n console.debug('[chat-messages] Archive written to remote storage');\n return true;\n },function(error){\n console.warn('[chat-messages] Error trying to store object', error);\n return error;\n });\n }\n };\n\n return {\n exports: {\n DailyArchive,\n privateClient,\n publicClient\n }\n };\n};\n\nexport default { name: 'chat-messages', builder: ChatMessages };\n"],"names":["root","factory","exports","module","define","amd","self","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","pad","num","String","length","name","builder","privateClient","publicClient","archiveSchema","declareType","DailyArchive","options","isPublic","channelType","service","protocol","domain","channelName","date","Date","this","parsedDate","year","getUTCFullYear","month","getUTCMonth","day","getUTCDate","dateId","replace","path","client","previous","next","message","match","Promise","resolve","type","getObject","then","archive","_updateDocument","_createDocument","messages","overwrite","forEach","remove","console","debug","Array","isArray","today","push","_sync","_buildArchiveObject","_updatePreviousArchive","roomName","_findPreviousArchive","substring","storeObject","monthPath","yearPath","basePath","getListing","listing","days","keys","map","i","parseInt","filter","Math","max","toString","months","substr","years","error","warn"],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"build.js","mappings":"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","sources":["webpack://ChatMessages/webpack/universalModuleDefinition","webpack://ChatMessages/webpack/bootstrap","webpack://ChatMessages/webpack/runtime/define property getters","webpack://ChatMessages/webpack/runtime/hasOwnProperty shorthand","webpack://ChatMessages/./src/chat-messages.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine(\"ChatMessages\", [], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ChatMessages\"] = factory();\n\telse\n\t\troot[\"ChatMessages\"] = factory();\n})(this, function() {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","function pad (num) {\n num = String(num);\n if (num.length === 1) { num = \"0\" + num; }\n return num;\n};\n\nfunction parseDate (date) {\n return {\n year: date.getUTCFullYear(),\n month: pad( date.getUTCMonth() + 1 ),\n day: pad( date.getUTCDate() )\n };\n};\n\nconst ChatMessages = function (privateClient, publicClient) {\n /**\n * Schema: chat-messages/daily\n *\n * Represents one calendar day of chat messages\n *\n * @example\n * {\n * \"@context\": \"https://kosmos.org/ns/v2\",\n * \"@id\": \"chat-messages/irc.libera.chat/channels/kosmos/\",\n * \"@type\": \"ChatChannel\",\n * \"service\": {\n * \"domain\": \"irc.libera.chat\",\n * \"protocol\": \"IRC\",\n * },\n * \"name\": \"#kosmos\",\n * \"type\": \"room\",\n * \"today\": {\n * \"@id\": \"2015/01/01\",\n * \"@type\": \"ChatLog\",\n * \"messageType\": \"InstantMessage\",\n * \"previous\": \"2014/12/31\",\n * \"next\": \"2015/01/02\",\n * \"messages\": [\n * { \"date\": \"2015-06-05T17:35:28.454Z\", \"user\": \"hal8000\", \"text\": \"knock knock\" },\n * { \"date\": \"2015-06-05T17:37:42.123Z\", \"user\": \"raucao\", \"text\": \"who's there?\" },\n * { \"date\": \"2015-06-05T17:55:01.235Z\", \"user\": \"hal8000\", \"text\": \"HAL\" }\n * ]\n * }\n * }\n */\n const archiveSchema = {\n \"type\": \"object\",\n \"properties\": {\n \"@context\": {\n \"type\": \"string\",\n \"default\": \"https://kosmos.org/ns/v2\",\n \"enum\": [\"https://kosmos.org/ns/v2\"]\n },\n \"@id\": {\n \"type\": \"string\",\n \"required\": true\n },\n \"@type\": {\n \"type\": \"string\",\n \"default\": \"ChatChannel\",\n \"enum\": [\"ChatChannel\"]\n },\n \"service\": {\n \"type\": \"object\",\n \"properties\": {\n \"domain\": {\n \"type\": \"string\",\n \"required\": true\n },\n \"protocol\": {\n \"type\": \"string\",\n \"required\": true\n }\n }\n },\n \"name\": {\n \"type\": \"string\",\n \"required\": true\n },\n \"type\": {\n \"type\": \"string\",\n \"required\": true,\n \"enum\": [ \"room\", \"person\" ]\n },\n \"today\": {\n \"type\": \"object\",\n \"properties\": {\n \"@id\": {\n \"type\": \"string\",\n \"pattern\": \"^[0-9]{4}\\/[0-9]{2}\\/[0-9]{2}$\",\n \"required\": true\n },\n \"@type\": {\n \"type\": \"string\",\n \"default\": \"ChatLog\",\n \"pattern\": \"^ChatLog$\"\n },\n \"messageType\": {\n \"type\": \"string\",\n \"default\": \"InstantMessage\",\n \"pattern\": \"^InstantMessage$\"\n },\n \"previous\": {\n \"type\": \"string\",\n \"pattern\": \"^[0-9]{4}\\/[0-9]{2}\\/[0-9]{2}$\"\n },\n \"next\": {\n \"type\": \"string\",\n \"pattern\": \"^[0-9]{4}\\/[0-9]{2}\\/[0-9]{2}$\"\n },\n \"messages\": {\n \"type\": \"array\",\n \"required\": true,\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"date\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"user\": {\n \"type\": \"string\"\n },\n \"text\": {\n \"type\": \"string\"\n },\n \"type\": \"string\",\n \"default\": \"text\",\n \"enum\": [\n \"text\",\n \"join\",\n \"leave\",\n \"action\"\n ]\n }\n }\n }\n }\n }\n },\n \"required\": []\n };\n\n privateClient.declareType(\"daily-archive\", \"https://kosmos.org/ns/v2\", archiveSchema);\n publicClient.declareType(\"daily-archive\", \"https://kosmos.org/ns/v2\", archiveSchema);\n\n /**\n * A daily archive stores chat messages by calendar day.\n *\n * @class\n */\n class DailyArchive {\n /**\n * @param {object} options\n * @param {object} options.service\n * @param {string} options.service.protocol - Type of chat service/protocol (e.g. \"IRC\", \"XMPP\", \"Campfire\", \"Slack\")\n * @param {string} options.service.domain - Domain of the chat service (e.g. \"irc.libera.chat\", \"kosmos.chat\")\n * @param {string} options.channelName - Name of room/channel (e.g. \"#kosmos\")\n * @param {string} [options.channelType] - Type of channel (\"room\" or \"person\")\n * @param {date} options.date - Date of archive day\n * @param {boolean} [options.isPublic] - Store logs in public folder (defaults to false)\n * @param {string} [options.previous] - Date of previous log file as `YYYY/MM/DD`. Looked up automatically when not given\n * @param {string} [options.next] - Date of next log file as `YYYY/MM/DD`. looked up automatically when not given\n *\n * @example\n * // IRC archive:\n * const archive = new chatMessages.DailyArchive({\n * service: {\n * protocol: 'IRC',\n * domain: 'irc.libera.chat',\n * },\n * channelName: '#kosmos-dev',\n * channelType: 'room',\n * date: new Date(),\n * isPublic: true\n * });\n *\n * // XMPP archive:\n * const archive = new chatMessages.DailyArchive({\n * service: {\n * protocol: 'XMPP',\n * domain: 'kosmos.chat',\n * },\n * channelName: 'kosmos-dev',\n * channelType: 'room',\n * date: new Date(),\n * isPublic: false\n * });\n *\n */\n constructor (options) {\n //\n // Defaults\n //\n options.isPublic = options.isPublic || false;\n options.channelType = options.channelType || \"room\";\n\n //\n // Validate options\n //\n if (typeof options !== \"object\") {\n throw \"options must be an object\";\n }\n if (typeof options.service !== \"object\" ||\n typeof options.service.protocol !== \"string\" ||\n typeof options.service.domain !== \"string\") {\n throw \"service must be an object containing at least service \\\"protocol\\\" and \\\"domain\\\"\";\n }\n if (typeof options.channelName !== \"string\") {\n throw \"channelName must be a string\";\n }\n if (!(options.date instanceof Date)) {\n throw \"date must be a date object\";\n }\n if (typeof options.isPublic !== \"boolean\") {\n throw \"isPublic must be a boolean value\";\n }\n\n /**\n * @property {object} service\n * @property {string} service.protocol - Type of chat service/protocol (e.g. \"IRC\", \"XMPP\", \"campfire\", \"slack\")\n * @property {string} service.domain - Domain of the chat service (e.g. \"irc.libera.chat\", \"kosmos.chat\")\n */\n this.service = options.service;\n\n /**\n * @property {string} channelName - Name of channel (e.g. \"#kosmos\")\n */\n this.channelName = options.channelName;\n\n /**\n * @property {string} channelType - Type of channel (\"room\" or \"person\")\n */\n this.channelType = options.channelType;\n\n /**\n * @property {string} date - Gregorian calendar date of the archive's content\n */\n this.date = options.date;\n\n /**\n * @property {boolean} isPublic - `true` for public archives, `false` for private ones\n */\n this.isPublic = options.isPublic || false;\n\n /**\n * @property {object} parsedDate - Contains padded year, month and day of date\n * @property {string} year\n * @property {string} month\n * @property {string} day\n */\n this.parsedDate = parseDate(this.date);\n\n /**\n * @property {string} dateId - Date string in the form of YYYY/MM/DD\n */\n this.dateId = this.parsedDate.year+'/'+this.parsedDate.month+'/'+this.parsedDate.day;\n\n /**\n * @property {string} path - Document path of the archive file\n */\n if (this.channelType === \"room\") {\n // Normal chatroom\n const channelName = this.channelName.replace(/#/,'');\n this.path = `${this.service.domain}/channels/${channelName}/${this.dateId}`;\n } else {\n // User direct message\n this.path = `${this.service.domain}/users/${this.channelName}/${this.dateId}`;\n }\n\n /**\n * @property {object} client - Public or private remoteStorgage.js BaseClient\n */\n this.client = this.isPublic ? publicClient : privateClient;\n\n /**\n * @property {string} previous - Date of previous log file as YYYY/MM/DD\n */\n this.previous = options.previous;\n\n /**\n * @property {string} next - Date of next log file as YYYY/MM/DD\n */\n this.next = options.next;\n }\n\n /*\n * @param {object} message\n * @param {string} message.timestamp - Timestamp of the message\n * @param {string} message.from - The sender of the message\n * @param {string} message.text - The message itself\n * @param {string} message.type - Type of message (one of text, join, leave, action)\n * @param {string} [message.id] - Unique ID of message. TODO implement\n *\n * @returns {Promise}\n */\n addMessage (message) {\n if (this.isPublic && !this.channelName.match(/^#/)) {\n return Promise.resolve(false);\n }\n\n message.type = message.type || 'text';\n\n return this.client.getObject(this.path).then((archive) => {\n if (typeof archive === 'object') {\n return this._updateDocument(archive, message);\n } else {\n return this._createDocument(message);\n }\n });\n }\n\n /*\n * Like , but for multiple messages at once. Useful for bulk\n * imports of messages.\n *\n * @param {Array} messages - Array of message objects (see params for addMessage)\n * @param {boolean} overwrite - If true, creates a new archive file and overwrites the old one. Defaults to false.\n *\n * @returns {Promise}\n */\n addMessages (messages, overwrite) {\n if (this.isPublic && !this.channelName.match(/^#/)) {\n return Promise.resolve(false);\n }\n\n overwrite = overwrite || false;\n\n messages.forEach(function(message) {\n message.type = message.type || 'text';\n });\n\n if (overwrite) {\n return this._createDocument(messages);\n } else {\n return this.client.getObject(this.path).then((archive) => {\n if (typeof archive === 'object') {\n return this._updateDocument(archive, messages);\n } else {\n return this._createDocument(messages);\n }\n });\n }\n }\n\n /*\n * Deletes the entire archive document from storage\n *\n * @returns {Promise}\n */\n remove () {\n return this.client.remove(this.path);\n }\n\n /*\n * Updates and writes an existing archive document\n *\n * @returns {Promise}\n *\n * @private\n */\n _updateDocument (archive, messages) {\n console.debug('[chat-messages] Updating archive document');\n\n if (Array.isArray(messages)) {\n messages.forEach(function(message) {\n archive.today.messages.push(message);\n });\n } else {\n archive.today.messages.push(messages);\n }\n\n return this._sync(archive);\n }\n\n /*\n * Creates and writes a new archive document\n *\n * @returns {Promise}\n *\n * @private\n */\n _createDocument (messages) {\n console.debug('[chat-messages] Creating new archive document');\n const archive = this._buildArchiveObject();\n\n if (Array.isArray(messages)) {\n messages.forEach((message) => {\n archive.today.messages.push(message);\n });\n } else {\n archive.today.messages.push(messages);\n }\n\n if (this.previous || this.next) {\n // The app is handling previous/next keys itself\n // That includes setting 'next' in the previous log file\n if (this.previous) { archive.today.previous = this.previous; }\n if (this.next) { archive.today.next = this.next; }\n return this._sync(archive);\n } else {\n // Find and update previous archive, set 'previous' on this one\n return this._updatePreviousArchive().then((previous) => {\n if (typeof previous === 'object') {\n archive.today.previous = previous.today['@id'];\n }\n return this._sync(archive);\n });\n }\n }\n\n /*\n * Builds the object to be stored in remote storage\n *\n * @returns {object}\n *\n * @private\n */\n _buildArchiveObject () {\n const roomName = this.channelName.replace(/#/,'');\n\n const archive = {\n \"@id\": \"chat-messages/\"+this.service.domain+\"/channels/\"+roomName+\"/\",\n \"@type\": \"ChatChannel\",\n \"service\": this.service,\n \"name\": this.channelName,\n \"type\": this.channelType,\n \"today\": {\n \"@id\": this.dateId,\n \"@type\": \"ChatLog\",\n \"messageType\": \"InstantMessage\",\n \"messages\": []\n }\n };\n\n switch (this.service.protocol) {\n case 'IRC':\n if (!this.channelName.match(/^#/)) {\n archive[\"@id\"] = \"chat-messages/\"+this.service.domain+\"/users/\"+this.channelName+\"/\";\n }\n break;\n case 'XMPP':\n // XMPP-specific adjustments\n break;\n }\n\n return archive;\n }\n\n /*\n * Finds the previous archive document and updates its today.next value\n *\n * @returns {boolean|Promise}\n *\n * @private\n */\n _updatePreviousArchive () {\n return this._findPreviousArchive().then((archive) => {\n if (typeof archive === 'object' && archive.today) {\n archive.today.next = this.dateId;\n const path = this.path.substring(0, this.path.length-this.dateId.length)+archive.today['@id'];\n\n return this.client.storeObject('daily-archive', path, archive).then(() => {\n console.debug('[chat-messages] Previous archive written to remote storage', path, archive);\n return archive;\n });\n } else {\n console.debug('[chat-messages] Previous archive not found');\n return false;\n }\n });\n }\n\n /*\n * Returns the previous archive document\n *\n * @returns {Promise}\n *\n * @private\n */\n _findPreviousArchive () {\n const monthPath = this.path.substring(0, this.path.length-2);\n const yearPath = this.path.substring(0, this.path.length-5);\n const basePath = this.path.substring(0, this.path.length-10);\n\n return this.client.getListing(monthPath).then((listing) => {\n const days = Object.keys(listing).map((i) => parseInt(i)).map((i) => {\n return (i < parseInt(this.parsedDate.day)) ? i : null;\n }).filter(function(i){ return i != null; });\n\n if (days.length > 0) {\n const day = pad(Math.max(...days).toString());\n return this.client.getObject(monthPath+day);\n }\n\n // Find last day in previous month\n return this.client.getListing(yearPath).then((listing) => {\n const months = Object.keys(listing).map((i) => parseInt(i.substr(0,2))).map((i) => {\n return (i < parseInt(this.parsedDate.month)) ? i : null;\n }).filter(function(i){ return i != null; });\n\n if (months.length > 0) {\n const month = pad(Math.max(...months).toString());\n\n return this.client.getListing(yearPath+month+'/').then((listing) => {\n const days = Object.keys(listing).map((i) => parseInt(i));\n const day = pad(Math.max(...days).toString());\n return this.client.getObject(yearPath+month+'/'+day);\n });\n } else {\n // Find last month and day in previous year\n return this.client.getListing(basePath).then((listing) => {\n\n const years = Object.keys(listing).map((i) => parseInt(i.substr(0,4))).map((i) => {\n return (i < parseInt(this.parsedDate.year)) ? i : null;\n }).filter(function(i){ return i != null; });\n\n if (years.length > 0) {\n const year = Math.max(...years).toString();\n\n return this.client.getListing(basePath+year+'/').then((listing) => {\n const months = Object.keys(listing).map((i) => parseInt(i.substr(0,2)));\n const month = pad(Math.max(...months).toString());\n\n return this.client.getListing(basePath+year+'/'+month+'/').then((listing) => {\n const days = Object.keys(listing).map((i) => parseInt(i));\n const day = pad(Math.max(...days).toString());\n return this.client.getObject(basePath+year+'/'+month+'/'+day);\n });\n });\n } else {\n return false;\n }\n });\n }\n });\n });\n }\n\n /*\n * Write archive document\n *\n * @returns {Promise}\n *\n * @private\n */\n _sync (obj) {\n console.debug(`[chat-messages] Writing archive object with ${obj.today.messages.length} messages`);\n\n return this.client.storeObject('daily-archive', this.path, obj).then(function(){\n console.debug('[chat-messages] Archive written to remote storage');\n return true;\n },function(error){\n console.warn('[chat-messages] Error trying to store object', error);\n return error;\n });\n }\n };\n\n return {\n exports: {\n DailyArchive,\n privateClient,\n publicClient\n }\n };\n};\n\nexport default { name: 'chat-messages', builder: ChatMessages };\n"],"names":["root","factory","exports","module","define","amd","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","pad","num","String","length","name","builder","privateClient","publicClient","archiveSchema","declareType","DailyArchive","options","isPublic","channelType","service","protocol","domain","channelName","date","Date","parsedDate","year","getUTCFullYear","month","getUTCMonth","day","getUTCDate","dateId","replace","path","client","previous","next","message","match","Promise","resolve","type","getObject","then","archive","_updateDocument","_createDocument","messages","overwrite","forEach","remove","console","debug","Array","isArray","today","push","_sync","_buildArchiveObject","_updatePreviousArchive","roomName","_findPreviousArchive","substring","storeObject","monthPath","yearPath","basePath","getListing","listing","days","keys","map","i","parseInt","filter","Math","max","toString","months","substr","years","error","warn"],"sourceRoot":""} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 1cddecd..84a6b1e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "remotestorage-module-chat-messages", - "version": "1.0.1", + "version": "2.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 533bee6..5547183 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "remotestorage-module-chat-messages", - "version": "1.0.1", + "version": "2.0.0", "description": "Stores chat messages in daily archive files", "main": "./dist/build.js", "scripts": {