Skip to main content
Mod dapat menggambar antarmukanya sendiri di Claude Code dan mengubah bagian antarmuka yang sudah digambar Claude Code. Setiap tempat mod dapat menggambar disebut render site, seperti panel, pita di atas prompt, atau spinner. Claude Code menaikkan event ui.render setiap kali akan menggambar render site, dan hook Anda untuk event tersebut mengembalikan apa yang akan digambar di sana. Peta ini menunjukkan di mana mod dapat menggambar dalam sesi terminal: Peta sesi terminal Claude Code. Mod dapat menambahkan panel sebagai sidebar di sebelah kanan, toast di sudut kanan atas transkrip, baris log dalam transkrip, pita di atas prompt, dan baris status di bawah prompt. Mod dapat menggambar ulang pesan, baris panggilan alat, dan spinner. Prompt adalah milik Claude Code sendiri. Peta sesi terminal Claude Code. Mod dapat menambahkan panel sebagai sidebar di sebelah kanan, toast di sudut kanan atas transkrip, baris log dalam transkrip, pita di atas prompt, dan baris status di bawah prompt. Mod dapat menggambar ulang pesan, baris panggilan alat, dan spinner. Prompt adalah milik Claude Code sendiri. Di terminal yang lebih sempit, panel duduk di atas prompt daripada di samping transkrip. Bangun mod pertama Anda sebelum Anda mulai di sini. Mulai dengan contoh yang dikerjakan, yang membangun panel dengan dua tab dan penghitung, kemudian baca bagian untuk setiap bagian yang ingin Anda ubah.
Untuk mencari satu prop atau batas, lihat referensi.

Bangun panel dengan tab

Di bagian ini Anda membangun mod yang menambahkan perintah /hello-tabs, dan perintah membuka panel. Panel adalah sidebar di samping transkrip dalam terminal fullscreen yang lebar, atau wilayah berbingkai di atas prompt sebaliknya. Panel ini menampilkan dua tab, dan tab kedua memiliki tombol yang menambah satu ke penghitung. Hitungan masih ada setelah Anda memulai ulang Claude Code. Mod yang selesai terlihat seperti ini. Rekaman membuka panel, beralih ke tab kedua, menekan tombol beberapa kali, dan kembali ke tab pertama:
Claude Code tidak memiliki elemen tab bawaan, jadi tab adalah dua tombol dalam satu baris. Mod melacak mana yang aktif dan menggambar konten tab tersebut di bawah baris.
1

Buat plugin

Mod adalah plugin dengan manifest, hooks.json yang menunjuk ke kode Anda, dan file kode. Buat mod menjelaskan masing-masing. Buat direktori bernama hello-tabs dengan direktori .claude-plugin dan hooks di dalamnya, kemudian simpan dua file pertama.Simpan manifest sebagai hello-tabs/.claude-plugin/plugin.json:
hello-tabs/.claude-plugin/plugin.json
Beri nama titik masuk Anda di hello-tabs/hooks/hooks.json:
hello-tabs/hooks/hooks.json
2

Tulis kodenya

Kode melakukan tiga pekerjaan, satu di setiap hook:
  • Menambahkan perintah /hello-tabs
  • Membuka panel saat Anda menjalankan perintah tersebut
  • Menggambar konten panel: baris tab dan badan tab yang terbuka
Dua variabel tingkat modul, tab dan count, menyimpan status panel.Simpan ini sebagai hello-tabs/hooks/register.js:
hello-tabs/hooks/register.js
Setiap hook juga melakukan sesuatu yang tidak jelas dari kode:
  • session.start juga membaca hitungan yang disimpan dari $.store, penyimpanan kunci-nilai yang bertahan antar sesi.
  • command.run hanya memberi tahu Claude Code bahwa panel ada. Membuka panel tidak menggambar apa pun dengan sendirinya: Claude Code kemudian menaikkan ui.render untuk menanyakan apa yang ada di dalamnya.
  • ui.render mengembalikan pohon elemen, Box yang menyimpan kotak lain, teks, dan tombol, dan membangunnya lagi dari tab dan count setiap kali berjalan.
Menekan tombol menjalankan callback onPress-nya, yang mengubah variabel dan memanggil redraw. Claude Code kemudian menjalankan hook ui.render lagi, dan hook membangun pohon baru dari nilai baru. Setiap gambar interaktif menggunakan siklus render itu: callback mengubah status, dan hook merender lagi dari status baru.
3

Buka panel

Di shell Anda, mulai Claude Code dengan claude --plugin-dir ./hello-tabs. Di prompt Claude Code, jalankan /hello-tabs. Panel terbuka dengan 1: One dan 2: Two di seluruh bagian atas. Tekan 2, kemudian tekan a, pintasan keyboard untuk Add one, beberapa kali. Hitungan naik.
4

Periksa bahwa hitungan disimpan

Tekan Esc untuk menutup panel, kemudian keluar dari sesi. Di shell Anda, mulai Claude Code lagi dengan perintah claude --plugin-dir ./hello-tabs yang sama, dan di prompt Claude Code jalankan /hello-tabs. Hitungan ada di mana Anda meninggalkannya.Untuk menghapus hitungan, buat mod memanggil $.store.delete('count'). Jaga status mencakup berapa lama setiap jenis nilai bertahan.

Pilih di mana menggambar

Hook ui.render berjalan untuk setiap render site kecuali Anda mempersempit ke yang Anda inginkan. Untuk memilih render site, teruskan filter, disebut matcher, sebagai argumen kedua ke on. { component: 'Pane' } menjalankan hook hanya untuk panel. Dalam hook, e.component menamai situs, e.surface mengatakan aplikasi mana yang menggambar, dan e.props menyimpan data situs sendiri. Untuk panel, e.requestId adalah id yang Anda buka dengannya. Dua situs kosong sampai mod mengisinya, panel dan pita. Pilih tab untuk melihat apa itu masing-masing dan cara menggambar di dalamnya:
Panel adalah sidebar di samping transkrip dalam terminal fullscreen yang lebar, atau wilayah berbingkai di atas prompt sebaliknya. Dengan beberapa panel terbuka, masing-masing mendapat tab yang menampilkan judulnya.Panel muncul saat mod Anda memanggil $.ui.open dengan id yang Anda pilih, seperti dalam $.ui.open({ id: 'hello-tabs' }). Buka panel pada waktu yang tepat mencakup bidang lain dan kapan panel menunggu terminal yang lebih lebar.Untuk menggambar di panel Anda, filter pada { component: 'Pane' } dan periksa bahwa e.requestId adalah id Anda.

Ubah apa yang sudah digambar Claude Code

Claude Code menggambar sebagian besar antarmukanya sendiri: pesan, baris panggilan alat, spinner, dan lainnya. Masing-masing bagian itu adalah render site juga, jadi mod dapat mengubah gaya atau menggantinya. Untuk mengubah satu, filter hook ui.render Anda pada namanya dari tabel ini: Di situs yang sudah digambar Claude Code, hook Anda memiliki tiga pilihan: ubah detail, ganti gambar, atau biarkan saja. Pilih tab untuk melihat masing-masing diterapkan pada spinner. Contoh membaca variabel calls yang hook lain hitung, seperti dalam mod tutorial.
Untuk menjaga gambar Claude Code dan mengubah satu bagian darinya, teruskan next salinan event dengan props yang diubah. Hook ini mengubah teks setelah kata spinner:
Spinner menjaga animasi dan katanya, dan teks Anda mengikuti kata:
Prompt izin bukan render site, jadi mod tidak dapat mengubah apa yang ditampilkannya. Dialog pertanyaan, AskUserQuestion, adalah satu, jadi mod dapat mengubah itu. Terminal dan aplikasi Desktop tidak menaikkan semua situs yang sama. Pane, AbovePrompt, Spinner, dan situs transkrip bekerja di keduanya. Beberapa baris status lainnya hanya diangkat di terminal. Tabel render sites mencantumkan di mana masing-masing diangkat.

Buka panel pada waktu yang tepat

Panel hanya muncul saat mod Anda membukanya. Bagaimana dan kapan Anda membukanya menentukan apakah itu mengambil fokus keyboard, berapa banyak ruang yang dimintanya, dan apakah itu menampilkan sama sekali di terminal yang sempit. Untuk membuka panel, panggil $.ui.open dengan id yang Anda pilih. id adalah nama panel: hook ui.render Anda memeriksanya, dan Anda meneruskannya lagi untuk menutup panel.
Untuk menutup panel, panggil $.ui.close dengan id yang Anda buka dengannya:
Selain id, $.ui.open mengambil bidang opsional ini: Untuk membiarkan perintah membuka panel saat Claude bekerja, tambahkan immediate: true saat Anda mendaftarkan perintah. Tanpanya, perintah yang diketik selama giliran menunggu giliran berakhir.

Ketika panel menunggu terminal yang lebih lebar

Panel yang dibuka mod Anda tanpa diminta tidak muncul di terminal sempit, jadi tidak dapat mengambil alih layar kecil. Apakah itu muncul tergantung pada apa yang membukanya:
  • Dibuka oleh sesuatu yang dilakukan pengguna, seperti perintah yang mereka jalankan atau tombol yang mereka tekan, panel muncul pada lebar apa pun
  • Dibuka oleh mod Anda bertindak sendiri, seperti dari timer atau hook turn.start, panel hanya muncul di terminal setidaknya 144 kolom lebar. Setelah pengguna telah membuka panel itu sendiri sekali, 110 kolom cukup.
Ketika panel muncul, $.ui.open diselesaikan ke { isPlaced: true }. Ketika panel menunggu, isPlaced adalah false dan reason adalah string yang mengatakan mengapa. Panel yang menunggu muncul saat pengguna membukanya atau memperlebar terminal. Untuk mengatakan sesuatu tersedia tanpa membuka panel, panggil $.ui.toast('Your message'), yang menampilkan pemberitahuan kecil yang hilang setelah beberapa detik.

Bangun pohon dari elemen

Apa yang dikembalikan hook ui.render adalah pohon elemen: deskripsi apa yang akan digambar, terbuat dari kotak, teks, dan kontrol bersarang di dalam satu sama lain. Anda mendeskripsikan gambar, dan Claude Code merender di terminal atau aplikasi Desktop. Untuk mendapatkan elemen, panggil $.ui.resolve(e) dalam hook Anda, seperti dalam const { Box, Text, Button } = $.ui.resolve(e). Setiap elemen adalah fungsi. Anda meneruskan prop, dan Anda menempatkan elemen dan string yang ada di dalamnya dalam children. Sebagian besar gambar menggunakan empat elemen. Pilih tab untuk melihat masing-masing dan cara terminal menggambarnya:
Text menggambar string, dengan gaya opsional seperti bold dan color:
Tabel ini mencantumkan setiap elemen: Jika modul Anda adalah file .tsx atau .jsx, Anda dapat menulis pohon sebagai JSX. Dekonstruksi elemen dari $.ui.resolve(e) terlebih dahulu, karena modul hooks tidak memiliki global elemen. Jika pohon menggunakan elemen yang tidak dimiliki aplikasi, prop yang tidak diambil elemen, atau anak di mana tidak ada, Claude Code menggambar versinya sendiri dari situs. Dalam sesi yang dimulai dengan --plugin-dir, baris transkrip mengatakan demikian, seperti ui.render (Pane) refused: Text prop "bogusProp" is not allowed; the engine drew its own. Debug log mencatatnya sebagai ui.render (Pane): a hook returned a tree that does not validate dengan alasan yang sama. Tidak ada yang lain muncul dalam sesi, jadi ketika gambar tidak muncul, periksa baris itu atau log.

Gambar grid sel berwarna

Untuk peta panas, sparkline, atau papan permainan di terminal, gambar satu Raster dan bukan Box untuk setiap sel. Raster mengambil key, ukurannya dalam columns dan rows, dan cells, yang mengemas setiap sel menjadi satu string. Setiap sel adalah tiga angka: titik kode karakter, warnanya, dan warna latar belakangnya. Warna adalah angka heksadesimal dengan dua digit masing-masing untuk merah, hijau, dan biru, seperti 0xc62828 untuk merah, atau 0x01000000 untuk default terminal. Aplikasi Desktop tidak memiliki Raster, jadi periksa e.surface dan gambar teks di sana. Badan panel ini menggambar peta panas tiga kali dua:
Di terminal, panel menampilkan grid: Panel di terminal yang menyimpan grid kecil blok berwarna, dua baris tiga. Baris atas adalah hijau, amber, dan merah. Baris bawah adalah hijau, hijau, dan amber. Array rows adalah bagian yang akan Anda ubah, dan cellsOf mengubahnya menjadi string yang dikemas. Hook menggambar hanya di panel yang id-nya adalah heat, jadi buka satu dengan $.ui.open({ id: 'heat' }) dari perintah, seperti contoh hello-tabs membuka panelnya. Setiap karakter harus lebar satu sel. Untuk menganimasikan Raster yang sudah di layar, panggil $.ui.blit dengan id panel sebagai requestId, key Raster, ukuran yang sama, dan sel baru. Untuk contoh ini, itu adalah $.ui.blit({ requestId: 'heat', key: 'grid', columns: 3, rows: 2, cells: cellsOf(newRows) }). Itu melukis ulang elemen itu saja tanpa menjalankan hook ui.render Anda lagi.

Merespons penekanan dan pengetikan

Ketika pengguna menekan tombol, mengetik ke bidang, atau memilih dari daftar yang digambar mod Anda, Claude Code memanggil fungsi yang Anda berikan kontrol itu, dan itu berjalan dalam modul Anda. Setiap kontrol mengambil callback-nya sendiri:
  • Button: mengambil onPress(e), di mana e.surface adalah aplikasi tempat penekanan berasal
  • Input: mengambil onSubmit(value) dan onInput(value)
  • Select: mengambil onSelect(value) dengan pilihan dalam options, daftar setidaknya satu pilihan dengan nilai unik, seperti [{ value: 'sm', label: 'Small' }, { value: 'lg', label: 'Large' }]
Tes menekan atau mengetik ke kontrol dengan key-nya, jadi berikan masing-masing satu. Setiap penggunaan kontrol juga menembakkan ui.press, ui.input, atau ui.select dengan key dalam e.element, dan mod lain dapat menghubungkan event tersebut. Hook-nya berjalan sebelum callback Anda, jadi itu melihat apa yang pengguna ketik ke Input Anda dan dapat mengubahnya atau menjawab sebagai pengganti callback Anda. API mods tidak memiliki metode yang menekan tombol mod lain.

Fokus keyboard dan pintasan keyboard

Mod Anda tidak pernah membaca keyboard itu sendiri. Pengguna menekan kunci, Claude Code memutuskan kontrol mana yang dimaksudkan, dan callback kontrol itu berjalan. Terlepas dari pintasan keyboard digit di pita, itu hanya terjadi saat panel atau pita Anda memiliki fokus keyboard. Sisa waktu, kunci pergi ke prompt.

Bagaimana panel mendapat fokus keyboard

Panel mendapat fokus keyboard dalam salah satu dari tiga cara:
  • Mod Anda membukanya dengan focus: true dari perintah atau penekanan
  • Pengguna menekan Ctrl+X kemudian Tab
  • Pengguna mengkliknya
Claude Code memberikan focus: true hanya saat prompt kosong dan tidak ada yang lain memiliki fokus keyboard. Panel yang terbuka saat pengguna mengetik tidak mengambil keystroke mereka.

Apa yang dilakukan setiap kunci

Tabel ini mencantumkan apa yang dilakukan kunci saat panel atau pita Anda memiliki fokus keyboard: Mod tidak dapat mengikat Tab atau tombol panah ke apa pun yang lain, jadi permainan mengarahkan dengan w, a, s, dan d.

Atur pintasan keyboard dan fokus pertama

Dua prop pada kontrol memutuskan bagaimana keyboard mencapainya:
  • hotkey: untuk membiarkan pengguna menekan Button dengan satu kunci, berikan hotkey dari satu digit atau satu huruf kecil, seperti dalam hotkey: 'a'
  • autoFocus: untuk memilih kontrol mana yang memiliki fokus saat panel terbuka, tambahkan autoFocus: true ke dalamnya. Tinggalkan prop dari yang lain, karena Claude Code menolak autoFocus: false.
Bagaimana pintasan keyboard ditampilkan tergantung pada tombol dan aplikasi: Di terminal, beri nama kunci dalam label tombol berbingkai, atau gunakan plain: true, sehingga pengguna dapat melihat apa yang harus ditekan. Referensi elemen memiliki aturan Button lainnya: action, pintasan keyboard digit di pita, dan dua tombol pada satu pintasan keyboard.

Ambil input yang diketik dan gambar baris untuk setiap item

Banyak panel adalah bidang teks dengan daftar di bawahnya. Contoh di bagian ini adalah panel catatan: Anda mengetik catatan dan menekan Enter untuk menambahkannya, dan setiap catatan memiliki tombol x yang menghapusnya. Dengan dua catatan ditambahkan, terminal menggambar panel dengan cara ini:
Contoh menggunakan dua teknik:
  • Ambil input yang diketik: Input memanggil onSubmit(value) dengan teks bidang saat pengguna menekan Enter, dan onInput(value) pada setiap perubahan
  • Gambar daftar: petakan data Anda ke satu baris masing-masing, dan berikan setiap tombol baris key-nya sendiri
Hook ini menggambar konten panel:
Untuk mencoba panel:
  • Tambahkan catatan: ketik baris dan tekan Enter. Baris muncul sebagai baris baru, dan bidang kosong.
  • Hapus catatan: tekan Tab sampai tombol x catatan memiliki fokus, kemudian tekan Enter. x adalah label tombol dan bukan pintasan keyboard, jadi mengetik huruf tidak menekan itu.
Setiap perubahan mengikuti siklus render yang sama seperti hello-tabs: callback mengubah notes, memanggil redraw, dan menyimpan daftar ke $.store. Bidang kosong setelah setiap submit karena prop value-nya. value adalah teks yang dipegang bidang saat digambar, dan pengetikan pengguna menggantinya sampai hook Anda menggambar bidang lagi. Contoh selalu menggambar bidang dengan ''. Contoh menyimpan catatan dan tidak memuatnya. Untuk membawanya kembali di sesi berikutnya, bacalah dalam hook session.start, cara hello-tabs membaca count. Tiga prop membuat baris bidang, Note: Type a note and press Enter ⏎ add: Mengirimkan Input tidak memulai giliran kecuali callback Anda memanggil $.prompt.submit.

Gambar ulang situs

Gambar adalah snapshot: itu menunjukkan apa yang dikembalikan hook ui.render Anda terakhir kali hook berjalan. Untuk menampilkan sesuatu yang baru, hook harus berjalan lagi. Claude Code menjalankannya lagi untuk beberapa perubahan, dan mod Anda meminta sisanya.

Ketika Claude Code menggambar ulang tanpa diminta

Claude Code menjalankan hook ui.render Anda lagi ketika prop situs berubah atau lebar terminal berubah. Itu tidak menjalankan hook pada timer, dan itu tidak dapat mengatakan ketika variabel dalam modul Anda berubah.

Gambar ulang saat data Anda berubah

Untuk memiliki situs Anda digambar lagi setelah data Anda sendiri berubah, panggil $.ui.invalidate('ui.render'). Panel ini menghitung penekanan. Callback tombol mengubah count, kemudian meminta redraw:
Setiap penekanan menaikkan angka di panel. Contoh hello-tabs membungkus panggilan yang sama dalam fungsi redraw-nya. Nilai yang Anda simpan dalam $.state tidak memerlukan panggilan, karena menulis nilai menggambar ulang situs yang membacanya.

Gambar ulang pada timer

Untuk menjaga jam, hitung mundur, atau nilai dari luar sesi saat ini, gambar ulang sesuai jadwal. Mulai timer dalam hook session.start modul. Jika modul sudah memiliki satu, seperti hello-tabs, tambahkan baris $.clock.every ke dalamnya:
Claude Code sekarang menjalankan hook ui.render Anda sekali per detik. Timer berhenti saat modul dimuat ulang, dan salinan baru modul memulai miliknya sendiri.

Seberapa sering situs dapat digambar ulang

Claude Code membatasi seberapa sering itu menggambar ulang situs, jadi mod Anda dapat memanggil $.ui.invalidate sesering data berubah. Panel yang terlihat dan pita memiliki batas yang lebih tinggi daripada situs lainnya, dan tabel batas memiliki angkanya. Panggilan yang datang lebih cepat dari batas digabungkan menjadi satu redraw. Redraw itu menjalankan hook Anda sekali, dan hook membaca data Anda seperti adanya saat itu, jadi nilai terbaru ditampilkan dan nilai di antaranya tidak. Animasi tidak dapat berjalan lebih cepat dari batas.

Jaga status

Mod memiliki tiga tempat untuk menyimpan nilai, dan mereka berbeda dalam berapa lama nilai bertahan: sampai modul dimuat ulang, sampai sesi berakhir, atau dari satu sesi ke sesi berikutnya. Pilih berdasarkan berapa lama nilai harus bertahan: $.store.get(key) diselesaikan ke nilai atau undefined, dan $.store.set(key, value) mengambil nilai JSON apa pun.

Simpan nilai dalam $.state

$.state menyimpan nilai untuk panjang sesi, dan itu menggambar ulang untuk Anda. Ini adalah status reaktif: hook ui.render yang membaca nilai berlangganan ke dalamnya, jadi Claude Code menggambar ulang situs itu setiap kali Anda menulis nilai, dan Anda tidak memanggil $.ui.invalidate. Nilai dalam $.state juga bertahan reload modul, yang variabel tidak. Untuk mengaturnya, deklarasikan nilai Anda, arahkan manifest Anda ke deklarasi, kemudian tentukan dan gunakan setiap nilai. Contoh memindahkan count dari hello-tabs ke dalam $.state.

Deklarasikan nilai

Deklarasikan nilai dalam file tipe. Kunci luar adalah nama plugin Anda, dan setiap entri di bawahnya adalah nilai dan tipenya. Simpan ini sebagai hello-tabs/types/index.d.ts:
hello-tabs/types/index.d.ts

Arahkan manifest ke deklarasi

Untuk membiarkan claude plugin validate memeriksa kode Anda terhadap file itu, tambahkan bidang types ke manifest dengan jalurnya:
hello-tabs/.claude-plugin/plugin.json

Tentukan, baca, dan tulis nilai

Dalam modul Anda, tentukan setiap nilai dengan default, bacalah saat menggambar, dan tulislah dari callback. atom menamai nilai dan defaultnya, read mengembalikannya, dan update menulisnya. Tiga pembantu memanggil $.state.get dan $.state.set untuk Anda:
Karena hook ui.render membaca count, Claude Code menjalankan hook lagi setiap kali tombol menulisnya. Tiga aturan berlaku untuk kode:
  • Tulis plugin dan key sebagai string literal: claude plugin validate membacanya dari sumber Anda
  • Deklarasikan setiap nilai dalam file tipe: jika tidak, validasi gagal dengan hello-tabs.count is not declared
  • Tulis dari callback atau hook event lain: hook ui.render dapat membaca status dan tidak dapat menulisnya, jadi tulis dari onPress, onSubmit, atau hook untuk event lain

