Nuvaka › Geliştirici belgeleri › Çekirdek eklentileri

Çekirdek eklentileri

Uzantın Nuvaka'nın kendi ekranlarına seçenek ekleyebilir: Dosyalarım'da bir dosyanın menüsüne "Düzenle" gibi bir eylem ya da "Birlikte aç" alt menüsüne bir satır. Kullanıcı seçince uzantının sayfası açılır ve yalnız o dosyaya erişen, süreli bir tanıtıcı (handle) alır.

Eklenti noktaları

NoktaNeredeVarsayılan kip
storage.fileActionDosyalarım › dosya menüsü (ör. "Düzenle")readwrite
storage.openWithDosyalarım › dosya menüsü › Birlikte açread
"entry": { "ui": "index.html" },
"pages": [{ "id": "main", "title": { "tr": "Düzenleyici", "en": "Editor" } }],
"contributes": {
  "storage.fileAction": [
    { "id": "edit", "title": { "tr": "Düzenle", "en": "Edit" }, "icon": "pencil", "extensions": ["txt", "md"], "page": "main" }
  ],
  "storage.openWith": [
    { "id": "view", "title": { "tr": "Görüntüle", "en": "View" }, "mimeTypes": ["text/*"], "page": "main", "mode": "read" }
  ]
}

Alan kuralları: Manifest › contributes. Öğe, dosyanın uzantısı (extensions) ya da MIME türü (mimeTypes, image/* gibi joker dahil) uyuyorsa görünür.

Öğeyi Nuvaka çizer

  • Menüdeki satırı Nuvaka arayüzü çizer: manifestteki ad (title), ikon ve uzantının adı. Uzantı Nuvaka ekranına HTML, stil ya da kod koyamaz; kullanıcı seçene kadar uzantı hiçbir şey görmez.
  • Kullanıcı eklentileri uzantı başına kapatıp açabilir (Uygulamalar ekranında "Nuvaka ekranlarına eklentiler"). Kapalı eklenti menüde görünmez.
  • Aynı dosya türü için birden çok uzantı "Birlikte aç" sunuyorsa kullanıcı birini o tür için varsayılan yapabilir.
  • Mağazada kart ve detayda "Nuvaka ekranlarına eklenti yapar" bilgisi görünür; izin listesinin başında ayrı bir satır olarak gösterilir.
  • contributes içeren her sürüm Nuvaka incelemesinden geçer. Eklentileri değiştiren ya da kaldıran bir güncelleme otomatik kurulmaz; kullanıcıya sorulur.

Tek dosya tanıtıcısı

Kullanıcı eklentiyi seçince uygulama kullanıcı oturumuyla o dosya için bir tanıtıcı alır ve uzantının page sayfasını açar. Tanıtıcı:

  • yalnız bu kullanıcı ve bu uzantı için geçerlidir; başka uzantı kullanamaz;
  • yalnız o tek dosyaya erişir; nuvaka.cloud izni gerekmez;
  • kip taşır: read ya da readwrite. Kipin üst sınırı eklentinin mode'udur (varsayılan: storage.fileAction → readwrite, storage.openWith → read); daha geniş istek read_only_contribution ile reddedilir;
  • kayan sürelidir: açılışta 15 dakika; her okuma, yazma ya da meta() süreyi 15 dakika uzatır; açılıştan en çok 8 saat. Uzun süre açık kalan bir düzenleyici ara ara meta() çağırarak tanıtıcıyı canlı tutabilir. Güncel bitiş meta().expiresAt'tedir;
  • adres çubuğuna ya da geçmişe yazılmaz; her kullanımı uzantının etkinlik kaydına düşer.

SDK: nuvaka.files.handle

Sayfa bir eklentiyle açıldıysa bağlamda handle ve fileName gelir. Sayfa açıkken kullanıcı başka bir dosyada eklentiyi seçerse file.open olayı gelir ve bağlam güncellenir.

const ctx = await nuvaka.ready
if (ctx.handle) await openFile(ctx.handle)
nuvaka.on('file.open', ({ handle }) => openFile(handle))

async function openFile(h) {
  const file = nuvaka.files.handle(h)
  const meta = await file.meta()        // { fileId, name, size, contentType, version, updatedAt, mode, contribution, expiresAt }
  editor.value = await file.readText()  // ya da read() → Uint8Array
  saveButton.disabled = meta.mode !== 'readwrite'
  saveButton.onclick = async () => {
    try {
      const r = await file.write(editor.value, { version: meta.version, contentType: 'text/plain' })
      meta.version = r.file.version     // sonraki kayıt için
      showInline(`Kaydedildi. Eski hâli: ${r.previous.name}`)
    } catch (e) {
      if (e.code === 'version_conflict') showInline('Dosya başka yerde değişti; yeniden yükle.')   // e.data.current = güncel Meta
      else throw e
    }
  }
}
ÇağrıDönüş
nuvaka.files.handle(h)tanıtıcı nesnesi (senkron; ağ çağrısı yapmaz)
.meta(){ fileId, name, size, contentType, version, updatedAt, mode, contribution, expiresAt }
.read()Uint8Array
.readText()metin (UTF-8)
.write(data, { version, contentType? }){ previous: { fileId, name }, file: Meta }; yalnız readwrite; en çok 100 MB

Yazma: MVCC ve önceki sürüm

  • write okuduğun version'ı ister (meta().version). Sen okuduktan sonra dosya değiştiyse çağrı version_conflict verir ve hata dosyanın güncel hâlini (e.data.current; SDK'da VersionConflictError.file) taşır. Sürüm vermezsen if_version_required.
  • Eski içerik silinmez: aynı klasörde "<ad> (önceki sürüm yyyy-MM-dd HH.mm.ss).<uzantı>" adıyla korunur. Yeni içerik asıl adla yeni dosya olur, tanıtıcı yeni dosyaya taşınır (fileId değişir). Paylaşım bağlantıları eski dosyada kalır.

Hatalar

KodAnlamı
bad_handletanıtıcı geçersiz, süresi dolmuş ya da başka uzantının
read_onlyread tanıtıcıyla yazma denendi
version_conflictdosya sen okuduktan sonra değişti
if_version_requiredwrite sürümsüz çağrıldı

Tanıtıcıyı açarken (uygulama tarafı) görülebilecek durumlar: eklenti bu dosya türüne uymuyor (no_contribution), kullanıcı eklentiyi kapatmış (contribution_disabled), eklentinin kipinden geniş istek (read_only_contribution), uzantı durdurulmuş ya da engellenmiş. Bunları kullanıcıya Nuvaka gösterir.

Test

SDK'nın sahte nuvaka'sı tanıtıcıları taklit eder: kayan süre, MVCC, önceki sürüm adı, read_only.

import { installMockNuvaka } from '@nuvaka/extension-sdk/testing'

const m = installMockNuvaka({ file: { name: 'not.txt', content: 'merhaba', contentType: 'text/plain', contribution: 'edit' } })
const h = nuvaka.files.handle(nuvaka.context().handle)
m.remote.editFile(nuvaka.context().handle, 'başkası değiştirdi')   // sonraki write çakışır
await m.openFile({ name: 'b.md', content: '# b' })                 // file.open olayı
m.log.fileWrites                                                    // yazma kayıtları

Nuvaka Apps API v1 · son güncelleme 2026-09-27