Giter VIP home page Giter VIP logo

Comments (12)

scottwrobinson avatar scottwrobinson commented on July 1, 2024

I should preface this by saying I'm not very familiar with TypeScript, so please forgive my ignorance.

I agree that its a bit weird defining the schema and then using the same properties for their values. I would love to use decorators, but they aren't supported in ES6 (as far as I know, at least). As of right now there is a method, schema(), that allows you to set the schema, but its not as clean as the current way :)

class Person extends Document {
    constructor() {
        super('persons');

        this.schema({
            birthday: Date,
            name: String,
            age: Number
        });
    }
}

I'm up for ideas if you have any. Thanks for your input!

from camo.

WorldMaker avatar WorldMaker commented on July 1, 2024

That schema method looks like a great start for what I'm looking for. I will try it when I get a chance.

I recommend you take a look at TypeScript when you get a chance. It's all the smart OO things of ES6 with some benefits of compile time static typing. As someone with a background in static typed languages, I think you might appreciate what TypeScript does.

Yeah, decorators are not ES6, but heavily planned for ES7. (Technically, ES6 is now referred to as ES2015 and Decorators are planned for ES2016...) The Angular team at Google seems very fervent that Decorators make it into ES2016. Almost all of the transpilers (Traceur, Babel, and TypeScript) support Decorators now, so it's a "future feature" of JS that's very easy to explore today.

Ultimately, ES2016 Decorators are very heavily influenced by Python Decorators if you've seen them, and are similar enough to C# Attributes and Java Annotations that you shouldn't be too shocked at how they are/will be used. The link in my first post is pretty informative.

from camo.

scottwrobinson avatar scottwrobinson commented on July 1, 2024

Thanks for the info! I'll definitely take a look at TypeScript.

I'm really looking forward to ES2016's decorators as I come from a Java and Python background :) I like where things are heading in JS.

Let me know if you run in to any problems using schema(). I haven't used/tested it as much as I should have. It was an early feature that I've kinda forgot about lately. I'd be happy to bolster it up a bit knowing its useful to people.

Closing this issue for now.

from camo.

scottwrobinson avatar scottwrobinson commented on July 1, 2024

FYI I found some issues with the schema() method, which are now fixed as of v0.5.7. It should work as expected now. Let me know if you have any problems.

from camo.

developit avatar developit commented on July 1, 2024

@scottwrobinson I know this issue is closed, I just came across the project and figured I'd drop a suggestion here: use class properties to define schema methods (and perhaps the collection name?) instead of putting them in the constructor:

class Person extends Document {
  collection = 'person';

  name = { type:String, required:true },
  birthday = Date;
  updated = { type:String, default:Date.now };
}

Ideally, though, since most NodeJS code is not being minified, it would be nice to automatically create a collection name based on the value of this.constructor.name.

Just some thoughts!

from camo.

WorldMaker avatar WorldMaker commented on July 1, 2024

@developit From my understanding class properties as you show are syntactic sugar in ES6 for the constructor syntax, or at least, that's how TypeScript transpiles them:

// Input
class Person extends Document {
  name = { type:String, required:true };
  constructor() {
    super('people');
  }
}

// Output (ie, functionally the same as)
class Person extends Document {
  constructor() {
    super('people');
    this.name = { type:String, required:true };
  }
}

So you should already be able to do that in whatever transpiler you are using if it already supports class properties.

That doesn't solve my issue in TypeScript because { type: any, required: boolean } is not the same type as string and thus once you've set the schema in the constructor you can't actually use that instance property.

Decorators help here because you could do something like:

import { Document } from 'camo';
import { collection, field, required } from 'camo/decorators';

@collection('people')
class Person extends Document {
  @field(String)
  @required
  name: string = '';
}

With experimental TypeScript Descriptor metadata a TypeScript-specific version of @field could even deduce that the field was a string without needing to pass it in by getting the type information from the compiler. The same reflection metadata could also probably be used to default the collection name, and doing that at TypeScript compile time would avoid minification issues at least. (Eventually minifiers will probably have to deal with Reflect.metadata, definitely if/when Decorators land...)

from camo.

scottwrobinson avatar scottwrobinson commented on July 1, 2024

@developit Thanks for the suggestion!

I'd like to get the declarations out of the constructor, but class properties aren't supported in ES6, which is the current focus of Camo. Ideally we'll be able to use decorators, like @WorldMaker suggested, when possible. If there is a way to support this on a transpiler, I'd be happy to add it (although I haven't had time to make myself familiar with any transpilers lately).

As for declaring the collection name, I plan to have it determine the name via this.constructor.name and have it use something like Pluralize to make it plural.

As always, ideas/suggestions are welcome.

from camo.

developit avatar developit commented on July 1, 2024

Using babel-node or Babel's require hook with the {stage:0} option in a
.babelrc would enable both decorator and class property support.

@developit https://github.com/developit Thanks for the suggestion!

I'd like to get the declarations out of the constructor, but class
properties aren't supported in ES6, which is the current focus of Camo.
Ideally we'll be able to use decorators, like @WorldMaker
https://github.com/WorldMaker suggested, when possible. If there is a
way to support this on a transpiler, I'd be happy to add it (although I
haven't had time to make myself familiar with any transpilers lately).

As for declaring the collection name, I plan to have it determine the name
via this.constructor.name and have it use something like Pluralize
https://github.com/blakeembrey/pluralize to make it plural.

As always, ideas/suggestions are welcome.


Reply to this email directly or view it on GitHub
#6 (comment).

from camo.

WorldMaker avatar WorldMaker commented on July 1, 2024

TypeScript also transpiles both features today. I like the extra type-checking Typescript provides and do recommend it as an option.

from camo.

scottwrobinson avatar scottwrobinson commented on July 1, 2024

How do you envision this working? Camo's main focus is on Node/io.js, so we'd probably have to fork the project to add this. As these features aren't yet supported by Node, I probably won't be able to put much time in to something like this until after we cross v1.0. There are still quite a few higher priority features I need to add first.

from camo.

WorldMaker avatar WorldMaker commented on July 1, 2024

I have projects that I use in Node that are transpiled from Typescript with a build process. Lately I've been using VSCode and the build process is just Ctrl+Shift+B. Source is Typescript, output can be "runs anywhere" ES5 JS.

With Babel, as the other option, you can transpile through a loader. SystemJS is the one of choice for me. It acts like the ES6/ES2015 loader (kind of a polyfill+extra goodness) and will transpile modules when needed. I use SystemJS in the browser mostly, but it supports Node too. I think there is a way to bundle things so that users don't need to use SystemJS directly unless they too want to make use of it, but I could be wrong.

from camo.

developit avatar developit commented on July 1, 2024

Currently the most pain-free option is to use Babel's Require Hook. You just add this to the entry file of a node application and everything else is transpiled and cached on-the-fly:

require("babel/register");

// then jump into your ES6/7/x code
require('./main');

from camo.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.