1 import Promise from 'bluebird';
2 import { stat } from 'fs';
3 import * as fs from 'graceful-fs';
4 import path from 'path';
5 import { ChannelStateSizeError } from '../errors';
7 const readFileAsync = Promise.promisify(fs.readFile);
8 const writeFileAsync = Promise.promisify(fs.writeFile);
9 const readdirAsync = Promise.promisify(fs.readdir);
10 const statAsync = Promise.promisify(stat);
11 const SIZE_LIMIT = 1048576;
12 const CHANDUMP_DIR = path.resolve(__dirname, '..', '..', 'chandump');
14 export class FileStore {
15 filenameForChannel(channelName) {
16 return path.join(CHANDUMP_DIR, channelName);
19 load(id, channelName) {
20 const filename = this.filenameForChannel(channelName);
21 return statAsync(filename).then(stats => {
22 if (stats.size > SIZE_LIMIT) {
23 return Promise.reject(
24 new ChannelStateSizeError(
25 'Channel state file is too large',
33 return readFileAsync(filename);
35 }).then(fileContents => {
37 return JSON.parse(fileContents);
39 return Promise.reject(new Error('Channel state file is not valid JSON: ' + e));
44 async save(id, channelName, data) {
47 original = await this.load(id, channelName);
49 if (error.code !== 'ENOENT') {
56 Object.keys(data).forEach(key => {
57 original[key] = data[key];
60 const filename = this.filenameForChannel(channelName);
61 const fileContents = new Buffer(JSON.stringify(original), 'utf8');
62 if (fileContents.length > SIZE_LIMIT) {
63 throw new ChannelStateSizeError(
64 'Channel state size is too large',
67 actual: fileContents.length
72 return await writeFileAsync(filename, fileContents);
76 return readdirAsync(CHANDUMP_DIR);