Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Server Sent Events #4609

Closed
wants to merge 14 commits into from
Closed

Add Server Sent Events #4609

wants to merge 14 commits into from

Conversation

Arlen22
Copy link
Contributor

@Arlen22 Arlen22 commented Apr 29, 2020

This is related to Issue #4608 and also fixes Issue #4605.

To test this, run node tiddlywiki.js editions/server --listen then open two pages side-by-side and watch changes propagate in almost real time.

@Arlen22
Copy link
Contributor Author

Arlen22 commented Apr 29, 2020

I used the TypeScript compiler to convert it to ES5, so I'm sorry if it doesn't look great.

@Arlen22
Copy link
Contributor Author

Arlen22 commented Apr 29, 2020

Tested this on TiddlyServer and after fixing this one bug, everything works on TiddlyServer as well, without any changes to TiddlyServer.

var events = new EventSource(host + "events/plugins/tiddlywiki/tiddlyweb");
events.addEventListener("change", function () {
$tw.syncer.syncFromServer();
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be a good idea to add some debouncing here to reduce the amount of requests going to the server over a small period of time?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another idea - you might want to add an event listener for the error event. Otherwise if you lose the connection to the server, you'll need to reload the entire wiki to reestablish it!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think debouncing is going to be necessary to avoid obvious DDOS vectors. Alternatively, perhaps we should disable SSE by default.

@hoelzro
Copy link
Contributor

hoelzro commented May 15, 2020

Hi @Arlen22 - this is great! I've been hoping for support for SSE in TiddlyWiki for a while, and I agree that this would be a good time to add it. I looked at your code and left some ideas I have for improvement - please let me know what you think!

Also, you mentioned how you originally wrote this in TypeScript - do you by chance have a TypeScript definition file for TiddlyWiki's API? I think it would be very useful!

@Arlen22
Copy link
Contributor Author

Arlen22 commented May 15, 2020

Also, you mentioned how you originally wrote this in TypeScript - do you by chance have a TypeScript definition file for TiddlyWiki's API? I think it would be very useful!

I do not. Because of how often closures are used it is very hard to make it work properly with TypeScript. Plus I don't know how to keep it in sync. It seems like it would be a full time job. I have often wished, though :)

@Arlen22
Copy link
Contributor Author

Arlen22 commented Jun 22, 2020

@Jermolene any idea when we can get this in?

@hoelzro
Copy link
Contributor

hoelzro commented Oct 20, 2020

@Arlen22 Have you considered lifting this out into a standalone plugin so that others could play with it some more? I'd like to give this a try in my wiki, but I'd feel more comfortable with it as a plugin rather than having to patch the tiddlyweb plugin!

@Arlen22
Copy link
Contributor Author

Arlen22 commented Oct 20, 2020

No. Jeremy has said that it would be ideal to have SSE in core, and the other two files are tiddlyweb specific so can't really separate them out.

@Jermolene
Copy link
Member

Thank you @Arlen22 @hoelzro, and apologies for the slow response. There are some coding standards issues that I'll mark up shortly.

Copy link
Member

@Jermolene Jermolene left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Arlen22. In most cases I've just marked up the first occurrence of repeated issues.

"use strict";

/**
* @param {string} prefix
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core doesn't use JSDoc, just plain text for code comments

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use it to give VS Code the proper intellisense. TiddlyWiki is really hard to work with otherwise.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, for us familiar with type script, interface with typing is very nice.

return ServerSentEvents;
}());

exports.ServerSentEvents = ServerSentEvents;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The construction used to export the class isn't consistent with the rest of the core, which doesn't use the inner IIFE that returns "ServerSentEvents". It should follow the same approach as, say, the core widget classes.

this.handler = handler;
this.prefix = prefix;
}
ServerSentEvents.prototype.getExports = function () {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core leaves a blank line between methods

* @param {*} state
*/
ServerSentEvents.prototype.handleEventRequest = function (request, response, state) {
if (request.headers.accept && request.headers.accept.startsWith('text/event-stream')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core doesn't use a space between if and the following parenthesis

ServerSentEvents.prototype.handleEventRequest = function (request, response, state) {
if (request.headers.accept && request.headers.accept.startsWith('text/event-stream')) {
response.writeHead(200, {
'Content-Type': 'text/event-stream',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core prefers double quotes for string constants, only using single quotes for strings that need to contain double quotes.

};
ServerSentEvents.prototype.emit = function (response, event, data) {
if (typeof event !== "string" || event.indexOf("\n") !== -1)
throw new Error("type must be a single-line string");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We would normally capitalise an error message

exports.synchronous = true;
exports.platforms = ["browser"];
exports.startup = function () {
//make sure we're actually being used
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments should be capitalised, with a space after the //

exports.platforms = ["browser"];
exports.startup = function () {
//make sure we're actually being used
if($tw.syncadaptor.name !== "tiddlyweb") return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we instead install the event handler when we startup the syncadaptor?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sure we could but I don't really know where. I did it here because that is right after the syncer and sync adapter are initialized. But you could just as easily do it there.

plugins/tiddlywiki/tiddlyweb/sse-client.js Outdated Show resolved Hide resolved
var events = new EventSource(host + "events/plugins/tiddlywiki/tiddlyweb");
events.addEventListener("change", function () {
$tw.syncer.syncFromServer();
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think debouncing is going to be necessary to avoid obvious DDOS vectors. Alternatively, perhaps we should disable SSE by default.

@Arlen22
Copy link
Contributor Author

Arlen22 commented Oct 29, 2020

I'm sure I missed stuff. I don't know really. I've kind of lost interest. Feel free to use it if you feel it's useful. I use VS Code and Typescript for several years now and depend on it for a lot of stuff. So it's kind of hard to work with the internals of TiddlyWiki code because the wrapper functions block the type detection.

@NicolasPetton
Copy link
Contributor

@Arlen22 Since you said you've lost interest, I've made some more changes to your PR here #5279

@Arlen22
Copy link
Contributor Author

Arlen22 commented Dec 28, 2020

@NicolasPetton I appreciate the work here. I'll close mine as it looks like you've taken care of everything.

@Arlen22 Arlen22 closed this Dec 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants