Skip to content
This repository was archived by the owner on Apr 18, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 9 additions & 16 deletions api/app.api.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,22 @@ var path = require('path');
var loopback = require('loopback');
var explorer = require('loopback-explorer');
var CONFIG = require('global.config');
var LOCAL_CONFIG = require('local.config');
var boot = require('loopback-boot');

// server
var server = module.exports = loopback();

// data source
// var db = loopback.createDataSource(LOCAL_CONFIG.db);
var db = loopback.createDataSource({
connector: require('loopback-connector-mongodb'),
database: 'todo-example'
boot(server, {
appRootDir: path.resolve(__dirname),
modelsRootDir: path.resolve(__dirname, '..'),
appConfig: {
// No app config to load, we are processing it manually now
// TODO(bajtos) modify Gulp to create app.* config files
},
});

// models
var User = require('models/user');
var Todo = require('models/todo');

// setup the model data sources
User.attachTo(db);
Todo.attachTo(db);
server.model(User);
server.model(Todo);

// TODO(ritch) this should be unecessary soon....
var Todo = server.models.Todo;
server.model(Todo.getChangeModel());

// root api path
Expand Down
14 changes: 0 additions & 14 deletions api/configure.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,3 @@ exports.global = function(env, global) {
root: '/api'
};
}

exports.local = function(env, global, local) {
var db = local.db = {};

if(env === 'staging' || env === 'production') {
db.host = process.env.DB_HOST || global.api.host;
db.port = process.env.DB_PORT || 27015;
db.connector = 'mongodb';
db.user = process.env.DB_USER;
db.password = process.env.DB_PASSWORD;
} else {
db.connector = 'memory';
}
}
6 changes: 6 additions & 0 deletions api/datasources.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"db": {
"connector": "memory",
"defaultForType": "db"
}
}
2 changes: 2 additions & 0 deletions api/datasources.production.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Use the same environment-based configuration as in staging
module.exports = require('./datasources.staging');
12 changes: 12 additions & 0 deletions api/datasources.staging.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
var globalConfig = require('global.config');

