You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is an idea for possible feature we could implement (in part or in full). Currently we're assuming that document store provides an acyclic graph structure. Linking back to other fields is also not supported, however sometimes it seems it could be beneficial. Keeping live status of changed fields in other structures is technically possible using collection observer events, but it's definitely a suboptimal way to go.
To fill this gap, we could provide a new type of item content like ContentLink, which would allow to reference to other shared structures. It's purpose would be to allow users to read the referenced state and react to it as it changes. React here also means it could be integrated with event system (changes at link source would trigger event observers in collections where these link blocks were integrated in).
Below I'll discuss some of the properties, we could implement:
Use case 1: referencing data from another collection
This is the simplest variant - link A(key|index) to have value of B(key|index). For indexes it means "index at a moment of establishing a link" and in practice we could realize it using StickyIndexes.
let doc = Doc::new();let a = doc.get_or_insert_map("A");let b = doc.get_or_insert_map("B");letmut txn = doc.transact_mut();
a.insert(&mut txn,"A1","1");// => { A1: 1 }
b.insert(&mut txn,"B1","2");// => { B1: 2 }let link = a.link_to(&txn,"A1");
b.insert(&mut txn,"B2", link);// => { B1: 2, B2: 1 }// change linked value from '1' -> '3'
a.insert(&mut txn,"A1","3");let value = b.get(&txn,"B2");assert_eq!(value, Some(3.into()));
Use case 2: quotations
Another option is to have a link that describes a range of values (start..end, also implemented with StickyIndexes) instead of a single one. This way we could i.e. implement text quotations, that maintain the current state of quoted piece of text (which is not always desired but sometimes it is):
let doc = Doc::new();let a = doc.get_or_insert_text("A");let b = doc.get_or_insert_text("B");letmut txn = doc.transact_mut();
a.push(&mut txn,"hello ");// => 'hello '
b.push(&mut txn,"world");// => 'world'let quote = b.quote(&txn,0,5);// => 'world'
a.insert_embed(&mut txn,6, quote);// => 'hello world'// modify text inside of quoted range
b.insert(&mut txn,2,"o");// => quoted range changed 'woorld'let str = a.get_string(&txn);assert_eq!(str, "hello woorld");
For text specifically this could potentially require additional consideration: what to do with formatting? Quoted text piece may be within formatted attributes range, however the beginning of a ContentFormat itself maybe outside of that range. For quotations we would probably expect them to be carried over. Tbh. I've already was thinking about having some index along the text that would allow for fast mapping of formatting attribute ranges into blocks.
Use case 3: computed cells
The last - also most powerful and the hardest to implement - would be to offer an ability of computing elements over multiple linked fields into a new value. Example - excel spreadsheets:
Here the biggest problem is actually how to propagate custom computations as Yrs updates. Technically we could do so by integrating WebAssembly modules - make calc! macro to be converted into WASM function, compile it and put instruction bytes as a binary payload. WASM also gives a huge degree of control (we could let users define their own well-known functions to be used within custom cells, just like i.e. Excel defines its core library of functions) and supports pretty much any language.
The main problem is that WASM comes with a huge complexity cost. For this reason I'd consider this feature as a separate one to think about in the future.
Other considerations
Circular references
The biggest challenge is of course about risk of circular references. We cannot really "just" prevent them as updates are done concurrently and while they individually don't produce any circular conflicts, when merged they could. With move feature the proposal was to delete both blocks that could produce circular loop upon merge and we could use the same here.
Another option is to allow circular references in some scenarios and produce errors/exceptions (but never infinite loops) when they are used in other scenarios eg. mapA[key1] = link(mapB); mapB[key2] = link(mapA) which technically is not an issue as long as you don't try produce JSON out of it.
The text was updated successfully, but these errors were encountered:
Feature proposal: Live Links
This is an idea for possible feature we could implement (in part or in full). Currently we're assuming that document store provides an acyclic graph structure. Linking back to other fields is also not supported, however sometimes it seems it could be beneficial. Keeping live status of changed fields in other structures is technically possible using collection observer events, but it's definitely a suboptimal way to go.
To fill this gap, we could provide a new type of item content like
ContentLink
, which would allow to reference to other shared structures. It's purpose would be to allow users to read the referenced state and react to it as it changes. React here also means it could be integrated with event system (changes at link source would trigger event observers in collections where these link blocks were integrated in).Below I'll discuss some of the properties, we could implement:
Use case 1: referencing data from another collection
This is the simplest variant - link
A(key|index)
to have value ofB(key|index)
. For indexes it means "index at a moment of establishing a link" and in practice we could realize it usingStickyIndex
es.Use case 2: quotations
Another option is to have a link that describes a range of values (start..end, also implemented with
StickyIndex
es) instead of a single one. This way we could i.e. implement text quotations, that maintain the current state of quoted piece of text (which is not always desired but sometimes it is):For text specifically this could potentially require additional consideration: what to do with formatting? Quoted text piece may be within formatted attributes range, however the beginning of a
ContentFormat
itself maybe outside of that range. For quotations we would probably expect them to be carried over. Tbh. I've already was thinking about having some index along the text that would allow for fast mapping of formatting attribute ranges into blocks.Use case 3: computed cells
The last - also most powerful and the hardest to implement - would be to offer an ability of computing elements over multiple linked fields into a new value. Example - excel spreadsheets:
Here the biggest problem is actually how to propagate custom computations as Yrs updates. Technically we could do so by integrating WebAssembly modules - make
calc!
macro to be converted into WASM function, compile it and put instruction bytes as a binary payload. WASM also gives a huge degree of control (we could let users define their own well-known functions to be used within custom cells, just like i.e. Excel defines its core library of functions) and supports pretty much any language.The main problem is that WASM comes with a huge complexity cost. For this reason I'd consider this feature as a separate one to think about in the future.
Other considerations
Circular references
The biggest challenge is of course about risk of circular references. We cannot really "just" prevent them as updates are done concurrently and while they individually don't produce any circular conflicts, when merged they could. With move feature the proposal was to delete both blocks that could produce circular loop upon merge and we could use the same here.
Another option is to allow circular references in some scenarios and produce errors/exceptions (but never infinite loops) when they are used in other scenarios eg.
mapA[key1] = link(mapB); mapB[key2] = link(mapA)
which technically is not an issue as long as you don't try produce JSON out of it.The text was updated successfully, but these errors were encountered: