import { describe, it } from 'mocha'; //@ts-ignore import assert from 'assert' //@ts-ignore import init, { create, load } from '..' describe('Automerge', () => { describe('Readme Examples', () => { it('Using the Library and Creating a Document (1)', () => { const doc = create() doc.free() }) it('Using the Library and Creating a Document (2)', (done) => { init().then((_:any) => { const doc = create() doc.free() done() }) }) it('Automerge Scalar Types (1)', () => { const doc = create() doc.put("/", "prop1", 100) // int doc.put("/", "prop2", 3.14) // f64 doc.put("/", "prop3", "hello world") doc.put("/", "prop4", new Date(0)) doc.put("/", "prop5", new Uint8Array([1,2,3])) doc.put("/", "prop6", true) doc.put("/", "prop7", null) assert.deepEqual(doc.materialize("/"), { prop1: 100, prop2: 3.14, prop3: "hello world", prop4: new Date(0), prop5: new Uint8Array([1,2,3]), prop6: true, prop7: null }) doc.free() }) it('Automerge Scalar Types (2)', () => { const doc = create() doc.put("/", "prop1", 100, "int") doc.put("/", "prop2", 100, "uint") doc.put("/", "prop3", 100.5, "f64") doc.put("/", "prop4", 100, "counter") doc.put("/", "prop5", 1647531707301, "timestamp") doc.put("/", "prop6", new Date(), "timestamp") doc.put("/", "prop7", "hello world", "str") doc.put("/", "prop8", new Uint8Array([1,2,3]), "bytes") doc.put("/", "prop9", true, "boolean") doc.put("/", "prop10", null, "null") doc.free() }) it('Automerge Object Types (1)', () => { const doc = create() // you can create an object by passing in the inital state - if blank pass in `{}` // the return value is the Object Id // these functions all return an object id const config = doc.putObject("/", "config", { align: "left", archived: false, cycles: [10, 19, 21] }) const token = doc.putObject("/", "tokens", {}) // lists can be made with javascript arrays const birds = doc.putObject("/", "birds", ["bluejay", "penguin", "puffin"]) const bots = doc.putObject("/", "bots", []) // text is initialized with a string const notes = doc.putObject("/", "notes", "Hello world!") doc.free() }) it('Automerge Object Types (2)', () => { const doc = create() const config = doc.putObject("/", "config", { align: "left", archived: false, cycles: [10, 19, 21] }) doc.put(config, "align", "right") // Anywhere Object Ids are being used a path can also be used. // The following two statements are equivalent: const id = doc.get("/", "config") if (id && id[0] === 'map') { doc.put(id[1], "align", "right") } doc.put("/config", "align", "right") assert.deepEqual(doc.materialize("/"), { config: { align: "right", archived: false, cycles: [ 10, 19, 21 ] } }) doc.free() }) it('Maps (1)', () => { const doc = create() const mymap = doc.putObject("_root", "mymap", { foo: "bar"}) // make a new map with the foo key doc.put(mymap, "bytes", new Uint8Array([1,2,3])) // assign a byte array to key `bytes` of the mymap object const submap = doc.putObject(mymap, "sub", {}) // make a new empty object and assign it to the key `sub` of mymap assert.deepEqual(doc.keys(mymap),["bytes","foo","sub"]) assert.deepEqual(doc.materialize("_root"), { mymap: { bytes: new Uint8Array([1,2,3]), foo: "bar", sub: {} }}) doc.free() }) it('Lists (1)', () => { const doc = create() const items = doc.putObject("_root", "items", [10,"box"]) // init a new list with two elements doc.push(items, true) // push `true` to the end of the list doc.putObject(items, 0, { hello: "world" }) // overwrite the value 10 with an object with a key and value doc.delete(items, 1) // delete "box" doc.splice(items, 2, 0, ["bag", "brick"]) // splice in "bag" and "brick" at position 2 doc.insert(items, 0, "bat") // insert "bat" to the beginning of the list doc.insertObject(items, 1, [ 1, 2 ]) // insert a list with 2 values at pos 1 assert.deepEqual(doc.materialize(items),[ "bat", [ 1 ,2 ], { hello : "world" }, true, "bag", "brick" ]) assert.deepEqual(doc.length(items),6) doc.free() }) it('Text (1)', () => { const doc = create("aaaaaa") const notes = doc.putObject("_root", "notes", "Hello world") doc.splice(notes, 6, 5, "everyone") assert.deepEqual(doc.text(notes), "Hello everyone") const obj = doc.insertObject(notes, 6, { hi: "there" }) assert.deepEqual(doc.text(notes), "Hello \ufffceveryone") assert.deepEqual(doc.get(notes, 6), ["map", obj]) assert.deepEqual(doc.get(obj, "hi"), ["str", "there"]) doc.free() }) it('Querying Data (1)', () => { const doc1 = create("aabbcc") doc1.put("_root", "key1", "val1") const key2 = doc1.putObject("_root", "key2", []) assert.deepEqual(doc1.get("_root", "key1"), ["str", "val1"]) assert.deepEqual(doc1.get("_root", "key2"), ["list", "2@aabbcc"]) assert.deepEqual(doc1.keys("_root"), ["key1", "key2"]) const doc2 = doc1.fork("ffaaff") // set a value concurrently doc1.put("_root","key3","doc1val") doc2.put("_root","key3","doc2val") doc1.merge(doc2) assert.deepEqual(doc1.get("_root","key3"), ["str", "doc2val"]) assert.deepEqual(doc1.getAll("_root","key3"),[[ "str", "doc1val", "3@aabbcc"], ["str", "doc2val", "3@ffaaff"]]) doc1.free(); doc2.free() }) it('Counters (1)', () => { const doc1 = create("aaaaaa") doc1.put("_root", "number", 0) doc1.put("_root", "total", 0, "counter") const doc2 = doc1.fork("bbbbbb") doc2.put("_root", "number", 10) doc2.increment("_root", "total", 11) doc1.put("_root", "number", 20) doc1.increment("_root", "total", 22) doc1.merge(doc2) assert.deepEqual(doc1.materialize("_root"), { number: 10, total: 33 }) doc1.free(); doc2.free() }) it('Transactions (1)', () => { const doc = create() doc.put("_root", "key", "val1") assert.deepEqual(doc.get("_root", "key"),["str","val1"]) assert.deepEqual(doc.pendingOps(),1) doc.rollback() assert.deepEqual(doc.get("_root", "key"),null) assert.deepEqual(doc.pendingOps(),0) doc.put("_root", "key", "val2") assert.deepEqual(doc.pendingOps(),1) doc.commit("test commit 1") assert.deepEqual(doc.get("_root", "key"),["str","val2"]) assert.deepEqual(doc.pendingOps(),0) doc.free() }) it('Viewing Old Versions of the Document (1)', () => { const doc = create() doc.put("_root", "key", "val1") const heads1 = doc.getHeads() doc.put("_root", "key", "val2") const heads2 = doc.getHeads() doc.put("_root", "key", "val3") assert.deepEqual(doc.get("_root","key"), ["str","val3"]) assert.deepEqual(doc.get("_root","key",heads2), ["str","val2"]) assert.deepEqual(doc.get("_root","key",heads1), ["str","val1"]) assert.deepEqual(doc.get("_root","key",[]), null) doc.free() }) it('Forking And Merging (1)', () => { const doc1 = create() doc1.put("_root", "key1", "val1") const doc2 = doc1.fork() doc1.put("_root", "key2", "val2") doc2.put("_root", "key3", "val3") doc1.merge(doc2) assert.deepEqual(doc1.materialize("_root"), { key1: "val1", key2: "val2", key3: "val3" }) assert.deepEqual(doc2.materialize("_root"), { key1: "val1", key3: "val3" }) doc1.free(); doc2.free() }) it('Saving And Loading (1)', () => { const doc1 = create() doc1.put("_root", "key1", "value1") const save1 = doc1.save() const doc2 = load(save1) doc2.materialize("_root") // returns { key1: "value1" } doc1.put("_root", "key2", "value2") const saveIncremental = doc1.saveIncremental() const save2 = doc1.save() const save3 = new Uint8Array([... save1, ... saveIncremental]) // save2 has fewer bytes than save3 but contains the same ops doc2.loadIncremental(saveIncremental) const doc3 = load(save2) const doc4 = load(save3) assert.deepEqual(doc1.materialize("_root"), { key1: "value1", key2: "value2" }) assert.deepEqual(doc2.materialize("_root"), { key1: "value1", key2: "value2" }) assert.deepEqual(doc3.materialize("_root"), { key1: "value1", key2: "value2" }) assert.deepEqual(doc4.materialize("_root"), { key1: "value1", key2: "value2" }) doc1.free(); doc2.free(); doc3.free(); doc4.free() }) it.skip('Syncing (1)', () => { }) }) })