3 poin oleh GN⁺ 5 jam lalu | Belum ada komentar. | Bagikan ke WhatsApp
  • Hanya beberapa tahun lalu, sinkronisasi data multipemain waktu nyata adalah salah satu masalah tersulit yang memerlukan tenaga ahli dan investasi setingkat perusahaan, tetapi kini bahkan proyek hobi pun bisa mewujudkan UI multipemain hanya dengan sekali npm install
  • Automerge adalah alat untuk membangun model data yang local-first, aman untuk multipemain, dan memiliki kontrol versi; ia secara otomatis menangani persistensi data, pengelolaan riwayat, siaran ke kolaborator, dan penyelesaian konflik dengan cara yang mirip pola useState di React, tanpa UI perlu memikirkannya
  • Dalam kasus Ducking, editor audio multipemain berbasis browser, kuncinya adalah merancang model data agar terpetakan secara alami ke operasi CRDT
  • Untuk kasus yang tidak dijamin oleh Automerge, seperti pengurutan ulang daftar, kode di lapisan aplikasi perlu langsung mengimplementasikan invariant yang lebih kuat
  • Makna terpentingnya adalah bahwa pengeditan kolaboratif waktu nyata, yang dulu seperti sihir tingkat industri, kini bisa diterapkan dengan bebas bahkan pada aplikasi kecil untuk segelintir orang

Latar belakang — proyek Ducking

  • Selama beberapa bulan terakhir, dibuat editor audio multipemain berbasis browser bernama Ducking untuk podcast pasangan penulis
  • Terasa aneh bahwa pengeditan audio masih bertahan pada aplikasi desktop pengguna tunggal berumur 20 tahun dan alur bertukar file
    • Saat satu orang mengedit klip, orang lain seharusnya bisa memperbaiki transkrip atau menyesuaikan setelan EQ — dibutuhkan alur kerja kolaboratif seperti Google Docs atau Figma
    • Juga dibutuhkan alat kolaborasi modern seperti komentar, riwayat, dan pelacakan perubahan
  • Tulisan sebelumnya membahas desain UI yang unik dan model tata letak audio, yang membuat editor tunggal lebih efektif, tetapi yang benar-benar diinginkan adalah alur kerja yang lebih kolaboratif

Cara kerja Automerge

  • Semua data Ducking selain blob audio disimpan dalam dokumen Automerge
  • Pola intinya akan terasa akrab bagi pengembang React: ambil data lewat hook lalu render, kirim permintaan perubahan asinkron, dan setelah data berubah hook akan memicu render ulang
    • Contoh penggunaan hook useDocument: dokumen diterima dalam bentuk const [doc, changeDoc] = useDocument<Episode>(docUrl), lalu saat nilai input berubah diperbarui dengan changeDoc((d) => { d.title = e.target.value })
  • Operasi pembaruan data tampak imperatif, tetapi berbeda dari objek dan array JS native
    • Metodenya lebih sedikit, tidak langsung memodifikasi (mutate), dan secara internal mencegat perubahan lalu mengubahnya menjadi item changelist dalam riwayat dokumen
  • Untuk penggunaan sederhana, Automerge menangani hal yang dibutuhkan, tetapi ini bukan sihir; invariant-nya tidak selalu sesuai dengan makna yang diinginkan, sehingga perancangan model data yang cermat sangat penting
    • Sebisa mungkin, setiap tindakan pengguna yang bermakna dipetakan ke satu operasi tunggal yang disediakan Automerge
    • Tindakan pengguna terpisah pada data yang saling terkait sebaiknya terselesaikan secara alami dari sudut pandang invariant operasi Automerge tersebut
    • Pisahkan dengan jelas data kanonis yang disimpan dan data turunan yang dihitung

