From a394d7a59179cd5b27f901bc193271956a769ada Mon Sep 17 00:00:00 2001 From: WofWca Date: Sat, 13 Jul 2024 17:46:54 +0400 Subject: [PATCH 1/3] add examples for `sendUpdate`, `setUpdateListener` Closes https://github.com/webxdc/website/issues/60 Some might say that the setUpdateListener example is too convoluted, but you can't really showcase the usage of `serial` without this much code. Plus, a briefer example is already shown in `sendUpdate()` docs. The code has been tested with the `webxdc-dev` tool, and (mostly) fomatted with Prettier. --- src-docs/spec/sendUpdate.md | 15 +++++++++ src-docs/spec/setUpdateListener.md | 50 ++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/src-docs/spec/sendUpdate.md b/src-docs/spec/sendUpdate.md index 147ed5b..1e50b50 100644 --- a/src-docs/spec/sendUpdate.md +++ b/src-docs/spec/sendUpdate.md @@ -29,6 +29,21 @@ Send an update to all peers. - `descr`: short, human-readable description what this update is about. this is shown e.g. as a fallback text in an e-mail program. +Example: + +```js +window.webxdc.sendUpdate( + { payload: "Hello from Alice" }, + "A 'hello' message" +); + +// Peers can receive messages as such: +window.webxdc.setUpdateListener((update) => { + console.log(update.payload); +}); +// 'Hello from Alice' is printed in the console +``` + All peers, including the sending one, will receive the update by the callback given to [`setUpdateListener()`](./setUpdateListener.html). diff --git a/src-docs/spec/setUpdateListener.md b/src-docs/spec/setUpdateListener.md index ff5a063..0318f4c 100644 --- a/src-docs/spec/setUpdateListener.md +++ b/src-docs/spec/setUpdateListener.md @@ -29,6 +29,56 @@ Each `update` which is passed to the callback comes with the following propertie - `update.summary`: optional, short text, shown beside icon (see [`sendUpdate()`]) +Example: + +```js +let myDocumentState = localStorage.getItem("myDocumentState") ?? ""; + +let initialPendingUpdatesHandled = false; +const initialPendingUpdatesHandledPromise = window.webxdc.setUpdateListener( + (update) => { + // Remember that the listener is invoked for + // your own `window.webxdc.sendUpdate()` calls as well! + + applyDocumentUpdate(update.payload); + localStorage.setItem("myDocumentState", myDocumentState); + localStorage.setItem("lastHandledUpdateSerial", update.serial); + + const areMoreUpdatesPending = update.serial !== update.max_serial; + if ( + !areMoreUpdatesPending && + // We'll make the initial render when the promise resolves, + // because if there are no pending updates, + // the listener will not be invoked. + initialPendingUpdatesHandled + ) { + renderDocument(); + } + }, + parseInt(localStorage.getItem("lastHandledUpdateSerial") ?? "0") +); + +initialPendingUpdatesHandledPromise.then(() => { + initialPendingUpdatesHandled = true; + renderDocument(); +}); + +function applyDocumentUpdate(myDocumentUpdate) { + // Dummy `applyDocumentUpdate` logic. + // Yours might be more complex, + // such as applying a chess move to the board. + myDocumentState = myDocumentUpdate; +} +// Let's only call this when there are no pending updates. +function renderDocument() { + document.body.innerText = myDocumentState; +} + +// ... +// Other peers, or you: +window.webxdc.sendUpdate({ payload: "Knight d3" }, "Bob made a move!"); +``` + Calling `setUpdateListener()` multiple times is undefined behavior: in current implementations only the last invocation works. [`sendUpdate()`]: ./sendUpdate.html From 7263ac52c0c259bdea67b5eec5f52fc199136c28 Mon Sep 17 00:00:00 2001 From: WofWca Date: Sun, 14 Jul 2024 12:52:50 +0400 Subject: [PATCH 2/3] simplify `setUpdateListener` example --- src-docs/spec/setUpdateListener.md | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/src-docs/spec/setUpdateListener.md b/src-docs/spec/setUpdateListener.md index 0318f4c..7ace51c 100644 --- a/src-docs/spec/setUpdateListener.md +++ b/src-docs/spec/setUpdateListener.md @@ -32,43 +32,28 @@ Each `update` which is passed to the callback comes with the following propertie Example: ```js -let myDocumentState = localStorage.getItem("myDocumentState") ?? ""; - -let initialPendingUpdatesHandled = false; +let myDocumentState = ""; const initialPendingUpdatesHandledPromise = window.webxdc.setUpdateListener( (update) => { // Remember that the listener is invoked for // your own `window.webxdc.sendUpdate()` calls as well! - applyDocumentUpdate(update.payload); - localStorage.setItem("myDocumentState", myDocumentState); - localStorage.setItem("lastHandledUpdateSerial", update.serial); + // Dummy document update logic. + // Yours might be more complex, + // such as applying a chess move to the board. + myDocumentState = myDocumentUpdate; const areMoreUpdatesPending = update.serial !== update.max_serial; - if ( - !areMoreUpdatesPending && - // We'll make the initial render when the promise resolves, - // because if there are no pending updates, - // the listener will not be invoked. - initialPendingUpdatesHandled - ) { + if (!areMoreUpdatesPending) { renderDocument(); } - }, - parseInt(localStorage.getItem("lastHandledUpdateSerial") ?? "0") + } ); initialPendingUpdatesHandledPromise.then(() => { - initialPendingUpdatesHandled = true; renderDocument(); }); -function applyDocumentUpdate(myDocumentUpdate) { - // Dummy `applyDocumentUpdate` logic. - // Yours might be more complex, - // such as applying a chess move to the board. - myDocumentState = myDocumentUpdate; -} // Let's only call this when there are no pending updates. function renderDocument() { document.body.innerText = myDocumentState; From a7147f47ff6369290c28d6ede553f24bdd4d773e Mon Sep 17 00:00:00 2001 From: WofWca Date: Wed, 17 Jul 2024 10:06:08 +0000 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: holger krekel --- src-docs/spec/setUpdateListener.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src-docs/spec/setUpdateListener.md b/src-docs/spec/setUpdateListener.md index 7ace51c..2d44db1 100644 --- a/src-docs/spec/setUpdateListener.md +++ b/src-docs/spec/setUpdateListener.md @@ -43,8 +43,8 @@ const initialPendingUpdatesHandledPromise = window.webxdc.setUpdateListener( // such as applying a chess move to the board. myDocumentState = myDocumentUpdate; - const areMoreUpdatesPending = update.serial !== update.max_serial; - if (!areMoreUpdatesPending) { + const areAllUpdatesProcessed = update.serial === update.max_serial; + if (areAllUpdatesProcessed) { renderDocument(); } } @@ -59,8 +59,7 @@ function renderDocument() { document.body.innerText = myDocumentState; } -// ... -// Other peers, or you: +// Peers can send messages like this window.webxdc.sendUpdate({ payload: "Knight d3" }, "Bob made a move!"); ```