Ubah hello-tabs untuk menggunakan $.state

Untuk memindahkan count dalam hello-tabs ke dalam $.state, ubah setiap baris yang menggunakannya:
  • Di atas modul: tambahkan baris import, dan ganti let count = 0 dengan baris atom
  • Dalam hook ui.render: tambahkan baris read sebelum tabButton, dan gambar 'Count: ' + n dalam Text
  • Dalam tombol Add one: ganti onPress dengan yang dalam Simpan dari lebih dari satu sesi, yang menyimpan hitungan serta menulisnya
  • Dalam hook session.start: ganti dua baris yang membaca saved dengan panggilan loadCount dari Muat nilai yang disimpan lagi setelah /clear
Simpan redraw untuk tombol tab, karena tab masih variabel.

Muat nilai yang disimpan lagi setelah /clear

Jika mod Anda menyalin nilai yang disimpan dari $.store ke dalam $.state pada session.start, itu harus menyalinnya lagi setelah /clear, /resume, atau /branch. Perintah tersebut mengembalikan setiap nilai $.state ke defaultnya, dan session.start tidak dipecat lagi. classic.SessionStart dipecat setelah masing-masing, dengan e.source diatur ke clear, resume, atau fork, jadi salin nilai lagi dalam hook di atasnya. Jika tidak, gambar Anda menampilkan default, dan callback yang menyimpan nilai $.state menulis default di atas apa yang Anda simpan. Kode ini memuat count dari kedua hook. Itu dibangun di atas versi $.state dari hello-tabs, di mana count adalah atom dan update diimpor. Letakkan loadCount di atas register, dan tambahkan panggilan loadCount ke hook session.start yang sudah Anda miliki. classic.SessionStart juga dipecat saat startup dan setelah pemadatan, yang tidak mengatur ulang $.state, jadi filter pada source menjaga hook ke tiga reset:
Dengan kedua hook di tempat, panel menampilkan hitungan yang disimpan setelah /clear dan bukan 0, dan penekanan berikutnya dari Add one menambah ke hitungan yang disimpan. loadCount menulis nilai yang disimpan di atas yang ada dalam $.state, dan session.start dipecat lagi setiap kali modul dimuat ulang. Untuk menjaga penyimpanan agar tidak tertinggal, simpan pada setiap perubahan, seperti yang dilakukan tombol Add one. Untuk memeriksa reload tanpa sesi, uji gambar setelah /clear.

Simpan dari lebih dari satu sesi

Setiap sesi di mesin Anda yang menjalankan mod Anda berbagi satu $.store. get diikuti oleh set bukan atomik. Ketika dua sesi masing-masing membaca nilai, mengubahnya, dan menulisnya kembali, mereka bersaing, dan penulisan kedua menggantikan yang pertama. Dua pilihan membuat itu kurang mungkin:
  • Berikan setiap item kuncinya sendiri: set mengubah hanya kuncinya sendiri, jadi sesi yang menulis kunci berbeda tidak menimpa satu sama lain
  • Baca lagi tepat sebelum Anda menulis: untuk nilai yang beberapa sesi ubah, get kunci dalam callback dan bangun nilai baru dari itu, bukan dari salinan yang Anda muat pada session.start. Penulisan sesi lain masih hilang jika mendarat antara get dan set Anda.
Tombol ini menambahkan satu ke apa pun yang disimpan sekarang, kemudian memperbarui gambar:
Jika sesi kedua telah menekan tombolnya sendiri tiga kali sejak sesi ini dimulai, penekanan ini menampilkan dan menyimpan hitungan yang mencakup ketiga itu.

Langkah berikutnya