Pemodelan data untuk multipemain

  • Dalam model data Ducking, clip adalah jendela yang memutar sebagian dari sumber audio dasar yang tidak dapat diubah; ia bertugas atas rentang pemutaran, penerapan efek, dan pemakaian ruang pada timeline
    • Efek yang paling umum adalah klip mengatur volume audio dasar seiring waktu untuk membuat crossfade atau menghilangkan noise
  • Awalnya, tiap klip memiliki daftar level volume yang diindeks berdasarkan waktu relatif terhadap awal klip, tetapi ini menimbulkan masalah karena kebanyakan perubahan volume sebenarnya terkait audio dasar, bukan klip
    • Jika waktu mulai klip sedikit dimajukan, semua perubahan volume akan diterapkan ke bagian audio yang berbeda
    • Menulis kode yang memperbarui semua timestamp volume setiap kali waktu mulai klip berubah adalah pilihan yang buruk
  • Jika dua kolaborator mengedit waktu mulai klip secara bersamaan, masing-masing edit menggabungkan perubahan waktu mulai dan semua timestamp otomasi volume
    • Automerge tidak mengetahui hubungan kausal di antara perubahan itu, sehingga saat digabung hasilnya bisa kacau
    • Ini contoh klasik ketika satu tindakan bermakna mencoba memperbarui beberapa data persisten dengan cara kausal yang tidak dipahami CRDT
  • Solusinya adalah memindahkan data efek audio agar tidak lagi berbasis klip, melainkan berdasarkan kerangka waktu audio dasar
    • Dengan begitu, perubahan awal atau panjang klip tidak lagi memerlukan pembaruan; beberapa editor bisa mengubah waktu mulai, otomasi volume, dan efek lain secara independen, sehingga peluang merge yang benar jauh lebih tinggi
  • Perbedaan UI pengguna tunggal dan UI multipemain
    • Pada UI pengguna tunggal, kadang model data lama tetap dipakai lalu ditambah perhitungan ekstra saat penulisan
    • Pada UI multipemain, migrasi model data jauh lebih umum agar semua data persisten tetap ortogonal
  • Ada kecenderungan kuat untuk menyederhanakan saat menulis dan lebih banyak menghitung saat membaca, demi memaksimalkan merge otomatis dari Automerge
  • Saran tentang migrasi bentuk data
    • Terimalah bahwa bentuk data mungkin perlu dimigrasikan selama proses pengembangan, dan luangkan waktu sejak awal untuk berlatih agar migrasi besar pertama tidak terasa menakutkan
    • Ada berbagai pola seperti pemrosesan saat baca di klien atau upgrade massal di server
    • Jika bisa menemukan invariant praktis untuk memeriksa bahwa sebelum dan sesudah migrasi tetap sama, pekerjaan akan jauh lebih mudah
    • Di Ducking, audio semua proyek diekspor sebelum dan sesudah migrasi lalu diperiksa lewat audio fingerprint, sehingga perubahan skema besar pun bisa dirilis tanpa rasa takut

