UNPKG

everything-dev

Version:

A consolidated product package for building Module Federation apps with oRPC APIs.

1 lines 11 kB
{"version":3,"file":"dag.cjs","names":[],"sources":["../src/dag.ts"],"sourcesContent":["import type { JsonObject, RuntimeConfig, RuntimeDependencyNode } from \"./types\";\n\nexport interface DependencyDAG {\n nodes: Map<string, RuntimeDependencyNode>;\n sorted: string[];\n}\n\nexport function normalizeToNodes(config: RuntimeConfig): Map<string, RuntimeDependencyNode> {\n const nodes = new Map<string, RuntimeDependencyNode>();\n\n if (config.api?.url) {\n nodes.set(\"api\", {\n key: \"api\",\n kind: \"api\",\n name: config.api.name,\n url: config.api.url,\n entry: config.api.entry,\n source: config.api.source,\n localPath: config.api.localPath,\n port: config.api.port,\n proxy: config.api.proxy,\n variables: config.api.variables,\n secrets: config.api.secrets,\n integrity: config.api.integrity,\n shared: config.api.shared,\n dependsOn: config.api.dependsOn,\n sourceOrigin: \"config\",\n singletonKey: `api:${config.api.url}`,\n });\n }\n\n if (config.auth?.url) {\n nodes.set(\"auth\", {\n key: \"auth\",\n kind: \"auth\",\n name: config.auth.name,\n url: config.auth.url,\n entry: config.auth.entry,\n source: config.auth.source,\n extendsRef: config.auth.extendsRef,\n localPath: config.auth.localPath,\n port: config.auth.port,\n proxy: config.auth.proxy,\n variables: config.auth.variables,\n secrets: config.auth.secrets,\n integrity: config.auth.integrity,\n shared: config.auth.shared,\n dependsOn: config.auth.dependsOn,\n sourceOrigin: \"config\",\n singletonKey: `auth:${config.auth.url}`,\n });\n }\n\n if (config.ui?.url) {\n nodes.set(\"ui\", {\n key: \"ui\",\n kind: \"ui\",\n name: config.ui.name,\n url: config.ui.url,\n entry: config.ui.entry,\n source: config.ui.source,\n localPath: config.ui.localPath,\n port: config.ui.port,\n integrity: config.ui.integrity,\n dependsOn: config.ui.dependsOn,\n sourceOrigin: \"config\",\n singletonKey: `ui:${config.ui.url}`,\n });\n }\n\n for (const [key, plugin] of Object.entries(config.plugins ?? {})) {\n if (!plugin.url) continue;\n nodes.set(key, {\n key,\n kind: \"plugin\",\n name: plugin.name,\n url: plugin.url,\n entry: plugin.entry,\n source: plugin.source,\n extendsRef: plugin.extendsRef,\n localPath: plugin.localPath,\n port: plugin.port,\n proxy: plugin.proxy,\n variables: plugin.variables,\n secrets: plugin.secrets,\n integrity: plugin.integrity,\n shared: plugin.shared,\n ui: plugin.ui,\n routes: plugin.routes,\n dependsOn: plugin.dependsOn,\n sourceOrigin: \"config\",\n singletonKey: `plugin:${key}:${plugin.url}`,\n });\n }\n\n return nodes;\n}\n\nexport function manifestPluginsToNodes(\n plugins: Array<{\n key: string;\n name: string;\n url: string;\n dependsOn?: string[];\n secrets?: string[];\n variables?: JsonObject;\n }>,\n): RuntimeDependencyNode[] {\n if (!plugins?.length) return [];\n return plugins.map((p) => ({\n key: p.key,\n kind: \"plugin\" as const,\n name: p.name,\n url: p.url,\n entry: `${p.url}/mf-manifest.json`,\n source: \"remote\" as const,\n dependsOn: p.dependsOn,\n secrets: p.secrets,\n variables: p.variables,\n sourceOrigin: \"manifest\" as const,\n singletonKey: `plugin:${p.key}:${p.url}`,\n }));\n}\n\nexport function buildDependencyDAG(config: RuntimeConfig): DependencyDAG {\n const nodes =\n config.nodes && Object.keys(config.nodes).length > 0\n ? new Map(Object.entries(config.nodes))\n : normalizeToNodes(config);\n const sorted = topologicalSort(nodes);\n return { nodes, sorted };\n}\n\nexport function getImplicitApiDependencies(nodes: Map<string, RuntimeDependencyNode>): string[] {\n return [...nodes.values()].filter((n) => n.kind !== \"api\" && n.kind !== \"ui\").map((n) => n.key);\n}\n\nexport function topologicalSort(nodes: Map<string, RuntimeDependencyNode>): string[] {\n const inDegree = new Map<string, number>();\n const adjacency = new Map<string, Set<string>>();\n\n for (const key of nodes.keys()) {\n inDegree.set(key, 0);\n adjacency.set(key, new Set());\n }\n\n for (const [key, node] of nodes) {\n for (const dep of node.dependsOn ?? []) {\n if (nodes.has(dep)) {\n adjacency.get(dep)!.add(key);\n inDegree.set(key, (inDegree.get(key) ?? 0) + 1);\n }\n }\n }\n\n const apiNode = nodes.get(\"api\");\n if (apiNode && !apiNode.dependsOn?.length) {\n for (const depKey of getImplicitApiDependencies(nodes)) {\n if (!adjacency.get(depKey)!.has(\"api\")) {\n adjacency.get(depKey)!.add(\"api\");\n inDegree.set(\"api\", (inDegree.get(\"api\") ?? 0) + 1);\n }\n }\n }\n\n const queue: string[] = [];\n for (const [key, degree] of inDegree) {\n if (degree === 0) queue.push(key);\n }\n queue.sort();\n\n const result: string[] = [];\n while (queue.length > 0) {\n const current = queue.shift()!;\n result.push(current);\n const neighbors = adjacency.get(current);\n if (neighbors) {\n for (const neighbor of neighbors) {\n const newDegree = (inDegree.get(neighbor) ?? 0) - 1;\n inDegree.set(neighbor, newDegree);\n if (newDegree === 0) {\n const insertPos = queue.findIndex((k) => k > neighbor);\n if (insertPos === -1) queue.push(neighbor);\n else queue.splice(insertPos, 0, neighbor);\n }\n }\n }\n }\n\n if (result.length !== nodes.size) {\n const cyclic = [...nodes.keys()].filter((k) => !result.includes(k));\n throw new Error(\n `Circular dependency detected among: ${cyclic.join(\" -> \")}. Check dependsOn declarations in bos.config.json.`,\n );\n }\n\n return result;\n}\n\nexport function mergeManifestNodes(\n configNodes: Map<string, RuntimeDependencyNode>,\n manifestNodes: RuntimeDependencyNode[],\n): Map<string, RuntimeDependencyNode> {\n const merged = new Map(configNodes);\n\n for (const node of manifestNodes) {\n if (merged.has(node.key) && merged.get(node.key)!.sourceOrigin === \"config\") {\n continue;\n }\n merged.set(node.key, node);\n }\n\n return merged;\n}\n\nexport function getDependenciesForNode(\n node: RuntimeDependencyNode,\n allNodes: Map<string, RuntimeDependencyNode>,\n): RuntimeDependencyNode[] {\n if (node.kind === \"api\" && !node.dependsOn?.length) {\n return getImplicitApiDependencies(allNodes)\n .map((k) => allNodes.get(k))\n .filter(Boolean) as RuntimeDependencyNode[];\n }\n\n const explicitDeps = (node.dependsOn ?? [])\n .map((k) => allNodes.get(k))\n .filter(Boolean) as RuntimeDependencyNode[];\n\n return explicitDeps;\n}\n\nexport function getSingletonKey(node: RuntimeDependencyNode): string {\n return node.singletonKey ?? `${node.kind}:${node.key}:${node.url}`;\n}\n"],"mappings":";;;AAOA,SAAgB,iBAAiB,QAA2D;CAC1F,MAAM,wBAAQ,IAAI,IAAmC;CAErD,IAAI,OAAO,KAAK,KACd,MAAM,IAAI,OAAO;EACf,KAAK;EACL,MAAM;EACN,MAAM,OAAO,IAAI;EACjB,KAAK,OAAO,IAAI;EAChB,OAAO,OAAO,IAAI;EAClB,QAAQ,OAAO,IAAI;EACnB,WAAW,OAAO,IAAI;EACtB,MAAM,OAAO,IAAI;EACjB,OAAO,OAAO,IAAI;EAClB,WAAW,OAAO,IAAI;EACtB,SAAS,OAAO,IAAI;EACpB,WAAW,OAAO,IAAI;EACtB,QAAQ,OAAO,IAAI;EACnB,WAAW,OAAO,IAAI;EACtB,cAAc;EACd,cAAc,OAAO,OAAO,IAAI;CAClC,CAAC;CAGH,IAAI,OAAO,MAAM,KACf,MAAM,IAAI,QAAQ;EAChB,KAAK;EACL,MAAM;EACN,MAAM,OAAO,KAAK;EAClB,KAAK,OAAO,KAAK;EACjB,OAAO,OAAO,KAAK;EACnB,QAAQ,OAAO,KAAK;EACpB,YAAY,OAAO,KAAK;EACxB,WAAW,OAAO,KAAK;EACvB,MAAM,OAAO,KAAK;EAClB,OAAO,OAAO,KAAK;EACnB,WAAW,OAAO,KAAK;EACvB,SAAS,OAAO,KAAK;EACrB,WAAW,OAAO,KAAK;EACvB,QAAQ,OAAO,KAAK;EACpB,WAAW,OAAO,KAAK;EACvB,cAAc;EACd,cAAc,QAAQ,OAAO,KAAK;CACpC,CAAC;CAGH,IAAI,OAAO,IAAI,KACb,MAAM,IAAI,MAAM;EACd,KAAK;EACL,MAAM;EACN,MAAM,OAAO,GAAG;EAChB,KAAK,OAAO,GAAG;EACf,OAAO,OAAO,GAAG;EACjB,QAAQ,OAAO,GAAG;EAClB,WAAW,OAAO,GAAG;EACrB,MAAM,OAAO,GAAG;EAChB,WAAW,OAAO,GAAG;EACrB,WAAW,OAAO,GAAG;EACrB,cAAc;EACd,cAAc,MAAM,OAAO,GAAG;CAChC,CAAC;CAGH,KAAK,MAAM,CAAC,KAAK,WAAW,OAAO,QAAQ,OAAO,WAAW,CAAC,CAAC,GAAG;EAChE,IAAI,CAAC,OAAO,KAAK;EACjB,MAAM,IAAI,KAAK;GACb;GACA,MAAM;GACN,MAAM,OAAO;GACb,KAAK,OAAO;GACZ,OAAO,OAAO;GACd,QAAQ,OAAO;GACf,YAAY,OAAO;GACnB,WAAW,OAAO;GAClB,MAAM,OAAO;GACb,OAAO,OAAO;GACd,WAAW,OAAO;GAClB,SAAS,OAAO;GAChB,WAAW,OAAO;GAClB,QAAQ,OAAO;GACf,IAAI,OAAO;GACX,QAAQ,OAAO;GACf,WAAW,OAAO;GAClB,cAAc;GACd,cAAc,UAAU,IAAI,GAAG,OAAO;EACxC,CAAC;CACH;CAEA,OAAO;AACT;AAEA,SAAgB,uBACd,SAQyB;CACzB,IAAI,CAAC,SAAS,QAAQ,OAAO,CAAC;CAC9B,OAAO,QAAQ,KAAK,OAAO;EACzB,KAAK,EAAE;EACP,MAAM;EACN,MAAM,EAAE;EACR,KAAK,EAAE;EACP,OAAO,GAAG,EAAE,IAAI;EAChB,QAAQ;EACR,WAAW,EAAE;EACb,SAAS,EAAE;EACX,WAAW,EAAE;EACb,cAAc;EACd,cAAc,UAAU,EAAE,IAAI,GAAG,EAAE;CACrC,EAAE;AACJ;AAEA,SAAgB,mBAAmB,QAAsC;CACvE,MAAM,QACJ,OAAO,SAAS,OAAO,KAAK,OAAO,KAAK,CAAC,CAAC,SAAS,IAC/C,IAAI,IAAI,OAAO,QAAQ,OAAO,KAAK,CAAC,IACpC,iBAAiB,MAAM;CAE7B,OAAO;EAAE;EAAO,QADD,gBAAgB,KACV;CAAE;AACzB;AAEA,SAAgB,2BAA2B,OAAqD;CAC9F,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,CAAC,CAAC,QAAQ,MAAM,EAAE,SAAS,SAAS,EAAE,SAAS,IAAI,CAAC,CAAC,KAAK,MAAM,EAAE,GAAG;AAChG;AAEA,SAAgB,gBAAgB,OAAqD;CACnF,MAAM,2BAAW,IAAI,IAAoB;CACzC,MAAM,4BAAY,IAAI,IAAyB;CAE/C,KAAK,MAAM,OAAO,MAAM,KAAK,GAAG;EAC9B,SAAS,IAAI,KAAK,CAAC;EACnB,UAAU,IAAI,qBAAK,IAAI,IAAI,CAAC;CAC9B;CAEA,KAAK,MAAM,CAAC,KAAK,SAAS,OACxB,KAAK,MAAM,OAAO,KAAK,aAAa,CAAC,GACnC,IAAI,MAAM,IAAI,GAAG,GAAG;EAClB,UAAU,IAAI,GAAG,CAAC,CAAE,IAAI,GAAG;EAC3B,SAAS,IAAI,MAAM,SAAS,IAAI,GAAG,KAAK,KAAK,CAAC;CAChD;CAIJ,MAAM,UAAU,MAAM,IAAI,KAAK;CAC/B,IAAI,WAAW,CAAC,QAAQ,WAAW,QACjC;OAAK,MAAM,UAAU,2BAA2B,KAAK,GACnD,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,CAAE,IAAI,KAAK,GAAG;GACtC,UAAU,IAAI,MAAM,CAAC,CAAE,IAAI,KAAK;GAChC,SAAS,IAAI,QAAQ,SAAS,IAAI,KAAK,KAAK,KAAK,CAAC;EACpD;CACF;CAGF,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,CAAC,KAAK,WAAW,UAC1B,IAAI,WAAW,GAAG,MAAM,KAAK,GAAG;CAElC,MAAM,KAAK;CAEX,MAAM,SAAmB,CAAC;CAC1B,OAAO,MAAM,SAAS,GAAG;EACvB,MAAM,UAAU,MAAM,MAAM;EAC5B,OAAO,KAAK,OAAO;EACnB,MAAM,YAAY,UAAU,IAAI,OAAO;EACvC,IAAI,WACF,KAAK,MAAM,YAAY,WAAW;GAChC,MAAM,aAAa,SAAS,IAAI,QAAQ,KAAK,KAAK;GAClD,SAAS,IAAI,UAAU,SAAS;GAChC,IAAI,cAAc,GAAG;IACnB,MAAM,YAAY,MAAM,WAAW,MAAM,IAAI,QAAQ;IACrD,IAAI,cAAc,IAAI,MAAM,KAAK,QAAQ;SACpC,MAAM,OAAO,WAAW,GAAG,QAAQ;GAC1C;EACF;CAEJ;CAEA,IAAI,OAAO,WAAW,MAAM,MAAM;EAChC,MAAM,SAAS,CAAC,GAAG,MAAM,KAAK,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,OAAO,SAAS,CAAC,CAAC;EAClE,MAAM,IAAI,MACR,uCAAuC,OAAO,KAAK,MAAM,EAAE,mDAC7D;CACF;CAEA,OAAO;AACT;AAEA,SAAgB,mBACd,aACA,eACoC;CACpC,MAAM,SAAS,IAAI,IAAI,WAAW;CAElC,KAAK,MAAM,QAAQ,eAAe;EAChC,IAAI,OAAO,IAAI,KAAK,GAAG,KAAK,OAAO,IAAI,KAAK,GAAG,CAAC,CAAE,iBAAiB,UACjE;EAEF,OAAO,IAAI,KAAK,KAAK,IAAI;CAC3B;CAEA,OAAO;AACT;AAEA,SAAgB,uBACd,MACA,UACyB;CACzB,IAAI,KAAK,SAAS,SAAS,CAAC,KAAK,WAAW,QAC1C,OAAO,2BAA2B,QAAQ,CAAC,CACxC,KAAK,MAAM,SAAS,IAAI,CAAC,CAAC,CAAC,CAC3B,OAAO,OAAO;CAOnB,QAJsB,KAAK,aAAa,CAAC,EAAC,CACvC,KAAK,MAAM,SAAS,IAAI,CAAC,CAAC,CAAC,CAC3B,OAAO,OAEQ;AACpB;AAEA,SAAgB,gBAAgB,MAAqC;CACnE,OAAO,KAAK,gBAAgB,GAAG,KAAK,KAAK,GAAG,KAAK,IAAI,GAAG,KAAK;AAC/D"}