Skip to content
Permalink
Browse files

Add RTT tests and example

  • Loading branch information
legastero committed Dec 21, 2019
1 parent 1eb3a27 commit 8710331c5349b51e83668a9db0ef8acda60eccb2
Showing with 742 additions and 15 deletions.
  1. +41 −0 examples/rtt-demo.html
  2. +1 −3 src/Utils.ts
  3. +19 −12 src/helpers/RTT.ts
  4. +430 −0 test/rtt/display-buffer.ts
  5. +251 −0 test/rtt/input-buffer.ts
@@ -0,0 +1,41 @@
<script src="../dist/stanza.browser.js"></script>

<h2>Input Buffer:</h2>
<textarea id="textInput" rows="5" cols="72"></textarea>

<h2>Display Buffer:</h2>
<p id="textOutput"></p>

<script>
const inputBuffer = new XMPP.RTT.InputBuffer();
inputBuffer.start();

// Use oninput to capture updates from non-keypress actions,
// such as copy/pasting or autocorrect
textInput.oninput = function(e) {
inputBuffer.update(e.target.value);
};

const displayBuffer = new XMPP.RTT.DisplayBuffer(state => {
console.log(state);
textOutput.textContent = state.text;
});

setInterval(() => {
const diff = inputBuffer.diff();
if (diff) {
console.log(diff);

// To send diff to peer:
// client.sendMessage({ rtt: diff, to: ... });

// Upon receiving diff from peer:
// client.on('rtt', msg => { displayBuffer.process(msg.rtt); });

// To reset the display buffer after the final message is received:
// client.on('chat', msg => { displayBuffer.commit(); });

displayBuffer.process(diff);
}
}, 700);
</script>
@@ -28,9 +28,7 @@ export async function timeoutPromise<T>(
timeoutRef = setTimeout(() => reject(rejectValue()), delay);
})
]);
if (timeoutRef) {
clearTimeout(timeoutRef);
}
clearTimeout(timeoutRef);
return result;
}

@@ -77,11 +77,12 @@ export class DisplayBuffer {
public synced: boolean = false;
public onStateChange: (state: DisplayBufferState) => void;
public cursorPosition: number = 0;
public ignoreWaits: boolean = false;

private buffer: UnicodeBuffer;
private timeDeficit: number = 0;
private sequenceNumber: number = 0;
private actionQueue!: AsyncPriorityQueue<RTTAction>;
private ignoreWaits: boolean = false;

constructor(onStateChange?: (state: DisplayBufferState) => void, ignoreWaits: boolean = false) {
this.onStateChange =
@@ -124,9 +125,10 @@ export class DisplayBuffer {
public process(event: RTT): void {
if (event.event === 'cancel' || event.event === 'init') {
this.resetActionQueue();
return;
} else if (event.event === 'reset' || event.event === 'new') {
this.resetActionQueue();
if (event.seq) {
if (event.seq !== undefined) {
this.sequenceNumber = event.seq;
}
} else if (event.seq !== this.sequenceNumber) {
@@ -205,8 +207,7 @@ export class DisplayBuffer {
this.sequenceNumber = 0;
this.synced = true;
this.buffer = [];

this.emitState();
this.timeDeficit = 0;

this.actionQueue = priorityQueue((action: RTTAction, done: () => void) => {
const currentTime = Date.now();
@@ -226,15 +227,21 @@ export class DisplayBuffer {
action.duration = 700;
}

if (currentTime >= action.baseTime! + action.duration) {
const waitTime =
action.duration - (currentTime - action.baseTime!) + this.timeDeficit;
if (waitTime <= 0) {
this.timeDeficit = waitTime;
return done();
} else {
setTimeout(() => done(), action.duration);
this.timeDeficit = 0;
setTimeout(() => done(), waitTime);
}
} else {
return done();
}
}, 1);

this.emitState();
}
}

@@ -244,13 +251,13 @@ export class DisplayBuffer {
export class InputBuffer {
public onStateChange: (state: InputBufferState) => void;
public resetInterval: number = 10000;
public ignoreWaits: boolean = false;
public sequenceNumber: number;

private ignoreWaits: boolean = false;
private isStarting: boolean = false;
private isReset: boolean = false;
private buffer: UnicodeBuffer;
private actionQueue: RTTAction[];
private sequenceNumber: number;
private lastActionTime?: number;
private lastResetTime?: number;
private changedBetweenResets: boolean = false;
@@ -283,11 +290,9 @@ export class InputBuffer {
let actions: RTTAction[] = [];

if (text !== undefined) {
if (text.normalize) {
text = text.normalize('NFC');
}
text = text.normalize('NFC');

const newBuffer = Punycode.ucs2.decode(text || '');
const newBuffer = Punycode.ucs2.decode(text);
actions = diff(this.buffer, newBuffer.slice());

this.buffer = newBuffer;
@@ -319,6 +324,8 @@ export class InputBuffer {
}
this.lastActionTime = now;
this.changedBetweenResets = true;
} else {
this.lastActionTime = now;
}
}

0 comments on commit 8710331

Please sign in to comment.
You can’t perform that action at this time.