diff --git a/AGENTS.md b/AGENTS.md index 375ace7..bac78a1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -37,59 +37,59 @@ These are not preferences. Breaking one is a defect. ``` src/ - 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, the logger contract, and silentLog — the default - message.ts Encoding detection, splitting, bit counting, SMPP date formatting - 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, and an untyped value as error material: errorFrom(), namedValue(), quoted() - session.ts Session: the socket's life, dispatch, events, and the collaborators in session/ - 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 - commands.ts The 33 commands, their ids and ordered parameter lists - constants.ts consts + constsById, and the version that allows optional parameters - encodings.ts GSM 03.38, LATIN1, UCS2, detection, data_coding resolution - field-types.ts Wire types: int8/int16/int32/string/cstring/buffer/arrays - framer.ts PduFramer: a byte stream cut into complete PDUs - pdu.ts pduToObj / objToPdu / pduReturn — synchronous, result-returning - 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 - statuses.ts errors + errorsById (ESME_*) - tlvs.ts TLV definitions, tlvsById, the typed read and input shapes, and reading and writing a TLV stream - protocol/ What the fields mean - 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 - 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 - 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 - uuid.ts uuidv7() — the ids the library generates for messages - messages/ Whole messages across segments and time + index.ts Public surface. Named exports only, no default export; assembles `defs`. + log.ts SmppLog, silentLog — the default, and guardedLog(): a logger that cannot throw + message.ts Message bodies: encodeBody/decodeMessage under a data_coding, splitting, bit counting, smppDate/smppTime + options.ts SessionOptions, ReconnectOptions, their checks, and `defaults`: every default and internal cap + result.ts Result, and an untyped value as error material: errorFrom(), namedValue(), quoted() + unanswered-error.ts + codec/ Bytes <-> PduObject + commands.ts The 33 commands, their ids and ordered parameter lists + constants.ts consts + constsById, optionalParamsMinVersion, and esm_class's readers: hasUdh(), messageTypeOf() + encodings.ts GSM 03.38, LATIN1, UCS2, detection, data_coding resolution, message class + errors.ts errors + errorsById (ESME_*) + pdu-framer.ts PduFramer + pdu.ts pduToObj / objToPdu / pduReturn — synchronous, result-returning + refusal.ts A PDU the codec would not read, and the answer SMPP names for it + retained-pdu.ts A PDU copied off the wire so holding it pins nothing else, and what holding it costs + 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 + 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 + 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-ids.ts Message ids: the peer's notation, the - a segment gets, which response carries one + 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 + 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 - 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 - session/ One socket's collaborators - 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 + reassembly.ts Reassembler: capped, expiring multipart groups + submit.ts submitSms composition and the submitSmParams builder + 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 + 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 - pending-requests.ts PendingRequests: sequence numbers, correlation, timeout, abort - requests-in.ts IncomingRequests: every request the peer sends: messages, receipts, links, unknown commands - send-window.ts SendWindow: the maxOutstanding semaphore - transport.ts PduTransport: the socket a session reads complete PDUs off - waiting.ts IdleWaiters: waiting for a count to fall to zero, and what is left of a budget - client/client.ts client() -> { err, session } - server/server.ts server() -> { err, server }, server owns the listener + close() + pdu-transport.ts PduTransport: the socket a session reads complete PDUs off + pending-requests.ts PendingRequests: sequence numbers, correlation, timeout, abort + reconnect-loop.ts ReconnectLoop: backoff, retry timer, stopped-ness + send-window.ts SendWindow: the maxOutstanding semaphore + session.ts Session: the socket's life, dispatch and events, composing the rest of session/ + sms.ts The live handle emitted as the 'sms' event (sendResp/sendDlr) + client/client.ts client() -> { err, session } + server/server.ts server() -> { err, server }, server owns the listener + close() ``` -Imports point one way: `codec` ← `protocol` ← `messages` ← `session/` ← `client`/`server`, and the -root files sit beside that order. One edge runs against it: `codec/pdu.ts` reads `message.ts`, which -reads `protocol/udh.ts`, so moving `message.ts` into `protocol/` needs `pdu.ts` off it first. The -ways back up are the `Session` handed to `createSms()`, `HeldMessages` and `IncomingRequests`, which -call back into it, and to `OnRequest` and `onConnected` in `options.ts`, all imported as a type -only. +Imports point one way: `codec` ← `protocol` ← `messages` ← `session` ← `client`/`server`. At the +root, `result.ts`, `log.ts` and `unanswered-error.ts` sit below `codec`, and `message.ts` and +`options.ts` with `protocol`. One edge runs up: `codec/pdu.ts` imports `encodeBody()` and +`decodeMessage()` from `message.ts`. The ways back up are the `Session` handed to `createSms()`, +`HeldMessages` and `IncomingRequests`, which call back into it, and to `OnRequest` and `onConnected` +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 written to and read from the buffer. Never sort those alphabetically — the alphabetical-ordering diff --git a/docs/decisions.md b/docs/decisions.md index 3828d92..034d884 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -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 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 - 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 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 @@ -796,11 +796,10 @@ rule and an index of the titles below. dev image has no openssl. - **`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/`, - `client/`, `server/`, with the [map](../AGENTS.md#architecture) naming the direction. Serves goal - 8's reshapeable internals, which a reader has to find before reshaping: every comprehension panel - navigated by AGENTS.md's map rather than the flat tree it described. Rejected: `src/` flat until a - module has to move for another reason. + with the Locality rewrite; the [map](../AGENTS.md#architecture) names the order and places each + root file in a layer. Serves goal 8: internals are reshapeable only once a reader can find them, + and every comprehension panel navigated by the map. Rejected: `src/` flat until a module has to + move for another reason. Valid while the map is what readers navigate by. - **`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 diff --git a/eslint.config.js b/eslint.config.js index 0b22b9d..5eb123a 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -35,12 +35,12 @@ export default tseslint.config( }, { // 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' }, }, { // 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] }, }, { diff --git a/interop-tests/cloudhopper.test.ts b/interop-tests/cloudhopper.test.ts index 37c3ac7..a31e8e7 100644 --- a/interop-tests/cloudhopper.test.ts +++ b/interop-tests/cloudhopper.test.ts @@ -1,8 +1,8 @@ import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import test, { after, describe } from 'node:test'; -import type { Session } from '../src/session.ts'; -import type { Sms } from '../src/sms.ts'; +import type { Session } from '../src/session/session.ts'; +import type { Sms } from '../src/session/sms.ts'; import type { SmppServer } from '../src/server/server.ts'; import { server } from '../src/server/server.ts'; diff --git a/interop-tests/dumbclient.test.ts b/interop-tests/dumbclient.test.ts index 2edcce9..ba9b82c 100644 --- a/interop-tests/dumbclient.test.ts +++ b/interop-tests/dumbclient.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import test, { after, describe } from 'node:test'; -import type { Session } from '../src/session.ts'; -import type { Sms } from '../src/sms.ts'; +import type { Session } from '../src/session/session.ts'; +import type { Sms } from '../src/session/sms.ts'; import type { LogMethod, SmppLog } from '../src/log.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'); // 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 // 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. diff --git a/interop-tests/jasmin.test.ts b/interop-tests/jasmin.test.ts index a835572..4ee53a0 100644 --- a/interop-tests/jasmin.test.ts +++ b/interop-tests/jasmin.test.ts @@ -1,15 +1,15 @@ import assert from 'node:assert/strict'; import http from 'node:http'; 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 { PduObject } from '../src/codec/pdu.ts'; -import type { Session } from '../src/session.ts'; -import type { Sms } from '../src/sms.ts'; +import type { Session } from '../src/session/session.ts'; +import type { Sms } from '../src/session/sms.ts'; import { ConcatReference } from '../src/protocol/udh.ts'; import { client } from '../src/client/client.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 { encodeMessage, splitMessage } from '../src/message.ts'; import { submitSmParams } from '../src/messages/submit.ts'; diff --git a/interop-tests/jsmpp.test.ts b/interop-tests/jsmpp.test.ts index ed2ba0b..aeefb65 100644 --- a/interop-tests/jsmpp.test.ts +++ b/interop-tests/jsmpp.test.ts @@ -1,8 +1,8 @@ import assert from 'node:assert/strict'; import net from 'node:net'; import test, { after, describe } from 'node:test'; -import type { Session } from '../src/session.ts'; -import type { Sms } from '../src/sms.ts'; +import type { Session } from '../src/session/session.ts'; +import type { Sms } from '../src/session/sms.ts'; import { PduRefusedError } from '../src/index.ts'; import { bareTlvHeader, pduBytes } from '../test/raw-pdus.ts'; import { server } from '../src/server/server.ts'; diff --git a/interop-tests/kannel.test.ts b/interop-tests/kannel.test.ts index 4ce96be..f82e065 100644 --- a/interop-tests/kannel.test.ts +++ b/interop-tests/kannel.test.ts @@ -2,13 +2,13 @@ import assert from 'node:assert/strict'; import http from 'node:http'; import test, { after, describe } from 'node:test'; import type { MessageState } from '../src/codec/constants.ts'; -import type { Dlr } from '../src/protocol/receipt.ts'; -import type { Session } from '../src/session.ts'; -import type { Sms } from '../src/sms.ts'; +import type { Dlr } from '../src/protocol/dlr.ts'; +import type { Session } from '../src/session/session.ts'; +import type { Sms } from '../src/session/sms.ts'; import { ConcatReference } from '../src/protocol/udh.ts'; import { consts } from '../src/codec/constants.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 { splitMessage } from '../src/message.ts'; import { submitSmParams } from '../src/messages/submit.ts'; diff --git a/interop-tests/php.test.ts b/interop-tests/php.test.ts index 761f138..0c08623 100644 --- a/interop-tests/php.test.ts +++ b/interop-tests/php.test.ts @@ -1,8 +1,8 @@ import assert from 'node:assert/strict'; import test, { after, describe } from 'node:test'; -import type { Session } from '../src/session.ts'; -import type { Sms } from '../src/sms.ts'; -import { paramText } from '../src/codec/field-types.ts'; +import type { Session } from '../src/session/session.ts'; +import type { Sms } from '../src/session/sms.ts'; +import { paramText } from '../src/codec/types.ts'; import { isCommand, server } from '../src/index.ts'; const DRIVER = process.env.PHP_DRIVER ?? 'php:8080'; diff --git a/interop-tests/python.test.ts b/interop-tests/python.test.ts index 138b897..6ed20ee 100644 --- a/interop-tests/python.test.ts +++ b/interop-tests/python.test.ts @@ -1,9 +1,9 @@ import assert from 'node:assert/strict'; import test, { after, describe } from 'node:test'; -import type { Session } from '../src/session.ts'; -import type { Sms } from '../src/sms.ts'; +import type { Session } from '../src/session/session.ts'; +import type { Sms } from '../src/session/sms.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'; const DRIVER = process.env.PYTHON_DRIVER ?? 'python:8080'; diff --git a/interop-tests/smppload.test.ts b/interop-tests/smppload.test.ts index a8ebe1b..b35add5 100644 --- a/interop-tests/smppload.test.ts +++ b/interop-tests/smppload.test.ts @@ -1,6 +1,6 @@ import assert from 'node:assert/strict'; 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'; const SMPP_PORT = Number(process.env.SMPP_PORT ?? '2775'); diff --git a/interop-tests/smppsim.test.ts b/interop-tests/smppsim.test.ts index 141eda3..169ad22 100644 --- a/interop-tests/smppsim.test.ts +++ b/interop-tests/smppsim.test.ts @@ -1,15 +1,15 @@ import assert from 'node:assert/strict'; 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 { 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 { Session } from '../src/session.ts'; -import type { Sms } from '../src/sms.ts'; +import type { Session } from '../src/session/session.ts'; +import type { Sms } from '../src/session/sms.ts'; import { client } from '../src/client/client.ts'; import { closeAfter } from '../test/teardown.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'; const PEER_HOST = process.env.PEER_HOST ?? 'smppsim'; diff --git a/interop-tests/smscsim.test.ts b/interop-tests/smscsim.test.ts index 35bbb0f..228bc23 100644 --- a/interop-tests/smscsim.test.ts +++ b/interop-tests/smscsim.test.ts @@ -1,8 +1,8 @@ import assert from 'node:assert/strict'; import test, { describe } from 'node:test'; -import type { Dlr } from '../src/protocol/receipt.ts'; -import type { Session } from '../src/session.ts'; -import type { Sms } from '../src/sms.ts'; +import type { Dlr } from '../src/protocol/dlr.ts'; +import type { Session } from '../src/session/session.ts'; +import type { Sms } from '../src/session/sms.ts'; import { client } from '../src/client/client.ts'; import { closeAfter } from '../test/teardown.ts'; diff --git a/src/client/client.ts b/src/client/client.ts index 4243441..046e3f4 100644 --- a/src/client/client.ts +++ b/src/client/client.ts @@ -7,8 +7,8 @@ import type { SmsIdFormat } from '../protocol/message-ids.ts'; import type { Socket } from 'node:net'; export type { BindType }; -import { ReconnectLoop } from '../reconnect-loop.ts'; -import { Session } from '../session.ts'; +import { ReconnectLoop } from '../session/reconnect-loop.ts'; +import { Session } from '../session/session.ts'; import { checkSessionOptions, defaults } from '../options.ts'; import { connect as netConnect } from 'node:net'; import { connect as tlsConnect } from 'node:tls'; diff --git a/src/codec/commands.ts b/src/codec/commands.ts index 1be9a60..13ebf82 100644 --- a/src/codec/commands.ts +++ b/src/codec/commands.ts @@ -1,5 +1,5 @@ -import type { WireType } from './field-types.ts'; -import { buffer, cstring, dest_address_array, int8, unsuccess_sme_array } from './field-types.ts'; +import type { WireType } from './types.ts'; +import { buffer, cstring, dest_address_array, int8, unsuccess_sme_array } from './types.ts'; type CommandSpec = { id: number; diff --git a/src/codec/statuses.ts b/src/codec/errors.ts similarity index 100% rename from src/codec/statuses.ts rename to src/codec/errors.ts diff --git a/src/codec/framer.ts b/src/codec/pdu-framer.ts similarity index 100% rename from src/codec/framer.ts rename to src/codec/pdu-framer.ts diff --git a/src/codec/pdu.ts b/src/codec/pdu.ts index b27c7cc..8d97194 100644 --- a/src/codec/pdu.ts +++ b/src/codec/pdu.ts @@ -1,6 +1,6 @@ import type { CommandDefinition, CommandName, PduParams, PduParamsInput } from './commands.ts'; -import type { ErrorName } from './statuses.ts'; -import type { ParamValue } from './field-types.ts'; +import type { ErrorName } from './errors.ts'; +import type { ParamValue } from './types.ts'; import type { PduHeader } from './refusal.ts'; import type { Result, VoidResult } from '../result.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 { hasUdh } from './constants.ts'; import { decodeMessage, encodeBody } from '../message.ts'; -import { errorNameById, errors, isErrorName } from './statuses.ts'; -import { paramNumber, valueText } from './field-types.ts'; +import { errorNameById, errors, isErrorName } from './errors.ts'; +import { paramNumber, valueText } from './types.ts'; import { parseTlvs, writeTlvs } from './tlvs.ts'; /** The highest sequence number this library hands out; SMPP 3.4 4.7.1 reserves 0x7fffffff. */ diff --git a/src/codec/refusal.ts b/src/codec/refusal.ts index 317b69d..233503b 100644 --- a/src/codec/refusal.ts +++ b/src/codec/refusal.ts @@ -1,5 +1,5 @@ import type { CommandName } from './commands.ts'; -import type { ErrorName } from './statuses.ts'; +import type { ErrorName } from './errors.ts'; import { respNameFor } from './commands.ts'; /** A hostile peer must not be able to make us allocate arbitrarily. */ diff --git a/src/codec/retained.ts b/src/codec/retained-pdu.ts similarity index 94% rename from src/codec/retained.ts rename to src/codec/retained-pdu.ts index 9fda3cc..36c670d 100644 --- a/src/codec/retained.ts +++ b/src/codec/retained-pdu.ts @@ -1,6 +1,6 @@ -import type { ParamValue } from './field-types.ts'; +import type { ParamValue } from './types.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. */ export function detach(pduObj: PduObject): PduObject { diff --git a/src/codec/tlvs.ts b/src/codec/tlvs.ts index d54d57e..fc4d6b0 100644 --- a/src/codec/tlvs.ts +++ b/src/codec/tlvs.ts @@ -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 { 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. */ type Definition = { id: number; multiple?: false; tag: Tag; type: WireType } diff --git a/src/codec/field-types.ts b/src/codec/types.ts similarity index 100% rename from src/codec/field-types.ts rename to src/codec/types.ts diff --git a/src/index.ts b/src/index.ts index 80ca7d8..623b60f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,20 +1,20 @@ import { cmds, cmdsById } from './codec/commands.ts'; import { consts, constsById } from './codec/constants.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 { types } from './codec/field-types.ts'; +import { types } from './codec/types.ts'; export { client } from './client/client.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 { consts, constsById } from './codec/constants.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 { types } from './codec/field-types.ts'; +export { types } from './codec/types.ts'; export { isCommand, @@ -36,16 +36,16 @@ export { splitMessage, } 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 { concatOf } from './protocol/concat.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 type { BindType, ClientOptions } from './client/client.ts'; -export type { Dlr, Receipt } from './protocol/receipt.ts'; -export type { SendDlrResult, SendRespOptions, Sms } from './sms.ts'; +export type { Dlr, Receipt } from './protocol/dlr.ts'; +export type { SendDlrResult, SendRespOptions, Sms } from './session/sms.ts'; export type { Concat } from './protocol/concat.ts'; export type { ConcatInfo } from './protocol/udh.ts'; export type { Result, VoidResult } from './result.ts'; @@ -66,16 +66,16 @@ export type { SendSmsResult, SessionEvents, SessionOptions, -} from './session.ts'; +} from './session/session.ts'; export type { CommandName, PduParams, PduParamsInput } from './codec/commands.ts'; export type { ConstGroup, MessageState, SubmitMessagingMode } from './codec/constants.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 { PduHeader } from './codec/refusal.ts'; export type { SplitOptions } from './message.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. */ export const defs = { diff --git a/src/messages/receipt-merge.ts b/src/messages/dlr-merger.ts similarity index 99% rename from src/messages/receipt-merge.ts rename to src/messages/dlr-merger.ts index 541ecd7..0b85fe7 100644 --- a/src/messages/receipt-merge.ts +++ b/src/messages/dlr-merger.ts @@ -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 { SmppLog } from '../log.ts'; import { ExpiringGroups } from './expiring-groups.ts'; diff --git a/src/messages/reassembly.ts b/src/messages/reassembly.ts index 97c73ff..f9e13f4 100644 --- a/src/messages/reassembly.ts +++ b/src/messages/reassembly.ts @@ -4,9 +4,9 @@ import type { SmppLog } from '../log.ts'; import { ExpiringGroups } from './expiring-groups.ts'; import { decodeMessage } from '../message.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 { paramNumber, paramText } from '../codec/field-types.ts'; +import { paramNumber, paramText } from '../codec/types.ts'; import { uuidv7 } from '../protocol/uuid.ts'; /** A concatenated message given up on, whose segments the peer has already been answered for. */ diff --git a/src/messages/submit.ts b/src/messages/submit.ts index 4a65858..4382f13 100644 --- a/src/messages/submit.ts +++ b/src/messages/submit.ts @@ -1,5 +1,5 @@ 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 { PduObject, PduObjectInput } from '../codec/pdu.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 { UnansweredError } from '../unanswered-error.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 { namedValue } from '../result.ts'; import { normaliseSmsId } from '../protocol/message-ids.ts'; diff --git a/src/options.ts b/src/options.ts index 79e28a3..f856cf0 100644 --- a/src/options.ts +++ b/src/options.ts @@ -1,6 +1,6 @@ import type { PduObject } from './codec/pdu.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 { SmsIdFormat } from './protocol/message-ids.ts'; import type { Socket } from 'node:net'; diff --git a/src/protocol/concat.ts b/src/protocol/concat.ts index 3aa021d..9932323 100644 --- a/src/protocol/concat.ts +++ b/src/protocol/concat.ts @@ -3,7 +3,7 @@ import type { PduObject } from '../codec/pdu.ts'; import { concatInfo } from './udh.ts'; import { hasUdh } from '../codec/constants.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. */ export type Concat = ConcatInfo & { diff --git a/src/protocol/receipt.ts b/src/protocol/dlr.ts similarity index 98% rename from src/protocol/receipt.ts rename to src/protocol/dlr.ts index 7b85584..7782f53 100644 --- a/src/protocol/receipt.ts +++ b/src/protocol/dlr.ts @@ -1,12 +1,12 @@ 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 { SmsIdFormat } from './message-ids.ts'; import { consts, constsById, hasUdh, messageTypeOf } from '../codec/constants.ts'; import { encodings } from '../codec/encodings.ts'; import { messageOctets } from './message-body.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'; /** diff --git a/src/protocol/message-ids.ts b/src/protocol/message-ids.ts index 047dea1..b4440d9 100644 --- a/src/protocol/message-ids.ts +++ b/src/protocol/message-ids.ts @@ -1,5 +1,5 @@ import type { CommandName } from '../codec/commands.ts'; -import type { ParamValue } from '../codec/field-types.ts'; +import type { ParamValue } from '../codec/types.ts'; const notations = { decimal: { digits: /^[0-9]+$/, prefix: '' }, diff --git a/src/server/server.ts b/src/server/server.ts index 2aa4f1f..edca63f 100644 --- a/src/server/server.ts +++ b/src/server/server.ts @@ -6,13 +6,13 @@ import type { Server as NetServer, Socket } from 'node:net'; import type { Server as TlsServer, TlsOptions } from 'node:tls'; import type { SmppLog } from '../log.ts'; import { EventEmitter } from 'node:events'; -import { Session } from '../session.ts'; +import { Session } from '../session/session.ts'; import { bindTypeFromCommand } from '../protocol/bind.ts'; import { checkSessionOptions, defaults } from '../options.ts'; import { createServer as createNetServer } from 'node:net'; import { createServer as createTlsServer } from 'node:tls'; import { errorFrom } from '../result.ts'; -import { paramText } from '../codec/field-types.ts'; +import { paramText } from '../codec/types.ts'; import { guardedLog } from '../log.ts'; import { respNameFor } from '../codec/commands.ts'; diff --git a/src/session/held-messages.ts b/src/session/held-messages.ts index 517472e..eb52310 100644 --- a/src/session/held-messages.ts +++ b/src/session/held-messages.ts @@ -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 { Result } from '../result.ts'; -import type { Session } from '../session.ts'; -import type { SmsHandlers } from '../sms.ts'; +import type { Session } from './session.ts'; +import type { SmsHandlers } from './sms.ts'; import type { SmppLog } from '../log.ts'; import { ExpiringGroups } from '../messages/expiring-groups.ts'; -import { IdleWaiters } from './waiting.ts'; -import { createSms } from '../sms.ts'; -import { retainedOctets } from '../codec/retained.ts'; +import { IdleWaiters } from './idle-waiters.ts'; +import { createSms } from './sms.ts'; +import { retainedOctets } from '../codec/retained-pdu.ts'; export type HeldMessagesOptions = { link: LinkLife; diff --git a/src/session/waiting.ts b/src/session/idle-waiters.ts similarity index 100% rename from src/session/waiting.ts rename to src/session/idle-waiters.ts diff --git a/src/session/requests-in.ts b/src/session/incoming-requests.ts similarity index 96% rename from src/session/requests-in.ts rename to src/session/incoming-requests.ts index 73e1b22..153dd01 100644 --- a/src/session/requests-in.ts +++ b/src/session/incoming-requests.ts @@ -1,13 +1,13 @@ import type { Concat } from '../protocol/concat.ts'; -import type { DlrMerger } from '../messages/receipt-merge.ts'; -import type { ErrorName } from '../codec/statuses.ts'; +import type { DlrMerger } from '../messages/dlr-merger.ts'; +import type { ErrorName } from '../codec/errors.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 { OnRequest } from '../options.ts'; import type { PduObject } from '../codec/pdu.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 { SmsIdFormat } from '../protocol/message-ids.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 { defaults } from '../options.ts'; import { concatOf } from '../protocol/concat.ts'; -import { detach } from '../codec/retained.ts'; -import { dlrFromPdu } from '../protocol/receipt.ts'; +import { detach } from '../codec/retained-pdu.ts'; +import { dlrFromPdu } from '../protocol/dlr.ts'; import { respIdParams, segmentId } from '../protocol/message-ids.ts'; import { respNameFor } from '../codec/commands.ts'; diff --git a/src/link-life.ts b/src/session/link-life.ts similarity index 98% rename from src/link-life.ts rename to src/session/link-life.ts index f44f2ea..6b42559 100644 --- a/src/link-life.ts +++ b/src/session/link-life.ts @@ -1,5 +1,5 @@ -import type { SmppLog } from './log.ts'; -import type { VoidResult } from './result.ts'; +import type { SmppLog } from '../log.ts'; +import type { VoidResult } from '../result.ts'; export type LinkLifeOptions = { log: SmppLog; diff --git a/src/session/keepalive.ts b/src/session/link-timers.ts similarity index 100% rename from src/session/keepalive.ts rename to src/session/link-timers.ts diff --git a/src/session/outgoing-requests.ts b/src/session/outgoing-requests.ts index 429834e..2dede98 100644 --- a/src/session/outgoing-requests.ts +++ b/src/session/outgoing-requests.ts @@ -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 { PduTransport } from './transport.ts'; +import type { PduTransport } from './pdu-transport.ts'; import type { Result, VoidResult } from '../result.ts'; import type { SendOptions } from '../options.ts'; import type { SmppLog } from '../log.ts'; diff --git a/src/session/transport.ts b/src/session/pdu-transport.ts similarity index 98% rename from src/session/transport.ts rename to src/session/pdu-transport.ts index e453c0c..df1b5de 100644 --- a/src/session/transport.ts +++ b/src/session/pdu-transport.ts @@ -2,7 +2,7 @@ import type { PduObject } from '../codec/pdu.ts'; import type { SmppLog } from '../log.ts'; import type { Socket } from 'node:net'; 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 { pduToObj } from '../codec/pdu.ts'; diff --git a/src/reconnect-loop.ts b/src/session/reconnect-loop.ts similarity index 96% rename from src/reconnect-loop.ts rename to src/session/reconnect-loop.ts index 52a3c92..19dd79a 100644 --- a/src/reconnect-loop.ts +++ b/src/session/reconnect-loop.ts @@ -1,7 +1,7 @@ -import type { Result, VoidResult } from './result.ts'; -import type { SmppLog } from './log.ts'; +import type { Result, VoidResult } from '../result.ts'; +import type { SmppLog } from '../log.ts'; import type { Socket } from 'node:net'; -import { defaults } from './options.ts'; +import { defaults } from '../options.ts'; export type ReconnectLoopOptions = { connect: () => Promise>; diff --git a/src/session/send-window.ts b/src/session/send-window.ts index 3eabe8f..033a746 100644 --- a/src/session/send-window.ts +++ b/src/session/send-window.ts @@ -1,6 +1,6 @@ import type { SmppLog } from '../log.ts'; import type { VoidResult } from '../result.ts'; -import { IdleWaiters } from './waiting.ts'; +import { IdleWaiters } from './idle-waiters.ts'; export type SendWindowOptions = { limit: number; diff --git a/src/session.ts b/src/session/session.ts similarity index 90% rename from src/session.ts rename to src/session/session.ts index c74e902..326d3dc 100644 --- a/src/session.ts +++ b/src/session/session.ts @@ -1,34 +1,34 @@ -import type { Dlr } from './protocol/receipt.ts'; -import type { ErrorName } from './codec/statuses.ts'; -import type { MessageDlr } from './messages/receipt-merge.ts'; -import type { ParamValue } from './codec/field-types.ts'; -import type { PduObject, PduObjectInput, TlvInputs } from './codec/pdu.ts'; -import type { PduRefusedError } from './codec/refusal.ts'; -import type { BindType, LinkEnd, SessionBind } from './protocol/bind.ts'; -import type { CloseOptions, ReconnectOptions, SendOptions, SessionOptions } from './options.ts'; -import type { Result, VoidResult } from './result.ts'; -import type { SendSmsOptions, SendSmsResult } from './messages/submit.ts'; -import type { SmppLog } from './log.ts'; +import type { Dlr } from '../protocol/dlr.ts'; +import type { ErrorName } from '../codec/errors.ts'; +import type { MessageDlr } from '../messages/dlr-merger.ts'; +import type { ParamValue } from '../codec/types.ts'; +import type { PduObject, PduObjectInput, TlvInputs } from '../codec/pdu.ts'; +import type { PduRefusedError } from '../codec/refusal.ts'; +import type { BindType, LinkEnd, SessionBind } from '../protocol/bind.ts'; +import type { CloseOptions, ReconnectOptions, SendOptions, SessionOptions } from '../options.ts'; +import type { Result, VoidResult } from '../result.ts'; +import type { SendSmsOptions, SendSmsResult } from '../messages/submit.ts'; +import type { SmppLog } from '../log.ts'; import type { Sms } from './sms.ts'; 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 { IncomingRequests } from './session/requests-in.ts'; +import { IncomingRequests } from './incoming-requests.ts'; import { LinkLife } from './link-life.ts'; -import { LinkTimers } from './session/keepalive.ts'; -import { OutgoingRequests } from './session/outgoing-requests.ts'; -import { PduTransport } from './session/transport.ts'; +import { LinkTimers } from './link-timers.ts'; +import { OutgoingRequests } from './outgoing-requests.ts'; +import { PduTransport } from './pdu-transport.ts'; import { ReconnectLoop } from './reconnect-loop.ts'; -import { leftOf } from './session/waiting.ts'; -import { errorFrom } from './result.ts'; -import { optionalParamsMinVersion } from './codec/constants.ts'; -import { bindCarries, checkedBind } from './protocol/bind.ts'; -import { defaults } from './options.ts'; -import { isResp, objToPdu, pduReturn } from './codec/pdu.ts'; -import { refusalAnswer } from './codec/refusal.ts'; -import { guardedLog } from './log.ts'; -import { submitSms, unsent } from './messages/submit.ts'; -import { ConcatReference } from './protocol/udh.ts'; +import { leftOf } from './idle-waiters.ts'; +import { errorFrom } from '../result.ts'; +import { optionalParamsMinVersion } from '../codec/constants.ts'; +import { bindCarries, checkedBind } from '../protocol/bind.ts'; +import { defaults } from '../options.ts'; +import { isResp, objToPdu, pduReturn } from '../codec/pdu.ts'; +import { refusalAnswer } from '../codec/refusal.ts'; +import { guardedLog } from '../log.ts'; +import { submitSms, unsent } from '../messages/submit.ts'; +import { ConcatReference } from '../protocol/udh.ts'; export type { CloseOptions, diff --git a/src/sms.ts b/src/session/sms.ts similarity index 90% rename from src/sms.ts rename to src/session/sms.ts index aadcab6..2270f72 100644 --- a/src/sms.ts +++ b/src/session/sms.ts @@ -1,17 +1,17 @@ -import type { ErrorName } from './codec/statuses.ts'; -import type { MessageState } from './codec/constants.ts'; -import type { PduObject, PduObjectInput, TlvInputs } from './codec/pdu.ts'; -import type { Result, VoidResult } from './result.ts'; +import type { ErrorName } from '../codec/errors.ts'; +import type { MessageState } from '../codec/constants.ts'; +import type { PduObject, PduObjectInput, TlvInputs } from '../codec/pdu.ts'; +import type { Result, VoidResult } from '../result.ts'; import type { Session } from './session.ts'; -import { UnansweredError } from './unanswered-error.ts'; -import { consts } from './codec/constants.ts'; -import { decodeSegments } from './messages/reassembly.ts'; -import { messageClassOf } from './codec/encodings.ts'; -import { paramText } from './codec/field-types.ts'; -import { receiptCodes, transientStates } from './protocol/receipt.ts'; -import { smppDate } from './message.ts'; -import { respIdParams, segmentId } from './protocol/message-ids.ts'; -import { uuidv7 } from './protocol/uuid.ts'; +import { UnansweredError } from '../unanswered-error.ts'; +import { consts } from '../codec/constants.ts'; +import { decodeSegments } from '../messages/reassembly.ts'; +import { messageClassOf } from '../codec/encodings.ts'; +import { paramText } from '../codec/types.ts'; +import { receiptCodes, transientStates } from '../protocol/dlr.ts'; +import { smppDate } from '../message.ts'; +import { respIdParams, segmentId } from '../protocol/message-ids.ts'; +import { uuidv7 } from '../protocol/uuid.ts'; /** `pduObjs` holds what the peer took, so a partial failure names what is already receipted. */ export type SendDlrResult = { diff --git a/test/declared-alphabet.test.ts b/test/declared-alphabet.test.ts index 33bf704..66481aa 100644 --- a/test/declared-alphabet.test.ts +++ b/test/declared-alphabet.test.ts @@ -5,10 +5,10 @@ import { client } from '../src/client/client.ts'; import { closeAfter } from './teardown.ts'; import { consts } from '../src/codec/constants.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 { 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 type { PduObject } from '../src/codec/pdu.ts'; diff --git a/test/dlr.test.ts b/test/dlr.test.ts index 0dfa471..b48540a 100644 --- a/test/dlr.test.ts +++ b/test/dlr.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import test, { describe } from 'node:test'; 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 { objToPdu, pduToObj } from '../src/codec/pdu.ts'; import type { PduObject, TlvInputs } from '../src/codec/pdu.ts'; diff --git a/test/dummy-smsc.ts b/test/dummy-smsc.ts index 2a12f82..6f6d9af 100644 --- a/test/dummy-smsc.ts +++ b/test/dummy-smsc.ts @@ -1,8 +1,8 @@ import assert from 'node:assert/strict'; 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 { PduFramer } from '../src/codec/framer.ts'; +import { PduFramer } from '../src/codec/pdu-framer.ts'; import { client } from '../src/client/client.ts'; import { closeAfter, closeListenerAfter } from './teardown.ts'; import { consts } from '../src/codec/constants.ts'; diff --git a/test/interop.test.ts b/test/interop.test.ts index d2638f8..7e658c2 100644 --- a/test/interop.test.ts +++ b/test/interop.test.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import test, { describe } from 'node:test'; import reference 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 { closeAfter } from './teardown.ts'; import { concatInfo } from '../src/protocol/udh.ts'; diff --git a/test/message-class.test.ts b/test/message-class.test.ts index 9d0d4a5..6b3ed7c 100644 --- a/test/message-class.test.ts +++ b/test/message-class.test.ts @@ -2,14 +2,14 @@ import assert from 'node:assert/strict'; import test, { describe } from 'node:test'; import type { PduObjectInput } from '../src/codec/pdu.ts'; import type { SendSmsDeps } from '../src/messages/submit.ts'; -import type { Session } from '../src/session.ts'; -import type { Sms } from '../src/sms.ts'; +import type { Session } from '../src/session/session.ts'; +import type { Sms } from '../src/session/sms.ts'; import type { TestContext } from 'node:test'; import { bindToSmsc, dummySmsc } from './dummy-smsc.ts'; import { client } from '../src/client/client.ts'; import { closeAfter } from './teardown.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 { server } from '../src/server/server.ts'; import { silentLog } from '../src/log.ts'; diff --git a/test/messaging-mode.test.ts b/test/messaging-mode.test.ts index 4b97e3f..fd0b1d7 100644 --- a/test/messaging-mode.test.ts +++ b/test/messaging-mode.test.ts @@ -2,12 +2,12 @@ import assert from 'node:assert/strict'; import test, { describe } from 'node:test'; import type { PduObjectInput } from '../src/codec/pdu.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 { TestContext } from 'node:test'; import { bindToSmsc, dummySmsc } from './dummy-smsc.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 { silentLog } from '../src/log.ts'; import { submitSms } from '../src/messages/submit.ts'; diff --git a/test/operator-receipts.test.ts b/test/operator-receipts.test.ts index 03d3bb3..c02ae29 100644 --- a/test/operator-receipts.test.ts +++ b/test/operator-receipts.test.ts @@ -1,11 +1,11 @@ import assert from 'node:assert/strict'; import test, { describe } from 'node:test'; -import type { Dlr, Receipt } from '../src/protocol/receipt.ts'; -import type { MessageDlr } from '../src/session.ts'; +import type { Dlr, Receipt } from '../src/protocol/dlr.ts'; +import type { MessageDlr } from '../src/session/session.ts'; import type { PduObject, TlvInputs } from '../src/codec/pdu.ts'; import { bindToSmsc, dummySmsc } from './dummy-smsc.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'; /** diff --git a/test/pdu-framer.test.ts b/test/pdu-framer.test.ts index 3bafb85..fa4d538 100644 --- a/test/pdu-framer.test.ts +++ b/test/pdu-framer.test.ts @@ -1,6 +1,6 @@ import assert from 'node:assert/strict'; 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'; function pdu(seqNr: number): Buffer { diff --git a/test/pdu.test.ts b/test/pdu.test.ts index c363efc..73179a2 100644 --- a/test/pdu.test.ts +++ b/test/pdu.test.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import test, { describe } from 'node:test'; import { PduRefusedError, refusalAnswer } from '../src/codec/refusal.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'; function encode(...args: Parameters): Buffer { diff --git a/test/readme.test.ts b/test/readme.test.ts index 1cb446b..5853bd9 100644 --- a/test/readme.test.ts +++ b/test/readme.test.ts @@ -1,8 +1,8 @@ import assert from 'node:assert/strict'; import test, { describe } from 'node:test'; -import type { Dlr } from '../src/protocol/receipt.ts'; -import type { Session } from '../src/session.ts'; -import type { Sms } from '../src/sms.ts'; +import type { Dlr } from '../src/protocol/dlr.ts'; +import type { Session } from '../src/session/session.ts'; +import type { Sms } from '../src/session/sms.ts'; import type { SmppLog } from '../src/log.ts'; import type { SmppServer } from '../src/server/server.ts'; import type { TestContext } from 'node:test'; diff --git a/test/session-extras.test.ts b/test/session-extras.test.ts index e362ef2..530b373 100644 --- a/test/session-extras.test.ts +++ b/test/session-extras.test.ts @@ -2,28 +2,28 @@ import assert from 'node:assert/strict'; import net from 'node:net'; import test, { describe } from 'node:test'; import type { Collected, LostGroup } from '../src/messages/reassembly.ts'; -import type { Dlr } from '../src/protocol/receipt.ts'; -import type { ErrorName } from '../src/codec/statuses.ts'; -import type { IncomingRequestsOptions } from '../src/session/requests-in.ts'; +import type { Dlr } from '../src/protocol/dlr.ts'; +import type { ErrorName } from '../src/codec/errors.ts'; +import type { IncomingRequestsOptions } from '../src/session/incoming-requests.ts'; import type { HeldMessagesOptions, MessageHold } from '../src/session/held-messages.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 { Result } from '../src/result.ts'; import type { SendSmsResult } from '../src/messages/submit.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 { TestContext } from 'node:test'; 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 { createSms } from '../src/sms.ts'; -import { LinkLife } from '../src/link-life.ts'; +import { createSms } from '../src/session/sms.ts'; +import { LinkLife } from '../src/session/link-life.ts'; import { SendWindow } from '../src/session/send-window.ts'; import { Reassembler, decodeSegments } from '../src/messages/reassembly.ts'; -import { Session } from '../src/session.ts'; -import { DlrMerger } from '../src/messages/receipt-merge.ts'; +import { Session } from '../src/session/session.ts'; +import { DlrMerger } from '../src/messages/dlr-merger.ts'; import { PduRefusedError } from '../src/codec/refusal.ts'; import { objToPdu } from '../src/codec/pdu.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 { concatOf } from '../src/protocol/concat.ts'; import { consts } from '../src/codec/constants.ts'; -import { errors } from '../src/codec/statuses.ts'; -import { paramNumber, paramText } from '../src/codec/field-types.ts'; +import { errors } from '../src/codec/errors.ts'; +import { paramNumber, paramText } from '../src/codec/types.ts'; import { server } from '../src/server/server.ts'; import { silentLog } from '../src/log.ts'; import { splitMessage } from '../src/message.ts'; diff --git a/test/session.test.ts b/test/session.test.ts index ee84322..30dccff 100644 --- a/test/session.test.ts +++ b/test/session.test.ts @@ -1,17 +1,17 @@ import assert from 'node:assert/strict'; import net from 'node:net'; 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 { Sms } from '../src/sms.ts'; +import type { Sms } from '../src/session/sms.ts'; import type { ServerOptions, SmppServer } from '../src/server/server.ts'; import type { SmppLog } from '../src/log.ts'; import type { TestContext } from 'node:test'; import type { VoidResult } from '../src/result.ts'; -import { DlrMerger } from '../src/messages/receipt-merge.ts'; -import { PduFramer } from '../src/codec/framer.ts'; -import { ReconnectLoop } from '../src/reconnect-loop.ts'; -import { Session } from '../src/session.ts'; +import { DlrMerger } from '../src/messages/dlr-merger.ts'; +import { PduFramer } from '../src/codec/pdu-framer.ts'; +import { ReconnectLoop } from '../src/session/reconnect-loop.ts'; +import { Session } from '../src/session/session.ts'; import { bindCommands } from '../src/protocol/bind.ts'; import { checkSessionOptions } from '../src/options.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 { PduRefusedError } from '../src/codec/refusal.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 { bareTlvHeader, pduBytes, shortened, truncatedTlv, withUnknownCmdId } from './raw-pdus.ts'; import { silentLog } from '../src/log.ts'; diff --git a/test/tls.test.ts b/test/tls.test.ts index 056f93b..c65ea4b 100644 --- a/test/tls.test.ts +++ b/test/tls.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import net from 'node:net'; 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 { TestContext } from 'node:test'; import { Log } from '@larvit/log'; diff --git a/test/types.test.ts b/test/types.test.ts index aec5399..b8c329a 100644 --- a/test/types.test.ts +++ b/test/types.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import test, { describe } from 'node:test'; -import type { DestAddress, UnsuccessSme } from '../src/codec/field-types.ts'; -import { paramText, types } from '../src/codec/field-types.ts'; +import type { DestAddress, UnsuccessSme } from '../src/codec/types.ts'; +import { paramText, types } from '../src/codec/types.ts'; import { tlvs } from '../src/codec/tlvs.ts'; describe('integers', () => { diff --git a/test/unsendable.test.ts b/test/unsendable.test.ts index d7cbb67..a9bacc2 100644 --- a/test/unsendable.test.ts +++ b/test/unsendable.test.ts @@ -6,7 +6,7 @@ import { bindToSmsc, dummySmsc } from './dummy-smsc.ts'; import { decodeMessage } from '../src/message.ts'; import { messageOctets } from '../src/protocol/message-body.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 { submitSms } from '../src/messages/submit.ts'; diff --git a/todo.md b/todo.md index f73b491..58deb96 100644 --- a/todo.md +++ b/todo.md @@ -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. - The `gsm7` rename, A6 included: `'ASCII'` becomes `'GSM7'` in every export. - 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 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. @@ -250,6 +252,17 @@ to the plan are [plan 3 §8](docs/comprehension-rewrite/plan-3.md#8-architecture ### 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 `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, @@ -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 - [ ] **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 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. @@ -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 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 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 `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 - 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. - [ ] **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. - [ ] **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 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