Skip to content

Commit 9dc0347

Browse files
committed
added: isomorphic
1 parent ca07522 commit 9dc0347

11 files changed

Lines changed: 168 additions & 27 deletions

File tree

changes.txt

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
11
BETA ======= 1.8.1
22

3+
- added: (IMPORTANT) ISOMORPHIC using
4+
- added: (IMPORTANT) new flag `mobile` (mobile routing), you can create a route to mobile device
5+
- added: readonly `req.mobile` -> returns `boolean`
6+
- added: new view tag: @{mobile} –> returns `boolean`
7+
- added: new view tag: @{isomorphic} –> returns `Object` with isomorphic objects
38
- added: `config['disable-clear-temporary-directory'] = false` (after start)
4-
- added: `config['default-timezone']`
5-
- added: `SchemaBuilderEntity.filter(custom, [model])`
6-
- added: `SchemaBuilderEntity.trim = true`(enable/disable trim strings (default: true))
7-
- added: cache for HTTP routing
9+
- added: `config['allow-compatibility'] = true` - a backward compatibility mode (in newest version - added: `config['default-timezone']`
10+
- added: `config['directory-isomorphic']`
811
- added: `config['directory-private']`
912
- added: `F.path.private([filename])`
13+
- added: `F.path.isomorphic([filename])`
1014
- added: `Controller.ping()` for WebSocket
1115
- added: `global.DB()` --> same as `global.DATABASE()`
12-
- added: `config['allow-compatibility'] = true` - a backward compatibility mode (in newest version 1.9 will be set to `false`)
16+
- added: `global.isomorphic` --> returns `framework.isomorphic` --> returns isomorphic objects
17+
- added: cache for HTTP routing
18+
1.9 will be set to `false`)
1319
- added: RegExp routing `F.route('/{/^\\d+$/}', ...)`
1420
- added: `F.responseBinary(req, res, contentType, buffer, [type], [download], [headers])`
21+
- added: `SchemaBuilderEntity.filter(custom, [model])`
22+
- added: `SchemaBuilderEntity.trim = true`(enable/disable trim strings (default: true))
1523
- added: `Date.prototype.toUTC([ticksOnly])`
1624
- added: `Date.prototype.extend()` -> extend current datetime about new date or time (more in documentation)
17-
- added: new flag `mobile` (mobile routing), you can create a route to mobile device
18-
- added: readonly `req.mobile` -> returns `boolean`
19-
- added: new view tag: @{mobile} –> returns `boolean`
2025
- added: `F.stats.request.mobile`, `F.stats.request.desktop`
21-
- added: `res.setHeader('Vary', 'Accept-Encoding, User-Agent')` for same url address and different devices (desktop vs mobile)
26+
- added: `res.setHeader('Vary', 'Accept-Encoding, User-Agent')` for same url addresses and different devices (desktop vs mobile)
2227
- added: binary - `total --translatecsv`
2328

2429
- updated: `F.route(url, ...)`, `F.websocket(url, ...)` --> URL can be function(url, req, [flags])

index.js

Lines changed: 131 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ function Framework() {
196196

197197
this.id = null;
198198
this.version = 1810;
199-
this.version_header = '1.8.1-30';
199+
this.version_header = '1.8.1-31';
200200

201201
var version = process.version.toString().replace('v', '').replace(/\./g, '');
202202
if (version[1] === '0')
@@ -232,6 +232,7 @@ function Framework() {
232232
'directory-workers': '/workers/',
233233
'directory-packages': '/packages/',
234234
'directory-private': '/private/',
235+
'directory-isomorphic': '/isomorphic/',
235236

236237
// all HTTP static request are routed to directory-public
237238
'static-url': '',
@@ -315,6 +316,7 @@ function Framework() {
315316
this.sources = {};
316317
this.controllers = {};
317318
this.dependencies = {};
319+
this.isomorphic = {};
318320
this.tests = [];
319321
this.errors = [];
320322
this.problems = [];
@@ -1119,10 +1121,11 @@ Framework.prototype.merge = function(url) {
11191121
}
11201122
}
11211123

1124+
url = self._version(url);
1125+
11221126
if (url[0] !== '/')
11231127
url = '/' + url;
11241128

1125-
url = self._version(url);
11261129
var filename = self.path.temp('merge-' + createTemporaryKey(url));
11271130
self.routes.merge[url] = { filename: filename, files: arr };
11281131
return self;
@@ -1149,6 +1152,12 @@ Framework.prototype.map = function(url, filename, filter) {
11491152

11501153
url = self._version(url);
11511154

1155+
if (filename[0] === '#') {
1156+
// isomorphic
1157+
self.routes.mapping[url] = filename;
1158+
return self;
1159+
}
1160+
11521161
if (filename[0] === '@') {
11531162
filename = self.path.package(filename.substring(1));
11541163
isPackage = true;
@@ -1636,6 +1645,14 @@ Framework.prototype.load = function() {
16361645
self.install('module', item.name, item.filename, undefined, undefined, undefined, true);
16371646
});
16381647

1648+
dir = path.join(directory, self.config['directory-isomorphic']);
1649+
arr = [];
1650+
listing(dir, 0, arr, '.js');
1651+
1652+
arr.forEach(function(item) {
1653+
self.install('isomorphic', item.name, item.filename, undefined, undefined, undefined, true);
1654+
});
1655+
16391656
dir = path.join(directory, self.config['directory-packages']);
16401657
arr = [];
16411658
listing(dir, 0, arr, '.package');
@@ -1927,6 +1944,59 @@ Framework.prototype.install = function(type, name, declaration, options, callbac
19271944
return self;
19281945
}
19291946

1947+
if (type === 'isomorphic') {
1948+
1949+
var content = '';
1950+
1951+
try {
1952+
1953+
if (useRequired) {
1954+
delete require.cache[require.resolve(declaration)];
1955+
obj = require(declaration);
1956+
content = fs.readFileSync(declaration).toString(ENCODING);
1957+
(function(name) {
1958+
setTimeout(function() {
1959+
delete require.cache[name];
1960+
}, 1000);
1961+
})(require.resolve(declaration));
1962+
}
1963+
else {
1964+
obj = typeof(declaration) === TYPE_FUNCTION ? eval('(' + declaration.toString() + ')()') : eval(declaration);
1965+
content = declaration.toString();
1966+
}
1967+
1968+
} catch (ex) {
1969+
1970+
self.error(ex, 'framework.install(\'' + type + '\')', null);
1971+
1972+
if (callback)
1973+
callback(ex);
1974+
1975+
return self;
1976+
}
1977+
1978+
if (typeof(obj.id) === STRING)
1979+
name = obj.id;
1980+
else if (typeof(obj.name) === STRING)
1981+
name = obj.name;
1982+
1983+
if (obj.url)
1984+
framework.map(obj.url, '#' + name);
1985+
1986+
framework.temporary.other['#isomorphic_' + name] = framework_internal.compile_javascript(content, '#' + name);
1987+
framework.isomorphic[name] = obj;
1988+
1989+
if (callback)
1990+
callback(null);
1991+
1992+
setTimeout(function() {
1993+
self.emit(type + '#' + name);
1994+
self.emit('install', type, name);
1995+
}, 500);
1996+
1997+
return self;
1998+
}
1999+
19302000
if (type === 'model' || type === 'source') {
19312001

19322002
_controller = '';
@@ -2261,6 +2331,15 @@ Framework.prototype.uninstall = function(type, name, options, skipEmit) {
22612331
return self;
22622332
}
22632333

2334+
if (type === 'isomorphic') {
2335+
var obj = self.isomorphic[name];
2336+
if (obj.url)
2337+
delete self.routes.mapping[self._version(obj.url)];
2338+
delete self.isomorphic[name];
2339+
self.emit('uninstall', type, name);
2340+
return self;
2341+
}
2342+
22642343
if (type === 'middleware') {
22652344

22662345
if (!self.routes.middleware[name])
@@ -2584,6 +2663,7 @@ Framework.prototype.usage = function(detailed) {
25842663
var connections = Object.keys(self.connections);
25852664
var workers = Object.keys(self.workers);
25862665
var modules = Object.keys(self.modules);
2666+
var isomorphic = Object.keys(self.isomorphic);
25872667
var models = Object.keys(self.models);
25882668
var schedules = Object.keys(self.schedules);
25892669
var helpers = Object.keys(self.helpers);
@@ -2616,6 +2696,7 @@ Framework.prototype.usage = function(detailed) {
26162696
resource: resources.length,
26172697
controller: controllers.length,
26182698
module: modules.length,
2699+
isomorphic: isomorphic.length,
26192700
cache: cache.length,
26202701
worker: workers.length,
26212702
connection: connections.length,
@@ -2851,6 +2932,12 @@ Framework.prototype.compileMerge = function(uri, key, extension, callback) {
28512932
return;
28522933
}
28532934

2935+
if (filename[0] === '#') {
2936+
writer.write(prepare_isomorphic(filename.substring(1)), ENCODING);
2937+
next();
2938+
return;
2939+
}
2940+
28542941
if (filename[0] !== '~') {
28552942
var tmp = self.path.public(filename);
28562943
if (self.isVirtualDirectory && !fs.existsSync(tmp))
@@ -2990,12 +3077,35 @@ Framework.prototype.responseStatic = function(req, res, done) {
29903077
filename = self.onMapping(name, framework.path.public($decodeURIComponent(name)));
29913078

29923079
if (!isResize) {
2993-
self.responseFile(req, res, filename, undefined, undefined, done);
3080+
3081+
// is isomorphic?
3082+
if (filename[0] !== '#') {
3083+
self.responseFile(req, res, filename, undefined, undefined, done);
3084+
return self;
3085+
}
3086+
3087+
var key = filename.substring(1);
3088+
var iso = framework.isomorphic[key];
3089+
3090+
if (!iso) {
3091+
self.response404(req, res);
3092+
return;
3093+
}
3094+
3095+
var etag = framework_utils.etag(filename, (iso.version || '') + '-' + (self.config['etag-version'] || ''));
3096+
if (RELEASE && framework.notModified(req, res, etag))
3097+
return;
3098+
3099+
// isomorphic
3100+
var headers = {};
3101+
headers['Etag'] = etag;
3102+
headers['Expires'] = new Date().add('M', 3);
3103+
headers[RESPONSE_HEADER_CACHECONTROL] = 'public, max-age=86400';
3104+
framework.responseContent(req, res, 200, prepare_isomorphic(key), 'text/javascript', true, headers);
29943105
return self;
29953106
}
29963107

29973108
var method = resizer.cache ? self.responseImage : self.responseImageWithoutCache;
2998-
29993109
method.call(self, req, res, filename, function(image) {
30003110

30013111
if (resizer.width || resizer.height) {
@@ -4200,6 +4310,7 @@ Framework.prototype.responseContent = function(req, res, code, contentBody, cont
42004310

42014311
if (res.success || res.headersSent)
42024312
return self;
4313+
42034314
req.clear(true);
42044315
res.success = true;
42054316

@@ -4339,6 +4450,7 @@ Framework.prototype.initialize = function(http, debug, options) {
43394450

43404451
global.DEBUG = debug;
43414452
global.RELEASE = !debug;
4453+
global.isomorphic = framework.isomorphic;
43424454

43434455
self._configure();
43444456
self._configure_versions();
@@ -6052,6 +6164,10 @@ Framework.prototype._configure_versions = function(content) {
60526164
return self;
60536165
}
60546166

6167+
var arr = content.split('\n');
6168+
content = '';
6169+
for (var i = 0, length = arr.length; i < length; i++)
6170+
content += (arr[i][0] === '/' ? '' : '/') + arr[i] + '\n';
60556171
self.versions = content.parseConfig();
60566172
return self;
60576173
};
@@ -6308,7 +6424,7 @@ Framework.prototype.routeStatic = function(name) {
63086424
return {String}
63096425
*/
63106426
Framework.prototype._routeStatic = function(name, directory) {
6311-
return this._version(directory + this._version(name));
6427+
return this._version((name[0] === '/' ? '' : directory) + this._version(name));
63126428
};
63136429

63146430
/*
@@ -6318,13 +6434,10 @@ Framework.prototype._routeStatic = function(name, directory) {
63186434
*/
63196435
Framework.prototype._version = function(name) {
63206436
var self = this;
6321-
63226437
if (self.versions !== null)
63236438
name = self.versions[name] || name;
6324-
63256439
if (self.onVersion !== null)
63266440
name = self.onVersion(name) || name;
6327-
63286441
return name;
63296442
};
63306443

@@ -7157,15 +7270,16 @@ FrameworkPath.prototype.public = function(filename) {
71577270
return utils.combine(framework.config['directory-public'], filename || '').replace(/\\/g, '/');
71587271
};
71597272

7160-
/*
7161-
@filename {String} :: optional
7162-
return {String}
7163-
*/
71647273
FrameworkPath.prototype.private = function(filename) {
71657274
framework._verify_directory('private');
71667275
return utils.combine(framework.config['directory-private'], filename || '').replace(/\\/g, '/');
71677276
};
71687277

7278+
FrameworkPath.prototype.isomorphic = function(filename) {
7279+
framework._verify_directory('isomorphic');
7280+
return utils.combine(framework.config['directory-isomorphic'], filename || '').replace(/\\/g, '/');
7281+
};
7282+
71697283
/*
71707284
@filename {String} :: optional
71717285
return {String}
@@ -13054,4 +13168,8 @@ process.on('message', function(msg, h) {
1305413168
}
1305513169

1305613170
framework.emit('message', msg, h);
13057-
});
13171+
});
13172+
13173+
function prepare_isomorphic(name) {
13174+
return 'if(window["isomorphic"]===undefined)window.isomorphic={};isomorphic["' + name + '"]=(function(framework,F,U,utils,Utils){var exports={};' + (framework.temporary.other['#isomorphic_' + name] || '') + ';return exports;})(null,null,null,null,null)';
13175+
}

internal.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1921,6 +1921,10 @@ function view_prepare(command, dynamicCommand, functions) {
19211921
return '$STRING(' + command + ').encode()';
19221922
case '!cookie':
19231923
return '$STRING(' + command + ')';
1924+
case 'isomorphic':
1925+
return '$STRING(' + command + ').encode()';
1926+
case '!isomorphic':
1927+
return '$STRING(' + command + ')';
19241928

19251929
case 'model':
19261930
case 'repository':

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,5 @@
6565
"scripts": {
6666
"test": "echo \"Error: no test specified\" && exit 1"
6767
},
68-
"version": "1.8.1-30"
68+
"version": "1.8.1-31"
6969
}

test/controllers/default.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ exports.install = function() {
8585
framework.route('/put/xml/', plain_put_xml, ['xml', 'put']);
8686

8787
framework.route('/upload/', plain_upload, ['upload']);
88+
framework.route('/index/', 'homepage');
8889

8990
framework.file('Resizing of images', function(req, res) {
9091
return req.url.indexOf('.jpg') !== -1;

test/isomorphic/test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
exports.id = 'test';
2+
exports.url = 'isomorphic.js';
3+
4+
exports.price = function(count) {
5+
return count * 1.20;
6+
};

test/test-framework-debug.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,8 @@ function test_routing(next) {
551551
});
552552

553553
async.await('merge package', function(complete) {
554-
utils.request(url + 'mergepackage.js', [], function(error, data, code, headers) {
554+
// mergepackage2 is from versions
555+
utils.request(url + 'mergepackage2.js', [], function(error, data, code, headers) {
555556
if (error)
556557
throw error;
557558
assert(data === 'console.log(\'test\');', 'merge package');

test/test-framework-test.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,8 @@ mem.on('stats', function(info) {
1919
});
2020
*/
2121

22+
framework.on('load', function() {
23+
framework.merge('/mergepackage.js', '@testpackage/test.js');
24+
});
25+
2226
framework.http('debug', { port: 8001 });

test/versions

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
default.js : default101.js
1+
/default.js : default101.js
2+
mergepackage.js : mergepackage2.js

test/views/homepage.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
<div>Hello World!</div>
1+
<div>Hello World!</div>
2+
<div>Price: @{isomorphic.test.price(10)}</div>

0 commit comments

Comments
 (0)