Skip to content

Commit

Permalink
making some good progress...
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredly committed Feb 5, 2020
1 parent ec27be9 commit a9dbefd
Show file tree
Hide file tree
Showing 13 changed files with 305 additions and 178 deletions.
82 changes: 41 additions & 41 deletions examples/simple-example/blob/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import makeClient, {
} from '../fault-tolerant/client';
import { syncMessages, onMessage } from '../fault-tolerant/delta-client';
import { ItemSchema } from '../shared/schema.js';
import { makeFullPersistence } from '../client/idb-persistence';
import makeFullPersistence from '../client/idb-persistence';

// const syncFetch = async function<Delta, Data>(
// url: string,
Expand All @@ -36,43 +36,43 @@ import { makeFullPersistence } from '../client/idb-persistence';
// await onMessages(data);
// };

const setup = (name, colids, crdt) => {
const persistence = makeFullPersistence(name, colids);
// const client = makeClient(persistence, crdt, () => {}, 'full');
const url = `http://localhost:7898`;
const listeners = [];
// const network = makeNetwork(
// // 'http://localhost:9900/sync',
// 'ws://localhost:9104/sync',
// persistence.getHLC().node,
// reconnected =>
// syncMessages(client, reconnected),
// messages =>
// Promise.all(messages.map(message => onMessage(client, message))),
// peerChange => receiveCrossTabChanges(client, peerChange),
// );
const fullSync = async client => {
const server = await fetch(`${url}/${colids.join(',')}`);
if (server.status === 404) {
const collections = {};
await fetch(`${url}/${colids}`, {
method: 'POST',
headers: { 'Content-type': 'application/json' },
body: JSON.stringify(await persistence.getFull()),
});
} else {
// Ok to update, we'll want to do this in a transaction w/ idb.
await persistence.updateFull(await server.json(), crdt.merge);
}
};
// client.listeners.push(network.sendCrossTabChanges);
// client.setDirty = () => {
// fullSync(client);
// };
return {
// client,
onConnection: listener => {
listeners.push(listener);
},
};
};
// const setup = (name, colids, crdt) => {
// const persistence = makeFullPersistence(name, colids);
// // const client = makeClient(persistence, crdt, () => {}, 'full');
// const url = `http://localhost:7898`;
// const listeners = [];
// // const network = makeNetwork(
// // // 'http://localhost:9900/sync',
// // 'ws://localhost:9104/sync',
// // persistence.getHLC().node,
// // reconnected =>
// // syncMessages(client, reconnected),
// // messages =>
// // Promise.all(messages.map(message => onMessage(client, message))),
// // peerChange => receiveCrossTabChanges(client, peerChange),
// // );
// const fullSync = async client => {
// const server = await fetch(`${url}/${colids.join(',')}`);
// if (server.status === 404) {
// const collections = {};
// await fetch(`${url}/${colids}`, {
// method: 'POST',
// headers: { 'Content-type': 'application/json' },
// body: JSON.stringify(await persistence.getFull()),
// });
// } else {
// // Ok to update, we'll want to do this in a transaction w/ idb.
// await persistence.updateFull(await server.json(), crdt.merge);
// }
// };
// // client.listeners.push(network.sendCrossTabChanges);
// // client.setDirty = () => {
// // fullSync(client);
// // };
// return {
// client,
// onConnection: listener => {
// listeners.push(listener);
// },
// };
// };
194 changes: 97 additions & 97 deletions examples/simple-example/client/idb-persistence.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,106 +29,106 @@ const getHLC = (name: string) => {
}
};

