Framework data WebSocket-first untuk SolidJS

Berhenti membuat user menunggu data yang sudah ada.

0ms kunjungan ulang · 2.8KB gzipped · WebSocket-first

npm install @uikode/tide Klik untuk menyalin
tide-demo.tsx

// Kunjungan pertama: shimmer skeleton

Kunjungan ulang: render dari cache instan

// Kunjungan ulang: 0ms dari sessionStorage

🔷 100% TypeScript 📐 2.8KB gzipped 🧩 Zero dependencies ⚖️ MIT Lihat source →
~5.4× lebih kecil dari TanStack+persist (measured, gzip) ⚡ 0ms revisit

Masalahnya

Kamu membangun dashboard real-time. Panggilan API butuh 1–9 detik. Setiap navigasi = halaman kosong → spinner → tunggu → render. Data kamu BARU SAJA ADA 2 detik lalu.

/api/dashboard1,490× faster
Before
8.9s
After
6ms
/api/agentic/tooling350× faster
Before
5.6s
After
16ms
/api/stack/status833× faster
Before
5.0s
After
6ms
/api/gateways914× faster
Before
1.8s
After
2ms
/api/agentic/summary20× faster
Before
200ms
After
10ms
/api/announcements faster
Before
50ms
After
8ms
/api/daemon/status2.5× faster
Before
10ms
After
4ms

7

Endpoint dioptimasi

<25ms

Semua respons setelah cache

1,490×

Peningkatan tercepat

"Data kamu BARU SAJA ADA. Kenapa harus tunggu lagi?"

Lihat perbedaannya

Tanpa Tide
Navigasi
typical spinner load (ilustratif)Total: ~850ms
vs
Dengan Tide
Navigasi
2.8KB totalTotal: 0ms (dirasakan)

Cara Kerja Tide

5 layer, 1 hook. Tanpa konfigurasi.

Hidrasi sinkron sebelum first paint — render instan saat kunjungan ulang

sessionStorage
// Layer 1: sessionStorage cache (persist: true)
const cached = readCache(key, cacheTime)
if (cached) {
  setData(cached)     // 0ms — instant render
  setStale(true)      // mark as potentially stale
  if (hashCompare) lastHash = contentHash(cached)
}

Server mengirim update via WS broadcast setiap 5 detik — update DOM reaktif

WebSocket Push
// Layer 2: WebSocket push (wsPath dot-notation)
createEffect(() => {
  const msg = wsData()
  const extracted = getByPath(msg, opts.wsPath)
  if (hashCompare && contentHash(extracted) === lastHash)
    return  // identical — skip re-render
  setData(extracted)  // 12ms from server to DOM
})

Server-side cache mengembalikan dalam 2ms (dashboard) hingga 16ms (query kompleks)

HTTP SWR Fetch
// Layer 3: HTTP SWR fetch (url shorthand + ETag)
const fresh = await fetchWithRetry(fetcher, retries, signal)
if (fresh === NOT_MODIFIED) return  // 304 — no update
if (hashCompare && contentHash(fresh) === lastHash)
  return  // content identical — skip DOM update
setData(fresh)
writeCache(key, fresh)

Pemulihan eksponensial 1d/2d/4d, abort request basi saat re-fetch

Retry + Abort
// Layer 4: Retry + Abort + Dedup
const controller = new AbortController()
const fetchFn = opts.dedupe !== false
  ? () => deduped(key, doFetch)  // prevent parallel fetches
  : doFetch
// Exponential backoff on WS: 1s → 2s → 4s → ... → 30s max
// Heartbeat ping every 25s keeps connection alive

Update UI sebelum server konfirmasi — rollback jika gagal

Optimistic UI
// Layer 5: Visibility + enabled() toggle
if (document.hidden) {
  stopPolling()  // save bandwidth when tab hidden
} else if (awayTime > 30_000 && refetchOnFocus) {
  refresh()      // re-validate after 30s away
}
// enabled: () => isLoggedIn() — reactive toggle
if (opts.enabled?.() === false) stopPolling()

Tap a layer to explore ↑

Perbandingan Tide

TanStack Query hebat untuk REST. Tide dibangun untuk data live.

TanStack Query

API response (server cache) N/A
Revisit render ~80ms
WebSocket-first
sessionStorage persist
Server cache convention
Bundle size 15.5KB

solid-swr

API response (server cache) N/A
Revisit render ~100ms
WebSocket-first
sessionStorage persist
Server cache convention
Bundle size 1.33KB

@uikode/tide ✨

API response (server cache) 2ms
Revisit render 0ms
WebSocket-first
sessionStorage persist
Server cache convention
Bundle size 2.8KB

"TanStack melakukan polling. Tide melakukan push. Ketika data berubah 10×/detik, kamu tidak mau bertanya — kamu mau langsung dikasih tahu."

"Kenapa tidak cukup tambahkan WebSocket ke TanStack?" →

🔄 Sudah pakai TanStack Query?

Sebelum — TanStack
import { createQuery } from '@tanstack/solid-query'

const q = createQuery(() => ({
queryKey: ['dashboard'],
queryFn: fetchDashboard,
}))
Sesudah — Tide
import { createTide } from '@uikode/tide'

const d = createTide({
key: 'dashboard',
fetcher: ({ signal }) => fetchDashboard(signal),
})
Baca Panduan Migrasi →

5 menit. Tanpa breaking change.

See It In Action

example.tsx
import { createTide } from "@uikode/tide"

// v1.1: URL shorthand — no fetcher needed!
const users = createTide<User[]>({
  key: "users",
  url: "/api/users",         // auto-creates fetcher
  transform: (raw) => raw.data,  // optional transform
  staleTime: 30_000,
  cacheTime: 300_000,
})

// Revisit? Renders instantly from sessionStorage.

Benchmark Produksi Nyata

Dari ACS Dashboard — 11 halaman, 12 gateway Hermes, backend Go, WS broadcast tiap 5d

Revisit render (sessionStorage)0ms
WS → DOM update0ms
First paint (server cache warm)0ms
First paint (cold, no cache)0ms
Bundle size (gzipped, core+skeleton)0KB

vs TanStack Query

Kunjungan ulang: ~80ms

Bundle: 15.5KB (+persist)

vs solid-swr

Kunjungan ulang: ~100ms

Bundle: 1.33KB

@uikode/tide

Kunjungan ulang: 0ms

Bundle: 2.8KB

ACS Dashboard menggunakan Tide — cache hit 0.5ms, TTFB 1ms, full load 16ms dari sessionStorage
Dashboard ACS produksi — Tide me-render data dari sessionStorage dalam 0.5ms sebelum API merespons

Waktu Respons API (Server Cache)

Endpoint Sebelum Sesudah Kecepatan
/api/dashboard8,941ms6ms1,490×
/api/agentic/tooling5,609ms16ms350×
/api/stack/status5,000ms6ms833×
/api/gateways1,828ms2ms914×
/api/agentic/summary200ms10ms20×
/api/announcements50ms8ms
/api/daemon/status10ms4ms2.5×

Semua endpoint < 25ms setelah server-side cache hangat

Lingkungan test: Windows 11, Go binary, 12 gateway Hermes, 26 skill, 279 task kanban, 10 provider API, WS broadcast tiap 5d. Diukur via CloakBrowser automated testing di localhost.

⚡ Jalan dalam 60 Detik

Install
npm install @uikode/tide solid-js
Bungkus app-mu
import { TideProvider } from '@uikode/tide'

function Root() {
return (
<TideProvider ws={{ url: 'wss://your-server/ws' }}>
<App />
</TideProvider>
)
}
Pakai di mana saja
import { createTide } from '@uikode/tide'

const todos = createTide({
key: 'todos',
fetcher: ({ signal }) =>
fetch('/api/todos', { signal }).then((r) => r.json()),
ws: (msg) => (msg.type === 'todos' ? msg.data : null),
})

Selesai. WebSocket, caching, reconnect, skeleton — semua ditangani.

12 Masalah, 2.8KB

🌊

WebSocket-first

Push utama, poll sebagai fallback

Kunjungan ulang instan

Hidrasi sessionStorage (0ms)

💀

Sistem skeleton

Komponen shimmer sesuai layout

🔄

Stale-while-revalidate

Tampilkan data, refresh di belakang

🎯

Prefetch saat hover

Panaskan cache sebelum navigasi

🔁

Retry dengan backoff

Eksponensial 1d/2d/4d pemulihan

🛑

Deduplikasi request

1 request aktif per key

Abort saat re-fetch

Data fetching bebas race condition

👁️

Jeda saat tab hidden

Hentikan polling saat tab tersembunyi

🔌

Tahan offline

Cache tetap melayani saat offline

📊

Dev logging

Hit/miss/timing di console

🪶

< 3KB gzipped

Tanpa dependensi, solid-js peer

Yang Dibangun dengan Tide

📊

Dashboard

Panel admin, monitoring, analitik

💬

Chat/Kolaborasi

Pesan, editing live, multiplayer

📈

Trading

Data finansial, order book, harga real-time

🤖

IoT/Perangkat

Stream sensor, manajemen armada

🎮

State game

Status lobby, state pemain

🔧

Dev tools

Viewer log, monitor proses

Pertanyaan yang Sering Ditanyakan

Apakah Tide bekerja dengan SSR / SSG?

Ya. Tide menghidrasi dari sessionStorage di klien. Server merender skeleton/fallback. Tidak ada mismatch hidrasi.

Bisakah saya pakai Tide dengan React atau Vue?

Tide khusus SolidJS. Signal SolidJS memungkinkan reactive subscription tanpa overhead. Kami pilih kedalaman daripada jangkauan.

Bagaimana ukuran bundle dibanding TanStack Query?

Tide: 2.8KB gzipped (core+skeleton), termasuk transport WebSocket. TanStack Query + plugin persist (paritas untuk revisit instan): 15.5KB — Tide ~5.4x lebih kecil. Catatan: solid-swr lebih kecil (1.33KB) tapi tanpa WebSocket, persistence, atau sistem skeleton.

Apakah Tide siap produksi?

Tide di v1.1.0 (rilis Juni 2026) dan dipakai di dashboard ACS (11 halaman, 12 gateway) secara nyata. Benchmark di halaman ini dari deployment tersebut. Masih muda dengan adopsi rendah — evaluasi sesuai kebutuhan.

Kenapa tidak cukup tambahkan adapter WebSocket ke TanStack Query?

TanStack didesain HTTP-first. Menempelkan WS memberi double caching, tanpa reconnection bawaan, dan kehilangan stale-while-revalidate saat transport switch. Tide WS-first sejak baris 1.

Apa yang terjadi saat WebSocket terputus?

Backoff eksponensial otomatis (1d/2d/4d) + fallback HTTP. UI tetap interaktif dengan cache lama, update saat koneksi pulih.

Bagaimana cara migrasi dari TanStack Query?

Kebanyakan kasus: ganti createQuery dengan createTide, ganti provider. Lihat Panduan Migrasi.

Lihat Panduan Migrasi lengkap →

Kirim lebih cepat. Sekarang.

npm install @uikode/tide

Lisensi MIT • Dibuat oleh Andy Vandaric • © 2026 UIKode