From a4c3378d1a948bf09cdc4e72f234425c80163ebf Mon Sep 17 00:00:00 2001 From: dev Date: Tue, 5 May 2026 03:02:30 +0200 Subject: [PATCH] =?UTF-8?q?Bloque=20G3=20=E2=80=94=20defineActivePerm=20wi?= =?UTF-8?q?res=20App.http=20when=20declared?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The perm client accepts `http?: EngineHttp` for transport, but the service factory previously did not forward `App.http` automatically. An app that declared both `http` and `perm` had to wire them together by hand or pass `endpoint` + a custom `fetcher`. `defineActivePerm` now declares `serviceDependencies: ['http']` and forwards `App.http` to `createActivePerms({ http })` when: - the caller did NOT pass `options.http` (explicit wins) - AND did NOT pass `options.fetcher` (caller signaled their own transport — leave `http` undefined to avoid double-wiring) Apps without `http` declared keep working — `services.http` is `undefined` and we leave the `http` slot empty. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/arts/active-app/service-factories/perm.ts | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/arts/active-app/service-factories/perm.ts b/src/arts/active-app/service-factories/perm.ts index c91a5ac..78d135d 100644 --- a/src/arts/active-app/service-factories/perm.ts +++ b/src/arts/active-app/service-factories/perm.ts @@ -1,4 +1,5 @@ import { createActivePerms } from '$perm/active-permissions.svelte'; +import type { EngineHttp } from '$http'; import type { ActivePerms, ActivePermsOptions } from '$perm/types'; import type { AppServiceFactory } from '../services.ts'; @@ -11,22 +12,33 @@ import type { AppServiceFactory } from '../services.ts'; * `applyPermInvalidateOnIdentityChange` to react to identity changes. * * The factory wires `logger` and `clock` from the core, so decision - * cache TTL math runs on `App.Timers.clock`. The application still - * needs to provide `endpoint` (or a custom `fetcher`) — the perm - * client cannot work without a backend. + * cache TTL math runs on `App.Timers.clock`. If `App` declares an `http` + * service, this factory also wires `App.http` as the perm client's + * `http` transport so retry/timeout/auth hooks composed at the App + * level apply uniformly. Apps that prefer their own transport can pass + * `http` or `fetcher` explicitly in `options` — those win over the + * App-level default. + * + * The application still needs to provide `endpoint` — the perm client + * cannot work without a backend. */ export function defineActivePerm( options: Omit -): AppServiceFactory<'perm', readonly ['logger', 'timers'], readonly [], ActivePerms> { +): AppServiceFactory<'perm', readonly ['logger', 'timers'], readonly ['http'], ActivePerms> { return { name: 'perm', coreDependencies: ['logger', 'timers'], + serviceDependencies: ['http'], initMode: 'lazy', - create({ core }): ActivePerms { + create({ core, services }): ActivePerms { + const httpFromApp = services.http as EngineHttp | undefined; return createActivePerms({ ...options, logger: core.logger, - clock: options.clock ?? { now: () => core.timers.clock.now() } + clock: options.clock ?? { now: () => core.timers.clock.now() }, + // Caller-provided `http`/`fetcher` win; otherwise inherit + // `App.http` when declared. + http: options.http ?? (options.fetcher === undefined ? httpFromApp : undefined) }); }, dispose(instance) {