1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-11-11 04:19:56 +00:00
TiddlyWiki5/plugins/tiddlywiki/multiwikiserver/modules/routes/handlers/get-recipe-events.js
2024-03-25 08:36:42 +00:00

89 lines
2.6 KiB
JavaScript

/*\
title: $:/plugins/tiddlywiki/multiwikiserver/routes/handlers/get-recipe-events.js
type: application/javascript
module-type: mws-route
GET /recipes/:recipe_name/events
headers:
Last-Event-ID:
\*/
(function() {
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
const SSE_HEARTBEAT_INTERVAL_MS = 10 * 1000;
exports.method = "GET";
exports.path = /^\/recipes\/([^\/]+)\/events$/;
exports.handler = function(request,response,state) {
// Get the parameters
const recipe_name = $tw.utils.decodeURIComponentSafe(state.params[0]);
let last_known_tiddler_id = 0;
if(request.headers["Last-Event-ID"]) {
last_known_tiddler_id = $tw.utils.parseNumber(request.headers["Last-Event-ID"]);
} else if(state.queryParameters.last_known_tiddler_id) {
last_known_tiddler_id = $tw.utils.parseNumber(state.queryParameters.last_known_tiddler_id);
}
if(recipe_name) {
// Start streaming the response
response.writeHead(200, {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
"Connection": "keep-alive"
});
// Setup the heartbeat timer
var heartbeatTimer = setInterval(function() {
response.write(':keep-alive\n\n');
},SSE_HEARTBEAT_INTERVAL_MS);
// Method to get changed tiddler events and send to the client
function sendUpdates() {
// Get the tiddlers in the recipe since the last known tiddler_id
var recipeTiddlers = $tw.mws.store.getRecipeTiddlers(recipe_name,{
include_deleted: true,
last_known_tiddler_id: last_known_tiddler_id
});
// Send to the client
if(recipeTiddlers) {
for(let index = recipeTiddlers.length-1; index>=0; index--) {
const tiddlerInfo = recipeTiddlers[index];
if(tiddlerInfo.tiddler_id > last_known_tiddler_id) {
last_known_tiddler_id = tiddlerInfo.tiddler_id;
}
response.write(`event: change\n`)
let data = tiddlerInfo;
if(!tiddlerInfo.is_deleted) {
const tiddler = $tw.mws.store.getRecipeTiddler(tiddlerInfo.title,recipe_name);
if(tiddler) {
data = $tw.utils.extend({},data,{tiddler: tiddler.tiddler})
}
}
response.write(`data: ${JSON.stringify(data)}\n`);
response.write(`id: ${tiddlerInfo.tiddler_id}\n`)
response.write(`\n`);
}
}
}
// Send current and future changes
sendUpdates();
$tw.mws.store.addEventListener("change",sendUpdates);
// Clean up when the connection closes
response.on("close",function () {
clearInterval(heartbeatTimer);
$tw.mws.store.removeEventListener("change",sendUpdates);
});
return;
}
// Fail if something went wrong
response.writeHead(404);
response.end();
};
}());