Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
efddeb4edThis file is pinned to the selected release. Download the original to open it in your design tool.
export const DEVICE_RECENT_ENCRYPTED_FRAME_CAP_BYTES = 16 * 1024
export const DEVICE_RECENT_SAFE_RATIO = 0.9
export const DEVICE_RECENT_SAFE_FRAME_BYTES = Math.floor(DEVICE_RECENT_ENCRYPTED_FRAME_CAP_BYTES * DEVICE_RECENT_SAFE_RATIO)
type Payload = Record<string, unknown>
type MeasureFn = (payload: Payload) => number | null
export interface RecentTrimResult {
payload: Payload
trimmed: boolean
originalBytes: number | null
finalBytes: number | null
textBytes: number
recapBytes: number
}
function byteLen(s: string): number {
return Buffer.byteLength(s, 'utf8')
}
export function truncateUtf8(input: string, maxBytes: number): string {
if (maxBytes <= 0) return ''
if (byteLen(input) <= maxBytes) return input
let out = ''
let used = 0
for (const ch of input) {
const n = byteLen(ch)
if (used + n > maxBytes) break
out += ch
used += n
}
return out
}
function normalizeString(v: unknown): string {
return typeof v === 'string' ? v : ''
}
function oneEventPayload(base: Payload, kind: string, text: string, recap: string): Payload {
return {
...base,
events: [{
kind,
text,
...(recap ? { recap } : {}),
}],
}
}
function maxFittingBytes(input: string, makePayload: (value: string) => Payload, measure: MeasureFn, targetBytes: number): string {
let lo = 0
let hi = byteLen(input)
let best = ''
while (lo <= hi) {
const mid = Math.floor((lo + hi) / 2)
const candidate = truncateUtf8(input, mid)
const bytes = measure(makePayload(candidate))
if (bytes !== null && bytes < targetBytes) {
best = candidate
lo = mid + 1
} else {
hi = mid - 1
}
}
return best
}
export function fitRecentReplyPayloadForDevice(
payload: Payload,
measure: MeasureFn,
targetBytes = DEVICE_RECENT_SAFE_FRAME_BYTES,
): RecentTrimResult {
const originalBytes = measure(payload)
if (originalBytes !== null && originalBytes < targetBytes) {
const events = Array.isArray(payload.events) ? payload.events : []
const e = (events[0] ?? {}) as Record<string, unknown>
const text = normalizeString(e.text)
const recap = normalizeString(e.recap)
return { payload, trimmed: false, originalBytes, finalBytes: originalBytes, textBytes: byteLen(text), recapBytes: byteLen(recap) }
}
const events = Array.isArray(payload.events) ? payload.events : []
const raw = (events[0] ?? {}) as Record<string, unknown>
const kind = normalizeString(raw.kind) || 'summary'
const originalText = normalizeString(raw.text)
const originalRecap = normalizeString(raw.recap)
let fitted = oneEventPayload(payload, kind, originalText, originalRecap)
let finalBytes = measure(fitted)
if (finalBytes !== null && finalBytes < targetBytes) {
return { payload: fitted, trimmed: true, originalBytes, finalBytes, textBytes: byteLen(originalText), recapBytes: byteLen(originalRecap) }
}
const fitTextForRecap = (recap: string) => maxFittingBytes(
originalText,
(text) => oneEventPayload(payload, kind, text || recap || kind, recap),
measure,
targetBytes,
)
const fittedText = fitTextForRecap(originalRecap)
fitted = oneEventPayload(payload, kind, fittedText || originalRecap || kind, originalRecap)
finalBytes = measure(fitted)
if (finalBytes !== null && finalBytes < targetBytes) {
return { payload: fitted, trimmed: true, originalBytes, finalBytes, textBytes: byteLen(fittedText), recapBytes: byteLen(originalRecap) }
}
let lo = 0
let hi = byteLen(originalRecap)
let fittedRecap = ''
while (lo <= hi) {
const mid = Math.floor((lo + hi) / 2)
const recap = truncateUtf8(originalRecap, mid)
const bytes = measure(oneEventPayload(payload, kind, originalText || recap || kind, recap))
if (bytes !== null && bytes < targetBytes) {
fittedRecap = recap
lo = mid + 1
} else {
hi = mid - 1
}
}
let finalText = originalText
if (!fittedRecap && originalRecap) {
lo = 0
hi = byteLen(originalRecap)
while (lo <= hi) {
const mid = Math.floor((lo + hi) / 2)
const recap = truncateUtf8(originalRecap, mid)
const text = fitTextForRecap(recap)
const candidateText = text || recap || kind
const bytes = measure(oneEventPayload(payload, kind, candidateText, recap))
const hasRequiredText = !originalText || text.length > 0
if (hasRequiredText && bytes !== null && bytes < targetBytes) {
fittedRecap = recap
finalText = text || candidateText
lo = mid + 1
} else {
hi = mid - 1
}
}
}
if (fittedRecap) finalText = fitTextForRecap(fittedRecap) || finalText || fittedRecap || kind
fitted = oneEventPayload(payload, kind, finalText, fittedRecap)
finalBytes = measure(fitted)
return { payload: fitted, trimmed: true, originalBytes, finalBytes, textBytes: byteLen(finalText), recapBytes: byteLen(fittedRecap) }
}