Skip to content

API リファレンス

このページは Suzume の JavaScript / WASM バインディングについて解説します。npm では @libraz/suzume として公開しています。Python、Go、C/C++、2 種類のコマンドラインインターフェースには別のガイドがあります。

Suzume クラス

日本語トークン化のメインクラス。

Suzume.create(options?)

新しい Suzume インスタンスを作成します。

typescript
static async create(options?: SuzumeOptions & { wasmPath?: string }): Promise<Suzume>

SuzumeOptions:

オプションデフォルト説明
wasmPathstringundefinedWASM ファイルのカスタムパス
freshWasmModulebooleanfalse共有キャッシュを使わず、独立した WASM ランタイムを作成
preserveVubooleantrueヴを保持(ビ等に正規化しない)
preserveCasebooleantrue大文字小文字を保持(ASCII を小文字化しない)
preserveSymbolsbooleanfalse句読点などの SYMBOL トークンを保持。絵文字や内容を持つ記号は、この設定にかかわらず OTHER として保持
mode'normal' | 'search' | 'split''normal'解析モード。検索向けの分割には search または split を使用
lemmatizebooleantrue補正した辞書形を保持。品詞と活用情報はこの設定にかかわらず計算
mergeCompoundsbooleanfalse連続する名詞複合を可能な範囲で結合
skipUserDictionarybooleanfalse同梱ユーザー辞書の自動読み込みを省略
skipCoreDictionarybooleanfalse同梱 L2 コア辞書の自動読み込みを省略
skipEnvConfigbooleanfalseネイティブのスコアラー設定用環境変数を無視
reportScorerConfigbooleanfalseスコアラー設定の診断情報を dictionaryWarnings に追加
scorerOptionsstring | Record<string, unknown>undefined最優先で適用するスコアラー設定。JSON 文字列または JSON 化されるオブジェクト

通貨・単位記号、矢印、数学・技術記号、絵文字はテキストの内容を持つため、既定の解析でも OTHER として残ります。preserveSymbols: true は、 などの句読点もトークンとして必要な場合に指定します。

戻り値: Promise<Suzume>

例:

typescript
// 通常の使用
const defaultSuzume = await Suzume.create()
defaultSuzume.destroy()

// カスタム WASM パス
const customWasmSuzume = await Suzume.create({ wasmPath: '/path/to/suzume.wasm' })
customWasmSuzume.destroy()

// オプション指定
const searchSuzume = await Suzume.create({
  preserveSymbols: true,
  preserveVu: false,
  mode: 'search',
  mergeCompounds: true,
  scorerOptions: {
    unary: { noun_prior: 0.25 },
  },
})
searchSuzume.destroy()

解析モード:

mode オプションはテキストの分割方法を制御します。

  • normal — 汎用向けのバランスの取れた分割(デフォルト)。
  • search — 連続する名詞複合語を大きな検索単位として結合する、検索向けの出力。
  • split — 最も細かい分割。複合語を意味を持つ最小単位まで分解します。

normal モードでは mergeCompounds が名詞複合語の結合を制御します。search は結合を有効にし、split は無効にします。

scorerOptions は作成時に検証されます。不正な JSON を渡すと Suzume.create() が失敗します。reportScorerConfig: true を指定すると、有効な設定が dictionaryWarnings に記録されます。WASM ビルドはネイティブのスコアラー環境変数を読み込まないため、このバインディングでは skipEnvConfig を指定しても動作は変わりません。

共有 WASM ランタイム

デフォルトでは、同じ wasmPath を使う呼び出しが 1 つの WASM ランタイムを共有します。各 Suzume オブジェクトは個別の解析ハンドルと設定を持ちますが、WebAssembly の線形メモリは共有です。destroy() が解放するのは 1 つのハンドルだけです。キャッシュ済みランタイムは残り、ほかのハンドルにも影響しません。

ランタイムごと分離する必要がある場合は freshWasmModule: true を指定します。単独の version() 関数も、freshWasmModule: true を指定しない限り同じキャッシュを使います。


mode

辞書を読み直さずに解析モードを取得・変更します。

typescript
get mode(): 'normal' | 'search' | 'split'
set mode(value: 'normal' | 'search' | 'split')
typescript
console.log(suzume.mode) // "normal"
suzume.mode = 'split'

analyze(text)

日本語テキストを解析し、トークンの配列を返します。

typescript
analyze(text: string): Morpheme[]
パラメータ説明
textstring解析する日本語テキスト

戻り値: Morpheme[]

例:

