<commit_before>StreamSaver.js
==============

First I want to thank [<NAME>][1] for a fantastic work implementing the
[FileSaver.js][2] to save files & blob's so easily!
But there is one obstacle - The RAM it can hold and the max blob size limitation

StreamSaver.js takes a different approach. Instead of saving data in client-side
storage or in memory you could now actually create a writable stream directly to
the file system (I'm not talking about chromes sandboxed file system)

StreamSaver.js is the solution to saving streams on the client-side.
It is perfect for webapps that need to save really large amount of data created
on the client-side where the RAM is really low like on mobile devices


Getting started
===============
**It's important to test browser support before you include the [web stream polyfill][15]**<br>
cuz the serverWroker need to respondWith a native version of the ReadableStream
```html
<script src="StreamSaver.js"></script> <!-- load before streams polyfill to detect support -->
<script src="https://wzrd.in/standalone/web-streams-polyfill@latest"></script>
<script>
	// it also support commonJs and amd
	import { createWriteStream, supported, version } from 'StreamSaver'
	const { createWriteStream, supported, version } = require('StreamSaver')
	const { createWriteStream, supported, version } = window.streamSaver
	alert( supported )
</script>
```

Syntax
======

**Writing some plain text**

```javascript
const writeStream = streamSaver.createWriteStream('filename.txt')
const encoder = new TextEncoder
let data = 'a'.repeat(1024)
let uint8array = encoder.encode(data + "\n\n")

writeStream.write(uint8array)
writeStream.close()
```

**Read blob as a stream and pipe it**

```javascript
const writeStream = streamSaver.createWriteStream('filename.txt')
const blob = new Blob([ 'a'.repeat(1E9*5) ]) // 1*5 MB
const blobStream = streamSaver.createBlobReader(blob)

blobStream.pipeTo(writeStream)
```

###Save a media stream


```javascript
get_user_media_stream_somehow().then(mediaStream => {
	let fr = new FileReader
	let mediaRecorder = new MediaRecorder(mediaStream)
	let chunks = Promise.resolve()
	let writeStream = streamSaver.createWriteStream('filename.mp4')
	// use .mp4 for video(camera & screen) and .wav for audio(microphone)

	// Start recording
	mediaRecorder.start()
	
	closeBtn.onclick = event => {
		mediaRecorder.stop()
		setTimeout(() =>
			chunks.then(evt => writeStream.close())
		, 1000)
	}
	
	mediaRecorder.ondataavailable = evt => {
		let blob = evt.data

		chunks = chunks.then(() => new Promise(resolve => {
			fr.onload = () => {
				writeStream.write(fr.result)
				resolve()
			}
			fr.readAsArrayBuffer(blob)
		}))
	}

})
```

**Get a "stream" from ajax**<br>
res.body is a readableByteStream, but don't have pipeTo yet<br>
So we have to use the reader instead which is the underlying method in streams

```javascript
fetch(url).then(res => {
	const writeStream = streamSaver.createWriteStream('filename.txt')
	// Later you will be able to just simply do
	// res.body.pipeTo(writeStream)

	const reader = res.body.getReader()
	const pump = () => reader.read()
		.then(({ value, done }) => done<commit_msg>Made sub topics to links on github<commit_after>StreamSaver.js
==============

First I want to thank [<NAME>][1] for a fantastic work implementing the
[FileSaver.js][2] to save files & blob's so easily!
But there is one obstacle - The RAM it can hold and the max blob size limitation

StreamSaver.js takes a different approach. Instead of saving data in client-side
storage or in memory you could now actually create a writable stream directly to
the file system (I'm not talking about chromes sandboxed file system)

StreamSaver.js is the solution to saving streams on the client-side.
It is perfect for webapps that need to save really large amount of data created
on the client-side where the RAM is really low like on mobile devices


Getting started
===============
**It's important to test browser support before you include the [web stream polyfill][15]**<br>
cuz the serverWroker need to respondWith a native version of the ReadableStream
```html
<script src="StreamSaver.js"></script> <!-- load before streams polyfill to detect support -->
<script src="https://wzrd.in/standalone/web-streams-polyfill@latest"></script>
<script>
	// it also support commonJs and amd
	import { createWriteStream, supported, version } from 'StreamSaver'
	const { createWriteStream, supported, version } = require('StreamSaver')
	const { createWriteStream, supported, version } = window.streamSaver
	alert( supported )
</script>
```

Syntax
======

### Writing some plain text

```javascript
const writeStream = streamSaver.createWriteStream('filename.txt')
const encoder = new TextEncoder
let data = 'a'.repeat(1024)
let uint8array = encoder.encode(data + "\n\n")

writeStream.write(uint8array)
writeStream.close()
```

### Read blob as a stream and pipe it

```javascript
const writeStream = streamSaver.createWriteStream('filename.txt')
const blob = new Blob([ 'a'.repeat(1E9*5) ]) // 1*5 MB
const blobStream = streamSaver.createBlobReader(blob)

blobStream.pipeTo(writeStream)
```

### Save a media stream


```javascript
get_user_media_stream_somehow().then(mediaStream => {
	let fr = new FileReader
	let mediaRecorder = new MediaRecorder(mediaStream)
	let chunks = Promise.resolve()
	let writeStream = streamSaver.createWriteStream('filename.mp4')
	// use .mp4 for video(camera & screen) and .wav for audio(microphone)

	// Start recording
	mediaRecorder.start()
	
	closeBtn.onclick = event => {
		mediaRecorder.stop()
		setTimeout(() =>
			chunks.then(evt => writeStream.close())
		, 1000)
	}
	
	mediaRecorder.ondataavailable = evt => {
		let blob = evt.data

		chunks = chunks.then(() => new Promise(resolve => {
			fr.onload = () => {
				writeStream.write(fr.result)
				resolve()
			}
			fr.readAsArrayBuffer(blob)
		}))
	}

})
```

### Get a "stream" from ajax
res.body is a readableByteStream, but don't have pipeTo yet<br>
So we have to use the reader instead which is the underlying method in streams

```javascript
fetch(url).then(res => {
	const writeStream = streamSaver.createWriteStream('filename.txt')
	// Later you will be able to just simply do
	// res.body.pipeTo(writeStream)

	const reader = res.body.getReader()
	const pump = () => reader.read()
		.then(({ value, done }) => done
{'fraction_non_alphanumeric': 0.121939736346516, 'fraction_numerical': 0.006591337099811676, 'mean_word_length': 4.654835847382431, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 46, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2380754', 'n_tokens_mistral': 1994, 'n_tokens_neox': 1870, 'n_words': 657}