Dumb DOM API questions

@bochaco Reading the documentation for window.safeNfs.update(), it appears to be the only Nfs method that requires a version parameter [edit, actuall delete() does too]. Is this correct? It seems odd that it’s the only one, and if version is required that there’s no way to obtain this from the Nfs APIs, only the underlying container. Thanks.

EDIT 1: Another question - we can obtain file metadata with window.safeNfsFile.metadata(), but how can we set this?

EDIT 2: It might be useful to be able to get the MutableDataHandle from an Nfs API using the NFSHandle.

EDIT 3: If I want to read the whole file, can I pass -1 as len, or do I first need to get the file length first in order to call window.safeNfsFile.read(fileHandle, position, len)?

EDIT 4: Returning to the initial question of how to use versions, should I not be able to specify the version when I want to read or write to it? So for example as part of fetch or open?

Hey @bochaco, thanks for looking into it. I haven’t had time to work more on it but since the problem is only on my side I’ll probably figure it out some way of another, I’ll let you know if I find exactly what I did wrong. Thanks again and keep up the good work, it’s shaping up pretty well.

Cheers!

1 Like

@bochaco I amended /added to my question (previous post but one) so letting you know! On the version stuff, I think it would be good to say more in the API docs, and also to have a longer expansion with code fragments somewhere - a new topic here would be great for now.

@hunterlester this issue is now blocking me as I can’t test my code and it isn’t intermittent:

2 Likes

Please note this is the NFS File’s metadata and not the MutableData’s metadata. I don’t think there is anything you would need to set in the NFS File’s metadata, and the MD metadata can be set with MD’s setMetadata function.

Yes, although you have it in the first place, so it’s just a matter of keeping it in a variable which I think would also be preferable in order to avoid an unnecessary call to the libs to fetch what you already have. I’ll add it to the list as a nice-to-have anyway.

You can pass 0 to do that, and we have a task (MAID-2337) to expose constants for those type of things, you can see the safe_app_nodejs already use them internally here: https://github.com/bochaco/safe_app_nodejs/blob/master/src/consts.js#L32

That’s the MD entry’s version, so for reading/open you shouldn’t need it, I think the current version can be read from the NFS File’s metadata.

So dumb question but how do you create a subfolder using the NFS API? Or, is it that there is no real folder structure and that it’s just the name of the file within the MD that contain the folder path as a prefix?

Like:
filename: “/css/style.css”

So in other word we can’t create empty subfolder?

I got to say, there’s a bit of a steep learning curve to use the API. And my code looks like crap cause I don’t master the promise flow of coding, but that’s my problem eheh.

2 Likes

There are no such things as true “folders” on the network, you use slashes to represent that the files are within folders.

Hierarchy File-System Emulation
When dealing with folders and files being uploaded that are within subdirectories it is recommended to use a slash (/) to separate the subdirectory and the file name.
This means the key of the Mutable Data could look something like this: filepath/subdir/index.html.

Taken from here

2 Likes

Alright, so the only way to “navigate” through a tree-like structure is to parse all keys from a container and fake it on the app side correct?

Also, this means that currently a container can only contain up to 100 files (or is it 1000 now?).

2 Likes

Increase the maximum number of allowed entries in a Mutable Data object from 100 to 1000.

Yea you will have to do on the app side, I am working a website that shows how that will work (hopefully) not too long from now.

2 Likes

I’m working in this NFS area too, and also wrestling with promises, so I feel your pain :-/

4 Likes

What’s the best way to free a handle in a chain of promises? I find myself having to “nest” my calls instead of chaining them because if I simply chain them I lose the reference of the handle used previously so I can’t free it once the chain is done.

Or a simple example of the problem:

window.safeMutableDataEntries.forEach(entriesHandle, (k, v) => {

    let key = String.fromCharCode.apply(null, k);
    let value = String.fromCharCode.apply(null, new Uint8Array(v.buf));

    console.log(key + ': ' + value);
  }).then(_ => {
    // You can't free entriesHandle here since it is not in scope
    return 'Iteration complete' + _;
  });
}