typescript
const result = suzume.analyze('東京に行きました')

// 結果:
// [
//   { surface: '東京', pos: 'NOUN', posJa: '名詞', ... },
//   { surface: 'に', pos: 'PARTICLE', posJa: '助詞', ... },
//   { surface: '行き', pos: 'VERB', posJa: '動詞', ... },
//   { surface: 'まし', pos: 'AUX', posJa: '助動詞', ... },
//   { surface: 'た', pos: 'AUX', posJa: '助動詞', ... }
// ]

analyzeWithNormalizedText(text)

形態素と、そのオフセットが参照する正規化後の文字列を返します。

typescript
interface AnalysisResult {
  normalizedText: string
  morphemes: Morpheme[]
}

analyzeWithNormalizedText(text: string): AnalysisResult

JavaScript の文字列を切り出す場合は UTF-16 オフセットを使います。

typescript
const { normalizedText, morphemes } =
  suzume.analyzeWithNormalizedText('🎉𠮷字を読む')

for (const morpheme of morphemes) {
  const surface = normalizedText.slice(
    morpheme.startUtf16,
    morpheme.endUtf16,
  )
  console.log(surface)
}

startendnormalizedText 内の Unicode コードポイント単位の位置です。startUtf16endUtf16 は JavaScript の UTF-16 コードユニット単位で、そのまま String.prototype.slice() に渡せます。絵文字や一部の漢字など、基本多言語面の外にある文字より後ろ、またはその文字をまたぐ範囲では両者の値が異なります。オフセットは入力ではなく正規化後の文字列を参照します。内容を持つ記号と絵文字は、preserveSymbolsfalse でも OTHER として既定の出力に残るため、その範囲も欠けません。


generateTags(text, options?)

検索インデックス、分類、コンテンツ分析用のタグを生成します。デフォルトでは内容語(名詞、動詞、形容詞、副詞)を返し、助詞、助動詞、形式名詞、低情報語を除外します。

typescript
generateTags(text: string, options?: TagOptions): Tag[]

Tag:

プロパティ説明
tagstringタグテキスト(useLemma 設定に応じて表層形または原形)
posstring品詞(NOUN, VERB, ADJ, ADV 等)
パラメータ説明
textstringタグを抽出する日本語テキスト
optionsTagOptionsタグ生成のオプション設定

TagOptions:

オプションデフォルト説明
posFilterreadonly TagPosFilterName[]undefined(全て)抽出する品詞カテゴリ。空配列もフィルタ可能な全カテゴリを含む
posreadonly TagPosFilterName[]undefinedposFilter の非推奨エイリアス。両方を指定した場合は posFilter を優先
excludeBasicbooleanfalseひらがなのみの原形を持つ基本動詞等を除外
useLemmabooleantrue表層形の代わりに原形(辞書形)を使用
minLengthnumber2タグの最小文字数
maxTagsnumber0タグの最大数(0 = 無制限)
excludeParticlesbooleantrue助詞を除外
excludeAuxiliariesbooleantrue助動詞を除外
excludeFormalNounsbooleantrueこと、もの等の形式名詞を除外
excludeLowInfobooleantrue低情報語を除外
removeDuplicatesbooleantrue重複タグを削除

TagPosFilterName'noun' | 'verb' | 'adjective' | 'adverb' | 'particle' | 'auxiliary' です。未知の名前を渡すと Error が発生します。助詞または助動詞を含めるには、対応する除外オプションも無効にします。

戻り値: Tag[]

例:

typescript
// 基本的な使い方
const tags = suzume.generateTags('東京スカイツリーに行きました')
// [{ tag: '東京', pos: 'NOUN' },
//  { tag: 'スカイツリー', pos: 'NOUN' },
//  { tag: '行く', pos: 'VERB' }]

// 名詞のみ
const nouns = suzume.generateTags('美しい花が静かに咲いている', {
  posFilter: ['noun'],
  minLength: 1,
})
// [{ tag: '花', pos: 'NOUN' }]

// 助詞と助動詞
const functionWords = suzume.generateTags('花が咲きます', {
  posFilter: ['particle', 'auxiliary'],
  excludeParticles: false,
  excludeAuxiliaries: false,
  minLength: 1,
})
// [{ tag: 'が', pos: 'PARTICLE' },
//  { tag: 'ます', pos: 'AUX' }]

// 基本動詞の除外(する、いる、ある、なる等のひらがなのみの原形を持つ語)
const tags2 = suzume.generateTags('新しいプロジェクトを開始して管理する', {
  excludeBasic: false
})
// [{ tag: '新しい', pos: 'ADJ' },
//  { tag: 'プロジェクト', pos: 'NOUN' },
//  { tag: '開始', pos: 'NOUN' },
//  { tag: 'する', pos: 'VERB' },
//  { tag: '管理', pos: 'NOUN' }]

const tags3 = suzume.generateTags('新しいプロジェクトを開始して管理する', {
  excludeBasic: true
})
// [{ tag: '新しい', pos: 'ADJ' },
//  { tag: 'プロジェクト', pos: 'NOUN' },
//  { tag: '開始', pos: 'NOUN' },
//  { tag: '管理', pos: 'NOUN' }]
// 'する' は除外される(原形がひらがなのみ)

// 結果数を制限
const top3 = suzume.generateTags('東京タワーと東京スカイツリーを見学しました', {
  maxTags: 3
})
// [{ tag: '東京', pos: 'NOUN' },
//  { tag: 'タワー', pos: 'NOUN' },
//  { tag: 'スカイツリー', pos: 'NOUN' }]

excludeBasic

excludeBasic: true は原形(辞書形)がすべてひらがなで書かれた語を除外します。する、いる、ある、なる、いく、くるなどを除外し、開始、管理、確認など漢字を含む語は残します。

フィルタパイプライン

タグジェネレーターは以下の順序でフィルタを適用します:

  1. 助詞excludeParticlestrue の場合に除外(デフォルト)
  2. 助動詞excludeAuxiliariestrue の場合に除外(デフォルト)
  3. 形式名詞excludeFormalNounstrue の場合に除外(デフォルト)
  4. 低情報語excludeLowInfotrue の場合に除外(デフォルト)
  5. 接続詞 — 常に除外
  6. 記号 — 常に除外
  7. 品詞フィルタposFilter が空でない場合、一致するカテゴリのみ通過
  8. 基本語excludeBasic: true の場合、ひらがなのみの原形を持つ語を除外
  9. タグ文字列useLemma に従って原形または表層形を選択
  10. 最小文字数 — Unicode 文字数が minLength 未満のタグを除外
  11. 重複排除removeDuplicatestrue の場合に重複タグを削除
  12. 結果数maxTags 件で生成を終了。0 は無制限

loadUserDictionary(data)

解析器にソース辞書のエントリを追加します。clearUserDictionaries() を呼ぶまで、読み込み内容は累積します。

typescript
loadUserDictionary(data: string): boolean
パラメータ説明
datastring現行 TSV 形式の辞書エントリ。従来の CSV も読み込み可能

戻り値: boolean — 展開後のエントリを 1 件以上登録できた場合は true

現行形式: 表層形<TAB>品詞[<TAB>活用型][<TAB>原形]。活用型は省略可能で、活用形を展開させる場合に指定します。第3列が既知の活用型でなければ原形として扱われます。完全な形式はユーザー辞書を参照してください。

例:

typescript
// 単一エントリ
suzume.loadUserDictionary('ChatGPT\tNOUN\n')

// 複数エントリ
suzume.loadUserDictionary(`
ChatGPT	NOUN
スカイツリー	NOUN
DeepL	NOUN
`)

// 活用するエントリ
suzume.loadUserDictionary('検査する\tVERB\tSURU\n')

loadUserDictionaryCount(data)

ソース辞書を読み込み、登録した展開後エントリの件数を返します。

typescript
loadUserDictionaryCount(data: string): number

活用形を展開するため、1 行から複数のエントリが登録されることがあります。0 は読み込み失敗です。lastErrorlastErrorCode を確認するか、loadUserDictionaryOrThrow() を使ってください。読み飛ばした行や展開処理の致命的でない診断は dictionaryWarnings に追加されます。


loadUserDictionaryOrThrow(data)

ソース形式のユーザー辞書を読み込み、エントリを 1 件も登録できなければ C API の詳細を持つ SuzumeError を投げます。

typescript
loadUserDictionaryOrThrow(data: string): void

セットアップ処理やテストで、不正な辞書を即座に失敗させたい場合に使います。


loadBinaryDictionary(data)

コンパイル済みバイナリ辞書(.dic)を実行時に追加します。バイナリ辞書とソース辞書の読み込み内容は累積します。

typescript
loadBinaryDictionary(data: Uint8Array): boolean
パラメータ説明
dataUint8Arrayバイナリ辞書データ(.dic形式)

戻り値: boolean - 成功時 true

例:

