From 4133e7d6d6e1f0ac582c7d604993c587abba0a3d Mon Sep 17 00:00:00 2001 From: Jeremy Ruston Date: Fri, 19 Jan 2024 10:52:12 +0000 Subject: [PATCH] Stream wiki generation Avoids "string too long" errors when working with big tiddlers (>100MB) --- .../multiwikiserver/modules/route-get-wiki.js | 74 ++++++++++--------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/plugins/tiddlywiki/multiwikiserver/modules/route-get-wiki.js b/plugins/tiddlywiki/multiwikiserver/modules/route-get-wiki.js index f520e53e8..17170d078 100644 --- a/plugins/tiddlywiki/multiwikiserver/modules/route-get-wiki.js +++ b/plugins/tiddlywiki/multiwikiserver/modules/route-get-wiki.js @@ -19,42 +19,46 @@ exports.path = /^\/wiki\/([^\/]+)$/; exports.handler = function(request,response,state) { // Get the recipe name from the parameters var recipe_name = $tw.utils.decodeURIComponentSafe(state.params[0]); - // Get the tiddlers in the recipe - var titles = $tw.sqlTiddlerStore.getRecipeTiddlers(recipe_name); - // Render the template - var template = $tw.wiki.renderTiddler("text/plain","$:/core/templates/tiddlywiki5.html",{ - variables: { - saveTiddlerFilter: ` - $:/boot/boot.css - $:/boot/boot.js - $:/boot/bootprefix.js - $:/core - $:/library/sjcl.js - $:/plugins/tiddlywiki/tiddlyweb - $:/themes/tiddlywiki/snowwhite - $:/themes/tiddlywiki/vanilla - ` + // Check request is valid + if(recipe_name) { + // Start the response + response.writeHead(200, "OK",{ + "Content-Type": "text/html" + }); + // Get the tiddlers in the recipe + var titles = $tw.sqlTiddlerStore.getRecipeTiddlers(recipe_name); + // Render the template + var template = $tw.wiki.renderTiddler("text/plain","$:/core/templates/tiddlywiki5.html",{ + variables: { + saveTiddlerFilter: ` + $:/boot/boot.css + $:/boot/boot.js + $:/boot/bootprefix.js + $:/core + $:/library/sjcl.js + $:/plugins/tiddlywiki/tiddlyweb + $:/themes/tiddlywiki/snowwhite + $:/themes/tiddlywiki/vanilla + ` + } + }); + // Splice in our tiddlers + var marker = `<` + `script class="tiddlywiki-tiddler-store" type="application/json">[`, + markerPos = template.indexOf(marker); + if(markerPos === -1) { + throw new Error("Cannot find tiddler store in template"); } - }); - // Splice in our tiddlers - var marker = `<` + `script class="tiddlywiki-tiddler-store" type="application/json">[`, - markerPos = template.indexOf(marker); - if(markerPos === -1) { - throw new Error("Cannot find tiddler store in template"); - } - var htmlParts = []; - htmlParts.push(template.substring(0,markerPos + marker.length)); - $tw.utils.each(titles,function(title) { - var tiddler = $tw.sqlTiddlerStore.getTiddler(title,recipe_name); - htmlParts.push(JSON.stringify(Object.assign({},tiddler,{revision: "0", bag: "bag-gamma"}))); - htmlParts.push(",") - }); - htmlParts.push(JSON.stringify({title: "$:/config/tiddlyweb/host",text: "$protocol$//$host$$pathname$/"})); - htmlParts.push(",") - htmlParts.push(template.substring(markerPos + marker.length)) - // Send response - if(htmlParts) { - state.sendResponse(200,{"Content-Type": "text/html"},htmlParts.join("\n"),"utf8"); + response.write(template.substring(0,markerPos + marker.length)); + $tw.utils.each(titles,function(title) { + var tiddler = $tw.sqlTiddlerStore.getTiddler(title,recipe_name); + response.write(JSON.stringify(Object.assign({},tiddler,{revision: "0", bag: "bag-gamma"}))); + response.write(",") + }); + response.write(JSON.stringify({title: "$:/config/tiddlyweb/host",text: "$protocol$//$host$$pathname$/"})); + response.write(",") + response.write(template.substring(markerPos + marker.length)) + // Finish response + response.end(); } else { response.writeHead(404); response.end();