Hosted onnoosphere.hyper.mediavia theHypermedia Protocol

This document describes the Entities gRPC API used to read, search, discover, and manage hypermedia entities (documents, groups, accounts, comments) and their change DAGs.

Overview

  • Entity: a content addressable object (document, group, account alias, comment) with a timeline of Change nodes forming a DAG.

  • Timeline: per-entity DAG with roots, heads, and per-author “versions”.

  • Discovery: best-effort background task that finds/syncs blobs for a target entity and optionally its children.

  • Search: local fuzzy search over titles (default) and optionally bodies/comments.

Protobuf Definition

syntax = "proto3";

package com.seed.entities.v1alpha;

import "google/protobuf/timestamp.proto";

import "google/protobuf/empty.proto";

option go_package = "seed/backend/genproto/entities/v1alpha;entities";

// Provides functionality to query information about Hypermedia Entities.
service Entities {
  // Gets a change by ID.
  rpc GetChange(GetChangeRequest) returns (Change);

  // Gets the DAG of changes for an entity.
  rpc GetEntityTimeline(GetEntityTimelineRequest) returns (EntityTimeline);

  // Triggers a best-effort discovery of an entity.
  rpc DiscoverEntity(DiscoverEntityRequest) returns (DiscoverEntityResponse);

  // Finds the list of local entities whose titles match the input string.
  // A fuzzy search is performed among documents, groups and accounts.
  // For groups and documents, we match the title, while we match alias in accounts.
  rpc SearchEntities(SearchEntitiesRequest) returns (SearchEntitiesResponse);

  // Deletes an entity from the local node. It removes all the patches corresponding to it, including comments.
  rpc DeleteEntity(DeleteEntityRequest) returns (google.protobuf.Empty);

  // Lists deleted entities.
  rpc ListDeletedEntities(ListDeletedEntitiesRequest) returns (ListDeletedEntitiesResponse);

  // Undo the entity delition by removing the entity from the deleted list. That entity, if available
  // will be synced back in the next syncing round (or manually discovered).
  rpc UndeleteEntity(UndeleteEntityRequest) returns (google.protobuf.Empty);

  // List mentions of a given Entity across the locally-available content.
  rpc ListEntityMentions(ListEntityMentionsRequest) returns (ListEntityMentionsResponse);
}

// Request to get a change by ID.
message GetChangeRequest {
  // ID of the change.
  string id = 1;
}

// Request to get the timeline of an entity.
message GetEntityTimelineRequest {
  // The entity ID to get the timeline for.
  string id = 1;

  // Flag to include draft changes in the timeline,
  // otherwise they are omitted by default.
  bool include_drafts = 2;
}

// Request to discover an entity.
message DiscoverEntityRequest {
  // Required. The account the entity belongs to.
  string account = 1;

  // Required. The path of the wanted entity.
  string path = 2;

  // Optional. Version of the entity to discover.
  string version = 3;

  // Optional. If true, we sync the document and the child
  // documents as well.
  bool recursive = 4;
}

// Describes the state of the discovery task.
enum DiscoveryTaskState {
  // The task has just started.
  DISCOVERY_TASK_STARTED = 0;

  // The task is in progess — we keep looking for peers who can provide the content,
  // and downloading the content we are finding.
  DISCOVERY_TASK_IN_PROGRESS = 1;

  // The task has completed and the result is cached for the duration of the duration of the TTL.
  DISCOVERY_TASK_COMPLETED = 2;
}

// Response to discover an entity.
message DiscoverEntityResponse {
  // The cached version of the document we've discovered within the last discovery process.
  string version = 1;

  // The state of the discovery task.
  DiscoveryTaskState state = 2;

  // The number of times we've called the discovery process for this entity and version so far.
  int32 call_count = 3;

  // The timestamp of the last result we've found.
  // It can be empty if the discovery is still in progress.
  google.protobuf.Timestamp last_result_time = 4;

  // The cached error message of the last discovery attempt if it failed.
  string last_error = 5;

  // The time when the currently cached result will expire, and a new discovery attempt will be made,
  // if the client keeps calling the discovery RPC.
  // Can be empty if no results have been found yet.
  google.protobuf.Timestamp result_expire_time = 6;

  // The progress of the discovery process.
  DiscoveryProgress progress = 7;
}

