UNPKG

metagraph

Version:

A framework for building higher-order graph data structures

161 lines (156 loc) 5.95 kB
/*! * metagraph.js <%= conf.pkg.version %> * http://gordonwoodhull.github.io/metagraph.js/ * Copyright 2019 AT&T Intellectual Property * * Licensed under the MIT License * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ import { as_array, build_map } from './core.js'; /** * Creates a dataflow input node that reads data from the input namespace. * * @param path - Optional path to the input data (defaults to node key) * @returns A dataflow node specification for reading input data * * @example * ```typescript * // Read from 'data.nodeList' * const nodeInput = input('data.nodeList'); * * // Read from default path * const defaultInput = input(); * ``` */ const input = (path) => ({ calc: (fnode) => { const actualPath = path || fnode.key(); const parts = actualPath.split('.'); const [namespace, name] = parts.length > 1 ? parts : ['data', actualPath]; return (defn) => (flow) => () => flow.input(namespace, name); } }); /** * Creates a dataflow output node that passes through its input unchanged. * Used as a terminal node in dataflow graphs. * * @param name - Optional output name (unused in current implementation) * @param namespace - Optional output namespace (unused in current implementation) * @returns A dataflow node specification that passes through input data */ const output = (name, namespace) => ({ calc: (fnode) => (defn) => (flow) => (x) => x }); /** * Creates a dataflow node that builds a map from array data using pattern-defined accessors. * Maps each item in the input array to a wrapped object using the pattern's key accessor. * * @returns A dataflow node specification for creating maps from arrays * * @example * ```typescript * // In a pattern definition * const mapNode = map(); // Creates {key1: wrappedItem1, key2: wrappedItem2, ...} * ``` */ const map = () => ({ calc: (fnode) => { const iref = as_array(fnode.value().refs)[0]; return (defn) => (flow) => (data) => build_map(data, defn.node[iref].members.key.accessor, defn.node[iref].wrap.bind(null, flow)); } }); /** * Creates a dataflow node representing a singleton that must be initialized elsewhere. * Throws an error if accessed before initialization. * * @returns A dataflow node specification for singleton values * @throws Error when accessed before proper initialization */ const singleton = () => ({ calc: (fnode) => (defn) => (flow) => () => { throw new Error('singleton not initialized'); } }); /** * Creates a dataflow node that converts a map back to a list using array order. * Takes input data array and map, returns array of mapped objects in original order. * * @returns A dataflow node specification for creating ordered lists from maps * * @example * ```typescript * // Convert map back to ordered array * const listNode = list(); // [data[0] -> map[key0], data[1] -> map[key1], ...] * ``` */ const list = () => ({ calc: (fnode) => { const iref = as_array(fnode.value().refs)[0]; return (defn) => (flow) => (data, map) => data.map(val => map[defn.node[iref].members.key.accessor(val)]); } }); /** * Creates a dataflow node that groups array items into lists based on a grouping function. * Useful for creating adjacency lists or grouping related items. * * @param accessor - Function to extract the grouping key from each item * @returns A dataflow node specification for grouping items into lists * * @example * ```typescript * // Group edges by source node * const outEdges = map_of_lists(edge => edge.source); * // Result: {nodeA: [edge1, edge2], nodeB: [edge3], ...} * ``` */ const map_of_lists = (accessor) => ({ calc: (fnode) => (defn) => (flow) => (data, map) => { const iref = as_array(fnode.value().refs)[0]; return data.reduce((o, v) => { const key = accessor(v); const list = o[key] = o[key] || []; list.push(map[defn.node[iref].members.key.accessor(v)]); return o; }, {}); } }); /** * Creates a dataflow node that filters array items to include only those with keys in a specified set. * Used for creating subgraphs or filtering collections. * * @returns A dataflow node specification for filtering arrays by key membership * * @example * ```typescript * // Keep only nodes with keys in the specified set * const filteredNodes = subset(); // filters items where item.key ∈ keySet * ``` */ const subset = () => ({ calc: (fnode) => { const iref = as_array(fnode.value().refs)[0]; return (defn) => (flow) => (items, keys) => { const keySet = new Set(keys); return items.filter(r => keySet.has(defn.node[iref].members.key.accessor(r))); }; } }); export { input, list, map, map_of_lists, output, singleton, subset }; //# sourceMappingURL=dataflow_calcs.js.map