{"id":"griffin-dalby/sawdust","name":"sawdust","scope":"griffin-dalby","platform":"roblox","description":"Mirrored from the Wally registry.","version":"1.6.0","latest":"1.6.0","versions":["1.1.0","1.2.0","1.2.1","1.2.2","1.2.3","1.2.5","1.3.0","1.4.0","1.4.1","1.4.2","1.4.4","1.4.5","1.5.0","1.5.1","1.6.0"],"license":"Apache-2.0","licenseRating":"safe","licenseCaveats":["Modified files must carry a notice of changes. If the package ships a NOTICE file, its attributions must be preserved."],"licenseVerified":true,"dependencies":{"roblox/testez":{"version":"^0.4.1","alias":"testez"}},"integrity":"6d8bc1d7ed90cbcca61efc0180f603e19fecf52c0abca9fce834cffd6f3f2533","likes":0,"downloads":0,"install":"forest install griffin-dalby/sawdust","url":"https://forest.dev/p/roblox/griffin-dalby/sawdust","files":"https://api.forest.dev/ai/package/roblox/griffin-dalby/sawdust/files","readme":"# 🌲 Sawdust Framework\r\n![Made for Roblox](https://img.shields.io/badge/Made%20for-Roblox-red?logo=roblox)\r\n![LuaU](https://img.shields.io/badge/Powered%20by-LuaU-yellow)\r\n![Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue)\r\n\r\nSawdust is a lightweight, modular framework for Roblox developers who want clarity, control, and smart abstractions, without the bloat 😉\r\n\r\n> 💖 Built with love by **Griffin Dalby**<br>\r\n> 🛠 Designed for efficient, easy-to-read, and easy-to-use code - made for devs who hate reading docs.\r\n\r\n---\r\n\r\n## ✨ Features\r\n\r\n- 💉 **Service Injection System**<br>\r\n  Build, inject, and manage services with dependency resolution.\r\n\r\n- 🔗 **Smart Networking**<br>\r\n  Networking w/ a custom protocol for secure returns from each side, all with a friendly interface.\r\n\r\n- 📦 **CDN System**<br>\r\n  Efficient asset delivery with preload batching and efficient caching.\r\n\r\n- 📣 **Signal Emitters**<br>\r\n  Embeddable event behavior for services or general-purpose modules.\r\n\r\n- 📜 **Cache API**<br>\r\n  Stackable cache management built for structure, and speed.\r\n\r\n- 🧹 **Maid Utility**<br>\r\n  Clean up anything, connections, callbacks, instances, all with tag-based logic.\r\n\r\n- ✈ **And much, much more planned**<br>\r\n  I hope to get as much quality of life features as possible.\r\n\r\n- 🌳 **Lignin**<br>\r\n  Lignin is a plugin being developed to aid even further with sawdust development.\r\n  You'll be able to gradually create networking channels and events/functions, and many more things\r\n  All of these will create automatic type metadata for a dynamic feeling typechecking experience including assetIds and networking event names.\r\n\r\n---\r\n\r\n## 🚀 Quick Start\r\n\r\n### Network from server <-> client\r\n```lua\r\n--> In StarterCharacterScripts.Mechanics\r\n\r\nlocal networking = sawdust.core.networking\r\nlocal mechanics = networking.getChannel('mechanics')\r\n\r\nmechanics.skill:useMiddleware('after', 1, function(pipeline)\r\n    --> I'll fill this all out soon I just want to push this for the rodev game jam tmr I love this module\r\nend)\r\n\r\nmechanics.skill:with() --> Returns a new call\r\n    :intent('use')\r\n    :data('fireball', mousePosition)\r\n    :timeout(4)\r\n    :invoke() --> Returns a promise\r\n        :finally(function(req)\r\n            local intent, data = req.intent, req.data\r\n            local didUse = (data[1]==true)\r\n\r\n\r\n        end)\r\n        :catch(function(issue)\r\n            warn('Issue with skill: fireball')\r\n            warn(issue)\r\n        end)\r\n\r\n```\r\n\r\n```lua\r\n--> In ServerScriptService.Mechanics\r\n\r\nlocal networking = sawdust.core.networking\r\nlocal mechanics = networking.getChannel('mechanics')\r\n\r\nmechanics.skill:handle(function(req, res)\r\n    local intent, data = req.intent, req.data\r\n\r\n    res.intent('success')\r\n    res.data('Whatever you\\'d need')\r\n    res.send() --> Send the data back\r\nend)\r\n```\r\n\r\n### Build a Service\r\n```lua\r\n--> In ServerScriptService.SawdustServices\r\n\r\nlocal builder = sawdust.builder\r\nlocal services = sawdust.services\r\n\r\nservices:register(builder.new('OtherService')\r\n    :init(function(self, deps) --> 'init' runtime phase\r\n        self.data = 'Hello!' --> Set OtherService.data to 'Hello!'\r\n    end)\r\n    :method('methodName', function(msg) --> Create a new method (OtherService.methodName(msg))\r\n        print(`Method was called, message: \"{msg}\"`)\r\n    end)\r\n    :inject('init', function(self, deps) --> Inject function into 'init' runtime phase\r\n        print('Injection into OtherService success!')\r\n    end))\r\n\r\nservices:register(builder.new('ExampleService')\r\n    :dependsOn('OtherService') --> Depend on the OtherService\r\n    :init(function(self, deps) --> :init() phase\r\n        self.otherService = deps.OtherService\r\n    end)\r\n    :start(function(self) --> :start() phase\r\n        print(`Data from other service: \"{self.otherService.data}\"`)\r\n        self.otherService.methodName('I called the function from ExampleService!')\r\n    end))\r\n\r\nservices:resolveAll() --> :init() all services\r\nservices:startAll() --> :start() all services\r\n\r\n--[[\r\n\r\n    This should print this, in order:\r\n    'Injection into OtherService success!'\r\n    'Data from other service: \"Hello!\"'\r\n    'Method was called, message: \"I called the function from ExampleService!\"'\r\n\r\n--]]\r\n```\r\n\r\n---\r\n\r\n## 🧠 Philosophy\r\n\r\nSawdust is designed to:\r\n- Give **maximum control** to the developer\r\n- Encourage **clean runtime logic**\r\n- Reduce **boilerplate**\r\n- Promote **discoverabiliy** via tooling & naming clarity\r\n- Minimize documentation checks\r\n\r\nYou get **injection + dependency** management without losing Luau's flexibility.\r\n\r\n---\r\n\r\n## 🚚 Installation\r\n\r\n1. Drop the Sawdust folder into `ReplicatedStorage`\r\n2. Access it on server or client via:\r\n```lua\r\nlocal sawdust = require(game:GetService('ReplicatedStorage').Sawdust)\r\n```\r\n3. Access the implementations like:\r\n```lua\r\nlocal sawdust = require(game:GetService('ReplicatedStorage').Sawdust)\r\n\r\nlocal services = sawdust.services\r\nlocal networking = sawdust.core.networking\r\nlocal maid = sawdust.util.maid\r\n```\r\n\r\n---\r\n\r\n## 🧪 Tests\r\nI've built unit tests for sawdust and all of the implementations *(this may not be ALL implementations at time of reading, I may still be working on some.)*\r\n\r\n## 📖 Documentation\r\nYou can find full documentation & quick start examples + implementation tutorials [Here!](https://griffin-dalby.github.io/Sawdust/)\r\n\r\n---\r\n\r\n## 📚 Modules\r\n\r\n#### Services\r\n| Module | Description |\r\n| ------ | ----------- |\r\n| ```builder``` | Service definition w/ injections & dependencies |\r\n| ```services``` | Service resolver, runner, and state tracker |\r\n\r\n#### Core\r\n| Module | Description |\r\n| ------ | ----------- |\r\n| ```networking``` | Networking system modeled after NodeJS' Express |\r\n| ```promise``` | Promise system modeled after NodeJS |\r\n| ```signal``` | Simple event emitter system |\r\n| ```cache``` | Fast, structured memory management |\r\n| ```cdn``` | Asset delivery w/ preload features |\r\n\r\n#### Util\r\n| Module | Description |\r\n| ------ | ----------- |\r\n| ```maid``` | Cleanup utility for tagged objects |\r\n| ```debounce``` | Timed and interactable debounces |\r\n| ```enum_map``` | \"Maps\" enums to human readable, and back. |\r\n| ```states```| Simple dynamic state management |\r\n| ```timer```| Heartbeat wrapper w/ decay and start/stop control |\r\n| ```uuid``` | Customizable UUID generator |\r\n\r\n---\r\n\r\n## 📜 License\r\nSawdust is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0).<br>\r\nContributions are welcome! While not required by the license, if you would like to improve Sawdust or find bugs, please consider contributing or filing a issue report, it means a lot more than you think <3\r\n","readmeBorrowedFrom":{"version":"1.4.0","source":"wally"},"readmeTruncated":false}