{"_id":"parse-sse","name":"parse-sse","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"parse-sse","version":"0.1.0","description":"Parse Server-Sent Events (SSE) from a Response","license":"MIT","repository":{"type":"git","url":"git+https://github.com/sindresorhus/parse-sse.git"},"funding":"https://github.com/sponsors/sindresorhus","author":{"name":"Sindre Sorhus","email":"sindresorhus@gmail.com","url":"https://sindresorhus.com"},"type":"module","exports":{"types":"./index.d.ts","default":"./index.js"},"sideEffects":false,"engines":{"node":">=20"},"scripts":{"test":"xo && node --test"},"keywords":["sse","server-sent-events","eventsource","event-stream","parse","parser","stream","streaming","readablestream","transformstream","fetch","response","async","generator","iterable"],"devDependencies":{"@types/node":"^24.9.1","xo":"^1.2.3"},"xo":{"rules":{"max-depth":"off"}},"gitHead":"e9370e84515cd2a71fcc5d01ffd8fc5be17f2143","types":"./index.d.ts","_id":"parse-sse@0.1.0","bugs":{"url":"https://github.com/sindresorhus/parse-sse/issues"},"homepage":"https://github.com/sindresorhus/parse-sse#readme","_nodeVersion":"24.9.0","_npmVersion":"11.6.1","dist":{"integrity":"sha512-8bObUwtEuLp2Z1gP6iRVMBzmEqaU5ohmofa3WmZVFfFZFKRP/+c03y8NVYzzXmQMotQ6mDS5Mnyk6tT1gKOTcQ==","shasum":"e7eae72ef6852cf75270aab5c91a0898e62864d0","tarball":"https://registry.npmjs.org/parse-sse/-/parse-sse-0.1.0.tgz","fileCount":5,"unpackedSize":18501,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQD84US1riHt4ZheaRZzVTLxewIvrOicKI4tBCURGCqoxQIgKjKB1weO67riM/8tjpIWD0Cnudp7xhr1Vaf1iI15BqQ="}]},"_npmUser":{"name":"sindresorhus","email":"sindresorhus@gmail.com"},"directories":{},"maintainers":[{"name":"sindresorhus","email":"sindresorhus@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/parse-sse_0.1.0_1761410805466_0.5478903741039591"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-25T16:46:45.464Z","0.1.0":"2025-10-25T16:46:45.645Z","modified":"2025-10-25T16:46:46.045Z"},"maintainers":[{"name":"sindresorhus","email":"sindresorhus@gmail.com"}],"description":"Parse Server-Sent Events (SSE) from a Response","homepage":"https://github.com/sindresorhus/parse-sse#readme","keywords":["sse","server-sent-events","eventsource","event-stream","parse","parser","stream","streaming","readablestream","transformstream","fetch","response","async","generator","iterable"],"repository":{"type":"git","url":"git+https://github.com/sindresorhus/parse-sse.git"},"author":{"name":"Sindre Sorhus","email":"sindresorhus@gmail.com","url":"https://sindresorhus.com"},"bugs":{"url":"https://github.com/sindresorhus/parse-sse/issues"},"license":"MIT","readme":"# parse-sse\n\n> Parse [Server-Sent Events](https://html.spec.whatwg.org/multipage/server-sent-events.html) (SSE) from a [Response](https://developer.mozilla.org/docs/Web/API/Response)\n\nA lightweight, spec-compliant parser for Server-Sent Events that works with the native Fetch API. Returns a standard ReadableStream for maximum composability.\n\nPerfect for consuming streaming APIs from OpenAI, Anthropic, and other services.\n\n## Install\n\n```sh\nnpm install parse-sse\n```\n\n## Usage\n\n```js\nimport {parseServerSentEvents} from 'parse-sse';\n\nconst response = await fetch('https://api.example.com/events');\n\nfor await (const event of parseServerSentEvents(response)) {\n\tconsole.log(event.type);        // Event type (default: 'message')\n\tconsole.log(event.data);        // Event data\n\tconsole.log(event.lastEventId); // Last event ID (always present as string)\n\tconsole.log(event.retry);       // Retry interval in ms (if specified)\n}\n```\n\n### With [Ky](https://github.com/sindresorhus/ky)\n\n```js\nimport {parseServerSentEvents} from 'parse-sse';\nimport ky from 'ky';\n\nconst response = await ky('https://api.example.com/events');\n\nfor await (const event of parseServerSentEvents(response)) {\n\tconst data = JSON.parse(event.data);\n\tconsole.log(data);\n}\n```\n\n### OpenAI Streaming\n\n```js\nimport {parseServerSentEvents} from 'parse-sse';\n\nconst response = await fetch('https://api.openai.com/v1/chat/completions', {\n\tmethod: 'POST',\n\theaders: {\n\t\t'Content-Type': 'application/json',\n\t\t'Authorization': `Bearer ${apiKey}`,\n\t},\n\tbody: JSON.stringify({\n\t\tmodel: 'gpt-4',\n\t\tmessages: [{role: 'user', content: 'Hello!'}],\n\t\tstream: true,\n\t}),\n});\n\nfor await (const event of parseServerSentEvents(response)) {\n\tif (event.data === '[DONE]') {\n\t\tbreak;\n\t}\n\n\tconst data = JSON.parse(event.data);\n\tconsole.log(data.choices[0]?.delta?.content);\n}\n```\n\n### Custom Event Types\n\n```js\nimport {parseServerSentEvents} from 'parse-sse';\n\nconst response = await fetch('https://api.example.com/events');\n\nfor await (const event of parseServerSentEvents(response)) {\n\tswitch (event.type) {\n\t\tcase 'update':\n\t\t\tconsole.log('Update:', event.data);\n\t\t\tbreak;\n\t\tcase 'complete':\n\t\t\tconsole.log('Complete:', event.data);\n\t\t\tbreak;\n\t\tcase 'error':\n\t\t\tconsole.error('Error:', event.data);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tconsole.log('Message:', event.data);\n\t}\n}\n```\n\n### Advanced: Stream Composability\n\nSince `parseServerSentEvents()` returns a standard ReadableStream, you can use all stream methods:\n\n```js\nimport {parseServerSentEvents} from 'parse-sse';\n\nconst response = await fetch('https://api.example.com/events');\nconst eventStream = parseServerSentEvents(response);\n\n// Tee the stream to consume it twice\nconst [stream1, stream2] = eventStream.tee();\n\n// Process both streams in parallel\nawait Promise.all([\n\t(async () => {\n\t\tfor await (const event of stream1) {\n\t\t\tconsole.log('Stream 1:', event.data);\n\t\t}\n\t})(),\n\t(async () => {\n\t\tfor await (const event of stream2) {\n\t\t\tconsole.log('Stream 2:', event.data);\n\t\t}\n\t})(),\n]);\n```\n\n### Advanced: Using ServerSentEventTransformStream\n\nFor advanced use cases, you can use `ServerSentEventTransformStream` directly for custom stream pipelines:\n\n```js\nimport {ServerSentEventTransformStream} from 'parse-sse';\n\n// Custom pipeline\nmyTextStream\n\t.pipeThrough(new ServerSentEventTransformStream())\n\t.pipeTo(myWritableStream);\n```\n\n```js\nimport {ServerSentEventTransformStream} from 'parse-sse';\n\n// With custom decoder\nresponse.body\n\t.pipeThrough(new MyCustomDecoderStream())\n\t.pipeThrough(new ServerSentEventTransformStream());\n```\n\n```js\nimport {ServerSentEventTransformStream} from 'parse-sse';\n\n// Filter events in a pipeline\nfetch(url)\n\t.then(r => r.body)\n\t.pipeThrough(new TextDecoderStream())\n\t.pipeThrough(new ServerSentEventTransformStream())\n\t.pipeThrough(new TransformStream({\n\t\ttransform(event, controller) {\n\t\t\tif (event.type === 'update') {\n\t\t\t\tcontroller.enqueue(event);\n\t\t\t}\n\t\t}\n\t}));\n```\n\n## API\n\n### parseServerSentEvents(response)\n\nParse a Server-Sent Events (SSE) stream from a `Response` object.\n\nReturns a [`ReadableStream`](https://developer.mozilla.org/docs/Web/API/ReadableStream) that yields parsed events as they arrive. The stream can be consumed using async iteration (`for await...of`) or stream methods like `.pipeTo()`, `.pipeThrough()`, and `.tee()`.\n\n#### response\n\nType: `Response`\n\nA [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) object with a `text/event-stream` body.\n\n#### Returns\n\nType: `ReadableStream<ServerSentEvent>`\n\nA stream of parsed events that can be consumed using async iteration or standard stream methods.\n\n### ServerSentEventTransformStream\n\nTransformStream that parses Server-Sent Events.\n\nUse this for advanced stream composition or when you have a text stream that's already decoded.\n\n**Important:** This expects string chunks as input. If you have a byte stream, pipe it through `TextDecoderStream` first.\n\n```js\nimport {ServerSentEventTransformStream} from 'parse-sse';\n\n// Correct - with TextDecoderStream for bytes\nresponse.body\n\t.pipeThrough(new TextDecoderStream())\n\t.pipeThrough(new ServerSentEventTransformStream());\n\n// Correct - if you already have text chunks\nmyTextStream\n\t.pipeThrough(new ServerSentEventTransformStream());\n```\n\n#### Input\n\nType: `string`\n\nText chunks (already decoded from bytes). If you pass byte chunks, a `TypeError` will be thrown.\n\n#### Output\n\nType: `ServerSentEvent`\n\nParsed SSE events.\n\n### ServerSentEvent\n\nA parsed Server-Sent Event.\n\nType: `object`\n\n#### type\n\nType: `string`\\\nDefault: `'message'`\n\nThe event type.\n\n#### data\n\nType: `string`\n\nThe event data.\n\nMultiple `data:` fields are joined with newlines.\n\n#### lastEventId\n\nType: `string`\n\nThe last event ID in the stream.\n\nThis is connection-scoped state that persists across events. When an event includes an `id:` field, this value is updated and persists for all subsequent events until changed again.\n\nAlways present as a string (empty string if no ID has been set). Matches browser `MessageEvent.lastEventId` behavior.\n\nUsed for reconnection with `Last-Event-ID` header.\n\n#### retry\n\nType: `number | undefined`\n\nThe retry interval in milliseconds, if specified.\n\nIndicates how long to wait before reconnecting.\n\n## FAQ\n\n### Why not use [`EventSource`](https://developer.mozilla.org/en-US/docs/Web/API/EventSource)?\n\nThe browser's built-in `EventSource` API has several limitations:\n\n- Can't set custom headers (like `Authorization`)\n- Only supports GET requests\n- Doesn't work with the Fetch API\n- No support for async iteration\n- Can't be used with custom `fetch` implementations\n\nThis package works with any `Response` object, giving you full control over the request.\n\n### How is this different from other SSE parsers?\n\nMost SSE parsers either:\n- Implement their own HTTP client (limiting flexibility)\n- Don't follow the spec correctly (especially for edge cases)\n- Have dependencies or large bundle sizes\n- Use callbacks instead of streams\n\nThis package focuses on doing one thing well: parsing SSE from a standard `Response` object using web platform standards (ReadableStream, TransformStream).\n\n### Can I use this with other HTTP clients?\n\nYes! Any HTTP client that returns a standard `Response` object will work:\n\n```js\n// With Ky\nimport ky from 'ky';\n\nconst response = await ky(url);\n\n// With native fetch\nconst response = await fetch(url);\n\n// Both work the same way\nfor await (const event of parseServerSentEvents(response)) {\n\tconsole.log(event.data);\n}\n```\n\n## Related\n\n- [ky](https://github.com/sindresorhus/ky) - Tiny and elegant HTTP client based on Fetch\n- [fetch-extras](https://github.com/sindresorhus/fetch-extras) - Useful utilities for working with Fetch\n","readmeFilename":"readme.md","_rev":"1-bec6d5e491b89912ee6a3462006338d4"}