pubkey / rxdb

A fast, local first, reactive Database for JavaScript Applications https://rxdb.info/
https://rxdb.info/
Apache License 2.0
21.36k stars 1.04k forks source link

RxDocument to offer a proxy object? #19

Closed jimthedev closed 7 years ago

jimthedev commented 7 years ago

Hi there. Great job on this project.

One thing that might be helpful:

Right now you need to called person.get('name') to get the name property off of a person RxDocument. Is there a way to have RxDocument be a proxy object so that we could call person.name instead?

Currently I am doing this with:

// Proxy simple properties get calls to an rxdocument's get method
const p = function(proxyObj) {
  return new Proxy({}, {
    get: (target, name) => {
      return proxyObj.get(name);
    },
  });
};

// Example:
const person = p(rxPerson);
console.log(person.name);

My use case is pretty much getting a lot of properties off of a single model so I don't know how well this scales.

pubkey commented 7 years ago

Hi @jimthedev I have thought about using the proxy-object for several times the last month. I know that the usecase you describe is exactly what the proxy-object is here for.

I will try to figure out how to implement it the best way after the holidays.

In your example, how do you handle nested sub-objects like person.hair.color and how to use the observables like person.hair.color.$ or person.hair.color$ ?

marshall007 commented 7 years ago

@pubkey you might want to consider wrapping RxDocument in an observable wrapper like lell to avoid any specialized getter/setter or "get as observable" functions all together. Then you can just treat RxDocument as a plain ol' assignable object.

pubkey commented 7 years ago

@marshall007 lell looks nice.

I will make the proxy-feature after I finished the one I'm currently making (middleware-hooks).

Or is there someone willing to create a PR for this?

pubkey commented 7 years ago

@jimthedev Finished. RxDocument is now a proxy-object so you can directly set and get values and also observables of values.

CHANGELOG DOCS

get:

var name = myDocument.name;
var nestedValue = myDocument.whatever.nestedfield;

set:

myDocument.firstName = 'foobar';
myDocument.whatever.nestedfield = 'foobar2';

await myDocument.save();

get observable:

myDocument.firstName$
  .subscribe(newName => {
    console.log(newName)
  });

// nested
myDocument.whatever.nestedfield$
  .subscribe(newValue => {
    console.log(newValue)
  });

Check it out.

marshall007 commented 7 years ago

@pubkey really slick. Nice work!

ssured commented 7 years ago

It's a cool feature, but can this be made an opt-in? Afaik Proxy is not available on Edge, IE and Safari. Maybe because I dont know the objectives of this lib, but not supporting all 4 evergreen browsers makes rxdb unusable for me... Very cool project though

pubkey commented 7 years ago

@ssured Before I implemented it, I checked caniuse-proxy which tells me that I can use it on all relevant browsers (including edge).

But since it's not supported by IE, you are right, I should provide an opt-out of the proxy-feature which is easy to implement. I will finish the key-compression and than do that (max 2 weeks). Or maybe you want to send a PR for that?

ssured commented 7 years ago

This table has some more detailed info on all browsers and ES6 features: http://kangax.github.io/compat-table/es6/#test-Proxy

pubkey commented 7 years ago

Hi @ssured . I now refactored and found out that we don't need the proxy-object. Because of the strict schema-enforcement, we can use defineGetter/Setter which is supported by IE11. See this commit.

ssured commented 7 years ago

Smart thinking! Cool stuff!