typescript
// ファイルから読み込み(Node.js)
import { readFile } from 'fs/promises'
const dictData = new Uint8Array(await readFile('custom.dic'))
suzume.loadBinaryDictionary(dictData)

// URLから読み込み(ブラウザ)
const response = await fetch('/dictionaries/custom.dic')
const browserDictData = new Uint8Array(await response.arrayBuffer())
suzume.loadBinaryDictionary(browserDictData)

バイナリ辞書とソース辞書

バイナリ辞書(.dic)はソース TSV よりも高速に読み込めます。suzume-cli dict compile で TSV 辞書をコンパイルできます。


loadBinaryDictionaryOrThrow(data)

コンパイル済みバイナリ辞書を読み込み、失敗時に C API 由来の詳細を含むエラーを投げます。

typescript
loadBinaryDictionaryOrThrow(data: Uint8Array): void

clearUserDictionaries()

呼び出し元が読み込んだ辞書と、その読み込み時に記録された警告を削除します。自動読み込みされた同梱ユーザー辞書があれば、その辞書は残ります。

typescript
clearUserDictionaries(): void

hasCoreDictionary

同梱 L2 コア辞書が読み込まれているかを返します。

typescript
get hasCoreDictionary(): boolean

skipCoreDictionary: true で作成した場合や、コア辞書の自動読み込みに失敗した場合は false です。


version

Suzume のバージョン文字列を取得します。

typescript
get version(): string

例:

typescript
console.log(suzume.version) // "0.9.9"

このゲッターは解析ハンドルを必要とせず、destroy() 後も利用できます。


version(options?)

解析ハンドルを作成せずにバージョンを返します。

typescript
import { version } from '@libraz/suzume'

const current = await version()
console.log(current) // "0.9.9"
typescript
function version(options?: {
  wasmPath?: string
  freshWasmModule?: boolean
}): Promise<string>

WASM ランタイムを作成または取得するため、この関数は非同期です。


lastError

現在のスレッドにおける最後のC APIエラーを返します。直前のC API呼び出しが成功していれば空文字列です。

typescript
get lastError(): string

false または 0 を返したメソッドの直後に読み取ってください。後続の C API 呼び出しで内容が置き換わる場合があります。


lastErrorCode

最後に失敗した C ABI 呼び出しの安定したエラーカテゴリを返します。

typescript
get lastErrorCode(): ErrorCode

dictionaryWarnings

この解析器に記録された、処理を中断しない診断情報を返します。

typescript
get dictionaryWarnings(): string[]

配列には、作成時の辞書読み込み診断、任意のスコアラー設定診断、読み飛ばした行や展開後の重複など、読み込みに成功したソース辞書の警告が入ります。clearUserDictionaries() は呼び出し元が読み込んだソース辞書の警告を削除しますが、作成時の診断は残します。致命的な読み込み失敗は、メソッドの戻り値または例外と、lastError / lastErrorCode で確認します。


wasmMemoryBytes()

このランタイムが現在確保している WebAssembly 線形メモリのサイズをバイト単位で返します。

typescript
wasmMemoryBytes(): number

共有ランタイム上のインスタンスは、同じ線形メモリのサイズを返します。


destroy()

この解析ハンドルと関連するメモリを解放します。共有 WASM ランタイムは、ほかのインスタンスや今後作成するインスタンスのためにキャッシュへ残ります。

typescript
destroy(): void

FinalizationRegistry による自動クリーンアップ

Suzume は FinalizationRegistry コールバックを登録しているため、インスタンスがガベージコレクションされるとリソースは自動的に解放されます。ただし、destroy() を明示的に呼び出して即座にクリーンアップすることを推奨します。特に Node.js では GC のタイミングが不定で、WASM メモリは GC のヒープ使用量に反映されず、メモリ逼迫と判断されにくいためです。

例:

typescript
const suzume = await Suzume.create()
// ... suzume を使用 ...
suzume.destroy() // 即座にリソースを解放

Morpheme インターフェース

単一のトークン(言語単位)を表します。

typescript
interface Morpheme {
  surface: string      // 表層形(テキスト中の表記)
  pos: string          // 品詞(英語)
  baseForm: string     // 基本形/辞書形
  posJa: string        // 品詞(日本語)
  conjType: string | null  // 活用型
  conjForm: string | null  // 活用形
  extendedPos: string  // 安定した拡張品詞コード(例: "VERB_連用")
  start: number        // 正規化後テキスト内の開始位置(Unicode コードポイント単位)
  end: number          // 正規化後テキスト内の終了位置(Unicode コードポイント単位)
  startUtf16: number   // JavaScript UTF-16 単位の開始位置
  endUtf16: number     // JavaScript UTF-16 単位の終了位置
  isUserDict: boolean
  isFormalNoun: boolean
  isLowInfo: boolean
  isUnknown: boolean
  isFromDictionary: boolean
  score: number
}

