Bloque G3 — defineActivePerm wires App.http when declared

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) <noreply@anthropic.com>
master
dev 5 months ago
parent ddfc4dc6ea
commit a4c3378d1a

@ -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<ActivePermsOptions, 'logger'>
): 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) {

Loading…
Cancel
Save

Powered by TurnKey Linux.