diff --git a/index.js b/index.js index 0132dec..44aefde 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,7 @@ var level = require('level') var hypercore = require('hypercore') var createImportPipeline = require('./lib/import.js') +var feedOperations = require('./lib/feedOperations.js') module.exports = Jawn @@ -14,3 +15,8 @@ function Jawn (opts) { Jawn.prototype.createImportPipeline = function (opts) { return createImportPipeline(this, opts) } + +Jawn.prototype.createAppendableFeed = function (feedId, data) { + var feed = feedOperations.appendTo(this.core, feedId) + return feed +} diff --git a/lib/feedOperations.js b/lib/feedOperations.js new file mode 100644 index 0000000..c9765f0 --- /dev/null +++ b/lib/feedOperations.js @@ -0,0 +1,48 @@ + +module.exports.appendTo = appendableFeed + +function appendableFeed (core, feedId) { + var refFeed = core.get(feedId) + var newFeed = core.add() + var blockNumber = 0 + + var copyOriginal = function (resolve, reject) { + for (var i = 0; i < refFeed.blocks; i++) { + refFeed.get(i, function (err, block) { + if (err) { + console.log(err) + reject() + } + + newFeed.append(block, function () { + blockNumber++ + console.log('Copying block ' + blockNumber + '/' + newFeed.blocks + ' from original feed') + + if (blockNumber === refFeed.blocks) { + resolve() + } + }) + }) + } + } + + newFeed.append_p = function (data) { + return new Promise(function (resolve, reject) { + newFeed.append(data, resolve) + }) + } + + newFeed.finalize_p = function () { + return new Promise(function (resolve, reject) { + newFeed.finalize(resolve) + }) + } + + newFeed.initialize = function () { + return new Promise(function (resolve, reject) { + copyOriginal(resolve, reject) + }) + } + + return newFeed +} diff --git a/test/feedOperations.js b/test/feedOperations.js new file mode 100644 index 0000000..55125ae --- /dev/null +++ b/test/feedOperations.js @@ -0,0 +1,103 @@ +var test = require('tape') +var Jawn = require('../') +var memdb = require('memdb') +var feedOps = require('../lib/feedOperations.js') + +test('appendable feed', function (t) { + var jawn = freshJawn() + var feed = jawn.core.add() + + feed.pappend = function (data) { + return new Promise(function (resolve, reject) { + feed.append(data, resolve) + }) + } + + feed.pfinalize = function () { + return new Promise(function (resolve, reject) { + feed.finalize(resolve) + }) + } + + feed.pappend('hello').then(function () { + console.log('Appended') + return feed + }) + .then(function (feed) { + return feed.pfinalize() + }) + .then(function () { + console.log('Finalized with id ' + feed.id.toString('hex')) + var appfeed = feedOps.appendTo(jawn.core, feed.id) + appfeed.initialize().then(function () { + return appfeed.finalize_p() + }) + .then(function () { + t.same(appfeed.blocks, feed.blocks, 'testing') + t.end() + }) + }) +}) + +test('append to feed', function (t) { + var jawn = freshJawn() + var feed = jawn.core.add() + var expected = ['hello', 'there', 'goodbye'] + + storeDataInFeed(feed, ['hello', 'there']) + .then(function () { + console.log('Finalized with id ' + feed.id.toString('hex')) + + var appfeed = feedOps.appendTo(jawn.core, feed.id) + + appfeed.initialize().then(function () { + return appfeed.append_p('goodbye') + }) + .then(function () { + return appfeed.finalize_p() + }) + .then(function () { + t.same(appfeed.blocks, expected.length, 'Correct number of blocks') + for (var i = 0; i < appfeed.blocks; i++) { + appfeed.get(i, function (err, block) { + if (err) { + console.log(err) + } + t.same(block.toString(), expected.shift(), 'Feed block match') + if (expected.length === 0) { + t.end() + } + }) + } + }) + }) +}) + +function storeDataInFeed (feed, data) { + feed.pappend = function (data) { + return new Promise(function (resolve, reject) { + feed.append(data, resolve) + }) + } + + feed.pfinalize = function () { + return new Promise(function (resolve, reject) { + feed.finalize(resolve) + }) + } + + return new Promise(function (resolve, reject) { + feed.pappend(data).then(function () { + console.log('Appended') + return feed + }) + .then(function (feed) { + return feed.pfinalize() + }) + .then(resolve) + }) +} + +function freshJawn () { + return new Jawn({db: memdb()}) +} diff --git a/test/import.js b/test/import.js index 09a3c1b..4b16485 100644 --- a/test/import.js +++ b/test/import.js @@ -30,7 +30,7 @@ test('import json to jawn', function (t) { test('import csv to jawn', function (t) { var jawn = freshJawn() importFromFile(jawn, 'sample.csv', {'format': 'csv'}) - var importStream = importFromFile(jawn, 'sample.csv', {'format': 'csv'}, verify) + var importStream = importFromFile(jawn, 'sample.csv', {'format': 'csv'}) var expected = [ '{"Type of Experience":"Writing software in any programming language","Little/No Experience":"1","Some Experience":"5","Very Familiar":"4"}', '{"Type of Experience":"Frontend Web Development","Little/No Experience":"4","Some Experience":"3","Very Familiar":"3"}',