Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
timacdonald committed Oct 15, 2023
1 parent 47f11d1 commit 93dfac0
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 89 deletions.
67 changes: 9 additions & 58 deletions src/Concerns/Caching.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,12 @@
use TiMacDonald\JsonApi\JsonApiResource;
use TiMacDonald\JsonApi\JsonApiResourceCollection;

/**
* @internal
* @todo can we get rid of this?
*/
trait Caching
{
/**
* @internal
*/
private string|null $idCache = null;

/**
* @internal
*/
private string|null $typeCache = null;

/**
* @internal
*
* @var Collection<string, JsonApiResource|JsonApiResourceCollection>|null
*/
private Collection|null $requestedRelationshipsCache = null;

/**
* @internal
* @infection-ignore-all
Expand All @@ -35,51 +22,14 @@ trait Caching
*/
public function flush()
{
$this->idCache = null;

$this->typeCache = null;

if ($this->requestedRelationshipsCache !== null) {
$this->requestedRelationshipsCache->each(fn (JsonApiResource|JsonApiResourceCollection $relation) => $relation->flush());
}
// TODO can we just let this garbage collect?
$this->requestedRelationshipsCache?->each(fn (JsonApiResource|JsonApiResourceCollection $relation) => $relation->flush());

$this->requestedRelationshipsCache = null;
}

/**
* @internal
* @infection-ignore-all
*
* @param (callable(): string) $callback
* @return string
*/
private function rememberId(callable $callback)
{
return $this->idCache ??= $callback();
}

/**
* @internal
* @infection-ignore-all
*
* @param (callable(): string) $callback
* @return string
*/
private function rememberType(callable $callback)
{
return $this->typeCache ??= $callback();
}
$this->idCache = null;

/**
* @internal
* @infection-ignore-all
*
* @param (callable(): Collection<string, JsonApiResource|JsonApiResourceCollection>) $callback
* @return Collection<string, JsonApiResource|JsonApiResourceCollection>
*/
private function rememberRequestRelationships(callable $callback)
{
return $this->requestedRelationshipsCache ??= $callback();
$this->typeCache = null;
}

/**
Expand All @@ -89,6 +39,7 @@ private function rememberRequestRelationships(callable $callback)
*/
public function requestedRelationshipsCache()
{
// TODO can we remove this if we ditch caching? Only here for tests.
return $this->requestedRelationshipsCache;
}
}
8 changes: 6 additions & 2 deletions src/Concerns/Identification.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@

trait Identification
{
private string|null $idCache = null;

private string|null $typeCache = null;

/**
* @internal
*
Expand Down Expand Up @@ -105,7 +109,7 @@ public function toUniqueResourceIdentifier(Request $request)
*/
private function resolveId(Request $request)
{
return $this->rememberId(fn (): string => $this->toId($request));
return $this->idCache ??= $this->toId($request);
}

/**
Expand All @@ -115,7 +119,7 @@ private function resolveId(Request $request)
*/
private function resolveType(Request $request)
{
return $this->rememberType(fn (): string => $this->toType($request));
return $this->typeCache ??= $this->toType($request);
}

/**
Expand Down
9 changes: 7 additions & 2 deletions src/Concerns/Relationships.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@

trait Relationships
{
/**
* @var Collection<string, JsonApiResource|JsonApiResourceCollection>|null
*/
private Collection|null $requestedRelationshipsCache = null;

/**
* @internal
*
Expand Down Expand Up @@ -103,10 +108,10 @@ private function requestedRelationshipsAsIdentifiers(Request $request)
*/
private function requestedRelationships(Request $request)
{
return $this->rememberRequestRelationships(fn (): Collection => $this->resolveRelationships($request)
return $this->requestedRelationshipsCache ??= $this->resolveRelationships($request)
->only($this->requestedIncludes($request))
->map(fn (callable $value, string $prefix): null|JsonApiResource|JsonApiResourceCollection => $this->resolveInclude($value(), $prefix))
->reject(fn (JsonApiResource|JsonApiResourceCollection|null $resource): bool => $resource === null));
->reject(fn (JsonApiResource|JsonApiResourceCollection|null $resource): bool => $resource === null);
}

/**
Expand Down
9 changes: 6 additions & 3 deletions src/JsonApiResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Illuminate\Http\Resources\PotentiallyMissing;
use Illuminate\Support\Collection;
use stdClass;

use function property_exists;

abstract class JsonApiResource extends JsonResource
Expand Down Expand Up @@ -115,7 +116,7 @@ public function toArray(Request $request)
}

/**
* @return array{included?: Collection<int, JsonApiResource>, jsonapi: JsonApiServerImplementation}
* @return array{included?: array<int, JsonApiResource>, jsonapi: JsonApiServerImplementation}
*/
public function with(Request $request)
{
Expand All @@ -129,6 +130,8 @@ public function with(Request $request)
}

/**
* TODO this may be removed once all supported versions have `newCollection`.
*
* @return JsonApiResourceCollection<int, mixed>
*/
public static function collection(mixed $resource)
Expand All @@ -155,7 +158,7 @@ public static function newCollection(mixed $resource)
*/
public function toResponse($request)
{
// TODO: the flush call here is triggering repeated Includes::flush() cals, because of collection.s
return tap(parent::toResponse($request)->header('Content-type', 'application/vnd.api+json'), fn () => $this->flush());
// TODO: should this header be configurable? Should it be a middleware? Should we not set it if one exists?
return tap(parent::toResponse($request)->header('Content-type', 'application/vnd.api+json'), $this->flush(...));
}
}
11 changes: 6 additions & 5 deletions src/JsonApiResourceCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ private function resolveResourceIdentifiers(Request $request)
}

/**
* @return array{included?: Collection<int, JsonApiResource>, jsonapi: JsonApiServerImplementation}
* @return array{included?: array<int, JsonApiResource>, jsonapi: JsonApiServerImplementation}
*/
public function with(Request $request)
{
Expand All @@ -63,7 +63,8 @@ public function with(Request $request)
*/
public function toResponse($request)
{
return tap(parent::toResponse($request)->header('Content-type', 'application/vnd.api+json'), fn () => $this->flush());
// TODO: should this header be configurable? Should it be a middleware? Should we not set it if one exists?
return tap(parent::toResponse($request)->header('Content-type', 'application/vnd.api+json'), $this->flush(...));
}

/**
Expand Down Expand Up @@ -98,9 +99,9 @@ function (array $link): array {
*/
public function withIncludePrefix(string $prefix)
{
return tap($this, function (JsonApiResourceCollection $resource) use ($prefix): void {
$resource->collection->each(fn (JsonApiResource $resource): JsonApiResource => $resource->withIncludePrefix($prefix));
});
$this->collection->each(fn (JsonApiResource $resource): JsonApiResource => $resource->withIncludePrefix($prefix));

return $this;
}

/**
Expand Down
10 changes: 1 addition & 9 deletions src/Support/Fields.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ final class Fields
*/
private WeakMap $cache;

private function __construct(WeakMap $cache = new WeakMap)
private function __construct(WeakMap $cache = new WeakMap())
{
$this->cache = $cache;
}
Expand Down Expand Up @@ -78,12 +78,4 @@ private function rememberResourceType(Request $request, string $resourceType, ca

return $this->cache[$request][$resourceType] ??= $callback();
}

/**
* @return void
*/
public function flush()
{
$this->cache = new WeakMap();
}
}
11 changes: 2 additions & 9 deletions src/Support/Includes.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Illuminate\Support\Str;
use Symfony\Component\HttpKernel\Exception\HttpException;
use WeakMap;

use function explode;
use function is_array;

Expand All @@ -24,7 +25,7 @@ final class Includes
*/
private WeakMap $cache;

private function __construct(WeakMap $cache = new WeakMap)
private function __construct(WeakMap $cache = new WeakMap())
{
$this->cache = $cache;
}
Expand Down Expand Up @@ -80,12 +81,4 @@ private function rememberIncludes(Request $request, string $prefix, callable $ca

return $this->cache[$request][$prefix] ??= $callback();
}

/**
* @return void
*/
public function flush()
{
$this->cache = new WeakMap();
}
}
2 changes: 1 addition & 1 deletion tests/Feature/JsonApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
use Tests\TestCase;
use TiMacDonald\JsonApi\JsonApiResource;
use TiMacDonald\JsonApi\JsonApiResourceCollection;
use TiMacDonald\JsonApi\ServerImplementation;
use TiMacDonald\JsonApi\Link;
use TiMacDonald\JsonApi\RelationshipObject;
use TiMacDonald\JsonApi\ResourceIdentifier;
use TiMacDonald\JsonApi\ServerImplementation;

class JsonApiTest extends TestCase
{
Expand Down

0 comments on commit 93dfac0

Please sign in to comment.