Skip to content

Commit db12b5b

Browse files
wip merge props
1 parent 09d3b11 commit db12b5b

File tree

16 files changed

+433
-308
lines changed

16 files changed

+433
-308
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
}
2727
],
2828
"require": {
29+
"php": "^8.4",
2930
"tempest/framework": "dev-main"
3031
},
3132
"config": {

composer.lock

Lines changed: 255 additions & 253 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Concerns/IsMergeableProp.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace NeoIsRecursive\Inertia\Concerns;
6+
7+
use NeoIsRecursive\Inertia\Contracts\MergeableProp;
8+
9+
/**
10+
* @implements MergeableProp
11+
*/
12+
trait IsMergeableProp
13+
{
14+
public function merge(): self
15+
{
16+
$this->shouldMerge = true;
17+
18+
return $this;
19+
}
20+
}

src/Contracts/MergeableProp.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace NeoIsRecursive\Inertia\Contracts;
6+
7+
interface MergeableProp
8+
{
9+
public bool $shouldMerge { get; }
10+
11+
public function merge(): self;
12+
}

src/Http/InertiaResponse.php

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace NeoIsRecursive\Inertia\Http;
44

55
use Closure;
6+
use NeoIsRecursive\Inertia\Contracts\MergeableProp;
67
use NeoIsRecursive\Inertia\Props\AlwaysProp;
78
use NeoIsRecursive\Inertia\Props\LazyProp;
89
use NeoIsRecursive\Inertia\Support\Header;
@@ -11,6 +12,7 @@
1112
use Tempest\Router\IsResponse;
1213
use Tempest\Router\Request;
1314
use Tempest\Router\Response;
15+
use Tempest\Support\ArrayHelper;
1416

1517
use function Tempest\invoke;
1618
use function Tempest\Support\arr;
@@ -26,24 +28,31 @@ public function __construct(
2628
string $rootView,
2729
string $version,
2830
) {
31+
2932
$alwaysProps = $this->resolveAlwaysProps(props: $props);
30-
$props = $this->resolvePartialProps(request: $request, component: $page, props: $props);
33+
$partialProps = $this->resolvePartialProps(request: $request, component: $page, props: $props);
34+
$mergeProps = $this->resolveMergeProps($props, $request);
3135

3236
$props = $this->evaluateProps(
33-
props: array_merge($props, $alwaysProps),
37+
props: array_merge(
38+
$alwaysProps,
39+
$partialProps,
40+
$mergeProps
41+
),
3442
request: $request,
3543
unpackDotProps: true
3644
);
3745

3846
$page = [
3947
'component' => $page,
4048
'props' => $props,
41-
'url' => $request->getUri(),
49+
'url' => $request->uri,
4250
'version' => $version,
51+
'mergeProps' => array_keys($mergeProps),
4352
];
4453

4554

46-
if (array_key_exists(Header::INERTIA, $request->getHeaders()) && $request->getHeaders()[Header::INERTIA] == 'true') {
55+
if (array_key_exists(Header::INERTIA, $request->headers) && $request->headers[Header::INERTIA] == 'true') {
4756
$this->status = Status::OK;
4857

4958
$this->body = $page;
@@ -69,7 +78,7 @@ private function resolveAlwaysProps(array $props): array
6978

7079
private function resolvePartialProps(Request $request, string $component, array $props): array
7180
{
72-
$headers = $request->getHeaders();
81+
$headers = $request->headers;
7382

7483
$partialHeader = $headers[Header::PARTIAL_COMPONENT] ?? null;
7584

@@ -84,9 +93,9 @@ private function resolvePartialProps(Request $request, string $component, array
8493
$only = array_filter(explode(',', $headers[Header::PARTIAL_ONLY] ?? ''));
8594
$except = array_filter(explode(',', $headers[Header::PARTIAL_EXCEPT] ?? ''));
8695

87-
$props = $only ? array_intersect_key($props, array_flip((array) $only)) : $props;
96+
$props = $only ? array_intersect_key($props, array_flip($only)) : $props;
8897

89-
if ($except) {
98+
if (count($except) > 0) {
9099
foreach ($except as $key) {
91100
unset($props[$key]);
92101
}
@@ -95,7 +104,20 @@ private function resolvePartialProps(Request $request, string $component, array
95104
return $props;
96105
}
97106

98-
public function evaluateProps(array $props, Request $request, bool $unpackDotProps = true): array
107+
public static function resolveMergeProps(array $props, Request $request): array
108+
{
109+
$resetProps = arr(explode(',', $request->headers[Header::RESET] ?? ''));
110+
$mergeProps = arr($props)
111+
->filter(fn($prop) => $prop instanceof MergeableProp && $prop->shouldMerge)
112+
->filter(
113+
fn($_, $key) => ! $resetProps->contains($key)
114+
)
115+
->keys();
116+
117+
return $mergeProps->toArray();
118+
}
119+
120+
public static function evaluateProps(array $props, Request $request, bool $unpackDotProps = true): array
99121
{
100122
foreach ($props as $key => $value) {
101123
if ($value instanceof Closure) {
@@ -110,8 +132,12 @@ public function evaluateProps(array $props, Request $request, bool $unpackDotPro
110132
$value = $value();
111133
}
112134

135+
if ($value instanceof ArrayHelper) {
136+
$value = $value->toArray();
137+
}
138+
113139
if (is_array($value)) {
114-
$value = $this->evaluateProps($value, $request, false);
140+
$value = self::evaluateProps($value, $request, false);
115141
}
116142

117143
if ($unpackDotProps && str_contains($key, '.')) {

src/Http/Middleware.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,19 @@ public function __invoke(Request $request, HttpMiddlewareCallable $next): Respon
3333

3434
$response->addHeader('Vary', Header::INERTIA);
3535

36-
if (!array_key_exists(Header::INERTIA, $request->getHeaders())) {
36+
if (!array_key_exists(Header::INERTIA, $request->headers)) {
3737
return $response;
3838
}
3939

40-
$versionHeaderValue = $request->getHeaders()[Header::VERSION] ?? '';
40+
$versionHeaderValue = $request->headers[Header::VERSION] ?? '';
4141

42-
if ($request->getMethod() === Method::GET && $versionHeaderValue !== $this->inertia->version) {
42+
if ($request->method === Method::GET && $versionHeaderValue !== $this->inertia->version) {
4343
// TODO: reflash session data
4444

45-
return $this->inertia->location($request->getUri());
45+
return $this->inertia->location($request->uri);
4646
}
4747

48-
if ($response->getStatus() === Status::FOUND && in_array($request->getMethod(), [Method::POST, Method::PUT, Method::PATCH])) {
48+
if ($response->status === Status::FOUND && in_array($request->method, [Method::POST, Method::PUT, Method::PATCH])) {
4949
// TODO: set status to 303
5050
// return new GenericResponse(
5151
// status: Status::SEE_OTHER,

src/Inertia.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public function render(string $page, array $props = []): InertiaResponse
5353

5454
public function location(string|Redirect $url): Response
5555
{
56-
$isInertiaRequest = isset($this->container->get(Request::class)->getHeaders()[Header::INERTIA]);
56+
$isInertiaRequest = isset($this->container->get(Request::class)->headers[Header::INERTIA]);
5757

5858
if ($isInertiaRequest) {
5959
if ($url instanceof Redirect) {

src/Props/AlwaysProp.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,21 @@
33
namespace NeoIsRecursive\Inertia\Props;
44

55
use Closure;
6+
use NeoIsRecursive\Inertia\Concerns\IsMergeableProp;
7+
use NeoIsRecursive\Inertia\Contracts\MergeableProp;
68
use Tempest\Reflection\FunctionReflector;
79
use Tempest\Reflection\MethodReflector;
810

911
use function Tempest\invoke;
1012

11-
final readonly class AlwaysProp
13+
final class AlwaysProp implements MergeableProp
1214
{
13-
public function __construct(public MethodReflector|FunctionReflector|string|Closure $value) {}
15+
use IsMergeableProp;
16+
17+
public function __construct(
18+
public readonly MethodReflector|FunctionReflector|string|Closure|array $value,
19+
public private(set) bool $shouldMerge = false
20+
) {}
1421

1522
public function __invoke()
1623
{

src/Props/DeferredProp.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace NeoIsRecursive\Inertia\Props;
4+
5+
use Closure;
6+
use NeoIsRecursive\Inertia\Concerns\IsMergeableProp;
7+
use NeoIsRecursive\Inertia\Contracts\MergeableProp;
8+
use Tempest\Reflection\FunctionReflector;
9+
use Tempest\Reflection\MethodReflector;
10+
11+
use function Tempest\invoke;
12+
13+
final class DeferredProp implements MergeableProp
14+
{
15+
use IsMergeableProp;
16+
17+
public function __construct(
18+
public MethodReflector|FunctionReflector|string|array|Closure $callback,
19+
public private(set) bool $shouldMerge = false
20+
) {}
21+
22+
public function __invoke()
23+
{
24+
return invoke($this->callback);
25+
}
26+
}

src/Props/LazyProp.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,21 @@
33
namespace NeoIsRecursive\Inertia\Props;
44

55
use Closure;
6+
use NeoIsRecursive\Inertia\Concerns\IsMergeableProp;
7+
use NeoIsRecursive\Inertia\Contracts\MergeableProp;
8+
use Tempest\Reflection\FunctionReflector;
9+
use Tempest\Reflection\MethodReflector;
610

711
use function Tempest\invoke;
812

9-
final readonly class LazyProp
13+
final class LazyProp implements MergeableProp
1014
{
11-
public function __construct(public Closure $callback) {}
15+
use IsMergeableProp;
16+
17+
public function __construct(
18+
public MethodReflector|FunctionReflector|string|array|Closure $callback,
19+
public private(set) bool $shouldMerge = false
20+
) {}
1221

1322
public function __invoke()
1423
{

0 commit comments

Comments
 (0)