AnyCable **real-time server** (WS, or WebSocket, since it's a primary transport) is responsible for handling clients, or connections. That includes:
diff --git a/docs/assets/styles.css b/docs/assets/styles.css
index b44e0a2..bf8cc13 100644
--- a/docs/assets/styles.css
+++ b/docs/assets/styles.css
@@ -604,4 +604,41 @@ h4:has(+.pro-badge-header):after {
.sidebar li.open>p {
/* color: var(--theme-color-dark); */
font-weight: 600;
-}
\ No newline at end of file
+}
+
+@keyframes full-slide-right {
+ from { transform: translateX(0); }
+ to { transform: translateX(100%); }
+}
+
+@keyframes full-slide-left {
+ from { transform: translateX(100%); }
+}
+
+@keyframes fade-in {
+ from { opacity: 0; }
+}
+
+@keyframes fade-out {
+ to { opacity: 0; }
+}
+
+::view-transition-old(section) {
+ animation: 700ms ease-in 0ms both full-slide-right, 500ms ease-out 0ms both fade-out;
+}
+
+::view-transition-new(section) {
+ animation: 500ms ease-in 0ms both fade-in;
+}
+
+section.content {
+ view-transition-name: section;
+}
+
+@media (prefers-reduced-motion) {
+ ::view-transition-group(*),
+ ::view-transition-old(*),
+ ::view-transition-new(*) {
+ animation: none !important;
+ }
+}
diff --git a/docs/assets/turbo-view-transitions.js b/docs/assets/turbo-view-transitions.js
new file mode 100644
index 0000000..02aeb03
--- /dev/null
+++ b/docs/assets/turbo-view-transitions.js
@@ -0,0 +1,69 @@
+window.TurboViewTransitions = (function () {
+ function shouldPerformTransition() {
+ return !!(
+ "undefined" !== typeof document &&
+ document.head &&
+ document.startViewTransition &&
+ document.head.querySelector('meta[name="view-transition"]')
+ );
+ }
+ const t = "data-turbo-transition";
+ const e = "data-turbo-transition-active";
+ const resetTransitions = (t, e) => {
+ t = t || document;
+ let { activeAttr: r } = e;
+ t.querySelectorAll(`[${r}]`).forEach((t) => {
+ t.style.viewTransitionName = "";
+ t.removeAttribute(r);
+ });
+ };
+ const activateTransitions = (t, e, r) => {
+ let { transitionAttr: i, activeAttr: n } = r;
+ let a = Array.from(t.querySelectorAll(`[${i}]`)).reduce((t, e) => {
+ let r = e.id || "0";
+ let n = e.getAttribute(i) || `__${r}`;
+ t[n] ||
+ (t[n] = {
+ ids: {},
+ active: false,
+ discarded: false,
+ });
+ t[n].ids[r] = e;
+ return t;
+ }, {});
+ Array.from(e.querySelectorAll(`[${i}]`)).forEach((t) => {
+ let e = t.id || "0";
+ let r = t.getAttribute(i) || `__${e}`;
+ if (a[r] && a[r].ids[e]) {
+ if (a[r].active) {
+ a[r].discarded = true;
+ return;
+ }
+ a[r].newEl = t;
+ a[r].oldEl = a[r].ids[e];
+ a[r].active = true;
+ }
+ });
+ for (let t in a) {
+ let { newEl: e, oldEl: r, active: i, discarded: o } = a[t];
+ if (!o && i) {
+ r.style.viewTransitionName = t;
+ e.style.viewTransitionName = t;
+ r.setAttribute(n, "");
+ e.setAttribute(n, "");
+ }
+ }
+ };
+ async function performTransition(r, i, n, a = {}) {
+ a.activeAttr = a.activeAttr || e;
+ a.transitionAttr = a.transitionAttr || t;
+ resetTransitions(r, a);
+ activateTransitions(r, i, a);
+ await document.startViewTransition(n).finished.then(() => {
+ resetTransitions(r, a);
+ resetTransitions(i, a);
+ });
+ }
+
+ return { shouldPerformTransition, performTransition };
+})();
diff --git a/docs/benchmarks.md b/docs/benchmarks.md
index da3300e..ce6e840 100644
--- a/docs/benchmarks.md
+++ b/docs/benchmarks.md
@@ -12,7 +12,7 @@ Broadcasting round-trip time benchmark (based on [Hashrocket's bench](https://gi
The results of this benchmark could be seen below.
-
+
diff --git a/docs/getting_started.md b/docs/getting_started.md
index 84df9b3..c058d16 100644
--- a/docs/getting_started.md
+++ b/docs/getting_started.md
@@ -3,7 +3,7 @@
AnyCable acts like a bridge between _logic-less_ real-time server and _Action Cable-like_ Ruby framework (i.e. framework which support [Action Cable protocol](misc/action_cable_protocol.md)). AnyCable is a multi-transport server supporting WebSockets, [Server-Sent Events](/anycable-go/sse.md) and [long-polling](/anycable-go/long_polling.md).
-