export const makeFullPersistence = function<Data>(
name: string,
collections: Array<string>,
): FullPersistence<Data> {
const db = openDB(name, 1, {
upgrade(db, oldVersion, newVersion, transaction) {
collections.forEach(name =>
db.createObjectStore(name, { keyPath: 'id' }),
);
},
});
// export const makeFullPersistence = function<Data>(
// name: string,
// collections: Array<string>,
// ): FullPersistence<Data> {
// const db = openDB(name, 1, {
// upgrade(db, oldVersion, newVersion, transaction) {
// collections.forEach(name =>
// db.createObjectStore(name, { keyPath: 'id' }),
// );
// },
// });

return {
collections,
saveHLC: (clock: HLC) => saveHLC(name, clock),
getHLC: () => getHLC(name),
async get(collection: string, id: string) {
const data = await (await db).get(collection, id);
if (data) {
return data.value;
}
},
async getAll(collection: string) {
const items = await (await db).getAll(collection);
const res = {};
items.forEach(item => (res[item.id] = item.value));
return res;
},
async getFull() {
const tx = (await db).transaction(collections, 'readonly');
const res = {};
await Promise.all(
collections.map(async id => {
res[id] = {};
const all = await tx.objectStore(id).getAll();
all.forEach(item => (res[id][item.id] = item.value));
}),
);
return res;
},
async updateFull(
datas: { [col: string]: { [key: string]: Data } },
merge: (Data, Data) => Data,
) {
const tx = (await db).transaction(Object.keys(datas), 'readwrite');
const res = {};
await Promise.all(
Object.keys(datas).map(async col => {
const store = tx.objectStore(col);
res[col] = await store.getAll();
Object.keys(datas[col]).forEach(key => {
const prev = res[col][key];
if (res[col][key]) {
res[col][key] = merge(
res[col][key],
datas[col][key],
);
} else {
res[col][key] = datas[col][key];
}
if (!deepEqual(prev, res[col][key])) {
store.put(res[col][key]);
}
});
}),
);
await tx.done;
return res;
},
async update<Delta>(
collection: string,
deltas: Array<{ node: string, delta: Delta }>,
apply: (?Data, Delta) => Data,
) {
const tx = (await db).transaction(collection, 'readwrite');
const changedIds = {};
deltas.forEach(d => (changedIds[d.node] = true));
// return {
// collections,
// saveHLC: (clock: HLC) => saveHLC(name, clock),
// getHLC: () => getHLC(name),
// async get(collection: string, id: string) {
// const data = await (await db).get(collection, id);
// if (data) {
// return data.value;
// }
// },
// async getAll(collection: string) {
// const items = await (await db).getAll(collection);
// const res = {};
// items.forEach(item => (res[item.id] = item.value));
// return res;
// },
// async getFull() {
// const tx = (await db).transaction(collections, 'readonly');
// const res = {};
// await Promise.all(
// collections.map(async id => {
// res[id] = {};
// const all = await tx.objectStore(id).getAll();
// all.forEach(item => (res[id][item.id] = item.value));
// }),
// );
// return res;
// },
// async updateFull(
// datas: { [col: string]: { [key: string]: Data } },
// merge: (Data, Data) => Data,
// ) {
// const tx = (await db).transaction(Object.keys(datas), 'readwrite');
// const res = {};
// await Promise.all(
// Object.keys(datas).map(async col => {
// const store = tx.objectStore(col);
// res[col] = await store.getAll();
// Object.keys(datas[col]).forEach(key => {
// const prev = res[col][key];
// if (res[col][key]) {
// res[col][key] = merge(
// res[col][key],
// datas[col][key],
// );
// } else {
// res[col][key] = datas[col][key];
// }
// if (!deepEqual(prev, res[col][key])) {
// store.put(res[col][key]);
// }
// });
// }),
// );
// await tx.done;
// return res;
// },
// async update<Delta>(
// collection: string,
// deltas: Array<{ node: string, delta: Delta }>,
// apply: (?Data, Delta) => Data,
// ) {
// const tx = (await db).transaction(collection, 'readwrite');
// const changedIds = {};
// deltas.forEach(d => (changedIds[d.node] = true));

const gotten = await Promise.all(
Object.keys(changedIds).map(id => tx.store.get(id)),
);
const data = {};
gotten.forEach(res => {
if (res) {
data[res.id] = res.value;
}
});
// const gotten = await Promise.all(
// Object.keys(changedIds).map(id => tx.store.get(id)),
// );
// const data = {};
// gotten.forEach(res => {
// if (res) {
// data[res.id] = res.value;
// }
// });

deltas.forEach(({ node, delta }) => {
data[node] = apply(data[node], delta);
});
await Promise.all(
Object.keys(changedIds).map(id =>
tx.store.put({ id, value: data[id] }),
),
);
return data;
},
};
};
// deltas.forEach(({ node, delta }) => {
// data[node] = apply(data[node], delta);
// });
// await Promise.all(
// Object.keys(changedIds).map(id =>
// tx.store.put({ id, value: data[id] }),
// ),
// );
// return data;
// },
// };
// };

// const makeFullPersistence = <Delta, Data>(
// name: string,
Expand Down
5 changes: 0 additions & 5 deletions examples/simple-example/client/simple-index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ const useCollection = (client, name) => {
);
const [data, setData] = React.useState((col.loadAll(): Tasks));
React.useEffect(() => {
// col.loadAll().then(data => {
// console.log('loaded all', data);
// console.log(Object.keys(client.collections[name].data));
// setData(a => ({ ...a, ...data }));
col.onChanges(changes => {
setData(data => {
const n = { ...data };
Expand All @@ -59,7 +55,6 @@ const useCollection = (client, name) => {
return n;
});
});
// });
}, []);
return [col, data];
};
Expand Down
18 changes: 18 additions & 0 deletions examples/simple-example/client/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,30 @@ const clockPersist = (key: string) => ({
},
});

import createBlobClient from '../fault-tolerant/blob/create-client';
import makeBlobPersistence from '../fault-tolerant/blob/idb-persistence';
import createBasicBlobNetwork from '../fault-tolerant/blob/basic-network';

// window.clientLib = clientLib;
window.ItemSchema = ItemSchema;
window.setupPolling = port =>
setup(createPollingNetwork(`http://localhost:${port}/sync`));
window.setupWebSockets = port =>
setup(createWebSocketNetwork(`ws://localhost:${port}/sync`));
window.setupBlob = port => {
const client = createBlobClient(
crdt,
clockPersist('local-first'),
makeBlobPersistence('local-first', ['tasks']),
// etag: ?string => Promise<?Blob<Data>>
// Blob<data> => Promise<string>
createBasicBlobNetwork(`http://localhost:${port}/blob/stuff`),
// createPollingNetwork('http://localhost:9900/sync'),
// createWebSocketNetwork('ws://localhost:9900/sync'),
);
console.log('set up blob');
window.client = client;
};

const setup = makeNetwork => {
const client = createClient(
Expand Down
Loading

0 comments on commit a9dbefd

Please sign in to comment.