Implementasi pengurutan ulang daftar

  • Terkadang, untuk jaminan yang tidak disediakan Automerge, perlu langsung menulis invariant yang lebih kuat dengan kode di lapisan aplikasi
  • Masalah ini muncul saat mengimplementasikan magnetic timeline Ducking, yaitu daftar klip terurut yang akan diputar
    • Automerge menyediakan operasi array untuk menghapus dan menyisipkan item berdasarkan indeks, tetapi tidak menyediakan operasi pengurutan ulang atomik untuk item yang sudah ada
  • Sudah ada solusi yang dikenal
    • Martin Kleppmann menerbitkan makalah tentang operasi pengurutan ulang daftar atomik
    • Bersama Liangrun Da, ia juga menerbitkan makalah "Extending JSON CRDTs with Move Operations"
    • Ada juga draft PR untuk menambahkannya ke Automerge, tetapi belum di-merge
  • Masalah pada cara pengurutan ulang yang sederhana
    • Menghapus objek dari indeks saat ini lalu menambahkannya kembali di indeks tujuan
    • Bahkan jika invariant dua operasi itu digabungkan, tetap tidak ada jaminan invariant yang diinginkan, yaitu bahwa "saat banyak pengurutan ulang bersamaan, objek muncul tepat satu kali di dalam daftar"
    • Jika ada banyak penghapusan dan penambahan bersamaan, objek bisa muncul di beberapa posisi dalam daftar sekaligus (jika Alice dan Bob sama-sama memindahkan B dengan delete+insert, dua penghapusan bergabung menjadi satu tombstone, tetapi dua penyisipan masing-masing membuat elemen baru, sehingga keduanya tetap hidup dan B muncul dua kali)
  • Implementasi langsung di lapisan aplikasi untuk invariant "tepat satu kali"
    • Saat klip dimasukkan ke timeline, ia diberi semantic id
    • Saat diurutkan ulang, operasi hapus+sisip seperti di atas dipicu
    • Saat membaca, aplikasi memindai duplikasi dengan semantic id yang sama, memilih secara arbitrer item pertama yang belum dihapus, lalu mengabaikan sisanya
    • Dengan ini, objek hanya muncul satu kali dalam daftar dan semua pembaca tetap mencapai keadaan akhir yang sama
  • Pengurutan ulang daftar adalah satu-satunya operasi di Ducking yang belum disediakan Automerge; jika PR tersebut di-merge, logika tingkat aplikasi ini kemungkinan tak lagi diperlukan

Riwayat dokumen (Document history)

  • UI multipemain yang baik memerlukan alat pengelolaan riwayat; kolaborator ingin melihat perubahan saat mereka pergi, menambahkan komentar diff, membandingkan versi lama, dan melakukan rollback
  • Automerge melacak riwayat versi dokumen dan menyediakan primitive yang sangat baik untuk menangani riwayat serta perbandingan
    • Namun, bagaimana informasi itu ditampilkan dan konsep apa yang ditawarkan ke pengguna tetap harus diputuskan oleh pengembang aplikasi
  • Patchwork lab notes dari Ink & Switch sangat direkomendasikan
    • Khususnya menarik adalah upaya menampilkan branch kepada pengguna dan pekerjaan pada universal comments
  • Ducking akhirnya memakai model kolaborasi dan riwayat yang relatif sederhana
    • Riwayat versi linear dengan checkpoint bernama khusus pengguna; checkpoint menjadi unit pengelompokan perubahan sekaligus unit untuk diskusi, diff, dan rollback
    • Ada pula thread komentar yang bisa dikaitkan ke titik tertentu pada audio, area pada transkrip, atau checkpoint versi
  • Belum ada alasan yang cukup kuat untuk memperkenalkan branch, tetapi disebutkan bahwa itu mungkin berguna di masa depan

Teks dan marks

  • Bekerja dengan rich text sangat rumit, terutama saat mencoba menambahkan logika kustom di atas teks yang bisa diedit
    • Makalah Peritext sangat direkomendasikan untuk memahami kesulitan rich text dan perangkat lunak multipemain secara umum
  • Skema rich text Automerge mencakup marks, yaitu anotasi yang diterapkan pada rentang teks dan tetap konsisten meski teks diedit
    • Paling sering digunakan untuk format seperti tebal atau miring, tetapi juga bisa dibuat mark kustom khusus aplikasi
  • Dua penggunaan mark kustom di Ducking
    • Melacak area transkrip yang menjadi target thread komentar
    • Melacak timestamp kata-kata di transkrip sambil tetap mengizinkan pengeditan
      • Layanan transkripsi menyimpan transkrip ke Automerge sebagai objek richtext dengan mark informasi waktu pada tiap kata
      • Jika hanya satu kata diperbaiki karena typo kecil, mark tetap dipertahankan sehingga semua informasi waktu tetap utuh
      • Jika satu kalimat penuh diperbaiki, beberapa mark di tengah mungkin hilang, tetapi mark di awal dan akhir kalimat tetap ada sehingga setidaknya informasi waktu kasar masih tersedia
  • Salah satu batasan marks adalah datum-nya harus berupa nilai sederhana, umumnya string, dan tidak di-merge secara multipemain
    • Untuk data kecil dan tak berubah seperti informasi waktu transkrip, dipakai serialisasi JSON ke string
    • Untuk data yang lebih kompleks atau dapat berubah seperti thread komentar, mark hanya menyimpan id, sedangkan data sebenarnya disimpan di bagian lain dalam dokumen
  • marks menyediakan fondasi yang sangat baik untuk membangun fitur aplikasi di atas rich text multipemain

