Name files for what they export, and move the session files into session/
Mirror / push (push) Has been cancelled
Test / lint (pull_request) Successful in 21s
Test / test (18) (pull_request) Successful in 29s
Test / test (20) (pull_request) Successful in 29s
Test / test (22) (pull_request) Successful in 30s
Test / test (24) (pull_request) Successful in 29s
Test / test (26) (pull_request) Successful in 34s

This commit is contained in:
2026-09-30 20:33:13 +02:00
parent 92479d697d
commit bf1bddba3b
58 changed files with 242 additions and 230 deletions
+26 -26
View File
@@ -38,58 +38,58 @@ These are not preferences. Breaking one is a defect.
``` ```
src/ src/
index.ts Public surface. Named exports only, no default export; assembles `defs`. index.ts Public surface. Named exports only, no default export; assembles `defs`.
link-life.ts LinkLife: whether the link lives, and where a request waits for the next one log.ts SmppLog, silentLog — the default, and guardedLog(): a logger that cannot throw
log.ts SmppLog, the logger contract, and silentLog — the default message.ts Message bodies: encodeBody/decodeMessage under a data_coding, splitting, bit counting, smppDate/smppTime
message.ts Encoding detection, splitting, bit counting, SMPP date formatting
options.ts SessionOptions, ReconnectOptions, their checks, and `defaults`: every default and internal cap options.ts SessionOptions, ReconnectOptions, their checks, and `defaults`: every default and internal cap
reconnect-loop.ts ReconnectLoop: backoff, retry timer, stopped-ness
result.ts Result<T>, and an untyped value as error material: errorFrom(), namedValue(), quoted() result.ts Result<T>, and an untyped value as error material: errorFrom(), namedValue(), quoted()
session.ts Session: the socket's life, dispatch, events, and the collaborators in session/ unanswered-error.ts
sms.ts The live handle emitted as the 'sms' event (sendResp/sendDlr)
unanswered-error.ts UnansweredError: it went out and no answer came back
codec/ Bytes <-> PduObject codec/ Bytes <-> PduObject
commands.ts The 33 commands, their ids and ordered parameter lists commands.ts The 33 commands, their ids and ordered parameter lists
constants.ts consts + constsById, and the version that allows optional parameters constants.ts consts + constsById, optionalParamsMinVersion, and esm_class's readers: hasUdh(), messageTypeOf()
encodings.ts GSM 03.38, LATIN1, UCS2, detection, data_coding resolution encodings.ts GSM 03.38, LATIN1, UCS2, detection, data_coding resolution, message class
field-types.ts Wire types: int8/int16/int32/string/cstring/buffer/arrays errors.ts errors + errorsById (ESME_*)
framer.ts PduFramer: a byte stream cut into complete PDUs pdu-framer.ts PduFramer
pdu.ts pduToObj / objToPdu / pduReturn — synchronous, result-returning pdu.ts pduToObj / objToPdu / pduReturn — synchronous, result-returning
refusal.ts A PDU the codec would not read, and the answer SMPP names for it refusal.ts A PDU the codec would not read, and the answer SMPP names for it
retained.ts A PDU copied off the wire so holding it pins nothing else, and what holding it costs retained-pdu.ts A PDU copied off the wire so holding it pins nothing else, and what holding it costs
statuses.ts errors + errorsById (ESME_*)
tlvs.ts TLV definitions, tlvsById, the typed read and input shapes, and reading and writing a TLV stream tlvs.ts TLV definitions, tlvsById, the typed read and input shapes, and reading and writing a TLV stream
types.ts Wire types: int8/int16/int32/string/cstring/buffer/arrays
protocol/ What the fields mean protocol/ What the fields mean
bind.ts Bind directions: which commands bind, what a direction carries, data_sm's stand-in, checkedBind() bind.ts Bind directions: which commands bind, what a direction carries, data_sm's stand-in, checkedBind()
concat.ts How a PDU says it is a segment: its UDH, or the sar_* TLVs concat.ts How a PDU says it is a segment: its UDH, or the sar_* TLVs
dlr.ts Delivery receipts: text and TLV parsing, receipt status codes
message-body.ts Where an inbound body is: short_message, or the message_payload TLV message-body.ts Where an inbound body is: short_message, or the message_payload TLV
message-ids.ts Message ids: the peer's notation, the <base>-<n> a segment gets, which response carries one message-ids.ts Message ids: the peer's notation, the <base>-<n> a segment gets, which response carries one
receipt.ts Delivery receipts: text and TLV parsing, receipt status codes
udh.ts User data header: its length, the concatenation fields of a long SMS and their reference udh.ts User data header: its length, the concatenation fields of a long SMS and their reference
uuid.ts uuidv7() — the ids the library generates for messages uuid.ts uuidv7() — the ids the library generates for messages
messages/ Whole messages across segments and time messages/ Whole messages across segments and time
dlr-merger.ts DlrMerger: per-segment receipts counted into one MessageDlr
expiring-groups.ts ExpiringGroups: the capped, weighed, expiring store DlrMerger, HeldMessages and Reassembler share expiring-groups.ts ExpiringGroups: the capped, weighed, expiring store DlrMerger, HeldMessages and Reassembler share
reassembly.ts Reassembler: capped, expiring multipart groups reassembly.ts Reassembler: capped, expiring multipart groups
receipt-merge.ts DlrMerger: per-segment receipts counted into one MessageDlr
submit.ts submitSms composition and the submitSmParams builder submit.ts submitSms composition and the submitSmParams builder
session/ One socket's collaborators session/ One socket's life, and reconnecting it
held-messages.ts HeldMessages: a message from its `sms` event to its answer, capped and expiring, one MessageHold each held-messages.ts HeldMessages: a message from its `sms` event to its answer, capped and expiring, one MessageHold each
keepalive.ts LinkTimers: the enquire_link heartbeat and the idle timeout idle-waiters.ts IdleWaiters: waiting for a count to fall to zero, and what is left of a budget
incoming-requests.ts IncomingRequests: every request the peer sends — messages, receipts, links, unknown commands
link-life.ts LinkLife: whether the link lives, and where a request waits for the next one
link-timers.ts LinkTimers: the enquire_link heartbeat and the idle timeout
outgoing-requests.ts OutgoingRequests: the window, the pending map and the retry outgoing-requests.ts OutgoingRequests: the window, the pending map and the retry
pdu-transport.ts PduTransport: the socket a session reads complete PDUs off
pending-requests.ts PendingRequests: sequence numbers, correlation, timeout, abort pending-requests.ts PendingRequests: sequence numbers, correlation, timeout, abort
requests-in.ts IncomingRequests: every request the peer sends: messages, receipts, links, unknown commands reconnect-loop.ts ReconnectLoop: backoff, retry timer, stopped-ness
send-window.ts SendWindow: the maxOutstanding semaphore send-window.ts SendWindow: the maxOutstanding semaphore
transport.ts PduTransport: the socket a session reads complete PDUs off session.ts Session: the socket's life, dispatch and events, composing the rest of session/
waiting.ts IdleWaiters: waiting for a count to fall to zero, and what is left of a budget sms.ts The live handle emitted as the 'sms' event (sendResp/sendDlr)
client/client.ts client() -> { err, session } client/client.ts client() -> { err, session }
server/server.ts server() -> { err, server }, server owns the listener + close() server/server.ts server() -> { err, server }, server owns the listener + close()
``` ```
Imports point one way: `codec` ← `protocol` ← `messages` ← `session/` ← `client`/`server`, and the Imports point one way: `codec` ← `protocol` ← `messages` ← `session` ← `client`/`server`. At the
root files sit beside that order. One edge runs against it: `codec/pdu.ts` reads `message.ts`, which root, `result.ts`, `log.ts` and `unanswered-error.ts` sit below `codec`, and `message.ts` and
reads `protocol/udh.ts`, so moving `message.ts` into `protocol/` needs `pdu.ts` off it first. The `options.ts` with `protocol`. One edge runs up: `codec/pdu.ts` imports `encodeBody()` and
ways back up are the `Session` handed to `createSms()`, `HeldMessages` and `IncomingRequests`, which `decodeMessage()` from `message.ts`. The ways back up are the `Session` handed to `createSms()`,
call back into it, and to `OnRequest` and `onConnected` in `options.ts`, all imported as a type `HeldMessages` and `IncomingRequests`, which call back into it, and to `OnRequest` and `onConnected`
only. in `options.ts`, all imported as a type only.
**Parameter order is wire order.** The key order inside `cmds.*.params` is the order the fields are **Parameter order is wire order.** The key order inside `cmds.*.params` is the order the fields are
written to and read from the buffer. Never sort those alphabetically — the alphabetical-ordering written to and read from the buffer. Never sort those alphabetically — the alphabetical-ordering
+5 -6
View File
@@ -295,7 +295,7 @@ rule and an index of the titles below.
a delivery receipt (0x04).** Appendix B makes a receipt's `stat` the message's final status, so a delivery receipt (0x04).** Appendix B makes a receipt's `stat` the message's final status, so
0x04 over `ENROUTE` emits the two disagreeing spellings of finality the reading side above has to 0x04 over `ENROUTE` emits the two disagreeing spellings of finality the reading side above has to
reconcile, and goal 3 has our own senders write the marker 3.4 defines. `sendDlr()` takes the list reconcile, and goal 3 has our own senders write the marker 3.4 defines. `sendDlr()` takes the list
from `transientStates` in `protocol/receipt.ts`, the same one the reader uses, so the two cannot drift. from `transientStates` in `protocol/dlr.ts`, the same one the reader uses, so the two cannot drift.
Rejected: 0x04 for every state, for the sake of a peer that classifies on the marker — the cost Rejected: 0x04 for every state, for the sake of a peer that classifies on the marker — the cost
accepted here is that such a peer stops recognising a transient report as a report at all and hands accepted here is that such a peer stops recognising a transient report as a report at all and hands
its application receipt text as an inbound message, where under 0x04 it would have read the state its application receipt text as an inbound message, where under 0x04 it would have read the state
@@ -796,11 +796,10 @@ rule and an index of the titles below.
dev image has no openssl. dev image has no openssl.
- **`src/` is grouped by layer, and imports point down the layers.** Maintainer's call, 2026-09-30, - **`src/` is grouped by layer, and imports point down the layers.** Maintainer's call, 2026-09-30,
building [plan 3](comprehension-rewrite/plan-3.md): `codec/`, `protocol/`, `messages/`, `session/`, with the Locality rewrite; the [map](../AGENTS.md#architecture) names the order and places each
`client/`, `server/`, with the [map](../AGENTS.md#architecture) naming the direction. Serves goal root file in a layer. Serves goal 8: internals are reshapeable only once a reader can find them,
8's reshapeable internals, which a reader has to find before reshaping: every comprehension panel and every comprehension panel navigated by the map. Rejected: `src/` flat until a module has to
navigated by AGENTS.md's map rather than the flat tree it described. Rejected: `src/` flat until a move for another reason. Valid while the map is what readers navigate by.
module has to move for another reason.
- **`test/` stays flat, and a file there is named for the question it answers rather than for the - **`test/` stays flat, and a file there is named for the question it answers rather than for the
module it covers.** Architecture review, 2026-09-08, at 18 test files: what keeps that count honest module it covers.** Architecture review, 2026-09-08, at 18 test files: what keeps that count honest
+2 -2
View File
@@ -35,12 +35,12 @@ export default tseslint.config(
}, },
{ {
// The spec tables are data: their length tracks the specification, not any complexity. // The spec tables are data: their length tracks the specification, not any complexity.
files: ['src/codec/{commands,constants,encodings,field-types,statuses,tlvs}.ts'], files: ['src/codec/{commands,constants,encodings,errors,tlvs,types}.ts'],
rules: { 'max-lines': 'off' }, rules: { 'max-lines': 'off' },
}, },
{ {
// ESLint counts every ?. and ?? in dlrFromPdu as a branch; the 19 is 26 lines of flat field resolution. // ESLint counts every ?. and ?? in dlrFromPdu as a branch; the 19 is 26 lines of flat field resolution.
files: ['src/protocol/receipt.ts'], files: ['src/protocol/dlr.ts'],
rules: { complexity: ['error', 19] }, rules: { complexity: ['error', 19] },
}, },
{ {
+2 -2
View File
@@ -1,8 +1,8 @@
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs'; import { readFileSync } from 'node:fs';
import test, { after, describe } from 'node:test'; import test, { after, describe } from 'node:test';
import type { Session } from '../src/session.ts'; import type { Session } from '../src/session/session.ts';
import type { Sms } from '../src/sms.ts'; import type { Sms } from '../src/session/sms.ts';
import type { SmppServer } from '../src/server/server.ts'; import type { SmppServer } from '../src/server/server.ts';
import { server } from '../src/server/server.ts'; import { server } from '../src/server/server.ts';
+3 -3
View File
@@ -1,7 +1,7 @@
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import test, { after, describe } from 'node:test'; import test, { after, describe } from 'node:test';
import type { Session } from '../src/session.ts'; import type { Session } from '../src/session/session.ts';
import type { Sms } from '../src/sms.ts'; import type { Sms } from '../src/session/sms.ts';
import type { LogMethod, SmppLog } from '../src/log.ts'; import type { LogMethod, SmppLog } from '../src/log.ts';
import { server } from '../src/server/server.ts'; import { server } from '../src/server/server.ts';
@@ -270,7 +270,7 @@ describe('S6 - idle peer, no enquire_link at all', () => {
assert.ok(bound, 'dumb-idle never submitted its one message'); assert.ok(bound, 'dumb-idle never submitted its one message');
// idleTimeout is 40s from the last byte the peer sent (its submit_sm), never from our own // idleTimeout is 40s from the last byte the peer sent (its submit_sm), never from our own
// writes (session/keepalive.ts resets only on inbound data). This test may start running well // writes (session/link-timers.ts resets only on inbound data). This test may start running well
// past that mark on its own (S9 above can take a minute) - statsFor(...).closed is set from // past that mark on its own (S9 above can take a minute) - statsFor(...).closed is set from
// a 'close' listener attached at session-creation time, so a close from before this test // a 'close' listener attached at session-creation time, so a close from before this test
// even started is still seen; budget is slack for a session that is still open, not a clock. // even started is still seen; budget is slack for a session that is still open, not a clock.
+4 -4
View File
@@ -1,15 +1,15 @@
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import http from 'node:http'; import http from 'node:http';
import test, { after, describe } from 'node:test'; import test, { after, describe } from 'node:test';
import type { Dlr } from '../src/protocol/receipt.ts'; import type { Dlr } from '../src/protocol/dlr.ts';
import type { EncodingName } from '../src/codec/encodings.ts'; import type { EncodingName } from '../src/codec/encodings.ts';
import type { PduObject } from '../src/codec/pdu.ts'; import type { PduObject } from '../src/codec/pdu.ts';
import type { Session } from '../src/session.ts'; import type { Session } from '../src/session/session.ts';
import type { Sms } from '../src/sms.ts'; import type { Sms } from '../src/session/sms.ts';
import { ConcatReference } from '../src/protocol/udh.ts'; import { ConcatReference } from '../src/protocol/udh.ts';
import { client } from '../src/client/client.ts'; import { client } from '../src/client/client.ts';
import { closeAfter } from '../test/teardown.ts'; import { closeAfter } from '../test/teardown.ts';
import { paramText } from '../src/codec/field-types.ts'; import { paramText } from '../src/codec/types.ts';
import { server } from '../src/server/server.ts'; import { server } from '../src/server/server.ts';
import { encodeMessage, splitMessage } from '../src/message.ts'; import { encodeMessage, splitMessage } from '../src/message.ts';
import { submitSmParams } from '../src/messages/submit.ts'; import { submitSmParams } from '../src/messages/submit.ts';
+2 -2
View File
@@ -1,8 +1,8 @@
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import net from 'node:net'; import net from 'node:net';
import test, { after, describe } from 'node:test'; import test, { after, describe } from 'node:test';
import type { Session } from '../src/session.ts'; import type { Session } from '../src/session/session.ts';
import type { Sms } from '../src/sms.ts'; import type { Sms } from '../src/session/sms.ts';
import { PduRefusedError } from '../src/index.ts'; import { PduRefusedError } from '../src/index.ts';
import { bareTlvHeader, pduBytes } from '../test/raw-pdus.ts'; import { bareTlvHeader, pduBytes } from '../test/raw-pdus.ts';
import { server } from '../src/server/server.ts'; import { server } from '../src/server/server.ts';
+4 -4
View File
@@ -2,13 +2,13 @@ import assert from 'node:assert/strict';
import http from 'node:http'; import http from 'node:http';
import test, { after, describe } from 'node:test'; import test, { after, describe } from 'node:test';
import type { MessageState } from '../src/codec/constants.ts'; import type { MessageState } from '../src/codec/constants.ts';
import type { Dlr } from '../src/protocol/receipt.ts'; import type { Dlr } from '../src/protocol/dlr.ts';
import type { Session } from '../src/session.ts'; import type { Session } from '../src/session/session.ts';
import type { Sms } from '../src/sms.ts'; import type { Sms } from '../src/session/sms.ts';
import { ConcatReference } from '../src/protocol/udh.ts'; import { ConcatReference } from '../src/protocol/udh.ts';
import { consts } from '../src/codec/constants.ts'; import { consts } from '../src/codec/constants.ts';
import { detect, encodings } from '../src/codec/encodings.ts'; import { detect, encodings } from '../src/codec/encodings.ts';
import { paramText } from '../src/codec/field-types.ts'; import { paramText } from '../src/codec/types.ts';
import { server } from '../src/server/server.ts'; import { server } from '../src/server/server.ts';
import { splitMessage } from '../src/message.ts'; import { splitMessage } from '../src/message.ts';
import { submitSmParams } from '../src/messages/submit.ts'; import { submitSmParams } from '../src/messages/submit.ts';
+3 -3
View File
@@ -1,8 +1,8 @@
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import test, { after, describe } from 'node:test'; import test, { after, describe } from 'node:test';
import type { Session } from '../src/session.ts'; import type { Session } from '../src/session/session.ts';
import type { Sms } from '../src/sms.ts'; import type { Sms } from '../src/session/sms.ts';
import { paramText } from '../src/codec/field-types.ts'; import { paramText } from '../src/codec/types.ts';
import { isCommand, server } from '../src/index.ts'; import { isCommand, server } from '../src/index.ts';
const DRIVER = process.env.PHP_DRIVER ?? 'php:8080'; const DRIVER = process.env.PHP_DRIVER ?? 'php:8080';
+3 -3
View File
@@ -1,9 +1,9 @@
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import test, { after, describe } from 'node:test'; import test, { after, describe } from 'node:test';
import type { Session } from '../src/session.ts'; import type { Session } from '../src/session/session.ts';
import type { Sms } from '../src/sms.ts'; import type { Sms } from '../src/session/sms.ts';
import { encodings } from '../src/codec/encodings.ts'; import { encodings } from '../src/codec/encodings.ts';
import { paramText } from '../src/codec/field-types.ts'; import { paramText } from '../src/codec/types.ts';
import { isCommand, server } from '../src/index.ts'; import { isCommand, server } from '../src/index.ts';
const DRIVER = process.env.PYTHON_DRIVER ?? 'python:8080'; const DRIVER = process.env.PYTHON_DRIVER ?? 'python:8080';
+1 -1
View File
@@ -1,6 +1,6 @@
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import test, { after, describe } from 'node:test'; import test, { after, describe } from 'node:test';
import type { Session } from '../src/session.ts'; import type { Session } from '../src/session/session.ts';
import { server } from '../src/server/server.ts'; import { server } from '../src/server/server.ts';
const SMPP_PORT = Number(process.env.SMPP_PORT ?? '2775'); const SMPP_PORT = Number(process.env.SMPP_PORT ?? '2775');
+5 -5
View File
@@ -1,15 +1,15 @@
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import test, { describe } from 'node:test'; import test, { describe } from 'node:test';
import type { Dlr } from '../src/protocol/receipt.ts'; import type { Dlr } from '../src/protocol/dlr.ts';
import type { EncodingName } from '../src/codec/encodings.ts'; import type { EncodingName } from '../src/codec/encodings.ts';
import type { MessageDlr } from '../src/messages/receipt-merge.ts'; import type { MessageDlr } from '../src/messages/dlr-merger.ts';
import type { PduObject } from '../src/codec/pdu.ts'; import type { PduObject } from '../src/codec/pdu.ts';
import type { Session } from '../src/session.ts'; import type { Session } from '../src/session/session.ts';
import type { Sms } from '../src/sms.ts'; import type { Sms } from '../src/session/sms.ts';
import { client } from '../src/client/client.ts'; import { client } from '../src/client/client.ts';
import { closeAfter } from '../test/teardown.ts'; import { closeAfter } from '../test/teardown.ts';
import { consts } from '../src/codec/constants.ts'; import { consts } from '../src/codec/constants.ts';
import { paramText } from '../src/codec/field-types.ts'; import { paramText } from '../src/codec/types.ts';
import { server } from '../src/server/server.ts'; import { server } from '../src/server/server.ts';
const PEER_HOST = process.env.PEER_HOST ?? 'smppsim'; const PEER_HOST = process.env.PEER_HOST ?? 'smppsim';
+3 -3
View File
@@ -1,8 +1,8 @@
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import test, { describe } from 'node:test'; import test, { describe } from 'node:test';
import type { Dlr } from '../src/protocol/receipt.ts'; import type { Dlr } from '../src/protocol/dlr.ts';
import type { Session } from '../src/session.ts'; import type { Session } from '../src/session/session.ts';
import type { Sms } from '../src/sms.ts'; import type { Sms } from '../src/session/sms.ts';
import { client } from '../src/client/client.ts'; import { client } from '../src/client/client.ts';
import { closeAfter } from '../test/teardown.ts'; import { closeAfter } from '../test/teardown.ts';
+2 -2
View File
@@ -7,8 +7,8 @@ import type { SmsIdFormat } from '../protocol/message-ids.ts';
import type { Socket } from 'node:net'; import type { Socket } from 'node:net';
export type { BindType }; export type { BindType };
import { ReconnectLoop } from '../reconnect-loop.ts'; import { ReconnectLoop } from '../session/reconnect-loop.ts';
import { Session } from '../session.ts'; import { Session } from '../session/session.ts';
import { checkSessionOptions, defaults } from '../options.ts'; import { checkSessionOptions, defaults } from '../options.ts';
import { connect as netConnect } from 'node:net'; import { connect as netConnect } from 'node:net';
import { connect as tlsConnect } from 'node:tls'; import { connect as tlsConnect } from 'node:tls';
+2 -2
View File
@@ -1,5 +1,5 @@
import type { WireType } from './field-types.ts'; import type { WireType } from './types.ts';
import { buffer, cstring, dest_address_array, int8, unsuccess_sme_array } from './field-types.ts'; import { buffer, cstring, dest_address_array, int8, unsuccess_sme_array } from './types.ts';
type CommandSpec = { type CommandSpec = {
id: number; id: number;
+4 -4
View File
@@ -1,6 +1,6 @@
import type { CommandDefinition, CommandName, PduParams, PduParamsInput } from './commands.ts'; import type { CommandDefinition, CommandName, PduParams, PduParamsInput } from './commands.ts';
import type { ErrorName } from './statuses.ts'; import type { ErrorName } from './errors.ts';
import type { ParamValue } from './field-types.ts'; import type { ParamValue } from './types.ts';
import type { PduHeader } from './refusal.ts'; import type { PduHeader } from './refusal.ts';
import type { Result, VoidResult } from '../result.ts'; import type { Result, VoidResult } from '../result.ts';
import type { TlvInputs, Tlvs } from './tlvs.ts'; import type { TlvInputs, Tlvs } from './tlvs.ts';
@@ -8,8 +8,8 @@ import { PduRefusedError, framingRefusal } from './refusal.ts';
import { cmds, commandNameById, respNameFor } from './commands.ts'; import { cmds, commandNameById, respNameFor } from './commands.ts';
import { hasUdh } from './constants.ts'; import { hasUdh } from './constants.ts';
import { decodeMessage, encodeBody } from '../message.ts'; import { decodeMessage, encodeBody } from '../message.ts';
import { errorNameById, errors, isErrorName } from './statuses.ts'; import { errorNameById, errors, isErrorName } from './errors.ts';
import { paramNumber, valueText } from './field-types.ts'; import { paramNumber, valueText } from './types.ts';
import { parseTlvs, writeTlvs } from './tlvs.ts'; import { parseTlvs, writeTlvs } from './tlvs.ts';
/** The highest sequence number this library hands out; SMPP 3.4 4.7.1 reserves 0x7fffffff. */ /** The highest sequence number this library hands out; SMPP 3.4 4.7.1 reserves 0x7fffffff. */
+1 -1
View File
@@ -1,5 +1,5 @@
import type { CommandName } from './commands.ts'; import type { CommandName } from './commands.ts';
import type { ErrorName } from './statuses.ts'; import type { ErrorName } from './errors.ts';
import { respNameFor } from './commands.ts'; import { respNameFor } from './commands.ts';
/** A hostile peer must not be able to make us allocate arbitrarily. */ /** A hostile peer must not be able to make us allocate arbitrarily. */
@@ -1,6 +1,6 @@
import type { ParamValue } from './field-types.ts'; import type { ParamValue } from './types.ts';
import type { PduObject } from './pdu.ts'; import type { PduObject } from './pdu.ts';
import { tlvOctets } from './field-types.ts'; import { tlvOctets } from './types.ts';
/** Wire reads hand back views, so retaining one PDU would pin the whole chunk it arrived in. */ /** Wire reads hand back views, so retaining one PDU would pin the whole chunk it arrived in. */
export function detach(pduObj: PduObject): PduObject { export function detach(pduObj: PduObject): PduObject {
+2 -2
View File
@@ -1,6 +1,6 @@
import type { ParamValue, TlvValue, WireType } from './field-types.ts'; import type { ParamValue, TlvValue, WireType } from './types.ts';
import type { Result } from '../result.ts'; import type { Result } from '../result.ts';
import { tlv } from './field-types.ts'; import { tlv } from './types.ts';
/** Only a tag read as octets or as a number may repeat, since its occurrences are listed as one of those. */ /** Only a tag read as octets or as a number may repeat, since its occurrences are listed as one of those. */
type Definition<Tag> = { id: number; multiple?: false; tag: Tag; type: WireType<Buffer | number | string> } type Definition<Tag> = { id: number; multiple?: false; tag: Tag; type: WireType<Buffer | number | string> }
+12 -12
View File
@@ -1,20 +1,20 @@
import { cmds, cmdsById } from './codec/commands.ts'; import { cmds, cmdsById } from './codec/commands.ts';
import { consts, constsById } from './codec/constants.ts'; import { consts, constsById } from './codec/constants.ts';
import { encodings } from './codec/encodings.ts'; import { encodings } from './codec/encodings.ts';
import { errors, errorsById } from './codec/statuses.ts'; import { errors, errorsById } from './codec/errors.ts';
import { tlvs, tlvsById } from './codec/tlvs.ts'; import { tlvs, tlvsById } from './codec/tlvs.ts';
import { types } from './codec/field-types.ts'; import { types } from './codec/types.ts';
export { client } from './client/client.ts'; export { client } from './client/client.ts';
export { server, SmppServer } from './server/server.ts'; export { server, SmppServer } from './server/server.ts';
export { Session } from './session.ts'; export { Session } from './session/session.ts';
export { cmds, cmdsById, commandNameById, isCommandName } from './codec/commands.ts'; export { cmds, cmdsById, commandNameById, isCommandName } from './codec/commands.ts';
export { consts, constsById } from './codec/constants.ts'; export { consts, constsById } from './codec/constants.ts';
export { dataCodingByEncoding, detect, encodingByDataCoding, encodings, isEncodingName, messageClassOf, unencodable } from './codec/encodings.ts'; export { dataCodingByEncoding, detect, encodingByDataCoding, encodings, isEncodingName, messageClassOf, unencodable } from './codec/encodings.ts';
export { errorNameById, errors, errorsById, isErrorName } from './codec/statuses.ts'; export { errorNameById, errors, errorsById, isErrorName } from './codec/errors.ts';
export { isTlvName, tlvs, tlvsById } from './codec/tlvs.ts'; export { isTlvName, tlvs, tlvsById } from './codec/tlvs.ts';
export { types } from './codec/field-types.ts'; export { types } from './codec/types.ts';
export { export {
isCommand, isCommand,
@@ -36,16 +36,16 @@ export {
splitMessage, splitMessage,
} from './message.ts'; } from './message.ts';
export { dlrFromPdu, parseReceipt, receiptCodes } from './protocol/receipt.ts'; export { dlrFromPdu, parseReceipt, receiptCodes } from './protocol/dlr.ts';
export { messageOctets } from './protocol/message-body.ts'; export { messageOctets } from './protocol/message-body.ts';
export { concatOf } from './protocol/concat.ts'; export { concatOf } from './protocol/concat.ts';
export { concatInfo } from './protocol/udh.ts'; export { concatInfo } from './protocol/udh.ts';
export { PduFramer } from './codec/framer.ts'; export { PduFramer } from './codec/pdu-framer.ts';
export { uuidv7 } from './protocol/uuid.ts'; export { uuidv7 } from './protocol/uuid.ts';
export type { BindType, ClientOptions } from './client/client.ts'; export type { BindType, ClientOptions } from './client/client.ts';
export type { Dlr, Receipt } from './protocol/receipt.ts'; export type { Dlr, Receipt } from './protocol/dlr.ts';
export type { SendDlrResult, SendRespOptions, Sms } from './sms.ts'; export type { SendDlrResult, SendRespOptions, Sms } from './session/sms.ts';
export type { Concat } from './protocol/concat.ts'; export type { Concat } from './protocol/concat.ts';
export type { ConcatInfo } from './protocol/udh.ts'; export type { ConcatInfo } from './protocol/udh.ts';
export type { Result, VoidResult } from './result.ts'; export type { Result, VoidResult } from './result.ts';
@@ -66,16 +66,16 @@ export type {
SendSmsResult, SendSmsResult,
SessionEvents, SessionEvents,
SessionOptions, SessionOptions,
} from './session.ts'; } from './session/session.ts';
export type { CommandName, PduParams, PduParamsInput } from './codec/commands.ts'; export type { CommandName, PduParams, PduParamsInput } from './codec/commands.ts';
export type { ConstGroup, MessageState, SubmitMessagingMode } from './codec/constants.ts'; export type { ConstGroup, MessageState, SubmitMessagingMode } from './codec/constants.ts';
export type { Encoding, EncodingName, Unencodable } from './codec/encodings.ts'; export type { Encoding, EncodingName, Unencodable } from './codec/encodings.ts';
export type { ErrorName } from './codec/statuses.ts'; export type { ErrorName } from './codec/errors.ts';
export type { PduObject, PduObjectInput, TlvInputs } from './codec/pdu.ts'; export type { PduObject, PduObjectInput, TlvInputs } from './codec/pdu.ts';
export type { PduHeader } from './codec/refusal.ts'; export type { PduHeader } from './codec/refusal.ts';
export type { SplitOptions } from './message.ts'; export type { SplitOptions } from './message.ts';
export type { Tlv, TlvDefinition, TlvName, Tlvs } from './codec/tlvs.ts'; export type { Tlv, TlvDefinition, TlvName, Tlvs } from './codec/tlvs.ts';
export type { DestAddress, ParamValue, TlvValue, UnsuccessSme, WireType } from './codec/field-types.ts'; export type { DestAddress, ParamValue, TlvValue, UnsuccessSme, WireType } from './codec/types.ts';
/** The spec tables, grouped the way `larvitsmpp.defs` was in 0.4.0. */ /** The spec tables, grouped the way `larvitsmpp.defs` was in 0.4.0. */
export const defs = { export const defs = {
@@ -1,4 +1,4 @@
import type { Dlr } from '../protocol/receipt.ts'; import type { Dlr } from '../protocol/dlr.ts';
import type { MessageState } from '../codec/constants.ts'; import type { MessageState } from '../codec/constants.ts';
import type { SmppLog } from '../log.ts'; import type { SmppLog } from '../log.ts';
import { ExpiringGroups } from './expiring-groups.ts'; import { ExpiringGroups } from './expiring-groups.ts';
+2 -2
View File
@@ -4,9 +4,9 @@ import type { SmppLog } from '../log.ts';
import { ExpiringGroups } from './expiring-groups.ts'; import { ExpiringGroups } from './expiring-groups.ts';
import { decodeMessage } from '../message.ts'; import { decodeMessage } from '../message.ts';
import { defaults } from '../options.ts'; import { defaults } from '../options.ts';
import { detach, retainedOctets } from '../codec/retained.ts'; import { detach, retainedOctets } from '../codec/retained-pdu.ts';
import { messageOctets } from '../protocol/message-body.ts'; import { messageOctets } from '../protocol/message-body.ts';
import { paramNumber, paramText } from '../codec/field-types.ts'; import { paramNumber, paramText } from '../codec/types.ts';
import { uuidv7 } from '../protocol/uuid.ts'; import { uuidv7 } from '../protocol/uuid.ts';
/** A concatenated message given up on, whose segments the peer has already been answered for. */ /** A concatenated message given up on, whose segments the peer has already been answered for. */
+2 -2
View File
@@ -1,5 +1,5 @@
import type { EncodingName, Unencodable } from '../codec/encodings.ts'; import type { EncodingName, Unencodable } from '../codec/encodings.ts';
import type { ParamValue } from '../codec/field-types.ts'; import type { ParamValue } from '../codec/types.ts';
import type { SubmitMessagingMode } from '../codec/constants.ts'; import type { SubmitMessagingMode } from '../codec/constants.ts';
import type { PduObject, PduObjectInput } from '../codec/pdu.ts'; import type { PduObject, PduObjectInput } from '../codec/pdu.ts';
import type { Result } from '../result.ts'; import type { Result } from '../result.ts';
@@ -7,7 +7,7 @@ import type { SmppLog } from '../log.ts';
import type { SmsIdNotation } from '../protocol/message-ids.ts'; import type { SmsIdNotation } from '../protocol/message-ids.ts';
import { UnansweredError } from '../unanswered-error.ts'; import { UnansweredError } from '../unanswered-error.ts';
import { consts, defaultMessagingMode, isMessagingMode, isSubmitMessagingMode, submitMessagingModes } from '../codec/constants.ts'; import { consts, defaultMessagingMode, isMessagingMode, isSubmitMessagingMode, submitMessagingModes } from '../codec/constants.ts';
import { cstring, paramText } from '../codec/field-types.ts'; import { cstring, paramText } from '../codec/types.ts';
import { dataCodingByEncoding, detect, encodingNames, isEncodingName, unencodable, unencodableText } from '../codec/encodings.ts'; import { dataCodingByEncoding, detect, encodingNames, isEncodingName, unencodable, unencodableText } from '../codec/encodings.ts';
import { namedValue } from '../result.ts'; import { namedValue } from '../result.ts';
import { normaliseSmsId } from '../protocol/message-ids.ts'; import { normaliseSmsId } from '../protocol/message-ids.ts';
+1 -1
View File
@@ -1,6 +1,6 @@
import type { PduObject } from './codec/pdu.ts'; import type { PduObject } from './codec/pdu.ts';
import type { Result, VoidResult } from './result.ts'; import type { Result, VoidResult } from './result.ts';
import type { Session } from './session.ts'; import type { Session } from './session/session.ts';
import type { SmppLog } from './log.ts'; import type { SmppLog } from './log.ts';
import type { SmsIdFormat } from './protocol/message-ids.ts'; import type { SmsIdFormat } from './protocol/message-ids.ts';
import type { Socket } from 'node:net'; import type { Socket } from 'node:net';
+1 -1
View File
@@ -3,7 +3,7 @@ import type { PduObject } from '../codec/pdu.ts';
import { concatInfo } from './udh.ts'; import { concatInfo } from './udh.ts';
import { hasUdh } from '../codec/constants.ts'; import { hasUdh } from '../codec/constants.ts';
import { messageOctets } from './message-body.ts'; import { messageOctets } from './message-body.ts';
import { paramNumber } from '../codec/field-types.ts'; import { paramNumber } from '../codec/types.ts';
/** Where a segment sits in its message, and what ties it to the rest of that message. */ /** Where a segment sits in its message, and what ties it to the rest of that message. */
export type Concat = ConcatInfo & { export type Concat = ConcatInfo & {
@@ -1,12 +1,12 @@
import type { MessageState } from '../codec/constants.ts'; import type { MessageState } from '../codec/constants.ts';
import type { TlvValue } from '../codec/field-types.ts'; import type { TlvValue } from '../codec/types.ts';
import type { PduObject } from '../codec/pdu.ts'; import type { PduObject } from '../codec/pdu.ts';
import type { SmsIdFormat } from './message-ids.ts'; import type { SmsIdFormat } from './message-ids.ts';
import { consts, constsById, hasUdh, messageTypeOf } from '../codec/constants.ts'; import { consts, constsById, hasUdh, messageTypeOf } from '../codec/constants.ts';
import { encodings } from '../codec/encodings.ts'; import { encodings } from '../codec/encodings.ts';
import { messageOctets } from './message-body.ts'; import { messageOctets } from './message-body.ts';
import { normaliseSmsId } from './message-ids.ts'; import { normaliseSmsId } from './message-ids.ts';
import { paramNumber, paramText } from '../codec/field-types.ts'; import { paramNumber, paramText } from '../codec/types.ts';
import { udhLength } from './udh.ts'; import { udhLength } from './udh.ts';
/** /**
+1 -1
View File
@@ -1,5 +1,5 @@
import type { CommandName } from '../codec/commands.ts'; import type { CommandName } from '../codec/commands.ts';
import type { ParamValue } from '../codec/field-types.ts'; import type { ParamValue } from '../codec/types.ts';
const notations = { const notations = {
decimal: { digits: /^[0-9]+$/, prefix: '' }, decimal: { digits: /^[0-9]+$/, prefix: '' },
+2 -2
View File
@@ -6,13 +6,13 @@ import type { Server as NetServer, Socket } from 'node:net';
import type { Server as TlsServer, TlsOptions } from 'node:tls'; import type { Server as TlsServer, TlsOptions } from 'node:tls';
import type { SmppLog } from '../log.ts'; import type { SmppLog } from '../log.ts';
import { EventEmitter } from 'node:events'; import { EventEmitter } from 'node:events';
import { Session } from '../session.ts'; import { Session } from '../session/session.ts';
import { bindTypeFromCommand } from '../protocol/bind.ts'; import { bindTypeFromCommand } from '../protocol/bind.ts';
import { checkSessionOptions, defaults } from '../options.ts'; import { checkSessionOptions, defaults } from '../options.ts';
import { createServer as createNetServer } from 'node:net'; import { createServer as createNetServer } from 'node:net';
import { createServer as createTlsServer } from 'node:tls'; import { createServer as createTlsServer } from 'node:tls';
import { errorFrom } from '../result.ts'; import { errorFrom } from '../result.ts';
import { paramText } from '../codec/field-types.ts'; import { paramText } from '../codec/types.ts';
import { guardedLog } from '../log.ts'; import { guardedLog } from '../log.ts';
import { respNameFor } from '../codec/commands.ts'; import { respNameFor } from '../codec/commands.ts';
+6 -6
View File
@@ -1,13 +1,13 @@
import type { LinkLife } from '../link-life.ts'; import type { LinkLife } from './link-life.ts';
import type { PduObject, PduObjectInput } from '../codec/pdu.ts'; import type { PduObject, PduObjectInput } from '../codec/pdu.ts';
import type { Result } from '../result.ts'; import type { Result } from '../result.ts';
import type { Session } from '../session.ts'; import type { Session } from './session.ts';
import type { SmsHandlers } from '../sms.ts'; import type { SmsHandlers } from './sms.ts';
import type { SmppLog } from '../log.ts'; import type { SmppLog } from '../log.ts';
import { ExpiringGroups } from '../messages/expiring-groups.ts'; import { ExpiringGroups } from '../messages/expiring-groups.ts';
import { IdleWaiters } from './waiting.ts'; import { IdleWaiters } from './idle-waiters.ts';
import { createSms } from '../sms.ts'; import { createSms } from './sms.ts';
import { retainedOctets } from '../codec/retained.ts'; import { retainedOctets } from '../codec/retained-pdu.ts';
export type HeldMessagesOptions = { export type HeldMessagesOptions = {
link: LinkLife; link: LinkLife;
@@ -1,13 +1,13 @@
import type { Concat } from '../protocol/concat.ts'; import type { Concat } from '../protocol/concat.ts';
import type { DlrMerger } from '../messages/receipt-merge.ts'; import type { DlrMerger } from '../messages/dlr-merger.ts';
import type { ErrorName } from '../codec/statuses.ts'; import type { ErrorName } from '../codec/errors.ts';
import type { HeldMessagesOptions } from './held-messages.ts'; import type { HeldMessagesOptions } from './held-messages.ts';
import type { LinkLife } from '../link-life.ts'; import type { LinkLife } from './link-life.ts';
import type { LostGroup, Refusal } from '../messages/reassembly.ts'; import type { LostGroup, Refusal } from '../messages/reassembly.ts';
import type { OnRequest } from '../options.ts'; import type { OnRequest } from '../options.ts';
import type { PduObject } from '../codec/pdu.ts'; import type { PduObject } from '../codec/pdu.ts';
import type { VoidResult } from '../result.ts'; import type { VoidResult } from '../result.ts';
import type { Session } from '../session.ts'; import type { Session } from './session.ts';
import type { SmppLog } from '../log.ts'; import type { SmppLog } from '../log.ts';
import type { SmsIdFormat } from '../protocol/message-ids.ts'; import type { SmsIdFormat } from '../protocol/message-ids.ts';
import { HeldMessages } from './held-messages.ts'; import { HeldMessages } from './held-messages.ts';
@@ -15,8 +15,8 @@ import { Reassembler } from '../messages/reassembly.ts';
import { bindCommands, standsInFor } from '../protocol/bind.ts'; import { bindCommands, standsInFor } from '../protocol/bind.ts';
import { defaults } from '../options.ts'; import { defaults } from '../options.ts';
import { concatOf } from '../protocol/concat.ts'; import { concatOf } from '../protocol/concat.ts';
import { detach } from '../codec/retained.ts'; import { detach } from '../codec/retained-pdu.ts';
import { dlrFromPdu } from '../protocol/receipt.ts'; import { dlrFromPdu } from '../protocol/dlr.ts';
import { respIdParams, segmentId } from '../protocol/message-ids.ts'; import { respIdParams, segmentId } from '../protocol/message-ids.ts';
import { respNameFor } from '../codec/commands.ts'; import { respNameFor } from '../codec/commands.ts';
@@ -1,5 +1,5 @@
import type { SmppLog } from './log.ts'; import type { SmppLog } from '../log.ts';
import type { VoidResult } from './result.ts'; import type { VoidResult } from '../result.ts';
export type LinkLifeOptions = { export type LinkLifeOptions = {
log: SmppLog; log: SmppLog;
+2 -2
View File
@@ -1,6 +1,6 @@
import type { LinkLife } from '../link-life.ts'; import type { LinkLife } from './link-life.ts';
import type { PduObject, PduObjectInput } from '../codec/pdu.ts'; import type { PduObject, PduObjectInput } from '../codec/pdu.ts';
import type { PduTransport } from './transport.ts'; import type { PduTransport } from './pdu-transport.ts';
import type { Result, VoidResult } from '../result.ts'; import type { Result, VoidResult } from '../result.ts';
import type { SendOptions } from '../options.ts'; import type { SendOptions } from '../options.ts';
import type { SmppLog } from '../log.ts'; import type { SmppLog } from '../log.ts';
@@ -2,7 +2,7 @@ import type { PduObject } from '../codec/pdu.ts';
import type { SmppLog } from '../log.ts'; import type { SmppLog } from '../log.ts';
import type { Socket } from 'node:net'; import type { Socket } from 'node:net';
import type { VoidResult } from '../result.ts'; import type { VoidResult } from '../result.ts';
import { PduFramer } from '../codec/framer.ts'; import { PduFramer } from '../codec/pdu-framer.ts';
import { PduRefusedError } from '../codec/refusal.ts'; import { PduRefusedError } from '../codec/refusal.ts';
import { pduToObj } from '../codec/pdu.ts'; import { pduToObj } from '../codec/pdu.ts';
@@ -1,7 +1,7 @@
import type { Result, VoidResult } from './result.ts'; import type { Result, VoidResult } from '../result.ts';
import type { SmppLog } from './log.ts'; import type { SmppLog } from '../log.ts';
import type { Socket } from 'node:net'; import type { Socket } from 'node:net';
import { defaults } from './options.ts'; import { defaults } from '../options.ts';
export type ReconnectLoopOptions = { export type ReconnectLoopOptions = {
connect: () => Promise<Result<{ sock: Socket }>>; connect: () => Promise<Result<{ sock: Socket }>>;
+1 -1
View File
@@ -1,6 +1,6 @@
import type { SmppLog } from '../log.ts'; import type { SmppLog } from '../log.ts';
import type { VoidResult } from '../result.ts'; import type { VoidResult } from '../result.ts';
import { IdleWaiters } from './waiting.ts'; import { IdleWaiters } from './idle-waiters.ts';
export type SendWindowOptions = { export type SendWindowOptions = {
limit: number; limit: number;
+26 -26
View File
@@ -1,34 +1,34 @@
import type { Dlr } from './protocol/receipt.ts'; import type { Dlr } from '../protocol/dlr.ts';
import type { ErrorName } from './codec/statuses.ts'; import type { ErrorName } from '../codec/errors.ts';
import type { MessageDlr } from './messages/receipt-merge.ts'; import type { MessageDlr } from '../messages/dlr-merger.ts';
import type { ParamValue } from './codec/field-types.ts'; import type { ParamValue } from '../codec/types.ts';
import type { PduObject, PduObjectInput, TlvInputs } from './codec/pdu.ts'; import type { PduObject, PduObjectInput, TlvInputs } from '../codec/pdu.ts';
import type { PduRefusedError } from './codec/refusal.ts'; import type { PduRefusedError } from '../codec/refusal.ts';
import type { BindType, LinkEnd, SessionBind } from './protocol/bind.ts'; import type { BindType, LinkEnd, SessionBind } from '../protocol/bind.ts';
import type { CloseOptions, ReconnectOptions, SendOptions, SessionOptions } from './options.ts'; import type { CloseOptions, ReconnectOptions, SendOptions, SessionOptions } from '../options.ts';
import type { Result, VoidResult } from './result.ts'; import type { Result, VoidResult } from '../result.ts';
import type { SendSmsOptions, SendSmsResult } from './messages/submit.ts'; import type { SendSmsOptions, SendSmsResult } from '../messages/submit.ts';
import type { SmppLog } from './log.ts'; import type { SmppLog } from '../log.ts';
import type { Sms } from './sms.ts'; import type { Sms } from './sms.ts';
import type { Socket } from 'node:net'; import type { Socket } from 'node:net';
import { DlrMerger } from './messages/receipt-merge.ts'; import { DlrMerger } from '../messages/dlr-merger.ts';
import { EventEmitter } from 'node:events'; import { EventEmitter } from 'node:events';
import { IncomingRequests } from './session/requests-in.ts'; import { IncomingRequests } from './incoming-requests.ts';
import { LinkLife } from './link-life.ts'; import { LinkLife } from './link-life.ts';
import { LinkTimers } from './session/keepalive.ts'; import { LinkTimers } from './link-timers.ts';
import { OutgoingRequests } from './session/outgoing-requests.ts'; import { OutgoingRequests } from './outgoing-requests.ts';
import { PduTransport } from './session/transport.ts'; import { PduTransport } from './pdu-transport.ts';
import { ReconnectLoop } from './reconnect-loop.ts'; import { ReconnectLoop } from './reconnect-loop.ts';
import { leftOf } from './session/waiting.ts'; import { leftOf } from './idle-waiters.ts';
import { errorFrom } from './result.ts'; import { errorFrom } from '../result.ts';
import { optionalParamsMinVersion } from './codec/constants.ts'; import { optionalParamsMinVersion } from '../codec/constants.ts';
import { bindCarries, checkedBind } from './protocol/bind.ts'; import { bindCarries, checkedBind } from '../protocol/bind.ts';
import { defaults } from './options.ts'; import { defaults } from '../options.ts';
import { isResp, objToPdu, pduReturn } from './codec/pdu.ts'; import { isResp, objToPdu, pduReturn } from '../codec/pdu.ts';
import { refusalAnswer } from './codec/refusal.ts'; import { refusalAnswer } from '../codec/refusal.ts';
import { guardedLog } from './log.ts'; import { guardedLog } from '../log.ts';
import { submitSms, unsent } from './messages/submit.ts'; import { submitSms, unsent } from '../messages/submit.ts';
import { ConcatReference } from './protocol/udh.ts'; import { ConcatReference } from '../protocol/udh.ts';
export type { export type {
CloseOptions, CloseOptions,
+13 -13
View File
@@ -1,17 +1,17 @@
import type { ErrorName } from './codec/statuses.ts'; import type { ErrorName } from '../codec/errors.ts';
import type { MessageState } from './codec/constants.ts'; import type { MessageState } from '../codec/constants.ts';
import type { PduObject, PduObjectInput, TlvInputs } from './codec/pdu.ts'; import type { PduObject, PduObjectInput, TlvInputs } from '../codec/pdu.ts';
import type { Result, VoidResult } from './result.ts'; import type { Result, VoidResult } from '../result.ts';
import type { Session } from './session.ts'; import type { Session } from './session.ts';
import { UnansweredError } from './unanswered-error.ts'; import { UnansweredError } from '../unanswered-error.ts';
import { consts } from './codec/constants.ts'; import { consts } from '../codec/constants.ts';
import { decodeSegments } from './messages/reassembly.ts'; import { decodeSegments } from '../messages/reassembly.ts';
import { messageClassOf } from './codec/encodings.ts'; import { messageClassOf } from '../codec/encodings.ts';
import { paramText } from './codec/field-types.ts'; import { paramText } from '../codec/types.ts';
import { receiptCodes, transientStates } from './protocol/receipt.ts'; import { receiptCodes, transientStates } from '../protocol/dlr.ts';
import { smppDate } from './message.ts'; import { smppDate } from '../message.ts';
import { respIdParams, segmentId } from './protocol/message-ids.ts'; import { respIdParams, segmentId } from '../protocol/message-ids.ts';
import { uuidv7 } from './protocol/uuid.ts'; import { uuidv7 } from '../protocol/uuid.ts';
/** `pduObjs` holds what the peer took, so a partial failure names what is already receipted. */ /** `pduObjs` holds what the peer took, so a partial failure names what is already receipted. */
export type SendDlrResult = { export type SendDlrResult = {
+2 -2
View File
@@ -5,10 +5,10 @@ import { client } from '../src/client/client.ts';
import { closeAfter } from './teardown.ts'; import { closeAfter } from './teardown.ts';
import { consts } from '../src/codec/constants.ts'; import { consts } from '../src/codec/constants.ts';
import { decodeMessage } from '../src/message.ts'; import { decodeMessage } from '../src/message.ts';
import { dlrFromPdu } from '../src/protocol/receipt.ts'; import { dlrFromPdu } from '../src/protocol/dlr.ts';
import { encodingByDataCoding, encodings } from '../src/codec/encodings.ts'; import { encodingByDataCoding, encodings } from '../src/codec/encodings.ts';
import { objToPdu, pduToObj } from '../src/codec/pdu.ts'; import { objToPdu, pduToObj } from '../src/codec/pdu.ts';
import { paramNumber } from '../src/codec/field-types.ts'; import { paramNumber } from '../src/codec/types.ts';
import { server } from '../src/server/server.ts'; import { server } from '../src/server/server.ts';
import type { PduObject } from '../src/codec/pdu.ts'; import type { PduObject } from '../src/codec/pdu.ts';
+1 -1
View File
@@ -1,7 +1,7 @@
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import test, { describe } from 'node:test'; import test, { describe } from 'node:test';
import { consts } from '../src/codec/constants.ts'; import { consts } from '../src/codec/constants.ts';
import { dlrFromPdu, parseReceipt, receiptCodes } from '../src/protocol/receipt.ts'; import { dlrFromPdu, parseReceipt, receiptCodes } from '../src/protocol/dlr.ts';
import { encodeMessage } from '../src/message.ts'; import { encodeMessage } from '../src/message.ts';
import { objToPdu, pduToObj } from '../src/codec/pdu.ts'; import { objToPdu, pduToObj } from '../src/codec/pdu.ts';
import type { PduObject, TlvInputs } from '../src/codec/pdu.ts'; import type { PduObject, TlvInputs } from '../src/codec/pdu.ts';
+2 -2
View File
@@ -1,8 +1,8 @@
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import net from 'node:net'; import net from 'node:net';
import type { Session } from '../src/session.ts'; import type { Session } from '../src/session/session.ts';
import type { TestContext } from 'node:test'; import type { TestContext } from 'node:test';
import { PduFramer } from '../src/codec/framer.ts'; import { PduFramer } from '../src/codec/pdu-framer.ts';
import { client } from '../src/client/client.ts'; import { client } from '../src/client/client.ts';
import { closeAfter, closeListenerAfter } from './teardown.ts'; import { closeAfter, closeListenerAfter } from './teardown.ts';
import { consts } from '../src/codec/constants.ts'; import { consts } from '../src/codec/constants.ts';
+1 -1
View File
@@ -2,7 +2,7 @@ import assert from 'node:assert/strict';
import test, { describe } from 'node:test'; import test, { describe } from 'node:test';
import reference from 'smpp'; import reference from 'smpp';
import type { ReferenceSession } from 'smpp'; import type { ReferenceSession } from 'smpp';
import type { Sms } from '../src/sms.ts'; import type { Sms } from '../src/session/sms.ts';
import { client } from '../src/client/client.ts'; import { client } from '../src/client/client.ts';
import { closeAfter } from './teardown.ts'; import { closeAfter } from './teardown.ts';
import { concatInfo } from '../src/protocol/udh.ts'; import { concatInfo } from '../src/protocol/udh.ts';
+3 -3
View File
@@ -2,14 +2,14 @@ import assert from 'node:assert/strict';
import test, { describe } from 'node:test'; import test, { describe } from 'node:test';
import type { PduObjectInput } from '../src/codec/pdu.ts'; import type { PduObjectInput } from '../src/codec/pdu.ts';
import type { SendSmsDeps } from '../src/messages/submit.ts'; import type { SendSmsDeps } from '../src/messages/submit.ts';
import type { Session } from '../src/session.ts'; import type { Session } from '../src/session/session.ts';
import type { Sms } from '../src/sms.ts'; import type { Sms } from '../src/session/sms.ts';
import type { TestContext } from 'node:test'; import type { TestContext } from 'node:test';
import { bindToSmsc, dummySmsc } from './dummy-smsc.ts'; import { bindToSmsc, dummySmsc } from './dummy-smsc.ts';
import { client } from '../src/client/client.ts'; import { client } from '../src/client/client.ts';
import { closeAfter } from './teardown.ts'; import { closeAfter } from './teardown.ts';
import { messageClassOf } from '../src/codec/encodings.ts'; import { messageClassOf } from '../src/codec/encodings.ts';
import { paramNumber } from '../src/codec/field-types.ts'; import { paramNumber } from '../src/codec/types.ts';
import { pduToObj } from '../src/codec/pdu.ts'; import { pduToObj } from '../src/codec/pdu.ts';
import { server } from '../src/server/server.ts'; import { server } from '../src/server/server.ts';
import { silentLog } from '../src/log.ts'; import { silentLog } from '../src/log.ts';
+2 -2
View File
@@ -2,12 +2,12 @@ import assert from 'node:assert/strict';
import test, { describe } from 'node:test'; import test, { describe } from 'node:test';
import type { PduObjectInput } from '../src/codec/pdu.ts'; import type { PduObjectInput } from '../src/codec/pdu.ts';
import type { SendSmsDeps } from '../src/messages/submit.ts'; import type { SendSmsDeps } from '../src/messages/submit.ts';
import type { Session } from '../src/session.ts'; import type { Session } from '../src/session/session.ts';
import type { SubmitMessagingMode } from '../src/codec/constants.ts'; import type { SubmitMessagingMode } from '../src/codec/constants.ts';
import type { TestContext } from 'node:test'; import type { TestContext } from 'node:test';
import { bindToSmsc, dummySmsc } from './dummy-smsc.ts'; import { bindToSmsc, dummySmsc } from './dummy-smsc.ts';
import { consts, submitMessagingModes } from '../src/codec/constants.ts'; import { consts, submitMessagingModes } from '../src/codec/constants.ts';
import { paramNumber } from '../src/codec/field-types.ts'; import { paramNumber } from '../src/codec/types.ts';
import { pduToObj } from '../src/codec/pdu.ts'; import { pduToObj } from '../src/codec/pdu.ts';
import { silentLog } from '../src/log.ts'; import { silentLog } from '../src/log.ts';
import { submitSms } from '../src/messages/submit.ts'; import { submitSms } from '../src/messages/submit.ts';
+3 -3
View File
@@ -1,11 +1,11 @@
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import test, { describe } from 'node:test'; import test, { describe } from 'node:test';
import type { Dlr, Receipt } from '../src/protocol/receipt.ts'; import type { Dlr, Receipt } from '../src/protocol/dlr.ts';
import type { MessageDlr } from '../src/session.ts'; import type { MessageDlr } from '../src/session/session.ts';
import type { PduObject, TlvInputs } from '../src/codec/pdu.ts'; import type { PduObject, TlvInputs } from '../src/codec/pdu.ts';
import { bindToSmsc, dummySmsc } from './dummy-smsc.ts'; import { bindToSmsc, dummySmsc } from './dummy-smsc.ts';
import { consts } from '../src/codec/constants.ts'; import { consts } from '../src/codec/constants.ts';
import { dlrFromPdu, parseReceipt, receiptCodes, transientStates } from '../src/protocol/receipt.ts'; import { dlrFromPdu, parseReceipt, receiptCodes, transientStates } from '../src/protocol/dlr.ts';
import { objToPdu, pduToObj } from '../src/codec/pdu.ts'; import { objToPdu, pduToObj } from '../src/codec/pdu.ts';
/** /**
+1 -1
View File
@@ -1,6 +1,6 @@
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import test, { describe } from 'node:test'; import test, { describe } from 'node:test';
import { PduFramer } from '../src/codec/framer.ts'; import { PduFramer } from '../src/codec/pdu-framer.ts';
import { objToPdu } from '../src/codec/pdu.ts'; import { objToPdu } from '../src/codec/pdu.ts';
function pdu(seqNr: number): Buffer { function pdu(seqNr: number): Buffer {
+1 -1
View File
@@ -2,7 +2,7 @@ import assert from 'node:assert/strict';
import test, { describe } from 'node:test'; import test, { describe } from 'node:test';
import { PduRefusedError, refusalAnswer } from '../src/codec/refusal.ts'; import { PduRefusedError, refusalAnswer } from '../src/codec/refusal.ts';
import { isCommand, isResp, objToPdu, pduReturn, pduToObj } from '../src/codec/pdu.ts'; import { isCommand, isResp, objToPdu, pduReturn, pduToObj } from '../src/codec/pdu.ts';
import { paramText } from '../src/codec/field-types.ts'; import { paramText } from '../src/codec/types.ts';
import { isTlvName, tlvsById } from '../src/codec/tlvs.ts'; import { isTlvName, tlvsById } from '../src/codec/tlvs.ts';
function encode(...args: Parameters<typeof objToPdu>): Buffer { function encode(...args: Parameters<typeof objToPdu>): Buffer {
+3 -3
View File
@@ -1,8 +1,8 @@
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import test, { describe } from 'node:test'; import test, { describe } from 'node:test';
import type { Dlr } from '../src/protocol/receipt.ts'; import type { Dlr } from '../src/protocol/dlr.ts';
import type { Session } from '../src/session.ts'; import type { Session } from '../src/session/session.ts';
import type { Sms } from '../src/sms.ts'; import type { Sms } from '../src/session/sms.ts';
import type { SmppLog } from '../src/log.ts'; import type { SmppLog } from '../src/log.ts';
import type { SmppServer } from '../src/server/server.ts'; import type { SmppServer } from '../src/server/server.ts';
import type { TestContext } from 'node:test'; import type { TestContext } from 'node:test';
+12 -12
View File
@@ -2,28 +2,28 @@ import assert from 'node:assert/strict';
import net from 'node:net'; import net from 'node:net';
import test, { describe } from 'node:test'; import test, { describe } from 'node:test';
import type { Collected, LostGroup } from '../src/messages/reassembly.ts'; import type { Collected, LostGroup } from '../src/messages/reassembly.ts';
import type { Dlr } from '../src/protocol/receipt.ts'; import type { Dlr } from '../src/protocol/dlr.ts';
import type { ErrorName } from '../src/codec/statuses.ts'; import type { ErrorName } from '../src/codec/errors.ts';
import type { IncomingRequestsOptions } from '../src/session/requests-in.ts'; import type { IncomingRequestsOptions } from '../src/session/incoming-requests.ts';
import type { HeldMessagesOptions, MessageHold } from '../src/session/held-messages.ts'; import type { HeldMessagesOptions, MessageHold } from '../src/session/held-messages.ts';
import type { MessageState } from '../src/codec/constants.ts'; import type { MessageState } from '../src/codec/constants.ts';
import type { MessageDlr } from '../src/session.ts'; import type { MessageDlr } from '../src/session/session.ts';
import type { PduObject, PduObjectInput } from '../src/codec/pdu.ts'; import type { PduObject, PduObjectInput } from '../src/codec/pdu.ts';
import type { Result } from '../src/result.ts'; import type { Result } from '../src/result.ts';
import type { SendSmsResult } from '../src/messages/submit.ts'; import type { SendSmsResult } from '../src/messages/submit.ts';
import type { SmppLog } from '../src/log.ts'; import type { SmppLog } from '../src/log.ts';
import type { Sms } from '../src/sms.ts'; import type { Sms } from '../src/session/sms.ts';
import type { SmppServer } from '../src/server/server.ts'; import type { SmppServer } from '../src/server/server.ts';
import type { TestContext } from 'node:test'; import type { TestContext } from 'node:test';
import { HeldMessages } from '../src/session/held-messages.ts'; import { HeldMessages } from '../src/session/held-messages.ts';
import { IncomingRequests, refusedSegmentStatus } from '../src/session/requests-in.ts'; import { IncomingRequests, refusedSegmentStatus } from '../src/session/incoming-requests.ts';
import { UnansweredError } from '../src/unanswered-error.ts'; import { UnansweredError } from '../src/unanswered-error.ts';
import { createSms } from '../src/sms.ts'; import { createSms } from '../src/session/sms.ts';
import { LinkLife } from '../src/link-life.ts'; import { LinkLife } from '../src/session/link-life.ts';
import { SendWindow } from '../src/session/send-window.ts'; import { SendWindow } from '../src/session/send-window.ts';
import { Reassembler, decodeSegments } from '../src/messages/reassembly.ts'; import { Reassembler, decodeSegments } from '../src/messages/reassembly.ts';
import { Session } from '../src/session.ts'; import { Session } from '../src/session/session.ts';
import { DlrMerger } from '../src/messages/receipt-merge.ts'; import { DlrMerger } from '../src/messages/dlr-merger.ts';
import { PduRefusedError } from '../src/codec/refusal.ts'; import { PduRefusedError } from '../src/codec/refusal.ts';
import { objToPdu } from '../src/codec/pdu.ts'; import { objToPdu } from '../src/codec/pdu.ts';
import { checkSessionOptions, defaults } from '../src/options.ts'; import { checkSessionOptions, defaults } from '../src/options.ts';
@@ -32,8 +32,8 @@ import { client } from '../src/client/client.ts';
import { closeAfter, closeListenerAfter } from './teardown.ts'; import { closeAfter, closeListenerAfter } from './teardown.ts';
import { concatOf } from '../src/protocol/concat.ts'; import { concatOf } from '../src/protocol/concat.ts';
import { consts } from '../src/codec/constants.ts'; import { consts } from '../src/codec/constants.ts';
import { errors } from '../src/codec/statuses.ts'; import { errors } from '../src/codec/errors.ts';
import { paramNumber, paramText } from '../src/codec/field-types.ts'; import { paramNumber, paramText } from '../src/codec/types.ts';
import { server } from '../src/server/server.ts'; import { server } from '../src/server/server.ts';
import { silentLog } from '../src/log.ts'; import { silentLog } from '../src/log.ts';
import { splitMessage } from '../src/message.ts'; import { splitMessage } from '../src/message.ts';
+7 -7
View File
@@ -1,17 +1,17 @@
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import net from 'node:net'; import net from 'node:net';
import test, { describe } from 'node:test'; import test, { describe } from 'node:test';
import type { Dlr } from '../src/protocol/receipt.ts'; import type { Dlr } from '../src/protocol/dlr.ts';
import type { PduObject, PduObjectInput } from '../src/codec/pdu.ts'; import type { PduObject, PduObjectInput } from '../src/codec/pdu.ts';
import type { Sms } from '../src/sms.ts'; import type { Sms } from '../src/session/sms.ts';
import type { ServerOptions, SmppServer } from '../src/server/server.ts'; import type { ServerOptions, SmppServer } from '../src/server/server.ts';
import type { SmppLog } from '../src/log.ts'; import type { SmppLog } from '../src/log.ts';
import type { TestContext } from 'node:test'; import type { TestContext } from 'node:test';
import type { VoidResult } from '../src/result.ts'; import type { VoidResult } from '../src/result.ts';
import { DlrMerger } from '../src/messages/receipt-merge.ts'; import { DlrMerger } from '../src/messages/dlr-merger.ts';
import { PduFramer } from '../src/codec/framer.ts'; import { PduFramer } from '../src/codec/pdu-framer.ts';
import { ReconnectLoop } from '../src/reconnect-loop.ts'; import { ReconnectLoop } from '../src/session/reconnect-loop.ts';
import { Session } from '../src/session.ts'; import { Session } from '../src/session/session.ts';
import { bindCommands } from '../src/protocol/bind.ts'; import { bindCommands } from '../src/protocol/bind.ts';
import { checkSessionOptions } from '../src/options.ts'; import { checkSessionOptions } from '../src/options.ts';
import { client } from '../src/client/client.ts'; import { client } from '../src/client/client.ts';
@@ -19,7 +19,7 @@ import { closeAfter, closeListenerAfter } from './teardown.ts';
import { consts } from '../src/codec/constants.ts'; import { consts } from '../src/codec/constants.ts';
import { PduRefusedError } from '../src/codec/refusal.ts'; import { PduRefusedError } from '../src/codec/refusal.ts';
import { isCommand, objToPdu, pduReturn, pduToObj } from '../src/codec/pdu.ts'; import { isCommand, objToPdu, pduReturn, pduToObj } from '../src/codec/pdu.ts';
import { paramText } from '../src/codec/field-types.ts'; import { paramText } from '../src/codec/types.ts';
import { server } from '../src/server/server.ts'; import { server } from '../src/server/server.ts';
import { bareTlvHeader, pduBytes, shortened, truncatedTlv, withUnknownCmdId } from './raw-pdus.ts'; import { bareTlvHeader, pduBytes, shortened, truncatedTlv, withUnknownCmdId } from './raw-pdus.ts';
import { silentLog } from '../src/log.ts'; import { silentLog } from '../src/log.ts';
+1 -1
View File
@@ -1,7 +1,7 @@
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import net from 'node:net'; import net from 'node:net';
import test, { describe } from 'node:test'; import test, { describe } from 'node:test';
import type { Sms } from '../src/sms.ts'; import type { Sms } from '../src/session/sms.ts';
import type { SmppServer } from '../src/server/server.ts'; import type { SmppServer } from '../src/server/server.ts';
import type { TestContext } from 'node:test'; import type { TestContext } from 'node:test';
import { Log } from '@larvit/log'; import { Log } from '@larvit/log';
+2 -2
View File
@@ -1,7 +1,7 @@
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import test, { describe } from 'node:test'; import test, { describe } from 'node:test';
import type { DestAddress, UnsuccessSme } from '../src/codec/field-types.ts'; import type { DestAddress, UnsuccessSme } from '../src/codec/types.ts';
import { paramText, types } from '../src/codec/field-types.ts'; import { paramText, types } from '../src/codec/types.ts';
import { tlvs } from '../src/codec/tlvs.ts'; import { tlvs } from '../src/codec/tlvs.ts';
describe('integers', () => { describe('integers', () => {
+1 -1
View File
@@ -6,7 +6,7 @@ import { bindToSmsc, dummySmsc } from './dummy-smsc.ts';
import { decodeMessage } from '../src/message.ts'; import { decodeMessage } from '../src/message.ts';
import { messageOctets } from '../src/protocol/message-body.ts'; import { messageOctets } from '../src/protocol/message-body.ts';
import { objToPdu, pduToObj } from '../src/codec/pdu.ts'; import { objToPdu, pduToObj } from '../src/codec/pdu.ts';
import { paramNumber, paramText } from '../src/codec/field-types.ts'; import { paramNumber, paramText } from '../src/codec/types.ts';
import { silentLog } from '../src/log.ts'; import { silentLog } from '../src/log.ts';
import { submitSms } from '../src/messages/submit.ts'; import { submitSms } from '../src/messages/submit.ts';
+17 -4
View File
@@ -230,6 +230,8 @@ to the plan are [plan 3 §8](docs/comprehension-rewrite/plan-3.md#8-architecture
reference counter goes to `SmppClient` in the lifecycle split. reference counter goes to `SmppClient` in the lifecycle split.
- The `gsm7` rename, A6 included: `'ASCII'` becomes `'GSM7'` in every export. - The `gsm7` rename, A6 included: `'ASCII'` becomes `'GSM7'` in every export.
- A test that fails on a spec citation without its sentence. - A test that fails on a spec citation without its sentence.
- Settle where `encodeBody()` and `decodeMessage()` land before splitting `message.ts`: `codec/pdu.ts`
reads them, so a home in `protocol/` is an upward edge.
- [ ] **Build `messages/` on a `BoundedStore` that enforces its own bounds.** Reassembly refuses at its - [ ] **Build `messages/` on a `BoundedStore` that enforces its own bounds.** Reassembly refuses at its
bound instead of evicting, recorded against goals 2 and 4; the receipt merge follows Q8 and its bound instead of evicting, recorded against goals 2 and 4; the receipt merge follows Q8 and its
spent set expires by age. README's bound text is updated. spent set expires by age. README's bound text is updated.
@@ -250,6 +252,17 @@ to the plan are [plan 3 §8](docs/comprehension-rewrite/plan-3.md#8-architecture
### Correctness ### Correctness
- [ ] **Bound a rebind's wait when `responseTimeout` is 0.** `comeBackUp()` arms no timers until the
bind is answered, so an SMSC that takes the TCP connection and never answers leaves
`ReconnectLoop` attempting forever: no `close`, no next attempt. `answering()` already falls
back to the default for held messages; the bind has no such floor. From the 2026-09-30 scoring
run; confirm with a test first.
- [ ] **Type a parsed `short_message` as what the parser puts there.** `parsePdu()` replaces it with
a decoded string wherever no UDH is present, while `PduParams<'submit_sm'>['short_message']`
is `Buffer` and `isCommand()`'s docstring calls the narrowing sound. Public type; from the
2026-09-30 scoring run.
- [ ] **Refuse to open a link that dropped while its rebind was answered.** A peer sending - [ ] **Refuse to open a link that dropped while its rebind was answered.** A peer sending
`bind_resp` and FIN together can tear the link down before `comeBackUp()` resumes; it then `bind_resp` and FIN together can tear the link down before `comeBackUp()` resumes; it then
calls `link.open()` on a `down` link, `resetTimers()` skips, and `attempt()` reports success, calls `link.open()` on a `down` link, `resetTimers()` skips, and `attempt()` reports success,
@@ -336,7 +349,7 @@ to the plan are [plan 3 §8](docs/comprehension-rewrite/plan-3.md#8-architecture
### Shape — 6 today, and the gate is 7 ### Shape — 6 today, and the gate is 7
- [ ] **Answer "is this a bind command" in one place.** `bindCommands` (read by - [ ] **Answer "is this a bind command" in one place.** `bindCommands` (read by
`session/requests-in.ts`, `session/outgoing-requests.ts` and `test/session.test.ts`) and `session/incoming-requests.ts`, `session/outgoing-requests.ts` and `test/session.test.ts`) and
`bindTypeFromCommand()` (read by `server.ts` and `checkedBind()`) each list the three bind `bindTypeFromCommand()` (read by `server.ts` and `checkedBind()`) each list the three bind
commands, so a fourth added to one is missed by the other. Derive the list from the function, commands, so a fourth added to one is missed by the other. Derive the list from the function,
or the reverse. From the stability review of #42. or the reverse. From the stability review of #42.
@@ -442,7 +455,7 @@ to the plan are [plan 3 §8](docs/comprehension-rewrite/plan-3.md#8-architecture
- [ ] **Narrow the `src/codec/` table lint exemption to the four table files.** Its stated reason — "the - [ ] **Narrow the `src/codec/` table lint exemption to the four table files.** Its stated reason — "the
spec tables are data: their length tracks the specification, not any complexity" — is false for spec tables are data: their length tracks the specification, not any complexity" — is false for
`codec/field-types.ts`, which is 595 lines of wire codec with 25 functions and is the file that parses `codec/types.ts`, which is 595 lines of wire codec with 25 functions and is the file that parses
hostile input from the network. It carries more over-budget methods than any other file in the hostile input from the network. It carries more over-budget methods than any other file in the
repo, under a suppression written for something else. repo, under a suppression written for something else.
@@ -500,7 +513,7 @@ to the plan are [plan 3 §8](docs/comprehension-rewrite/plan-3.md#8-architecture
`idleTimeout: '5000'` is refused with `got 5000` — a value the reader reads as correct — where `idleTimeout: '5000'` is refused with `got 5000` — a value the reader reads as correct — where
`connectTimeout` quotes it. `namedValue()`'s four sites — `messagingMode`, `encoding`, the time `connectTimeout` quotes it. `namedValue()`'s four sites — `messagingMode`, `encoding`, the time
options and `smsIdFormat` — are the same defect once more: there `true` and `'true'` both print options and `smsIdFormat` — are the same defect once more: there `true` and `'true'` both print
as `true`. One fix closes all three, and `valueText()` in `codec/field-types.ts` is the quoted as `true`. One fix closes all three, and `valueText()` in `codec/types.ts` is the quoted
spelling to take it from. Raised by review, 2026-09-20. spelling to take it from. Raised by review, 2026-09-20.
- [ ] **Refuse a send the codec cannot build before it waits for a link and a window slot.** Today - [ ] **Refuse a send the codec cannot build before it waits for a link and a window slot.** Today
@@ -537,7 +550,7 @@ to the plan are [plan 3 §8](docs/comprehension-rewrite/plan-3.md#8-architecture
Maintainer's ask, 2026-09-14; not started until asked. Maintainer's ask, 2026-09-14; not started until asked.
- [ ] **Count what is left of a budget one way in `leftOf()` and `LinkLife`.** Today they are one - [ ] **Count what is left of a budget one way in `leftOf()` and `LinkLife`.** Today they are one
concept counted twice. `session/waiting.ts` reads what is left of a budget as `Math.max(1, concept counted twice. `session/idle-waiters.ts` reads what is left of a budget as `Math.max(1,
deadline - now)`, because 0 means "forever" there; `link-life.ts` runs the same subtraction deadline - now)`, because 0 means "forever" there; `link-life.ts` runs the same subtraction
and calls `<= 0` expired. Neither is reachable from the other, so nothing can disagree today, and calls `<= 0` expired. Neither is reachable from the other, so nothing can disagree today,
but a reader who learns one and applies it to the other is wrong. A budget type both take but a reader who learns one and applies it to the other is wrong. A budget type both take