명세 · 데이터
리소스 형식
리소스 구성
Full POS lexicon.bin은 넓은 표제어·세부 품사를 제공합니다. Enriched TSV는 검증된 용언 alternation·derivation을 제공합니다. Compact KFC는 smart plan이 원문 token 내부의 같은 품사 구성 요소 span과 인접 token 구조를 검증하는 index입니다.
npm 패키지는 enriched와 compact를 포함하지만 full POS는 포함하지 않습니다.
npm asset export
@kfind/kfind/assets는 componentResourceFileUrl과 enrichedPredicatesFileUrl을 같은 패키지 안의 URL로 제공합니다. 복사 기반 배포 도구에서는 raw subpath @kfind/kfind/assets/morphology-component-compact.kfc와 @kfind/kfind/assets/predicates.enriched.tsv도 사용할 수 있습니다.
Resolver는 파일을 다운로드하거나 route를 만들지 않습니다. 애플리케이션이 필요한 리소스만 서빙하고, 읽은 KFC byte 배열과 TSV 텍스트를 Kfind.withResources에 전달합니다.
SPA bundling
Vite처럼 new URL(relative, import.meta.url)을 지원하는 bundler는 resolver가 가리키는 파일을 SPA 배포물에 content-hashed asset으로 출력합니다. 기본 URL은 JavaScript와 origin이 같으므로 별도 CORS가 필요하지 않습니다.
Component KFC는 35.4 MiB이므로 smart 구조 판정이 필요한 화면에서 지연 fetch할 수 있습니다. 한 번 만든 engine은 여러 matcher에서 리소스를 재사용합니다.
import { Kfind } from '@kfind/kfind';
import {
componentResourceFileUrl,
enrichedPredicatesFileUrl,
} from '@kfind/kfind/assets';
const [componentResponse, enrichedResponse] = await Promise.all([
fetch(componentResourceFileUrl),
fetch(enrichedPredicatesFileUrl),
]);
if (!componentResponse.ok || !enrichedResponse.ok) {
throw new Error('failed to load kfind resources');
}
const engine = Kfind.withResources({
component: new Uint8Array(await componentResponse.arrayBuffer()),
enrichedPredicates: await enrichedResponse.text(),
});
Node.js server
Node.js에서 resolver는 설치된 패키지 내부의 file: URL을 반환합니다. 서버는 패키지를 별도 asset 디렉터리에 복사하지 않고 이 URL을 createReadStream에 전달할 수 있습니다.
고정 route 예제는 배포할 때마다 revalidation하도록 no-cache를 사용합니다. Route에 패키지 버전이나 content hash를 포함한 경우에만 장기 immutable cache로 바꿉니다.
import { createReadStream } from 'node:fs';
import { createServer } from 'node:http';
import { componentResourceFileUrl } from '@kfind/kfind/assets';
createServer((request, response) => {
if (
request.method !== 'GET' ||
request.url !== '/assets/morphology-component-compact.kfc'
) {
response.writeHead(404).end();
return;
}
response.writeHead(200, {
'Cache-Control': 'no-cache',
'Content-Type': 'application/octet-stream',
'X-Content-Type-Options': 'nosniff',
});
const stream = createReadStream(componentResourceFileUrl);
stream.on('error', (error) => response.destroy(error));
stream.pipe(response);
}).listen(3000);
HTTP 전달
KFC는 application/octet-stream, TSV는 text/tab-separated-values; charset=utf-8로 응답하고 X-Content-Type-Options: nosniff를 설정합니다. 별도 origin에서는 모든 origin을 허용하지 말고 실제 애플리케이션 origin을 Access-Control-Allow-Origin에 명시합니다.
Content hash나 패키지 버전이 URL에 들어간 파일은 public, max-age=31536000, immutable로 캐시할 수 있습니다. 고정 URL은 no-cache 또는 짧은 수명과 revalidation을 사용하고, 애플리케이션 cache key에도 리소스 revision을 포함합니다.
schema
Manifest는 source URL·checksum, 생성 도구와 output digest를 기록합니다. Binary header에는 schema, 패키지 버전과 source identity가 포함됩니다.
TSV와 TOML은 build 단계에서 NFC, tag, rule ID와 중복 충돌을 검증합니다.
호환성
구성 요소 패키지 버전은 engine 버전과 정확히 같아야 합니다. Schema와 source digest가 다르면 불러오지 않습니다.
패키지를 업그레이드할 때 JavaScript·WASM·리소스를 한 배포에서 교체합니다. 이전 cache의 KFC를 새 engine에 전달해 실패하면 boundary를 완화해 계속 실행하지 않습니다. Full과 compact projection은 구조 cost를 제외한 exact·common-prefix 일치, POS와 span이 같아야 합니다.