@arki/string
For @arki/[email protected] · source AGENTS.md
AGENTS.md = laws, docs/agent-guide.md = tasks, llms.txt = map.
@arki/string
Grapheme-aware string functions with canonical encoding failures, one subpath per concern, and an immutable fluent wrapper. Read docs/agent-guide.md for tasks. When a doc and the code disagree, src/index.ts wins.
Laws
- The sole runtime dependency is
@arki/failure, authorized for canonical encoding failures. - Positions and lengths count graphemes, not UTF-16 units. A function that cuts, pads, slices or measures must never split an emoji, a flag or a combining sequence.
- Literal search and replace match only on grapheme boundaries, and replacement strings are literal.
$&stays$&. - Results never depend on the machine locale. A locale only applies when the caller passes
{ locale }. - Use ECMAScript 2022 plus Unicode property escapes only. No
Buffer,atob,btoa,TextEncoder,node:imports or ES2023 array-copy methods. A lint rule andsrc/runtime.test.tsfail the build if that changes. Hermes is the floor. Intl.Segmenteris the one feature check. The fallback scanner insrc/internal/must match it.src/internal/graphemes.fuzz.test.tscompares both on seeded random strings.- Counting functions (
words,sentences,paragraphs, readability, keywords) share one definition of a word and a sentence insrc/segment.ts. Never write a second tokenizer. - Base64 decoding is strict. Whitespace, mixed alphabets, bad padding and nonzero unused bits return
InvalidBase64. Invalid UTF-8 returnsInvalidUtf8.tryFromBase64aliasesfromBase64; it never returnsnull. - Encoding failures are canonical
@arki/failurevalues. Other static misuse remains aStringErrorwith a stable code, and each code inSTRING_ERROR_CODEShas JSDoc with@fixand@verify. Wrong runtime types are not checked and have no code. - Any path that was quadratic stays guarded by
src/performance.test.ts, which compares a large input with a small one so it fails on any machine. - Never write benchmark numbers by hand.
bun run bench --write-readmewrites them from an idle machine.
Changing this package
- Pick the concern file (
src/case.ts,src/format.ts,src/slug.ts, and so on). One concern per file, one subpath per concern. - Add the function, its test next to it, and its method in
src/fluent.tsif it returns a string. - A new subpath needs an
exportskey inpackage.json, a top JSDoc line on the entry module, and a run ofbun ../../tooling/library/src/llms.ts --write. - Test the Unicode edge, not only ASCII: a ZWJ emoji, a flag, a decomposed accent.
- Update
examples/describe-post.tsonly with its test. The README mirrors its region, so runarki-doc-examples --writeafter an edit. - Add a changeset in
.changeset/. Documentation-only changes usepatchand the lineno demo impact: documentation and doc-example changes only, runtime behaviour unchanged.
Verify
bun run build
bun run typecheck
bun run test
bun run test:docs
bun run test:runtimes
bun ../../tooling/library/src/error-index.ts
bun ../../tooling/library/src/llms.ts --check