Closed jamievicary closed 5 years ago
You might be able to do this without a server.
You can allow people to share models by serializing the state into the URL. So every time the user makes any change in the UI, you update the URL, like this:
window.location.hash = encodeURIComponent(JSON.stringify(state))
resulting in a URL like https://homotopy.io/#{cell1:"...",cell2:"...",...}
. That way, the current model is always sharable by copy-pasting the URL.
Google Maps does the same thing if you want to see it in action.
Saving models can be done locally using the browser's local storage. (You might want to use a library like store.js.)
Of course, saving to local storage doesn't help if the user switches computers. But perhaps that's an acceptable limitation.
If you manage to do everything in the client, you don't just avoid having to write all the server code, but it also means that you don't need to maintain a server indefinitely. Just find a place to serve static files from (GitHub Pages will do fine) and point your domain at it. We've been using this strategy for solitr.com, and it's been saving us so much headache!
That sounds great for sustainability but I am worried that the URLs would grow huge - workspaces can easily contain hundreds of cells. Maybe some URL shortener can be used for that though.
I agree in principle this would be fantastic. I think there might still be some use cases to have a server --- for example, letting people easily store their projects in progress without having to maintain their own private list of project URLs, and for hosting timestamped public projects --- but even so, having URL-encoded projects would be enormously useful and powerful.
I share Antonin's concern that the length of the URLs would be the problem. Here is a serialized state of a workspace with only very moderate complexity:
[homotopy.io - Tue Dec 11 2018 15_58_38 GMT+0000 (Greenwich Mean Time).txt](https://github.com/jamievicary/homotopy.io/files/2705551/homotopy.io.-.Tue.Dec.11.2018.15_58_38.GMT%2B0000.Greenwich.Mean.Time.txt)
It's over 2 Mb, compressing down to about 11kb. From some searches, it seems the maximum URL length is only 2083 characters. So unfortunately it seems implausible that it could be possible in general to fit the workspace data into the URL :(.
Hm, even compressed, 11KB is a lot.
From my reading, the ~2KB limit seems to apply to the non-fragment part of the URL that's transmitted via HTTP. I googled for maximum fragment length, and it doesn't seem to be super clear what limit there is in practice. The best I found was this StackOverflow answer, which seems to indicate that very long fragments seem to work in some (maybe all) browsers.
On the other hand, I don't recall ever seen multi-KB fragment URLs in the wild, so I have no idea how (un)usable it would be in practice.
I think getting this working using the fragment part of the URL is a fantastic idea. The limit there seems large so let's do it. Compression is now working as per #48, yielding compressed session strings as localStorage['persist:root']
. It would be great if the client put these strings in the fragment URL. This would allow hyperlinking workspaces from research papers without a server.
To be clear, I still think there are lots of reasons why we should have a server. But I think we should also have state in the URL in this way.
Update: Nick has suggested we use Firebase, which I think is a great idea.
Workspace encoding in the URL is now working in the current master branch, and the browser undo/redo buttons work as well.
We need a simple server (I presume node/express), supporting the following basic features:
This is already implemented for the old system at http://globular.science. That uses a filesystem database, with a simple structure that I would like to replicate. However, I suggest we re-write from scratch.