Repository navigation
stitchkit v0.108.0
·
129 commits
to master
since this release
⚠️ Breaking changes
Who must act: code with an exhaustive switch or Record over TelegramSendFailureReason or
TelegramSendFailure['evidence']; builds whose entry imports a stitchkit installation other
than the one their native packaging plugin came from.
stitchkit/telegram— a request that never left is its own send outcome.
TelegramSendFailureReasongainsnot-dispatched(retryable, recipient reachable) and
TelegramSendFailure.evidencegainstransport:classifyTelegramSendFailurereturns them for a
TelegramNotDispatchedErroranywhere in the cause chain, so a broadcast retries such a send as
transientand the operator channel sends it again, where both used to give it up as unknown.
// before: const code: Record<TelegramSendFailureReason, string> = { …, unknown: 'E_UNKNOWN' }
→// after: const code: Record<TelegramSendFailureReason, string> = { …, 'not-dispatched': 'E_NOT_SENT', unknown: 'E_UNKNOWN' }
Who must act: exhaustive code over the reasons or the evidence. See
migration. → ADR 0253
Affects:stitchkit/telegramTelegramSendFailureReason, TelegramSendFailure(evidence), TELEGRAM_SEND_FAILURE_REASONS, classifyTelegramSendFailure(reason)stitchkit/files/packaging— a packaging plugin fails a build that carries another
installation's loader. The plugin packages only the default Darwin loader of thestitchkitit
was created from; an entry that imports another installation (another version, or the same
version under another path, as when a build tool brings its own copy) used to build, ship that
installation's default loader and refuse the addon on macOS at run time. The build now fails with
an error naming both versions and roots.
// before: Bun.build({ plugins: [toolCopy.createNativePackaging(…).plugin] }) // entry imports another stitchkit
→// after: Bun.build({ plugins: [entryCopy.createNativePackaging(…).plugin] })
Who must act: builds that take the plugin from astitchkitthe entry does not import. See
migration. → ADR 0254
Affects:stitchkit/files/packagingcreateNativePackaging(plugin)
Added
stitchkit/telegram—createTelegramBotTransport(), afetchfor the Bot API senders that
connects before it writes: a failure before the first byte isTelegramNotDispatchedError
(stage:lookup,connect,request), any later one stays unknown. Addresses race in the
resolver's order (Happy Eyeballs); the lookup, the connection rounds, the answer's time and its size are bounded.
The senders'fetchoption is now typedTelegramFetch((url, init) => Promise<Response>), which
the globalfetchstill satisfies. → ADR 0253stitchkit—parseNDJSONandparseSSEread any byte source: aResponse, a
ReadableStream<Uint8Array>(a Bun child'sstdout) or anAsyncIterable<Uint8Array>(a Node
child'sstdout), withsignalcancelling the source.createNDJSONDecoderdrives the same
bounded reader bypush(chunk)/end()for a socket'sdatacallback. A line past
maxLineBytesthrowsStreamLineLimitError(limitBytes,lineBytes) at the chunk that crossed
the limit, so memory stays bounded; a source ended inside a line underfinalLine: 'require-newline'throwsStreamTruncatedLineError. They extend theRangeErrorandSyntaxError
thrown before, soinstanceofstill holds; theirnameis now the class name and their message
ends with the bytes seen. A decoder stops at
its first error, and an abort rejects with the signal's reason even whenonParseErroris set.stitchkit/files/packaging—inspectNativeArtifact(bytes)classifies a built artifact as
packaged,unpackagedorno-loaderby a marker every generated loader now carries
(module.exports.stitchkitNativeLoader), in latin1 and UTF-16LE. It replaces the documented search
forSTITCHKIT_NATIVE_NOT_PACKAGED, which every bundle with a lock carries as an error code and so
refused correct builds. → ADR 0254stitchkit upgrade— every breaking item from 0.104.0 carries an**Affects:**line naming its
entrypoints and exports (orbehaviour), andrelease:checkrefuses a breaking item without it.
The CLI reads the project's imports (--cwd, default.) and gives each item a verdict:
affects this projectwithpath:line,not used here,behavioural — check by handwith the
importing files, ornot declared — check by handfor older items;--jsonprints the verdicts.stitchkit/testing—createManualClock(): manual time for schedules, retries and deadlines. Due
timers fire in deadline order with real event-loop yields between them, soadvance(10_000)does
not skip a retry armed at the fifth second;holdkeeps time still while real work of unknown
length runs and fails naming it pastholdLimitMs;untilmoves deadline to deadline; one move
runs at a time. It is the
clock ofcreateManagedSchedule, a durable sleep, a revision signal and bounded admission.
Fixed
stitchkit/server,stitchkit/process,stitchkit/files— loading these leaves no longer calls
a Node API: process identity built its command runner withpromisify(execFile)at module scope,
so a browser bundle that reached the server leaf for an error class (wherenode:utilis an empty
module) threwpromisify is not a functionwhile loading, although nothing called it.