Variables
Section titled “Variables”EPISODIC_PREFIX_LENGTH
Section titled “EPISODIC_PREFIX_LENGTH”const EPISODIC_PREFIX_LENGTH: 9 = 9;The YYYYMMDD- prefix an episodic filename carries. Time is part of an episodic entry’s
identity and it never receives a correction in place, so the date belongs in the name;
every other type is timeless and correctable, so it gets a bare slug.
SLUG_FALLBACK
Section titled “SLUG_FALLBACK”const SLUG_FALLBACK: "untitled" = "untitled";The stem used when a title reduces to nothing sluggable, such as an all-punctuation or
non-Latin title. A placeholder beats an empty filename, and memhtml doctor can find
these by name.
SLUG_MAX_LENGTH
Section titled “SLUG_MAX_LENGTH”const SLUG_MAX_LENGTH: 80 = 80;Maximum slug length in characters, before any collision suffix.
Functions
Section titled “Functions”datePrefix()
Section titled “datePrefix()”function datePrefix(at): string;Format an instant as the YYYYMMDD stamp of an episodic filename, in UTC.
Parameters
Section titled “Parameters”Date
Returns
Section titled “Returns”string
filenameFor()
Section titled “filenameFor()”function filenameFor(input): string;The filename for a memory: 20260802-slug.html for episodic, slug.html otherwise.
The date prefix sits outside the slug’s length budget, because it is identity, not title.
Parameters
Section titled “Parameters”Date
episodic
Section titled “episodic”boolean
string
Returns
Section titled “Returns”string
hasDatePrefix()
Section titled “hasDatePrefix()”function hasDatePrefix(filename): boolean;True when a filename carries the YYYYMMDD- episodic prefix.
Parameters
Section titled “Parameters”filename
Section titled “filename”string
Returns
Section titled “Returns”boolean
isSlug()
Section titled “isSlug()”function isSlug(value): boolean;True when a string is already a valid slug, the fixed point of slugify.
Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”boolean
slugify()
Section titled “slugify()”function slugify(title): string;Kebab-case a title into [a-z0-9-], at most SLUG_MAX_LENGTH characters.
Diacritics are folded to their base letters (déployé ⇒ deploye) rather than dropped,
so a title stays recognizable. Runs of separators collapse to one hyphen and the result
carries no leading or trailing hyphen, which makes the function idempotent: a slug fed
back in comes out unchanged.
Truncation cuts at SLUG_MAX_LENGTH and then trims any hyphen the cut exposed, so a truncated slug is still a valid slug rather than one ending mid-separator.
Parameters
Section titled “Parameters”string
Returns
Section titled “Returns”string
withCollisionOrdinal()
Section titled “withCollisionOrdinal()”function withCollisionOrdinal(slug, ordinal): string;Append a collision suffix. ordinal is a 1-based ordinal for display in the filename;
ordinal 1 is the unsuffixed slug, 2 becomes -2, and so on, matching the -2/-3
convention. The suffix is added inside the length budget, so a maximum-length slug is
shortened rather than overflowed.
The result never equals the input, at any slug length. That is what makes the store’s
collision loop (packages/store/src/store.ts, pathFor) terminate rather than re-propose
the name that collided. It is not free near the length cap: for a slug whose own tail IS the
suffix, cutting to make room and appending the suffix can rebuild the slug — and because the
cut also trims any hyphen it exposes, the rebuild can recur at MORE than one cut width. The
stem is therefore re-cut from its own post-trim length until appending the suffix no longer
reproduces the input; each re-cut strictly shortens the stem, so the loop terminates and the
result stays inside the budget.
Parameters
Section titled “Parameters”string
ordinal
Section titled “ordinal”number
Returns
Section titled “Returns”string