-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to access stored documents on the server? #103
Comments
Hi, the demo somehow shows that: https://github.com/y-crdt/ydotnet/blob/main/Demo/Callback.cs You can implement a callback and then listen to changes on the client. This would be one way. Another option could be the following method: But you are right, there is no option to get all documents right now. I am not sure if this is really needed, as I would only make the change if a user is actually connected. |
Thanks a lot for your input! In my use case, what I want to achieve is to have an API endpoint that iterates over todo items and assigns them labels created by an algorithm. I want to trigger this via an API endpoint since finding which labels to use requires an LLM call, which I don't want to perform every time each todo item changes. With your hint on public async Task<IEnumerable<TaskModel>> GetAllTasksAsync(CancellationToken cancellationToken = default)
{
var tasks = new List<TaskModel>();
var context = new DocumentContext("shoppr", 0);
await documentManager.UpdateDocAsync(
context, doc =>
{
var docTasks = doc.Array("tasks");
using var transaction = docTasks.ReadTransaction();
tasks.AddRange(docTasks.Iterate(transaction).Select(output => output.To<TaskModel>(transaction)));
}, cancellationToken);
return tasks;
} Do you recognize any obvious issues with this approach? I'd then modify the tasks and push them back in using another |
No, this looks good to me. |
Then thanks for your help, I appreciate it! |
If you need an endpoint to fetch all documents, a PR would be welcome :) |
I'll try to add one to Currently, I need to specify a |
Separate PRs are always welcome. |
Alright, will do :) Another question I came across while trying to update the tasks in the document: Is there a way to modify an element in a doc array instead of removing and then adding it back in? Like I mentioned, I'm converting my [Edit] System.Runtime.InteropServices.SEHException (0x80004005): External component has thrown an exception.
at YDotNet.Native.Types.ArrayChannel.InsertRange(IntPtr array, IntPtr transaction, UInt32 index, IntPtr items, UInt32 itemsLength)
at YDotNet.Document.Types.Arrays.Array.InsertRange(Transaction transaction, UInt32 index, Input[] inputs)
at Shoppr.Api.Domain.Database.YDbContext.<>c__DisplayClass4_0`1.<UpdateArrayAsync>b__0(Doc doc) in C:\repos\shoppr\backend\shoppr-backend\Shoppr.Api\Domain\Database\YDbContext.cs:line 42
at YDotNet.Server.DefaultDocumentManager.<>c__DisplayClass10_0.<<UpdateDocAsync>b__0>d.MoveNext() The code is as follows (pretty similar to querying all elements): public async Task UpdateArrayAsync<T>(string collectionName, IEnumerable<ArrayElement<T>> items, CancellationToken cancellationToken = default)
{
await documentManager.UpdateDocAsync(
_documentContext, doc =>
{
var docArray = doc.Array(collectionName);
foreach (var item in items)
{
using var transaction = docArray.WriteTransaction();
docArray.RemoveRange(transaction, item.Index, 1);
docArray.InsertRange(transaction, item.Index, [item.Item.ToInput()]);
transaction.Commit();
}
}, cancellationToken);
} Not sure what's going on here tbh, but a little guidance would be greatly appreciated :) [Edit 2] |
If you have an array of objects you can just modify the objects. There might be exceptions like these, because it is a very new library but I hope we can always fix them asap. Perhaps we should also add a method to replace an element. |
I don't know how much work it is, but would it be possible to release a 0.4.1 patch including the fix you provided in #99? I tried setting up the dev environment, built the y-crdt libraries as specified and also the YDotNet.Native.Win32 dll. When referencing the built dll in my project, I keep running into the following error:
Any idea what I'm missing? As far as I can see in the y-crdt repo, there's only |
Thanks for updating to 0.4.1 :) Appreciate it! After some fiddling and still receiving the Input ConvertObject(JsonElement element)
{
// Works
return Input.Map(element.EnumerateObject().ToDictionary(x => useCamelCaseNames ? x.Name.ToCamelCase() : x.Name, x => ConvertValue(x.Value), StringComparer.Ordinal));
// Results in Unrecognized YVal value tag. as mentioned in #99.
return Input.Object(element.EnumerateObject().ToDictionary(x => useCamelCaseNames ? x.Name.ToCamelCase() : x.Name, x => ConvertValue(x.Value), StringComparer.Ordinal));
} [Edit] I've attempted to construct an
|
No idea at the moment. I will have to dig into that. Is there no test that covers that? |
I have no idea tbh. I'd appreciate you looking into the issue as being able to write JsonArrays and JsonObjects would simplify my code immensely. There's currently a workaround by storing all objects as YArray and YMap in the frontend (you'll also need to convert all children of the objects if they're objects or arrays). Then you're able to write to them in the backend. When I get back from vacation, I'll try to dig a bit deeper as well. |
First of all, thank you so much for the work you've done. I love this project, it's been so easy to add offline-first synchronization to my web app and C# backend using Yjs and this package for the server.
I'm currently struggling with how to modify documents on the server-side. I'm using the MongoDb Server and want to create a separate REST endpoint that my client apps can call (while online) to sort the objects stored in the document (using SyncedStore in the client projects). For this, I'd like to retrieve all objects stored in MongoDb and convert them to class instances that I have in the backend, modify them and then write them back to the store to be propagated to all clients.
Maybe I'm not searching right, but I haven't seen any methods to retrieve a stored document on the server and cast it's contents to my class types. Should I be using the IDocumentManager interface and if so, is there an example on what exactly you need to do?
[Edit]
In re-reading the example provided, I think it became more clear how the synchronization is supposed to work, but I'm still unsure as to how the connection is made from the server acting as a client and server for the documents at the same time. How would I retrieve a remote document? On the web clients I open my connections to the websocket API provided by the server, but I don't see how this would be done from the server directly.
The text was updated successfully, but these errors were encountered: