feat: entity streaming
All checks were successful
Build Test / test (pull_request) Successful in 30s
JS Unit Tests / test (pull_request) Successful in 28s
PHP Unit Tests / test (pull_request) Successful in 1m8s

Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
2026-02-20 16:27:31 -05:00
parent 3374d3a287
commit 6bf3cb11e1
5 changed files with 45 additions and 46 deletions

View File

@@ -68,8 +68,8 @@ class Module extends ModuleInstanceAbstract implements ModuleBrowserInterface
{
// Register JMAP providers - all three share the same service store
$this->providerManager->register(ProviderInterface::TYPE_MAIL, 'jmap', MailProvider::class);
$this->providerManager->register(ProviderInterface::TYPE_CHRONO, 'jmap', ChronoProvider::class);
$this->providerManager->register(ProviderInterface::TYPE_PEOPLE, 'jmap', PeopleProvider::class);
//$this->providerManager->register(ProviderInterface::TYPE_CHRONO, 'jmap', ChronoProvider::class);
//$this->providerManager->register(ProviderInterface::TYPE_PEOPLE, 'jmap', PeopleProvider::class);
}
public function registerBI(): array {

View File

@@ -30,7 +30,7 @@ class MessageProperties extends MessagePropertiesMutableAbstract {
$this->data['size'] = $parameters['size'];
}
if (isset($parameters['receivedAt'])) {
$this->data['receivedDate'] = $parameters['receivedAt'];
$this->data['received'] = $parameters['receivedAt'];
}
if (isset($parameters['sentAt'])) {
$this->data['date'] = $parameters['sentAt'];

View File

@@ -22,9 +22,6 @@ use KTXM\ProviderJmapc\Stores\ServiceStore;
/**
* JMAP Mail Provider
*
* Provides Mail services via JMAP protocol.
* Filters services by urn:ietf:params:jmap:mail capability.
*/
class Provider implements ProviderServiceMutateInterface, ProviderServiceDiscoverInterface, ProviderServiceTestInterface
{
@@ -110,11 +107,6 @@ class Provider implements ProviderServiceMutateInterface, ProviderServiceDiscove
return $list;
}
public function serviceExtant(string $tenantId, string $userId, string|int ...$identifiers): array
{
return $this->serviceStore->extant($tenantId, $userId, $identifiers);
}
public function serviceFetch(string $tenantId, string $userId, string|int $identifier): ?Service
{
return $this->serviceStore->fetch($tenantId, $userId, $identifier);
@@ -132,6 +124,11 @@ class Provider implements ProviderServiceMutateInterface, ProviderServiceDiscove
return null;
}
public function serviceExtant(string $tenantId, string $userId, string|int ...$identifiers): array
{
return $this->serviceStore->extant($tenantId, $userId, $identifiers);
}
public function serviceFresh(): ResourceServiceMutateInterface
{
return new Service();

View File

@@ -9,6 +9,7 @@ declare(strict_types=1);
namespace KTXM\ProviderJmapc\Providers\Mail;
use Generator;
use KTXF\Mail\Collection\CollectionBaseInterface;
use KTXF\Mail\Collection\CollectionMutableInterface;
use KTXF\Mail\Object\Address;
@@ -32,11 +33,6 @@ use KTXM\ProviderJmapc\Providers\ServiceLocation;
use KTXM\ProviderJmapc\Service\Remote\RemoteMailService;
use KTXM\ProviderJmapc\Service\Remote\RemoteService;
/**
* JMAP Service
*
* Represents a configured JMAP account
*/
class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceConfigurableInterface, ServiceCollectionMutableInterface
{
public const JSON_TYPE = ServiceBaseInterface::JSON_TYPE;
@@ -105,16 +101,14 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC
public function __construct(
) {}
private function initialize(): void
{
private function initialize(): void {
if (!isset($this->mailService)) {
$client = RemoteService::freshClient($this);
$this->mailService = RemoteService::mailService($client);
}
}
public function toStore(): array
{
public function toStore(): array {
return array_filter([
'tid' => $this->serviceTenantId,
'uid' => $this->serviceUserId,
@@ -130,8 +124,7 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC
], fn($v) => $v !== null);
}
public function fromStore(array $data): static
{
public function fromStore(array $data): static {
$this->serviceTenantId = $data['tid'] ?? null;
$this->serviceUserId = $data['uid'] ?? null;
$this->serviceIdentifier = $data['sid'];
@@ -160,8 +153,7 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC
return $this;
}
public function jsonSerialize(): array
{
public function jsonSerialize(): array {
return array_filter([
self::JSON_PROPERTY_TYPE => self::JSON_TYPE,
self::JSON_PROPERTY_PROVIDER => self::PROVIDER_IDENTIFIER,
@@ -177,8 +169,7 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC
], fn($v) => $v !== null);
}
public function jsonDeserialize(array|string $data): static
{
public function jsonDeserialize(array|string $data): static {
if (is_string($data)) {
$data = json_decode($data, true, 512, JSON_THROW_ON_ERROR);
}
@@ -218,14 +209,9 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC
return isset($this->serviceAbilities[$value]);
}
public function capabilities(): array
{
$caps = [];
foreach (array_keys($this->serviceAbilities) as $cap) {
$caps[$cap] = true;
}
return $caps;
}
public function capabilities(): array {
return $this->serviceAbilities;
}
public function provider(): string
{
@@ -486,6 +472,22 @@ class Service implements ServiceBaseInterface, ServiceMutableInterface, ServiceC
return $list;
}
public function entityListStream(string|int $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): Generator
{
$this->initialize();
$result = $this->mailService->entityList($collection, $filter, $sort, $range, $properties);
foreach ($result['list'] as $index => $entry) {
if (is_array($entry) && isset($entry['id'])) {
$object = new EntityResource(provider: $this->provider(), service: $this->identifier());
$object->fromJmap($entry);
yield $object;
}
unset($result['list'][$index]);
}
}
public function entityListFilter(): Filter
{
return new Filter($this->serviceAbilities[self::CAPABILITY_ENTITY_LIST_FILTER] ?? []);