semantic-stream
v3.0.5
Published
A library of stream classes for semantic text processing, including sources like Wikipedia and news articles.
Maintainers
Readme
semantic-stream
semantic-stream is a Node.js ESM module for building circular text streams from Wikipedia pages, news articles, and a YP/comment stream.
The package is now structured as a normal npm module:
- canonical source lives in
src/ - public entry point is
src/index.js - tests live in
test/ - live smoke tests are opt-in and gated by environment variables
3.0.5
initStreamscan skip titles containing configured filter words
3.0.4
- serializes Wikipedia requests per language and spaces them 250ms apart
3.0.2
- identifies requests with a configurable Wikipedia user agent
- retries Wikipedia
429and503responses with exponential backoff - honors
Retry-Afterwhen the HTTP client exposes it - avoids amplifying a rate limit with fallback searches
- initializes multiple streams sequentially by default
- supports normalized News API request options
What It Does
The module exposes stream classes that:
- fetch content from a source
- extract links or articles
- build circular link pools
- return the next item from the pool
The main use case is semantic text generation or exploration where the next result is derived from linked content rather than random selection.
Install
npm install semantic-streamRequirements
- Node.js
>= 22 - ESM-compatible runtime
Environment
Create a .env file if you want live news support:
NEWS_API_KEY=your-newsapi-key
SEMANTIC_STREAM_USER_AGENT=your-app/1.0 (https://example.com/contact)The live news test and NewsStream both read NEWS_API_KEY from the environment.
SEMANTIC_STREAM_USER_AGENT is optional. Set it to identify your application and
provide contact information to Wikimedia. A package-specific default is used when
the variable is absent.
Package Entry
Import from the package root:
import pkg from 'semantic-stream';
const { WordStream, NewsStream, YPStream, initStreams } = pkg;You can also use named imports:
import { WordStream, NewsStream, YPStream, initStreams } from 'semantic-stream';Public API
WordStream
Wikipedia-backed stream.
const stream = new WordStream('mami', 'de');
await stream.start();
const next = await stream.getNext();Constructor:
new WordStream(word = 'maus', lang = 'en', options = {})Supported options:
circularLinkType: link selection method used byCircularLinksuserAgent: overridesSEMANTIC_STREAM_USER_AGENTrequestPolicy: overrides retry settings such asmaxAttempts,baseDelayMs,maxDelayMs, andminIntervalMs(defaults to250)
Methods:
start()getArticle(title)getNext()searchArticle(str)check(wikijsResult)
NewsStream
News-backed stream.
const stream = new NewsStream({});
await stream.start();
const next = await stream.getNext();Constructor:
new NewsStream(options = {})Supported options for the News API request:
qsearchInsourcesdomainsexcludeDomainsfromtolanguagesortBypageSizepagenoCache
Accepted shapes:
searchIn,sources,domains,excludeDomainscan be a string or an array of stringsfromandtocan be ISO strings orDateobjectssortByacceptsrelevancy,popularity, orpublishedAt
Defaults:
language:enpageSize:100page:1noCache:truefor live requests- all other request fields are optional and may be omitted
Methods:
start()getNews()getSources()getNext()check(articles)
YPStream
YP/comment stream.
const stream = new YPStream({ startWord: 'example' });
await stream.start();
const next = await stream.getNext();Constructor:
new YPStream(options = {})Methods:
start()getComment()getNext()check(comments)
initStreams
Initializes multiple streams in one call.
import { initStreams } from 'semantic-stream';
const streams = await initStreams([
['mami', 'de'],
[':NEWS', {}],
[':YP', { startWord: 'Feedback' }]
], {
filter: ['DOI', 'ISBN']
});Input format:
[word, lang]creates aWordStream[':NEWS', options]creates aNewsStream[':YP', options]creates aYPStream
Optional initStreams options:
circularLinksGetNext: customgetNext()implementation bound onto each stream’sCircularLinksinstancefilter: array of case-insensitive words; a matching title is consumed and skipped, thengetNext()advances to the next itemwordStreamOptions: options forwarded to everyWordStreamstreamStartDelayMs: delay between sequential stream starts; defaults to1000initializeSequentially: set tofalseonly when parallel startup is intentionalregisterExitHandlers: set tofalsewhen the caller owns process lifecycle handling
Important Behavior
WordStream.getNext()may reload more content when the pool gets small.NewsStream.getNews()caches identical in-memory requests for the current process.CircularLinkscontrols which item is returned next.getNextClassicreturns items in insertion order.getNextUniquereturns each title once.
Tests
Run the deterministic suite:
npm testThis covers the local, stubbed behavior and does not require external API access.
Live Smoke Tests
The repo also has opt-in live tests.
Live News
Requires NEWS_API_KEY and RUN_LIVE_TESTS=1:
RUN_LIVE_TESTS=1 NEWS_API_KEY=your-key node --test test/news.live.test.jsLive Wikipedia
Requires RUN_LIVE_TESTS=1:
RUN_LIVE_TESTS=1 node --test test/streams.live.test.jsThe live Wikipedia smoke test fetches 10 live getNext() results for mami/de.
Repository Layout
src/
index.js
core/CircularLinks.js
streams/WordStream.js
streams/NewsStream.js
streams/YPStream.js
streams/onExit.js
utils/wiki-parse-fkt.js
utils/wiki-page-links.js
utils/news-article-groups.js
utils/news-request.js
utils/wikipedia-request-policy.js
utils/word-stream-context.js
utils/word-stream-reload.js
test/
*.test.js
*.live.test.jsDevelopment Notes
The test suite is designed to pin current legacy behavior before refactoring.
If you change stream logic, update or add tests first where possible.
If you add a new source or stream:
- put the implementation under
src/ - expose it from
src/index.js - add a deterministic test
- add a live test only if the live path is useful and safe
Agent Workflow
If a bot is working from this README, use this order:
- Read
package.jsonandsrc/index.js - Read the relevant file under
src/ - Check the corresponding
test/*.test.js - Make the smallest change that preserves the current tests
- Run
npm test - If the change touches live behavior, run the matching live test with
RUN_LIVE_TESTS=1 - Keep the published surface in
src/only
License
Beerware. If you like the project, buy the author a beer sometime.
