summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/transport.js
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/transport.js')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/transport.js38
1 files changed, 30 insertions, 8 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/transport.js b/packages/meshbay-hub/src/meshbay_hub/static/transport.js
index 3acfd20..179292e 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/transport.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/transport.js
@@ -72,13 +72,35 @@ function _aborted() {
// change anything — `op` is already on every admin_challenge, and this
// list is what lets a response two steps later be tied back to the right
// one.
-// The acks whose payload is state no caller could have predicted: they carry
-// the node's whole roots table back. See the note where they are dispatched.
-const ROOT_ACK_TYPES = new Set([
+// Acks the node *broadcasts* to everyone in the group, which the requester
+// therefore also has to be handed.
+//
+// `_dispatch` resolves an admin ack against the pending request and returns,
+// which is right for an op whose caller already knows the value it chose. It is
+// wrong for these: every *other* connected client learns the change from the
+// broadcast, and the one that asked for it is the only one that does not,
+// because its own request swallowed its copy. Found twice — first on the root
+// table, then on Chat's directory, where it meant the pane went on showing an
+// unsaved-looking draft after a save that had worked.
+const BROADCAST_ACK_TYPES = new Set([
'root_update_ack', 'root_eject_ack', 'root_plug_ack',
'root_add_ack', 'root_remove_ack',
+ 'app_directories_ack', 'chat_directory_ack', 'chat_link_preview_ack',
]);
+/** Hand a broadcast ack to the callback that would have had it from a peer. */
+function _replayBroadcast(transport, msg) {
+ if (msg.type === 'app_directories_ack' && transport._onAppDirectories) {
+ transport._onAppDirectories(msg.app, msg.directories || []);
+ } else if (msg.type === 'chat_directory_ack' && transport._onChatDirectory) {
+ transport._onChatDirectory(msg.path || '');
+ } else if (msg.type === 'chat_link_preview_ack' && transport._onChatLinkPreview) {
+ transport._onChatLinkPreview(Boolean(msg.enabled));
+ } else if (transport._onRootsChanged) {
+ transport._onRootsChanged(msg);
+ }
+}
+
const ADMIN_OP_TYPES = new Set([
'tmdb_override', 'tmdb_rematch', 'tmdb_config', 'tmdb_enabled', 'video_root', 'audio_root',
'photo_roots',
@@ -2349,9 +2371,7 @@ class MeshBayTransport {
// name it settled on. Returning here left the operator who clicked
// Eject as the one client that never saw it happen, while every
// other peer got the broadcast. So this one type is handed on.
- if (ROOT_ACK_TYPES.has(msg.type) && this._onRootsChanged) {
- this._onRootsChanged(msg);
- }
+ if (BROADCAST_ACK_TYPES.has(msg.type)) _replayBroadcast(this, msg);
return;
}
}
@@ -2486,8 +2506,10 @@ class MeshBayTransport {
// A root's flags changed, or one was ejected, plugged, added or removed.
// Broadcast by the node to every peer, so everyone's table updates without
// waiting for the next index_sync.
- if (ROOT_ACK_TYPES.has(msg.type) && this._onRootsChanged) {
- this._onRootsChanged(msg);
+ if (msg.type === 'root_update_ack' || msg.type === 'root_eject_ack'
+ || msg.type === 'root_plug_ack' || msg.type === 'root_add_ack'
+ || msg.type === 'root_remove_ack') {
+ if (this._onRootsChanged) this._onRootsChanged(msg);
}
// The operator's node is scanning — never the entries themselves, just