diff --git a/NEXT_STEPS.md b/NEXT_STEPS.md index de6f76b..b77bfd0 100644 --- a/NEXT_STEPS.md +++ b/NEXT_STEPS.md @@ -25,6 +25,7 @@ Estado al cierre: - `arts/conn/connection.ts` delega current transport, attach/detach y close en `connection-transport-runtime.ts`. - `arts/timr/engine-timers.ts` delega fan-out de listeners y diagnostico de listeners en `timer-events.ts`. - `arts/timr/engine-timers.ts` delega la construccion de entradas internas en `timer-entry.ts`. + - `arts/timr/engine-timers.ts` delega cancelacion y seleccion por scope en `timer-cancel.ts`. - Integracion total ampliada: `Auth.signOut()` valida anonimizacion, invalidacion de `Permissions` y evento `Cache.invalidate`. - Tanda focalizada verde: `npx vitest run src/arts/conn src/libs/cach src/arts/cach src/svrs/cach src/arts/auth src/svrs/auth src/libs/auth src/arts/aapp/test/ecosystem.integration.test.ts` -> 19 archivos, 82 tests. - `/test/ecosystem` revisado en navegador: carga sin errores de consola, `ar` cambia a `rtl`, Formats se actualiza por locale, Perm cambia con rol `viewer`, Cach re-scopea por locale y Conn loopback publica/recibe. diff --git a/src/arts/timr/engine-timers.ts b/src/arts/timr/engine-timers.ts index 696fd23..5fae6fa 100644 --- a/src/arts/timr/engine-timers.ts +++ b/src/arts/timr/engine-timers.ts @@ -30,7 +30,6 @@ import { ENGINE_METHOD_SCHEDULE, ENGINE_METHOD_SCHEDULE_AT, TIMER_DIAGNOSTIC_EVENTS, - TIMER_EVENT_CANCELLED, TIMER_EVENT_COMPLETED, TIMER_EVENT_DISPOSED, TIMER_EVENT_FAILED, @@ -46,9 +45,9 @@ import { } from './consts.ts'; import { createTimerDiagnostics, emitTimerDiagnostic } from './diagnostics.ts'; import { TimrDuplicateKeyError } from './errors.ts'; +import { cancelTimerEntry, collectTimerKeysInScope } from './timer-cancel.ts'; import { createInternalTimerEntry, - isTimerKeyInScope, timerEntrySnapshot, type InternalTimerEntry } from './timer-entry.ts'; @@ -238,15 +237,7 @@ export function createEngineTimers(options: EngineTimersOptions = {}): EngineTim // ── Cancellation ──────────────────────────────────────────────────────── function cancelEntry(entry: InternalTimerEntry): void { - entry.version += 1; - entry.status = TIMER_STATUS_CANCELLED; - if (entry.native !== null) { - clock.clearTimeout(entry.native); - entry.native = null; - } - entry.controller.abort(); - entries.delete(entry.key); - emit({ type: TIMER_EVENT_CANCELLED, entry: timerEntrySnapshot(entry) }); + cancelTimerEntry({ entry, entries, clock, emit }); } // ── Public scheduling ─────────────────────────────────────────────────── @@ -369,11 +360,7 @@ export function createEngineTimers(options: EngineTimersOptions = {}): EngineTim cancelAll(scope) { ensureLive(ENGINE_METHOD_CANCEL_ALL); let count = 0; - // Snapshot keys to avoid mutating during iteration. - const keys: string[] = []; - for (const k of entries.keys()) { - if (scope === undefined || isTimerKeyInScope(k, scope)) keys.push(k); - } + const keys = collectTimerKeysInScope(entries, scope); for (const k of keys) { const entry = entries.get(k); if (entry === undefined) continue; diff --git a/src/arts/timr/timer-cancel.ts b/src/arts/timr/timer-cancel.ts new file mode 100644 index 0000000..a2dd423 --- /dev/null +++ b/src/arts/timr/timer-cancel.ts @@ -0,0 +1,38 @@ +import { TIMER_EVENT_CANCELLED, TIMER_STATUS_CANCELLED } from './consts.ts'; +import { + isTimerKeyInScope, + timerEntrySnapshot, + type InternalTimerEntry +} from './timer-entry.ts'; +import type { TimerClock, TimerEvent } from './types.ts'; + +export interface CancelTimerEntryInput { + readonly entry: InternalTimerEntry; + readonly entries: Map; + readonly clock: TimerClock; + emit(event: TimerEvent): void; +} + +export function cancelTimerEntry(input: CancelTimerEntryInput): void { + const { entry, entries, clock } = input; + entry.version += 1; + entry.status = TIMER_STATUS_CANCELLED; + if (entry.native !== null) { + clock.clearTimeout(entry.native); + entry.native = null; + } + entry.controller.abort(); + entries.delete(entry.key); + input.emit({ type: TIMER_EVENT_CANCELLED, entry: timerEntrySnapshot(entry) }); +} + +export function collectTimerKeysInScope( + entries: Map, + scope: string | undefined +): string[] { + const keys: string[] = []; + for (const key of entries.keys()) { + if (scope === undefined || isTimerKeyInScope(key, scope)) keys.push(key); + } + return keys; +}