diff --git a/package-lock.json b/package-lock.json index 098cb2d43ba0610edad56ac733b7fcaae8dd74d9..883f15c0cfda04ca8944828a94ec5f5c64dc46dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2559,9 +2559,9 @@ } }, "@concordant/c-crdtlib": { - "version": "0.0.1", - "resolved": "https://gitlab.inria.fr/api/v4/projects/18591/packages/npm/@concordant/c-crdtlib/-/@concordant/c-crdtlib-0.0.1.tgz", - "integrity": "sha1-BLJO4ekZytccKTpa+xjYWkGfHRg=", + "version": "0.0.7-1", + "resolved": "https://gitlab.inria.fr/api/v4/projects/18591/packages/npm/@concordant/c-crdtlib/-/@concordant/c-crdtlib-0.0.7-1.tgz", + "integrity": "sha1-lkVUeMFQAuVhS5pP4gjGdN4vaUs=", "requires": { "kotlin": "1.4.10", "kotlinx-serialization-kotlinx-serialization-core-jsLegacy": "1.0.0", diff --git a/package.json b/package.json index 26f75fa6477a9990796e2f46fc970919403d689b..5cef4c04747f9d476a36d8475e054040e667ac04 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "typescript": "^3.9.7" }, "dependencies": { - "@concordant/c-crdtlib": "0.0.1", + "@concordant/c-crdtlib": "0.0.7-1", "@types/uuid": "^3.4.9", "apollo-server-express": "^2.19.0", "body-parser": "^1.19.0", diff --git a/src/Utils/CRDTWrapper.ts b/src/Utils/CRDTWrapper.ts index 3e720663e17cf73cf846c2355ad25cbab2042b13..32bd3d46f6381542bba453cf64f472ab645de443 100644 --- a/src/Utils/CRDTWrapper.ts +++ b/src/Utils/CRDTWrapper.ts @@ -23,34 +23,13 @@ */ import { crdtlib } from "@concordant/c-crdtlib"; -export default class CRDTWrapper<T> { - public static wrap<T>(crdt: any): CRDTWrapper<T> { +export default class CRDTWrapper { + public static wrap(crdt: any): CRDTWrapper { return new CRDTWrapper(crdt.toJson()); } - public static unwrap<T>(wrapper: CRDTWrapper<T>): any { - const crdtType = JSON.parse(wrapper.crdtJson)["_type"]; - switch (crdtType) { - case "PNCounter": - return crdtlib.crdt.PNCounter.Companion.fromJson(wrapper.crdtJson); - case "MVRegister": - return crdtlib.crdt.MVRegister.Companion.fromJson(wrapper.crdtJson); - case "LWWRegister": - return crdtlib.crdt.LWWRegister.Companion.fromJson(wrapper.crdtJson); - case "Ratchet": - return crdtlib.crdt.Ratchet.Companion.fromJson(wrapper.crdtJson); - case "RGA": - return crdtlib.crdt.RGA.Companion.fromJson(wrapper.crdtJson); - case "LWWMap": - return crdtlib.crdt.LWWMap.Companion.fromJson(wrapper.crdtJson); - case "MVMap": - return crdtlib.crdt.MVMap.Companion.fromJson(wrapper.crdtJson); - case "Map": - return crdtlib.crdt.Map.Companion.fromJson(wrapper.crdtJson); - default: - break; - } - throw new Error("Unknown CRDT type"); + public static unwrap(wrapper: CRDTWrapper): any { + return crdtlib.crdt.DeltaCRDT.Companion.fromJson(wrapper.crdtJson); } constructor(public crdtJson: string) { diff --git a/test/CRDTs/PouchDBCRDTs.test.ts b/test/CRDTs/PouchDBCRDTs.test.ts index 0f0e689be4f2b6e55fb6ca26c7a232abd0347b90..569526b069b8beca277ab09185ae6a7d9e8eab89 100644 --- a/test/CRDTs/PouchDBCRDTs.test.ts +++ b/test/CRDTs/PouchDBCRDTs.test.ts @@ -94,15 +94,15 @@ describe("Basic usage", () => { TEST_KEY = uuid(); const defaultObject = CRDTWrapper.wrap(new crdtlib.crdt.PNCounter()); return connection2 - .get<CRDTWrapper<any>>(TEST_KEY, () => defaultObject) - .then(() => connection2.get<CRDTWrapper<any>>(TEST_KEY)) - .then((obj: Document<CRDTWrapper<any>>) => { + .get<CRDTWrapper>(TEST_KEY, () => defaultObject) + .then(() => connection2.get<CRDTWrapper>(TEST_KEY)) + .then((obj: Document<CRDTWrapper>) => { const newCRDT = CRDTWrapper.unwrap(obj.current()); newCRDT.increment(42, environment1.tick()); return obj.update(CRDTWrapper.wrap(newCRDT)).save(); }) - .then(() => connection2.get<CRDTWrapper<any>>(TEST_KEY)) - .then((obj: Document<CRDTWrapper<any>>) => { + .then(() => connection2.get<CRDTWrapper>(TEST_KEY)) + .then((obj: Document<CRDTWrapper>) => { const newCRDT = CRDTWrapper.unwrap(obj.current()); expect(newCRDT.get()).toBe(42); }) @@ -118,15 +118,15 @@ describe("Basic usage", () => { const client2DefaultObjectWrapped = CRDTWrapper.wrap( new crdtlib.crdt.PNCounter() ); - let remoteObj: Document<CRDTWrapper<any>>; + let remoteObj: Document<CRDTWrapper>; let onlyAfter = false; // hooks are handled by client2 // need to create hooks for different connections to set different clientIds. const hooks: DatabaseHooks = { conflictHandler: ( - obj: Document<CRDTWrapper<any>>, - objs: Array<Document<CRDTWrapper<any>>> + obj: Document<CRDTWrapper>, + objs: Array<Document<CRDTWrapper>> ) => { if (!onlyAfter) { fail("Unexpected conflict trigger"); @@ -146,7 +146,7 @@ describe("Basic usage", () => { connection2.registerHooks(hooks); - const sub = connection1.subscribe<CRDTWrapper<any>>(TEST_KEY, { + const sub = connection1.subscribe<CRDTWrapper>(TEST_KEY, { change: (key, newObj) => { connection1.cancel(sub); onlyAfter = true; @@ -163,7 +163,7 @@ describe("Basic usage", () => { .catch((err) => fail(err)); }) .then(() => promiseDelay(null, 200)) - .then(() => connection2.get<CRDTWrapper<any>>(TEST_KEY)) + .then(() => connection2.get<CRDTWrapper>(TEST_KEY)) .then((obj) => { const unwrapped = CRDTWrapper.unwrap(obj.current()); expect(unwrapped.get()).toBe(42); @@ -173,8 +173,8 @@ describe("Basic usage", () => { }); return connection2 - .get<CRDTWrapper<any>>(TEST_KEY, () => client2DefaultObjectWrapped) - .then((obj: Document<CRDTWrapper<any>>) => (remoteObj = obj)) + .get<CRDTWrapper>(TEST_KEY, () => client2DefaultObjectWrapped) + .then((obj: Document<CRDTWrapper>) => (remoteObj = obj)) .catch((error) => fail(error)); }); }); @@ -245,13 +245,13 @@ describe("Test offline support with CRDTs", () => { const client2DefaultObjectWrapped = CRDTWrapper.wrap( new crdtlib.crdt.PNCounter() ); - let remoteObj: Document<CRDTWrapper<any>>; + let remoteObj: Document<CRDTWrapper>; let onlyAfter = false; const hooks: DatabaseHooks = { conflictHandler: ( - obj: Document<CRDTWrapper<any>>, - objs: Array<Document<CRDTWrapper<any>>> + obj: Document<CRDTWrapper>, + objs: Array<Document<CRDTWrapper>> ) => { if (!onlyAfter) { fail("Unexpected conflict trigger"); @@ -270,7 +270,7 @@ describe("Test offline support with CRDTs", () => { connection2.registerHooks(hooks); - const sub = connection1.subscribe<CRDTWrapper<any>>(TEST_KEY, { + const sub = connection1.subscribe<CRDTWrapper>(TEST_KEY, { change: (key, newObj) => { connection1.cancel(sub); onlyAfter = true; @@ -288,7 +288,7 @@ describe("Test offline support with CRDTs", () => { }) .then(() => promiseDelay(null, 200)) // .then(() => connection2.goOnline()) - .then(() => connection2.get<CRDTWrapper<any>>(TEST_KEY)) + .then(() => connection2.get<CRDTWrapper>(TEST_KEY)) .then((obj) => { const unwrapped = CRDTWrapper.unwrap(obj.current()); expect(unwrapped.get()).toBe(42); @@ -298,8 +298,8 @@ describe("Test offline support with CRDTs", () => { }); return connection2 - .get<CRDTWrapper<any>>(TEST_KEY, () => client2DefaultObjectWrapped) - .then((obj: Document<CRDTWrapper<any>>) => (remoteObj = obj)) + .get<CRDTWrapper>(TEST_KEY, () => client2DefaultObjectWrapped) + .then((obj: Document<CRDTWrapper>) => (remoteObj = obj)) .then(() => connection2.goOffline()) .catch((error) => fail(error)); });