automerge / automerge-classic

A JSON-like data structure (a CRDT) that can be modified concurrently by different users, and merged again automatically.
http://automerge.org/
MIT License
14.75k stars 466 forks source link

ApplyChanges error: TypeError: Cannot read property 'backendState' of undefined #391

Closed fabiobosisio closed 3 years ago

fabiobosisio commented 3 years ago

Hi

I'm trying to do a apply changes POC but I'm facing a problem:

I got the TEMP file using JSON.stringify(Automerge.getChanges... and I'm trying to apply this chamges on the original file CONTENT

CONTENT:["~#iL",[["~#iM",["ops",["^0",[["^1",["action","makeList","obj","87062acf-7fd9-4732-9cc3-871318d27d2d"]],["^1",["action","ins","obj","87062acf-7fd9-4732-9cc3-871318d27d2d","key","_head","elem",1]],["^1",["action","set","obj","87062acf-7fd9-4732-9cc3-871318d27d2d","key","8d38382f-31ef-4383-844e-aace1e545942:1","value","p2p networking is..."]],["^1",["action","link","obj","00000000-0000-0000-0000-000000000000","key","titulo","value","87062acf-7fd9-4732-9cc3-871318d27d2d"]]]],"actor","8d38382f-31ef-4383-844e-aace1e545942","seq",1,"deps",["^1",[]],"message","Initialization","undoable",false]]]]

TEMP:[{"ops":[{"action":"makeList","obj":"b8d3425e-dd05-4fef-8d59-1c57710c3980"},{"action":"link","obj":"00000000-0000-0000-0000-000000000000","key":"posts","value":"b8d3425e-dd05-4fef-8d59-1c57710c3980"},{"action":"ins","obj":"b8d3425e-dd05-4fef-8d59-1c57710c3980","key":"_head","elem":1},{"action":"makeMap","obj":"5187ee7f-6c24-44c9-9bdb-e45bf5fae4e8"},{"action":"set","obj":"5187ee7f-6c24-44c9-9bdb-e45bf5fae4e8","key":"mensagem","value":"The USENET, ..."},{"action":"link","obj":"b8d3425e-dd05-4fef-8d59-1c57710c3980","key":"5b0c62e4-aed4-4a5e-8ca1-cf5cbe1958dd:1","value":"5187ee7f-6c24-44c9-9bdb-e45bf5fae4e8"}],"actor":"5b0c62e4-aed4-4a5e-8ca1-cf5cbe1958dd","seq":1,"deps":{"8d38382f-31ef-4383-844e-aace1e545942":1},"message":"Adicionando uma lista e postando uma mensagem"}]

When I try to apply the temp changes on content:

content = Automerge.applyChanges(content,JSON.parse(temp));

I have the error below:

TypeError: Cannot read property 'backendState' of undefined at Object.getBackendState (/home/pi/node_modules/automerge/dist/automerge.js:3984:21) at Object.applyChanges (/home/pi/node_modules/automerge/dist/automerge.js:14554:27) at receivefile (/home/pi/teste/freechains-json.js:174:24) at Object. (/home/pi/teste/freechains-json.js:252:20) at Module._compile (internal/modules/cjs/loader.js:1063:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10) at Module.load (internal/modules/cjs/loader.js:928:32) at Function.Module._load (internal/modules/cjs/loader.js:769:14) at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12) at internal/main/run_main_module.js:17:47

Please do you know why I'm having this error? Thank you!

ept commented 3 years ago

Hi @fabiobosisio, it looks like the content object (first argument you're passing to applyChanges) is not an Automerge document, but something else. What is the last thing you did to obtain that object?

By the way, looks like you're using Automerge 0.14? All the new work is happening on the 1.0-preview series, which no longer needs JSON.stringify and JSON.parse because the new version already encodes changes as byte arrays (which allows much more efficient storage).

fabiobosisio commented 3 years ago

Hi @ept Thank you for the quick answer! About the version, I'm following the samples on the readme page, and this is why I'm using this version... this samples works with this new version? just removing the parser and the stringify?

The content file I build using the code below:

function savefile(filename,data,message, flag) { try { const fs = require('fs'); if(flag=="write")fs.writeFileSync(filename, data,{encodig: 'utf-8', flag: "wx"}); if(flag=="overw")fs.writeFileSync(filename, data,{encodig: 'utf-8'}); console.log('\x1b[36m%s\x1b[0m',message); }catch{ console.log('\x1b[36m%s\x1b[0m',\nO arquivo ${filename} ja existe!); return; } } const Automerge = require('automerge'); let doc1 = Automerge.from({titulo:["p2p networking is..."]}); savefile("p2p.automerge", Automerge.save(doc1),"\nO arquivo p2p.automerge foi salvo!", "overw"); savefile("p2p.json", JSON.stringify(doc1),"\nO arquivo p2p.json foi salvo!", "overw");

ept commented 3 years ago

Hi @fabiobosisio, the latest version of Automerge on npm is 1.0.1-preview.2; unless you have a version restriction in your package.json, you should get that if you install it. Also, I've just updated the README to reflect the API changes for 1.0.

If you still can't get it working, please put a self-contained source code example on https://gist.github.com and link it here.

fabiobosisio commented 3 years ago

Ok, I will try with this version, thank you!

fabiobosisio commented 3 years ago

Hi @ept, Now I'm using the last version, and I adjust the code to read binary files intead of json. But I'm still having the same error of backendState. maybe I'm doing something wrong. I did 3 steps files.js to show what I'm trying to do resumed. on the step 3 (file3.js) you can see the error...

https://gist.github.com/fabiobosisio/f0cd30085dd2e2fc8a887e9233b7f89f

ept commented 3 years ago

Hi @fabiobosisio, the argument to Automerge.save on file3.js line 36 needs to be an Automerge document such as doc2, not a list of changes. Just like you do on file1.js line 50.

Also, after you've loaded the document on file3.js line 38, you don't also need to apply changes (line 40), unless you have some additional changes that were not included in the saved document.

fabiobosisio commented 3 years ago

Hi @ept I'm saving this changes because I will send this file with the difference over the internet, and on the other side I will apply this difference on an file based on file1. I did this operacion of write and read in sequence on file3.js just to make a example of this two steps with the internet in the middle. I'm sending just the changes to reduce the payload...