// Various metrics reporting on the progress of the discovery process.
message DiscoveryProgress {
  // Number of peers we have found so far.
  int32 peers_found = 1;

  // Number of peers we have successfully synced with.
  int32 peers_synced_ok = 2;

  // Number of peers we have failed to sync with.
  int32 peers_failed = 3;

  // Number of blobs we have discovered so far.
  int32 blobs_discovered = 4;

  // Number of blobs we have successfully downloaded.
  int32 blobs_downloaded = 5;

  // Number of blobs we have failed to download.
  int32 blobs_failed = 6;
}

// A change to an entity.
message Change {
  // ID of the change.
  string id = 1;

  // Author of the change.
  string author = 2;

  // Timestamp when the change was created.
  google.protobuf.Timestamp create_time = 3;

  // IDs of other changes this change depends on.
  repeated string deps = 4;

  // IDs of other changes that depend on this change.
  repeated string children = 6;

  // Indicates whether this changes comes from a trusted peer of ours.
  bool is_trusted = 5;

  // Indicates whether this change is a draft.
  bool is_draft = 7;
}

// The timeline of an entity.
message EntityTimeline {
  // The ID of the entity.
  string id = 1;

  // Account ID of the owner of the entity.
  string owner = 2;

  // The set of changes for the entity keyed by change ID.
  map<string, Change> changes = 3;

  // The sorted list of change IDs by time.
  repeated string changes_by_time = 4;

  // The set of changes that has no dependencies.
  // Normally there should only be one root,
  // but just in case it's defined as a list.
  repeated string roots = 5;

  // The set of leaf changes considering the entire DAG.
  repeated string heads = 6;

  // The set of author versions/variants sorted by timestamp.
  repeated AuthorVersion author_versions = 7;
}

// Set of heads from a given author.
message AuthorVersion {
  // Account ID of the author.
  string author = 1;

  // The set of leaf changes from that author.
  repeated string heads = 2;

  // The version string corresponding to the author's variant.
  // I.e. same as heads but concatenated with a '.' delimiter.
  string version = 3;

  // The timestamp of the author's version.
  // For compound versions the greatest timestamp is used.
  google.protobuf.Timestamp version_time = 4;
}

// An entity record found
message Entity {
  // EID of the entity, including version, block id and range
  string id = 1;

  // Blob Id of the resource containing the matching record.
  string blob_id = 2;

  // The time of the version of the entity.
  google.protobuf.Timestamp version_time = 3;

  // In the case of comments, the document id
  // containing the comment.
  string doc_id = 4;

  // Content of the entity, depending on the type:
  // Alias in the case of account.
  // Title/Body in the case of groups and documents.
  // Body in the case of comments. We don't fill up the whole
  // block, just the part that contains the search term, with
  // the surrounding context. The context size is defined by
  // the context_size parameter.
  string content = 5;

  // The owner of the entity
  string owner = 6;

  // The type of the entity it coud be Title, Document, Comment, ...
  string type = 7;

  // Icon of the document containing that entity
  string icon = 8;

  // Parent document names
  repeated string parent_names = 9;

  // Metadata of the document containing that entity.
  string metadata = 10;
}

// Publication that has been deleted
message DeletedEntity {
  // EID of the deleted entity.
  string id = 1;

  // When the entity was deleted.
  google.protobuf.Timestamp delete_time = 2;

  // Reason why this entity was deleted.
  string deleted_reason = 3;

  // Further metadata about the deleted entity, title, etc ...
  string metadata = 4;
}
// Request to
message SearchEntitiesRequest {
  // Query to find. We Ssupport wildcards and phrases.
  // See https://sqlite.org/fts5.html#full_text_query_syntax.
  string query = 1;

  // Whether to look into all content available or just the titles.
  // If false, comments are not included in the search.
  // Default is false.
  bool include_body = 2;

  // Optional. The size of the text accompanying the search match.
  // Half of the size is before the match, and half after.
  // Default is 48 runes.
  int32 context_size = 3;

  // Optional. The account uid to filter the search by.
  // If not set, the search will be performed across all accounts.
  string account_uid = 4;

  // Optional. The account uid the user is logged in with.
  // This is used to filter out contacts that the user doesn't have access to.
  // If not set, we won't provide any contact entities in the response.
  string logged_account_uid = 5;
}

