Coder Social home page Coder Social logo

jagi / meteor-astronomy Goto Github PK

View Code? Open in Web Editor NEW
607.0 27.0 66.0 2 MB

Model layer for Meteor

Home Page: https://atmospherejs.com/jagi/astronomy

License: MIT License

JavaScript 100.00%
javascript astronomy meteor schema model mvc validation mongodb

meteor-astronomy's People

Contributors

awei01 avatar axelvaindal avatar ben-wd avatar ben305 avatar dandv avatar dovrosenberg avatar eranbot avatar erobit avatar faberle avatar ffxsam avatar jasonk avatar joaorjose avatar joefru avatar jthomaschewski avatar lukejagodzinski avatar lukemt avatar niceilm avatar peterchoo avatar ribbedcrown avatar space-alien avatar talha-asad avatar tdamsma avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

meteor-astronomy's Issues

Update an object without fetching it first?

Consider the following code:

Meteor.methods({
  setPostTitle: function(postId, title) {
    Posts.update(postId, { title: title });
  }
});

It this the Astronomy equivalent?:

Meteor.methods({
  setPostTitle: function(postId, title) {
    var post = Posts.findOne(postId);
    post.set('title', title);
    post.save();
  }
});

Any way to avoid the extra database read? (findOne)

How validators should work?

Hi, I have question to you about validators. I'm working now on implementing them as a module for Meteor Astronomy. Here is the repository. It's not finished yet and I need your support on how it should work to be the most intuitive and easy in use. Please take a look at read me in the repository.

Let me describe here how it works. Right now, we can define array of validators in the class schema. In validator definition, we have to provide name of the field on which validation should take place, type of the validator, some options if required and error messages. We can also add validators that works on many fields like Compare validator. To validate object we call validate() function on given object. Now few questions arises.

  1. Should validation take place automatically when calling save() method on the object?
  2. In what form would you like to get error message? Should it throw exception that you're gonna catch and display somewhere error or you want just true or false return value from the validate() method? And later you would like to call function like for instance object.getErrors() to get all errors.
  3. Right now you can have multiple validators per one field and validators that work on two fields (Compare). With validators working on one field there is no problem because we exactly know with what field it's related. But where to display error messages saying for instance that two values are not equal? What kind of customisation would you like to see?
  4. Do you need possibility to validate single field? Or single validator that works on two fields? Like object.validate('comparePasswords')?
  5. Do you want error messages to be reactive?

If you have any other idea I'm open for discussion :)

Validating before saving

I am trying to see if packages astronomy+validator can replace aldeed::Collection2 in my project.
One thing I don't see clearly is how to validate any object that I intend to save to the database. By validate I mean "throwing an exception if the object is ill-formed".
What are the best practices? Should I implement my own validateAndSave() function? Is there something I am missing?

self relation based in a variable

The wiki does not specify this situation I have.

How could one do a relation to self based on an array of ids?

User follows other User and maybe vice-versa?

class User would have an array "followersIds" with all of the ids of its followers.

User: _id, followersIds: [id2,id3,id4]; var user = new User(); user.followers

Thank you for your time

Default values on nested inherited fields

It doesn't appear that these work.. I realise it's an edge case!

Code something like this:

