# stream-sac

> Stream related functions: Html minifier, Markdown parser, concat as stream and streamify a string function.

Latest version **3.1.0** (published 2026-09-15) · CC0-1.0 license · 0 weekly downloads

## Install

```sh
npm install stream-sac
pnpm add stream-sac
yarn add stream-sac
bun add stream-sac
```

## Health

**Score 60/100 (C)** — status: active.

Positive: esm support; no vulnerabilities; recently updated; high maintenance score.

Warnings: low downloads; no types.

## Facts

| | |
|---|---|
| Version | 3.1.0 |
| Published | 2026-09-15 |
| First published | 2021-02-27 |
| Weekly downloads | 0 |
| License | CC0-1.0 |
| TypeScript types | none |
| Module format | ESM |
| Dependencies | 5 |
| Unpacked size | 162.7 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 3 |
| Maintainers | grossacasacs |
| Keywords | stream, concat, string, html, minify |

## Links

- npm: https://www.npmjs.com/package/stream-sac
- Repository: https://github.com/GrosSacASac/stream-sac
- Homepage: https://github.com/GrosSacASac/stream-sac#readme
- Issues: https://github.com/GrosSacASac/stream-sac/issues
- npm.io page: https://npm.io/package/stream-sac

## Dependencies (5)

- [into-stream](https://npm.io/package/into-stream.md) ^9.1.0
- [multistream](https://npm.io/package/multistream.md) ^4.1.0
- [html-escaper](https://npm.io/package/html-escaper.md) ^3.0.3
- [@sindresorhus/slugify](https://npm.io/package/@sindresorhus/slugify.md) ^3.0.1
- [is-whitespace-character](https://npm.io/package/is-whitespace-character.md) ^2.0.1

## Alternatives

- [@tsparticles/shape-image](https://npm.io/package/@tsparticles/shape-image.md) — 303.7K weekly downloads
- [@tsparticles/shape-line](https://npm.io/package/@tsparticles/shape-line.md) — 233.7K weekly downloads
- [stringify-attributes](https://npm.io/package/stringify-attributes.md) — 58.6K weekly downloads
- [mobile-drag-drop](https://npm.io/package/mobile-drag-drop.md) — 46.3K weekly downloads
- [@comunica/actor-rdf-parse-html](https://npm.io/package/@comunica/actor-rdf-parse-html.md) — 29.2K weekly downloads

## Recent versions

- 3.1.0 (latest) — 2026-09-15
- 3.0.1 — 2022-09-26
- 2.2.1 — 2022-03-29
- 2.2.0 — 2022-03-16
- 2.1.2 — 2022-02-12
- 2.1.0 — 2021-12-20
- 2.0.2 — 2021-11-26
- 2.0.1 — 2021-11-26
- 2.0.0 — 2021-11-10
- 1.16.0 — 2021-11-03
- 1.15.14 — 2021-05-11
- 1.15.11 — 2021-05-11
- 1.15.7 — 2021-05-11
- 1.15.4 — 2021-05-11
- 1.15.1 — 2021-05-10
- … 17 more at https://npm.io/package/stream-sac/versions

## README

# [stream-sac](https://github.com/GrosSacASac/stream-sac)

Stream related functions: Html minifier, Markdown parser, concat as stream and streamify a string function.

## Installation

[`npm i stream-sac`](https://www.npmjs.com/package/stream-sac)

## Usage

## HtmlMinifier.js

Minify Html with a transform stream. Line breaks and spaces are combined into 1 space.
The input should be valid. Optional pass jsMinifier and cssMinifier to minify inline.

```js
import fs from "node:fs";
import { pipeline } from "node:stream";
import {
    HtmlMinifier,
} from "stream-sac/source/html/HtmlMinifier.js";


const source = `./tests/manual/html.html`;
const destination =  `./tests/output/html.min.html`;
const htmlMinifier = new HtmlMinifier({
    jsMinifier: (x) => x, // sync function
    cssMinifier: (y) => y,
});
htmlMinifier.setEncoding(`utf8`);

pipeline(
    fs.createReadStream(source),
    htmlMinifier,
    fs.createWriteStream(destination),
    (error) => {
    if (error) {
        console.error(error);
    }
});

```

## MarkdownParser.js

Parse markdown into html with a transform stream. The input should be valid. Check the demo in the demo/ folder. Deployed demo at [stream-sac.vercel.app/editor](https://stream-sac.vercel.app/editor.html)

```js
import {
    MarkdownParser,
} from "stream-sac/source/markdown/MarkdownParserNode.js";

const markdownStream = new MarkdownParser({
    // all optional
    languagePrefix: `language-`,
    highlight: function (str, lang) {
        // import hljs to get code highlighting
        if (lang && hljs.getLanguage(lang)) {
            try {
            return hljs.highlight(lang, str).value;
            } catch (__) {}
        }
    
        return ``;
    },
    // for example to resize images on the fly
    mediaHook: function (src, alt) {
        return `<img alt="${alt}" src="${src}">`;
    },
    // for example to disable all external links 
    linkHrefHook: function (src) {
        if (!src.startsWith("https://example.com")) {
            return "#";
        }
        return src;
    },
    linkAttributeString: "", // or `target="_blank"`
});
```

### Deno and Web

`createMarkdownParserStream` takes the same options as above, however it is a function that returns a web transform stream. It expects data to be strings, so TextDecoderStream may have to be used.

```js
import { createMarkdownParserStream } from "stream-sac/built/MarkdownParserWeb.es.js"
// or
import { createMarkdownParserStream } from "https://unpkg.com/stream-sac/built/MarkdownParserWeb.es.js";
```

[Complete Example for Deno](./tests/manual/DenoMarkdownParser.js)

## streamifyStringFunction.js

Take any function that takes as input and out a string, and return a transform stream creator, that does the same on streams.

```js
import {
    streamifyStringFunction,
} from "stream-sac/source/streamifyStringFunction.js";


// Caesar cipher -only lowercase letters
const shift = 1;
const lowera = 97
const lowerZ = 122;
const range = lowerZ - lowera + 1;
const encodeCaesar = s => {
    return Array.from(s).map(c => {
        const unicodeNumber = c.charCodeAt(0);
        if (unicodeNumber >= lowera && unicodeNumber <= lowerZ) {   
            return String.fromCharCode(((unicodeNumber - lowera + shift) % range) + lowera);
        }
        return c;
    }).join(``);
};

// transforms a function that works with strings into a function that returns a transform stream
const createCesarEncodeStream = streamifyStringFunction(encodeCaesar);
const cesarEncodeStream = createCesarEncodeStream();
cesarEncodeStream.pipe(process.stdout);
cesarEncodeStream.write(`The lazy fox ...`);
cesarEncodeStream.write(`jumps over !`);
cesarEncodeStream.end(); // output: Tif mbaz gpy ...kvnqt pwfs !

```

## concatAsStream.js

Concatenate arrays, strings, streams, promises as one Readable stream.

```js
import {
    concatAsStream,
} from "stream-sac/source/concatAsStream.js";

import { pipeline } from "node:stream";
import fs from "node:fs";
import { concatAsStream } from "../../source/concatAsStream.js";


// example sources
const readStream = fs.createReadStream(`./readme.md`);
const readStreamInPromise = fs.createReadStream(`./changelog.md`);
const promise = Promise.resolve(readStreamInPromise);
const aString = `Hello love
`;
const otherString = `THE END`;

// create
const concatedStream = concatAsStream([
    readStream, // stream readme
    aString, // String and linebreak
    promise, // promise of a stream (changelog)
    otherString, // String and linebreak
]);
concatedStream.setEncoding(`utf8`);

// output to standard out, could also output to http response, file, etc.
pipeline(concatedStream, process.stdout, (error) => {
    if (error) {
        console.error(error);
    }
});

```

## About

### Logo

![Put logo here](https://avatars.githubusercontent.com/u/5721194?v=4)

### Changelog

[Changelog](./changelog.md)

### License

[CC0](./license.txt)

### Related

- [from2](https://www.npmjs.com/package/from2)
- [Readable.from](https://nodejs.org/api/stream.html#stream_creating_readable_streams_with_async_generators)
- [into-stream](https://github.com/sindresorhus/into-stream)
- [table generator](https://www.tablesgenerator.com/markdown_tables)

---
_Source: https://npm.io/package/stream-sac · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