プロパティ

プロパティ説明
surfacestringテキスト中の表層形"食べ"
posstring品詞(英語)"VERB"
baseFormstring辞書形/基本形"食べる"
posJastring品詞(日本語)"動詞"
conjTypestring | null活用型(動詞/形容詞)"一段"
conjFormstring | null活用形"連用形"
extendedPosstring安定した拡張品詞コード"VERB_連用"
startnumber正規化後テキスト内の開始位置(Unicode コードポイント単位)0
endnumber正規化後テキスト内の終了位置(Unicode コードポイント単位)2
startUtf16number正規化後テキスト内の開始位置(JavaScript UTF-16 単位)0
endUtf16number正規化後テキスト内の終了位置(JavaScript UTF-16 単位)2
isUserDictbooleanユーザー辞書に一致した場合 truefalse
isFormalNounbooleanこと、もの等の形式名詞なら truefalse
isLowInfobooleanタグ生成で低情報語として扱われる場合 truefalse
isUnknownboolean未知語候補として生成された場合 truefalse
isFromDictionarybooleanいずれかの辞書に一致した場合 truetrue
scorenumber解析器が使う候補スコア/コスト12.5

品詞一覧(pos)

posposJa説明
NOUN名詞名詞
VERB動詞動詞
ADJ形容詞形容詞
ADV副詞副詞
PARTICLE助詞助詞
AUX助動詞助動詞
PRON代名詞代名詞
DET連体詞連体詞
CONJ接続詞接続詞
INTJ感動詞感動詞
PREFIX接頭辞接頭辞
SUFFIX接尾辞接尾辞
SYMBOL記号記号
OTHERその他その他/不明

拡張品詞一覧(extendedPos)

extendedPos プロパティは基本の pos タグを超えた詳細なサブカテゴリを提供します。活用形の区別、助詞の役割、助動詞の機能、名詞のサブタイプなどを識別する場合に有用です。

動詞の活用形:

説明
VERB_終止終止形食べる, 書く
VERB_連用連用形食べ, 書き
VERB_未然未然形食べ-, 書か-
VERB_音便音便形書い-, 泳い-
VERB_て形て形食べて, 書いて
VERB_仮定仮定形食べれば, 書けば
VERB_仮定縮約ばが融合した口語の仮定形縮約行きゃ, 食べりゃ, すりゃ
VERB_命令命令形食べろ, 書け
VERB_連体連体形(現代語では終止形と同形)
VERB_た形た形食べた, 書いた
VERB_たら形たら形食べたら, 書いたら

形容詞の活用形:

説明
ADJ_終止終止形美しい, 高い
ADJ_連用連用形(く)美しく, 高く
ADJ_語幹語幹(ガル接続)美し-, 高-
ADJ_かっかっ形美しかっ-, 高かっ-
ADJ_け形け形(仮定)美しけれ-
ADJ_未然未然形美しくな-
ADJ_NAナ形容詞語幹静か, 綺麗

助動詞:

説明
AUX_過去過去た, だ
AUX_丁寧丁寧ます, まし, ませ
AUX_否定否定ない, なかっ
AUX_否定古否定(古語)ぬ, ん
AUX_打消推量打消推量まい
AUX_文語断定文語の断定なり
AUX_文語過去文語の過去けり
AUX_文語断定連体文語の断定・連体たる
AUX_文語完了文語の完了つ, ぬ
AUX_文語過去キ文語の過去「き」とその活用形き, し, しか
AUX_文語当為文語の当為べし
AUX_不可能不可能かねる
AUX_授受授受あげる, くれる, もらう
AUX_願望願望たい, たかっ
AUX_意志意志/推量う, よう
AUX_受身受身れる, られる
AUX_使役使役せる, させる
AUX_可能可能れる, られる
AUX_継続継続いる, い, おる
AUX_完了完了しまう, ちゃう
AUX_準備準備おく, とく
AUX_試行試行みる
AUX_進行進行方向いく
AUX_接近接近くる
AUX_開始開始はじめる
AUX_様態様態そう
AUX_推定推定らしい
AUX_みたい推定みたい
AUX_断定断定だ, で, な, なら
AUX_丁寧断定丁寧断定です, でし
AUX_尊敬尊敬れる, られる
AUX_丁重丁重ござる
AUX_過度過度すぎる
AUX_ガルガル接続がる
AUX_よう様態・比況よう
AUX_KURUWA_POLITE丁寧な補助表現くるわ