module.exports = {
db: {
connector: 'mongodb',
hostname: process.env.DB_HOST || globalConfig.api.host,
port: process.env.DB_PORT || 27017,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: 'todo-example',
}
};
4 changes: 3 additions & 1 deletion gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,10 @@ function findAndBuild(packageName, cb) {
function findSrc(package) {
var paths = [];
findPackages(package).forEach(function(pkg) {
paths.push(path.join(__dirname, pkg, '*', '*') + '.js');
paths.push(path.join(__dirname, pkg, '*', '*.js'));
paths.push(path.join(__dirname, pkg, '*', '*.json'));
paths.push(path.join(__dirname, pkg, '*.js'));
paths.push(path.join(__dirname, pkg, '*.json'));
});
return paths;
}
Expand Down
63 changes: 30 additions & 33 deletions html5/app.html5.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,41 @@
var LOCAL_CONFIG = require('local.config');
var loopback = require('loopback');
var client = exports.client = loopback();
var async = require('async');

// angular.js dependencies
require('./bower_components/angular/angular.js');
require('./bower_components/angular-route/angular-route.js');

// data sources
var remote = loopback.createDataSource({
connector: loopback.Remote,
url: LOCAL_CONFIG.serverInfo.url
});
var memory = loopback.createDataSource({
connector: loopback.Memory,
localStorage: 'todo-db'
});

// models
var User = require('models/user');
var RemoteTodo = window.RemoteTodo = require('models/todo');
var LocalTodo = window.LocalTodo = RemoteTodo.extend('LocalTodo');
var lbapp = loopback();

require('./build/datasources.js')(lbapp);
require('./build/models.js')(lbapp);

// TODO(bajtos) Move the bi-di replication to loopback core,
// add model settings to enable the replication.
// Example:
// LocalTodo: { options: {
// base: 'Todo',
// replicate: {
// target: 'Todo',
// mode: 'push' | 'pull' | 'bidi'
// }}}

var LocalTodo = lbapp.models.LocalTodo;
var RemoteTodo = lbapp.models.Todo;

// setup model replication
function sync(cb) {
if(window.connected()) {
RemoteTodo.replicate(LocalTodo, function() {
LocalTodo.replicate(RemoteTodo, cb);
});
}
}

// sync local changes if connected
LocalTodo.on('changed', sync);
LocalTodo.on('deleted', sync);

// routes
var routes = LOCAL_CONFIG.routes;
Expand All @@ -47,31 +62,13 @@ require('./controllers/login.ctrl');
require('./controllers/register.ctrl');
require('./controllers/change.ctrl');

// setup the model data sources
RemoteTodo.attachTo(remote);
LocalTodo.attachTo(memory);


window.isConnected = true;

window.connected = function connected() {
console.log('isConnected?', window.isConnected);
return window.isConnected;
}

// setup model replication
function sync(cb) {
if(connected()) {
RemoteTodo.replicate(LocalTodo, function() {
LocalTodo.replicate(RemoteTodo, cb);
});
}
}

// sync local changes if connected
LocalTodo.on('changed', sync);
LocalTodo.on('deleted', sync);

// setup routes
Object.keys(routes)
.forEach(function(route) {
Expand Down
8 changes: 8 additions & 0 deletions html5/client.models.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"LocalTodo": {
"dataSource": "local",
"options": {
"base": "Todo"
}
}
}
107 changes: 106 additions & 1 deletion html5/configure.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
var gulp = require('gulp');
var async = require('async');
var path = require('path');
var pkg = require('./package.json');
var fs = require('fs');
var browserify = require('browserify');
var sh = require('shelljs');
var BootConfigLoader = require('loopback-boot').ConfigLoader;

exports.global = function(env, global) {
// routes
Expand Down Expand Up @@ -61,6 +63,105 @@ exports.local = function configure(env, global, local) {
}

exports.build = function(env, global, local, cb) {
async.waterfall([
function(next) {
async.parallel([
function(next) {
buildDataSources(env, next);
},
function(next) {
buildModels(env, next);
}
], function(err) { next(err); });
},
function(next) {
createBundle(env, global, next);
}
], cb);
};

function buildDataSources(env, cb) {
var dataSources = BootConfigLoader.loadDataSources(__dirname, env);
for (var name in dataSources) {
var cfg = dataSources[name];
var connector = cfg.connector;
if (connector !== 'memory' && connector !== 'remote') {
return cb(new Error(
'Datasource ' + name + ' uses unknown connector ' + connector + '.'));
}
}

var dsconfig = 'var loopback = require(\'loopback\');' +
'\nvar config;' +
'\nmodule.exports = function(app) {\n' +
' for (var name in config) {\n' +
' app.dataSource(name, config[name]);\n' +
' }\n'+
'};\n' +
'\n' +
'config = ' +
JSON.stringify(dataSources, null, 2) +
';\n';

fs.writeFile(
path.resolve(__dirname, 'build', 'datasources.js'),
dsconfig,
'utf-8',
cb);
}

function buildModels(env, cb) {
var models = BootConfigLoader.loadModels(path.resolve(__dirname, '..'), env);
var clientModels = require('./client.models.json');

var modelsFile = path.resolve(__dirname, 'build', 'models.js');
var modelsDir = path.resolve(__dirname, '..', 'models');

fs.readdir(modelsDir, function(err, files) {
if (err) return cb(err);

var code = 'var loopback = require(\'loopback\');\n' +
'var models, clientModels;\n\n' +
'module.exports = function(app) {\n' +
' for (var name in models) {\n' +
' app.model(name, models[name]);\n' +
' }\n\n';

files.forEach(function(f) {
f = path.resolve(modelsDir, f);
if (path.extname(f) !== '.js' || !fs.statSync(f).isFile()) return;
var relative = path.relative(path.dirname(modelsFile), f);
code += ' runExportedFn(app, require(' +
JSON.stringify(relative) + '));\n';
});

// It is important to create client models only after the shared models
// were fully initialized. Otherwise client models extending server models
// won't get static methods defined in models/*.js scripts.
code += '\n' +
' for (name in clientModels) {\n' +
' app.model(name, clientModels[name]);\n' +
' }\n';

//TODO(bajtos) Require and run all files in `client.models/*`

// end of the exported fn
code += '};\n';

code += '\nmodels = ' + JSON.stringify(models, null, 2) + ';\n';
code += '\nclientModels = ' + JSON.stringify(clientModels, null, 2) + ';\n';
code += '\nfunction runExportedFn(app, fn) {\n' +
' var executable = typeof fn === \'function\' &&\n' +
' !(fn.prototype instanceof loopback.Model);\n' +
' if (!executable) return;\n' +
' fn(app);\n' +
'}';

fs.writeFile(modelsFile, code, 'utf-8', cb);
});
}

function createBundle(env, global, cb) {
var b = browserify({basedir: __dirname});
b.add('./' + pkg.main);

Expand All @@ -76,7 +177,11 @@ exports.build = function(env, global, local, cb) {
}, 'uglifyify');
}

b.bundle().pipe(out);
b.bundle({
// TODO(bajtos) debug should be always true, the sourcemaps should be
// saved to a standalone file when !isDev(env)
debug: isDev(env)
}).pipe(out);

out.on('error', cb);
out.on('close', cb);
Expand Down
9 changes: 9 additions & 0 deletions html5/datasources.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"db": {
"connector": "remote"
},
"local": {
"connector": "memory",
"localStorage": "todo-db"
}
}
7 changes: 7 additions & 0 deletions html5/datasources.local.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
var LOCAL_CONFIG = require('local.config');

module.exports = {
db: {
url: LOCAL_CONFIG.serverInfo.url
}
};
37 changes: 37 additions & 0 deletions models.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"Todo": {
"options": {
"trackChanges": true,
"base": "DataModel"
},
"properties": {
"id": {
"id": true,
"type": "string"
},
"title": "string",
"completed": {
"type": "boolean",
"default": false
},
"created": {
"type": "number",
"//default": "//TODO: Date.now"
}
},
"dataSource": "db"
},
"user": {
"options": {
"base": "User"
},
"properties": {
"title": "string",
"done": {
"type": "boolean",
"default": false
}
},
"dataSource": "db"
}
}
2 changes: 0 additions & 2 deletions models/index.js

This file was deleted.

11 changes: 0 additions & 11 deletions models/package.json

This file was deleted.

Loading