This is an incredibly insightful debugging moment, and you have stumbled upon
a fascinating quirk of how your legacy C-style dialect is being transpiled
into modern JavaScript.
You are 100% correct: **No network traffic was sent.** Let's look at exactly
why the proxy was completely blind to your state changes, and how we can use a
brilliant syntax hack to fix it.
### The Diagnosis: The Closure Scope Trap
In `tests/mesh_test.c`, you declared the state variables at the top of the
file:
```c
int counter;
string last_user;
```
When your custom `codegen.js` processes these global variables, it creates a
private closure for the object blueprint and injects them as standard
JavaScript `let` variables:
```javascript
rt.blueprints["tests/mesh_test"] = function() {
let _this = {};
let counter = 0;
let last_user = "nobody";
// ...
```
The problem is your `10_mesh.js` module wraps the `Proxy` around `_this` (the
object instance itself). When you do `counter = counter + 1;`, you are
modifying a private, lexically-scoped variable hidden deep inside the function
closure. Because you aren't mutating a property *on the object itself* (e.g.,
`_this.counter = ...`), the Proxy's `set` trap never fires, the `__OUTBOX`
remains empty, and the DOM sweeper sends nothing to the DMZ Relay.
### The Solution: The Proxy Bracket Hack
We need to force the transpiler to mutate properties directly on `_this`.
Because your `codegen.js` translates LPC mapping brackets `obj["key"]` into JS
brackets `obj["key"]`, we can bypass the closure trap completely by treating
`this_object()` as a mapping! By writing `this_object()["counter"] = 1`, the
compiler translates it to `_this["counter"] = 1`, which acts as a physical
mutation on the object and instantly trips the Proxy traps.
Update your **`tests/mesh_test.c`** file to look exactly like this:
```c
/ tests/mesh_test.c
void create() {
// Force state onto the physical object properties
this_object()["counter"] = 0;
this_object()["last_user"] = "nobody";
// Intercept and sync any property matching "counter" or "last_user"
mesh_sync_object(this_object(), "sync_test_topic", "^(counter|last_user)$")
;
}
void increment(string user) {
this_object()["counter"] = this_object()["counter"] + 1;
this_object()["last_user"] = user;
printf("State bumped! Counter: %d, User: %s
", this_object()["counter"], this_object()["last_user"]);
}
void display() {
printf("Current Network State -> Counter: %d, Last User: %s
", this_object()["counter"], this_object()["last_user"]);
}
```
### The Execution Workflow
Because `CRDT_MUTATION` payloads are currently ephemeral (the DMZ Relay
broadcasts them live but doesn't archive them to disk like virtual files),
**Browser B must be online and listening when the event happens**.
Run `node build_web.js` to rebuild the AST, and then follow this exact
sequence:
1. **Open Browser A** and boot the object into RAM so the Proxy activates:
> `eval load_object("tests/mesh_test")`
2. **Open Browser B** and do the same:
> `eval load_object("tests/mesh_test")`
3. **In Browser A**, mutate the state:
> `eval load_object("tests/mesh_test")->increment("Browser_A")`
4. **In Browser B**, check the state:
> `eval load_object("tests/mesh_test")->display()`
When you run this, you will see the `CRDT_MUTATION` payload fly across your
terminal in `wscat`, and Browser B will output `Counter: 1, Last User:
Browser_A`!