Git Product home page Git Product logo

vixenypluginimplementation's Introduction

Introduction to Plugins in the Vixeny Library

In this guide, we're embarking on an exciting journey to create an application leveraging the power of plugins within the Vixeny library. We'll begin by setting up our file structure, which is the foundation of our application:

app.ts
src/
    /plugins/*
    /helpers.ts

Setting Up the Base Application

In app.ts, our starting point:

import fun from 'vixeny/fun';
// Global options
import options from './src/helpers';

Bun.serve({
    fetch: fun(
        options
    )([
        {
            path: '/',
            // A simple route for starters
            f: () => 'Hello World'
        }
    ])
});

Next, in src/helpers.ts:

import { FunRouterOptions } from 'vixeny/components/http/types';
// Setting up a default export for router options
export default {} as FunRouterOptions;

Crafting Our First Plugin

Let's dive into plugin creation by adding helloWorld.ts in the src/plugins directory:

const hello = {
    // Names in Vixeny are polymorphic, hence the necessity of inserting a Symbol
    name: Symbol.for('hello'),
    // Currently, no specific type is required
    type: undefined,
    // Ignoring the first two curried functions for now 
    f: (_) => (_) => (_) => 'Hello World'
};


export default {...hello};

And modify helpers.ts:

// Here we are using helloWorld, but it can be anything
import helloWorld from './plugins/helloWorld';

const options = {
    cyclePlugin: {
        // Integrating our HelloWorld plugin
        helloWorld
    }
};


// Ensuring correct typing due to TypeScript limitations
const typing = (I: FunRouterOptions) => I;
typing(options);

export default options;

And define our final route in app.ts:

        {
            path: '/',
            // Utilizing the HelloWorld plugin
            f: f => f.helloWorld
        }

Implementing the Request Plugin

Now, let's introduce url.ts:

import { CyclePlugin } from "vixeny/components/http/types";


const url = {
    // Use a unique symbol as the name for the plugin. This ensures the name is unique and avoids name collisions.
    name: Symbol.for("hello"),

    // 'type' is not requiered
    type: undefined,

    // Capturing the URL from the request.
    f: (_)=> (_)=>(r: Request)=>r.url
};

// Self-invoking function to enforce type-checking.
// This ensures 'url' adheres to the CyclePlugin type structure.
((I:CyclePlugin)=>I)(url);


export default {...url};

We'll incorporate this into helper.ts and update app.ts accordingly.

//helper.ts
{
    //other code
        cyclePlugin: {
        helloWorld,
        url
    }
}
//app.ts
        {
            path: '/url',
            f: f => f.url
        }

Exploring GlobalOptions

Understanding the polymorphic nature of Vixeny can be challenging. However, with the use of symbols, we can infer the name of our plugin:

/**
 * Creates a unique CyclePlugin object each time it's called.
 * This plugin, when used, returns the name assigned to it in the router options.
 */
const whoIAM = () => {
    // Generates a unique symbol for each call, ensuring a distinct identifier.
    const sym = Symbol("whoIAM");

    return {
        name: sym,
        type: undefined,
        f: (routerOptions?:FunRouterOptions) => (_) => (_) => {
            // Finds and returns the key under which this plugin is stored in routerOptions.
            const currentName = Object
                .keys(routerOptions?.cyclePlugin ?? [])
                //
                .find(name => routerOptions.cyclePlugin[name].name === sym) as string;

            return currentName;
        }
    }
}

((I:CyclePlugin)=>I)(whoIAM());

After adding it to helper.ts, we set up corresponding routes in app.ts.

//helper.ts
{

    cyclePlugin: {
        helloWorld,
        url,
        dave : whoIAM(),
        avant: whoIAM(),
    }
}
//app.ts
        {
            path: '/dave',
            f: f => f.dave
        },
        {
            path: '/avant',
            f: f => f.avant
        }

Introducing Plugin Options

Our next step is to create an adder plugin, which retrieves its value from plugins. We'll add adder.ts in our plugins directory:

/**
 * Creates an 'adder' plugin that can be used to add a number to a given value.
 * Each instance of the plugin has a unique identifier.
 */
const adder = () => {
    // Generates a unique symbol for each call to ensure a distinct identity for the plugin.
    const sym = Symbol("adder");

    return {
        name: sym,
        // 'type' is set as a number, but it can represent a different type if needed.
        type: {} as number,
        f: (routerOptions?: FunRouterOptions) => (userOptions?: Petition) => {
            // Retrieves the name of this plugin from routerOptions based on the unique symbol.
            const currentName = Object
                .keys(routerOptions?.cyclePlugin ?? [])
                .find(name => routerOptions?.cyclePlugin[name].name === sym) as string;

            // Extracts the value associated with this plugin from userOptions.
            const value = userOptions.plugins[currentName] as number;

            // Throws an error if the value is not provided or is not a number.
            if (value === null || value === undefined) {
                throw new Error(`${currentName} requires a number in "plugins"`);
            }

            // Returns a function that adds the provided value to its argument.
            return(_R: Request)=> (n: number) => value + n;
        }
    }
};

// Self-invoking function to enforce type-checking against the CyclePlugin type.
((I: CyclePlugin) => I)(adder());

// Exports the 'adder' function as the default export of this module.
export default adder;

Following this, we'll update helper.ts and app.ts to integrate the new plugin.

//helper.ts
    cyclePlugin: {
        helloWorld,
        url,
        dave : whoIAM(),
        avant: whoIAM(),
        adder: adder()
    }
       {
            path: '/addFive/:number',
            f: f =>  f.adder(Number(f.param.number) || 0 ).toString(),
            plugins:{
                adder: 5
            }
        },
        {
            path: '/addFour/:number',
            f: f =>  f.adder(Number(f.param.number) || 0 ).toString(),
            plugins:{
                adder: 4
            }
        },

The Plugins in the Vixeny Library enhance applications with their unique and versatile features. Key capabilities include:

  1. Unique Identification: Each plugin is distinctively identified, usually with symbols, ensuring no conflicts and precise functionality within the application.

  2. Custom Functionality: They offer a range of functionalities, from simple tasks like returning a string to complex request-response interactions.

  3. Adaptable Configuration: They are highly configurable, allowing for diverse applications and enhancing their reusability.

  4. Dynamic Operations: The plugins are polymorphic and can dynamically determine their roles and names in the application, adapting to various scenarios.

Overall, Vixeny Library plugins provide a robust and adaptable way to extend application capabilities, suitable for a broad array of tasks and application needs.

And that's all for our guide on Vixeny plugins. Thank you for following along, and happy coding!

vixenypluginimplementation's People

Contributors

mimimonads avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.