v0.1.5
Namespace the container token by the package that owns it
Upstream namespaces a satellite's binding by its own package —
lucid.db, auth.manager, mail.manager, limiter.manager,
cache.manager, queue.manager, drive.manager — and leaves the
namespace off only where the package name IS the service (i18n,
redis, vite). Core's own bindings stay bare. Ours were all bare,
which is the vocabulary of no package in particular and one collision
away from a problem.
The bare token stays bound beside the new one, and typed beside it: it is
what every existing container.make(...) asks for, in this repo and in
applications this repo does not see, and a token is not worth breaking an
application over.
Both names are verified live rather than assumed — a declare module
naming a specifier that does not resolve is silently inert, so renaming
the member has to break the compile, and the provider has to bind both at
runtime.
Turn on noUncheckedIndexedAccess
It was not missing here — it was explicitly false, in sixteen of the
seventeen tsconfigs. eon alone had it on, which is why nobody had seen
what it finds.
It stays a named deviation from upstream: @adonisjs/tsconfig sets
strictNullChecks and noImplicitAny but not this one. We keep it because
turning it on is what caught an as asserting a possibly-absent regex
group was a known value — the exact shape the flag exists to find. Doing
better than upstream is kept and written down, not reverted to parity.
Every site is restated rather than silenced: no !, no cast, no ?? 0
standing in for a branch that cannot happen. A reversed copy read by
value where an index walked a callback list backwards, the winner of a
scan kept as the value it found rather than its position, destructuring
where a length check was doing the proving, and an explicit break where a
loop condition already bounds the read.
Say what container.make() returns for the tokens this package binds
ream declares ContainerBindings open on purpose: it registers its own
entries and expects each package to contribute the ones it owns — its
comment on the interface names auth (warden), logger (spectrum) and db
(atlas) as exactly this. None of them did, and every other package that
binds a string token was in the same state, so container.make('cache'),
make('mail'), make('hash') and the rest all answered unknown and
every call site had to assert a type it could not prove.
Loaded from the barrel AND from the provider, the second of which is where
AdonisJS puts its own (providers/redis_provider.ts carries the
declare module for redis, database_provider.ts for lucid.db).
Verified live rather than assumed: a declare module naming a specifier
that does not resolve is silently inert, so renaming the member has to
break the compile. It does.
Release 0.1.5
Stop treating a dead socket as a working one
Seven defects, all on the half of a connection's life no test reached: the
half where the server goes away rather than never answers.
A health check issued its command whatever the connection's state. ioredis
does not fail a command on a connection that is not ready, it QUEUES it —
measured at 73 seconds before it gave up with the defaults, and never with
maxRetriesPerRequest: null, which is what a queue needs. A readiness probe
that hangs for a minute is the outage it exists to report. Both checks now
take Adonis' guard: wait on a connection still dialling, never on one that
already recorded an error.
The memory check defaulted both thresholds to Infinity, so one added and
left unconfigured could never fail — which reads as a monitored server.
Adonis' 100 MB / 120 MB instead.
quit() sent QUIT whatever the socket's status. On an ended one ioredis
rejects every command, and that rejection travelled through Promise.all and
out of the provider's shutdown, so one socket that had died on its own
aborted the shutdown of every other. On a wait one it dialled a server, on
a shutdown path, for the sole purpose of saying goodbye. Both guards are
Adonis'.
The manager cached a connection whose socket had ended and handed it back
for the rest of the process: every command rejected, activeConnections still
reported it open, and nothing ever opened a live one. The subscriber socket
had the same defect one level down — the next subscribe reused an ended
socket, so the application stopped receiving with the failure reported as if
the channel were at fault.
A pattern handler took (message, channel); Adonis passes (channel, message).
Both are strings, so the swap was silent. BREAKING for psubscribe callers.
QuasarLogger asked for pino's error(payload, message), which nothing in this
framework implements, and the provider passed no logger at all — so every
connection failure went to the console. It now takes ream's signature and
the provider resolves one from the container.
Changes since v0.1.4.