Tulisan berikutnya — susunan seri

  • Tulisan ini adalah bagian 2 dari trilogi tentang pembuatan Ducking
    • Bagian 1: menjelaskan desain UI perangkat lunak yang unik
    • Bagian 2 (tulisan ini): merekomendasikan meninjau Automerge dan menunjukkan bahwa proyek multipemain hobi bisa dibuat
    • Bagian 3 terakhir yang direncanakan: refleksi atas pengalaman membuat Ducking
  • Disebutkan pula untuk bagian 3 terakhir
    • Dukungan LLM digunakan bukan untuk meningkatkan produktivitas kerja, melainkan untuk memberi lebih banyak waktu membuat sketsa dan bersantai di hammock
    • Ada kesenangan tersendiri dalam membuat narrowcast software yang hanya perlu memuaskan segelintir orang

Pertanyaan yang diperkirakan

Bagaimana dengan data audio?

  • Semua data multipemain disimpan di Automerge, tetapi blob audio dasar tidak diletakkan di Automerge demi pemutaran cepat, sehingga perlu penanganan terpisah
  • Targetnya adalah kolaborator baru bisa mulai mendengar dan mengedit dalam 4 detik setelah halaman dimuat, lebih cepat daripada menyalakan aplikasi desktop dan jauh lebih cepat daripada mengunduh seluruh file proyek
    • Satu episode berdurasi 1 jam bisa bergantung pada sekitar 1 gigabita audio, terdiri dari 4 jam rekaman studio berkualitas tinggi ditambah efek dan musik latar
  • Pekerjaan layanan audio saat unggah demi cold start yang cepat
    • Mencadangkan audio asli
    • Mentranskripsikan ucapan untuk tampilan transkrip
    • Membuat waveform untuk tampilan timeline
    • Jika dari rekaman 40 menit hanya 1 menit yang dipakai, file diiris menjadi jendela pendek agar kebanyakan klien hanya perlu menerima satu atau dua potongan kecil
    • Potongan-potongan itu ditranskode ke format terkompresi untuk menyediakan versi lossy yang bisa diputar segera sementara audio berkualitas tinggi diunduh di latar belakang
  • Lapisan data UI mengelola pemuatan versi cepat dari data yang langsung diperlukan sesuai niat pengguna, sekaligus versi berkualitas tinggi dari seluruh audio yang benar-benar dipakai
    • IndexedDB API di browser berguna untuk caching bertingkat dan penyimpanan content-addressable; jika dipakai ia tetap ada, jika tidak dipakai ia akan hilang lewat eviction otomatis
  • Setelah semua pemrosesan dan caching lokal ini selesai, sisa UI dapat mengasumsikan akses acak yang cepat ke audio dan fokus pada alur kerja pengeditan

