use crate*; pub use *; /// Create a link from a base hash to a target hash, with an optional tag. /// /// Links represent the general idea of relationships between data. /// /// Links are different from the tree of CRUD relationships: /// /// Links: /// /// - reference two hashes, base and target, and can be a local entry/action or some external hash /// - there is only one way to create a link, validation logic depends on only the base+target+tag /// - can represent circular references because only hashes are needed /// - support arbitrary bytes of data (i.e. "tag") that can be read or used to filter gets /// - deletes always point to a _specific_ link creation event, not the link itself /// - model dynamic sets of or relationships between things /// - can reference any hash regardless of type (e.g. posts can link to comments) /// /// Note: There is a hard limit of 1kb of data for the tag. /// /// CRUD: /// /// - creates reference a single entry /// - updates and deletes reference create/update records by both their entry+action /// - creates, updates and deletes all have different functions, network ops and validation logic /// - is cryptographically guaranteed to be a DAG (not-circular) because they include actions /// - model "mutability" for a single thing/identity in an immutable/append-only way /// - only reference other entries of the same entry type (e.g. comments can _not_ update posts) /// /// See [ `get_details` ] and get for more information about CRUD /// See [ `get_links` ] and [ `get_link_details` ] for more information about filtering by tag /// /// Generally links and CRUDs _do not interact_ beyond the fact that links need hashes to /// reference for the base and target to already exist due to a prior create or update. /// The referenced data only needs to exist on the DHT for the link to validate, it doesn't need to be /// live and can have any combination of valid/invalid crud actions. /// i.e. if you use link_entries! to create relationships between two entries, then update_entry /// on the base, the links will still only be visible to get_link(s_details)! against the original /// base, there is no logic to "bring forward" links to the updated entry because: /// /// - as per CRUD tree docs there is no "one size fits all" way to walk a tree of CRUDs /// - links are very generic and could even represent a comment thread against a specific revision /// such as those found against individual updates in a wiki/CMS tool so they need to stay where /// they were explicitly placed /// - it would actually be pretty crazy at the network layer to be gossiping links around to chase /// the "current revision" even if you could somehow unambiguously define "current revision" /// /// This can be frustrating if you want "get all the links" for an entry but also be tracking your /// revision history somehow. /// A simple pattern to workaround this is to create an immutable (updates and deletes are invalid) /// "identity" entry that links reference and is referenced as a field on the entry struct of each /// create/update action. /// If you have the hash of the identity entry you can get all the links, if you have the entry or /// action hash for any of the creates or updates you can lookup the identity entry hash out of the /// body of the create/update entry. /// Delete a specific link creation record. /// /// Links are defined by a [OR-Set CRDT](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type#OR-Set_(Observed-Remove_Set)) /// of "Creates" and "Deletes". /// The deletes form a "tombstone set", each of which can nullify one of the creates. /// A link only "exists" if it has one or more "creates" which have not been nullified by a "delete". /// /// For this reason the delete references the Create Action, not the Entry. /// Even more than that, both creates and deletes are _only_ actions, there is no separate entry /// and the delete is not simply a renamed mirror of the create (i.e. with base and target). /// /// Consider what would happen if the system simply had "create link" and "delete link" pointing at /// the base and target without pairing: /// - there would be no way to revert a specific link creation /// - a delete may be intended for an create you haven't seen yet, so network unpredictability /// would cause re-ording of any view on create/deletes which means an agent can see more deletes /// than creates, etc. /// - there would only be two ways to summarise the state of a relationship between two entries, /// either "there are N more/less creates than deletes" or "there is at least one delete", the /// former leads to flakiness as above and the latter means it would be impossible to create a /// link after any previous delete of any link. /// All of this is bad so link creates point to entries (See [ `create_link` ]) and deletes point to /// creates. /// Returns all links that reference a base hash, optionally filtered by link type and tag. /// /// Type can be filtered by providing a variant of the link types or the full range operator. Get links of /// all types like this: `get_links(base, .., None)`. Refer to the `get_links` function in /// [this coordinator zome](https://github.com/holochain/holochain/blob/develop/crates/test_utils/wasm/wasm_workspace/link/src/coordinator.rs) /// for examples. /// /// _Note this will only get links that are defined in dependent integrity zomes._ /// /// Tag filtering is a simple bytes prefix. /// /// e.g. if you had these links: /// - a: `[ 1, 2, 3]` /// - b: `[ 1, 2, 4]` /// - c: `[ 1, 3, 5]` /// /// Then tag filters: /// - `[ 1 ]` returns `[ a, b, c]` /// - `[ 1, 2 ]` returns `[ a, b ]` /// - `[ 1, 2, 3 ]` returns `[ a ]` /// - `[ 5 ]` returns `[ ]` (does _not_ return c because the filter is by "prefix", not "contains") /// /// This is mostly identical to [ `get_link_details` ] but returns only creates that have not been /// deleted, whereas `get_link_details` returns all the creates and all the deletes together. /// Also note that, unlike when [ `get` ] is used to retrieve an entry, links that /// only differ by author and creation time are not deduplicated; hence, you may receive multiple /// links with the same base, tag, and target. /// /// See [ `get_link_details` ]. /// Get all link creates and deletes that reference a base hash, optionally filtered by type or tag. /// /// Type can be filtered by providing a variant of the link types, or a range of them. To get links of /// all types, the full range operator can be used: `get_links(base, .., None)`. Furthermore, vectors of /// link types can be passed in to specify multiple types. Refer to the `get_links` function in /// [this coordinator zome](https://github.com/holochain/holochain/blob/develop/crates/test_utils/wasm/wasm_workspace/link/src/coordinator.rs) /// for several examples. /// /// Tag filtering is a simple bytes prefix. /// /// e.g. if you had these links: /// - a: `[ 1, 2, 3]` /// - b: `[ 1, 2, 4]` /// - c: `[ 1, 3, 5]` /// /// then tag filters: /// - `[ 1 ]` returns `[ a, b, c]` /// - `[ 1, 2 ]` returns `[ a, b ]` /// - `[ 1, 2, 3 ]` returns `[ a ]` /// - `[ 5 ]` returns `[ ]` (does _not_ return c because the filter is by "prefix", not "contains") /// /// This is mostly identical to get_links but it returns all the creates and all the deletes. /// c.f. get_links that returns only the creates that have not been deleted. /// /// See [ `get_links` ].