Flowgix.Core
0.1.0
dotnet add package Flowgix.Core --version 0.1.0
NuGet\Install-Package Flowgix.Core -Version 0.1.0
<PackageReference Include="Flowgix.Core" Version="0.1.0" />
<PackageVersion Include="Flowgix.Core" Version="0.1.0" />
<PackageReference Include="Flowgix.Core" />
paket add Flowgix.Core --version 0.1.0
#r "nuget: Flowgix.Core, 0.1.0"
#addin nuget:?package=Flowgix.Core&version=0.1.0
#tool nuget:?package=Flowgix.Core&version=0.1.0
@flowgix/core
A powerful and flexible core library for the Flowgix plugin system, written in F# and compiled to JavaScript using Fable. This library provides the foundation for building node-based visual programming environments with a robust plugin architecture.
Features
- Plugin System: A robust plugin architecture that allows for easy extension of functionality
- Dynamic plugin registration and unregistration
- Plugin lifecycle management (initialization and cleanup)
- Custom plugin configurations and engines
- Node Graph Engine: A powerful engine for evaluating node graphs with support for:
- Custom node types with type-safe inputs and outputs
- Port types with automatic type conversion
- Control system for node configuration
- Circular dependency detection
- Caching for performance optimization
- Type Safety: Full TypeScript support with comprehensive type definitions
- Strong typing for all core components
- Type-safe plugin development
- Runtime type checking and validation
- Extensibility: Easy to extend with custom node types, port types, and plugins
- Flexible plugin API
- Custom resolvers for ports and nodes
- Support for custom renderers and controls
Installation
NPM (JavaScript/TypeScript)
npm install @flowgix/core
NuGet (.NET/C#/F#)
# Using the .NET CLI
dotnet add package Flowgix.Core
# Using the Package Manager Console
Install-Package Flowgix.Core
Package References
C# (.csproj)
<PackageReference Include="Flowgix.Core" Version="0.1.0" />
F# (.fsproj)
<PackageReference Include="Flowgix.Core" Version="0.1.0" />
Prerequisites
For development:
Development Setup
- Install Fable as a local tool:
dotnet new tool-manifest
dotnet tool install fable
- Install npm dependencies:
npm install
Building
One-time Build
npm run build
Watch Mode (for development)
npm run watch
Testing
Run Tests Once
npm test
Watch Mode for Tests
npm run test:watch
Project Structure
flowgix-core/
├── src/
│ ├── Types.fs # Core type definitions
│ ├── Plugin.fs # Plugin system implementation
│ ├── Engine.fs # Node graph engine
│ ├── index.ts # TypeScript declarations
│ └── example.ts # Usage example
├── tests/ # Test files
├── dist/ # Compiled output
├── package.json # npm package configuration
├── tsconfig.json # TypeScript configuration
├── babel.config.js # Babel configuration
└── jest.config.cjs # Jest configuration
Usage
TS Example
import { IFlowgixEngine, IPluginManager, type NodeType, type PortType } from 'flowgix-core';
// Define port types
const numberPort: PortType = {
name: 'number',
type: 'number',
resolver: (type, inputData, value) => Number(value)
};
// Define node types
const addNumbers: NodeType = {
id: 'add-numbers',
name: 'Add Numbers',
description: 'Adds two numbers together',
category: 'Math',
inputs: ['a', 'b'],
outputs: ['result'],
controls: [],
resolver: (node, inputData, nodeType, context) => {
const a = Number(inputData['a']);
const b = Number(inputData['b']);
return { result: a + b };
}
};
// Create a plugin
const mathPlugin = {
id: 'math-plugin',
name: 'Math Plugin',
description: 'Basic mathematical operations',
nodeTypes: [addNumbers],
portTypes: [numberPort]
};
// Initialize the plugin manager
const pluginManager: IPluginManager = {
registerPlugin: (registration) => { /* ... */ },
unregisterPlugin: (pluginId) => { /* ... */ },
getPluginConfig: (pluginId) => { /* ... */ },
getPluginEngine: (pluginId) => { /* ... */ },
getPlugins: () => { /* ... */ },
onInit: () => { /* ... */ },
onCleanup: () => { /* ... */ }
};
// Create and evaluate a graph
const engine: IFlowgixEngine = {
createConfig: (nodeTypes, portTypes, controls) => { /* ... */ },
createEngine: (config, portResolver, nodeResolver) => { /* ... */ },
evaluateGraph: (engine, nodes) => { /* ... */ }
};
const config = engine.createConfig(
[addNumbers],
[numberPort],
[]
);
const rootEngine = engine.createEngine(
config,
(type, inputData, value) => Number(value),
(node, inputData, nodeType, context) => {
const resolver = nodeType.resolver;
if (resolver) {
return resolver(node, inputData, nodeType, context);
}
return {};
}
);
const nodes = new Map([
['node1', {
id: 'node1',
type: 'add-numbers',
root: true,
inputData: { a: 5, b: 3 },
connections: {}
}]
]);
const result = engine.evaluateGraph(rootEngine, nodes);
console.log(result); // { result: 8 }
F# Example
open Flowgix.Core
// Define port types
let numberPort = {
name = "number"
type = "number"
resolver = fun type inputData value ->
match value with
| :? string as s -> float s
| :? float as f -> f
| _ -> 0.0
}
// Define node types
let addNumbers = {
id = "add-numbers"
name = "Add Numbers"
description = "Adds two numbers together"
category = "Math"
inputs = ["a"; "b"]
outputs = ["result"]
controls = []
resolver = fun node inputData nodeType context ->
let a = float inputData["a"]
let b = float inputData["b"]
Map [("result", a + b)]
}
// Create a plugin
let mathPlugin = {
id = "math-plugin"
name = "Math Plugin"
description = "Basic mathematical operations"
nodeTypes = [addNumbers]
portTypes = [numberPort]
}
// Initialize the plugin manager
let pluginManager = {
registerPlugin = fun registration -> ()
unregisterPlugin = fun pluginId -> ()
getPluginConfig = fun pluginId -> Some mathPlugin
getPluginEngine = fun pluginId -> None
getPlugins = fun () -> [mathPlugin]
onInit = fun () -> ()
onCleanup = fun () -> ()
}
// Create and evaluate a graph
let engine = {
createConfig = fun nodeTypes portTypes controls ->
{ nodeTypes = nodeTypes; portTypes = portTypes; controls = controls }
createEngine = fun config portResolver nodeResolver ->
{ config = config; portResolver = portResolver; nodeResolver = nodeResolver }
evaluateGraph = fun engine nodes ->
let node = Map.find "node1" nodes
let result = engine.nodeResolver node node.inputData addNumbers Map.empty
result
}
let config = engine.createConfig [addNumbers] [numberPort] []
let rootEngine = engine.createEngine(
config,
(fun type inputData value -> float value),
(fun node inputData nodeType context ->
match nodeType.resolver with
| Some resolver -> resolver node inputData nodeType context
| None -> Map.empty)
)
let nodes = Map [
("node1", {
id = "node1"
type = "add-numbers"
root = true
inputData = Map [("a", 5.0); ("b", 3.0)]
connections = Map.empty
})
]
let result = engine.evaluateGraph(rootEngine, nodes)
printfn "%A" result // Map [("result", 8.0)]
C# Example
using Flowgix.Core;
// Define port types
var numberPort = new PortType
{
Name = "number",
Type = "number",
Resolver = (type, inputData, value) => Convert.ToDouble(value)
};
// Define node types
var addNumbers = new NodeType
{
Id = "add-numbers",
Name = "Add Numbers",
Description = "Adds two numbers together",
Category = "Math",
Inputs = new[] { "a", "b" },
Outputs = new[] { "result" },
Controls = Array.Empty<ControlType>(),
Resolver = (node, inputData, nodeType, context) =>
{
var a = Convert.ToDouble(inputData["a"]);
var b = Convert.ToDouble(inputData["b"]);
return new Dictionary<string, object> { { "result", a + b } };
}
};
// Create a plugin
var mathPlugin = new FlowgixPlugin
{
Id = "math-plugin",
Name = "Math Plugin",
Description = "Basic mathematical operations",
NodeTypes = new[] { addNumbers },
PortTypes = new[] { numberPort }
};
// Initialize the plugin manager
var pluginManager = new PluginManager
{
RegisterPlugin = registration => { },
UnregisterPlugin = pluginId => { },
GetPluginConfig = pluginId => mathPlugin,
GetPluginEngine = pluginId => null,
GetPlugins = () => new[] { mathPlugin },
OnInit = () => { },
OnCleanup = () => { }
};
// Create and evaluate a graph
var engine = new FlowgixEngine
{
CreateConfig = (nodeTypes, portTypes, controls) =>
new FlowgixConfig { NodeTypes = nodeTypes, PortTypes = portTypes, Controls = controls },
CreateEngine = (config, portResolver, nodeResolver) =>
new FlowgixRootEngine { Config = config, PortResolver = portResolver, NodeResolver = nodeResolver },
EvaluateGraph = (engine, nodes) =>
{
var node = nodes["node1"];
var result = engine.NodeResolver(node, node.InputData, addNumbers, new Dictionary<string, object>());
return result;
}
};
var config = engine.CreateConfig(new[] { addNumbers }, new[] { numberPort }, Array.Empty<Control>());
var rootEngine = engine.CreateEngine(
config,
(type, inputData, value) => Convert.ToDouble(value),
(node, inputData, nodeType, context) =>
{
if (nodeType.Resolver != null)
{
return nodeType.Resolver(node, inputData, nodeType, context);
}
return new Dictionary<string, object>();
}
);
var nodes = new Dictionary<string, FlumeNode>
{
["node1"] = new FlumeNode
{
Id = "node1",
Type = "add-numbers",
Root = true,
InputData = new Dictionary<string, object> { { "a", 5.0 }, { "b", 3.0 } },
Connections = new Dictionary<string, object>()
}
};
var result = engine.EvaluateGraph(rootEngine, nodes);
Console.WriteLine(string.Join(", ", result.Select(kvp => $"{kvp.Key}: {kvp.Value}"))); // result: 8
Core Components
Control Types
The library supports various control types for node configuration:
- Text
- Number
- Checkbox
- Select
- MultiSelect
- Custom
- Boolean
- Object
Port Types
Built-in port types include:
- NumberPort
- TextPort
- BooleanPort
- OutcomeActionCollectionPort
- LLMAgentPort
- CustomPort (for custom implementations)
Node Types
Core node types include:
- AddNumbers
- FlowgixResults
- OutcomeAttributes
- DivideNumbers
- CustomNode (for custom implementations)
API Reference
Core Types
ControlType
interface ControlType {
type: string;
label: string;
name: string;
portName: string;
defaultValue: any;
}
PortType
interface PortType {
name: string;
type: string;
resolver?: (type: string, inputData: any, value: any) => any;
}
NodeType
interface NodeType {
id: string;
name: string;
description: string;
category: string;
inputs: string[];
outputs: string[];
controls: ControlType[];
resolver?: (node: any, inputData: any, nodeType: NodeType, context: any) => Record<string, any>;
}
Plugin System
IPluginManager
interface IPluginManager {
registerPlugin(registration: PluginRegistration): void;
unregisterPlugin(pluginId: string): void;
getPluginConfig(pluginId: string): FlowgixPlugin | undefined;
getPluginEngine(pluginId: string): FlowgixRootEngine | undefined;
getPlugins(): FlowgixPlugin[];
onInit(): void;
onCleanup(): void;
}
Engine
IFlowgixEngine
interface IFlowgixEngine {
createConfig(
nodeTypes: NodeType[],
portTypes: PortType[],
controls: Control[]
): FlowgixConfig;
createEngine(
config: FlowgixConfig,
portResolver: (type: string, inputData: any, value: any) => any,
nodeResolver: (node: FlumeNode, inputData: any, nodeType: NodeType, context: any) => Record<string, any>
): FlowgixRootEngine;
evaluateGraph(engine: FlowgixRootEngine, nodes: Map<string, FlumeNode>): Record<string, any>;
}
Publishing
To publish this package to npm:
- Build the package:
npm run build
- Test the package:
npm test
- Update the version in package.json:
npm version patch # for bug fixes
npm version minor # for new features
npm version major # for breaking changes
- Login to npm (if not already logged in):
npm login
- Publish the package:
npm publish
For scoped packages (e.g., @your-org/flowgix-core):
npm publish --access public
Pre-publish Checklist
- All tests pass
- Build is successful
- Version is updated
- README is up to date
- No sensitive data in the package
- All necessary files are included
- package.json has correct metadata
Contributing
- Fork the repository at github.com/flowgix/flowgix-core
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
For support, please open an issue in the GitHub repository.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- FSharp.Core (>= 9.0.201)
- Thoth.Json.Net (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
0.1.0 | 156 | 3/31/2025 |
Initial release