{"id":"elentium/reactivetable","name":"reactivetable","scope":"elentium","platform":"roblox","description":"Mirrored from the Wally registry.","version":"0.1.1","latest":"0.1.1","versions":["0.1.0","0.1.1"],"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.","License identified from the packaged LICENSE file; the manifest declared none."],"licenseVerified":true,"dependencies":{},"integrity":"617d59ecf36b7d95314dd0206d52837db96652dac1aca43db80e1f7e740946c9","likes":0,"downloads":0,"install":"forest install elentium/reactivetable","url":"https://forest.dev/p/roblox/elentium/reactivetable","files":"https://api.forest.dev/ai/package/roblox/elentium/reactivetable/files","readme":"# ReactiveTable V1\n\n<p align=\"center\">\n  <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/License-Apache%202.0-blue?style=flat-square\" alt=\"License\" /></a>\n  <a href=\"https://wally.run/package/elentium/reactivetable\"><img src=\"https://img.shields.io/badge/📦_Wally-elentium%2Freactivetable-00b4ab?style=flat-square\" alt=\"Wally\" /></a>\n</p>\n\n<p align=\"center\">\n  <strong>DX-oriented observable table implementation for Luau</strong>\n</p>\n\nReactiveTable wraps normal Luau tables in a proxy that behaves like a table, but automatically broadcasts changes\nIt is designed to reduce the boilerplate of manual update calls while keeping the code ergonomic\n\n## Features\n- Table-like syntax via metatables (`t.key`, `t.key = value`, `for k, v in t do ... end`)\n- Signals for reactivity:\n  - `Changed` (fires on value updates)\n  - `New` (fires on key additions)\n  - `Removed` (fires on key removals)\n- Automatic wrapping of nested tables into ReactiveTable objects\n- 1-level ancestor notification (child writes bubble to direct parent only)\n- Freeze controls:\n  - freeze the table (rejects writes)\n  - freeze signals (suppresses signal emissions)\n- Utility methods: `Clone`, `Compare`, `Find`, `Sort`, `Insert`, `Remove`, `Clear`\n- Supports self-referential tables during construction (no stack overflow)\n\n## Installation\n### Using Wally\nAdd ReactiveTable to your `wally.toml`:\n```toml\n[dependencies]\nReactiveTable = \"elentium/reactivetable@0.1.1\"\n```\n\nThen run:\n```bash\nwally install\n```\n\n### Roblox Studio Direct Installation\n1. Install roblox/ReactiveTable.rbxm \n2. Insert it in your roblox studio project\n\n## Quick Start\n```luau\nlocal ReactiveTable = require(path.to.module) -- see Installation notes\n\nlocal reactive = ReactiveTable.new({ hello = \"world\" })\n\nprint(reactive.hello) -- \"world\"\n\nreactive:BindToKeyChanged(\"hello\", function(newValue: any)\n\tprint(`key \"hello\" changed, new value: {newValue}`)\nend)\n\nreactive.hello = \"goodbye\" -- triggers the callback\n\n-- listen for new keys\nreactive.New:Connect(function(newKey: any, newValue: any)\n\tprint(`New key added: {newKey}, value: {newValue}`)\nend)\n\nreactive.someNewKey = 123 -- triggers New\n```\n\n### Nested tables + ancestor bubbling (1-level)\n```luau\nlocal ReactiveTable = require(path.to.module)\n\nlocal reactive = ReactiveTable.new({ a = { b = 10 } })\n\nreactive.Changed:Connect(function(key: string, value: any)\n\tprint(`changed {key} -> {value}`)\nend)\n\n-- This fires `Changed` on the `a` table (and also on `reactive`)\nreactive.a.b = 11\n```\n\n## Signals\nReactiveTable exposes three signal objects:\n- `reactive.Changed:Connect(function(key, value) ... end)`\n- `reactive.New:Connect(function(key, value) ... end)`\n- `reactive.Removed:Connect(function(key) ... end)`\n\n`BindToKeyChanged(key, callback)` is a convenience wrapper for `Changed` that filters by a specific key.\n\nConnections returned by `:Connect(...)` support `:Disconnect()`.\n\n## API Reference\n### `ReactiveTable.new(tbl?) -> ReactiveTable<T>`\nCreates a ReactiveTable proxy.\n\n- `tbl?` is an optional source table (defaults to `{}`).\n- Nested tables inside `tbl` are automatically wrapped into ReactiveTable objects.\n- If the same raw table is wrapped more than once, the same userdata wrapper is reused (per process lifetime).\n\n### Introspection\n- `reactive:GetSource() -> { [any]: any }`\n- `reactive:GetSize() -> number`\n- `reactive:IsFrozen() -> boolean`\n- `reactive:AreSignalsFrozen() -> boolean`\n\n### Lifecycle\n- `reactive:Destroy()`\n  - Disconnects all signal listeners\n  - Removes internal registry entries\n\n### Change broadcasting\n- `reactive:BindToKeyChanged(key, callback) -> SignalConnection`\n  - `callback(newValue)`\n- `reactive:BroadcastChanges(changedKeys: { [any]: \"Added\" | \"Removed\" | \"Changed\" })`\n  - Manually emits signals for multiple keys (useful for batch updates)\n\n### Mutations\n- `reactive:Insert(value: any, index?: number) -> ()`\n  - Array-style insertion with `table.insert`\n  - Emits `New` and bubbles `Changed` to direct ancestors\n- `reactive:Remove(index?: number) -> any`\n  - Array-style removal with `table.remove`\n  - Emits `Removed` and bubbles `Changed` to direct ancestors\n- `reactive:Find(needle: any, init?: number) -> number?`\n  - Works with primitives and ReactiveTable userdata.\n- `reactive:Sort(comparator) -> ()`\n  - Sorts array contents via `table.sort`.\n- `reactive:Clear() -> ()`\n  - Clears an array-like ReactiveTable (sets numeric entries to nil)\n\n### Utility\n- `reactive:Clone(deepClone?: boolean) -> ReactiveTable<T>`\n  - `deepClone == true` deep-copies nested tables (and clones nested reactive children)\n  - `deepClone == nil/false` does a shallow copy: top-level is independent, nested tables are shared\n- `reactive:Compare(other: any) -> boolean`\n  - Deep-compares contents\n\n### Freeze controls\n- `reactive:Freeze() / reactive:Unfreeze()`\n  - Rejects write operations when frozen\n- `reactive:FreezeSignals() / reactive:UnfreezeSignals()`\n  - Suppresses signal emissions for that specific object\n\n## Notes / Limitations\n- Luau autocomplete for nested tables:\n- Autocomplete will show table contents, but will not show ReactiveTable API for nested objects unless you annotate types (see `src/init.luau` header docs).\n- Ancestor notifications are limited to 1-level for performance and simplicity.\n\n## Running Tests\nThe project includes a large test suite at `src/test/init.luau`.\nRequiring it in a Roblox environment runs correctness + performance checks and prints results/optionally creates a UI.\n\n## Contributing\nContributions are welcome. If you add features or fix edge cases, consider adding/adjusting tests in `src/test/init.luau`.\n\n## License\nApache License 2.0. See `LICENSE` for details.\n\n## Author\nIAMNOTULTRA3 (a.k.a. Elite, Elentium)\n\n## Credits\nSignal batching implementation based on `stravant` (Signal) and modified by IAMNOTULTRA3.","readmeTruncated":false}