// A list of entities matching the request.
message SearchEntitiesResponse {
  // Entities matching the input title
  repeated Entity entities = 1;

  // Token for the next page if there's any.
  string next_page_token = 2;
}

// Request for deleting an entity.
message DeleteEntityRequest {
  // Entity ID of the entity to be removed.
  // All versions will also be removed.
  string id = 1;

  // Optional. Reason why the user wants to delete that entity.
  string reason = 2;
}

// Request for listing deleted entities.
message ListDeletedEntitiesRequest {
  // Optional. Number of results per page. Default is defined by the server.
  int32 page_size = 1;

  // Optional. Value from next_page_token obtains from a previous response.
  string page_token = 2;
}

// Response with list of deleted entities.
message ListDeletedEntitiesResponse {
  // List of deleted entities.
  repeated DeletedEntity deleted_entities = 1;

  // Token for the next page if there're more results.
  string next_page_token = 2;
}

// Request for restoring an entity.
message UndeleteEntityRequest {
  // Entity ID of the entity to be restored.
  // All versions will also be restored.
  string id = 1;
}

// Request to list mentions of an entity.
message ListEntityMentionsRequest {
  // Required. ID of the entity to list mentions for.
  string id = 1;

  // Optional. The size of the page to return by the server.
  // The server may ignore this, and return a bigger response.
  int32 page_size = 2;

  // Optional. The page token to continue the pagination.
  string page_token = 3;

  // Optional. Whether to return the results in descending order (newest-first).
  // By default mentions are listed in the chronological order,
  // according to the *locally perceived* order of the blobs that contain the mentions.
  //
  // I.e. we sort the links according to the time we receive the blobs, not according to the time blobs claim to have been created.
  // This is to prevent losing new mentions in case of receiving out-of-date blobs.
  //
  // This flag must remain the same when paginating through the results.
  bool reverse_order = 4;
}

// Response to list mentions of an entity.
message ListEntityMentionsResponse {
  // Required. The list of mentions for the entity.
  repeated Mention mentions = 1;

  // Optional. Token for the next page if there's any.
  string next_page_token = 2;
}

// Mention of an Entity.
// Source means the place where the mention was found.
// Target means the entity being mentioned.
message Mention {
  // Information about a structural blob that contains the mention.
  message BlobInfo {
    // The CID-formatted hash of the blob.
    string cid = 1;

    // The Account ID of the author of the blob.
    string author = 2;

    // The timestamp of the blob.
    google.protobuf.Timestamp create_time = 3;
  }

  // Required. The source blob where the mention was found.
  string source = 1;

  // Required. The Type of the source where the mention was found.
  string source_type = 2;

  // Required. Context can mean different things depending on the type of the source:
  // it can be the block ID when source type is a Document or Comment,
  // it can be a pretty-path when source type is a Group that mentions a Document.
  string source_context = 3;

  // Required. Information about the blob where the mention was found.
  BlobInfo source_blob = 4;

  // Required. Specifies whether the link points to the exact/pinned version of the target document,
  // or if the target version is a *suggested* minimum version, and a later one should be preferred if exists.
  bool is_exact_version = 5;

  // Optional. Specifies the document where the mention was found. Relevant for comments.
  string source_document = 6;

  // Optional. The version of the target Entity the link points to,
  // if one is specified in the link.
  string target_version = 7;

  // Optional. The fragment portion of the link.
  string target_fragment = 8;

  // Optional. The type of mention. Could be embed, link, ...
  string mention_type = 9;
}

Do you like what you are reading?. Subscribe to receive updates.

Unsubscribe anytime