hubl/src/orbit-envoy.pug

231 lines
8.3 KiB
Plaintext

//-
Orbit Envoy - Collision-free route generation & federation management for latter usage
Create a window.orbit.components, accessible by all components with the route declaration.
Components can also get benefits from the `getRoute` function
Eg.
```
window.orbit.getRoute('chat', true)
window.orbit.getRoute('ffb39ad020645') // Where uxnzsa is the uniq of the component
```
will return the route of the first chat component, if exists, or triggers an error.
-
let routes = new Set();
const getRoute = (type, returnFirst = false) => {
let availables = components.filter(c => c.type == type || c.uniq == type);
components.forEach(c => {
if (c.extensions) {
c.extensions.forEach(e => {
if (e.type == type || e.uniq == type) {
availables.push(e);
}
});
}
});
if (availables.length > 1) {
if (returnFirst) {
return availables[0].route;
} else {
return availables[availables.length - 1].route;
}
} else if (availables.length < 1) {
console.error(`No component found for route ${type}`);
} else {
return availables[0].route;
}
}
const getComponent = (type, returnFirst = false) => {
let availables = components.filter(c=>c.type==type);
if(availables.length > 1) {
if(returnFirst) {
return availables[0];
} else {
console.error(`Too much components availables for type ${type}`);
}
} else if(availables.length < 1) {
console.error(`No component found for type ${type}`);
} else {
return availables[0];
}
}
const generateUrl = (federation, path) => {
let result = [];
for(let target of federation) {
result.push({
"@id": target + path.replace(/federation:\//, ''),
"@type": "sib:federatedContainer"
});
}
return result;
}
var federations = {};
for component of components
-
if(typeof component.route === 'undefined') {
component.route = component.type;
}
component.uniq = Math.random().toString(16).slice(2);
if(component.route) {
let route = component.route;
if (routes.has(component.route)) {
route += "-" + component.uniq;
}
routes.add(route);
component.route = route;
}
if(component.extensions) {
for(extension of component.extensions) {
if(typeof extension.route === 'undefined') {
extension.route = extension.type;
}
extension.uniq = Math.random().toString(16).slice(2);
if(extension.route) {
let route = extension.route;
if (routes.has(extension.route)) {
route += "-" + extension.uniq;
}
routes.add(route);
extension.route = route;
}
}
}
if(component.parameters) {
let federation = new Set();
if(client.server) {
federation.add(client.server);
}
if(client.servers) {
for(server of client.servers) {
federation.add(server);
}
}
if(component.federation) {
for(target of component.federation) {
federation.add(target);
}
}
component.federation = [...federation];
for(const [attribute, path] of Object.entries(component.parameters)) {
if(typeof path === 'string') {
if(path.startsWith('federation://')) {
let contains = generateUrl(federation, path);
if(contains.length > 1) {
federations[`store://local.${component.uniq}/${attribute}/`] = {
"@cache": "false",
"@context": "https://cdn.happy-dev.fr/owl/hdcontext.jsonld",
"@type": "ldp:Container",
"@id": `store://local.${component.uniq}/${attribute}/`,
"ldp:contains": contains,
"permissions": [{"mode": {"@type": "view"}}]
};
component.parameters[attribute] = `store://local.${component.uniq}/${attribute}/`;
} else {
component.parameters[attribute] = federation.values().next().value + path.replace(/federation:\//, '');
}
}
if(path.startsWith('server://')) {
component.parameters[attribute] = client.server + path.replace(/server:\//, '');
}
}
}
/* Rewrite every parameters to kebab-case */
let rewriteParameters = {};
for(const [attribute, value] of Object.entries(component.parameters)) {
rewriteParameters[attribute.replace(/((?<=[a-z\d])[A-Z]|(?<=[A-Z\d])[A-Z](?=[a-z]))/g, '-$1').toLowerCase()] = value;
}
component.attributes = rewriteParameters;
component.attributes.route = component.route;
component.attributes.uniq = component.uniq;
}
if(component.extensions) {
for(extension of component.extensions) {
if(extension.parameters) {
let federation = new Set();
if(client.server) {
federation.add(client.server);
}
if(client.servers) {
for(server of client.servers) {
federation.add(server);
}
}
if(component.federation) {
for(target of component.federation) {
federation.add(target);
}
}
if(extension.federation) {
for(target of extension.federation) {
federation.add(target);
}
}
extension.federation = [...federation];
for(const [attribute, path] of Object.entries(extension.parameters)) {
if(typeof path === 'string') {
if(path.startsWith('federation://')) {
let contains = generateUrl(federation, path);
if(contains.length > 1) {
federations[`store://local.${extension.uniq}/${attribute}/`] = {
"@cache": "false",
"@context": "https://cdn.happy-dev.fr/owl/hdcontext.jsonld",
"@type": "ldp:Container",
"@id": `store://local.${extension.uniq}/${attribute}/`,
"ldp:contains": contains,
"permissions": [{"mode": {"@type": "view"}}]
};
extension.parameters[attribute] = `store://local.${extension.uniq}/${attribute}/`;
} else {
component.parameters[attribute] = federation.values().next().value + path.replace(/federation:\//, '');
}
}
if(path.startsWith('server://')) {
extension.parameters[attribute] = client.server + path.replace(/server:\//, '');
}
}
}
/* Rewrite every parameters to kebab-case */
let rewriteParameters = {};
for(const [attribute, value] of Object.entries(extension.parameters)) {
rewriteParameters[attribute.replace(/((?<=[a-z\d])[A-Z]|(?<=[A-Z\d])[A-Z](?=[a-z]))/g, '-$1').toLowerCase()] = value;
}
extension.attributes = rewriteParameters;
extension.attributes.uniq = extension.uniq;
}
}
}
-
const defaultComponent = components.filter(e=>e.defaultRoute != undefined);
let defaultRoute = "dashboard";
if(defaultComponent.length == 1) {
defaultRoute = defaultComponent[0].uniq;
}
- const orbitComponents = `window.orbit={};window.orbit.components = ${JSON.stringify(components)};window.orbit.federations = ${JSON.stringify(federations)};window.orbit.defaultRoute = "${defaultRoute}";window.orbit.client = ${JSON.stringify(client)};`;
script!=orbitComponents
| window.orbit.getRoute = (type, returnFirst = false) => {
| let availables = window.orbit.components.filter(c => c.type == type || c.uniq == type);
| window.orbit.components.forEach(c => {
| if (c.extensions) {
| c.extensions.forEach(e => {
| if (e.type == type || e.uniq == type) {
| availables.push(e);
| }
| });
| }
| });
| if (availables.length > 1) {
| if (returnFirst) {
| return availables[0].route;
| } else {
| return availables[availables.length - 1].route;
| }
| } else if (availables.length < 1) {
| console.error(`No component found for route ${type}`);
| } else {
| return availables[0].route;
| }
| }
| window.hubl = window.orbit;