A DataObject contains a collection of one or more DDSes and nesting them allows you to create organizational structure. DDSes themselves can also be nested and retrieved in the initialization steps.
There are a few ways you can solve eg1
and I highlight two below.
For eg2
you're right that it's a bit complicated and generally not a pattern we are pushing at the moment. There are some example in the repo but you will find that they use a slightly different developer model then the HelloWorld. The SimpleComponentEmbed and the Pond are the best starting points if you want to explore DataObject embedding.
Using root SharedDirectory for nesting
The root
SharedDirectory
allows you to create sub-directories. This is a great way to manage collections of nested maps. Using sub-directories instead of putting a SharedMap on the root ensures creation and setting happens as one atomic action instead of two actions, (one to create and one to set).
The current draw back to this at the moment is that you have to listen to events on the root directory and see if it corresponds to your sub-directory. Eventing on sub-directories is being tracked with Issue #1403
protected async initializingFirstTime() {
const subDirectory = this.root.createSubDirectory("sub-dir");
subDirectory.createSubDirectory("sub-sub-dir");
}
protected async hasInitialized() {
const subDirectory = this.root.getSubDirectory("sub-dir");
const ssDir = subDirectory.getSubDirectory("sub-sub-dir");
this.root.on("valueChanged", (changed: IDirectoryValueChanged) => {
if (changed.path === ssDir.absolutePath) {
const newValue = ssDir.get(changed.key);
console.log(newValue);
}
});
// An easy way to trigger/test the above handler without user interaction
setTimeout(() => {
ssDir.set("foo", "bar2");
}, 10000); // 10 seconds
}
Using Nested DDSes
You can also store nested DDSes. The thing you need to remember is that you are storing/ retrieving the handle to the DDS. In the below example we are creating map1
with a key/value. We are string map1
in map2
which is being stored on the root
DDS. We will then get the value from map1
by first getting map2
then map1
then the value.
protected async initializingFirstTime() {
const map1 = SharedMap.create(this.runtime);
map1.set("foo", "bar");
const map2 = SharedMap.create(this.runtime);
map2.set("map1", map1.handle);
this.root.set("map2", map2.handle);
}
protected async hasInitialized() {
const map2 = await this.root.get<IFluidHandle<SharedMap>>("map2").get();
const map1 = await map2.get<IFluidHandle<SharedMap>>("map1").get();
console.log(map1.get("foo"));
}