FluxSharp Package System Guide
Overview
The FluxSharp package system allows you to organize, structure, and reuse code across multiple files. This guide covers how to create, organize, and manage packages effectively.
Table of Contents
- Basic Concepts
- Package Structure
- Creating Packages
- Importing Packages
- Best Practices
- Package Organization Patterns
- Error Handling
- Advanced Patterns
Basic Concepts
What is a Package?
A package in FluxSharp is a collection of related .fsh files that provide specific functionality. Packages are the primary mechanism for code organization and reuse.
Key Principles
- Modularity: Each package has a single responsibility
- Reusability: Packages can be imported and used in multiple programs
- Isolation: Packages maintain their own scope and dependencies
- Clarity: Clear naming and structure make packages easy to understand
Package Structure
Minimal Package Structure
project/
โโโ main.fsh # Entry point with Main class
โโโ packages/
โโโ math/
โ โโโ calculator.fsh # Core math operations
โ โโโ advanced.fsh # Advanced math functions
โโโ utils/
โโโ string.fsh # String utilities
โโโ array.fsh # Array utilitiesComplete Package Structure
project/
โโโ main.fsh # Entry point
โโโ packages/
โ โโโ math/
โ โ โโโ core.fsh # Core operations
โ โ โโโ algebra.fsh # Algebra module
โ โ โโโ geometry.fsh # Geometry module
โ โ โโโ README.md # Package documentation
โ โโโ utils/
โ โ โโโ string.fsh
โ โ โโโ array.fsh
โ โ โโโ date.fsh
โ โ โโโ README.md
โ โโโ database/
โ โโโ connection.fsh
โ โโโ query.fsh
โ โโโ migration.fsh
โ โโโ README.md
โโโ examples/
โโโ example1.fsh
โโโ example2.fshDirectory Naming Conventions
packages/
โโโ math/ # โ
Lowercase for package names
โโโ string_utils/ # โ
Use underscores for multi-word packages
โโโ DataAccess/ # โ Avoid PascalCase for directories
โโโ db-operations/ # โ ๏ธ Hyphens work but underscores are preferredCreating Packages
Step 1: Organize by Functionality
Create a package directory for each distinct set of features:
packages/
โโโ math/ # All math-related utilities
โโโ io/ # Input/output operations
โโโ crypto/ # Cryptographic functions
โโโ serialization/ # Data serializationStep 2: Define Package Classes
Each package typically contains one or more related classes:
packages/math/calculator.fsh
public class Calculator {
public int Add(int a, int b) {
return a + b;
}
public int Subtract(int a, int b) {
return a - b;
}
public int Multiply(int a, int b) {
return a * b;
}
public int Divide(int a, int b) {
if (b == 0) {
print("Error: Division by zero");
return 0;
}
return a / b;
}
}Step 3: Create Helper Utilities
packages/math/statistics.fsh
public class Statistics {
public int Sum(int[] numbers) {
int total = 0;
int i = 0;
while (i < numbers.Length) {
total = total + numbers[i];
i = i + 1;
}
return total;
}
public int Average(int[] numbers) {
if (numbers.Length == 0) {
return 0;
}
int total = this.Sum(numbers);
return total / numbers.Length;
}
}Step 4: Document Your Package
packages/math/README.md
# Math Package
Provides mathematical utilities for calculations.
## Classes
### Calculator
- `Add(int a, int b)` - Add two numbers
- `Subtract(int a, int b)` - Subtract two numbers
- `Multiply(int a, int b)` - Multiply two numbers
- `Divide(int a, int b)` - Divide two numbers
### Statistics
- `Sum(int[] numbers)` - Sum all numbers in array
- `Average(int[] numbers)` - Calculate average
## Usage Example
fsh using "packages/math/calculator.fsh"; using "packages/math/statistics.fsh";
public class Main { public void main() { Calculator calc = new Calculator(); int result = calc.Add(5, 3); print(result); } }
```
---
## Importing Packages
### Basic Import
**Using Directive (Recommended)**fsh using "packages/math/calculator.fsh"; using "packages/utils/string.fsh";
public class Main { public void main() { Calculator calc = new Calculator(); int sum = calc.Add(10, 20); print(sum); } }
**Import Directive (Alternative)**fsh import "packages/math/calculator.fsh";
public class Main { public void main() { // Same functionality as using } }
### Multiple Imports
fsh // Math package using "packages/math/calculator.fsh"; using "packages/math/statistics.fsh";
// Utilities package using "packages/utils/string.fsh"; using "packages/utils/array.fsh";
// Database package using "packages/database/connection.fsh"; using "packages/database/query.fsh";
public class Main { public void main() { // Use all imported classes } }
### Import Order
fsh // 1. System imports first (if any) // 2. Package imports (organized by module) // 3. Local imports
// Core math using "packages/math/core.fsh";
// Extended math (may depend on core) using "packages/math/advanced.fsh";
// Utilities using "packages/utils/helpers.fsh";
// Main program public class Main { public void main() { // Implementation } }
---
## Best Practices
### 1. Single Responsibility Principle
Each package should handle **one concept**:
โ Good packages/ โโโ http/ # Only HTTP functionality โโโ json/ # Only JSON parsing โโโ crypto/ # Only cryptography
โ Avoid packages/ โโโ utilities/ # Too vague, mixes everything
### 2. Clear Naming
fsh // โ Clear, descriptive names public class HttpClient { } public class JsonParser { } public class AesEncryption { }
// โ Vague names public class Helper { } public class Util { } public class Process { }
### 3. Consistent Naming Convention
fsh // Use PascalCase for class names public class UserManager { }
// Use PascalCase for method names public void CreateUser(string name) { }
// Use lowercase for package/directory names packages/user_management/
// Use underscores in filenames for multi-word files packages/user_management/user_validator.fsh
### 4. Dependency Organization
packages/ โโโ base/ # No dependencies โ โโโ types.fsh โโโ utils/ # Depends only on base โ โโโ helpers.fsh โโโ services/ # Depends on base and utils โโโ processor.fsh
**File Dependencies:**fsh // processor.fsh - Services level using "packages/base/types.fsh"; // โ Can import base using "packages/utils/helpers.fsh"; // โ Can import utils using "packages/services/other.fsh"; // โ Can import same level
### 5. Avoid Circular Dependencies
โ Bad (Circular) calculator.fsh imports validator.fsh validator.fsh imports calculator.fsh
โ Good (Linear) main.fsh imports calculator.fsh calculator.fsh imports validator.fsh validator.fsh has no imports (or only imports base)
---
## Package Organization Patterns
### Pattern 1: Functional Packages
Organize by functionality:packages/ โโโ authentication/ โโโ authorization/ โโโ payments/ โโโ notifications/ โโโ reports/
### Pattern 2: Layered Packages
Organize by architectural layer:packages/ โโโ domain/ # Core business logic โโโ application/ # Use cases and services โโโ infrastructure/ # External integrations โโโ presentation/ # UI/API logic
### Pattern 3: Domain-Driven Packages
Organize by business domain:packages/ โโโ user/ โ โโโ model.fsh โ โโโ service.fsh โ โโโ repository.fsh โโโ product/ โ โโโ model.fsh โ โโโ service.fsh โ โโโ repository.fsh โโโ order/ โโโ model.fsh โโโ service.fsh โโโ repository.fsh
### Pattern 4: Feature-Based Packages
Organize by features:packages/ โโโ authentication/ โ โโโ login.fsh โ โโโ logout.fsh โ โโโ token.fsh โโโ user_profile/ โ โโโ view.fsh โ โโโ edit.fsh โ โโโ settings.fsh โโโ notifications/ โโโ email.fsh โโโ sms.fsh โโโ push.fsh
---
## Error Handling
### Common Import Errors
#### 1. File Not Found
fsh using "packages/math/unknown.fsh"; // โ Error
Error: IMPORT FILE NOT FOUND Cannot find imported file: 'packages/math/unknown.fsh'
**Solution:**fsh using "packages/math/calculator.fsh"; // โ Correct path
#### 2. Invalid Extension
fsh using "packages/math/readme.txt"; // โ Error
Error: INVALID IMPORT FILE File must have .fsh extension: 'readme.txt'
**Solution:**fsh using "packages/math/calculator.fsh"; // โ .fsh extension
#### 3. Circular Import
fsh // file1.fsh using "packages/file2.fsh";
// file2.fsh using "packages/file1.fsh"; // โ Error - Circular import
**Solution:** Restructure dependencies:fsh // base.fsh (no imports) public class Base { }
// file1.fsh using "packages/base.fsh";
// file2.fsh using "packages/base.fsh";
#### 4. Multiple Main Classes
fsh // main.fsh using "packages/math/calculator.fsh";
public class Main { // โ Main class here public void main() { } }
// calculator.fsh public class Main { // โ Error - Another Main class public void process() { } }
**Solution:** Don't include Main class in packagesfsh // calculator.fsh public class Calculator { // โ Regular class, not Main public int Add(int a, int b) { return a + b; } }
---
## Advanced Patterns
### Pattern 1: Package Facade
Create a single entry point for a complex package:
fsh // packages/math/facade.fsh using "packages/math/calculator.fsh"; using "packages/math/statistics.fsh";
public class MathFacade { private Calculator calculator; private Statistics statistics;
public MathFacade() { this.calculator = new Calculator(); this.statistics = new Statistics(); }
public int Add(int a, int b) { return this.calculator.Add(a, b); }
public int GetAverage(int[] numbers) { return this.statistics.Average(numbers); } }
**Usage:**fsh using "packages/math/facade.fsh";
public class Main { public void main() { MathFacade math = new MathFacade(); int sum = math.Add(5, 3); int avg = math.GetAverage(new int[]{1, 2, 3}); } }
### Pattern 2: Package Initialization
Initialize package resources on startup:
fsh // packages/database/manager.fsh public class DatabaseManager { private bool initialized = false;
public void Initialize() { print("Initializing database..."); // Setup code this.initialized = true; print("Database ready"); }
public bool IsReady() { return this.initialized; } }
**Usage:**fsh using "packages/database/manager.fsh";
public class Main { public void main() { DatabaseManager db = new DatabaseManager(); db.Initialize();
if (db.IsReady()) { print("Starting application"); } } }
### Pattern 3: Configuration Injection
Pass configuration to packages:
fsh // packages/utils/logger.fsh public class Logger { private string logLevel;
public Logger(string level) { this.logLevel = level; }
public void Log(string message) { print("["); print(this.logLevel); print("] "); print(message); } }
**Usage:**fsh using "packages/utils/logger.fsh";
public class Main { public void main() { Logger logger = new Logger("INFO"); logger.Log("Application started"); } }
---
## Building and Installing Packages
### FluxSharp Built-in Package Manager
FluxSharp includes a **built-in package manager** directly in the `build.sh` script. Packages are bundled in the compiler binary, so no internet connection is required!
#### Available Built-in Packages
- **sdl2** - SDL2 graphics and input library
- **opengl** - OpenGL graphics rendering
- **stdio** - Standard input/output utilities
- **stdlib** - Standard library functions
- **ncurses** - Terminal UI library
- **sqlite3** - SQL database engine
#### Package Manager Commands
bash
List all available packages
./build.sh pkg list
Get details about a package
./build.sh pkg info sdl2
Install a package (extracts .fsh to ./packages/)
./build.sh pkg install sdl2
Search for packages by keyword
./build.sh pkg search "database"
#### Installing a Package
**Step 1: List available packages**bash $ ./build.sh pkg list ๐ฆ Available Packages: sdl2 - SDL2 graphics library opengl - OpenGL rendering stdio - Standard I/O functions stdlib - Standard library ncurses - Terminal UI sqlite3 - SQL database
**Step 2: Install the package you need**bash $ ./build.sh pkg install sdl2 โ Package 'sdl2' extracted to ./packages/sdl2/
Files:
- graphics.fsh
- input.fsh
- events.fsh
**Step 3: Use in your program**fsh using "packages/sdl2/graphics.fsh"; using "packages/sdl2/input.fsh";
public class Main { public void main() { // Your SDL2 code here } }
**Step 4: Compile with build.sh**bash ./build.sh main.fsh
The compiler automatically:
- โ
Finds installed packages
- โ
Processes all imports
- โ
Links with C libraries (if system libs are installed)
- โ
Creates executable
#### Package Information
**Get detailed package info:**bash $ ./build.sh pkg info sdl2
Package: sdl2 Version: 2.26.0 Description: Cross-platform SDL2 graphics and input library
Files:
- graphics.fsh (2.1 KB)
- input.fsh (1.8 KB)
- events.fsh (3.2 KB)
System Requirements: Ubuntu/Debian: sudo apt install libsdl2-dev Fedora/RHEL: sudo dnf install SDL2-devel macOS: brew install sdl2
Example Usage: using "packages/sdl2/graphics.fsh";
public class Main { public void main() { // Create window, handle events, etc. } }
#### System Library Dependencies
Some packages require C libraries to be installed on your system:
| Package | System Command |
|---------|-----------------|
| **sdl2** | `sudo apt install libsdl2-dev` |
| **opengl** | `sudo apt install libgl-dev` |
| **ncurses** | `sudo apt install libncurses-dev` |
| **sqlite3** | `sudo apt install libsqlite3-dev` |
**After installing system libraries**, your FluxSharp programs can use them directly!
### Using build.sh
The FluxSharp compiler provides a `build.sh` script for building and compiling packages. This script handles the complete compilation workflow including package resolution.
#### Basic Usage
bash
Compile a single file
./build.sh main.fsh
Build and output to specific location
./build.sh main.fsh -o bin/myapp
Show help
./build.sh --help
### Creating Local Custom Packages
In addition to built-in packages, you can create your own local packages for code organization.
**Two Types of Packages:**
| Type | Location | Installation | Usage |
|------|----------|--------------|-------|
| **Built-in** | Bundled in fluxc | `./build.sh pkg install <name>` | Installed to `./packages/<name>/` |
| **Custom** | Your project | Manual creation | `using "packages/<name>/file.fsh"` |
#### Creating a Custom Package
**Step 1: Create package directory**bash mkdir -p packages/myutils
**Step 2: Create package files**bash
packages/myutils/helpers.fsh
public class StringHelper { public void PrintUpper(string text) { // Implementation } }
packages/myutils/validators.fsh
public class InputValidator { public bool IsValidEmail(string email) { // Implementation } }
**Step 3: Import in your main program**fsh using "packages/myutils/helpers.fsh"; using "packages/myutils/validators.fsh";
public class Main { public void main() { StringHelper helper = new StringHelper(); InputValidator validator = new InputValidator(); } }
**Step 4: Compile**bash ./build.sh main.fsh
#### Combining Built-in and Custom Packages
You can use both at the same time!
**First, install built-in packages:**bash ./build.sh pkg install sdl2 ./build.sh pkg install sqlite3
**Then create custom packages:**bash mkdir -p packages/game mkdir -p packages/database
Create your custom files
- packages/game/engine.fsh
- packages/database/models.fsh
**Use both together:**fsh // Built-in packages (installed via pkg) using "packages/sdl2/graphics.fsh"; using "packages/sqlite3/database.fsh";
// Custom packages (created by you) using "packages/game/engine.fsh"; using "packages/database/models.fsh";
public class Main { public void main() { // Use all packages together } }
**Compile once:**bash ./build.sh main.fsh
### Basic Usage
### Package Management Best Practices
#### FluxSharp Package Model vs Traditional Package Managers
**FluxSharp's Simplified Approach:**
| Feature | FluxSharp | npm/pip | Cargo |
|---------|-----------|---------|-------|
| **Installation** | Just copy files | `npm install` | `cargo add` |
| **Package Registry** | File system | npmjs.com | crates.io |
| **Version Management** | File directories | package.json | Cargo.toml |
| **Dependency Resolution** | Compiler handles it | npm does it | cargo does it |
| **No need for** | Central registry | Central registry | Central registry |
**Why FluxSharp is simpler:**
- โ
**No installation command** - Just place files in directories
- โ
**No lockfile** - Dependencies are deterministic (local files)
- โ
**No version conflicts** - Each project has its own packages
- โ
**Easy to understand** - It's just `.fsh` files in folders
- โ
**Works offline** - No internet needed
**Trade-off:**
- You manage multiple local copies of shared packages (like old SVN days)
- Better for closed-source, private projects
- Better for learning and simple projects
#### 1. Local Package Organization
Organize packages in your project directory. The `build.sh` script automatically finds and compiles them:
bash project/ โโโ main.fsh # Your main entry point โโโ packages/ โ โโโ math/ โ โ โโโ calculator.fsh # Package file โ โ โโโ statistics.fsh โ โโโ utils/ โ โ โโโ helpers.fsh โ โ โโโ validators.fsh โ โโโ database/ โ โโโ connection.fsh โ โโโ query.fsh โโโ build.sh # The compiler & package manager
**That's all you need!** When you run `./build.sh main.fsh`, it:
- Finds all packages
- Processes all imports
- Compiles everything
- Links with runtime
- Creates executable
#### 2. Version Management
Manage package versions by organizing them in directories:
bash packages/ โโโ math/ โ โโโ v1/ # Older version โ โ โโโ calculator.fsh โ โโโ v2/ # Current version โ โโโ calculator.fsh โโโ utils/ โโโ helpers.fsh
**Usage:**fsh // Use specific version by path using "packages/math/v2/calculator.fsh";
#### 3. Package Documentation
Add a `README.md` in each package directory to document usage and contents
#### 4. Sharing Packages Between Projects
Since packages are just local files, you can easily share them:
**Option 1: Copy Package Directory**bash
Copy math package from another project
cp -r ../other-project/packages/math ./packages/
Now use it in your project
using "packages/math/calculator.fsh";
**Option 2: Git Submodules (for teams)**bash
Include shared package as submodule
git submodule add https://github.com/team/flux-math ./packages/math
Use the imported package
using "packages/math/calculator.fsh";
**Option 3: Package Template**bash
Maintain template packages for quick start
template-packages/ โโโ math/ โโโ utils/ โโโ database/
Copy what you need for each project
cp -r template-packages/math ./packages/
### Common Build Scenarios
#### Scenario 1: Build Single Package for Testing
bash
Create test file
cat > test_calculator.fsh << 'EOF' using "packages/math/calculator.fsh";
public class Main { public void main() { Calculator calc = new Calculator(); print(calc.Add(10, 20)); } } EOF
Build and run
./build.sh test_calculator.fsh
#### Scenario 2: Build and Deploy Application
bash #!/bin/bash
deploy.sh
Create deployment directory
mkdir -p build/
Build main application
echo "Building application..." ./build.sh main.fsh -o build/app
Copy packages (for reference)
cp -r packages/ build/packages/
Package for distribution
tar -czf build/fluxsharp-app.tar.gz build/app
echo "โ Deployment package ready: build/fluxsharp-app.tar.gz"
#### Scenario 3: Build Multiple Targets
bash #!/bin/bash
build-all.sh
TARGETS=("main.fsh" "server.fsh" "client.fsh" "cli.fsh")
for target in "${TARGETS[@]}"; do echo "Building $target..." ./build.sh "$target" -o "bin/${target%.fsh}" echo "โ Built: bin/${target%.fsh}" done
echo "All builds completed!"
### Troubleshooting Build Issues
#### Issue 1: Package Not Found
Error: IMPORT FILE NOT FOUND Cannot find imported file: 'packages/math/calculator.fsh'
**Solution:**bash
Check package path exists
ls -la packages/math/calculator.fsh
Verify relative path from main.fsh
pwd # Shows your current directory
#### Issue 2: Circular Dependencies
Error: CIRCULAR IMPORT DETECTED Circular dependency chain: main.fsh โ utils.fsh โ main.fsh
**Solution:**
Restructure your packages to break the cycle:packages/ โโโ core/ # No dependencies โโโ utils/ # Only imports core โโโ services/ # Imports core and utils
#### Issue 3: Build Fails with Multiple Imports
Error: MULTIPLE MAIN CLASSES DETECTED
**Solution:**
Ensure imported files don't have a Main class:fsh // โ packages/math/calculator.fsh (correct) public class Calculator { // No Main class here }
// โ Don't do this in packages public class Main { // Wrong! public void main() { } } ```
Summary
| Concept | Description |
|---|---|
| Package | A collection of related .fsh files |
| Module | A .fsh file containing one or more classes |
| Import | Loading external packages with using or import |
| Dependency | Relationship between packages |
| Facade | Single entry point for complex packages |
| Build Script | ./build.sh - Compiles, links packages & manages installations |
Next Steps
- โ Review Includes and Main for compilation details
- โ Check C# Imports Update for syntax variations
- โ Study Best Practices for general guidelines
- โ Explore Examples for working code