* SPDX-License-Identifier: AGPL-3.0-or-later */ namespace KTXF\Documents\Service; use Generator; use KTXF\Documents\Collection\CollectionBaseInterface; use KTXF\Documents\Entity\EntityBaseInterface; use KTXF\Resource\Delta\Delta; use KTXF\Resource\Filter\IFilter; use KTXF\Resource\Identifier\EntityIdentifierInterface; use KTXF\Resource\Provider\ResourceServiceBaseInterface; use KTXF\Resource\Range\IRange; use KTXF\Resource\Range\RangeType; use KTXF\Resource\Sort\ISort; /** * Service Base Interface * * Minimum interface for a service, providing read-only access to collections and entities. * * @since 2025.05.01 */ interface ServiceBaseInterface extends ResourceServiceBaseInterface { // Collection capabilities public const CAPABILITY_COLLECTION_LIST = 'CollectionList'; public const CAPABILITY_COLLECTION_LIST_FILTER = 'CollectionListFilter'; public const CAPABILITY_COLLECTION_LIST_SORT = 'CollectionListSort'; public const CAPABILITY_COLLECTION_EXTANT = 'CollectionExtant'; public const CAPABILITY_COLLECTION_FETCH = 'CollectionFetch'; // Collection Filter public const CAPABILITY_COLLECTION_FILTER_LABEL = 'label'; public const CAPABILITY_COLLECTION_FILTER_CONTENTS = 'contents'; // Collection Sort public const CAPABILITY_COLLECTION_SORT_LABEL = 'label'; public const CAPABILITY_COLLECTION_SORT_RANK = 'rank'; // Entity capabilities public const CAPABILITY_ENTITY_LIST = 'EntityList'; public const CAPABILITY_ENTITY_LIST_FILTER = 'EntityListFilter'; public const CAPABILITY_ENTITY_LIST_SORT = 'EntityListSort'; public const CAPABILITY_ENTITY_LIST_RANGE = 'EntityListRange'; public const CAPABILITY_ENTITY_DELTA = 'EntityDelta'; public const CAPABILITY_ENTITY_EXTANT = 'EntityExtant'; public const CAPABILITY_ENTITY_FETCH = 'EntityFetch'; public const CAPABILITY_ENTITY_READ = 'EntityRead'; // Filter capabilities public const CAPABILITY_ENTITY_FILTER_ALL = '*'; public const CAPABILITY_ENTITY_FILTER_ID = 'id'; public const CAPABILITY_ENTITY_FILTER_URID = 'urid'; public const CAPABILITY_ENTITY_FILTER_LABEL = 'label'; // Sort capabilities public const CAPABILITY_ENTITY_SORT_ID = 'id'; public const CAPABILITY_ENTITY_SORT_URID = 'urid'; public const CAPABILITY_ENTITY_SORT_LABEL = 'label'; public const CAPABILITY_ENTITY_SORT_PRIORITY = 'priority'; // Range capabilities public const CAPABILITY_ENTITY_RANGE_TALLY = 'tally'; public const CAPABILITY_ENTITY_RANGE_TALLY_ABSOLUTE = 'absolute'; public const CAPABILITY_ENTITY_RANGE_TALLY_RELATIVE = 'relative'; public const JSON_TYPE = 'document:service'; /** * Lists all collections in this service * * @since 2025.05.01 * * @param string|int|null $location Optional parent collection identifier to list within (null for root) * @param IFilter|null $filter Optional filter criteria * @param ISort|null $sort Optional sort order * * @return array Collections indexed by identifier */ public function collectionList(string|int|null $location, ?IFilter $filter = null, ?ISort $sort = null): array; /** * Creates a filter builder for collections * * @since 2025.05.01 * * @return IFilter */ public function collectionListFilter(): IFilter; /** * Creates a sort builder for collections * * @since 2025.05.01 * * @return ISort */ public function collectionListSort(): ISort; /** * Checks if collections exist * * @since 2025.05.01 * * @param string|int|null $location Optional parent collection identifier (null for root) * @param string|int ...$identifiers Collection identifiers to check * * @return array Map of identifier => exists */ public function collectionExtant(string|int|null $location, string|int ...$identifiers): array; /** * Fetches a single collection * * @since 2025.05.01 * * @param string|int $identifier Collection identifier * * @return CollectionBaseInterface|null Collection or null if not found */ public function collectionFetch(string|int $identifier): ?CollectionBaseInterface; /** * Lists entities in a collection * * @since 2025.05.01 * * @param string|int|null $collection Collection identifier (null for root) * @param IFilter|null $filter Optional filter criteria * @param ISort|null $sort Optional sort order * @param IRange|null $range Optional pagination * @param array|null $properties Optional entity properties to fetch * * @return array Entities indexed by identifier */ public function entityListBulk(string|int|null $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): array; /** * Lists entities in a collection * * @since 2025.05.01 * * @param string|int|null $collection Collection identifier (null for root) * @param IFilter|null $filter Optional filter criteria * @param ISort|null $sort Optional sort order * @param IRange|null $range Optional pagination * @param array|null $properties Optional entity properties to fetch * * @return Generator Yields entities one by one as EntityBaseInterface */ public function entityListStream(string|int|null $collection, ?IFilter $filter = null, ?ISort $sort = null, ?IRange $range = null, ?array $properties = null): Generator; /** * Creates a filter builder for entities * * @since 2025.05.01 * * @return IFilter */ public function entityListFilter(): IFilter; /** * Creates a sort builder for entities * * @since 2025.05.01 * * @return ISort */ public function entityListSort(): ISort; /** * Creates a range builder for entities * * @since 2025.05.01 * * @param RangeType $type Range type (offset, cursor, etc.) * * @return IRange */ public function entityListRange(RangeType $type): IRange; /** * Gets incremental changes since last signature * * @since 2025.05.01 * * @param string|int|null $collection Collection identifier (null for root) * @param string $signature Token from previous delta * * @return Delta */ public function entityDelta(string|int|null $collection, string $signature): Delta; /** * Checks if entities exist * * @since 2025.05.01 * * @param string|int|null $collection Collection identifier (null for root) * @param string|int ...$identifiers Entity identifiers to check * * @return array Map of identifier => exists */ public function entityExtant(string|int|null $collection, string|int ...$identifiers): array; /** * Fetches one or more entities as an array * * @since 2025.05.01 * * @param EntityIdentifierInterface ...$identifiers Entity identifiers to fetch * * @return array Entities indexed by identifier */ public function entityFetchBulk(EntityIdentifierInterface ...$identifiers): array; /** * Fetches one or more entities as a stream * * @since 2025.05.01 * * @param EntityIdentifierInterface ...$identifiers Entity identifiers to fetch * * @return Generator Yields entities one by one */ public function entityFetchStream(EntityIdentifierInterface ...$identifiers): Generator; /** * Reads the full content of an entity * * @since 2025.05.01 * * @param EntityIdentifierInterface $target Target entity identifier * * @return string|null Entity content or null if not found */ public function entityRead(EntityIdentifierInterface $target): ?string; /** * Opens a read stream for the content of an entity * * @since 2025.05.01 * * @param EntityIdentifierInterface $target Target entity identifier * * @return resource|null Read stream or null if not found */ public function entityReadStream(EntityIdentifierInterface $target); /** * Reads a chunk of the content of an entity * * @since 2025.05.01 * * @param EntityIdentifierInterface $target Target entity identifier * @param int $offset Byte offset to start reading from * @param int $length Number of bytes to read * * @return string|null Content chunk or null if not found */ public function entityReadChunk(EntityIdentifierInterface $target, int $offset, int $length): ?string; }