Comparing version 1.0.1-preview.0 to 1.0.1-preview.1
@@ -55,4 +55,4 @@ const { Map, List } = require('immutable') | ||
function makePatch(state, diffs, request, isIncremental) { | ||
const clock = state.getIn(['opSet', 'states']).map(seqs => seqs.size).toJSON() | ||
const deps = state.getIn(['opSet', 'deps']).toJSON().sort() | ||
const clock = state.getIn(['opSet', 'states']).map(seqs => seqs.size).toObject() | ||
const deps = state.getIn(['opSet', 'deps']).toArray().sort() | ||
const maxOp = state.getIn(['opSet', 'maxOp'], 0) | ||
@@ -59,0 +59,0 @@ const pendingChanges = OpSet.getMissingDeps(state.get('opSet')).length |
@@ -496,3 +496,3 @@ const { Map, List, Set, fromJS } = require('immutable') | ||
function getHeads(opSet) { | ||
return opSet.get('deps').toJSON().sort() | ||
return opSet.get('deps').toArray().sort() | ||
} | ||
@@ -522,3 +522,3 @@ | ||
if (haveDeps.isEmpty()) { | ||
return opSet.get('history').toJSON().map(hash => getChangeByHash(opSet, hash)) | ||
return opSet.get('history').toArray().map(hash => getChangeByHash(opSet, hash)) | ||
} | ||
@@ -569,3 +569,3 @@ | ||
.map(hash => getChangeByHash(opSet, hash)) | ||
.toJSON() | ||
.toArray() | ||
} | ||
@@ -572,0 +572,0 @@ |
@@ -433,3 +433,3 @@ /** | ||
let { sharedHeads, lastSentHeads } = oldSyncState, patch = null | ||
let { sharedHeads, lastSentHeads, sentHashes } = oldSyncState, patch = null | ||
const message = decodeSyncMessage(binaryMessage) | ||
@@ -457,2 +457,7 @@ const beforeHeads = Backend.getHeads(backend) | ||
sharedHeads = message.heads | ||
// If the remote peer has lost all its data, reset our state to perform a full resync | ||
if (message.heads.length === 0) { | ||
lastSentHeads = [] | ||
sentHashes = [] | ||
} | ||
} else { | ||
@@ -472,3 +477,3 @@ // If some remote heads are unknown to us, we add all the remote heads we know to | ||
theirNeed: message.need, | ||
sentHashes: oldSyncState.sentHashes, | ||
sentHashes | ||
} | ||
@@ -475,0 +480,0 @@ return [backend, syncState, patch] |
{ | ||
"name": "automerge", | ||
"version": "1.0.1-preview.0", | ||
"version": "1.0.1-preview.1", | ||
"description": "Data structures for building collaborative applications", | ||
@@ -57,3 +57,2 @@ "main": "dist/automerge.js", | ||
"webpack": "^5.24.0", | ||
"webpack-bundle-analyzer": "^4.4.0", | ||
"webpack-cli": "^4.5.0" | ||
@@ -60,0 +59,0 @@ }, |
@@ -847,3 +847,3 @@ /* eslint-disable no-unused-vars */ | ||
diffs: {objectId: '_root', type: 'map', props: { | ||
counter: {[`1@${actor}`]: {value: 3, datatype: 'counter'}} | ||
counter: {[`1@${actor}`]: {type: 'value', value: 3, datatype: 'counter'}} | ||
}} | ||
@@ -850,0 +850,0 @@ }) |
@@ -366,2 +366,47 @@ const assert = require('assert') | ||
}) | ||
it('should resync after one node experiences data loss without disconnecting', () => { | ||
let n1 = Automerge.init('01234567'), n2 = Automerge.init('89abcdef') | ||
let s1 = initSyncState(), s2 = initSyncState() | ||
// n1 makes three changes, which we sync to n2 | ||
for (let i = 0; i < 3; i++) n1 = Automerge.change(n1, {time: 0}, doc => doc.x = i) | ||
;[n1, n2, s1, s2] = sync(n1, n2, s1, s2) | ||
assert.deepStrictEqual(getHeads(n1), getHeads(n2)) | ||
assert.deepStrictEqual(n1, n2) | ||
let n2AfterDataLoss = Automerge.init('89abcdef') | ||
// "n2" now has no data, but n1 still thinks it does. Note we don't do | ||
// decodeSyncState(encodeSyncState(s1)) in order to simulate data loss without disconnecting | ||
;[n1, n2, s1, s2] = sync(n1, n2AfterDataLoss, s1, initSyncState()) | ||
assert.deepStrictEqual(getHeads(n1), getHeads(n2)) | ||
assert.deepStrictEqual(n1, n2) | ||
}) | ||
it('should handle changes concurrent to the last sync heads', () => { | ||
let n1 = Automerge.init('01234567'), n2 = Automerge.init('89abcdef'), n3 = Automerge.init('fedcba98') | ||
let s12 = initSyncState(), s21 = initSyncState(), s23 = initSyncState(), s32 = initSyncState() | ||
// Change 1 is known to all three nodes | ||
n1 = Automerge.change(n1, {time: 0}, doc => doc.x = 1) | ||
;[n1, n2, s12, s21] = sync(n1, n2, s12, s21) | ||
;[n2, n3, s23, s32] = sync(n2, n3, s23, s32) | ||
// Change 2 is known to n1 and n2 | ||
n1 = Automerge.change(n1, {time: 0}, doc => doc.x = 2) | ||
;[n1, n2, s12, s21] = sync(n1, n2, s12, s21) | ||
// Each of the three nodes makes one change (changes 3, 4, 5) | ||
n1 = Automerge.change(n1, {time: 0}, doc => doc.x = 3) | ||
n2 = Automerge.change(n2, {time: 0}, doc => doc.x = 4) | ||
n3 = Automerge.change(n3, {time: 0}, doc => doc.x = 5) | ||
// Sync change 5 from n3 to n2, then sync n1 and n2 | ||
;[n2, n3, s23, s32] = sync(n2, n3, s23, s32) | ||
;[n1, n2, s12, s21] = sync(n1, n2, s12, s21) | ||
assert.deepStrictEqual(getHeads(n1), getHeads(n2)) | ||
assert.deepStrictEqual(n1, n2) | ||
}) | ||
}) | ||
@@ -368,0 +413,0 @@ |
@@ -1138,2 +1138,16 @@ const assert = require('assert') | ||
it('should reload a document containing deflated columns', () => { | ||
// In this test, the keyCtr column is long enough for deflate compression to kick in, but the | ||
// keyStr column is short. Thus, the deflate bit gets set for keyCtr but not for keyStr. | ||
// When checking whether the columns appear in ascending order, we must ignore the deflate bit. | ||
let doc = Automerge.change(Automerge.init(), doc => { | ||
doc.list = [] | ||
for (let i = 0; i < 200; i++) doc.list.insertAt(Math.floor(Math.random() * i), 'a') | ||
}) | ||
Automerge.load(Automerge.save(doc)) | ||
let expected = [] | ||
for (let i = 0; i < 200; i++) expected.push('a') | ||
assert.deepStrictEqual(doc, {list: expected}) | ||
}) | ||
it('should call patchCallback if supplied', () => { | ||
@@ -1140,0 +1154,0 @@ const s1 = Automerge.change(Automerge.init(), doc => doc.birds = ['Goldfinch']) |
@@ -55,3 +55,3 @@ /* eslint-disable no-unused-vars */ | ||
diffs: {objectId: '_root', type: 'map', props: { | ||
bird: {[`1@${actor}`]: {value: 'magpie'}} | ||
bird: {[`1@${actor}`]: {type: 'value', value: 'magpie'}} | ||
}} | ||
@@ -93,3 +93,3 @@ }) | ||
diffs: {objectId: '_root', type: 'map', props: {birds: {[`1@${actor}`]: { | ||
objectId: `1@${actor}`, type: 'map', props: {wrens: {[`2@${actor}`]: {value: 3}}} | ||
objectId: `1@${actor}`, type: 'map', props: {wrens: {[`2@${actor}`]: {type: 'value', value: 3}}} | ||
}}}} | ||
@@ -111,5 +111,6 @@ }) | ||
diffs: {objectId: '_root', type: 'map', props: {birds: {[`1@${actor}`]: { | ||
objectId: `1@${actor}`, type: 'list', | ||
edits: [{action: 'insert', index: 0, elemId: `2@${actor}`}], | ||
props: {0: {[`2@${actor}`]: {value: 'chaffinch'}}} | ||
objectId: `1@${actor}`, type: 'list', edits: [ | ||
{action: 'insert', index: 0, elemId: `2@${actor}`, opId: `2@${actor}`, | ||
value: {type: 'value', value: 'chaffinch'}} | ||
] | ||
}}}} | ||
@@ -137,4 +138,4 @@ }) | ||
diffs: {objectId: '_root', type: 'map', props: {birds: {[`1@${actor}`]: { | ||
objectId: `1@${actor}`, type: 'list', props: {}, | ||
edits: [{action: 'remove', index: 0}] | ||
objectId: `1@${actor}`, type: 'list', | ||
edits: [{action: 'remove', index: 0, count: 1}] | ||
}}}} | ||
@@ -159,11 +160,4 @@ }) | ||
objectId: `1@${actor}`, type: 'text', edits: [ | ||
{action: 'insert', index: 0, elemId: `2@${actor}`}, | ||
{action: 'insert', index: 1, elemId: `3@${actor}`}, | ||
{action: 'insert', index: 2, elemId: `4@${actor}`} | ||
{action: 'multi-insert', index: 0, elemId: `2@${actor}`, values: ['a', 'b', 'c']}, | ||
], | ||
props: { | ||
0: {[`2@${actor}`]: {value: 'a'}}, | ||
1: {[`3@${actor}`]: {value: 'b'}}, | ||
2: {[`4@${actor}`]: {value: 'c'}}, | ||
} | ||
}}}} | ||
@@ -189,4 +183,4 @@ }) | ||
objectId: `2@${actor}`, type: 'map', props: { | ||
species: {[`3@${actor}`]: {value: 'Chaffinch'}}, | ||
colour: {[`4@${actor}`]: {value: 'brown'}} | ||
species: {[`3@${actor}`]: {type: 'value', value: 'Chaffinch'}}, | ||
colour: {[`4@${actor}`]: {type: 'value', value: 'brown'}} | ||
} | ||
@@ -222,3 +216,3 @@ }}} | ||
diffs: {objectId: '_root', type: 'map', props: { | ||
counter: {[`1@${actor}`]: {value: 3, datatype: 'counter'}} | ||
counter: {[`1@${actor}`]: {type: 'value', value: 3, datatype: 'counter'}} | ||
}} | ||
@@ -239,3 +233,3 @@ }) | ||
diffs: {objectId: '_root', type: 'map', props: { | ||
now: {[`1@${actor}`]: {value: now.getTime(), datatype: 'timestamp'}} | ||
now: {[`1@${actor}`]: {type: 'value', value: now.getTime(), datatype: 'timestamp'}} | ||
}} | ||
@@ -258,3 +252,3 @@ }) | ||
diffs: {objectId: '_root', type: 'map', props: { | ||
longString: {[`1@${actor}`]: {value: longString}} | ||
longString: {[`1@${actor}`]: {type: 'value', value: longString}} | ||
}} | ||
@@ -277,3 +271,3 @@ }) | ||
diffs: {objectId: '_root', type: 'map', props: { | ||
bird: {[`1@${actor}`]: {value: 'magpie'}} | ||
bird: {[`1@${actor}`]: {type: 'value', value: 'magpie'}} | ||
}} | ||
@@ -297,3 +291,3 @@ }) | ||
diffs: {objectId: '_root', type: 'map', props: { | ||
longString: {[`1@${actor}`]: {value: longString}} | ||
longString: {[`1@${actor}`]: {type: 'value', value: longString}} | ||
}} | ||
@@ -300,0 +294,0 @@ }) |
const path = require('path') | ||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin | ||
@@ -15,8 +14,2 @@ module.exports = { | ||
}, | ||
plugins: [ | ||
new BundleAnalyzerPlugin({ | ||
analyzerMode: 'static', | ||
openAnalyzer: false, | ||
}), | ||
], | ||
devtool: 'source-map', | ||
@@ -23,0 +16,0 @@ module: { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
25
40306
2967996
62