What I end up doing is create a variable outside of the promise, assign the handle to it and then free it using the outside variable like:

var handle_to_erase;
window.safeMutableDataEntries.forEach(entriesHandle, (k, v) => {
handle_to_erase = entriesHandle;
let key = String.fromCharCode.apply(null, k);
let value = String.fromCharCode.apply(null, new Uint8Array(v.buf));

    console.log(key + ': ' + value);
  }).then(_ => {
    window.safeMutableDataEntries.free(handle_to_erase);
    return 'Iteration complete' + _;
  });
}

So what’s the best way to handle handles? :slight_smile:

2 Likes

Another question:

When I remove an entry, it simply erases its value, the key of the entry is still present in the MD, is that a bug or am I missing a step?

1 Like

My solution was this:

function sendMessage() {
  window.safeMutableData.newMutation(auth)
    .then((mutationHandle) => {
      var date = new Date();
      var time = date.getTime();
      window.safeMutableDataMutation.insert(mutationHandle, time.toString(), textarea.value)
        .then(_ =>
          window.safeMutableData.applyEntriesMutation(mdHandle, mutationHandle))
        .then(_ => {
          Materialize.toast('Message has been sent to the network', 3000, 'rounded');
          window.safeMutableDataMutation.free(mutationHandle);
          getMutableDataHandle("getMessages");
        });
      textarea.value = "";

    });
}

example taken from Chaty. As far as I know nesting is the best way, but it should be possible to pass the handle as either a variable for chaining or a paramenter when doing a callback.

As far as I know you aren’t suppose to be able to remove the key from a Mutable Data Entry, Demoy’s Main.js video goes a bit into removing Mutable Data here and a few other functions of Mutable Data as well.

1 Like

Yeah I’m doing something similar, I just don’t like nesting just for the sake of freeing my handles. I’ll look at passing handle as variable for chaining. Do you have any example code?

Can you confirm @bochaco?

Thanks for your help @Joseph_Meagher, I’m slowly getting up to speed.

1 Like

Afraid not, but make sure to use local variables as global variables aren’t the best practice.

10 posts were split to a new topic: JavaScript tips for using the SAFE API

  • window.safeApp.free(appHandle)
    Does this also free other handles (ie mutable data, NFS, file etc) or do they have to be explicitly free’d?

  • safeNfs.open()
    …returns a new file handle. If it was given an existing file handle, does that get freed by this operation or does it remain valid?

1 Like

That’s correct, the entry’s value is cleared but the entry is not removed.

It does free them all, this is done by the safe_client_libs itself rather than the safe_app_nodejs layer though.

It remains valid, but it sounds to me we can enhance this by returning the same handle if one was provided instead of returning a new one (just created this for consideration MAID-2365).

3 Likes

If it’s not a temporary behaviour, I would suggest to change the name of the function to clear instead of remove to avoid confusion.

Btw, is this a technical limitation or a design choice?

2 Likes

I think this was to prevent people from being able to change content and claim it was never changed. Let’s say you have an entry with version N which other people take as valid, perhaps some contractual information, you could then remove it and create an new entry with the same key and same version N but new content, i.e. you remove the entry, then insert a new one with the same key, and update it until you reached the same version N but with a new value. So by clearing it, you can at least realise that the value for version N is not valid anymore.
This a whole topic in itself, my understanding is that there are also plans/proposals for having the network to keep the entire history of an entry or data.

4 Likes

Thanks Gabriel, that makes sense, but it has some unfortunate consequences.

For example, in using an MD for storing and regularly invalidating keys such as using an MD as a file index as in SAFE-NFS. Every time a filename is changed, an unused key is left which takes up space in the MD, and which has to be filtered whenever searching the index (such as to list a directory).

So I’m wondering if there are plans to mitigate this kind of issue?

Similarly, over time a container will become cluttered with discarded keys.

1 Like