mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-12-06 00:38:06 +00:00
Add server sent events (#5279)
* Create server-sent-events.js * Create sse-change-listener.js * Implement server sent events * Convert to ES5 and wrap in function * Use the host string from tiddlyweb * Improve comments in sse-server.js * Can't use object reference as key * Add retry timeout * Fix a bug * bug fix * Fix formatting * Fix ES5 compat * capitalize comments * more fixes * Refactor tiddlywek/sse-server.js * Extract helper functions for handling wikis and connections. * Replace JSDoc comments. * Fix formatting according to TW core. * Simplify the logic for adding and removing connections. * Fix formatting of tiddlyweb/sse-client.js Fix formatting according to TW core. * Fix formatting of server-sent-events.js Fix formatting and comments following TW core guidelines. * Extract a debounce function in sse-client.js * Avoid using startsWith in server-sent-events.js startsWith is part of ES2015, while TiddlyWiki uses the 5.1 dialect. * New sse-enabled WebServer parameter * If not set to "yes", disabled SSE request handling. * Add documentation for the parameter in core/language/en-GB/Help/listen.tid * Add new tiddler editions/tw5.com/tiddlers/webserver/WebServer Parameter_ sse-enabled.tid * Disable polling for changes if SSE is enabled * Add sse_enabled to /status JSON response * Store syncer polling status in $:/config/SyncDisablePolling * Handled disabling polling in core/modules/syncer.js * Simply boolean logic in syncer.js * Delete trailing whitespaces in syncer.js Co-authored-by: Arlen22 <arlenbee@gmail.com>
This commit is contained in:
53
plugins/tiddlywiki/tiddlyweb/sse-client.js
Normal file
53
plugins/tiddlywiki/tiddlyweb/sse-client.js
Normal file
@@ -0,0 +1,53 @@
|
||||
/*\
|
||||
title: $:/plugins/tiddlywiki/tiddlyweb/sse-client.js
|
||||
type: application/javascript
|
||||
module-type: startup
|
||||
|
||||
GET /recipes/default/tiddlers/:title
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
exports.name = "/events/plugins/tiddlywiki/tiddlyweb";
|
||||
exports.after = ["startup"];
|
||||
exports.synchronous = true;
|
||||
exports.platforms = ["browser"];
|
||||
exports.startup = function() {
|
||||
// Make sure we're actually being used
|
||||
if($tw.syncadaptor.name !== "tiddlyweb") {
|
||||
return;
|
||||
}
|
||||
// Get the mount point in case a path prefix is used
|
||||
var host = $tw.syncadaptor.getHost();
|
||||
// Make sure it ends with a slash (it usually does)
|
||||
if(host[host.length - 1] !== "/") {
|
||||
host += "/";
|
||||
}
|
||||
// Setup the event listener
|
||||
setupEvents(host);
|
||||
};
|
||||
|
||||
function debounce(callback) {
|
||||
var timeout = null;
|
||||
return function() {
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(callback,$tw.syncer.throttleInterval);
|
||||
};
|
||||
}
|
||||
|
||||
function setupEvents(host) {
|
||||
var events = new EventSource(host + "events/plugins/tiddlywiki/tiddlyweb");
|
||||
var debouncedSync = debounce($tw.syncer.syncFromServer.bind($tw.syncer));
|
||||
events.addEventListener("change",debouncedSync);
|
||||
events.onerror = function() {
|
||||
events.close();
|
||||
setTimeout(function() {
|
||||
setupEvents(host);
|
||||
},$tw.syncer.errorRetryInterval);
|
||||
};
|
||||
}
|
||||
})();
|
||||
94
plugins/tiddlywiki/tiddlyweb/sse-server.js
Normal file
94
plugins/tiddlywiki/tiddlyweb/sse-server.js
Normal file
@@ -0,0 +1,94 @@
|
||||
/*\
|
||||
title: $:/plugins/tiddlywiki/tiddlyweb/sse-server.js
|
||||
type: application/javascript
|
||||
module-type: route
|
||||
|
||||
GET /events/plugins/tiddlywiki/tiddlyweb
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var wikis = [];
|
||||
var connections = [];
|
||||
|
||||
/*
|
||||
Setup up the array for this wiki and add the change listener
|
||||
*/
|
||||
function setupWiki(wiki) {
|
||||
var index = wikis.length;
|
||||
// Add a new array for this wiki (object references work as keys)
|
||||
wikis.push(wiki);
|
||||
connections.push([]);
|
||||
// Listen to change events for this wiki
|
||||
wiki.addEventListener("change",function(changes) {
|
||||
var jsonChanges = JSON.stringify(changes);
|
||||
getWikiConnections(wiki).forEach(function(item) {
|
||||
item.emit("change",jsonChanges);
|
||||
});
|
||||
});
|
||||
return index;
|
||||
}
|
||||
|
||||
/*
|
||||
Setup this particular wiki if we haven't seen it before
|
||||
*/
|
||||
function ensureWikiSetup(wiki) {
|
||||
if(wikis.indexOf(wiki) === -1) {
|
||||
setupWiki(wiki);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Return the array of connections for a particular wiki
|
||||
*/
|
||||
function getWikiConnections(wiki) {
|
||||
return connections[wikis.indexOf(wiki)];
|
||||
}
|
||||
|
||||
function addWikiConnection(wiki,connection) {
|
||||
getWikiConnections(wiki).push(connection);
|
||||
}
|
||||
|
||||
function removeWikiConnection(wiki,connection) {
|
||||
var wikiConnections = getWikiConnections(wiki);
|
||||
var index = wikiConnections.indexOf(connection);
|
||||
if(index !== -1) {
|
||||
wikiConnections.splice(index,1);
|
||||
}
|
||||
}
|
||||
|
||||
function handleConnection(request,state,emit,end) {
|
||||
if(isDisabled(state)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ensureWikiSetup(state.wiki);
|
||||
// Add the connection to the list of connections for this wiki
|
||||
var connection = {
|
||||
request: request,
|
||||
state: state,
|
||||
emit: emit,
|
||||
end: end
|
||||
};
|
||||
addWikiConnection(state.wiki,connection);
|
||||
request.on("close",function() {
|
||||
removeWikiConnection(state.wiki,connection);
|
||||
});
|
||||
}
|
||||
|
||||
function isDisabled(state) {
|
||||
return state.server.get("sse-enabled") !== "yes";
|
||||
}
|
||||
|
||||
// Import the ServerSentEvents class
|
||||
var ServerSentEvents = require("$:/core/modules/server/server-sent-events.js").ServerSentEvents;
|
||||
// Instantiate the class
|
||||
var events = new ServerSentEvents("plugins/tiddlywiki/tiddlyweb", handleConnection);
|
||||
// Export the route definition for this server sent events instance
|
||||
module.exports = events.getExports();
|
||||
|
||||
})();
|
||||
@@ -91,10 +91,12 @@ TiddlyWebAdaptor.prototype.getStatus = function(callback) {
|
||||
self.isLoggedIn = json.username !== "GUEST";
|
||||
self.isReadOnly = !!json["read_only"];
|
||||
self.isAnonymous = !!json.anonymous;
|
||||
|
||||
var isSseEnabled = !!json.sse_enabled;
|
||||
}
|
||||
// Invoke the callback if present
|
||||
if(callback) {
|
||||
callback(null,self.isLoggedIn,json.username,self.isReadOnly,self.isAnonymous);
|
||||
callback(null,self.isLoggedIn,json.username,self.isReadOnly,self.isAnonymous,isSseEnabled);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user