mirror of
https://github.com/fluencelabs/fluent-pad
synced 2025-04-25 00:42:14 +00:00
Improve text synchronization performance
This commit is contained in:
parent
77b70b7c49
commit
633f43ec4d
6
client/package-lock.json
generated
6
client/package-lock.json
generated
@ -2190,6 +2190,12 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
||||
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4="
|
||||
},
|
||||
"@types/lodash": {
|
||||
"version": "4.14.167",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.167.tgz",
|
||||
"integrity": "sha512-w7tQPjARrvdeBkX/Rwg95S592JwxqOjmms3zWQ0XZgSyxSLdzWaYH3vErBhdVS/lRBX7F8aBYcYJYTr5TMGOzw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/minimatch": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
|
||||
|
@ -14,6 +14,7 @@
|
||||
"@types/react-dom": "^16.9.10",
|
||||
"automerge": "^0.14.2",
|
||||
"diff-match-patch": "^1.0.5",
|
||||
"lodash": "^4.17.20",
|
||||
"node-sass": "^4.14.1",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
@ -49,5 +50,7 @@
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {}
|
||||
"devDependencies": {
|
||||
"@types/lodash": "^4.14.167"
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { createClient, FluenceClient, subscribeToEvent } from '@fluencelabs/fluence';
|
||||
import { createClient, FluenceClient } from '@fluencelabs/fluence';
|
||||
import { dev } from '@fluencelabs/fluence-network-environment';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
@ -16,6 +16,7 @@ const App = () => {
|
||||
useEffect(() => {
|
||||
const fn = async () => {
|
||||
const c = await createClient(dev[0]);
|
||||
|
||||
setClient(c);
|
||||
};
|
||||
fn();
|
||||
@ -66,11 +67,14 @@ const App = () => {
|
||||
Leave Room
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button onClick={() => calls.clean(client!)}>Clean</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="wrapper">
|
||||
<div>{isInRoom && client && <CollaborativeEditor />}</div>
|
||||
{/* <div>{isInRoom && client && <UserList selfName={nickName} />}</div> */}
|
||||
<div>{isInRoom && client && <UserList selfName={nickName} />}</div>
|
||||
</div>
|
||||
</div>
|
||||
</FluenceClientContext.Provider>
|
||||
|
@ -4,7 +4,8 @@ import { useEffect, useState } from 'react';
|
||||
import { fluentPadServiceId, notifyTextUpdateFnName } from 'src/fluence/constants';
|
||||
import { useFluenceClient } from './FluenceClientContext';
|
||||
import * as calls from 'src/fluence/calls';
|
||||
import { subscribeToEvent } from '@fluencelabs/fluence';
|
||||
import { FluenceClient, subscribeToEvent } from '@fluencelabs/fluence';
|
||||
import _ from 'lodash';
|
||||
|
||||
interface TextDoc {
|
||||
value: Automerge.Text;
|
||||
@ -78,13 +79,26 @@ const applyStates = (startingDoc: TextDoc | null, entries: calls.Entry[]) => {
|
||||
return res;
|
||||
};
|
||||
|
||||
const broadcastUpdates = _.debounce(async (client: FluenceClient, doc: TextDoc) => {
|
||||
const entry = {
|
||||
fluentPadState: Automerge.save(doc),
|
||||
};
|
||||
const entryStr = JSON.stringify(entry);
|
||||
|
||||
await calls.addEntry(client, entryStr);
|
||||
}, 200);
|
||||
|
||||
export const CollaborativeEditor = () => {
|
||||
const client = useFluenceClient()!;
|
||||
const [text, setText] = useState<TextDoc | null>(null);
|
||||
const [text, setText] = useState<TextDoc | null>(Automerge.from({ value: new Automerge.Text() }));
|
||||
|
||||
useEffect(() => {
|
||||
const unsub1 = subscribeToEvent(client, fluentPadServiceId, notifyTextUpdateFnName, (args, tetraplets) => {
|
||||
const [stateStr, isAuthorized] = args;
|
||||
const [authorPeerId, stateStr, isAuthorized] = args;
|
||||
if (authorPeerId === client.selfPeerId.toB58String()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const state = parseState(stateStr);
|
||||
if (state && text) {
|
||||
const newDoc = Automerge.merge(text, state);
|
||||
@ -116,19 +130,13 @@ export const CollaborativeEditor = () => {
|
||||
setText(newDoc);
|
||||
|
||||
// don't block
|
||||
setImmediate(async () => {
|
||||
const entry = {
|
||||
fluentPadState: Automerge.save(newDoc),
|
||||
};
|
||||
const entryStr = JSON.stringify(entry);
|
||||
|
||||
await calls.addEntry(client, entryStr);
|
||||
});
|
||||
setImmediate(broadcastUpdates, client, newDoc);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<textarea value={textValue} disabled={!text} onChange={handleTextUpdate} />
|
||||
<div>
|
||||
Automerge changes:
|
||||
<ul>
|
||||
{amHistory.map((value, index) => (
|
||||
@ -136,5 +144,6 @@ export const CollaborativeEditor = () => {
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -262,7 +262,7 @@ export const addEntry = async (client: FluenceClient, entry: string) => {
|
||||
(par
|
||||
(seq
|
||||
(call u.$.relay_id ("op" "identity") [])
|
||||
(call u.$.peer_id (fluentPadServiceId notifyTextUpdate) [entry token.$.["is_authenticated"]])
|
||||
(call u.$.peer_id (fluentPadServiceId notifyTextUpdate) [myPeerId entry token.$.["is_authenticated"]])
|
||||
)
|
||||
(next u)
|
||||
)
|
||||
@ -284,7 +284,29 @@ export const addEntry = async (client: FluenceClient, entry: string) => {
|
||||
fluentPadServiceId: fluentPadServiceId,
|
||||
notifyTextUpdate: notifyTextUpdateFnName,
|
||||
},
|
||||
99999999,
|
||||
);
|
||||
|
||||
await sendParticle(client, particle);
|
||||
};
|
||||
|
||||
export const clean = async (client: FluenceClient) => {
|
||||
const particle = new Particle(
|
||||
`
|
||||
(seq
|
||||
(call myRelay ("op" "identity") [])
|
||||
(seq
|
||||
(call userlistNode (userlist "clear") [])
|
||||
(call historyNode (history "clear") [])
|
||||
)
|
||||
)
|
||||
`,
|
||||
{
|
||||
myRelay: client.relayPeerID.toB58String(),
|
||||
userlist: userListServiceId,
|
||||
history: historyServiceId,
|
||||
userlistNode: userListNodePid,
|
||||
historyNode: historyNodePid,
|
||||
},
|
||||
);
|
||||
|
||||
await sendParticle(client, particle);
|
||||
|
@ -7,8 +7,8 @@ export const notifyUserAddedFnName = 'notifyUserAdded';
|
||||
export const notifyUserRemovedFnName = 'notifyUserRemoved';
|
||||
export const notifyTextUpdateFnName = 'notifyTextUpdate';
|
||||
|
||||
export const userListServiceId = '65b7232f-45ff-464f-a804-c4c8ce563726';
|
||||
export const historyServiceId = '29a5724d-c865-42fe-bfc1-e2c6b84a89b4';
|
||||
export const userListServiceId = '03edcc81-7777-4234-b048-36305d8d65e2';
|
||||
export const historyServiceId = '7fb57031-1d3d-4391-9a9f-da40a6c4963d';
|
||||
|
||||
export const userListNodePid = dev[2].peerId;
|
||||
export const historyNodePid = dev[2].peerId;
|
||||
|
Loading…
x
Reference in New Issue
Block a user