Skip to documentation

reference

Compatibility Contract — @stackline/update-section

Project compatibility notes for @stackline/update-section 1.0.4. Review behavior, requirements and limitations.

Versioned project notes for @stackline/update-section 1.0.4. Original attribution is retained in the linked repository.

Compatibility Contract

This contract distinguishes behavior retained from [email protected] from narrow correctness changes made by @stackline/update-section.

Public surface

  • The CommonJS root export is a synchronous callable function.
  • .parse is an enumerable property of that function.
  • ESM exposes the same callable as the default export and parse as a named export.
  • The historical update-section.js deep entry and package metadata entry remain reachable.

Matching and replacement

updateSection(content, section, matchesStart, matchesEnd, top):

  1. Splits truthy string content on the literal LF character.
  2. Calls matchesStart(line) until the first truthy result.
  3. After a start, calls matchesEnd(line) until the first truthy result.
  4. Replaces the start and end lines inclusively.
  5. Replaces from the start through the final line if no later end matches.
  6. Appends content + '\n\n' + section if no start matches.
  7. Uses section + '\n\n' + content instead when top is truthy.

Only the first valid pair is replaced. Later pairs remain untouched. A line that satisfies both matchers is selected as the start; the end matcher is not called for that line. End markers observed before a start are ignored.

Matchers receive exactly one argument: the current line value. Results use JavaScript truthiness. Calls are synchronous, stop once the selected boundary is known, and preserve the thrown value and stack when a matcher throws.

Parse metadata

parse(lines, matchesStart, matchesEnd) returns four fields:

  • hasStart: whether a start matcher succeeded;
  • hasEnd: whether an end matcher succeeded after that start;
  • startIdx: inclusive start index, or the absent-marker sentinel;
  • endIdx: inclusive end index; when a start exists without an end, this is the final line index.

The inclusive end and truthful hasEnd behavior intentionally differ from 0.3.3, which mixed inclusive and exclusive indexes and forced hasEnd to true. Ignoring an end before the start also prevents crossed indexes and insertion without removal.

Strings and line endings

  • Splitting and joining use \n, not a universal-newline normalizer.
  • For CRLF input, matchers see lines ending in \r; untouched lines retain those characters.
  • Inserted section lines retain their own characters, so callers can create mixed line endings just as with 0.3.3.
  • Missing-start append/prepend separators are exactly two LF characters.
  • Existing trailing LF characters are not collapsed; appending to content that already ends with LF therefore produces three consecutive LF characters before the section.

Falsey and malformed values

  • A falsey content returns section immediately, without coercion or matcher invocation.
  • Truthy content without a callable start matcher throws synchronously.
  • A non-string truthy content fails at .split.
  • A non-string section can be coerced by append/prepend, but fails at .split when replacement is attempted. This historical timing is preserved.
  • Matcher exceptions propagate unchanged.

Inputs and callbacks are trusted application values. The package neither evaluates text nor performs file I/O.

Scale

Scanning is linear in the number of visited lines. The maintained insertion path must handle large generated sections without the Function.apply argument-count failure present in 0.3.3.

Out of scope

  • Parsing nested or overlapping section grammars.
  • Selecting or replacing every matching section in one call.
  • Automatically detecting marker strings or line-ending style.
  • Asynchronous callbacks, streams, file reads, or file writes.
  • Treating malformed marker order as a new grammar.

Package reference