{"id":"cosinewaves/loader","name":"loader","scope":"cosinewaves","platform":"roblox","description":"A lightweight, lifecycle-aware module loader for Roblox.","version":"1.2.4","latest":"1.2.4","versions":["1.2.1","1.2.2","1.2.3","1.2.4"],"license":"MIT","licenseRating":"safe","licenseCaveats":["The package archive does not include its license text; the license is declared in its manifest metadata."],"licenseVerified":false,"dependencies":{},"integrity":"e8bb1156bc1b6b07087c946dcd9139eb44c1621abd921c2887dd4442d7f20dd6","likes":0,"downloads":0,"install":"forest install cosinewaves/loader","url":"https://forest.dev/p/roblox/cosinewaves/loader","files":"https://api.forest.dev/ai/package/roblox/cosinewaves/loader/files","readme":"# ⚙️ Loader\n\nA lightweight, lifecycle-aware module loader for Roblox. This utility ensures a consistent `init → start` boot process across your game’s services and modules. Designed for modular architecture, dependency safety, and async initialization.\n\n> ⚠️ This is a **Promise-based** module loader. You should be familiar with [Promise](https://eryn.io/roblox-lua-promise/) usage in Roblox to use it effectively.\n\n---\n\n## 🚀 Key Features\n\n- 🔁 **Consistent Lifecycle**: Each module can optionally export `init()` and `start()` for structured loading.\n- ⏳ **Async Safety**: Modules are `required` safely, and `start()` is deferred until `init()` of all modules is complete.\n- 🧩 **Dependency Coordination**: Use `waitFor(\"ModuleName\")` to safely depend on another module’s completion.\n- 📦 **Batch Loading**: Load all children or descendant `ModuleScripts` from a container.\n\n---\n\n## 📦 Installation\n\nDrop the module into your project and `require()` it once during bootstrap.\n\n```lua\nlocal Loader = require(path.to.loader)\n```\n\n⸻\n\n## 📜 Module Lifecycle Order\n\nEach module can export the following optional functions and you can include your own:\n\n```lua\ninit(): () -> ()\n-- Called immediately after require().\n-- Use it to set up values, caches, or internal state.\n-- All init() methods are called before any start().\n```\n\n```lua\nstart(): () -> ()\n-- Called after all modules’ init() have run.\n-- Use this to begin logic, connect systems, or run loops.\n-- Automatically runs asynchronously.\n```\n\n```lua\nwaitFor(name: string): Promise<any>\n-- Provided automatically in each module’s returned table.\n-- Lets you await other modules’ startup before proceeding.\n```\n\n⸻\n\n🧩 Public API\n\n```lua\nloader.load_children(container: Instance, predicate?: (Instance) -> boolean): Promise<boolean>\n-- Loads all ModuleScripts that are direct children of the container.\n-- If a predicate is provided, only ModuleScripts where predicate(module) == true will be loaded.\n-- ✅ Optional predicate to filter modules.\n-- ✅ Returns a Promise that resolves after all modules are started.\n```\n\n```lua\nLoader:load_children(game.ReplicatedStorage.Modules)\n```\n\n⸻\n\n```lua\nloader.load_descendants(container: Instance, predicate?: (Instance) -> boolean): Promise<boolean>\n-- Loads all ModuleScripts found recursively in the container’s descendants.\n-- If a predicate is provided, only ModuleScripts where predicate(module) == true will be loaded.\n```\n\n```lua\nLoader:load_descendants(game.ServerScriptService.Services)\n```\n\n⸻\n\n🔍 Predicate Examples\n\nHere are some example predicates you can pass into `load_children` or `load_descendants` to control which modules are loaded:\n\n```lua\n-- Load only modules whose name ends with \"Service\"\nlocal function endsWithService(module)\n    return module.Name:match(\"Service$\") ~= nil\nend\n\nLoader:load_descendants(script.Modules, endsWithService)\n```\n\n```lua\n-- Load only modules that have a specific tag\nlocal CollectionService = game:GetService(\"CollectionService\")\n\nlocal function isTagged(module)\n    return CollectionService:HasTag(module, \"LoadMe\")\nend\n\nLoader:load_descendants(script.Modules, isTagged)\n```\n\n```lua\n-- Load only modules in a specific namespace\nlocal function isCoreModule(module)\n    return module.Name:sub(1, 5) == \"Core_\"\nend\n\nLoader:load_children(script.Modules, isCoreModule)\n```\n","readmeBorrowedFrom":{"version":"1.2.1","source":"wally"},"readmeTruncated":false}