Parent = Astro.Class({
name: 'Parent',
fields: {
'system': {
type: 'object',
default: {}
},
'system.field2': {
type: 'string',
default: 'field2test'
},
});

Child = Base.extend({
name: 'Child',
collection: Childs,
fields: {
"field1": {
type: 'string',
default: 'field1test'
}
});

new Child().save();

The record created will have the values {} for system, and field1test for 'field1', but not the nested field. Moving the nested field up to the top level causes this default to be inserted properly.

Will see if I can dig in the code and suggest a fix.

Nested field with Astro.Class value type

I tried to do that

Address = Astro.Class({
  name: 'Address',
  collection: Addresses,
  fields: {
    // ...
  }
});

Person = Astro.Class({
  name: 'Person',
  collection: Persons,
  fields: {
    // ...
    address: new Address() // here
  }
});

But it doesn't work, how do I achieve this ?

emitting custom events?

Is it possible for behaviors to emit custom events? For example, I'm doing a slightly different variant on softdelete that actually just runs on a remove via beforeremove. It flags the object as deleted and cancels the remove. Because the remove was cancelled, the afterremove event no longer fires (I assume). And it shouldn't.

But I'd like the ability to emit an "aftersoftdelete" event that objects with this behavior could handle.

Is that possible?

_errors is not send back to client

menu is instance of Astro.Class.

Server side :

    if ( menu.validate() ) {
        menu.save();
    } else {
        console.log( menu._errors._getMigrationData() );
        return menu;
    }

Above console.log show that there is invalid field in menu.
_errors : ReactiveDict is not send through DDP , so client side can't see errors sent by server side.
There are some custom validators which should run on server ( unique ). So my goal is to validate on client side and then validate on server side. Eventually errors should be send back to client side.

Having issues when saving objects in an array of an Astronomy.Class

Hi @jagi

when trying to save an array of objects, it works the first time, second time not.

You can use the same repo here: https://github.com/banglashi/astronomy-serverside-transform

Than run following on the console:

var newChat = new Chat()
undefined
newChat.title = "test";
"test"
newChat.members.push({title:'test'})
1
newChat.save()
"pz5FLFERiXgFfjkzJ"
newChat.members.push({title:'test2'})
2
newChat.save()
false

Any ideas? Is this perhaps still in development? Thanks and regards.

push/pop-like operator for array based fields

Currently, the only way to work with array-type fields is to explicitly specify them by index:

Let c be:
{
  members: [
    'member-1',
    'member-2',
    'member-3'
  ]
}

c.get('members.0') // Returns 'member-1'
c.set('members.4', 'member-4')

It would be nice to have a way to push a new element onto the array like so:

c.push('members', 'member-4')
c.pop('members') // Returns 'member-4'
c.pop('members', 0) // Returns 'member-1'

Null on insert document into collection

Great package. Seems to be working wonderfully in my project up to right now. I'm not quite sure of what I'm doing wrong but if anyone could help me out that'd be great.

This is going to seem like a very long issue but it's really just a lot of snippets of code. I basically have a simple Add Question page to that calls the /question/save Meteor Method on the server after validating and then inserts the document in the collection. For some reason, some of my fields (2 selects, 1 textarea and 1 input) come back as null. Not always the same one too (which makes things worst). I know the method is being called and a document is created (good sign) and I know the jQuery for querying the data from the form is sound. I'm just not sure what is going wrong.

<!-- Section of addQuestionAdmin Template -->
{{#with question}}
<div class="field">
    <label>Texto da Questรฃo</label>
    <textarea rows="4" placeholder="Escreva a questรฃo aqui..." type="text" value="{{text}}" id="text"></textarea>
</div>
<div class="inline fields">
    <div class="four wide field">
        <label>Resposta</label>
        <select class="ui dropdown" id="answer" value="{{answer}}">
            <option value="">Resposta</option>
            <option value="A">A</option>
            <option value="B">B</option>
            <option value="C">C</option>
            <option value="D">D</option>
        </select>
    </div>
    <div class="six wide field">
        <label>Prova</label>
        <input placeholder="Prova" type="text" id="prova" value="{{prova}}">
    </div>
    <div class="six wide field">
        <label>รrea</label>
        <select class="ui dropdown" type="text" id="materia" value="{{materia}}">
            <option value="">รrea da questรฃo</option>
            <option value="0">ร‰tica</option>
            <option value="1">Filosofia</option>
            <option value="2">Constitucional</option>
            <option value="3">Direitos Humanos</option>
            <option value="4">Direito Internacional</option>
        </select>
    </div>
</div>
<br>
<div class="right field">
    <div class="ui button green" type="button" name="save">Adicionar Questรฃo</div>
{{/with}}

I then have a simple events page on the template

Template.addQuestionAdmin.events({
    'focus .field': function(e, tmpl) {
        var question = this;

        var text = $('#text').val();
        var answer = $('#answer').val();
        var prova = $('#prova').val();
        var materia = $("#materia").val();

        question.set('text', text);
        question.set('answer', answer);
        question.set('materia', materia);
        question.set('prova', prova);

        question.validate(text, answer, materia, prova);
    },
    'click [name=save]': function(e, tmpl) {
        var question = this;

        if (question.validate()) {
            Meteor.call('/question/save', question, function(err) {
                if (!err) {
                    Router.go('/admin');
                } else {
                    question.catchValidationException(err);
                }
            });
        }
    },

});

I also have the /question/save method on the server.

Meteor.methods({
    '/question/save': function(question) {
        if (question.validate()) {
            question.set('author', Meteor.userId());
            question.save();
            return question;
        }

        question.throwValidationException();
    }
})

Here's my collection

// Create global Mongo collection.
Questions = new Mongo.Collection('questions');

// Create global class (model).
Question = Astro.Class({
    name: 'Question', // Name model.
    collection: Questions, // Associate collection with the model.
    transform: true, // Auto transform objects fetched from collection.
    fields: {
        text: 'string',
        answer: 'string', // Define "title" field of String type.
        prova: 'string',
        materia: 'string',
        author: 'string',
    },
    behaviors: ['timestamp'] // Add "timestamp" behavior that adds "createdAt" and "updatedAt" fields.
});

Here's my router:

Router.route('/add-question', {
    name: 'addQuestionAdmin',
    data: function() {
        return {
            question: new Question()
        }
    }
});

It should be simple. I don't understand why the data isn't coming through. Through using Mongol all I can see on the db that some values get the data, some get null. They interchange, sometimes getting the first two fields and then the next try only gets the last 2 selects. It's fucking with my brain. What am I doing wrong!?

Any help would be appreciated. Thanks in advance!

Setting _id on new document

Hi, great package and thanks for all the time put in!

Is it possible to set the _id when inserting new documents? I'm storing data from a 3rd party API which already includes a unique ID. I need to query based on this 3rd party ID, and since _id is indexed automatically I'd prefer to just use the 3rd party ID, rather than having to create another index.

Meteor.loginWithPassword fails when using "supportLegacyBrowsers" option

With the new "supportLegacyBrowsers" config (see #32) the "_values" object have been reintroduced. This causes some trouble with "Meteor.loginWithPassword".

It fails with "User has no password set" as it does not find a password in key "services" of user object - because its hidden inside the "_values" object

Astronomy module to track direct manipulations on DB/collections.

As discussed here it would be good to have a way to track changes made to a DB/collection (or a table in future) by some server-side process, or a user who can access the DB.

The module should be smart to analyze what kind of change has been made?, when?, and by whom? and be flexible to fire certain events with custom messages, something like:

"[a process, or] a user with *username* (*IP address*)  
touched *DB/collection* on *Date/Time* and *modified/deleted/created* this doc: 
docID, old version: "{modified properties}", new version:"{modified properties}"

This is just a quick example I can think of and surely there are better ways to design this, so I'd love to here some comments.

p.s.: perhaps it could be named as "DB-watch" or something. :)

Cannot use Meteor.userId() as default value for field

Hi.
First of all thank you very much for your excellent package.

I'm having an issue when trying to attach currently logged in userId as a default value for field in Astro.Class.

When I have

Message = Astro.Class({
    name: 'Messages',
    collection: Messages,
    fields: {
        'senderId': { type: 'string', default: Meteor.userId() },

I got an error: Error: Meteor.userId can only be invoked in method calls. Use this.userId in publish functions.

But with 'senderId': { type: 'string', default: this.userId }, this keyword is AstroClass and its userId is null.

Behaviors appear to not be working at all for me :/

I am quite new to meteor and I am playing with setting up models for a new project and I'm using the timestamp as well as some customer behaviours. At the moment I'm specifically using behaviours to add groups of fields to models that will be re-used in a few different models, for example address fields.

Astro.createBehavior({
    name: 'addresses',
    events: {
        addbehavior: function(behaviorData) {
            var Class = this;

            // Add fields to the Class.
            Class.addFields({
                'addresses': {
                    type: 'array',
                    default: []
                },
                'addresses.$': {
                    type: 'object',
                    default: {}
                },
                'addresses.$.name': 'string',
                'addresses.$.street': 'string',
                'addresses.$.town': 'string',
                'addresses.$.postcode': 'string',
                'addresses.$.country': 'string',
                'addresses.$.isDefault': 'boolean',
                'addresses.$.isBilling': 'boolean',
                'addresses.$.isShipping': 'boolean'
            });
        },
        initclass: function(schemaDefinition) {},
        initinstance: function(attrs) {}
    }
});

I have a customer class which implements the addresses and timestamp behaviours.

Customers = new Mongo.Collection('Customers');

Customer = Astro.Class({
    name: 'Customer',
    collection: Customers,
    transform: true,
    fields: {
        company: {
            type: 'string'
        }
    },
    behaviours: ['addresses', 'timestamp'],
    relations: {
        Quotes: {
            type: 'many',
            class: 'Quote',
            local: '_id',
            foreign: 'customerId'
        },
        Contacts: {
            type: 'many',
            class: 'Contact',
            local: '_id',
            foreign: 'customerId'
        }
    }
})

I am simply adding a quick customer on the server side at startup.

Meteor.startup(function() {
    Customers.remove({});
    cust = new Customer();
    cust.company = "Acme Cafe Ltd";
    cust.set('addresses.0', {
        name: "Cafe",
        street: "The Esplanade"
    });
    cust.save();
});

However the document thats created in Mongo has no createdAt or address fields, I do have the additional modules installed in the packages file.

What am I doing wrong? I don't see any errors and the 'just' object validates.

Many thanks for a great package, I hope I can get this working well.

Question about events

I have three questions about events.

  1. What is the order of execution for the events: beforesave, beforeinsert, beforeupdate, beforeremove, aftersave, afterinsert, afterupdate, afterremove? Is this correct: beforesave => aftersave => beforeinsert/update => afterinsert/update and independently beforeremove => afterremove

  2. Is the afterinsert hook from matb33:collection-hooks the same thing compared to the afterinsert event from astronomy?

  3. Is getModified() available to the events so that I can check what actually has been modified within the before/afterupdate hook and act accordingly? I'm referring to the this.previous from https://github.com/matb33/meteor-collection-hooks#afterupdateuserid-doc-fieldnames-modifier-options

Ability to mass-set attributes before .save() (update, not new object)

Vanilla meteor allows you to pass a hash to an .update() call using $set. This feature is missing from Astronomy. (or is it?) It's definitely missing from the docs. Is there a way to do this in Astronomoy, similar to mass-setting the parameters in a new Object(hash) call? Thanks!

eg.

var obj = {"name": "blah", "title": "name"}
// ast is an astronomy object
ast.update(obj)
ast.save()

remove syntax

Not a big deal at all, but it might be helpful to have a way to remove a document given just an _id. Because removes are often done in a meteor method, it can be more efficient to call the method with just an _id and not have to pass a full copy of the object back to the server. Similarly for cases where all I have is an _id (perhaps from a related record) and haven't yet pulled the whole document.

If I do Posts.remove(id), then any Astronomy beforeremove/afterremove events don't get called. So I've been doing (new Post({_id:id})).remove(), which seems a bit clunky. Is there a better way?

Support for observechanges?

I understand that meteor-astronomy uses the transform function to create classes and add methods, but some libraries (e.g. https://github.com/alethes/meteor-pages) use cursor.observechanges instead of cursor.find, so the transform function is never called. Is there a plan to patch this?

I would love to be able to use model methods from astronomy on my paginated pages.

Form data

When working with forms, we definitely want to set the label, placeholder, the input type, if it is a textarea, number of rows, min and max, etc to use then in template helpers.

Now, we can't define this on scheme level. Besides, if we use validators, we also define some of this info there: maxLen, minLen for example. The type definition is duplicated in fields and simpleValidators (string for example).

We need to think about a good api for that functionality.

@jagi , any thoughts on how this can be implemented? Where do you suggest to do that?

[FR] Transient fields

Since I see a natural evolution of astronomy to be a forms framework, I'd like the fields to have a selective:

  • persisted
  • transient

property where persisted is default but if marked as transient it becomes a part of the model and not saved in the db.

A practical use of transient fields would be form fields where we would like to validate, but only save a calculation or part of. For example, a form may consist of an address part where the user needs to enter areacode, areaname, district, province, city, state but evidently, only areacode is sufficient to deduce that whole set of fields. So I would not want to persist the whole thing, only the areacode.

This goes for the view as well, such that the user would be able to see the complete address information that is only derived from a few persisted fields.

Another example would be two fields, age<integer> and isAdult<boolean> where age needs to be persisted but isAdult is actully age>=18.

I know some of this can be done using methods, but I believe methods should be reserved mostly for mutators.

Actually, that kind of semantics goes for relationships as well, indicating that a field is actually a reference to another database object that is mapped by it.

This is actually not new, they are concepts from java's persistence api implementation. This is a very brief, but effective read: http://www.objectdb.com/java/jpa/entity/fields

PS: It also discusses @version which is used for optimistic locking of database records, and may be a good candidate to become a behaviour in astronomy.

Form model binding

Any plans to add form model binding? Thanks, this looks like a great package, looking forward to playing with it.

Two way data binding

Thanks for creating an amazing package. I would request you to add two way data binding.

Reactivity?

Nice package. The question is - when I get the post instance - will it reactively update when its data change or do I need to call reload method ?

Implicit Setter/Getter not possible?

Just learned about your package. I'll be tracking it to see how it evolves :)

First impression was that the setter/getter syntax is verbose. From docs

Setters and getters

Each class has the setter (set) and getter (get) functions. Let's take an example.

Post = Astro.Class({
  name: 'Post',
  collection: Posts,
  fields: ['title', 'commentsCount']
});

var post = new Post();
post.set('title', 'Title'); // Call field setter.
alert(post.get('title')); // Call field getter.
But you can also set values directly but assigned values won't be converted to the proper type of the fields.

post.title = 'New title';
post.title = 123; // Value won't be converted to the string.
alert(post.title);
You should always set values coming from the forms using the set function.

Can we not consolidate the approach somehow? object.property = x is much more terse.

validator syntax - feature request

Not sure if it's possible, since validators are a separate module, but I think it could be helpful to be able to specify single-field validators inside the fields object (as an option, in addition to the current syntax):

fields: {
    emailAddress: {
        type: 'string',
        validators: Validators.email
    }
}   

For more lengthy object definitions it would make it simpler to be able to tell which fields have been validated and which haven't (particularly important during development to be able to make sure I haven't forgotten about one).

Just a thought.

type validators and "required"

Sorry for the flood of new issues... hopefully they're helpful.

The type validators (date, email, etc.) all appear to return false (invalid) if the field is blank. To me, it's more intuitive that they'd return true in that case. If I want to fail a blank field, I'd add the "required" validator. But if it's not marked as "required", it should not be required. :)

Not sure what others think, though.

Release 0.13.0

This issue tracks the release of Astronomy 0.13.0.

  • Nested schema definition #42
  • Multiple fields validation #65
  • Warn about setting not defined field #63
  • Fix document states
  • Fix error with calling the init function on every document creation
  • Reorganize code
  • Nested fields validation
  • Tests for all features

Moved to the 0.14.0 release.

MomentJS on event hook

I'm trying to use MomentJS to format the date for the createdAt and updatedAt timestamps. I tried using an aftersave and a beforesave event like this

    events: {
        aftersave: function() {
            var date = moment();
            date = moment(date, 'MM-DD-YYYY');
            post.set('postedAt', date );
        }
    }

Neither of them seem to create a postedAt field on the db when I add another post. Am I approaching this the correct way?

Mention the prior art: SimpleSchema, CollectionHooks, Collection Behaviors

Many people in the Meteor community are familiar with @aldeed's SimpleSchema and @matb33's CollectionHooks. @Sewdn's collection-behaviors is another prior art that also seems to have been used as source of inspiration.

After reading the documentation, Astronomy seems to reinvent all these three packages and use neither. A lot of work has gone into both SimpleSchema, CollectionHooks and Collection Behaviors on one hand, and Astronomy on the other. There are probably good reasons for not reusing the existing packages, and why Astronomy decided to build its own schema, hooks and behaviors. Users would love to know these.

Thanks!

Allow child classes without extra fields

I want to create a child class, which only adds some methods.
But astronomy forces adding at least one field even to child classes:
Error: At least one field has to be defined

I think it should be possible to have child models without extra fields.

Validation stops on first invalid field

I noticed validation stops on first invalid field, that is perfect for most use cases.
However there is one use case where validation should not stop on first invalid field.

In my apps I try to keep structure of documents consistent all the time ( what a suprise ;-) ) so on every startup app is validating all documents in all collections.
It may happen that doing some changes manually on db admin simply broke structure.
It is better to see upfront how much db was damaged.

Let me know if sth like that could be easy to add.
Again, thanks for your hard work ! :)

reload() method causes recognition as "new" in astronomy 0.12.0

In my code I use the "reload" prototype method in some cases.

In Version 0.11.0 I was able to save a already persisted document after a reload. In 0.12.0 its recognized as new after reloading and saving it causes a duplicate key exception.

var post = Posts.findOne();
post.save(); // No error here
post.reload();
post.save(); // Exception while invoking method 'Post.save'
             // MongoError: insertDocument :: caused by :: 11000 E11000 duplicate key error index

After reload new property ".isNew" becomes true

Doc is not well organized IMO

A ToC is supposed to describe what's in the document below. Here there are 2 issues:

  • There are 2 ToCs! One at the beginning, and one in the "Features" chapter.
  • The second ToC points to following chapters _and_ to external documents.

As a result, I have just spent 15 minutes starring at the doc to find the concept of "validator" (although I used other keywords such as "validate" and "check"). I found nothing and went though the source code, wondering "how is it possible there is nothing to validate a value?!". Then I finally found that there is an external package for this (a package whose name isn't even mentioned in the doc).

I suggest the following:

  1. Merge chapter "Features" with the ToC.
  2. Create a chapter called "External features", containing a list of all external modules, with package name, description and github link.
  3. Remove the wiki pages and turn them into standard package doc.

Default value for nested fields

I have a lot of nested documents and would like to manage them using Astronomy package.

A = Astro.Class( {
    name: 'A',
    collection: ACollection,
    fields: {
        name: {
            type: 'string',
            default: ''
        },
        displayName: {
            type: 'string',
            default: ''
        },
        notes: {
            type: 'string',
            default: null
        },
        links: {
            type: 'array',
            default: []
        },
        category: {
            type: 'string',
            default: ''
        },
        subObject: {
            type: 'boolean',
            default: false
        }
    }
)

Field links is array of objects.
Usually I'm using js-schema library :

ASchema = schema({
    name : String,
    displayName : String,
    notes : String ,
    links : Array.of( {
        _id: String,
        amount: Number,
        unit: String,
        prepMethods: Array.of( String )
    }),
    category :  String,
    subObject : Boolean
})

However js-schema doesn't allows me to specify default values for each field.
I would love to have js-schema syntax together with your validators.

Something like that, would be brilliant :

var t = function(type, default){
   var obj = {type:type, default : default};
   return  obj
}
A = Astro.Class( {
    name: 'A',
    collection: ACollection,
    fields: {
        name :               t('string', 'hello'),
        displayName :       t('string', 'displayname'),
        notes :               t('string', 'default notes') ,
        links : Astro.arrayOf( {
            _id:                t('string', 'default notes'),
           amount:               t('number', 0) ,
           unit:                t('string', 'default notes'),
           prepMethods:       Astro.arrayOf( t('string', 'default') )
       }),
       category :  t('string', 'default'),
       subObject : t('boolean', true)
    }
)

Let me know what do you think about it?

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.