Skip to content

Commit

Permalink
build module for not rely on babel and harmony
Browse files Browse the repository at this point in the history
  • Loading branch information
lzztt committed Sep 10, 2016
1 parent ebcb596 commit dd23273
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 2 deletions.
34 changes: 34 additions & 0 deletions dist/memory_store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use strict';

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }

module.exports = class MemoryStore {
constructor() {
this.sessions = {};
}

get(sid) {
var _this = this;

return _asyncToGenerator(function* () {
return _this.sessions[sid];
})();
}

set(sid, val, ttl) {
var _this2 = this;

return _asyncToGenerator(function* () {
// eslint-disable-line no-unused-vars
_this2.sessions[sid] = val;
})();
}

destroy(sid) {
var _this3 = this;

return _asyncToGenerator(function* () {
delete _this3.sessions[sid];
})();
}
};
104 changes: 104 additions & 0 deletions dist/session.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
'use strict';

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }

const uid = require('uid-safe');
const deepEqual = require('deep-equal');
const Store = require('./store');
const MemoryStore = require('./memory_store');

const ONE_DAY = 24 * 3600 * 1000; // one day in milliseconds

const deleteSession = (ctx, key, ckOption, store, sid) => {
const deleteOption = Object.assign({}, ckOption);
delete deleteOption.maxAge;
ctx.cookies.set(key, null, deleteOption);
store.destroy(`${ key }:${ sid }`);
};

const saveSession = (ctx, key, ckOption, store, sid) => {
const ttl = ckOption.maxAge > 0 ? ckOption.maxAge : ONE_DAY;
ctx.cookies.set(key, sid, ckOption);
store.set(`${ key }:${ sid }`, ctx.session, ttl);
};

module.exports = options => {
const opt = options || {};
const key = opt.key || 'koa:sess';
const store = new Store(opt.store || new MemoryStore());
const cookie = opt.cookie || {};

return (() => {
var _ref = _asyncToGenerator(function* (ctx, next) {
// setup cookie options
const ckOption = {
maxAge: 0, // default to use session cookie
path: '/',
secure: false,
httpOnly: true
};
Object.assign(ckOption, cookie);
Object.assign(ckOption, {
overwrite: true, // overwrite previous session cookie changes
signed: false });
if (!(ckOption.maxAge >= 0)) ckOption.maxAge = 0;

// initialize session id and data
const cookieSid = ctx.cookies.get(key);

let sid = cookieSid;
if (!sid) {
sid = uid.sync(24);
ctx.session = {};
} else {
ctx.session = yield store.get(`${ key }:${ sid }`);
if (!ctx.session || typeof ctx.session !== 'object') {
ctx.session = {};
}
}

const sessionClone = JSON.parse(JSON.stringify(ctx.session));

// expose session handler to ctx
ctx.sessionHandler = {
getId: function () {
return sid;
},
regenerateId: function () {
sid = uid.sync(24);
},
setMaxAge: function (ms) {
ckOption.maxAge = ms >= 0 ? ms : 0;
}
};

yield next();

const sessionHasData = ctx.session && Object.keys(ctx.session).length;

if (sid !== cookieSid) {
// a new session id
// clean old session
if (cookieSid) deleteSession(ctx, key, ckOption, store, cookieSid);

// save new session
if (sessionHasData) saveSession(ctx, key, ckOption, store, sid);
} else {
// an existing session
// data has not been changed
if (deepEqual(ctx.session, sessionClone)) return;

// update session data
if (sessionHasData) {
saveSession(ctx, key, ckOption, store, sid);
} else {
deleteSession(ctx, key, ckOption, store, sid);
}
}
});

return function (_x, _x2) {
return _ref.apply(this, arguments);
};
})();
};
21 changes: 21 additions & 0 deletions dist/store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict';

const co = require('co');

module.exports = class Store {
constructor(store) {
this.store = store;
}

get(sid) {
return co(this.store.get(sid));
}

set(sid, val, ttl) {
return co(this.store.set(sid, val, ttl));
}

destroy(sid) {
return co(this.store.destroy(sid));
}
};
23 changes: 23 additions & 0 deletions example/counter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const Koa = require('koa')
const session = require('..')
const redisStore = require('koa-redis')

const app = new Koa()

app.use(session({
store: redisStore(),
}))

// update session count
app.use(async (ctx, next) => {
ctx.session.count = ctx.session.count || 0
if (ctx.path === '/add') ctx.session.count++
await next()
})

// populate response body
app.use(ctx => {
ctx.body = ctx.sessionHandler.getId() + ' : ' + ctx.session.count
})

app.listen(3000)
5 changes: 5 additions & 0 deletions example/run.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require('babel-register')({
plugins: ['transform-async-to-generator'],
})

require('./counter.js')
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
"name": "koa-session-minimal",
"version": "1.0.1",
"description": "Minimal implementation of session middleware for Koa 2. Inspired by and compatible with koa-generic-session",
"main": "lib/session.js",
"main": "dist/session.js",
"scripts": {
"lint": "eslint lib test",
"test": "mocha --harmony test"
"test": "mocha --harmony test",
"dist": "babel lib -d dist"
},
"repository": {
"type": "git",
Expand All @@ -27,6 +28,7 @@
"uid-safe": "^2.1.2"
},
"devDependencies": {
"babel-cli": "^6.14.0",
"babel-eslint": "^6.1.2",
"babel-plugin-transform-async-to-generator": "^6.8.0",
"babel-register": "^6.14.0",
Expand All @@ -35,6 +37,7 @@
"eslint-config-airbnb-base": "^5.0.3",
"eslint-plugin-import": "^1.14.0",
"koa": "^2.0.0-alpha.6",
"koa-redis": "^2.1.2",
"mocha": "^3.0.2",
"supertest": "^2.0.0"
}
Expand Down

0 comments on commit dd23273

Please sign in to comment.