Thanks for the feedback guys, I’ll take it into consideration
I’ve just had an idea to make this even simpler and at the same time solve the nested derived state problem in Frontity Connect, using the RES hooks.
The API is just a draft. It won’t be like that in Frontity if this ever makes it. And the way it is right now it won’t work for object overwrites, so I have to think about that. But the PoC is working: https://codesandbox.io/s/react-easy-state-object-filter-keys-and-nested-derived-state-8vny4
The idea would be to use object key filters instead of my proposal of Source Converters and avoid the need for an additional get
or getSomething
function:
export default {
state: {
hooks: {
access: {
source: {
dataTrailingSlash: {
path: "source.data.*",
library: "source.dataTrailingSlash",
priority: 5,
},
dataRemoveQueries: {
path: "source.data.*",
library: "source.dataRemoveQueries",
priority: 6,
options: {
// Whitelist the search query ("s").
whitelist: {
s: true
}
}
}
},
},
},
},
libraries: {
hooks: {
access: {
source: {
dataTrailingSlash: ({ key }) => ({
key: key.replace(/\/($|\?)/, ""),
}),
dataRemoveQueries: ({ key, options }) => ({
// You can access options and act accordingly.
key: key.replace(/\?.*$/, "");
})
},
},
},
},
};
Of course, any package can add these type of filters or modify the options of a filter using the state
.
// frontity.settings.js
const settings = {
state: {
hooks: {
access: {
source: {
dataRemoveQueries: {
options: {
// Whitelist other query.
whitelist: {
photo: true,
},
},
},
},
},
},
},
};
Then the object can be accessed normally, but it’ll return the correct object:
const state = store({
data: {
"/url": {
link: "/url",
},
},
});
state.data["/url"].link; // <- returns "/url"
state.data["/url/"].link; // <- returns "/url"
state.data["/url?query=true"].link; // <- returns "/url"
The same approach can also be used for derived state and nested derived state:
export default {
state: {
source: {
author: {
1: {
name: "Jon",
surname: "Snow",
},
},
},
hooks: {
access: {
users: {
path: "source.author.*.fullname",
library: "source.authorFullname",
},
},
},
},
libraries: {
hooks: {
access: {
source: {
authorFullname: ({ state, path }) => ({
value:
state.source.author[path[2]].name +
" " +
state.source.author[path[2]].surname,
}),
},
},
},
},
};
It’s probably not the best API so maybe it’s better to add an additional one for derived
, but I’m glad this is possible.