Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Engine] expose a way for 3rd party libraries to produce read only proxy objects #153

Closed
caridy opened this issue Mar 14, 2018 · 6 comments

Comments

@caridy
Copy link
Contributor

caridy commented Mar 14, 2018

Description

LDS, and other libraries that produce objects might want to produce values that can be used as properties. Additionally, they want to tap into the internal mechanism of the reactive engine to produce reactive objects that can trigger rehydration.

Initially, we want to try this model with LDS, and for what, we we exposing a high-privilege (not-documented) api to LDS can import it.

@jbenallen
Copy link

Is the goal here to allow a library (LDS in this case) to emit an object to a wired property that is internally reactive such that one of its properties may be mutated later by the library without replacing the whole thing from the wire and that that internal mutation will be observed by the engine?

@caridy
Copy link
Contributor Author

caridy commented Mar 15, 2018

After thinking more about this, I think @jbenallen has a good point here. Today, it is impossible for libraries to trigger rehydration, because they don't have a way to produce reactive/tracked objects. More thoughts:

  1. you can get a reactive proxy of any object via track() decorator today (libraries can attempt to do something funky to produce trackable objects (yes, it is a hack, but it is possible).

  2. today, we don't prevent the extraction of a writable version of a read only attribute. they can hack it by assigning the field decorated with @api into a field decorated with @track, and they effectively escape the restriction. We should close this loop asap, and throw an error in this case.

  3. You should be able to get a read only proxy of any object (no exceptions) to protect yourself when sending data like that to non-trusted parties.

  4. I think a method called readonly() makes sense to be part of the library, to match the expectation of @track, and in the future, we can make readonly a decorator, and @track to also function as a regular method to have some symmetry there.

@davidturissini
Copy link
Contributor

davidturissini commented Mar 15, 2018

My only question about readonly as a decorator, is what happens in this scenario?

import { Element, readonly } from 'engine';

export default class MyComponent extends Element {
  @readonly
  foo = { bar: true }
 
  connectedCallback() {
    this.foo.bar = false; // Error or allowed?
  }
}

It seems we should throw, because that object is readonly, but you also own that object so this restriction may be strange

@caridy
Copy link
Contributor Author

caridy commented Mar 15, 2018

@davidturissini good question. It will throw because it is a readonly. Also, this.foo = {something: 'new'} should also throw, the decorator makes impossible to change that field after initialization.

caridy added a commit that referenced this issue Mar 15, 2018
…obj (#154)

* feat(engine): issue #153 introducing track() and readonly() methods
@caridy
Copy link
Contributor Author

caridy commented Mar 30, 2018

keep in this open until we add the decorator and the docs.

@jmsjtu
Copy link
Member

jmsjtu commented May 7, 2024

We reviewed this as a team and the readonly decorator as described in this issue can be achieved with a combination of signals + Object.freeze.

Closing this issue out.

@jmsjtu jmsjtu closed this as completed May 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants