Skip to content

Commit ce95e96

Browse files
committed
Merge branch 'develop'
* develop: specify next release reduce routes memory footprint add Application::mapRoutes() remove wip
2 parents fdd25bc + 73238a3 commit ce95e96

8 files changed

Lines changed: 201 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
## 4.1.0 - 2026-04-12
4+
5+
### Added
6+
7+
- `Innmind\Framework\Application::mapRoutes()`
8+
9+
### Changed
10+
11+
- Reduced routes memory footprint
12+
313
## 4.0.2 - 2026-04-12
414

515
### Fixed

src/Application.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,11 @@ public function routes(string $routes): self
189189
}
190190

191191
/**
192+
* This wraps each route individually.
193+
*
194+
* This means that the code may be executed multiple times until it reaches
195+
* the appropriate route.
196+
*
192197
* @psalm-mutation-free
193198
*
194199
* @param callable(Component<SideEffect, Response>, Container): Component<SideEffect, Response> $map
@@ -201,6 +206,23 @@ public function mapRoute(callable $map): self
201206
return new self($this->app->mapRoute($map));
202207
}
203208

209+
/**
210+
* This wraps all routes as whole.
211+
*
212+
* This means that the code will be executed only once.
213+
*
214+
* @psalm-mutation-free
215+
*
216+
* @param callable(Component<SideEffect, Response>, Container): Component<SideEffect, Response> $map
217+
*
218+
* @return self<I, O>
219+
*/
220+
#[\NoDiscard]
221+
public function mapRoutes(callable $map): self
222+
{
223+
return new self($this->app->mapRoutes($map));
224+
}
225+
204226
/**
205227
* @psalm-mutation-free
206228
*

src/Application/Async/Http.php

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ final class Http implements Implementation
4949
* @param \Closure(OperatingSystem, Environment): Builder $container
5050
* @param Sequence<callable(Pipe, Container): Component<SideEffect, Response>> $routes
5151
* @param \Closure(Component<SideEffect, Response>, Container): Component<SideEffect, Response> $mapRoute
52+
* @param \Closure(Component<SideEffect, Response>, Container): Component<SideEffect, Response> $mapRoutes
5253
* @param Maybe<callable(ServerRequest, Container): Attempt<Response>> $notFound
5354
* @param \Closure(ServerRequest, \Throwable, Container): Attempt<Response> $recover
5455
*/
@@ -58,6 +59,7 @@ private function __construct(
5859
private \Closure $container,
5960
private Sequence $routes,
6061
private \Closure $mapRoute,
62+
private \Closure $mapRoutes,
6163
private Maybe $notFound,
6264
private \Closure $recover,
6365
) {
@@ -75,7 +77,8 @@ public static function of(OperatingSystem $os): self
7577
$os,
7678
static fn(OperatingSystem $os, Environment $env) => [$os, $env],
7779
static fn() => Builder::new(),
78-
Sequence::lazyStartingWith(),
80+
Sequence::of(),
81+
static fn(Component $component) => $component,
7982
static fn(Component $component) => $component,
8083
$notFound,
8184
static fn(ServerRequest $request, \Throwable $e) => Attempt::error($e),
@@ -101,6 +104,7 @@ static function(OperatingSystem $os, Environment $env) use ($previous, $map): ar
101104
$this->container,
102105
$this->routes,
103106
$this->mapRoute,
107+
$this->mapRoutes,
104108
$this->notFound,
105109
$this->recover,
106110
);
@@ -125,6 +129,7 @@ static function(OperatingSystem $os, Environment $env) use ($previous, $map): ar
125129
$this->container,
126130
$this->routes,
127131
$this->mapRoute,
132+
$this->mapRoutes,
128133
$this->notFound,
129134
$this->recover,
130135
);
@@ -147,6 +152,7 @@ public function service(Service $name, callable $definition): self
147152
),
148153
$this->routes,
149154
$this->mapRoute,
155+
$this->mapRoutes,
150156
$this->notFound,
151157
$this->recover,
152158
);
@@ -182,6 +188,7 @@ public function route(callable $handle): self
182188
$this->container,
183189
($this->routes)($handle),
184190
$this->mapRoute,
191+
$this->mapRoutes,
185192
$this->notFound,
186193
$this->recover,
187194
);
@@ -204,6 +211,30 @@ public function mapRoute(callable $map): self
204211
$previous($component, $get),
205212
$get,
206213
),
214+
$this->mapRoutes,
215+
$this->notFound,
216+
$this->recover,
217+
);
218+
}
219+
220+
/**
221+
* @psalm-mutation-free
222+
*/
223+
#[\Override]
224+
public function mapRoutes(callable $map): self
225+
{
226+
$previous = $this->mapRoutes;
227+
228+
return new self(
229+
$this->os,
230+
$this->map,
231+
$this->container,
232+
$this->routes,
233+
$this->mapRoute,
234+
static fn($component, $get) => $map(
235+
$previous($component, $get),
236+
$get,
237+
),
207238
$this->notFound,
208239
$this->recover,
209240
);
@@ -221,6 +252,7 @@ public function routeNotFound(callable $handle): self
221252
$this->container,
222253
$this->routes,
223254
$this->mapRoute,
255+
$this->mapRoutes,
224256
Maybe::just($handle),
225257
$this->recover,
226258
);
@@ -240,6 +272,7 @@ public function recoverRouteError(callable $recover): self
240272
$this->container,
241273
$this->routes,
242274
$this->mapRoute,
275+
$this->mapRoutes,
243276
$this->notFound,
244277
static fn($request, $e, $container) => $previous($request, $e, $container)->recover(
245278
static fn($e) => $recover($request, $e, $container),
@@ -252,9 +285,12 @@ public function run($input): Attempt
252285
{
253286
$map = $this->map;
254287
$container = $this->container;
255-
$routes = $this->routes;
288+
$routes = Sequence::lazyStartingWith($this->routes)->flatMap(
289+
static fn($routes) => $routes,
290+
);
256291
$notFound = $this->notFound;
257292
$mapRoute = $this->mapRoute;
293+
$mapRoutes = $this->mapRoutes;
258294
$recover = $this->recover;
259295

260296
$run = Commands::of(Serve::of(
@@ -265,6 +301,7 @@ static function(ServerRequest $request, OperatingSystem $os, Map $env) use (
265301
$routes,
266302
$notFound,
267303
$mapRoute,
304+
$mapRoutes,
268305
$recover,
269306
): Response {
270307
$env = Environment::of($env);
@@ -275,6 +312,7 @@ static function(ServerRequest $request, OperatingSystem $os, Map $env) use (
275312
->map(static fn($handle) => $handle($pipe, $container))
276313
->map(static fn($component) => $mapRoute($component, $container));
277314
$router = new Router(
315+
static fn($component) => $mapRoutes($component, $container),
278316
$routes,
279317
$notFound->map(
280318
static fn($handle) => static fn(ServerRequest $request) => $handle(

src/Application/Cli.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,15 @@ public function mapRoute(callable $map): self
178178
return $this;
179179
}
180180

181+
/**
182+
* @psalm-mutation-free
183+
*/
184+
#[\Override]
185+
public function mapRoutes(callable $map): self
186+
{
187+
return $this;
188+
}
189+
181190
/**
182191
* @psalm-mutation-free
183192
*/

src/Application/Http.php

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ final class Http implements Implementation
4040
* @param \Closure(OperatingSystem, Environment): Builder $container
4141
* @param Sequence<callable(Pipe, Container): Component<SideEffect, Response>> $routes
4242
* @param \Closure(Component<SideEffect, Response>, Container): Component<SideEffect, Response> $mapRoute
43+
* @param \Closure(Component<SideEffect, Response>, Container): Component<SideEffect, Response> $mapRoutes
4344
* @param Maybe<callable(ServerRequest, Container): Attempt<Response>> $notFound
4445
* @param \Closure(ServerRequest, \Throwable, Container): Attempt<Response> $recover
4546
*/
@@ -49,6 +50,7 @@ private function __construct(
4950
private \Closure $container,
5051
private Sequence $routes,
5152
private \Closure $mapRoute,
53+
private \Closure $mapRoutes,
5254
private Maybe $notFound,
5355
private \Closure $recover,
5456
) {
@@ -66,7 +68,8 @@ public static function of(OperatingSystem $os, Environment $env): self
6668
$os,
6769
$env,
6870
static fn() => Builder::new(),
69-
Sequence::lazyStartingWith(),
71+
Sequence::of(),
72+
static fn(Component $component) => $component,
7073
static fn(Component $component) => $component,
7174
$notFound,
7275
static fn(ServerRequest $request, \Throwable $e) => Attempt::error($e),
@@ -86,6 +89,7 @@ public function mapEnvironment(callable $map): self
8689
$this->container,
8790
$this->routes,
8891
$this->mapRoute,
92+
$this->mapRoutes,
8993
$this->notFound,
9094
$this->recover,
9195
);
@@ -104,6 +108,7 @@ public function mapOperatingSystem(callable $map): self
104108
$this->container,
105109
$this->routes,
106110
$this->mapRoute,
111+
$this->mapRoutes,
107112
$this->notFound,
108113
$this->recover,
109114
);
@@ -126,6 +131,7 @@ public function service(Service $name, callable $definition): self
126131
),
127132
$this->routes,
128133
$this->mapRoute,
134+
$this->mapRoutes,
129135
$this->notFound,
130136
$this->recover,
131137
);
@@ -161,6 +167,7 @@ public function route(callable $handle): self
161167
$this->container,
162168
($this->routes)($handle),
163169
$this->mapRoute,
170+
$this->mapRoutes,
164171
$this->notFound,
165172
$this->recover,
166173
);
@@ -183,6 +190,30 @@ public function mapRoute(callable $map): self
183190
$previous($component, $get),
184191
$get,
185192
),
193+
$this->mapRoutes,
194+
$this->notFound,
195+
$this->recover,
196+
);
197+
}
198+
199+
/**
200+
* @psalm-mutation-free
201+
*/
202+
#[\Override]
203+
public function mapRoutes(callable $map): self
204+
{
205+
$previous = $this->mapRoutes;
206+
207+
return new self(
208+
$this->os,
209+
$this->env,
210+
$this->container,
211+
$this->routes,
212+
$this->mapRoute,
213+
static fn($component, $get) => $map(
214+
$previous($component, $get),
215+
$get,
216+
),
186217
$this->notFound,
187218
$this->recover,
188219
);
@@ -200,6 +231,7 @@ public function routeNotFound(callable $handle): self
200231
$this->container,
201232
$this->routes,
202233
$this->mapRoute,
234+
$this->mapRoutes,
203235
Maybe::just($handle),
204236
$this->recover,
205237
);
@@ -219,6 +251,7 @@ public function recoverRouteError(callable $recover): self
219251
$this->container,
220252
$this->routes,
221253
$this->mapRoute,
254+
$this->mapRoutes,
222255
$this->notFound,
223256
static fn($request, $e, $container) => $previous($request, $e, $container)->recover(
224257
static fn($e) => $recover($request, $e, $container),
@@ -231,13 +264,15 @@ public function run($input): Attempt
231264
{
232265
$container = ($this->container)($this->os, $this->env)->build();
233266
$mapRoute = $this->mapRoute;
267+
$mapRoutes = $this->mapRoutes;
234268
$recover = $this->recover;
235269
$pipe = Pipe::new();
236-
$routes = $this
237-
->routes
270+
$routes = Sequence::lazyStartingWith($this->routes)
271+
->flatMap(static fn($routes) => $routes)
238272
->map(static fn($handle) => $handle($pipe, $container))
239273
->map(static fn($component) => $mapRoute($component, $container));
240274
$router = new Router(
275+
static fn($component) => $mapRoutes($component, $container),
241276
$routes,
242277
$this->notFound->map(
243278
static fn($handle) => static fn(ServerRequest $request) => $handle(

src/Application/Implementation.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,15 @@ public function route(callable $handle): self;
9696
*/
9797
public function mapRoute(callable $map): self;
9898

99+
/**
100+
* @psalm-mutation-free
101+
*
102+
* @param callable(Component<SideEffect, Response>, Container): Component<SideEffect, Response> $map
103+
*
104+
* @return self<I, O>
105+
*/
106+
public function mapRoutes(callable $map): self;
107+
99108
/**
100109
* @psalm-mutation-free
101110
*

src/Http/Router.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@
2929
final class Router
3030
{
3131
/**
32+
* @param \Closure(Component<SideEffect, Response>): Component<SideEffect, Response> $mapRoutes
3233
* @param Sequence<Component<SideEffect, Response>> $routes
3334
* @param Maybe<\Closure(ServerRequest): Attempt<Response>> $notFound
3435
* @param \Closure(ServerRequest, \Throwable): Attempt<Response> $recover
3536
*/
3637
public function __construct(
38+
private \Closure $mapRoutes,
3739
private Sequence $routes,
3840
private Maybe $notFound,
3941
private \Closure $recover,
@@ -52,7 +54,7 @@ public function __invoke(ServerRequest $request): Attempt
5254
* @psalm-suppress MixedArgumentTypeCoercion
5355
*/
5456
$route = Route::of(
55-
Any::from($this->routes)
57+
($this->mapRoutes)(Any::from($this->routes))
5658
->mapError(static fn($e) => match (true) {
5759
$e instanceof NoRouteProvided => new NotFound,
5860
default => $e,

0 commit comments

Comments
 (0)