From e803a1e79913a5a4a864d729520b2fca9992f20b Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Sun, 5 Sep 2021 14:05:06 +0200 Subject: [PATCH 1/3] Move source to src directory --- dist/build.js | 3 ++- dist/build.js.map | 2 +- index.js => src/chat-messages.js | 0 webpack.config.js | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) rename index.js => src/chat-messages.js (100%) diff --git a/dist/build.js b/dist/build.js index 22e3664..1902daf 100644 --- a/dist/build.js +++ b/dist/build.js @@ -1 +1,2 @@ -!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var n=e();for(var r in n)("object"==typeof exports?exports:t)[r]=n[r]}}(this,function(){return function(t){function e(r){if(n[r])return n[r].exports;var s=n[r]={exports:{},id:r,loaded:!1};return t[r].call(s.exports,s,s.exports,e),s.loaded=!0,s.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e){"use strict";function n(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e0){var u=a(Math.max.apply(Math,n(o)).toString());return t.client.getObject(e+u)}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=a(Math.max.apply(Math,n(i)).toString());return t.client.getListing(r+o+"/").then(function(e){var s=Object.keys(e).map(function(t){return parseInt(t)}),i=a(Math.max.apply(Math,n(s)).toString());return t.client.getObject(r+o+"/"+i)})}return t.client.getListing(s).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(s+i+"/").then(function(e){var r=Object.keys(e).map(function(t){return parseInt(t.substr(0,2))}),o=a(Math.max.apply(Math,n(r)).toString());return t.client.getListing(s+i+"/"+o+"/").then(function(e){var r=Object.keys(e).map(function(t){return parseInt(t)}),u=a(Math.max.apply(Math,n(r)).toString());return t.client.getObject(s+i+"/"+o+"/"+u)})})}return!1})})})},_sync: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})}};var a=function(t){return t=String(t),1===t.length&&(t="0"+t),t},o=function(t){return{year:t.getUTCFullYear(),month:a(t.getUTCMonth()+1),day:a(t.getUTCDate())}},u={DailyArchive:i,privateClient:t,publicClient:e};return{exports:u}};e.default={name:"chat-messages",builder:s}}])}); \ No newline at end of file +!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"]},name:{type:"string",required:!0},ircURI:{type:"string",format:"uri"},xmppURI:{type:"string",format:"uri"},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,"object"!==a(n))throw"options must be an object";if("object"!==a(n.server)||"string"!=typeof n.server.type||"string"!=typeof n.server.name)throw'server must be an object containing at least server "type" and "name"';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 s;switch(this.server=n.server,this.channelName=n.channelName,this.date=n.date,this.isPublic=n.isPublic,this.parsedDate={year:(s=this.date).getUTCFullYear(),month:i(s.getUTCMonth()+1),day:i(s.getUTCDate())},this.dateId=this.parsedDate.year+"/"+this.parsedDate.month+"/"+this.parsedDate.day,this.server.type){case"irc":if(this.channelName.match(/^#/)){var o=this.channelName.replace(/^#/,"");this.path="".concat(this.server.name,"/channels/").concat(o,"/").concat(this.dateId)}else this.path="".concat(this.server.name,"/users/").concat(this.channelName,"/").concat(this.dateId);break;default:this.path="".concat(this.server.name,"/").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.server.name+"/channels/"+t+"/","@type":"ChatChannel",name:this.channelName,today:{"@id":this.dateId,"@type":"ChatLog",messageType:"InstantMessage",messages:[]}};switch(this.server.type){case"irc":this.channelName.match(/^#/)||(e["@id"]="chat-messages/"+this.server.name+"/users/"+this.channelName+"/"),e.ircURI=this.server.ircURI+"/"+t;break;case"xmpp":e.xmppURI="xmpp:".concat(this.channelName,"@").concat(this.server.xmppMUC)}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(s){var o=Object.keys(s).map((function(t){return parseInt(t)})).map((function(e){return e0){var c=i(Math.max.apply(Math,n(o)).toString());return t.client.getObject(e+c)}return t.client.getListing(r).then((function(e){var s=Object.keys(e).map((function(t){return parseInt(t.substr(0,2))})).map((function(e){return e0){var o=i(Math.max.apply(Math,n(s)).toString());return t.client.getListing(r+o+"/").then((function(e){var a=Object.keys(e).map((function(t){return parseInt(t)})),s=i(Math.max.apply(Math,n(a)).toString());return t.client.getObject(r+o+"/"+s)}))}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 s=Math.max.apply(Math,n(r)).toString();return t.client.getListing(a+s+"/").then((function(e){var r=Object.keys(e).map((function(t){return parseInt(t.substr(0,2))})),o=i(Math.max.apply(Math,n(r)).toString());return t.client.getListing(a+s+"/"+o+"/").then((function(e){var r=Object.keys(e).map((function(t){return parseInt(t)})),c=i(Math.max.apply(Math,n(r)).toString());return t.client.getObject(a+s+"/"+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}))}}])&&s(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 aa77f35..390cda1 100644 --- a/dist/build.js.map +++ b/dist/build.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap fea08dbeb235bc9f8782","webpack:///./index.js","webpack:///external {\"root\":\"RemoteStorage\",\"commonjs2\":\"remotestoragejs\",\"commonjs\":\"remotestoragejs\",\"amd\":\"remotestoragejs\"}"],"names":["RemoteStorage","require","defineModule","privateClient","publicClient","archiveSchema","declareType","DailyArchive","options","isPublic","server","type","name","channelName","date","Date","parsedDate","parseDate","dateId","year","month","day","match","replace","path","client","previous","next","prototype","addMessage","message","Promise","resolve","getObject","then","archive","_updateDocument","_createDocument","addMessages","messages","overwrite","forEach","remove","log","Array","isArray","today","push","_sync","_buildArchiveObject","_updatePreviousArchive","roomName","ircURI","xmppMUC","_findPreviousArchive","substring","length","storeObject","monthPath","yearPath","basePath","getListing","listing","days","Object","keys","map","i","parseInt","filter","pad","Math","max","toString","months","substr","years","obj","error","console","num","String","getUTCFullYear","getUTCMonth","getUTCDate","exports"],"mappings":"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","file":"/home/basti/src/remotestorage/modules/remotestorage-module-chat-messages/dist/build.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"remotestoragejs\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"remotestoragejs\"], factory);\n\telse {\n\t\tvar a = typeof exports === 'object' ? factory(require(\"remotestoragejs\")) : factory(root[\"RemoteStorage\"]);\n\t\tfor(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n\t}\n})(this, function(__WEBPACK_EXTERNAL_MODULE_1__) {\nreturn \n\n\n// WEBPACK FOOTER //\n// webpack/universalModuleDefinition"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap fea08dbeb235bc9f8782","var RemoteStorage = require('remotestoragejs');\n\nRemoteStorage.defineModule(\"chat-messages\", function (privateClient, publicClient) {\n\n /**\n * Schema: chat-messages/daily\n *\n * Represents one day of chat messages\n *\n * Example:\n *\n * (start code)\n * {\n * \"@context\": \"https://kosmos.org/ns/v1\",\n * \"@id\": \"chat-messages/freenode/channels/kosmos/\",\n * \"@type\": \"ChatChannel\",\n * \"name\": \"#kosmos\",\n * \"ircURI\": \"irc://irc.freenode.net/kosmos\",\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 * (end code)\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 \"name\": {\n \"type\": \"string\",\n \"required\": true\n },\n \"ircURI\": {\n \"type\": \"string\",\n \"format\": \"uri\"\n },\n \"xmppURI\": {\n \"type\": \"string\",\n \"format\": \"uri\"\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 * Class: DailyArchive\n *\n * A daily archive stores IRC messages by day.\n *\n * Parameters (object):\n * server - Chat server info (see )\n * channelName - Name of room/channel\n * date - Date of archive day\n * isPublic - Store logs in public folder (defaults to false)\n * previous - Date of previous log file as YYYY/MM/DD;\n * looked up automatically when not given\n * next - Date of next log file as YYYY/MM/DD;\n * looked up automatically when not given\n *\n * Example for IRC:\n *\n * (start code)\n * var archive = new chatMessages.DailyArchive({\n * server: {\n * type: 'irc',\n * name: 'freenode',\n * ircURI: 'irc://irc.freenode.net'\n * },\n * channelName: '#kosmos',\n * date: new Date(),\n * isPublic: true\n * });\n * (end code)\n *\n * Example for XMPP:\n *\n * (start code)\n * var archive = new chatMessages.DailyArchive({\n * server: {\n * type: 'xmpp',\n * name: '5apps',\n * xmppMUC: 'muc.5apps.com'\n * },\n * channelName: 'watercooler',\n * date: new Date(),\n * isPublic: false\n * });\n * (end code)\n */\n var DailyArchive = function DailyArchive(options) {\n //\n // Defaults\n //\n options.isPublic = options.isPublic || false;\n\n //\n // Validate options\n //\n if (typeof options !== \"object\") {\n throw \"options must be an object\";\n }\n if (typeof options.server !== \"object\" ||\n typeof options.server.type !== \"string\" ||\n typeof options.server.name !== \"string\") {\n throw \"server must be an object containing at least server \\\"type\\\" and \\\"name\\\"\";\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: server\n *\n * Contains information about the chat server/network\n *\n * Properties:\n * type - Type of server/protocol (e.g. \"irc\", \"xmpp\", \"campfire\", \"slack\")\n * name - Shortname/id/alias of network/server (e.g. \"freenode\", \"mycompanyname\")\n * ircURI - (optional) IRC URI of network (e.g. \"irc://irc.freenode.net/\")\n * xmppMUC - (optional) XMPP MUC service host (e.g. \"conference.jabber.org\")\n */\n this.server = options.server;\n\n /**\n * Property: channelName\n *\n * Name of the IRC channel (e.g. \"#kosmos\")\n */\n this.channelName = options.channelName;\n\n /**\n * Property: date\n *\n * Date of the archive's content\n */\n this.date = options.date;\n\n /**\n * Property: isPublic\n *\n * `true` for public archives, `false` for private ones\n */\n this.isPublic = options.isPublic;\n\n /**\n * Property: parsedDate\n *\n * Object containing padded year, month and day of date\n */\n this.parsedDate = parseDate(this.date);\n\n /**\n * Property: dateId\n *\n * 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: path\n *\n * Document path of the archive file\n */\n switch (this.server.type) {\n case 'irc':\n if (this.channelName.match(/^#/)) {\n // normal chatroom\n var channelName = this.channelName.replace(/^#/,'');\n this.path = `${this.server.name}/channels/${channelName}/${this.dateId}`;\n } else {\n // user direct message\n this.path = `${this.server.name}/users/${this.channelName}/${this.dateId}`;\n }\n break;\n default:\n this.path = `${this.server.name}/${this.channelName}/${this.dateId}`;\n break;\n }\n\n /**\n * Property: client\n *\n * Public or private BaseClient, depending on isPublic\n */\n this.client = this.isPublic ? publicClient : privateClient;\n\n /**\n * Property: previous\n *\n * Date of previous log file as YYYY/MM/DD\n */\n this.previous = options.previous;\n\n /**\n * Property: next\n *\n * Date of next log file as YYYY/MM/DD\n */\n this.next = options.next;\n };\n\n DailyArchive.prototype = {\n /*\n * Method: addMessage\n *\n * Parameters (object):\n * timestamp - Timestamp of the message\n * from - The sender of the message\n * text - The message itself\n * type - Type of message (one of text, join, leave, action)\n */\n addMessage: function 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 * Method: addMessages\n *\n * Like , but for multiple messages at once. Useful for bulk\n * imports of messages.\n *\n * Parameters:\n * messages - Array of message objects (see params for addMessage)\n * overwrite - If true, creates a new archive file and overwrites the\n * old one. Defaults to false.\n */\n addMessages: function addMessage(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 * Method: remove\n *\n * Deletes the entire archive document from storage\n */\n remove: function() {\n return this.client.remove(this.path);\n },\n\n /*\n * Method: _updateDocument\n *\n * Updates and writes an existing archive document\n */\n _updateDocument: function(archive, messages) {\n RemoteStorage.log('[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 * Method: _createDocument\n *\n * Creates and writes a new archive document\n */\n _createDocument: function(messages) {\n RemoteStorage.log('[chat-messages] Creating new archive document');\n let 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 * Method: _buildArchiveObject\n *\n * Builds the object to be stored in remote storage\n */\n _buildArchiveObject: function() {\n let roomName = this.channelName.replace(/#/,'');\n\n let archive = {\n \"@id\": \"chat-messages/\"+this.server.name+\"/channels/\"+roomName+\"/\",\n \"@type\": \"ChatChannel\",\n \"name\": this.channelName,\n \"today\": {\n \"@id\": this.dateId,\n \"@type\": \"ChatLog\",\n \"messageType\": \"InstantMessage\",\n \"messages\": []\n }\n };\n\n switch (this.server.type) {\n case 'irc':\n if (!this.channelName.match(/^#/)) {\n archive[\"@id\"] = \"chat-messages/\"+this.server.name+\"/users/\"+this.channelName+\"/\";\n }\n archive[\"ircURI\"] = this.server.ircURI+\"/\"+roomName;\n break;\n case 'xmpp':\n archive[\"xmppURI\"] = `xmpp:${this.channelName}@${this.server.xmppMUC}`;\n break;\n }\n\n return archive;\n },\n\n /*\n * Method: _updatePreviousArchive\n *\n * Finds the previous archive document and updates its today.next value\n */\n _updatePreviousArchive: function() {\n return this._findPreviousArchive().then((archive) => {\n if (typeof archive === 'object' && archive.today) {\n archive.today.next = this.dateId;\n let 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 RemoteStorage.log('[chat-messages] Previous archive written to remote storage', path, archive);\n return archive;\n });\n } else {\n RemoteStorage.log('[chat-messages] Previous archive not found');\n return false;\n }\n });\n },\n\n /*\n * Method: _findPreviousArchive\n *\n * Returns the previous archive document\n */\n _findPreviousArchive: function() {\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 let 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 let 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 let 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 let month = pad(Math.max(...months).toString());\n\n return this.client.getListing(yearPath+month+'/').then((listing) => {\n let days = Object.keys(listing).map((i) => parseInt(i));\n let 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 let 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 let year = Math.max(...years).toString();\n\n return this.client.getListing(basePath+year+'/').then((listing) => {\n let months = Object.keys(listing).map((i) => parseInt(i.substr(0,2)));\n let month = pad(Math.max(...months).toString());\n\n return this.client.getListing(basePath+year+'/'+month+'/').then((listing) => {\n let days = Object.keys(listing).map((i) => parseInt(i));\n let 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 * Method: _sync\n *\n * Write archive document\n */\n _sync: function(obj) {\n RemoteStorage.log('[chat-messages] Writing archive object', obj);\n\n return this.client.storeObject('daily-archive', this.path, obj).then(function(){\n RemoteStorage.log('[chat-messages] Archive written to remote storage');\n return true;\n },function(error){\n console.log('[chat-messages] Error trying to store object', error);\n return error;\n });\n }\n };\n\n var pad = function(num) {\n num = String(num);\n if (num.length === 1) { num = \"0\" + num; }\n return num;\n };\n\n var parseDate = function(date) {\n return {\n year: date.getUTCFullYear(),\n month: pad( date.getUTCMonth() + 1 ),\n day: pad( date.getUTCDate() )\n };\n };\n\n var exports = {\n DailyArchive: DailyArchive,\n privateClient: privateClient,\n publicClient: publicClient\n };\n\n // Return public functions\n return { exports: exports };\n});\n\n\n\n// WEBPACK FOOTER //\n// ./index.js","module.exports = __WEBPACK_EXTERNAL_MODULE_1__;\n\n\n//////////////////\n// WEBPACK FOOTER\n// external {\"root\":\"RemoteStorage\",\"commonjs2\":\"remotestoragejs\",\"commonjs\":\"remotestoragejs\",\"amd\":\"remotestoragejs\"}\n// module id = 1\n// module chunks = 0"],"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([], 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 day of chat messages\n *\n * Example:\n *\n * (start code)\n * {\n * \"@context\": \"https://kosmos.org/ns/v1\",\n * \"@id\": \"chat-messages/freenode/channels/kosmos/\",\n * \"@type\": \"ChatChannel\",\n * \"name\": \"#kosmos\",\n * \"ircURI\": \"irc://irc.freenode.net/kosmos\",\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 * (end code)\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 \"name\": {\n \"type\": \"string\",\n \"required\": true\n },\n \"ircURI\": {\n \"type\": \"string\",\n \"format\": \"uri\"\n },\n \"xmppURI\": {\n \"type\": \"string\",\n \"format\": \"uri\"\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 * Class: DailyArchive\n *\n * A daily archive stores IRC messages by day.\n *\n * Parameters (object):\n * server - Chat server info (see )\n * channelName - Name of room/channel\n * date - Date of archive day\n * isPublic - Store logs in public folder (defaults to false)\n * previous - Date of previous log file as YYYY/MM/DD;\n * looked up automatically when not given\n * next - Date of next log file as YYYY/MM/DD;\n * looked up automatically when not given\n *\n * Example for IRC:\n *\n * (start code)\n * const archive = new chatMessages.DailyArchive({\n * server: {\n * type: 'irc',\n * name: 'freenode',\n * ircURI: 'irc://irc.freenode.net'\n * },\n * channelName: '#kosmos',\n * date: new Date(),\n * isPublic: true\n * });\n * (end code)\n *\n * Example for XMPP:\n *\n * (start code)\n * const archive = new chatMessages.DailyArchive({\n * server: {\n * type: 'xmpp',\n * name: '5apps',\n * xmppMUC: 'muc.5apps.com'\n * },\n * channelName: 'watercooler',\n * date: new Date(),\n * isPublic: false\n * });\n * (end code)\n */\n class DailyArchive {\n constructor (options) {\n //\n // Defaults\n //\n options.isPublic = options.isPublic || false;\n\n //\n // Validate options\n //\n if (typeof options !== \"object\") {\n throw \"options must be an object\";\n }\n if (typeof options.server !== \"object\" ||\n typeof options.server.type !== \"string\" ||\n typeof options.server.name !== \"string\") {\n throw \"server must be an object containing at least server \\\"type\\\" and \\\"name\\\"\";\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: server\n *\n * Contains information about the chat server/network\n *\n * Properties:\n * type - Type of server/protocol (e.g. \"irc\", \"xmpp\", \"campfire\", \"slack\")\n * name - Shortname/id/alias of network/server (e.g. \"freenode\", \"mycompanyname\")\n * ircURI - (optional) IRC URI of network (e.g. \"irc://irc.freenode.net/\")\n * xmppMUC - (optional) XMPP MUC service host (e.g. \"conference.jabber.org\")\n */\n this.server = options.server;\n\n /**\n * Property: channelName\n *\n * Name of the IRC channel (e.g. \"#kosmos\")\n */\n this.channelName = options.channelName;\n\n /**\n * Property: date\n *\n * Date of the archive's content\n */\n this.date = options.date;\n\n /**\n * Property: isPublic\n *\n * `true` for public archives, `false` for private ones\n */\n this.isPublic = options.isPublic;\n\n /**\n * Property: parsedDate\n *\n * Object containing padded year, month and day of date\n */\n this.parsedDate = parseDate(this.date);\n\n /**\n * Property: dateId\n *\n * 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: path\n *\n * Document path of the archive file\n */\n switch (this.server.type) {\n case 'irc':\n if (this.channelName.match(/^#/)) {\n // normal chatroom\n const channelName = this.channelName.replace(/^#/,'');\n this.path = `${this.server.name}/channels/${channelName}/${this.dateId}`;\n } else {\n // user direct message\n this.path = `${this.server.name}/users/${this.channelName}/${this.dateId}`;\n }\n break;\n default:\n this.path = `${this.server.name}/${this.channelName}/${this.dateId}`;\n break;\n }\n\n /**\n * Property: client\n *\n * Public or private BaseClient, depending on isPublic\n */\n this.client = this.isPublic ? publicClient : privateClient;\n\n /**\n * Property: previous\n *\n * Date of previous log file as YYYY/MM/DD\n */\n this.previous = options.previous;\n\n /**\n * Property: next\n *\n * Date of next log file as YYYY/MM/DD\n */\n this.next = options.next;\n }\n\n /*\n * Method: addMessage\n *\n * Parameters (object):\n * timestamp - Timestamp of the message\n * from - The sender of the message\n * text - The message itself\n * type - Type of message (one of text, join, leave, action)\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 * Method: addMessages\n *\n * Like , but for multiple messages at once. Useful for bulk\n * imports of messages.\n *\n * Parameters:\n * messages - Array of message objects (see params for addMessage)\n * overwrite - If true, creates a new archive file and overwrites the\n * old one. Defaults to false.\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 * Method: remove\n *\n * Deletes the entire archive document from storage\n */\n remove () {\n return this.client.remove(this.path);\n }\n\n /*\n * Method: _updateDocument\n *\n * Updates and writes an existing archive document\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 * Method: _createDocument\n *\n * Creates and writes a new archive document\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 * Method: _buildArchiveObject\n *\n * Builds the object to be stored in remote storage\n */\n _buildArchiveObject () {\n const roomName = this.channelName.replace(/#/,'');\n\n const archive = {\n \"@id\": \"chat-messages/\"+this.server.name+\"/channels/\"+roomName+\"/\",\n \"@type\": \"ChatChannel\",\n \"name\": this.channelName,\n \"today\": {\n \"@id\": this.dateId,\n \"@type\": \"ChatLog\",\n \"messageType\": \"InstantMessage\",\n \"messages\": []\n }\n };\n\n switch (this.server.type) {\n case 'irc':\n if (!this.channelName.match(/^#/)) {\n archive[\"@id\"] = \"chat-messages/\"+this.server.name+\"/users/\"+this.channelName+\"/\";\n }\n archive[\"ircURI\"] = this.server.ircURI+\"/\"+roomName;\n break;\n case 'xmpp':\n archive[\"xmppURI\"] = `xmpp:${this.channelName}@${this.server.xmppMUC}`;\n break;\n }\n\n return archive;\n }\n\n /*\n * Method: _updatePreviousArchive\n *\n * Finds the previous archive document and updates its today.next value\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 * Method: _findPreviousArchive\n *\n * Returns the previous archive document\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 * Method: _sync\n *\n * Write archive document\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","server","type","channelName","date","Date","this","parsedDate","year","getUTCFullYear","month","getUTCMonth","day","getUTCDate","dateId","match","replace","path","client","previous","next","message","Promise","resolve","getObject","then","archive","_updateDocument","_createDocument","messages","overwrite","forEach","remove","console","debug","Array","isArray","today","push","_sync","_buildArchiveObject","_updatePreviousArchive","roomName","ircURI","xmppMUC","_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/index.js b/src/chat-messages.js similarity index 100% rename from index.js rename to src/chat-messages.js diff --git a/webpack.config.js b/webpack.config.js index 6c91985..fc0e132 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -3,7 +3,7 @@ const isProd = (process.env.NODE_ENV === 'production'); const path = require('path'); module.exports = { - entry: ['./index.js'], + entry: ['./src/chat-messages.js'], output: { path: path.resolve(__dirname, 'dist'), filename: 'build.js', From dd1bfd08ea1d976162900c942c5a0d75f44df066 Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Sun, 5 Sep 2021 15:09:16 +0200 Subject: [PATCH 2/3] Update data model, documentation * Port NaturalDocs code documentation to JSDoc * server --> service, server.name --> service.domain, server.type --> service.protocol * Remove ircURI and xmppURI in favor of service.protocol * Add channel type ("room" or "person") * Change document path to use service domain instead of custom id/name --- src/chat-messages.js | 292 +++++++++++++++++++++---------------------- 1 file changed, 145 insertions(+), 147 deletions(-) diff --git a/src/chat-messages.js b/src/chat-messages.js index e7c4caa..573966f 100644 --- a/src/chat-messages.js +++ b/src/chat-messages.js @@ -16,18 +16,20 @@ const ChatMessages = function (privateClient, publicClient) { /** * Schema: chat-messages/daily * - * Represents one day of chat messages + * Represents one calendar day of chat messages * - * Example: - * - * (start code) + * @example * { * "@context": "https://kosmos.org/ns/v1", - * "@id": "chat-messages/freenode/channels/kosmos/", + * "@id": "chat-messages/irc.libera.chat/channels/kosmos/", * "@type": "ChatChannel", + * "service": { + * "domain": "irc.libera.chat", + * "protocol": "IRC", + * }, * "name": "#kosmos", - * "ircURI": "irc://irc.freenode.net/kosmos", - * "today": { + * "type": "room", + * "today": { * "@id": "2015/01/01", * "@type": "ChatLog", * "messageType": "InstantMessage", @@ -40,9 +42,7 @@ const ChatMessages = function (privateClient, publicClient) { * ] * } * } - * (end code) */ - const archiveSchema = { "type": "object", "properties": { @@ -60,17 +60,27 @@ const ChatMessages = function (privateClient, publicClient) { "default": "ChatChannel", "enum": ["ChatChannel"] }, + "service": { + "type": "object", + "properties": { + "domain": { + "type": "string", + "required": true + }, + "protocol": { + "type": "string", + "required": true + } + } + }, "name": { "type": "string", "required": true }, - "ircURI": { + "type": { "type": "string", - "format": "uri" - }, - "xmppURI": { - "type": "string", - "format": "uri" + "required": true, + "enum": [ "room", "person" ] }, "today": { "type": "object", @@ -135,56 +145,55 @@ const ChatMessages = function (privateClient, publicClient) { publicClient.declareType("daily-archive", "https://kosmos.org/ns/v1", archiveSchema); /** - * Class: DailyArchive + * A daily archive stores chat messages by calendar day. * - * A daily archive stores IRC messages by day. - * - * Parameters (object): - * server - Chat server info (see ) - * channelName - Name of room/channel - * date - Date of archive day - * isPublic - Store logs in public folder (defaults to false) - * previous - Date of previous log file as YYYY/MM/DD; - * looked up automatically when not given - * next - Date of next log file as YYYY/MM/DD; - * looked up automatically when not given - * - * Example for IRC: - * - * (start code) - * const archive = new chatMessages.DailyArchive({ - * server: { - * type: 'irc', - * name: 'freenode', - * ircURI: 'irc://irc.freenode.net' - * }, - * channelName: '#kosmos', - * date: new Date(), - * isPublic: true - * }); - * (end code) - * - * Example for XMPP: - * - * (start code) - * const archive = new chatMessages.DailyArchive({ - * server: { - * type: 'xmpp', - * name: '5apps', - * xmppMUC: 'muc.5apps.com' - * }, - * channelName: 'watercooler', - * date: new Date(), - * isPublic: false - * }); - * (end code) + * @class */ class DailyArchive { + /** + * @param {object} options + * @param {object} options.service + * @param {string} options.service.protocol - Type of chat service/protocol (e.g. "IRC", "XMPP", "Campfire", "Slack") + * @param {string} options.service.domain - Domain of the chat service (e.g. "irc.libera.chat", "kosmos.chat") + * @param {string} options.channelName - Name of room/channel (e.g. "#kosmos") + * @param {string} [options.channelType] - Type of channel ("room" or "person") + * @param {date} options.date - Date of archive day + * @param {boolean} options.isPublic - Store logs in public folder (defaults to false) + * @param {string} [options.previous] - Date of previous log file as `YYYY/MM/DD`. Looked up automatically when not given + * @param {string} [options.next] - Date of next log file as `YYYY/MM/DD`. looked up automatically when not given + * + * @example + * // IRC archive: + * const archive = new chatMessages.DailyArchive({ + * service: { + * protocol: 'IRC', + * domain: 'irc.libera.chat', + * }, + * channelName: '#kosmos-dev', + * channelType: 'room', + * date: new Date(), + * isPublic: true + * }); + * + * // XMPP archive: + * const archive = new chatMessages.DailyArchive({ + * service: { + * protocol: 'XMPP', + * domain: 'kosmos.chat', + * }, + * channelName: 'kosmos-dev', + * channelType: 'room', + * date: new Date(), + * isPublic: false + * }); + * + */ constructor (options) { // // Defaults // - options.isPublic = options.isPublic || false; + options.isPublic = options.isPublic || false; + options.channelType = options.channelType || "room"; // // Validate options @@ -192,10 +201,10 @@ const ChatMessages = function (privateClient, publicClient) { if (typeof options !== "object") { throw "options must be an object"; } - if (typeof options.server !== "object" || - typeof options.server.type !== "string" || - typeof options.server.name !== "string") { - throw "server must be an object containing at least server \"type\" and \"name\""; + if (typeof options.service !== "object" || + typeof options.service.protocol !== "string" || + typeof options.service.domain !== "string") { + throw "service must be an object containing at least service \"protocol\" and \"domain\""; } if (typeof options.channelName !== "string") { throw "channelName must be a string"; @@ -208,104 +217,82 @@ const ChatMessages = function (privateClient, publicClient) { } /** - * Property: server - * - * Contains information about the chat server/network - * - * Properties: - * type - Type of server/protocol (e.g. "irc", "xmpp", "campfire", "slack") - * name - Shortname/id/alias of network/server (e.g. "freenode", "mycompanyname") - * ircURI - (optional) IRC URI of network (e.g. "irc://irc.freenode.net/") - * xmppMUC - (optional) XMPP MUC service host (e.g. "conference.jabber.org") + * @property {object} service + * @property {string} service.protocol - Type of chat service/protocol (e.g. "IRC", "XMPP", "campfire", "slack") + * @property {string} service.domain - Domain of the chat service (e.g. "irc.libera.chat", "kosmos.chat") */ - this.server = options.server; + this.service = options.service; /** - * Property: channelName - * - * Name of the IRC channel (e.g. "#kosmos") + * @property {string} channelName - Name of channel (e.g. "#kosmos") */ this.channelName = options.channelName; /** - * Property: date - * - * Date of the archive's content + * @property {string} channelType - Type of channel ("room" or "person") + */ + this.channelType = options.channelType; + + /** + * @property {string} date - Gregorian calendar date of the archive's content */ this.date = options.date; /** - * Property: isPublic - * - * `true` for public archives, `false` for private ones + * @property {boolean} isPublic - `true` for public archives, `false` for private ones */ - this.isPublic = options.isPublic; + this.isPublic = options.isPublic || false; /** - * Property: parsedDate - * - * Object containing padded year, month and day of date + * @property {object} parsedDate - Contains padded year, month and day of date + * @property {string} year + * @property {string} month + * @property {string} day */ this.parsedDate = parseDate(this.date); /** - * Property: dateId - * - * Date string in the form of YYYY/MM/DD + * @property {string} dateId - Date string in the form of YYYY/MM/DD */ this.dateId = this.parsedDate.year+'/'+this.parsedDate.month+'/'+this.parsedDate.day; /** - * Property: path - * - * Document path of the archive file + * @property {string} path - Document path of the archive file */ - switch (this.server.type) { - case 'irc': - if (this.channelName.match(/^#/)) { - // normal chatroom - const channelName = this.channelName.replace(/^#/,''); - this.path = `${this.server.name}/channels/${channelName}/${this.dateId}`; - } else { - // user direct message - this.path = `${this.server.name}/users/${this.channelName}/${this.dateId}`; - } - break; - default: - this.path = `${this.server.name}/${this.channelName}/${this.dateId}`; - break; + if (this.channelType === "room") { + // Normal chatroom + const channelName = this.channelName.replace(/#/,''); + this.path = `${this.service.domain}/channels/${channelName}/${this.dateId}`; + } else { + // User direct message + this.path = `${this.service.domain}/users/${this.channelName}/${this.dateId}`; } /** - * Property: client - * - * Public or private BaseClient, depending on isPublic + * @property {object} client - Public or private remoteStorgage.js BaseClient */ this.client = this.isPublic ? publicClient : privateClient; /** - * Property: previous - * - * Date of previous log file as YYYY/MM/DD + * @property {string} previous - Date of previous log file as YYYY/MM/DD */ this.previous = options.previous; /** - * Property: next - * - * Date of next log file as YYYY/MM/DD + * @property {string} next - Date of next log file as YYYY/MM/DD */ this.next = options.next; } /* - * Method: addMessage + * @param {object} message + * @param {string} message.timestamp - Timestamp of the message + * @param {string} message.from - The sender of the message + * @param {string} message.text - The message itself + * @param {string} message.type - Type of message (one of text, join, leave, action) + * @param {string} [message.id] - Unique ID of message. TODO implement * - * Parameters (object): - * timestamp - Timestamp of the message - * from - The sender of the message - * text - The message itself - * type - Type of message (one of text, join, leave, action) + * @returns {Promise} */ addMessage (message) { if (this.isPublic && !this.channelName.match(/^#/)) { @@ -324,15 +311,13 @@ const ChatMessages = function (privateClient, publicClient) { } /* - * Method: addMessages - * * Like , but for multiple messages at once. Useful for bulk * imports of messages. * - * Parameters: - * messages - Array of message objects (see params for addMessage) - * overwrite - If true, creates a new archive file and overwrites the - * old one. Defaults to false. + * @param {Array} messages - Array of message objects (see params for addMessage) + * @param {boolean} overwrite - If true, creates a new archive file and overwrites the old one. Defaults to false. + * + * @returns {Promise} */ addMessages (messages, overwrite) { if (this.isPublic && !this.channelName.match(/^#/)) { @@ -359,18 +344,20 @@ const ChatMessages = function (privateClient, publicClient) { } /* - * Method: remove - * * Deletes the entire archive document from storage + * + * @returns {Promise} */ remove () { return this.client.remove(this.path); } /* - * Method: _updateDocument - * * Updates and writes an existing archive document + * + * @returns {Promise} + * + * @private */ _updateDocument (archive, messages) { console.debug('[chat-messages] Updating archive document', archive); @@ -387,9 +374,11 @@ const ChatMessages = function (privateClient, publicClient) { } /* - * Method: _createDocument - * * Creates and writes a new archive document + * + * @returns {Promise} + * + * @private */ _createDocument (messages) { console.debug('[chat-messages] Creating new archive document'); @@ -421,17 +410,21 @@ const ChatMessages = function (privateClient, publicClient) { } /* - * Method: _buildArchiveObject - * * Builds the object to be stored in remote storage + * + * @returns {object} + * + * @private */ _buildArchiveObject () { const roomName = this.channelName.replace(/#/,''); const archive = { - "@id": "chat-messages/"+this.server.name+"/channels/"+roomName+"/", + "@id": "chat-messages/"+this.service.domain+"/channels/"+roomName+"/", "@type": "ChatChannel", + "service": this.service, "name": this.channelName, + "type": this.channelType, "today": { "@id": this.dateId, "@type": "ChatLog", @@ -440,15 +433,14 @@ const ChatMessages = function (privateClient, publicClient) { } }; - switch (this.server.type) { - case 'irc': + switch (this.service.protocol) { + case 'IRC': if (!this.channelName.match(/^#/)) { - archive["@id"] = "chat-messages/"+this.server.name+"/users/"+this.channelName+"/"; + archive["@id"] = "chat-messages/"+this.service.domain+"/users/"+this.channelName+"/"; } - archive["ircURI"] = this.server.ircURI+"/"+roomName; break; - case 'xmpp': - archive["xmppURI"] = `xmpp:${this.channelName}@${this.server.xmppMUC}`; + case 'XMPP': + // XMPP-specific adjustments break; } @@ -456,9 +448,11 @@ const ChatMessages = function (privateClient, publicClient) { } /* - * Method: _updatePreviousArchive - * * Finds the previous archive document and updates its today.next value + * + * @returns {boolean|Promise} + * + * @private */ _updatePreviousArchive () { return this._findPreviousArchive().then((archive) => { @@ -478,9 +472,11 @@ const ChatMessages = function (privateClient, publicClient) { } /* - * Method: _findPreviousArchive - * * Returns the previous archive document + * + * @returns {Promise} + * + * @private */ _findPreviousArchive () { const monthPath = this.path.substring(0, this.path.length-2); @@ -542,9 +538,11 @@ const ChatMessages = function (privateClient, publicClient) { } /* - * Method: _sync - * * Write archive document + * + * @returns {Promise} + * + * @private */ _sync (obj) { console.debug('[chat-messages] Writing archive object', obj); From c42e0a37a815362f19338b7158f1a4a794a38c8b Mon Sep 17 00:00:00 2001 From: Sebastian Kippe Date: Sun, 5 Sep 2021 15:58:59 +0200 Subject: [PATCH 3/3] Update build --- dist/build.js | 2 +- dist/build.js.map | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/build.js b/dist/build.js index 1902daf..69099be 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"]},name:{type:"string",required:!0},ircURI:{type:"string",format:"uri"},xmppURI:{type:"string",format:"uri"},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,"object"!==a(n))throw"options must be an object";if("object"!==a(n.server)||"string"!=typeof n.server.type||"string"!=typeof n.server.name)throw'server must be an object containing at least server "type" and "name"';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 s;switch(this.server=n.server,this.channelName=n.channelName,this.date=n.date,this.isPublic=n.isPublic,this.parsedDate={year:(s=this.date).getUTCFullYear(),month:i(s.getUTCMonth()+1),day:i(s.getUTCDate())},this.dateId=this.parsedDate.year+"/"+this.parsedDate.month+"/"+this.parsedDate.day,this.server.type){case"irc":if(this.channelName.match(/^#/)){var o=this.channelName.replace(/^#/,"");this.path="".concat(this.server.name,"/channels/").concat(o,"/").concat(this.dateId)}else this.path="".concat(this.server.name,"/users/").concat(this.channelName,"/").concat(this.dateId);break;default:this.path="".concat(this.server.name,"/").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.server.name+"/channels/"+t+"/","@type":"ChatChannel",name:this.channelName,today:{"@id":this.dateId,"@type":"ChatLog",messageType:"InstantMessage",messages:[]}};switch(this.server.type){case"irc":this.channelName.match(/^#/)||(e["@id"]="chat-messages/"+this.server.name+"/users/"+this.channelName+"/"),e.ircURI=this.server.ircURI+"/"+t;break;case"xmpp":e.xmppURI="xmpp:".concat(this.channelName,"@").concat(this.server.xmppMUC)}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(s){var o=Object.keys(s).map((function(t){return parseInt(t)})).map((function(e){return e0){var c=i(Math.max.apply(Math,n(o)).toString());return t.client.getObject(e+c)}return t.client.getListing(r).then((function(e){var s=Object.keys(e).map((function(t){return parseInt(t.substr(0,2))})).map((function(e){return e0){var o=i(Math.max.apply(Math,n(s)).toString());return t.client.getListing(r+o+"/").then((function(e){var a=Object.keys(e).map((function(t){return parseInt(t)})),s=i(Math.max.apply(Math,n(a)).toString());return t.client.getObject(r+o+"/"+s)}))}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 s=Math.max.apply(Math,n(r)).toString();return t.client.getListing(a+s+"/").then((function(e){var r=Object.keys(e).map((function(t){return parseInt(t.substr(0,2))})),o=i(Math.max.apply(Math,n(r)).toString());return t.client.getListing(a+s+"/"+o+"/").then((function(e){var r=Object.keys(e).map((function(t){return parseInt(t)})),c=i(Math.max.apply(Math,n(r)).toString());return t.client.getObject(a+s+"/"+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}))}}])&&s(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([],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})()})); //# sourceMappingURL=build.js.map \ No newline at end of file diff --git a/dist/build.js.map b/dist/build.js.map index 390cda1..52df3d8 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 day of chat messages\n *\n * Example:\n *\n * (start code)\n * {\n * \"@context\": \"https://kosmos.org/ns/v1\",\n * \"@id\": \"chat-messages/freenode/channels/kosmos/\",\n * \"@type\": \"ChatChannel\",\n * \"name\": \"#kosmos\",\n * \"ircURI\": \"irc://irc.freenode.net/kosmos\",\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 * (end code)\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 \"name\": {\n \"type\": \"string\",\n \"required\": true\n },\n \"ircURI\": {\n \"type\": \"string\",\n \"format\": \"uri\"\n },\n \"xmppURI\": {\n \"type\": \"string\",\n \"format\": \"uri\"\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 * Class: DailyArchive\n *\n * A daily archive stores IRC messages by day.\n *\n * Parameters (object):\n * server - Chat server info (see )\n * channelName - Name of room/channel\n * date - Date of archive day\n * isPublic - Store logs in public folder (defaults to false)\n * previous - Date of previous log file as YYYY/MM/DD;\n * looked up automatically when not given\n * next - Date of next log file as YYYY/MM/DD;\n * looked up automatically when not given\n *\n * Example for IRC:\n *\n * (start code)\n * const archive = new chatMessages.DailyArchive({\n * server: {\n * type: 'irc',\n * name: 'freenode',\n * ircURI: 'irc://irc.freenode.net'\n * },\n * channelName: '#kosmos',\n * date: new Date(),\n * isPublic: true\n * });\n * (end code)\n *\n * Example for XMPP:\n *\n * (start code)\n * const archive = new chatMessages.DailyArchive({\n * server: {\n * type: 'xmpp',\n * name: '5apps',\n * xmppMUC: 'muc.5apps.com'\n * },\n * channelName: 'watercooler',\n * date: new Date(),\n * isPublic: false\n * });\n * (end code)\n */\n class DailyArchive {\n constructor (options) {\n //\n // Defaults\n //\n options.isPublic = options.isPublic || false;\n\n //\n // Validate options\n //\n if (typeof options !== \"object\") {\n throw \"options must be an object\";\n }\n if (typeof options.server !== \"object\" ||\n typeof options.server.type !== \"string\" ||\n typeof options.server.name !== \"string\") {\n throw \"server must be an object containing at least server \\\"type\\\" and \\\"name\\\"\";\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: server\n *\n * Contains information about the chat server/network\n *\n * Properties:\n * type - Type of server/protocol (e.g. \"irc\", \"xmpp\", \"campfire\", \"slack\")\n * name - Shortname/id/alias of network/server (e.g. \"freenode\", \"mycompanyname\")\n * ircURI - (optional) IRC URI of network (e.g. \"irc://irc.freenode.net/\")\n * xmppMUC - (optional) XMPP MUC service host (e.g. \"conference.jabber.org\")\n */\n this.server = options.server;\n\n /**\n * Property: channelName\n *\n * Name of the IRC channel (e.g. \"#kosmos\")\n */\n this.channelName = options.channelName;\n\n /**\n * Property: date\n *\n * Date of the archive's content\n */\n this.date = options.date;\n\n /**\n * Property: isPublic\n *\n * `true` for public archives, `false` for private ones\n */\n this.isPublic = options.isPublic;\n\n /**\n * Property: parsedDate\n *\n * Object containing padded year, month and day of date\n */\n this.parsedDate = parseDate(this.date);\n\n /**\n * Property: dateId\n *\n * 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: path\n *\n * Document path of the archive file\n */\n switch (this.server.type) {\n case 'irc':\n if (this.channelName.match(/^#/)) {\n // normal chatroom\n const channelName = this.channelName.replace(/^#/,'');\n this.path = `${this.server.name}/channels/${channelName}/${this.dateId}`;\n } else {\n // user direct message\n this.path = `${this.server.name}/users/${this.channelName}/${this.dateId}`;\n }\n break;\n default:\n this.path = `${this.server.name}/${this.channelName}/${this.dateId}`;\n break;\n }\n\n /**\n * Property: client\n *\n * Public or private BaseClient, depending on isPublic\n */\n this.client = this.isPublic ? publicClient : privateClient;\n\n /**\n * Property: previous\n *\n * Date of previous log file as YYYY/MM/DD\n */\n this.previous = options.previous;\n\n /**\n * Property: next\n *\n * Date of next log file as YYYY/MM/DD\n */\n this.next = options.next;\n }\n\n /*\n * Method: addMessage\n *\n * Parameters (object):\n * timestamp - Timestamp of the message\n * from - The sender of the message\n * text - The message itself\n * type - Type of message (one of text, join, leave, action)\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 * Method: addMessages\n *\n * Like , but for multiple messages at once. Useful for bulk\n * imports of messages.\n *\n * Parameters:\n * messages - Array of message objects (see params for addMessage)\n * overwrite - If true, creates a new archive file and overwrites the\n * old one. Defaults to false.\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 * Method: remove\n *\n * Deletes the entire archive document from storage\n */\n remove () {\n return this.client.remove(this.path);\n }\n\n /*\n * Method: _updateDocument\n *\n * Updates and writes an existing archive document\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 * Method: _createDocument\n *\n * Creates and writes a new archive document\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 * Method: _buildArchiveObject\n *\n * Builds the object to be stored in remote storage\n */\n _buildArchiveObject () {\n const roomName = this.channelName.replace(/#/,'');\n\n const archive = {\n \"@id\": \"chat-messages/\"+this.server.name+\"/channels/\"+roomName+\"/\",\n \"@type\": \"ChatChannel\",\n \"name\": this.channelName,\n \"today\": {\n \"@id\": this.dateId,\n \"@type\": \"ChatLog\",\n \"messageType\": \"InstantMessage\",\n \"messages\": []\n }\n };\n\n switch (this.server.type) {\n case 'irc':\n if (!this.channelName.match(/^#/)) {\n archive[\"@id\"] = \"chat-messages/\"+this.server.name+\"/users/\"+this.channelName+\"/\";\n }\n archive[\"ircURI\"] = this.server.ircURI+\"/\"+roomName;\n break;\n case 'xmpp':\n archive[\"xmppURI\"] = `xmpp:${this.channelName}@${this.server.xmppMUC}`;\n break;\n }\n\n return archive;\n }\n\n /*\n * Method: _updatePreviousArchive\n *\n * Finds the previous archive document and updates its today.next value\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 * Method: _findPreviousArchive\n *\n * Returns the previous archive document\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 * Method: _sync\n *\n * Write archive document\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","server","type","channelName","date","Date","this","parsedDate","year","getUTCFullYear","month","getUTCMonth","day","getUTCDate","dateId","match","replace","path","client","previous","next","message","Promise","resolve","getObject","then","archive","_updateDocument","_createDocument","messages","overwrite","forEach","remove","console","debug","Array","isArray","today","push","_sync","_buildArchiveObject","_updatePreviousArchive","roomName","ircURI","xmppMUC","_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([], 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