//- 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;