{"id":"neonifieddev/subscription","name":"subscription","scope":"neonifieddev","platform":"roblox","description":"Path-based state subscriptions for Roblox, powered by neonifieddev/network.","version":"1.0.0","latest":"1.0.0","versions":["0.1.0","1.0.0"],"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":{"neonifieddev/network":{"version":"^1.0.1","alias":"Network"}},"integrity":"d1a9a29c3e52f56c800e497680630b8a19fffd8ae6792f922c3dece7b19e6692","likes":0,"downloads":0,"install":"forest install neonifieddev/subscription","url":"https://forest.dev/p/roblox/neonifieddev/subscription","files":"https://api.forest.dev/ai/package/roblox/neonifieddev/subscription/files","readme":"# Subscription\n\nPath-based state subscriptions for Roblox, powered by `neonifieddev/network`.\n\n## Install\n\n```toml\n[dependencies]\nNetwork = \"neonifieddev/network@1.0.0\"\nSubscription = \"neonifieddev/subscription@0.1.0\"\n```\n\n`Subscription` also declares `Network` in its own `wally.toml`, so consumers only need to add `Subscription` if they are not using `Network` directly elsewhere.\n\n## Server\n\n```lua\nlocal Players = game:GetService(\"Players\")\nlocal ReplicatedStorage = game:GetService(\"ReplicatedStorage\")\n\nlocal Subscription = require(ReplicatedStorage.Packages.Subscription)\n\nlocal subscriptions = {}\n\nPlayers.PlayerAdded:Connect(function(player)\n\tlocal data = {\n\t\tleaderstats = {\n\t\t\tCash = 100,\n\t\t\tGems = 5,\n\t\t},\n\t\tinventory = {},\n\t}\n\n\tlocal playerSubscription = Subscription.ForPlayer(player, \"Data\", data)\n\tsubscriptions[player] = playerSubscription\n\n\tplayerSubscription:Activate()\n\n\tplayerSubscription:Set(\"leaderstats.Cash\", 250)\n\tplayerSubscription:Add(\"leaderstats.Cash\", 50)\n\tplayerSubscription:TableInsert(\"inventory\", {\n\t\tid = \"Sword\",\n\t\tamount = 1,\n\t})\nend)\n\nPlayers.PlayerRemoving:Connect(function(player)\n\tlocal playerSubscription = subscriptions[player]\n\tif playerSubscription then\n\t\tplayerSubscription:Destroy()\n\t\tsubscriptions[player] = nil\n\tend\nend)\n```\n\n## Client\n\n```lua\nlocal ReplicatedStorage = game:GetService(\"ReplicatedStorage\")\n\nlocal Subscription = require(ReplicatedStorage.Packages.Subscription)\n\nlocal playerSubscription = Subscription.ForPlayer(\"Data\")\n\nplayerSubscription:OnReady(function(data)\n\tprint(\"initial cash\", data.leaderstats.Cash)\nend)\n\nplayerSubscription:OnChanged(function(newValue, oldValue, changedPath, op)\n\tprint(\"changed\", table.concat(changedPath, \".\"), op, oldValue, newValue)\nend)\n\nplayerSubscription:OnPathChanged(\"leaderstats.Cash\", function(newCash, oldCash, changedPath, op)\n\tprint(\"cash changed\", oldCash, \"->\", newCash, op)\nend, true)\n\nplayerSubscription:OnPathChanged({ \"inventory\" }, function(inventory, oldInventory, changedPath, op)\n\tprint(\"inventory changed\", op, #inventory)\nend)\n```\n\nThe server sends one initial snapshot on `:Activate()`, then sends only operations such as `set`, `insert`, `remove`, and `clear`. Direct table mutations do not replicate; use the subscription methods for changes that should reach clients.\n","readmeTruncated":false}