Proxy, detect changes in vanilla tables


Nope, this has nothing to do with external apis


Ever heard of proxies? Well, this one is a little bit different. Proxy’s purpose is not working as a layer of communication between two machines but instead, working as an intermediary between the Server/Client and a table.

Ever tried to detect changes in a Roblox vanilla table? Well, I tried and found out that it wasn’t possible by default because there are no functions nor metamethods to do so. After a while searching I finally found out that the only way to detect direct changes and indexes of a table was by using a proxy table.

This is done by detecting indexes or new indexes inside the main table and passing or returning the values from the proxy table so the main one always remains empty and always notices changes.

So that’s it, you can make your own proxy table, it’s pretty simple, or just use this one which has some extra things.

local ProxyClass = require(Source.Proxy)
local Proxy = ProxyClass.new()

Proxy:OnIndex(function(Key: string, Value: any)) -- Will not fire when the key changes but when it is indexed (ex.: print)
    print("Indexed ->", Key, Value)
end)

local Disconnect = Proxy:OnChange(function(Key: string, Value: any, OldValue: any)
    print("Changed ->", Key, Value, OldValue)
end)

Proxy.Test = 10 -- Output: Changed -> Test 10 nil

print(Proxy.Test) -- 1st Output: 10
                  -- 2nd Output: Indexed -> Test 10
                  
print(ProxyClass.IsProxy(Proxy)) -- Output: true

Disconnect() -- The connection gets disconnected by just calling it, magic! Inspired by Fusion by Elttob

Proxy.Test = 50 -- Nothing prints out

Proxy provides a familiar and user-friendly API to connect listeners, add custom properties and more, but remember that the only needed code to make a proxy table are the two metamethods and a constructor which returns the metatable.

Basically, if you’re looking for a more specific or lightweight implementation of proxy only minimum functionality, you can always fork the code and remove all the methods you’re not interested in.


Installing Proxy


Wally

Proxy is avaible as a wally package! Just go ahead and add it to your wally.toml as a dependency

[dependencies]
Proxy = "flamenco687/roblox-proxy@3.1.1"

Github releases

Download the latest release

Roblox

By the time being, Proxy still has no roblox model to get from the library but it’ll soon be avaible.


Avaible in GitHub


If you want to get a more in-depth look at Proxy, contribute, report an issue or download source code of the project to make your own forks, go ahead and check out the github repository.


Documentation

moonwave


All needed documentation was generated with Moonwave and is found here Proxy. Documentation may not always be completely up to date due to errors building moonwave pages.

(Documents are still work in progress, but the API and the examples should be enough to understand Proxy)

6 Likes

So it’s a table wrapper? I’m not sure I get it. I currently use ReplicaService for replication and state change detection. What’s the benefit of using this?

You might want to watch out, I came into this expecting the usage of newproxy/roblox userdatas, Though the real reason why I posted this was to ask you if you wanted to try and create a Shadow Table in roblox. (I believe that’s the correct terminology. )
Essentially overcomplicated metastable manipulation & control. But I could find it being equally as useful as this proxy/table wrapper. ^.^

Where you recieve events for each index, i’ll list an example below.

local ShadowTable = require(...)({ 1, 2, 4 })

ShadowTable.Abc = "Abc, 123"
ShadowTable.Abc.Changed:Connect(function(...)
    return print(...) --> "Abc, 123", "Abc, 1234!
end)
ShadowTable.Abc = "Abc, 1234!"
1 Like

No benefit, proxy is not exactly meant for replication, it serves the basic and only purpose of detecting table indexing or changes at a local level, you can then use provided functions to replicate data with proxy or other things but there’s no intention of providing benefits over other things.

As stated in github, proxy is just one of my personal resources (which I use in my other packages) but open-sourced. However I’m still open to suggestions, @AsynchronousMatrix idea seems really interesting and keeps that vanilla feel I’m looking for with Proxy.

I will open a test-branch with pleasure to see how can I implement that. I already looked into proxies a while ago and they seem useful but somehow harder to understand at first glance.

And to clarify, the name of the library doesn’t come (for now) from the use of roblox proxies but from the purpose that the library itself serves.


QUICK UPDATE: After some quick testing I can verify that a newproxy() implementation is possible but has no sense at all since it’s pretty much a same result as using tables but with restricted capabilities due to the nature of custom userdatas. The way of connecting listeners to table changes will also stay the same since the actual one seems much more simple (or at least makes code cleaner) and serves a more general purpose while also giving the ability to listen to specific keys.

4 Likes