UNPKG

@xyo-network/react-node

Version:

Common React library for all XYO projects that use React

584 lines (551 loc) 20.3 kB
var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); // src/components/Node.tsx import React2 from "react"; // src/components/NodeDescriptionBox.tsx import { FlexCol } from "@xylabs/react-flexbox"; import React from "react"; // src/hooks/getModuleFilterOptions.ts var getModuleFilterOptions = /* @__PURE__ */ __name((config) => { const { direction, identity, maxDepth } = config ?? {}; return { direction, identity, maxDepth }; }, "getModuleFilterOptions"); // src/hooks/getWeakModuleFilterOptions.ts var getWeakModuleFilterOptions = /* @__PURE__ */ __name((config) => { const { direction, identity, maxDepth } = config ?? {}; return { direction, identity, maxDepth }; }, "getWeakModuleFilterOptions"); // src/hooks/ModuleFromNodeConfig.ts var getModuleFromNodeConfigLogger = /* @__PURE__ */ __name((config) => { return config?.logger; }, "getModuleFromNodeConfigLogger"); // src/hooks/provided/useProvidedNode.tsx import { NodeContext } from "@xyo-network/react-node-context"; import { use } from "react"; var useProvidedNode = /* @__PURE__ */ __name(() => { const { node } = use(NodeContext); return [ node ]; }, "useProvidedNode"); // src/hooks/provided/useWeakProvidedNode.tsx import { NodeContext as NodeContext2 } from "@xyo-network/react-node-context"; import { use as use2, useMemo } from "react"; var useWeakProvidedNode = /* @__PURE__ */ __name(() => { const { node } = use2(NodeContext2); const weakNode = useMemo(() => node ? new WeakRef(node) : null, [ node ]); return [ weakNode ]; }, "useWeakProvidedNode"); // src/hooks/useModuleFromNode.ts import { usePromise as usePromise2 } from "@xylabs/react-promise"; import { isModuleInstance } from "@xyo-network/module-model"; import { useState } from "react"; // src/hooks/useNode.ts import { usePromise } from "@xylabs/react-promise"; import { asNodeInstance } from "@xyo-network/node-model"; // src/hooks/useNodeConfigNodeField.ts import { useMemo as useMemo2 } from "react"; var useNodeConfigNodeField = /* @__PURE__ */ __name((config) => { const nodeAddress = useMemo2(() => typeof config?.node === "string" ? config?.node : void 0, [ config?.node ]); const nodeInstance = useMemo2(() => typeof config?.node === "object" ? config?.node : void 0, [ config?.node ]); return [ nodeAddress, nodeInstance ]; }, "useNodeConfigNodeField"); // src/hooks/useNode.ts var useNode = /* @__PURE__ */ __name((config) => { const [nodeAddress, nodeInstance] = useNodeConfigNodeField(config); const [providedNode] = useProvidedNode(); const [nodeAddressNode, error] = usePromise(async () => { if (providedNode && nodeAddress) { return asNodeInstance(await providedNode.resolve(nodeAddress), "Module is not a node"); } }, [ providedNode, nodeAddress ]); return [ nodeAddressNode ?? nodeInstance ?? providedNode ?? void 0, error ]; }, "useNode"); // src/hooks/useModuleFromNode.ts var useModuleFromNode = /* @__PURE__ */ __name((nameOrAddressOrInstance = void 0, config) => { const [node, nodeError] = useNode(config); const logger = getModuleFromNodeConfigLogger(config); const filterOptions = getModuleFilterOptions(config); const [result, setResult] = useState(); const [, error] = usePromise2(async () => { logger?.debug("useModuleFromNode: resolving"); const identity = config?.identity ?? isModuleInstance; if (node && nameOrAddressOrInstance) { node.on("moduleAttached", ({ mod }) => { logger?.debug(`useModuleFromNode: moduleAttached [${mod.config.name ?? mod.address}]`); if (mod.address === nameOrAddressOrInstance || mod.config?.name === nameOrAddressOrInstance) { setResult(identity(mod) ? mod : void 0); } }); node.on("moduleDetached", ({ mod }) => { logger?.debug(`useModuleFromNode: moduleDetached [${mod.config.name ?? mod.address}]`); if (mod.address === nameOrAddressOrInstance || mod.config?.name === nameOrAddressOrInstance) { setResult(void 0); } }); if (identity(nameOrAddressOrInstance)) { setResult(nameOrAddressOrInstance); } else { const result2 = await node.resolve(nameOrAddressOrInstance, filterOptions); logger?.debug(`Result: ${result2?.address}`); setResult(identity(result2) ? result2 : void 0); } return result; } logger?.debug("Result: No Node"); return; }, [ node, nameOrAddressOrInstance ]); return [ result, nodeError ?? error ]; }, "useModuleFromNode"); // src/hooks/useModulesFromNode.ts import { exists } from "@xylabs/exists"; import { usePromise as usePromise3 } from "@xylabs/react-promise"; import { useState as useState2 } from "react"; var useModulesFromNode = /* @__PURE__ */ __name((ids, config) => { const [node, nodeError] = useNode(config); const logger = config?.logger; const filterOptions = getModuleFilterOptions(); const [result, setResult] = useState2(); const [, error] = usePromise3(async () => { logger?.debug("useModuleFromNode: resolving"); if (node) { const refreshModules = /* @__PURE__ */ __name(async () => { const moduleInstances = ids ? (await Promise.all(ids.map((id) => node.resolve(id, filterOptions)))).filter(exists) : await node.resolve("*", filterOptions); setResult(moduleInstances); return moduleInstances; }, "refreshModules"); node.on("moduleAttached", async ({ mod }) => { logger?.debug(`useModuleFromNode: moduleAttached [${mod.config.name ?? mod.address}]`); await refreshModules(); }); node.on("moduleDetached", async ({ mod }) => { logger?.debug(`useModuleFromNode: moduleDetached [${mod.config.name ?? mod.address}]`); await refreshModules(); }); return await refreshModules(); } console.log("Result: No Node"); return; }, [ node, ids ]); return [ result, nodeError ?? error ]; }, "useModulesFromNode"); // src/hooks/useNodeDescription.ts import { usePromise as usePromise4 } from "@xylabs/react-promise"; import { ModuleDescriptionSchema } from "@xyo-network/module-model"; import { isPayloadOfSchemaType } from "@xyo-network/payload-model"; var useNodeDescription = /* @__PURE__ */ __name((config) => { const [activeNode, nodeError] = useNode(config); const [description, error] = usePromise4(async () => { const state = await activeNode?.state(); return state?.find(isPayloadOfSchemaType(ModuleDescriptionSchema)); }, [ activeNode ]); return [ description, nodeError ?? error ]; }, "useNodeDescription"); // src/hooks/useNodeFromNode.tsx import { asNodeInstance as asNodeInstance2 } from "@xyo-network/node-model"; var useNodeFromNode = /* @__PURE__ */ __name((nameOrAddressOrInstance, config) => { const [mod, error] = useModuleFromNode(nameOrAddressOrInstance, config); const instance = asNodeInstance2(mod); if (mod && !instance) { const error2 = new Error(`Resolved module is not a NodeInstance [${mod.config?.schema}:${mod.config?.name}:${mod.address}]`); console.error(error2.message); return [ void 0, error2 ]; } return [ instance, error ]; }, "useNodeFromNode"); // src/hooks/useNodesFromNode.tsx import { isNodeInstance } from "@xyo-network/node-model"; var useNodesFromNode = /* @__PURE__ */ __name((ids, config) => { const [modules, error] = useModulesFromNode(ids, config); if (error) { return [ null, error ]; } return modules ? [ // eslint-disable-next-line unicorn/no-array-reduce modules.reduce((prev, mod) => { if (isNodeInstance(mod)) { prev.push(mod); } return prev; }, []), void 0 ] : [ modules, error ]; }, "useNodesFromNode"); // src/hooks/useWeakModuleFromNode.ts import { usePromise as usePromise6 } from "@xylabs/react-promise"; import { isModuleInstance as isModuleInstance2 } from "@xyo-network/module-model"; import { useState as useState3 } from "react"; // src/hooks/useWeakNode.ts import { usePromise as usePromise5 } from "@xylabs/react-promise"; import { asNodeInstance as asNodeInstance3 } from "@xyo-network/node-model"; // src/hooks/useWeakNodeConfigNodeField.ts import { useMemo as useMemo3 } from "react"; var useWeakNodeConfigNodeField = /* @__PURE__ */ __name((config) => { const nodeAddress = useMemo3(() => typeof config?.node === "string" ? config?.node : void 0, [ config?.node ]); const nodeInstance = useMemo3(() => typeof config?.node === "object" ? config?.node : void 0, [ config?.node ]); return [ nodeAddress, nodeInstance ]; }, "useWeakNodeConfigNodeField"); // src/hooks/useWeakNode.ts var useWeakNode = /* @__PURE__ */ __name((config) => { const [nodeAddress, nodeInstance] = useWeakNodeConfigNodeField(config); const [providedNode] = useWeakProvidedNode(); const [nodeAddressNode, error] = usePromise5(async () => { const providedNodeInstance = providedNode?.deref(); if (providedNodeInstance && nodeAddress) { return new WeakRef(asNodeInstance3(await providedNodeInstance.resolve(nodeAddress), "Module is not a node")); } }, [ providedNode, nodeAddress ]); return [ nodeAddressNode ?? nodeInstance ?? providedNode ?? void 0, error ]; }, "useWeakNode"); // src/hooks/WeakModuleFromNodeConfig.ts var getWeakModuleFromNodeConfigLogger = /* @__PURE__ */ __name((config) => { return config?.logger; }, "getWeakModuleFromNodeConfigLogger"); // src/hooks/useWeakModuleFromNode.ts var useWeakModuleFromNode = /* @__PURE__ */ __name((nameOrAddressOrInstance = void 0, config) => { const [node, nodeError] = useWeakNode(config); const logger = getWeakModuleFromNodeConfigLogger(config); const filterOptions = getWeakModuleFilterOptions(config); const [result, setResult] = useState3(); const [, error] = usePromise6(async () => { logger?.debug("useModuleFromNode: resolving"); const identity = config?.identity ?? isModuleInstance2; const nodeInstance = node?.deref(); if (nodeInstance && nameOrAddressOrInstance) { nodeInstance.on("moduleAttached", ({ mod }) => { logger?.debug(`useModuleFromNode: moduleAttached [${mod.config.name ?? mod.address}]`); if (mod.address === nameOrAddressOrInstance || mod.config?.name === nameOrAddressOrInstance) { setResult(identity(mod) ? new WeakRef(mod) : void 0); } }); nodeInstance.on("moduleDetached", ({ mod }) => { logger?.debug(`useModuleFromNode: moduleDetached [${mod.config.name ?? mod.address}]`); if (mod.address === nameOrAddressOrInstance || mod.config?.name === nameOrAddressOrInstance) { setResult(void 0); } }); if (identity(nameOrAddressOrInstance)) { setResult(new WeakRef(nameOrAddressOrInstance)); } else { const result2 = await nodeInstance.resolve(nameOrAddressOrInstance, filterOptions); logger?.debug(`Result: ${result2?.address}`); setResult(identity(result2) ? new WeakRef(result2) : void 0); } return result; } logger?.debug("Result: No Node"); return; }, [ node, nameOrAddressOrInstance ]); return [ result, nodeError ?? error ]; }, "useWeakModuleFromNode"); // src/hooks/useWeakModulesFromNode.ts import { exists as exists2 } from "@xylabs/exists"; import { usePromise as usePromise7 } from "@xylabs/react-promise"; import { useState as useState4 } from "react"; var useWeakModulesFromNode = /* @__PURE__ */ __name((ids, config) => { const [node, nodeError] = useNode(config); const logger = config?.logger; const filterOptions = getModuleFilterOptions(); const [result, setResult] = useState4(); const [, error] = usePromise7(async () => { logger?.debug("useModuleFromNode: resolving"); const nodeInstance = node; if (nodeInstance) { const refreshModules = /* @__PURE__ */ __name(async () => { const moduleInstances = ids ? (await Promise.all(ids.map((id) => node.resolve(id, filterOptions)))).filter(exists2) : await node.resolve("*", filterOptions); setResult(moduleInstances.map((mod) => new WeakRef(mod))); return moduleInstances; }, "refreshModules"); nodeInstance.on("moduleAttached", async ({ mod }) => { logger?.debug(`useModuleFromNode: moduleAttached [${mod.config.name ?? mod.address}]`); await refreshModules(); }); nodeInstance.on("moduleDetached", async ({ mod }) => { logger?.debug(`useModuleFromNode: moduleDetached [${mod.config.name ?? mod.address}]`); await refreshModules(); }); return await refreshModules(); } console.log("Result: No Node"); return; }, [ node, ids ]); return [ result, nodeError ?? error ]; }, "useWeakModulesFromNode"); // src/hooks/useWeakNodeDescription.ts import { usePromise as usePromise8 } from "@xylabs/react-promise"; import { ModuleDescriptionSchema as ModuleDescriptionSchema2 } from "@xyo-network/module-model"; import { isPayloadOfSchemaType as isPayloadOfSchemaType2 } from "@xyo-network/payload-model"; var useWeakNodeDescription = /* @__PURE__ */ __name((config) => { const [activeNode, nodeError] = useWeakNode(config); const [description, error] = usePromise8(async () => { const state = await activeNode?.deref()?.state(); return state?.find(isPayloadOfSchemaType2(ModuleDescriptionSchema2)); }, [ activeNode ]); return [ description, nodeError ?? error ]; }, "useWeakNodeDescription"); // src/hooks/useWeakNodeFromNode.tsx import { isNodeInstance as isNodeInstance2 } from "@xyo-network/node-model"; var useWeakNodeFromNode = /* @__PURE__ */ __name((nameOrAddressOrInstance, config) => { return useWeakModuleFromNode(nameOrAddressOrInstance, { identity: isNodeInstance2, ...config }); }, "useWeakNodeFromNode"); // src/components/NodeDescriptionBox.tsx var NodeDescriptionBox = /* @__PURE__ */ __name(({ node, ...props }) => { const [description, error] = useWeakNodeDescription({ node }); return /* @__PURE__ */ React.createElement(FlexCol, props, /* @__PURE__ */ React.createElement("code", { color: error ? "red" : void 0 }, error ? error.message : JSON.stringify(description, null, 2))); }, "NodeDescriptionBox"); // src/components/Node.tsx var NodeBox = /* @__PURE__ */ __name(({ variant, ...props }) => { switch (variant) { // eslint-disable-next-line unicorn/no-useless-switch-case case "description": default: { return /* @__PURE__ */ React2.createElement(NodeDescriptionBox, props); } } }, "NodeBox"); // src/components/NodeDrawer.tsx import { Close as CloseIcon } from "@mui/icons-material"; import { ClickAwayListener, Drawer, IconButton } from "@mui/material"; import { FlexGrowCol, FlexRow } from "@xylabs/react-flexbox"; import { useNodeDrawer } from "@xyo-network/react-node-provider"; import React5 from "react"; // src/components/render/ModuleDescriptionBox.tsx import { ChevronRight as ChevronRightIcon, ExpandMore as ExpandMoreIcon } from "@mui/icons-material"; import { styled as styled2, Typography } from "@mui/material"; import { SimpleTreeView } from "@mui/x-tree-view"; import React4, { useRef } from "react"; // src/components/render/RenderModule.tsx import { styled } from "@mui/material"; import { TreeItem } from "@mui/x-tree-view"; import { useAsyncEffect } from "@xylabs/react-async-effect"; import React3, { useState as useState5 } from "react"; var RenderModule = /* @__PURE__ */ __name(({ mod, idRef }) => { const [childModules, setChildModules] = useState5(); useAsyncEffect(async (mounted) => { const moduleInstance2 = mod.deref(); const { address: address2 } = moduleInstance2 ?? {}; if (moduleInstance2) { const children = (await moduleInstance2.resolve("*")).filter((childModule) => childModule.address !== address2); if (mounted()) { setChildModules(children.map((childModule) => new WeakRef(childModule))); } } }, [ mod ]); const increment = /* @__PURE__ */ __name(() => { const newId = (idRef.current.idIncrementor++).toString(); idRef.current.ids.push(newId); return newId; }, "increment"); const moduleInstance = mod.deref(); const { queries, address } = moduleInstance ?? {}; return /* @__PURE__ */ React3.createElement(StyledAddressTreeItem, { itemId: increment(), label: `address: ${address}` }, queries?.map((query, index) => { return /* @__PURE__ */ React3.createElement(TreeItem, { key: query, itemId: increment(), label: `query : ${query}`, sx: { mb: index === queries.length - 1 ? 1.5 : 0.5 } }); }), childModules && childModules.length > 0 ? /* @__PURE__ */ React3.createElement(TreeItem, { itemId: increment(), label: "children", sx: { mb: 0.5 } }, childModules.map((childModuleRef) => { const childModule = childModuleRef.deref(); return childModule ? /* @__PURE__ */ React3.createElement(RenderModule, { key: childModule?.address, mod: childModuleRef, idRef }) : null; })) : null); }, "RenderModule"); var StyledAddressTreeItem = styled(TreeItem, { name: "StyledAddressTreeItem" })(({ theme }) => ({ "& .MuiTreeItem-content": { marginBottom: theme.spacing(0.25) } })); // src/components/render/ModuleDescriptionBox.tsx var ModuleDescriptionBox = /* @__PURE__ */ __name(({ mod }) => { const idRef = useRef({ idIncrementor: 0, ids: [] }); return /* @__PURE__ */ React4.createElement(React4.Fragment, null, mod ? /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(Typography, { variant: "h4" }, "Node Configuration"), /* @__PURE__ */ React4.createElement(StyledTreeView, { "aria-label": "file system navigator", slots: { collapseIcon: ExpandMoreIcon, expandIcon: ChevronRightIcon }, sx: { flexGrow: 1 } }, /* @__PURE__ */ React4.createElement(RenderModule, { mod, idRef }))) : mod === null ? /* @__PURE__ */ React4.createElement(Typography, { variant: "h4" }, "Node loading...") : /* @__PURE__ */ React4.createElement(Typography, { variant: "h4" }, "Node not found")); }, "ModuleDescriptionBox"); var StyledTreeView = styled2(SimpleTreeView, { name: "StyledTreeView" })(() => ({ height: "auto", maxWidth: "auto" })); // src/components/NodeDrawer.tsx var NodeDrawer = /* @__PURE__ */ __name(({ children, ...props }) => { const { open, setOpen } = useNodeDrawer(); const [node] = useWeakProvidedNode(); return /* @__PURE__ */ React5.createElement(Drawer, { open: open ?? false, anchor: "right", ...props }, /* @__PURE__ */ React5.createElement(ClickAwayListener, { onClickAway: /* @__PURE__ */ __name(() => setOpen?.(false), "onClickAway") }, /* @__PURE__ */ React5.createElement(FlexGrowCol, { role: "presentation", justifyContent: "start", p: 2, rowGap: 2, minWidth: "33vw" }, /* @__PURE__ */ React5.createElement(FlexRow, { alignContent: "start", justifyContent: "start", width: "100%" }, /* @__PURE__ */ React5.createElement(IconButton, { onClick: /* @__PURE__ */ __name(() => setOpen?.(false), "onClick") }, /* @__PURE__ */ React5.createElement(CloseIcon, null))), /* @__PURE__ */ React5.createElement(ModuleDescriptionBox, { mod: node }), children))); }, "NodeDrawer"); // src/index.ts export * from "@xyo-network/react-node-context"; export * from "@xyo-network/react-node-provider"; export { NodeBox, NodeDrawer, getModuleFilterOptions, getModuleFromNodeConfigLogger, getWeakModuleFilterOptions, getWeakModuleFromNodeConfigLogger, useModuleFromNode, useModulesFromNode, useNode, useNodeConfigNodeField, useNodeDescription, useNodeFromNode, useNodesFromNode, useProvidedNode, useWeakModuleFromNode, useWeakModulesFromNode, useWeakNodeConfigNodeField, useWeakNodeDescription, useWeakNodeFromNode, useWeakProvidedNode }; //# sourceMappingURL=index.mjs.map