NAME

   Evented::API::Engine - an Evented API Engine for Perl applications.

SYNOPSIS

   Main

       my $api = Evented::API::Engine->new;
       $api->load_module('My::Module');

   My::Module

       # Module metadata
       #
       # @name:        'My::Module'
       # @package:     'M::My::Module'
       # @description:
       #
       # @depends.modules+ 'Some::Other'
       # @depends.modules+ 'Another::Yet'
       #
       # @author.name:     'Mitchell Cooper'
       # @author.website:  'https://github.com/cooper'
       #
       package M::My::Module;

       use warnings;
       use strict;
       use 5.010;

       # Auto-exported variables
       our ($api, $mod);

       # Default initializer
       sub init {
           say 'Loading ', $mod->name;

           # indicates load success
           return 1;
       }

       # Default deinitializer
       sub void {
           say 'Bye!';

           # indicates unload success
           return 1;
       }

       # Package must return module object
       $mod;

DESCRIPTION

   Perl provides a simple way to load dependencies. But what about
   upgrading or unloading? API Engine makes it easy to create an
   excessively versatile Perl application capable of adapting dynamically
   with the user's ever-changing needs.

Module management

   Modules are Perl packages which can be easily loaded, unloaded, and
   reloaded. API Engine automatically tracks the changes made by each
   module and reverts them upon unload, leaving no trace. With API Engine
   used properly, it is even possible to reload your entire program
   without restarting it.

   Modules themselves can determine the necessity of additional code which
   may be dynamically added and removed through the use of submodules.

Dependency resolution

   API Engine automatically resolves dependencies of both modules and
   normal Perl packages. It loads and unloads dependencies in the proper
   order. It is also possible to specify that a submodule is automatically
   loaded and unloaded in conjunction with some top-level module.

Event management

   API Engine is Evented in that it tracks all Evented::Object callbacks
   attached from within modules and automatically removes them upon
   unloading. This allows you to employ events excessively without
   constantly worrying about their eventual disposal.

METHODS

Evented::API::Engine->new(%opts)

   Creates a new instance of the Evented API Engine. This single object
   will be used throughout the life of the application.

       my $api = Evented::API::Engine->new(
           mod_inc  => [ 'mod', '/usr/share/something/mod' ],
           features => [ qw(io-async something-else)       ],
           modules  => [ $conf->keys_for_block('modules')  ]
       );

   Parameters

     * %opts - optional, constructor options.

   %opts - API Engine options

     * \@mod_inc - list of module search directories

     * \@features - optional, list of feature names to enable immediately

     * \@modules - optional, list of names of toplevel modules to load
     immediately

     * \&log_sub - optional, code to be called for API Engine log messages

     * $developer - optional, if true, module info will be written to JSON
     metadata files. your program should include a developer mode option
     which in turn enables this.

   Returns API Engine.

$api->load_modules(@mod_names)

   Loads one or more modules at once.

   This is preferred over calling ->load_module() several times in a row
   because it skips common dependencies which have already been attempted.

   Parameters

     * @mod_names - list of module names to load

   Returns

   Module objects for those which loaded successfully.

$api->load_module($mod_name, $dirs)

   Loads a toplevel module.

   Parameters

     * $mod_name - name of the module to load.

     * \@dirs - optional, module search directories. if omitted, the
     normal search directories specified at API Engine construction time
     will be used.

   Returns

   On success, the loaded module object. Otherwise, false.

$api->unload_module($mod, $unload_dependents, $unload_parent)

   Unloads a module.

   Parameters

     * $mod - module object or name to unload.

     * $unload_dependents - optional, if true, modules dependent on the
     one being unloaded will also be unloaded. the normal behavior is to
     refuse to unload if dependent modules are loaded.

     * $unload_parent - optional, if true and the module being unloaded is
     a submodule, its parent will also be unloaded. the normal behavior is
     to refuse to unload if the requested module is a submodule.

   Returns

   Name of the unloaded module on success, otherwise false.

$api->reload_module($mod)

   Reloads a module.

   This is preferred over calling ->unload_module() and ->load_module()
   for a few reasons:

     * Some modules that do not allow permanent unloading may allow
     reloading.

     * Unchanged dependencies are not unloaded when reloading.

     * Some unchanged data can be retained during reload.

   Parameters

     * $mod - module object or name to reload.

   Returns

   True on success.

$api->reload_modules(@mods)

   Reloads one or more modules at once. See ->reload_module().

   Parameters

     * @mods - module objects or names to reload.

   Returns

   Number of modules reloaded successfully, false if all failed.

$api->get_module($mod_name)

   Fetches a loaded module object.

   Parameters

     * $mod_name - name of the module to find.

   Returns

   Module object on success, false otherwise.

$api->package_to_module($pkg)

   Fetches a loaded module object by the corresponding Perl package name.

   Parameters

     * $pkg - Perl package name to find.

   Returns

   Module object on success, false otherwise.

$api->module_loaded($mod_name)

   Returns true if the specified module is loaded.

   Parameters

     * $mod_name - name of the module to find.

   Returns

   True if the module is loaded.

$api->store($key, $value)

   Stores a piece of data associated with the API Engine.

   Parameters

     * $key - name for fetching data later.

     * $value - value to store.

$api->retrieve($key)

   Retrieves a piece of data associated with the API Engine.

   Parameters

     * $key - name associated with data to fetch.

   Returns

   Fetched data, undef if not found.

$api->list_store_add($key, $value)

   Adds an entry to a list of data associated with the API Engine.

     * $key - name for fetching data later.

     * $value - value to add.

$api->list_store_items($key)

   Fetches all values in a list associated with the API Engine.

     * $key - name of the list to retrieve.

   Returns

   List of fetch values, or empty list if none were found.

$api->add_feature($feature)

   Enables a feature.

   Features are just a simple way for modules to determine whether a
   feature is provided by another module. For instance, if multiple
   modules provide different database backends, each of these could enable
   the database feature. Modules requiring a database would check for the
   feature enabled without having to know which module provides it.

   Parameters

     * $feature - name of the feature to enable.

$api->remove_feature($feature)

   Disables a feature.

   See ->add_feature for an explanation of features.

   Parameters

     * $feature - name of the feature to disable.

$api->has_feature($feature)

   Returns true if the specified feature is enabled.

   See ->add_feature for an explanation of features.

   Parameters

     * $feature - name of the feature to find.

   Returns

   True if the requested feature is enabled.

$api->Log($msg)

   Used for logging associated with the API Engine. Use module ->Log() for
   messages associated with a specific module.

   Parameters

     * $msg - text to log.

$api->Debug($msg)

   Used for debug logging associated with the API Engine. Use module
   ->Debug() for messages associated with a specific module.

   Parameters

     * $msg - text to log.

AUTHOR

   Mitchell Cooper <https://github.com/cooper> <[email protected]>

   Copyright � 2017. Released under New BSD license.

   Comments, complaints, and recommendations are accepted. Bugs may be
   reported on GitHub
   <https://github.com/cooper/evented-api-engine/issues>.