Rehberler

Paketler için DevTools

Paketler için registerDevtools (describe, inspect, sources, commands, panels, olaylar, reveal), operation'lar ve yazma kayıtları; bir paketin kendi DevTools panelinin çekirdek tarafı.

Bir paket (bileşen kütüphanesi, veri katmanı, store) bir DevTools arayüzüne bağımlı olmadan kendi durumunu DevTools'ta gösterebilir: çekirdeğe kaydolur, arayüz verdiğini okur. Bu sayfa çekirdek tarafını anlatır: registerDevtools ne alır, tutamacı ne yapar, paket hangi işin neyi değiştirdiğini nasıl söyler. Arayüzün okuduğu nesne DevTools sözleşmesi sayfasındadır. @motifx-community/devtools panelinin panel metadata'sından ne çizdiği, widget'ları, route'ları ve sınırları o paketin docs/extensions.md dosyasında anlatılır, burada değil.

Paketler için registerDevtools

Bir paket kendi durumunu @motifx/core/devtools alt yolundan açar. describe ve inspect veri verir; sources, commands ve panels ile arayüz istediğinde okur, sayfaya komut gönderir ve ne çizeceğini bilir. Örnekte Üçüncü Parti Kütüphane Sarmalama sayfasındaki klasör grafiği, kurduğu grafikleri bileşene göre tutar ve verisini DevTools'a verir:

import { registerDevtools } from "@motifx/core/devtools";
import type { ComponentBase } from "@motifx/core";
import type { Chart } from "chart.js/auto";

const charts = new Map<object, Chart>();

const devtools = registerDevtools("folder-chart", {
  describe: () => ({ charts: charts.size }),
  inspect: (component) => charts.get(component)?.data.datasets[0].data,
  sources: {
    charts: { read: () => [...charts.values()].map(summaryOf), key: "id", events: { update: "refresh" } },
    chart: { read: (params: { id: string }) => detailOf(params.id) },
  },
  commands: {
    redraw: (args: { id: string }) => chartById(args.id)?.update(),
  },
  panels: [{
    id: "charts", title: "Folder charts", icon: "chart", order: 40,
    capabilities: { read: true, subscribe: true, write: true },
    layout: { /* arayüzün çizeceği şey; onun kendi şeması */ },
  }],
});

function track(canvas: ComponentBase, chart: Chart) {
  charts.set(canvas, chart);
  canvas.motif.setDisposable(() => charts.delete(canvas));
}

function updated(canvas: ComponentBase, counts: number[]) {
  devtools.emit("update", { path: devtools.pathOf(canvas), counts });
  devtools.changed("charts");
}
import { registerDevtools } from "@motifx/core/devtools";

const charts = new Map();

const devtools = registerDevtools("folder-chart", {
  describe: () => ({ charts: charts.size }),
  inspect: (component) => charts.get(component)?.data.datasets[0].data,
  sources: {
    charts: { read: () => [...charts.values()].map(summaryOf), key: "id", events: { update: "refresh" } },
    chart: { read: (params) => detailOf(params.id) },
  },
  commands: {
    redraw: (args) => chartById(args.id)?.update(),
  },
  panels: [{
    id: "charts", title: "Folder charts", icon: "chart", order: 40,
    capabilities: { read: true, subscribe: true, write: true },
    layout: { /* arayüzün çizeceği şey; onun kendi şeması */ },
  }],
});

function track(canvas, chart) {
  charts.set(canvas, chart);
  canvas.motif.setDisposable(() => charts.delete(canvas));
}

function updated(canvas, counts) {
  devtools.emit("update", { path: devtools.pathOf(canvas), counts });
  devtools.changed("charts");
}

Çekirdeğin okumadığı her şey (id ve capabilities dışında panelin biçimi, key, events ve max'ın anlamı, reveal hedefinin içeriği) arayüzle paket arasındaki sözleşmedir; çekirdek olduğu gibi taşır.

Operation'lar ve yazma kayıtları

@motifx/core/devtools, bir paketin hangi işin neyi değiştirdiğini söyleyebilmesi için gerekeni de dışa verir: operation'lar ve yazma kayıtları. Geçmiş tutan, zaman çizelgesi çizen ya da bir değişikliği açıklayan paketler içindir; uygulama kodunun bunlara ihtiyacı yoktur.

Operation o an çalışan iştir: bir tıklama işleyicisi, bir gezinme, bir paketin aksiyonu. Çekirdeğin bir fonksiyon çalışırken tuttuğu tek bir değerdir, çalışan effect'i tuttuğu gibi. Uygulamaya ya da bileşen ağacına bağlı değildir, aşağıya aktarılmaz, bileşenler onu görmez. Yazmalar, flush tetikleyicileri ve operation olayları onun id'sini taşır.

import { runOperation, startOperation, resumeOperation, endOperation, currentOperation } from "@motifx/core/devtools";

runOperation({ kind: "action", name: "cart/add", data: { id: 7 } }, () => {
    cart.items.push(item);                    // bu operation içinde yazıldı
});

await runOperation({ kind: "action", name: "orders/load" }, async () => {
    const operation = currentOperation();
    const rows = await api.orders();
    resumeOperation(operation, () => { state.orders = rows; });
});

const operation = startOperation({ kind: "action", name: "chat/send" });
resumeOperation(operation, () => { state.sending = true; });
socket.onAnswer(() => resumeOperation(operation, () => {
    state.sending = false;
    endOperation(operation);
}));

onWrite(fn) DevTools açıkken her reaktif yazmayı bildirir ve durduran bir fonksiyon döndürür. Her kaydın target'ı (ham nesne, dizi, Map, Set ya da signal) ve bir operation içindeyse operationId'si vardır:

kind Ne zaman Alanlar
add nesnede yeni anahtar, dizide sonun ötesinde bir indeks, Map'te yeni anahtar ya da Set'te yeni değer key, value
update değişen değer: nesne anahtarı, dizi indeksi, uzayan length, Map değeri, signal.value (key: 'value') key, previous, value
delete delete obj.key, map.delete(k), set.delete(v) key, previous
clear map.clear(), set.clear() removed: map'in [key, value] çiftleri, set'in değerleri
splice push, pop, shift, unshift, splice, sort, reverse, kısalan length method, index, removed, added
mutate signal.mutate(fn); çekirdek fn'in neyi değiştirdiğini göremez –

Sonraki adım

Dışa aktarılan bütün sembollerin özeti için API Referansı bölümüne geçin.