420 lines
11 KiB
Markdown
Executable File
420 lines
11 KiB
Markdown
Executable File
# WiréJS | Değişken değil, kablo kullanın !
|
||
|
||
# Açıklama
|
||
|
||
WiréJS, dizinlenmiş akıllı değişkenler oluşturup kendi kendini yönetebilen veri değişimini kolayca yönetebilen sistemler oluşturabileceğiniz
|
||
yapılar kurmanıza olanak sağlayan sistemdir.
|
||
|
||
Verileri wriré içerisinden oluşturarak değişimleri ile etkileyecek diğer değişkenleri bağımsız yapılar içinde yazabilirsiniz.
|
||
Ayrıca verilerinizi sistematik olarak depolar bu sayede veri türünü okuma ve yazma olaylarını denetleyebilirsiniz (getter/setter)
|
||
|
||
# Kullanım örneği
|
||
|
||
## Veri yazma
|
||
|
||
Tanım
|
||
|
||
```typescript
|
||
declare function é(name: string, value: any): void;
|
||
```
|
||
|
||
### Basit
|
||
|
||
`name` ve `value` değerlerini `é` fonksiyonuna aktardığınızda bu ismi ve değeri global olarak depolar. Bu değeri istediğiniz herhangi bir noktada kullanabilirsiniz
|
||
|
||
```javascript
|
||
// İlk argümanı isim ve ikinci argümanı değer olarak alır ve depolar
|
||
é('name', 'John');
|
||
é('surname', 'Carter');
|
||
é('age', '34');
|
||
```
|
||
|
||
### Gelişmiş
|
||
|
||
`name` alanına verdiğiniz değerler dosya sistemi benzeri dizinlenmiş olarak saklanır.
|
||
Teknik olarak `/` ile ayırdığınız her alan için sistem o alan klasör gibi davranır ve son eğik çizgiden sonraki isme o değeri kaydeder. Teknik olarak `name`, `surname` ve `age` değerleri `userform` adı altında tutulur ve izlenir
|
||
|
||
```javascript
|
||
é("userform/name/value", "John");
|
||
é("userform/name/required", true);
|
||
é("userform/surname/value", "carter");
|
||
é("userform/surname/required", true);
|
||
é("userform/age/value", "17");
|
||
é("userform/age/required", false);
|
||
```
|
||
|
||
## Veri okuma
|
||
|
||
Tanım
|
||
|
||
```typescript
|
||
declare function é(name: string): any;
|
||
```
|
||
|
||
### Basit
|
||
|
||
Bir değeri okumak için `é` fonksiyonune değerin ismini yazmanız yeterli
|
||
|
||
```javascript
|
||
let name = é("name");
|
||
console.log(name) // --> john
|
||
```
|
||
|
||
### Gelişmiş
|
||
|
||
Sistem yanlızca değerleri döner, dizinleri vermez. Bu yüzden değişkenin tam ismini kullanmanız gerekir
|
||
|
||
```javascript
|
||
é("userform/name/value", "John");
|
||
|
||
é("userform") // ----> undefined
|
||
é("userform/name") // ----> undefined
|
||
é("userform/name/value") // ----> "John" !!
|
||
é("userform/name/value/other") // ----> undefined
|
||
```
|
||
|
||
## Veriyi izleme
|
||
|
||
Tanım
|
||
|
||
```typescript
|
||
declare function é(callback: function, variables:string[]): any;
|
||
```
|
||
|
||
`variables` ismindeki veriler değiştiğinde `callback` fonksiyonunu tetikler.
|
||
|
||
### Basit
|
||
|
||
```javascript
|
||
é("number1", 20);
|
||
é("number2", 40);
|
||
é("number3", 60);
|
||
|
||
é("average", 0);
|
||
|
||
é(() => {
|
||
|
||
let total = é("number1") + é("number2") + é("number3");
|
||
é("average", total / 3);
|
||
|
||
},["number1","number2","number3"]);
|
||
```
|
||
|
||
Yukarıdaki kodda `number` isimli değişkenlerin herhangi birinin değişmesi durumunda en alttaki fonksiyonumuz çalışarak `average` değerini güncelleyecektir.
|
||
|
||
Değişiklik izleme tiplemeleride dikkate alan karmaşık bir karşılaştırma algoritması üzerinden yapılır böylecek number, string, boolean değişimleri dışında array ve object tipli değişkenlerin değerleri izlene rekürsif bir şekilde izlenir
|
||
|
||
```javascript
|
||
|
||
é("number1", 20);
|
||
é("number1", 20); // does nothing, no write, no access
|
||
é("number1", 21); // change detected, writed
|
||
é("number1", 21); // does nothing, no write, no access
|
||
|
||
|
||
é("object_variable", {var1: true,arr2: [1,2,3,[2]],callback: () => {}});
|
||
é("object_variable", {var1: true,arr2: [1,2,3,[2]],callback: () => {}}); // does nothing, no write, no access
|
||
é("object_variable", {var1: true,arr2: [1,2,3,[3]],callback: () => {}}); // does nothing, no write, no access
|
||
|
||
```
|
||
|
||
### Gelişmiş
|
||
|
||
Ayrıca dizinlenmiş veriler için iç değerlerin değişimi, üst dizinlerden de izlenebilir
|
||
|
||
```javascript
|
||
é("userform/register/name/value", "John");
|
||
é("userform/register/name/required", true);
|
||
é("userform/register/surname/value", "carter");
|
||
é("userform/register/surname/required", true);
|
||
é("userform/register/age/value", "17");
|
||
é("userform/register/age/required", false);
|
||
|
||
é(()=>{
|
||
console.log("changed userform -> register")
|
||
},["userform/register"]);
|
||
```
|
||
|
||
`userform/register` dizinin altındaki herhangi bir değerin değişmesi durumunda callback çağırılacaktır
|
||
|
||
|
||
## Okuma arabirimi (Middleware)
|
||
|
||
```typescript
|
||
declare namespace é {
|
||
function read(name: string, callback: (value:any) => any): void;
|
||
}
|
||
```
|
||
|
||
Okuma arabirimi bir değerin saklanmasından sonra `é` fonksiyonu üzerinden geri çağırılması durumunda durumunda devreye girer. Bazı verileri saklandığı gibi değilde, farklı bir formatta almak istediğinizde kullanışlıdır. Nesneye yönelik dillerde getter gibidir **ancak burda değişkenin bulunması zorunlu değildir**, önce getter daha sonra değer belirlenebilir
|
||
|
||
```javascript
|
||
|
||
é.read("code",usernameValue => {
|
||
return `CODE#` + usernameValue;
|
||
});
|
||
|
||
é("code", 117);
|
||
|
||
console.log(é("code")) // ---> CODE#117
|
||
|
||
|
||
```
|
||
|
||
```javascript
|
||
|
||
é("person", null);
|
||
é("person/name", "John");
|
||
é("person/surname", "Carter");
|
||
|
||
é.read('person',function(){
|
||
return é("person/name") + " " + é("person/surname");
|
||
})
|
||
|
||
console.log(é("person")) // ---> "John Carter"
|
||
|
||
é("person/name", "Bell");
|
||
|
||
console.log(é("person")) // ---> "Bell Carter"
|
||
|
||
```
|
||
|
||
|
||
## Yazma arabirimi (Middleware)
|
||
|
||
```typescript
|
||
declare namespace é {
|
||
function write(name: string, callback: (value:any) => any): void;
|
||
}
|
||
```
|
||
|
||
Yazma arabirimi bir verinin kaydedilmesi sırasında devreye girer ve verilen verinin depolanmadan önce ek kontroller yapılmasına değiştirilmesini sağlamak için kullanılabilir. Nesneye yönelik dillerde setter gibidir **ancak burda değişkenin bulunması zorunlu değildir**, önce setter daha sonra değer belirlenebilir
|
||
|
||
|
||
Bir değerin tipinin değiştirilmesi
|
||
|
||
```javascript
|
||
|
||
é("integer_value", 217.7525);
|
||
|
||
é.write("integer_value",usernameValue => {
|
||
return parseInt(usernameValue);
|
||
});
|
||
|
||
console.log(é("integer_value")) // ---> 217
|
||
|
||
|
||
```
|
||
|
||
Bir listenin içerisindeki null verilerinin çıkarılarak saklanması
|
||
|
||
```javascript
|
||
|
||
é.write("numberList",usernameValue => {
|
||
return usernameValue.filter(e => e != null)
|
||
});
|
||
|
||
é("numberList", [1, null, 7, 63, 74, null, 7, 15]);
|
||
|
||
console.log(é("numberList")) // ---> [1, 7, 63, 74, 7, 15]
|
||
|
||
```
|
||
|
||
> [!WARNING] Dikkat
|
||
> getter ve setter metotları belirlendiği andan itibaren devreye girer, kendinden önce ve sonraki depolama veya okuma operasyonlarına karışmaz
|
||
|
||
|
||
## Veriyi kısıtlama
|
||
|
||
|
||
```typescript
|
||
declare namespace é {
|
||
function typedLock(name: string, {instance?:Function, type?:string, nullable?:boolean}): void;
|
||
}
|
||
```
|
||
|
||
### Veri tipini kısıtlama
|
||
|
||
`typedLock` fonksiyonu belirlenen `name` değeri için tipleme ve değersizlik (nullable) kısıtlamalarını uygular. Bu tipleme isteğe bağlı olarak değiştirilebilir veya tekrar belirlenebilir
|
||
|
||
```javascript
|
||
é("person/name", "John");
|
||
|
||
|
||
é.typedLock("person/name",{
|
||
type: "string",
|
||
nullable: false
|
||
});
|
||
|
||
é("person/name", null); // ----> Uncaught Error: value is not typeof number
|
||
|
||
é("person/name", 27); /// -----> Uncaught Error: value is not typeof string
|
||
|
||
```
|
||
|
||
### Veri tipi kısıtını kaldırma
|
||
|
||
`typedLock` fonksiyonu belirlenen `name` değeri için tipleme ve değersizlik (nullable) kısıtlama kurallarını siler
|
||
|
||
```javascript
|
||
é("person/name", "John");
|
||
|
||
|
||
é.typedLock("person/name",{
|
||
type: "string",
|
||
nullable: false
|
||
});
|
||
|
||
é("person/name", null); // ----> Uncaught Error: value is not typeof number
|
||
|
||
é("person/name", 27); /// -----> Uncaught Error: value is not typeof string
|
||
|
||
é.typedUnLock("person/name");
|
||
|
||
|
||
é("person/name", null); // ----> success, allowed!
|
||
|
||
é("person/name", 27); /// -----> success, allowed !
|
||
|
||
```
|
||
|
||
|
||
## Seti temizleme
|
||
|
||
WiréJS'de veriler ile arabirim ve veri tipi kısıtlayıcıları vs. ayrı ayrı tutulur. Veri bellek içerisinden silinse veya null değeri verilse dahil dinleyiciler aktif olarak çalışır.
|
||
|
||
|
||
```typescript
|
||
declare namespace é {
|
||
function delete(name: string): void;
|
||
}
|
||
```
|
||
|
||
Verilen veri isminden tüm verileri, kısıtlayıcıları, okuma ve yazma arabirimlerini temizler.
|
||
|
||
```javascript
|
||
|
||
é("name", "john");
|
||
|
||
// use updated callback
|
||
é(()=> console.log("name changed"),['name']);
|
||
|
||
// use setter callback
|
||
é.read('name',value => `--${value}--`);
|
||
|
||
é('name'); // ---> "--john---"
|
||
|
||
é('name','Bell'); // ---> name changed
|
||
|
||
// Delete name value, remove updated callbacks and setter callbacks
|
||
é.delete("name");
|
||
|
||
é('name'); // ---> undefined
|
||
|
||
é('name','Kyra'); // ---> do nothing....
|
||
é('name','Oliver'); // ---> do nothing....
|
||
|
||
é('name'); // ---> "Oliver"
|
||
```
|
||
|
||
|
||
## Detaylar
|
||
|
||
### DOM ile birlikte kullanma
|
||
|
||
```javascript
|
||
|
||
let nameInput = document.createElement("input");
|
||
// input değiştiğinde bildir
|
||
nameInput.oninput = () => é('name', nameInput.value);
|
||
é.read('name/valid',value => value.trim() != "");
|
||
|
||
|
||
let surnameInput = document.createElement("input");
|
||
// input değiştiğinde bildir
|
||
surnameInput.oninput = () => é('surname', surnameInput.value);
|
||
é.read('surname/valid',value => value.trim() != "");
|
||
|
||
|
||
let errorSpan = document.createElement("span");
|
||
é(() => surnameInput.value = é('message'),['message']);
|
||
|
||
|
||
let submitButton = document.createElement("button");
|
||
submitButton.disabled = true;
|
||
// submit_isActive değeri değiştiğinde disabled özelliğini değiştir
|
||
é(() => {
|
||
submitButton.disabled = !é("submit_isActive")
|
||
},["submit_isActive"]);
|
||
|
||
é(()=>{
|
||
|
||
if(é("name/valid") && é("surname/valid")){
|
||
é('message', "Form's input is valid")
|
||
é("submit_isActive", true)
|
||
}else{
|
||
é('message', "Please fill all inputs")
|
||
é("submit_isActive", false)
|
||
}
|
||
|
||
},["name","surname"]);
|
||
```
|
||
|
||
### Fark algoritmasını değiştirme
|
||
|
||
|
||
Bazen verilerin değişimini algılamak için tipleri veya verinin içeriği kontrol etmek gereksiz olabilir. Senaryonuzu karmaşık veriler dışında basit primitive veriler üzerine kurguluyorsanız fark algoritmasını basitleştirerek performansı yarı yarıya artırabilirsiniz
|
||
|
||
```typescript
|
||
declare namespace é {
|
||
function diff(callback: (oldValue?:any, newValue?:any) => boolean): void;
|
||
}
|
||
```
|
||
|
||
Belirli bir verinin farklı bir algoritma kullanılarak karşılaştırılmasını sağlar
|
||
|
||
Örneğin sizin için basit bir (tipleme korumasız) bir karşılaştırma yetiyor olabilir
|
||
|
||
```javascript
|
||
|
||
é("number", 4);
|
||
|
||
é("number", 5); // ----> changed
|
||
|
||
é.diff("number", (oldValue, newValue) => oldValue != newValue);
|
||
|
||
é("number", 6); // ----> changed !
|
||
é("number", 0); // ----> changed !
|
||
é("number", false); // ----> no change
|
||
é("number", null); // ----> no change
|
||
é("number", undefined); // ----> no change
|
||
é("number", []); // ----> no change
|
||
é("number", 3); // ----> changed !
|
||
é("number", 1); // ----> changed !
|
||
é("number", true); // ----> no change
|
||
|
||
```
|
||
|
||
Veya ortalaması aynı olan bir listenin eşitlenmesi gereksiz bir durum olabilir
|
||
|
||
```javascript
|
||
|
||
é("numberList", [ 0, 1, 2, 3]);
|
||
é("numberList", [-1, 1, 2, 3, 4]); // ----> changed !
|
||
|
||
é.diff("numberList", (oldValue, newValue) => {
|
||
let oldValueSum = oldValue.reduce((sum, num) => sum + num, 0) / oldValue.length;
|
||
let newValue = newValue.reduce((sum, num) => sum + num, 0) / newValue.length;
|
||
return oldValueSum != newValue
|
||
});
|
||
|
||
é("numberList", [2]);
|
||
é("numberList", [ 1, 2, 3]); // ----> no change, no write
|
||
é("numberList", [ 0, 1, 2, 3, 4]); // ----> no change, no write
|
||
é("numberList", [-2, 0, 2, 4, 6]); // ----> no change, no write
|
||
é("numberList", [+1, 2, 3, 4, 5]) // ----> changed !
|
||
|
||
|
||
```
|
||
|
||
Bu karşılaştırmanın sonucunu depolamadığı gibi aynı zamanda dinleyicileride çalıştırmayacaktır |