1602 / jugglingdb Goto Github PK
View Code? Open in Web Editor NEWMulti-database ORM for nodejs: redis, mongodb, mysql, sqlite3, postgresql, arango, in-memory...
Home Page: http://1602.github.io/jugglingdb/
Multi-database ORM for nodejs: redis, mongodb, mysql, sqlite3, postgresql, arango, in-memory...
Home Page: http://1602.github.io/jugglingdb/
a must have!
Works with driver : memory, but on mongoose.
Would it be possible to fix that? Generally, should the updating parameter have value true/false, or another value?
Thank you.
Hello,
sequelize currently (version": "1.3.7") doesn't provide a "initialize" function, which leads to the following error:
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
TypeError: Object function (database, username, password, options) {
this.options = Utils._.extend({
dialect: 'mysql',
host: 'localhost',
port: 3306,
define: {},
query: {},
sync: {}
}, options || {})
this.config = {
database: database,
username: username,
password: (( (["", null, false].indexOf(password) > -1) || (typeof password == 'undefined')) ? null : password),
host : this.options.host,
port : this.options.port
}
var ConnectorManager = require("./dialects/" + this.options.dialect + "/connector-manager")
this.daoFactoryManager = new DAOFactoryManager(this)
this.connectorManager = new ConnectorManager(this, this.config)
} has no method 'initialize'
at new Schema (MYDEVDIR\node_modules\jugglingdb\lib\schema.js:72:13)
at Object.<anonymous> (MYDEVDIR\node_modules\jugglingdb\lib\railway.js:21:14)
at Module._compile (module.js:441:26)
at Object..js (module.js:459:10)
at Module.load (module.js:348:31)
at Function._load (module.js:308:12)
at Module.require (module.js:354:17)
at require (module.js:370:17)
at Object.init (MYDEVDIR\node_modules\jugglingdb\index.js:11:5)
at MYDEVDIR\node_modules\railway\lib\extensions.js:38:17
My first workaround was to write an adapter for jugglingdb, but i think this is not really what was intended in the example on the website.
The rootcause is to be found in "lib/schema.js
" where "adapter.initialize
" is called. As this initialization should be done in the custom schema (as this is a custom adapter), i'm a little confused there?
Does this simply not work anymore with sequelize?
Best Regards,
Uli
Am I missing them or they are non existant?
This needs issue #65 to be fixed first.
For this to happen we need a client pool that allows clients to be marked as non-reclaimable (node-postgres can do this), and "lock" the client for the duration of the transaction block. This would probably require a way to pass a client instance (which was generated at init-transaction time) to the query functions, and a callback to mark the transaction as done.
seems like sqlite is not supported yet
Database: Mongoose.
Schema has this relationship:
PersonInfo.belongsTo User, {as: 'user', foreignKey: 'personinfoId'}
and this is a code snippet
...
userdata.save () ->
userdata.user user
user.save () ->
promise.fulfill user
...
personinfoId field in User remains empty, and user() getter function does not work. This is remedied by explicitly assigning
userdata.save () ->
user.personinfoId = userdata.id
user.save () ->
promise.fulfill user
but then it seems that user() helper functionality is broken. Thanks.
Hello everyone, did someone started implementing a couchDB adapter?
friends = {
tom:{name:'tom',height:180},
john:{name:'john',height:189},
}
how to define the schema?
like bellow is wrong:
define('Musers', function(){
property('id', Number);
property('friends', []);
});
I'm trying to do a migration for postgres (new or existing table) and it doesn't seem to work. I can run queries fine, just no migration. Code follows:
conString = 'postgres://user:pass@localhost:5432/test'
jugglingdb = require('jugglingdb')
Schema = jugglingdb.Schema
pg_db = new Schema('postgres', { 'url': conString })
# Question model
Question = pg_db.define('Question', {
text: { type: String, length: 255 }
}, {table: 'questions'})
Question.validatesPresenceOf('text')
if !pg_db.isActual()
console.log 'migrating datatables'
pg_db.autoupdate (err) ->
if err?
console.log 'error during migration '+err
else
console.log 'migration successful'
Log output
migrating datatables
DEBUG: TypeError: Object #<Object> has no method 'table'
at /Users/casey/Documents/siide_learn/node_modules/jugglingdb/lib/adapters/postgres.js:277:176
at Array.forEach (native)
at PG.autoupdate (/Users/casey/Documents/siide_learn/node_modules/jugglingdb/lib/adapters/postgres.js:275:31)
Trying to connect to redistogo on heroku and I can't seem to get it.
new Schema 'redis', { host: 'guppy.redistogo.com',
port: '9306',
username: 'redistogo',
password: 'pass' }
This gives me:
2012-04-11T20:45:59+00:00 app[web.1]: node.js:201
2012-04-11T20:45:59+00:00 app[web.1]: throw e; // process.nextTick error, or 'error' event on first tick
2012-04-11T20:45:59+00:00 app[web.1]: Error: Uncaught, unspecified 'error' event.
2012-04-11T20:45:59+00:00 app[web.1]: ^
2012-04-11T20:45:59+00:00 app[web.1]: at RedisClient.emit (events.js:50:15)
2012-04-11T20:45:59+00:00 app[web.1]: at Command.callback (/app/node_modules/redis/index.js:322:14)
2012-04-11T20:45:59+00:00 app[web.1]: at RedisClient.return_error (/app/node_modules/redis/index.js:446:25)
2012-04-11T20:45:59+00:00 app[web.1]: at RedisClient.on_info_cmd (/app/node_modules/redis/index.js:271:21)
2012-04-11T20:45:59+00:00 app[web.1]: at RedisReplyParser.<anonymous> (/app/node_modules/redis/index.js:256:14)
2012-04-11T20:45:59+00:00 app[web.1]: at RedisReplyParser.emit (events.js:67:17)
2012-04-11T20:45:59+00:00 app[web.1]: at RedisReplyParser.send_error (/app/node_modules/redis/lib/parser/javascript.js:266:14)
2012-04-11T20:45:59+00:00 app[web.1]: at RedisReplyParser.execute (/app/node_modules/redis/lib/parser/javascript.js:125:22)
2012-04-11T20:45:59+00:00 app[web.1]: at RedisClient.on_data (/app/node_modules/redis/index.js:422:27)
2012-04-11T20:45:59+00:00 app[web.1]: at Socket.<anonymous> (/app/node_modules/redis/index.js:66:14)
And using the url:
new Schema 'redis', { url: 'redis://redistogo:[email protected]:9306/' }
And I get:
Error: Redis connection to 127.0.0.1:6379 failed - connect ECONNREFUSED
Items that get stored in constructor.cache do not ever seem to be freed up. Is there a way to make this an LRU cache with a fixed size?
It seems that it is not possible to do a simple inheritance on models. Let's say I have a model called Transaction and want to create a FreeTransaction sub model. Simple prototyping inheritence does not seem to work. I narrowed it down to the use of constructor to store schema dependent object (_validations, schema, modelName, etc).
How would you do this inheritence?
I am trying to remove the 'is blank' message or at least customize it.
I am having this validation rule
Domain.validatesPresenceOf('name', {
message : 'Domain name must be provided'
});
But then when doing validation, I got
{ name: [ 'Domain name must be provided', 'is blank' ] }
Is it possible to configure the 'is blank' message ? Or remove it ?
Using any of my models, I can use findOne but not find.
Example:
#define
User = pg_db.define('User', {
name: { type: String, length: 255 }
username: { type: String, length: 255 }
token: { type: String, length: 255 }
email: { type: String, length: 255 }
}, {table: 'users'})
User.find {where: {name: 'name'}},(err,users)->
if err?
console.log err
Gives me:
{ [error: syntax error at or near "["]
length: 83,
name: 'error',
severity: 'ERROR',
code: '42601',
detail: undefined,
hint: undefined,
position: '46',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
file: 'scan.l',
line: '1001',
routine: 'scanner_yyerror' }
JOINs and the like, generating the appropriate objects whenever necessary (ie, querying a Post joining with Author should give me a User object with an author attribute (or whatever is the foreignkey attribute, minus the '_id' part) which contains an Author object).
I have this schema definition
var Domain = schema.define('domain', {
name: Number
});
var User = schema.define('user', {
email: String
});
Domain.belongsTo(User, {as: 'user', foreignKey : 'user_id'});
User.hasMany(Domain, {as : 'domains', foreignKey: 'user_id'});
Then I created some domains and add them to a particular user. I have checked the database and everything is ok.
Then, I do
domain.user(); // It can get the user id
However if I do something like this
domain.user(function(error, user){
// user should be a user record ?
});
I got this error
TypeError: Object #<Object> has no method 'find'
at Object.domain (/home/vagrant/lib/node_modules/jugglingdb/lib/abstract-class.js:690:22)
at ModelConstructor.domain (/home/vagrant/lib/node_modules/jugglingdb/lib/abstract-class.js:705:40)
I am using postgresql 9.1 on Ubuntu 11.10.
Hi,
What I have experienced recently is that sometimes after updateAttributes(), find() returns an object by id, but there is no id element in it (so this property is undefined). This ends up interfering with the code, so I ended up assigning id explicitly in the callback:
7 before 'load role', ->
8 console.log "Looking up role id : " + params.id
9 Role.find params.id, (err, role) =>
10 if err
11 redirect path_to.admin_roles
12 else
13 role.id = params.id
14 @ROLE = role
15 console.log "Here it is : "
16 console.log JSON.stringify @ROLE
17 ## also load role privileges
18 role.privileges (err, privileges) =>
19 if err
20 redirect path_to.admin_roles
21 else
22 @roleprivileges = privileges
23 @roleprIDs = privileges.map (el) -> el.id
24 next()
25 , only: ['show', 'edit', 'update', 'destroy']
One scenario when this happens is in the standard crud generation rw g crud post title content --tpl jade, then rw server 8888, then create a post, then click edit, then update post, then edit again.
I do not know why sometimes find does not return id with the object, I am having trouble recreating this in rw console.
Thanks.
Working with legacy data is difficult. I have a 'user' table and want a User model. But there appears to be no way to tell Juggling to map one to the other. It appears currently that the model name is used as the table name.
Hello.
I encountered a problem when
var Clip = describe('Clip', function () {
property('name',String,{index:true});
property('pubdate',Date,{index:true});
});
Clip.validatesPresenceOf('name',{message:'name cannot be blank'});
Clip.validatesUniquenessOf('name',{message:'name must be unique'});
On create, everything works perfectly but on updating pubdate
and calling clip.updateAttributes()
, juggling fails to update the value in the database.
I am using the mongoose
adapter so this might be specific to it, but I strongly suspect it's a more generic issue.
In lib/validatable.js
on or about line 76, the uniqueness
validator is defined as:
uniqueness: function (attr, conf, err, done) {
var cond = {where: {}};
cond.where[attr] = this[attr];
this.constructor.all(cond, function (error, found) {
if (found.length > 1) {
err();
} else if (found.length === 1 && found[0].id !== this.id) {
err();
}
done();
}.bind(this));
}
The issue occurs when calling this.constructor.all()
which appears to overwrite some(?) properties in the validating object; I suspect this is related to database object caching.
I'm sure there's a more node-ish idiom for implementing a fix, but here's my contribution:
uniqueness: function (attr, conf, err, done) { // 20120224 RR
var orig=this.toObject(), // needed to preserve original props
cond = {where: {}};
cond.where[attr] = this[attr];
this.constructor.all(cond, function (error, found) {
if (found.length > 1) {
err();
} else if (found.length === 1 && found[0].id !== this.id) {
err();
}
for(var k in orig) { // since this.constructor.all() scribbles on this,
this[k]=orig[k]; // we need to copy back any changed props
}
done();
}.bind(this));
}
All best.
/rr
Heyo,
I just spent some time struggling getting data from my db using jugglingdb, and finally realized that my callback needed to an error param before the data param. I know that many things in node work this way, but I think having a prominent example of a callback in the documentation would be pretty awesome for NOOBs like myself. I would be happy to add it myself if that would be helpful. Let me know.
Best,
I'm working in a legacy code with 2 databases. Can I specify a database for each "model" instead of a global one?
Escaping user input is error prone and boring. We should just let the database handle those whenever possible.
Hi,
I'm interested in JugglingDB and wants to know if you have any plan to support advanced queries; maybe using something like https://github.com/balupton/query-engine.npm ?
The dirty state of the object you are trying to save is overridden when using the validatesUniquenessOf validation. The code queries the DB but the implementation of a trivial identity map is overwriting the previous object data (which is pretty bad because you most likely validate when you are trying to save a dirty state).
From @1602 own comments in AbstractClass.all function:
// really questionable stuff
// goal is obvious: to not create different instances for the same object
// but the way it implemented...
// we can lost some dirty state of object, for example
// TODO: think about better implementation, test keeping dirty state
I think it might just be my error right now :P
http://habrahabr.ru/blogs/webdev/130345/
Or add support node-mongodb-native.
It seems that create callback is:
User.create({...}, function(err, user){});
and save callback is
User.save(function(err){});
and is not bound to the object.
I would stick with one or the other. My preference is to use an explicit argument like create to pass the object to the callback.
Should be a pretty small change.
I got a failed test redis for the string "should find filtered set of records". The complete stack trace is:
AssertionError: false == true
at Object.ok (/usr/local/lib/node_modules/nodeunit/lib/types.js:83:39)
at /projects/jugglingdb/test/common_test.js:324:18
at /projects/jugglingdb/lib/abstract-class.js:214:13
at /projects/jugglingdb/lib/adapters/redis.js:158:13
at /projects/jugglingdb/node_modules/redis/index.js:922:13
at try_callback (/projects/jugglingdb/node_modules/redis/index.js:466:9)
at RedisClient.return_reply (/projects/jugglingdb/node_modules/redis/index.js:503:13)
at RedisReplyParser. (/projects/jugglingdb/node_modules/redis/index.js:259:14)
at RedisReplyParser.emit (events.js:64:17)
at RedisReplyParser.add_multi_bulk_reply (/projects/jugglingdb/node_modules/redis/lib/parser/javascript.js:306:18)
Currently the validation is synchronous and it fails when trying to check against an async resource (most notably the db...).
I was implementing a new uniqueness check and my tests were failing on this. The problem is bigger than it seems because isValid is used liberally throughout the code and mostly in conditions (making it difficult to just add a callback and move the next code within).
Any custom validator accessing an async data will have the same problem and without changing the way validation is handled within juggling it would be difficult to implement.
Consider code:
var jugglingdb = require('jugglingdb')
, Schema = jugglingdb.Schema
, accountingUrl = 'tcp://user:password@localhost/database'
, accountingDb = exports.accountingDb = new Schema('postgres', { 'url': accountingUrl });
var Ledger = exports.Ledger = accountingDb.define('ledger', {
'id': { 'type': String, 'length': 32, 'autoIncrement': true },
'name': { 'type': String, 'length': 35 },
'desc': { 'type': Schema.Text, 'length': 500 },
'createdOn': { 'type': Date, 'autoIncrement': true },
});
Ledger.create({name: 'General Ledger' }, function (err) {
console.log(arguments);
});
For some reason the SQL is cycling twice to the database, and it's three times for .save() I think. The same also applies to .all({}) queries. Not sure what would cause this, but if I run into the cause and I can fix it I'll patch it up.
Setter does not get called before User.create, it oly gets called on an update.
User.setter.password = function (pwd) { this.salt = salt; this._password = calcHash(pwd, salt); }; function calcHash(pass, salt) { var hash = crypto.createHash('sha256'); hash.update(pass); hash.update(salt); return hash.digest('base64'); }
The password setter only gets executed with the update event but not with the create event.
Thank you!
JB
Basically this is a non-issue, but would be a nice feature. If I could save multiple rows at once via an array (which with any good luck will run as a single transaction, depending on the driver), it would be useful.
Consider code:
var acc = require('./accounting'); //this has all the model stuff in it
acc.Ledger.create({name: 'General Ledger' }, function (err) {
//debug: console.log(arguments);
if (!err)
console.log('Saved General Ledger');
else if (err.code == '23505')
console.log('General Ledger already exists');
else {
console.log('Error:', err.detail);
return
}
//get general ledger
acc.Ledger.all({ 'where': { 'name': 'General Ledger' }}, function (err, docs){
if (err)
console.log('Error:', err.detail);
else {
var genleg = docs[0];
//this works:
/*genleg.accounts.create({
name: 'Assets'
, baseType: 'Asset'
, direction: 'debit'
}, function (err, docs) {
console.log(arguments);
});*/
//this fails:
genleg.accounts.create(
[
{
name: 'Assets'
, baseType: 'Asset'
, direction: 'debit'
},
{
name: 'Liabilities'
, baseType: 'Liability'
, direction: 'credit'
},
{
name: 'Equities'
, baseType: 'Equity'
, direction: 'credit'
},
],
function (err, docs) {
console.log(arguments);
});
}
});
});
The error provided is:
null value in column "name" violates not-null constraint
The error was probably due to the fact that it's looking for array['name'] but it doesn't exist (expected). So in order to permit this, some type of loop must be executed, either to devise multiple queries or to create a compound query, depending on each driver. You can figure out whether you have an array or not this way:
if (typeof objInput == 'object')
if (objInput instanceof Object)
//do this
else if (objInput instanceof Array)
//do that
After figuring out if it's an array or object, you could do one of two things. Split the code path as in above, or my favorite, force it to become an array and store the non-array in the first index. So:
if (typeof objInput == 'object' && objInput.prototype instanceof Array)
//if not an array, make it an array
objInput = [ objInput ];
for (var obj in objInput)
//either run multiple single queries or
//formulate a good INSERT ('A','B','C') VALUES( (1,2,3), (2,3,4) ) plan to run the query following the loop
Thanks, but I still haven't looked over the code enough to be comfortable butchering the code. I think you'll find this to be a useful feature as well, although it would probably require changes to every driver :~.
For my purposes of testing, I've been using postgres for this exercise. This may actually already exist in other drivers, as I haven't tested anything other than postgres.
Thanks,
David
Hi,
I am working on user authentication code, and the idea is that every user has a role, and every role has privileges. Each role corresponds to a collection of privileges. Each privilege may be in more than one role.
This is a use case of manyToMany I think. Is there a way to implement something like this with jugglingDB?
It seems that jugglingDB now only has oneToOn and oneToMany, and does not have manyToMany. Please let me know if I am not correct. Would be great if you could suggest a way to go about using the relationship.
Thanks!
Hi,
could you please explain how to use those hooking functionalities?
Do I have to use it like that:
var foo = schema.define('foo', {
bar: String
});
foo.beforeSave = function(fooInstance) {
fooInstance.bar = fooInstance.bar + 'foobar';
}
Also I'm interested in hearing how the three mentioned correlate with each other.. Is some e.g. beforeSave also called when updating/creating a row?
Thanks,
Michael
Why can't I call a find synchronously?
given the example from the readme:
Post.all({where: {userId: user.id}, order: 'id', limit: 10, skip: 20});
I have
User.all({where: {session: req.session.user_token}})
I get:
DEBUG: cb(err, collection);
^
DEBUG: TypeError: object is not a function
at Object.CALL_NON_FUNCTION (native)
And yes I realize that sync can be a bad idea, but how else am I to render my view? Using express.js as a web server backend.
This issue is migrated from the Google group....
I have the following in the model/facility.js file:
Facility.beforeCreate = createTimeStamp;
function createTimeStamp(done) {
this.date_created = (new Date()) - 0;
this.date_updated = (new Date()) - 0;
console.log('JKL: Inside createTimeStamp');
done();
};
I can see that the trigger is fired, i.e. the "JKL: Inside create TimeStamp" is showing in the console. But there is no value in the db table stored when I click on the Create Facility button. But all the other data columns have data except the date_created and date_updated column. So it either appears that the beforeCreate hook is fired, but the data are override in the ORM level.
I have added a console.log message in my sqlite3.js file in the adapter and in the AbstractClass.create() to see the data being passed into these routines and these two columns have no data in both cases.
I am using the scaffolding controller code. So it is using the .create() method to create the data in the database.
My _form.ejs for these two fields are "hidden", i.e. I am using the following:
<div class="controls">
<%- form.input("date_updated", {type: "hidden"}) %>
</div>
But they exist in the html page generated. I have also tried to display them and in both cases, the date_created and date_updated field in the db have null value in it.
But the beforeUpdate hook works normally.
Let me know if this is something that I miss or something the framework will need to be updated. Thanks.
MongooseAdapter.prototype.all = function all(model, filter, callback) {
...
if (filter.order) {
query.asc(filter.order); //direction is hardcoded
}
...
};
is there an easy way to patch this issue and define findOne method?
Thanks
Currently, an error is thrown ("Method only can be called with one or two arguments") when you try to call a hasMany without arguments. This is quite unintuitive.
If I have a User model that hasMany Post (as 'posts'), calling user.posts()
seems like it should return all of the user's posts. My guess is that this is merely a factor of Juggling's newness but it does seem like it should work as expected.
I actually can't figure out how to synchronously load the related posts using user.posts
. The posts
object/function has the _scope
property and there's a find
property (that has a find
and destroy
method...?) but I can get no combination to work.
I'm working in a legacy code with 2 databases. Can I specify a database for each "model" instead of a global one?
Is there (or could there be) a way to use natural keys instead of whatever the default key is (eg ObjIds for mongo)?
Some db layouts may require the app to access tables in more than one schema, therefore jugglingdb should support specifying which namespace a model belongs to.
There was an issue before about Boolean type not updating properly. In addition to that, even String type does not update consistently.
For example, we want to update one field F1. It is not updated unless in addition to F1 we make a dummy change to at least one another field (for example, F2). For some fields such trick is not necessary, for some you need it.
I am having trouble determining what is the reason behind this kind of behavior. Would be great if you could shed some light on this.
All fields are String, database is Mongoose. Thank you.
Hello,
what a lovely documentation, but I just found 2 minor typos:
https://github.com/1602/jugglingdb/blob/gh-pages/schema.html#L117
https://github.com/1602/jugglingdb/blob/gh-pages/schema.html#L127
Building queries through an interface leads to more portable code, since the interface can abstract all the differences.
Something like
query.select(['id','name']).from('user').where({age: 20}).sql(); // with chaining!
This is similar to what can be found in PHP-land with CodeIgniter or Symfony.
There are really 2 problems right now with the update attribute hooks:
I'm not sure if this is documented somewhere, but it seems that the neo4j adapter is not actually complete yet.
You can call methods on the adapter itself (through the mixin methods) and those actually take advantage of Neo4j's relationship model. However, if you use the hasMany type helpers it doesn't work properly and instead tries to create and query by node attributes such as it would with Mongo or Redis.
I'm not sure if the architecture allows us to customize the way these helpers work so that we can take advantage of Neo4j's strengths?
Not using pooling is inefficient since (at least with node-postgres) queries will be executed serially and not concurrently. It also breaks transactions, because different requests could cause commands to mix within a transaction.
Not sure if this should work... but if I want a parent-child relation on the same collection, it seems to generate non-functional convenience methods.
Example:
var Topics = describe('Topic', function () {
property('name', String);
});
Topics.hasMany(Topic, {as: 'subtopic', foreignKey:'topicId'});
Topics.belongsTo(Topic, {as: 'parentTopic', foreignKey:'topicId'});
if eventually I try to do
subtopic.parentTopic() I get nothing in return.
if I try:
topic.subtopics(callback) I get every topic in existence.
Model.all(function(err, objects){
objects.forEach(function(object){
console.log(object.property);
});
});
I can acess object.property inside scope of Model.all(), but to acess value outside scope I need to use a global variable, like this:
value = 0;
Model.all(function(err, objects){
objects.forEach(function(object){
value = object.property;
});
});
function showValue(){
return value;
}
If I try to use Model.all inside a model(instead controller or view), I can't do this:
Model.showValue = function showValue(){
value = 0;
Model.all(function(err, objects){
objects.forEach(function(object){
value = object.property;
});
return value;
});
}
Model.showValue returns always 0, instead object.property.
Maybe Model.all() could return objects values, like this:
var value = Model.all(callback);
Just an idea... probably I'm wrong
More of a discussion topic than an issue.
I notice that there is no support for advanced queries such as filtering where a specific column is greater/less than, and I appreciate your reasoning for this (issue #2 #2).
But this made me curious, is there any way to achieve the same effect without taking a large performance hit?
So let's take a simple django query that gets posts with pub_date >= someDate:
Post.objects.filter(pub_date__gte=someDate)
What would be the most efficient way to achieve the same effect when such queries aren't available?
Or would you tackle this issue in an entirely different manner?
Would needing this simply mean the application calls for a DBMS that supports this type of query?
Sorry if creating an issue is inappropriate for this, let me know if that is the case. Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.