助詞:

説明
PART_格格助詞が, を, に, で, へ, と, から, まで, より
PART_係係助詞は, も
PART_終終助詞ね, よ, わ, な, か
PART_接続接続助詞て, で, ば, ながら, たり, けど
PART_引用引用助詞と(引用)
PART_副副助詞ばかり, だけ, ほど, しか, など
PART_準体準体助詞
PART_係結係結びこそ, さえ, すら

名詞:

説明
NOUN普通名詞東京, 天気
NOUN_形式形式名詞こと, もの, ところ, わけ
NOUN_転成連用形転成名詞読み, 書き
NOUN_固有固有名詞
NOUN_姓固有名詞(姓)田中, 鈴木
NOUN_名固有名詞(名)太郎
NOUN_数数詞一, 100

その他:

説明
PRON代名詞
PRON_疑問疑問詞(何, 誰, どこ)
ADV副詞
ADV_引用引用副詞(そう, こう)
CONJ接続詞
DET連体詞
PREFIX接頭辞
SUFFIX接尾辞
SUFFIX_直後直後を表す接尾辞
SUFFIX_傾向傾向を表す接尾辞
DET_引用引用を伴う連体詞
SYMBOL記号
INTJ感動詞
OTHERその他
UNKNOWN不明

エラーハンドリング

ネイティブ側の失敗は Error を継承した SuzumeError で表され、安定した ErrorCode を持ちます。

typescript
enum ErrorCode {
  Success = 0,
  InvalidUtf8 = 1,
  DictionaryLoadFailed = 2,
  FileNotFound = 3,
  Parse = 4,
  OutOfMemory = 5,
  InvalidInput = 6,
  Internal = 7,
}

class SuzumeError extends Error {
  readonly code: ErrorCode
  constructor(message: string, code?: ErrorCode)
}
typescript
import { ErrorCode, Suzume, SuzumeError } from '@libraz/suzume'

let suzume: Suzume | undefined
try {
  suzume = await Suzume.create()
  suzume.analyze('\uD800') // 対になっていない UTF-16 サロゲート
} catch (error) {
  if (error instanceof SuzumeError) {
    console.error(ErrorCode[error.code], error.message)
  }
} finally {
  suzume?.destroy()
}

Suzume.create()analyze()analyzeWithNormalizedText()generateTags()、辞書読み込みの OrThrow メソッド、モード変更、clearUserDictionaries() は、ネイティブ側で失敗すると例外を投げます。例外を投げない辞書メソッドは false または 0 を返します。詳細は lastErrorlastErrorCode で確認できます。

WebAssembly のメモリ不足

メモリ確保に失敗すると、通常の OutOfMemory を返さず WASM ランタイムが停止します。回復可能な SuzumeError の経路には入らず、停止したランタイムは再利用できません。デフォルトでは複数のインスタンスがランタイムを共有するため、同じランタイム上のほかのハンドルも使えなくなります。長い文書は分割して処理してください。障害をランタイム単位で分離する必要がある場合は freshWasmModule: true を使います。


メモリ管理

Suzume は JavaScript ヒープ外にメモリを確保する WebAssembly を使用します。FinalizationRegistry により GC 時にクリーンアップされますが、明示的な destroy() を強く推奨します。特に Node.js では GC のタイミングが不定で、WASM メモリは GC のヒープ使用量に反映されず、メモリ逼迫と判断されにくいためです。

typescript
// 良い例:使用後にクリーンアップ
const suzume = await Suzume.create()
try {
  const result = suzume.analyze(text)
  // 結果を処理...
} finally {
  suzume.destroy()
}

// 長時間実行アプリ:インスタンスを再利用
class MyApp {
  private suzume: Suzume | null = null

  async init() {
    this.suzume = await Suzume.create()
  }

  analyze(text: string) {
    return this.suzume?.analyze(text) ?? []
  }

  dispose() {
    this.suzume?.destroy()
    this.suzume = null
  }
}

Node.js での注意

Node.js では WASM メモリは V8 のヒープサイズに追跡されません。destroy() を呼ばずに多くのハンドルを作成すると、GC からは圧力が見えず、メモリ使用量が増える場合があります。サーバーサイドコードでは destroy() を明示的に呼び出してください。