From b2945f011dfed66c069c03eabf1bc33ea2849a75 Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Tue, 29 Sep 2026 11:05:59 +0200 Subject: [PATCH] Derive every Sms field in createSms() --- src/held-messages.ts | 26 ++++++++------------------ src/sms.ts | 11 +++++------ test/session-extras.test.ts | 10 ++-------- 3 files changed, 15 insertions(+), 32 deletions(-) diff --git a/src/held-messages.ts b/src/held-messages.ts index a67f82d..5346b95 100644 --- a/src/held-messages.ts +++ b/src/held-messages.ts @@ -7,8 +7,6 @@ import type { SmppLog } from './log.ts'; import { ExpiringGroups } from './expiring-groups.ts'; import { IdleWaiters } from './idle-waiters.ts'; import { createSms } from './sms.ts'; -import { decodeSegments } from './reassembly.ts'; -import { paramText } from './defs/types.ts'; import { retainedOctets } from './retained-pdu.ts'; type Send = (input: PduObjectInput) => Promise>; @@ -36,7 +34,7 @@ function keyOf(pduObjs: PduObject[]): string | undefined { type HoldRoute = Pick; /** - * One message offered to the application. A drain waits on it until the first of: `answered()`, + * One message offered to the application, and the handlers its `Sms` answers through. A drain waits on it until the first of: `answered()`, * every listener that took it rejecting, no listener taking it or one throwing, a later message on * its sequence number, its deadline, or the link going. */ @@ -124,11 +122,8 @@ export class HeldMessages { return this.held.full || this.held.weight >= this.maxOctets; } - private hold(pduObjs: PduObject[], listeners: number): MessageHold { + private hold(key: string, pduObjs: PduObject[], listeners: number): MessageHold { const hold = new MessageHold(this, this.route, pduObjs, listeners); - const key = keyOf(pduObjs); - - if (key === undefined) return hold; this.sweep(); @@ -144,19 +139,12 @@ export class HeldMessages { /** Hands a whole message to the application as an `sms` event, held until it is answered. */ offer(pduObjs: PduObject[], answeredAs?: string): MessageHold | undefined { - const first = pduObjs[0]; + const key = keyOf(pduObjs); - if (!first) return undefined; + if (key === undefined) return undefined; - const hold = this.hold(pduObjs, this.route.session.listenerCount('sms')); - const sms = createSms({ - answeredAs, - from: paramText(first.params.source_addr), - message: decodeSegments(pduObjs), - pduObjs, - session: this.route.session, - to: paramText(first.params.destination_addr), - }, hold); + const hold = this.hold(key, pduObjs, this.route.session.listenerCount('sms')); + const sms = createSms({ answeredAs, pduObjs, session: this.route.session }, hold); this.offered.set(sms, hold); @@ -172,12 +160,14 @@ export class HeldMessages { this.offered.get(message)?.listenerGaveUp(); } + /** For `MessageHold`, which is how everything else asks. */ holds(pduObjs: PduObject[]): boolean { const key = keyOf(pduObjs); return key !== undefined && this.held.get(key) === pduObjs; } + /** For `MessageHold`, which is how everything else releases. */ release(pduObjs: PduObject[]): void { const key = keyOf(pduObjs); diff --git a/src/sms.ts b/src/sms.ts index 52eb357..19fb0a6 100644 --- a/src/sms.ts +++ b/src/sms.ts @@ -5,7 +5,9 @@ import type { Result, VoidResult } from './result.ts'; import type { Session } from './session.ts'; import { UnansweredError } from './unanswered-error.ts'; import { consts } from './defs/constants.ts'; +import { decodeSegments } from './reassembly.ts'; import { messageClassOf } from './defs/encodings.ts'; +import { paramText } from './defs/types.ts'; import { receiptCodes, transientStates } from './dlr.ts'; import { smppDate } from './message.ts'; import { respIdParams, segmentId } from './sms-id.ts'; @@ -59,11 +61,8 @@ export type Sms = { export type SmsInput = { /** The id base the segments were already answered with; absent leaves the answer to `sendResp()`. */ answeredAs?: string | undefined; - from: string; - message: string; pduObjs: PduObject[]; session: Session; - to: string; }; /** What the session's incoming side gives a message so it can be answered and accounted for. */ @@ -86,8 +85,8 @@ export function createSms(input: SmsInput, handlers: SmsHandlers): Sms { answeredOnArrival: input.answeredAs !== undefined, dlr: typeof registered === 'number' && registered !== 0, flash: typeof dataCoding === 'number' && messageClassOf(dataCoding) === immediateDisplayClass, - from: input.from, - message: input.message, + from: paramText(first?.params.source_addr), + message: decodeSegments(input.pduObjs), pduObjs: input.pduObjs, sendDlr: status => sendDlr(sms, input.session, handlers, status), sendResp: options => (input.answeredAs === undefined @@ -98,7 +97,7 @@ export function createSms(input: SmsInput, handlers: SmsHandlers): Sms { return answered.smsId; }, submitTime: new Date(), - to: input.to, + to: paramText(first?.params.destination_addr), }; return sms; diff --git a/test/session-extras.test.ts b/test/session-extras.test.ts index b2104ba..6b36279 100644 --- a/test/session-extras.test.ts +++ b/test/session-extras.test.ts @@ -1724,14 +1724,11 @@ describe('sendResp()', () => { session.sendReturn = () => Promise.resolve({ err: new Error('Socket is closed') }); const sms = createSms({ - from: '46701113311', - message: 'never answered', pduObjs: [submitPdu(1)], session, - to: '46709771337', }, { - lostLink: () => false, answered: () => { answered++; }, + lostLink: () => false, send: () => Promise.resolve({ err: new Error('never sent') }), }); @@ -1749,14 +1746,11 @@ describe('sendDlr()', () => { let call = 0; const sms = createSms({ - from: '46701113311', - message: 'three segments', pduObjs: [submitPdu(1), submitPdu(2), submitPdu(3)], session, - to: '46709771337', }, { - lostLink: () => false, answered: () => undefined, + lostLink: () => false, send: () => { call++;