Streaming API

g.stream(format?) returns a TransformStream<string, string> that you can pipe through to convert an arbitrarily large document without buffering it all at once.

Basic usage

import { 
function load(options?: GukhanmunOptions): Promise<Gukhanmun>

Creates a Gukhanmun converter with the given options.

Initialises the WASM module on the first call (subsequent calls reuse the cached module). Dictionaries supplied via GukhanmunOptions.dictionaries are fetched and passed to the Rust engine as FileDictionarySource values.

Note: unlike the Rust ko-kr preset, the JavaScript preset never includes a bundled dictionary. Pass dictionaries: [await stdictFst()] to include the Standard Korean Language Dictionary.

@paramoptions - Conversion options. All fields are optional; defaults match the ko-kr preset.@returnsA Gukhanmun instance.@throws{@linkGukhanmunError } on invalid options or dictionary load failure.
load
} from "@gukhanmun/wasm";
import {
function stdictFst(): Promise<FileDictionarySource>

Loads the bundled Standard Korean Language Dictionary as a

FileDictionarySource ready to pass to load({ dictionaries: [...] }).

@returnsA FileDictionarySource with format: "fst".
stdictFst
} from "@gukhanmun/stdict-fst";
const
const g: Gukhanmun
g
= await
function load(options?: GukhanmunOptions): Promise<Gukhanmun>

Creates a Gukhanmun converter with the given options.

Initialises the WASM module on the first call (subsequent calls reuse the cached module). Dictionaries supplied via GukhanmunOptions.dictionaries are fetched and passed to the Rust engine as FileDictionarySource values.

Note: unlike the Rust ko-kr preset, the JavaScript preset never includes a bundled dictionary. Pass dictionaries: [await stdictFst()] to include the Standard Korean Language Dictionary.

@paramoptions - Conversion options. All fields are optional; defaults match the ko-kr preset.@returnsA Gukhanmun instance.@throws{@linkGukhanmunError } on invalid options or dictionary load failure.
load
({
GukhanmunOptions.dictionaries?: readonly FileDictionarySource[] | undefined

Ordered list of dictionary sources. Sources are queried in order; earlier entries take precedence. When omitted (or empty), only the fallback Unihan character map is used (no stdict).

Unlike the "ko-kr" Rust preset, JavaScript presets do not automatically include a bundled dictionary. To use the Standard Korean Language Dictionary, add @gukhanmun/stdict-fst or @gukhanmun/stdict-cdb explicitly.

@seeDictionarySource
dictionaries
: [await
function stdictFst(): Promise<FileDictionarySource>

Loads the bundled Standard Korean Language Dictionary as a

FileDictionarySource ready to pass to load({ dictionaries: [...] }).

@returnsA FileDictionarySource with format: "fst".
stdictFst
()] });
const
const stream: TransformStream<string, string>
stream
=
const g: Gukhanmun
g
.
Gukhanmun.stream(format?: Format): TransformStream<string, string>

Returns a TransformStream<string, string> that converts chunks incrementally. Chunks are JavaScript strings; byte-level encoding is the caller's responsibility (TextDecoderStream / TextEncoderStream).

The stream guarantees that the concatenated output equals the result of calling convert on the concatenated input, regardless of chunk boundaries. Document-wide middlewares (e.g., homophone marking with homophoneWindow: "per-document") buffer until the writable side is closed.

