Proyek ini bertujuan untuk meringankan kesulitan dalam pengembangan SPA dengan menerapkan pola opini untuk memodelkan keadaan aplikasi dengan cara yang tidak bergantung pada kerangka kerja, mudah diuji, dan ramah pengembang. Sparix memungkinkan Anda merangkum status dalam Penyimpanan yang aman untuk tipe, dan menentukan transformasi yang dapat terjadi pada status tersebut. Pembaruan tidak akan pernah dapat mengubah status, melainkan membuat instance status baru yang diubah (seperti peredam redux). Urutan status yang diubah tersedia untuk umum sebagai RxJS Observable<State>
.
Sparix ditulis dalam TypeScript, begitu pula contoh kodenya. Ini didistribusikan sebagai perpustakaan JavaScript dengan definisi tipe yang tertanam dalam modul NPM, seperti RxJS.
$ npm i -S sparix rxjs
import { Store } from 'sparix'
import { add } from 'ramda'
export interface CounterState {
count : number
}
const initialState : CounterState = {
count : 0
}
export class Counter extends Store < CounterState > {
constructor ( ) {
super ( initialState )
}
increment ( ) {
// ALL THESE ARE EQUIVALENT
this . update ( state => { count : state . count + 1 } )
this . updateState ( { count : val => val + 1 } )
this . updateState ( { count : add ( 1 ) } ) // Using Ramda's automatically curryied functions
}
}
import { Counter , CounterState } from './counter'
const counter = new Counter ( )
// Recommended way
const state$ : Observable < CounterState > = counter . state$
const count$ : Observable < number > = counter . map ( state => state . count )
// Alternative way (useful for testing)
expect ( counter . currentState . count ) . toEqual ( 0 )
counter . increment ( )
expect ( counter . currentState . count ) . toEqual ( 1 )
Pertama, itu sebuah pola. Kedua, ini merupakan implementasi berdasarkan RxJS. Implementasinya cukup sepele, dan hanya memerlukan waktu beberapa jam untuk menulis ulang dengan perpustakaan reaktif lainnya. Namun, karena dunia SPA didominasi oleh React dan Angular2, dan karena Angular2 disertakan dengan RxJS, masuk akal untuk menggunakan perpustakaan ini sebagai referensi implementasi sparix.
Di sparix, status dimodelkan sebagai Observable<State>
, aliran transisi status yang tidak dapat diubah.
API Toko dibuat sederhana, dan semua logika kompleks dienkapsulasi dan disembunyikan dari luar, seperti yang Anda lakukan dengan Pemrograman Berorientasi Objek lama yang bagus. Untuk menguji Store, yang perlu Anda lakukan hanyalah menyimulasikan input (dengan memanggil salah satu metode publiknya) dan memeriksa outputnya (status).
Sparix sepenuhnya menganut prinsip redux (atau lebih tepatnya, prinsip Arsitektur Elm) di mana transformasi keadaan didefinisikan sebagai fungsi murni yang tidak mengubah keadaan sebelumnya.
Di redux, ketika Anda perlu memperbarui status, Anda mengirimkan suatu tindakan. Namun jika Anda perhatikan lebih dekat, Anda mungkin menyadari bahwa tindakan dapat diurutkan dalam dua kategori :
Klaim saya adalah bahwa tindakan merupakan mekanisme yang terlalu berat ketika tujuannya hanya untuk memperbarui status Toko tunggal (seperti dalam banyak kasus). Di sparix, Toko dapat langsung memperbarui statusnya hanya dengan upacara:
// Increment counter
this . update ( state => ( {
counter : state . counter + 1
} ) )
Ada cara yang lebih terperinci dan lebih deklaratif untuk menulis pembaru status ini:
this . updateState ( {
counter : prevCounter => prevCounter + 1
} )
Atau bahkan lebih baik:
const increment = value => value + 1
this . updateState ( {
counter : increment
} )
Sebenarnya Anda harus memanfaatkan kari otomatis Ramda:
import { add } from 'ramda'
this . updateState ( {
counter : add ( 1 )
} )
Saya suka menganggap pembaru negara ini sebagai tindakan anonim. Di redux, ini seperti mengirimkan peredam. Namun bagaimana dengan pembuat aksi? Sebenarnya kami tidak membutuhkannya:
const increment = val => val + 1
class SomeStore extends Store < SomeState > {
// constructor
incrementCounter ( ) {
this . updateState ( {
counter : increment
} )
}
}
Di sini, metode incrementCounter()
adalah bagian dari API publik Store. Anda tidak perlu lagi mengirimkan tindakan global yang dibuat oleh pembuat tindakan. Panggil saja metodenya!
Sparix adalah tentang memodelkan inti aplikasi Anda. Tapi apa itu inti? Atau lebih tepatnya, apa yang BUKAN pada intinya?
Inti aplikasi harus agnostik. Agnostik terhadap kerangka kerja dan database, agnostik terhadap lapisan presentasi, agnostik terhadap mekanisme dan protokol pengambilan data. Seharusnya agnostik terhadap SEMUANYA .
Inti aplikasi tidak mengetahui tentang HTML, DOM, Angular atau React, Penyimpanan Lokal, HTTP atau WebSockets.. Ia bahkan tidak mengetahui bahwa ia berada di browser web! Inti aplikasi yang sama harus dapat digunakan kembali di aplikasi Cordova, NativeScript, atau Electron tanpa mengubah satu baris kode pun !
Jadi apa yang Anda masukkan ke dalam inti? Jawabannya cukup sederhana: yang lainnya ! Kalau bisa menjadi bagian inti, maka harus menjadi bagian inti. Semua logika bisnis, transformasi data, logika interaksi, harus dimodelkan sebagai inti aplikasi. Dan semua itu tidak bergantung pada hal lain selain bahasa pemrograman yang digunakan untuk memodelkannya.
Jadi kembali ke sparix. Ini akan membantu Anda memodelkan inti aplikasi yang tidak bergantung pada perpustakaan dan kerangka kerja pihak ketiga, dengan dua pengecualian adalah RxJS dan sparix itu sendiri. Tapi itu tidak menjadi masalah besar. Observable sedang dalam proses menjadi fitur ECMAScript standar, dan sparix adalah pustaka non-intrusif, yang memudahkan untuk memodelkan hanya sebagian dari inti aplikasi Anda dengannya.