Nexus
Nexus is a module loading provider framework forked from Roam that is inspired by Sleitnick's Axis framework.) This module loader is barebones with the exception of extensions. There is no built-in networking layer or built-in state management. Nexus is designed to be a simple, yet powerful module loader that allows developers to easily load and manage modules in their game with the ability to add extensions for additional functionality.
Nexus collects load-elligable modules (modules that pass the predicate if one is supplied) and initializes them "syncronously" in the order they were collected in - the order is determined "randomly" or by the table of paths provided by the developer. Once all modules are initialized, Nexus then "starts" the modules "asyncronously" by spawning the "Start" method in a new thread.
NOTES
- Nexus does not need to be required in each module.
- All modules are guaranteed safe to access in the "Start" method.
- All modules are guaranteed to be initialized before the "Start" method is spawned.
- Providers do not have to have either the "Init" or "Start" method.
- Providers are guaranteed to be initialized in the expected order VIA the custom load order or topological sorting where dependencies are actually respected.
- The name "Provider", "Service", or "Controller" is not required, you decide what convention to follow when naming your modules.
- Extensions are optional and are used to extend the functionality of modules under-the-hood. They are there to save time writing common boilerplate code.
EXAMPLE USAGE
local MyProvider = {
Config = {
Name = "MyProvider", -- Optional, name is auto-generated.
Dependencies = {
[MyOtherProvider] = true,
},
},
}
function MyProvider:Add(x: number, y: number): number
return x + y
end
function MyProvider:Init()
print("MyProvider initialized!")
-- This is 100% safe to do:
print("OtherProvider runtime data:", MyOtherProvider:SomeMethod())
end
function MyProvider:Start()
print("MyProvider started!")
print(MyProvider:Add(1, 2))
end
return MyProvider
Types
StartConfig
interface
StartConfig {
PostInitPreStartCallback:
(
(
)
→
Promise
)
?
--
A callback that is called after all modules have been
Debug:
boolean?
--
Whether to log debug information.
}
and loaded in the order they are provided. loaded in the order they are provided. initialized and before they are started.
Provider
interface
Provider {
Init:
(
self:
Provider
)
→
(
)
?
--
The method that is spawned syncronously when the provider is initialized.
Start:
(
self:
Provider
)
→
(
)
?
--
The method that is spawned asyncronously when the provider is started.
}
Extension
interface
Extension {
}
Extensions allow developers to extend the functionality of modules under-the-hood. This is useful for adding additional functionality to modules without modifying the provider itself. Developers can save time writing common boilerplate code by using extensions, however, extensions do add a layer of abstraction. The use of extensions is optional and not required.
Functions
Predicates.MatchesName
Nexus.
Predicates.MatchesName
(
name:
string
--
The name to match.
) →
(
moduleScript:
ModuleScript
)
→
boolean
Returns a predicate that matches a module script's name.
Predicates.IsService
Returns the matching result of a module script's name ending with "Service".
Predicates.IsController
Returns the matching result of a module script's name ending with "Controller".
Predicates.IsProvider
Returns the matching result of a module script's name ending with "Provider".
Predicates.IsComponent
Returns the matching conditions of a module script being a component. This checks if the type is a table, if it has a metatable, and if the __tostring cotains "Component" in the beginning of the string.
Compatibility
This predicate is only compatible with component libraries that mimic Sleitnick's Component library! If you are using a different component library, that doesn't happen to follow the same structure, you will need to write your own predicate.
GetProvider
Returns a provider by name. Will error if the provider doesn't exist.
Safety
Providers are only safe to access after Nexus has started! If you try to access a provider before Nexus has started, you could encounter unexpected behavior.
local MyProvider = Nexus.GetProvider("MyModule")
-- Safe ONLY after Nexus has started.
MyModule:SomeMethod()
GetNameFromProvider
Returns the name of a provider.
local MyProvider = Nexus.GetProvider("MyModule")
print(Nexus.GetNameFromProvider(MyModule)) -- "MyModule"
RegisterExtensionsIn
Nexus.
RegisterExtensionsIn
(
deepSearch:
boolean?
--
Whether to search recursively within module scripts.
) →
(
)
Recursively registers extensions in the provided directories.
to search for modules.
Nexus.RegisterExtensionsIn(ServerScriptService.Extensions, Nexus.Predicates.IsExtension)
RegisterExtension
Registers an extension to be loaded by Nexus. This method should be called before Nexus.Start is called.
RegisterProvidersIn
Nexus.
RegisterProvidersIn
(
deepSearch:
boolean?
--
Whether to search recursively within module scripts.
) →
(
)
Recursively registers modules in the provided directories.
to search for modules.
Nexus.RegisterProvidersIn(ServerScriptService.Services, Nexus.Predicates.IsService)
Nexus.RegisterProvidersIn(ReplicatedStorage.Client.Controllers, Nexus.Predicates.IsController)
RegisterProvider
Registers a provider to be loaded by Nexus. This method should be called before Nexus.Start is called.
Start
Nexus.
Start
(
) →
Promise
--
A promise that is resolved once Nexus has fully started.
Starts Nexus by initializing and starting all registered modules.
Call Once
Can only be called once. Calling more than once will throw an error. You cannot register modules after Nexus has started.
Nexus.Start({
ExtensionsToLoad = {
ReplicatedStorage.Shared.Extensions.PlayerLifecycles,
},
ProvidersToLoad = {
ReplicatedStorage.Shared.Providers.MySharedProvider,
ServerScriptService.Server.Providers.MyServerProvider,
},
PostInitPreStartCallback = function()
print("All modules have been initialized, about to start them!")
end,
Debug = true, -- Same as doing Nexus.Debug = true
}):andThen(function()
print("Nexus has fully started!")
end):catch(warn)
PromiseOnStarted
Nexus.
PromiseOnStarted
(
) →
Promise
Returns a promise that is resolved once Nexus has fully started. This is useful for any code that
needs to tie into Nexus modules but is not the script that called Start
.
Nexus.PromiseOnStarted():andThen(function()
local MyProvider = Nexus.GetProvider("MyModule")
MyModule:SomeMethod()
end):catch(warn)