@paramformat - Input / output format. Defaults to "text".@returnsA platform TransformStream<string, string>.@throws{@linkGukhanmunError } on initialisation failure (not on chunk errors; those are signalled via the stream's error channel).
stream
("html");
const
const writer: WritableStreamDefaultWriter<string>
writer
=
const stream: TransformStream<string, string>
stream
.
TransformStream<string, string>.writable: WritableStream<string>

The writable read-only property of the TransformStream interface returns the WritableStream instance controlled by this TransformStream. This stream accepts input data that will be transformed and emitted to the readable stream.

MDN Reference

writable
.
WritableStream<string>.getWriter(): WritableStreamDefaultWriter<string>

The getWriter() method of the WritableStream interface returns a new instance of WritableStreamDefaultWriter and locks the stream to that instance. While the stream is locked, no other writer can be acquired until this one is released.

MDN Reference

getWriter
();
const
const reader: ReadableStreamDefaultReader<string>
reader
=
const stream: TransformStream<string, string>
stream
.
TransformStream<string, string>.readable: ReadableStream<string>

The readable read-only property of the TransformStream interface returns the ReadableStream instance controlled by this TransformStream. This stream emits the transformed output data.

MDN Reference

readable
.
ReadableStream<string>.getReader(): ReadableStreamDefaultReader<string> (+2 overloads)

The getReader() method of the ReadableStream interface creates a reader and locks the stream to it. While the stream is locked, no other reader can be acquired until this one is released.

MDN Reference

getReader
();
// Write chunks await
const writer: WritableStreamDefaultWriter<string>
writer
.
WritableStreamDefaultWriter<string>.write(chunk?: string | undefined): Promise<void>

The write() method of the WritableStreamDefaultWriter interface writes a passed chunk of data to a WritableStream and its underlying sink, then returns a Promise that resolves to indicate the success or failure of the write operation.

MDN Reference

write
("<p>漢");
await
const writer: WritableStreamDefaultWriter<string>
writer
.
WritableStreamDefaultWriter<string>.write(chunk?: string | undefined): Promise<void>

The write() method of the WritableStreamDefaultWriter interface writes a passed chunk of data to a WritableStream and its underlying sink, then returns a Promise that resolves to indicate the success or failure of the write operation.

MDN Reference

write
("字</p>");
await
const writer: WritableStreamDefaultWriter<string>
writer
.
WritableStreamDefaultWriter<string>.close(): Promise<void>

The close() method of the WritableStreamDefaultWriter interface closes the associated writable stream.

MDN Reference

close
();
// Read converted output const
const parts: string[]
parts
: string[] = [];
for (;;) { const {
const done: boolean
done
,
const value: string | undefined
value
} = await
const reader: ReadableStreamDefaultReader<string>
reader
.
ReadableStreamDefaultReader<string>.read(): Promise<ReadableStreamReadResult<string>>

The read() method of the ReadableStreamDefaultReader interface returns a Promise providing access to the next chunk in the stream's internal queue.

MDN Reference

read
();
if (
const done: boolean
done
) break;
if (
const value: string
value
)
const parts: string[]
parts
.
Array<string>.push(...items: string[]): number

Appends new elements to the end of an array, and returns the new length of the array.

@paramitems New elements to add to the array.
push
(
const value: string
value
);
}
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
@seesource
console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0 .1.100
log
(
const parts: string[]
parts
.
Array<string>.join(separator?: string): string

Adds all the elements of an array into a string, separated by the specified separator string.

@paramseparator A string used to separate one element of the array from the next in the resulting string. If omitted, the array elements are separated with a comma.
join
("")); // <p>한자</p>

Format argument

The format argument to stream accepts the same values as convert():

const g: Gukhanmun
g
.
Gukhanmun.stream(format?: Format): TransformStream<string, string>

Returns a TransformStream<string, string> that converts chunks incrementally. Chunks are JavaScript strings; byte-level encoding is the caller's responsibility (TextDecoderStream / TextEncoderStream).

The stream guarantees that the concatenated output equals the result of calling convert on the concatenated input, regardless of chunk boundaries. Document-wide middlewares (e.g., homophone marking with homophoneWindow: "per-document") buffer until the writable side is closed.

@paramformat - Input / output format. Defaults to "text".@returnsA platform TransformStream<string, string>.@throws{@linkGukhanmunError } on initialisation failure (not on chunk errors; those are signalled via the stream's error channel).
stream
(); // plain text (default)
const g: Gukhanmun
g
.
Gukhanmun.stream(format?: Format): TransformStream<string, string>

Returns a TransformStream<string, string> that converts chunks incrementally. Chunks are JavaScript strings; byte-level encoding is the caller's responsibility (TextDecoderStream / TextEncoderStream).

The stream guarantees that the concatenated output equals the result of calling convert on the concatenated input, regardless of chunk boundaries. Document-wide middlewares (e.g., homophone marking with homophoneWindow: "per-document") buffer until the writable side is closed.

@paramformat - Input / output format. Defaults to "text".@returnsA platform TransformStream<string, string>.@throws{@linkGukhanmunError } on initialisation failure (not on chunk errors; those are signalled via the stream's error channel).
stream
("html"); // HTML
const g: Gukhanmun
g
.
Gukhanmun.stream(format?: Format): TransformStream<string, string>

Returns a TransformStream<string, string> that converts chunks incrementally. Chunks are JavaScript strings; byte-level encoding is the caller's responsibility (TextDecoderStream / TextEncoderStream).

The stream guarantees that the concatenated output equals the result of calling convert on the concatenated input, regardless of chunk boundaries. Document-wide middlewares (e.g., homophone marking with homophoneWindow: "per-document") buffer until the writable side is closed.

@paramformat - Input / output format. Defaults to "text".@returnsA platform TransformStream<string, string>.@throws{@linkGukhanmunError } on initialisation failure (not on chunk errors; those are signalled via the stream's error channel).
stream
("markdown"); // CommonMark
const g: Gukhanmun
g
.
Gukhanmun.stream(format?: Format): TransformStream<string, string>

Returns a TransformStream<string, string> that converts chunks incrementally. Chunks are JavaScript strings; byte-level encoding is the caller's responsibility (TextDecoderStream / TextEncoderStream).

The stream guarantees that the concatenated output equals the result of calling convert on the concatenated input, regardless of chunk boundaries. Document-wide middlewares (e.g., homophone marking with homophoneWindow: "per-document") buffer until the writable side is closed.

@paramformat - Input / output format. Defaults to "text".@returnsA platform TransformStream<string, string>.@throws{@linkGukhanmunError } on initialisation failure (not on chunk errors; those are signalled via the stream's error channel).
stream
({
format: "markdown"
format
: "markdown",
gfm?: boolean | undefined
gfm
: true }); // GFM

Piping with the WHATWG Streams API

TransformStream integrates with the standard Streams API:

const 
const response: Response
response
= await
function fetch(input: string | URL | Request, init?: RequestInit): Promise<Response> (+1 overload)
fetch
("/large-document.html");
const
const converted: ReadableStream<Uint8Array<ArrayBuffer>>
converted
=
const response: Response
response
.
Body.body: ReadableStream<Uint8Array<ArrayBuffer>> | null
body
!
.
ReadableStream<Uint8Array<ArrayBuffer>>.pipeThrough<string>(transform: ReadableWritablePair<string, Uint8Array<ArrayBuffer>>, options?: StreamPipeOptions): ReadableStream<string>

The pipeThrough() method of the ReadableStream interface provides a chainable way of piping the current stream through a transform stream or any other writable/readable pair.

MDN Reference

pipeThrough
(new
var TextDecoderStream: new (label?: string, options?: TextDecoderOptions) => TextDecoderStream

The TextDecoderStream interface of the Encoding API converts a stream of text in a binary encoding, such as UTF-8 etc., to a stream of strings. It is the streaming equivalent of TextDecoder. It implements the same shape as a TransformStream, allowing it to be used in ReadableStream.pipeThrough() and similar methods.

MDN Reference

TextDecoderStream class is a global reference for import { TextDecoderStream } from 'node:stream/web'. https://nodejs.org/api/globals.html#class-textdecoderstream

@sincev18 .0.0
TextDecoderStream
())
.
ReadableStream<string>.pipeThrough<string>(transform: ReadableWritablePair<string, string>, options?: StreamPipeOptions): ReadableStream<string>

The pipeThrough() method of the ReadableStream interface provides a chainable way of piping the current stream through a transform stream or any other writable/readable pair.

MDN Reference

pipeThrough
(
const g: Gukhanmun
g
.
Gukhanmun.stream(format?: Format): TransformStream<string, string>

Returns a TransformStream<string, string> that converts chunks incrementally. Chunks are JavaScript strings; byte-level encoding is the caller's responsibility (TextDecoderStream / TextEncoderStream).

The stream guarantees that the concatenated output equals the result of calling convert on the concatenated input, regardless of chunk boundaries. Document-wide middlewares (e.g., homophone marking with homophoneWindow: "per-document") buffer until the writable side is closed.

@paramformat - Input / output format. Defaults to "text".@returnsA platform TransformStream<string, string>.@throws{@linkGukhanmunError } on initialisation failure (not on chunk errors; those are signalled via the stream's error channel).
stream
("html"))
.
ReadableStream<string>.pipeThrough<Uint8Array<ArrayBuffer>>(transform: ReadableWritablePair<Uint8Array<ArrayBuffer>, string>, options?: StreamPipeOptions): ReadableStream<Uint8Array<ArrayBuffer>>

The pipeThrough() method of the ReadableStream interface provides a chainable way of piping the current stream through a transform stream or any other writable/readable pair.

MDN Reference

pipeThrough
(new
var TextEncoderStream: new () => TextEncoderStream

The TextEncoderStream interface of the Encoding API converts a stream of strings into bytes in the UTF-8 encoding. It is the streaming equivalent of TextEncoder. It implements the same shape as a TransformStream, allowing it to be used in ReadableStream.pipeThrough() and similar methods.

MDN Reference

TextEncoderStream class is a global reference for import { TextEncoderStream } from 'node:stream/web'. https://nodejs.org/api/globals.html#class-textencoderstream

@sincev18 .0.0
TextEncoderStream
());

Streaming guarantee

Concatenating all chunks written to the stream's writable side and all chunks read from the readable side is equivalent to calling g.convert() on the full concatenated input:

// These are always equivalent:
const 
const result1: string
result1
=
const g: Gukhanmun
g
.
Gukhanmun.convert(source: string, format?: Format): string

Converts source to hangul in one shot. Buffers the entire input before returning.

@paramsource - The text to convert.@paramformat - Input / output format. Defaults to "text".@returnsThe converted text.@throws{@linkGukhanmunError } on conversion failure.
convert
(
const chunkA: string
chunkA
+
const chunkB: string
chunkB
+
const chunkC: string
chunkC
, "html");
// and const
const stream: TransformStream<string, string>
stream
=
const g: Gukhanmun
g
.
Gukhanmun.stream(format?: Format): TransformStream<string, string>

Returns a TransformStream<string, string> that converts chunks incrementally. Chunks are JavaScript strings; byte-level encoding is the caller's responsibility (TextDecoderStream / TextEncoderStream).

The stream guarantees that the concatenated output equals the result of calling convert on the concatenated input, regardless of chunk boundaries. Document-wide middlewares (e.g., homophone marking with homophoneWindow: "per-document") buffer until the writable side is closed.

@paramformat - Input / output format. Defaults to "text".@returnsA platform TransformStream<string, string>.@throws{@linkGukhanmunError } on initialisation failure (not on chunk errors; those are signalled via the stream's error channel).
stream
("html");
const
const writer: WritableStreamDefaultWriter<string>
writer
=
const stream: TransformStream<string, string>
stream
.
TransformStream<string, string>.writable: WritableStream<string>

The writable read-only property of the TransformStream interface returns the WritableStream instance controlled by this TransformStream. This stream accepts input data that will be transformed and emitted to the readable stream.

MDN Reference

writable
.
WritableStream<string>.getWriter(): WritableStreamDefaultWriter<string>

The getWriter() method of the WritableStream interface returns a new instance of WritableStreamDefaultWriter and locks the stream to that instance. While the stream is locked, no other writer can be acquired until this one is released.

MDN Reference

getWriter
();
await
const writer: WritableStreamDefaultWriter<string>
writer
.
WritableStreamDefaultWriter<string>.write(chunk?: string | undefined): Promise<void>

The write() method of the WritableStreamDefaultWriter interface writes a passed chunk of data to a WritableStream and its underlying sink, then returns a Promise that resolves to indicate the success or failure of the write operation.

MDN Reference

write
(
const chunkA: string
chunkA
);
await
const writer: WritableStreamDefaultWriter<string>
writer
.
WritableStreamDefaultWriter<string>.write(chunk?: string | undefined): Promise<void>

The write() method of the WritableStreamDefaultWriter interface writes a passed chunk of data to a WritableStream and its underlying sink, then returns a Promise that resolves to indicate the success or failure of the write operation.

MDN Reference

write
(
const chunkB: string
chunkB
);
await
const writer: WritableStreamDefaultWriter<string>
writer
.
WritableStreamDefaultWriter<string>.write(chunk?: string | undefined): Promise<void>

The write() method of the WritableStreamDefaultWriter interface writes a passed chunk of data to a WritableStream and its underlying sink, then returns a Promise that resolves to indicate the success or failure of the write operation.

MDN Reference

write
(
const chunkC: string
chunkC
);
await
const writer: WritableStreamDefaultWriter<string>
writer
.
WritableStreamDefaultWriter<string>.close(): Promise<void>

The close() method of the WritableStreamDefaultWriter interface closes the associated writable stream.

MDN Reference

close
();
const
const result2: Promise<string>
result2
=
const stream: TransformStream<string, string>
stream
.
TransformStream<string, string>.readable: ReadableStream<string>

The readable read-only property of the TransformStream interface returns the ReadableStream instance controlled by this TransformStream. This stream emits the transformed output data.

MDN Reference

readable
.
ReadableStream<string>.getReader(): ReadableStreamDefaultReader<string> (+2 overloads)

The getReader() method of the ReadableStream interface creates a reader and locks the stream to it. While the stream is locked, no other reader can be acquired until this one is released.

MDN Reference

getReader
()
.
ReadableStreamDefaultReader<string>.read(): Promise<ReadableStreamReadResult<string>>

The read() method of the ReadableStreamDefaultReader interface returns a Promise providing access to the next chunk in the stream's internal queue.

MDN Reference

read
()
.
Promise<ReadableStreamReadResult<string>>.then<string, never>(onfulfilled?: ((value: ReadableStreamReadResult<string>) => string | PromiseLike<string>) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<string>

Attaches callbacks for the resolution and/or rejection of the Promise.

@paramonfulfilled The callback to execute when the Promise is resolved.@paramonrejected The callback to execute when the Promise is rejected.@returnsA Promise for the completion of which ever callback is executed.
then
(({
value: string | undefined
value
}) =>
value: string | undefined
value
|| "");
import
function assert(value: unknown, message?: string | Error): asserts value
assert
from "node:assert/strict";
function assert(value: unknown, message?: string | Error): asserts value
assert
.
strict.strictEqual<Promise<string>>(actual: unknown, expected: Promise<string>, message?: string | Error): asserts actual is Promise<string>
export strict.strictEqual

Tests strict equality between the actual and expected parameters as determined by Object.is().

import assert from 'node:assert/strict';

assert.strictEqual(1, 2);
// AssertionError [ERR_ASSERTION]: Expected inputs to be strictly equal:
//
// 1 !== 2

assert.strictEqual(1, 1);
// OK

assert.strictEqual('Hello foobar', 'Hello World!');
// AssertionError [ERR_ASSERTION]: Expected inputs to be strictly equal:
// + actual - expected
//
// + 'Hello foobar'
// - 'Hello World!'
//          ^

const apples = 1;
const oranges = 2;
assert.strictEqual(apples, oranges, `apples ${apples} !== oranges ${oranges}`);
// AssertionError [ERR_ASSERTION]: apples 1 !== oranges 2

assert.strictEqual(1, '1', new TypeError('Inputs are not identical'));
// TypeError: Inputs are not identical

If the values are not strictly equal, an AssertionError is thrown with a message property set equal to the value of the message parameter. If the message parameter is undefined, a default error message is assigned. If the message parameter is an instance of an Error then it will be thrown instead of the AssertionError.

@sincev0 .1.21
strictEqual
(
const result1: string
result1
,
const result2: Promise<string>
result2
);

The stream may buffer internally at context boundaries (for example, "per-document" homophone tracking reads the entire document before flushing). With the default "per-block" setting, output is flushed after each block element.