Skip to content

Commit

Permalink
Adding a pure apply function
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasjm committed Jun 16, 2018
1 parent 9df44f0 commit e2f3976
Show file tree
Hide file tree
Showing 3 changed files with 257 additions and 3 deletions.
128 changes: 126 additions & 2 deletions lib/json0.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
Note: This is being made obsolete. It will soon be replaced by the JSON2 type.
*/

const update = require("immutability-helper");

/**
* UTILITY FUNCTIONS
*/
Expand Down Expand Up @@ -125,6 +127,17 @@ function convertFromText(c) {
c.o = [o];
}

function convertFromTextPure(c) {
var newC = {};
newC.t = 'text0';
var o = {p: c.p[c.p.length - 1]};
if (c.si != null) o.i = c.si;
if (c.sd != null) o.d = c.sd;
newC.o = [o];
newC.p = c.p.slice(0, c.p.length - 1);
return newC;
}

function convertToText(c) {
c.p.push(c.o[0].p);
if (c.o[0].i != null) c.si = c.o[0].i;
Expand Down Expand Up @@ -188,7 +201,7 @@ json.apply = function(snapshot, op) {
// List insert
else if (c.li !== void 0) {
json.checkList(elem);
elem.splice(key,0, c.li);
elem.splice(key, 0, c.li);
}

// List delete
Expand Down Expand Up @@ -234,6 +247,118 @@ json.apply = function(snapshot, op) {
return container.data;
};

json.applyPure = function(snapshot, op) {
var container = {
data: snapshot
};

for (var i = 0; i < op.length; i++) {
var c = op[i];

// convert old string ops to use subtype for backwards compatibility
if (c.si != null || c.sd != null) {
c = convertFromTextPure(c);
}

// get the part of the structure we care about
var parent = null;
var parentKey = null;
var elem = container;
var key = 'data';
for (var j = 0; j < c.p.length; j++) {
var p = c.p[j];

parent = elem;
parentKey = key;
elem = elem[key];
key = p;

if (parent == null)
throw new Error('Path invalid');
}

// build an update command
var command = {};
var wrapper = command;
for (var j = c.p.length - 2; j >= 0; j--) {
var newWrapper = {};
newWrapper[c.p[j]] = wrapper;
wrapper = newWrapper;
}

// handle subtype ops
if (c.t && c.o !== void 0 && subtypes[c.t]) {
let newValue = subtypes[c.t].apply(elem[key], c.o);
if (c.p.length === 0) command["$set"] = newValue;
else command[key] = {"$set": newValue};
} else if (c.na !== void 0) {
// Number add
if (typeof elem[key] != 'number')
throw new Error('Referenced element not a number');

if (c.p.length === 0) command["$set"] = elem[key] + c.na;
else command[key] = {"$set": elem[key] + c.na};
}

// List replace
else if (c.li !== void 0 && c.ld !== void 0) {
json.checkList(elem);
// Should check the list element matches c.ld

if (c.p.length === 0) command["$set"] = c.li;
else command[key] = {"$set": c.li};
}

// List insert
else if (c.li !== void 0) {
json.checkList(elem);
command["$splice"] = [[key, 0, c.li]];
}

// List delete
else if (c.ld !== void 0) {
json.checkList(elem);
// Should check the list element matches c.ld here too.
command["$splice"] = [[key, 1]];
}

// List move
else if (c.lm !== void 0) {
json.checkList(elem);
if (c.lm != key) {
var e = elem[key];
// Remove it and insert it back.
command["$splice"] = [[key, 1], [c.lm, 0, e]];
}
}

// Object insert / replace
else if (c.oi !== void 0) {
json.checkObj(elem);

// Should check that elem[key] == c.od
if (c.p.length === 0) command["$set"] = c.oi;
else command[key] = {$set: c.oi};
}

// Object delete
else if (c.od !== void 0) {
json.checkObj(elem);

// Should check that elem[key] == c.od
command["$unset"] = [key];
}

else {
throw new Error('invalid / missing instruction in op');
}

container.data = update(container.data, wrapper);
}

return container.data;
};

// Helper to break an operation up into a bunch of small ops.
json.shatter = function(op) {
var results = [];
Expand Down Expand Up @@ -660,4 +785,3 @@ var text = require('./text0');

json.registerSubtype(text);
module.exports = json;

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
"directories": {
"test": "test"
},
"dependencies": {},
"dependencies": {
"immutability-helper": "^2.7.0"
},
"devDependencies": {
"ot-fuzzer": "^1.0.0",
"mocha": "^1.20.1",
Expand Down
128 changes: 128 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


coffee-script@^1.7.1:
version "1.12.7"
resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.12.7.tgz#c05dae0cb79591d05b3070a8433a98c9a89ccc53"

commander@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06"

commander@2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873"

debug@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.0.0.tgz#89bd9df6732b51256bc6705342bba02ed12131ef"
dependencies:
ms "0.6.2"

diff@1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/diff/-/diff-1.0.8.tgz#343276308ec991b7bc82267ed55bc1411f971666"

escape-string-regexp@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1"

glob@3.2.3:
version "3.2.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.3.tgz#e313eeb249c7affaa5c475286b0e115b59839467"
dependencies:
graceful-fs "~2.0.0"
inherits "2"
minimatch "~0.2.11"

graceful-fs@~2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-2.0.3.tgz#7cd2cdb228a4a3f36e95efa6cc142de7d1a136d0"

growl@1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/growl/-/growl-1.8.1.tgz#4b2dec8d907e93db336624dcec0183502f8c9428"

immutability-helper@^2.7.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/immutability-helper/-/immutability-helper-2.7.0.tgz#4ea9916cc8f45142ec3e3f0fce75fa5d66fa1b38"
dependencies:
invariant "^2.2.0"

inherits@2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"

invariant@^2.2.0:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
dependencies:
loose-envify "^1.0.0"

jade@0.26.3:
version "0.26.3"
resolved "https://registry.yarnpkg.com/jade/-/jade-0.26.3.tgz#8f10d7977d8d79f2f6ff862a81b0513ccb25686c"
dependencies:
commander "0.6.1"
mkdirp "0.3.0"

js-tokens@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"

loose-envify@^1.0.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
dependencies:
js-tokens "^3.0.0"

lru-cache@2:
version "2.7.3"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952"

minimatch@~0.2.11:
version "0.2.14"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a"
dependencies:
lru-cache "2"
sigmund "~1.0.0"

minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"

mkdirp@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e"

mkdirp@0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.0.tgz#1d73076a6df986cd9344e15e71fcc05a4c9abf12"
dependencies:
minimist "0.0.8"

mocha@^1.20.1:
version "1.21.5"
resolved "https://registry.yarnpkg.com/mocha/-/mocha-1.21.5.tgz#7c58b09174df976e434a23b1e8d639873fc529e9"
dependencies:
commander "2.3.0"
debug "2.0.0"
diff "1.0.8"
escape-string-regexp "1.0.2"
glob "3.2.3"
growl "1.8.1"
jade "0.26.3"
mkdirp "0.5.0"

ms@0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-0.6.2.tgz#d89c2124c6fdc1353d65a8b77bf1aac4b193708c"

ot-fuzzer@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/ot-fuzzer/-/ot-fuzzer-1.1.0.tgz#b556a799117ceeb458794ef376f34b985f62dc8d"

sigmund@~1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590"

0 comments on commit e2f3976

Please sign in to comment.