DhruvPathak DhruvPathak - 5 months ago 10
Javascript Question

Is it possible to stream an octet stream being generated in javascript?

Lets suppose a case where a huge string is generated from a small string using some javascript logic, and then the text file is forced to be downloaded on the browser.

This is possible using an octet-stream download by putting it as an href , as mentioned in this answer :

Create a file in memory for user to download, not through server.

function download(filename, text) {
var pom = document.createElement('a');
pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
pom.setAttribute('download', filename);
pom.click();
}


But this solution requires 'text' to be fully generated before being pushed for the download,
hence it will have to be held in browser memory fully .

Is it possible to stream the text as it gets generated using CLIENT SIDE LOGIC ONLY ?

For example :

var inputString = "A";
var outStr = "";
for(var i = 0; i < 10000000 ; i++)
{
/* concatenate inputString to output on the go */
}

Answer

Yes & no. No because there's not a way to write to files with just client-side javascript. Kinda. You can prompt a user to download & save a file, but as you mentioned, the code must generate the whole file before that download happens. Note: By "stream" I assume you mean stream to file (constantly write to a file) & by "CLIENT SIDE LOGIC ONLY" I assume you mean in the browser.

Looks like Mozilla has been working on a way to let client-side code interact with files. Here comes the yes. Kind of. They have their own file system api that lets you interact with (write to) the local machines file system. Specifically, there's a function that lets you write an input stream to a file. However, there's a few asterisks:

1) looks like that whole system is being deprecated; they encourage developers to use OS.file over File I/O

2) You have to use XPConnect, a system that lets you access Mozilla's XPCOM (component library) in javascript. If you want to do this in the browser, it looks like only firefox extensions have the proper permissions to interact with those components (). If you didn't want to do this in the browser, you obviously could just use node.

Assuredly, more complications are bound to show up during implementation. But this looks like the most sure path forward, seeing as how OS.File gives you access to functions like OS.File.writeAtomic() & basic write to file

That being said, it's not that great of a path, but hopefully this gives you a solid starting point. As @dandavis mentioned, browsers (i.e. "client side logic") are designed to not allow this sort of thing. It would be an incredibly huge oversight / security flaw if a website could interact with any user's local file system.

Additional resources:
Wikipedia on XPConnect
Guide on working with XPCOM in javascript - may not be that useful