# JSONRegistry - Allows branded instances in regular JSON

**URL:** <https://es.discourse.group/t/jsonregistry-allows-branded-instances-in-regular-json/2569>\
**Category:** 💡 Ideas\
**Tags:** proposal\
**Created:** [May 18, 2026, 10:57am UTC](https://es.discourse.group/t/jsonregistry-allows-branded-instances-in-regular-json/2569 "2026-05-18T10:57:38Z")\
**Posts on this page:** 1\
**Showing post:** 45

<div class="post-metadata">

**Author:** ![WebReflection](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/webreflection/32/248_2.png) [@WebReflection](https://es.discourse.group/u/WebReflection)\
**Post date:** [June 4, 2026, 11:14am UTC](https://es.discourse.group/t/jsonregistry-allows-branded-instances-in-regular-json/2569/45 "2026-06-04T11:14:20Z")

</div>

I took the time to investigate inside-out the issue ... basically the example proposed is that `new Foo` has a `new Bar` that is lazily initialized with that `new Foo` "container" ... this serializes fine (`new Foo` is recursive via Foo-\>Bar-\>Circular) but unserialize breaks because Foo needs Bar to unserialize, but Bar needs Foo to be constructed.

The gotcha is evil on purpose because you cannot recreate that `new Foo` directly, you need to create `new Bar` a part and _then_ call `initBar` on `foo` but you want the result to be one shot:

- 3 operations to create the problematic `foo` but ...
- 2 operations to restore one shot?

Your `fooFromClonePayload` wants to recreate itself as if `bar` was possible as constructor but it's kinda obvious that cannot possibly work, the constructor design is broken in there ... here a better example:

```javascript
class Foo {
  #bar;

  get bar() {
    return this.#bar;
  }

  initBar(bar) {
    if (this.#bar !== undefined) throw Error();
    this.#bar = bar;
  }

  static isFoo(foo) {
    return #bar in foo;
  }

  static asClonePayload(foo) {
    return { bar: foo.#bar.foo === foo ? null : foo.#bar };
  }

  static fromClonePayload(data) {
    const foo = new Foo();
    foo.initBar(data.bar ?? new Bar(foo));
    return foo;
  }
}

class Bar {
  #foo;

  constructor(foo) {
    this.#foo = foo;
  }

  get foo() {
    return this.#foo;
  }

  static isBar(bar) {
    return #foo in bar;
  }

  static asClonePayload(bar) {
    return { foo: bar.#foo };
  }

  static fromClonePayload(data) {
    return new Bar(data.foo);
  }
}

```

I believe this is the correct implementation and it should work ... it does in _flatted-view_ I think it'd do even with my JSON registry proposal.

If the argument is "what should we do in such cases?" I think throwing is fine because these cases simply break the construction/destruction pattern and are kinda pointless to me as examples when the contract is clear: you provide a way to recreate an instance ... if that instance can be cyclic due lazy steps pollution of its fields you gotta deal with it ... would that work?

---

_[View the full topic](https://es.discourse.group/t/jsonregistry-allows-branded-instances-in-regular-json/2569)._