Mengapa membuat UI server+browser, bukan aplikasi local-first?

  • Penulis menyukai aplikasi local-first seperti Obsidian yang bisa berfungsi sepenuhnya tanpa server, terutama bentuk yang juga menawarkan pengalaman berbayar berbasis cloud sambil memberi jalur keluar yang tepercaya
  • Pada awalnya, opsi yang diambil adalah aplikasi Tauri dengan penyimpanan filesystem lokal dan sinkronisasi server opsional
    • UI dibangun berdasarkan antarmuka data yang bisa disuplai baik oleh server maupun aplikasi lokal
    • Ini menjadi pengaman agar, apa pun pendanaan di masa depan, tidak ada godaan untuk memonetisasi aplikasi lebih jauh lewat lock-in
  • Setelah itu disadari bahwa ini bukan SaaS, melainkan sesuatu yang ingin dipakai bersama pasangan dan beberapa teman dekat
    • Karena insentif untuk menyalahgunakannya hilang dan biaya operasional permanen rendah, dipilih cara termudah untuk membuatnya
  • Setelah berhasil mencapai cold start sekitar 3 detik, tak ada lagi yang ingin membuang waktu mengunduh dan memasang aplikasi native
  • Ada harapan agar aplikasi audio bisa langsung melompat dari dunia desktop-only saat ini ke dunia local-first dengan opsi sinkronisasi, sehingga melewati 10–20 tahun masa peralihan SaaS lock-in

Apakah Automerge aman dan siap web-scale? Haruskah startup memakainya?

  • Jawaban jujur dan santai adalah tidak tahu; ini bukan penolakan, memang benar-benar belum tahu
  • Saat penulis mulai bekerja, pengeditan multipemain waktu nyata tanpa konflik terasa seperti sihir; 10 tahun lalu memang ada solusi yang dikenal untuk masalah tertentu, tetapi memerlukan tim yang didanai dan keahlian lintas bidang
    • Sekarang, cukup ambil satu dependensi, lalu secara umum UI bisa dibuat dengan cukup intuitif dan dipakai berkolaborasi waktu nyata bersama teman
  • Dari sisi keamanan, Ducking saat ini dilindungi oleh akses jaringan terbatas dan tahap otorisasi saat membuat koneksi websocket ke server Automerge
    • Pengguna tidak bisa menemukan atau mengedit proyek yang tidak mengundang mereka
    • Atribusi pengguna untuk edit dan komentar hanya sebagian aman dan masih bergantung pada asumsi bahwa teman-teman tidak berbuat nakal
    • Hak akses granular seperti hanya boleh komentar tanpa edit, hanya boleh mengedit sebagian proyek, atau mengendalikan keterlihatan proyek masih memerlukan perancangan yang hati-hati
  • Keyhive yang sedang dikembangkan Ink & Switch menyediakan model kontrol akses berbasis capability yang aman secara kriptografis
    • Ini akan memudahkan berbagi aplikasi Automerge secara terbuka bahkan kepada pengguna yang tidak tepercaya, tetapi belum siap saat ini

Apakah Automerge lebih baik?

  • Ada solusi lain di bidang ini yaitu Yjs, tetapi tidak ada penilaian pasti mana yang paling cocok
  • Saran yang tetap berlaku
    • Pikirkan masalahnya dengan mendalam, lakukan perkiraan kasar terhadap batas yang mungkin ditemui, buat prototipe dengan beberapa alternatif, dan akui dengan jujur bahwa mungkin masalah Anda tidak terlalu sulit sehingga tidak perlu solusi paling mutakhir dan paling canggih
  • Dalam kasus Ducking, prototipe cepat dan penelusuran dokumentasi menunjukkan bahwa Automerge cukup matang dan cukup cepat untuk kebutuhan tersebut
  • Yang lebih penting, ekosistem Ink & Switch terasa menarik secara estetis
    • Automerge bukan sekadar mesin sinkronisasi dan kontrol versi, melainkan bagian dari visi yang lebih besar untuk membuat perangkat lunak menjadi lebih aman, kolaboratif, fleksibel, menyenangkan, dan personal
    • Ada harapan Keyhive dan lainnya berhasil, serta makin banyak perangkat lunak kecil namun magis untuk segelintir orang bermunculan

Belum ada komentar.

Belum ada komentar.