Dokümanları okudunuz, TOON'un tablo verilerde token sayısını yarıya indirdiğini biliyorsunuz. Şimdi gerçekten bir şeye bağlamak istiyorsunuz. Bu makale pratik konularla ilgili: .toon dosyaları okuma ve yazma, sistem sınırlarında TOON doğrulama, TOON istek gövdelerini ayrıştıran bir Express middleware oluşturma ve bir LLM'ye doğrudan TOON besleyen bir veritabanı-istem ardışık düzeni kurma. Gerçek kod, gerçek desenler — oyuncak örnek yok.

Kurulum

Paketi npm'den yükleyin. Yalnızca ESM olduğundan, package.json'ınızda "type": "module" gerekir veya .mjs uzantısı kullanın. Node.js 18+ yeterlidir — yapılandırma dosyası yok, eklenti yok.

bash
npm install @toon-format/toon
js
import { encode, decode } from '@toon-format/toon';

// That's it. encode() → TOON string, decode() → JS value.

TOON Dosyaları Okuma ve Yazma

Node.js fs modülü G/Ç işlemlerini halleder. Dosya içeriğini doğrudan decode()'a iletin veya verilerinizi encode()'a iletip sonucu diske yazın. Aşağıda her iki desen var — betikler ve CLI araçları için senkron, sunucu rotaları için asenkron.

js
// --- Sync (scripts, CLI tools) ---
import { readFileSync, writeFileSync } from 'fs';
import { encode, decode } from '@toon-format/toon';

// Read a .toon file and decode it to a JS value
const raw = readFileSync('./data/products.toon', 'utf8');
const products = decode(raw);
console.log(products); // → JS array or object

// Encode a JS value and write it to a .toon file
const inventory = [
  { sku: 'WDG-001', name: 'Widget A', qty: 142, price: 9.99 },
  { sku: 'WDG-002', name: 'Widget B', qty: 87,  price: 14.49 },
  { sku: 'GDG-001', name: 'Gadget X', qty: 31,  price: 49.99 },
];
writeFileSync('./data/inventory.toon', encode(inventory, { indent: 2 }), 'utf8');
js
// --- Async (server routes, pipelines) ---
import { promises as fs } from 'fs';
import { encode, decode } from '@toon-format/toon';

// Read
async function loadReportData(filePath) {
  const raw = await fs.readFile(filePath, 'utf8');
  return decode(raw); // throws if malformed — handle upstream
}

// Write
async function saveSnapshot(data, filePath) {
  const toon = encode(data, { indent: 2 });
  await fs.writeFile(filePath, toon, 'utf8');
}
Her zaman 'utf8' kodlamasını kullanın. TOON dosyaları düz metindir. Kodlama argümanını atlamak bir Buffer döndürür — decode() bir dize bekler ve Buffer iletilirse tür hatası fırlatır.

Sistem Sınırlarında TOON Doğrulama

decode() geçersiz girişte fırlatır, bu bir ayrıştırıcı için doğru davranıştır ancak yapılandırılmış bir sonuca ihtiyaç duyduğunuz API sınırında veya mesaj kuyruğu tüketicisinde uygunsuztur — yakalanmamış bir istisna değil. Çözüm, fırlatmayı bir dönüş değerine dönüştüren ince bir sarmalayıcıdır. Bu, Express rota işleyicilerinde, kuyruk işlemcilerinde ve harici verilerin sisteminize girdiği her yerde kullanacağınız desendir.

js
import { decode } from '@toon-format/toon';

/**
 * Safely parse a TOON string.
 * Returns { valid: true, data } on success,
 * or { valid: false, error } on failure — never throws.
 */
export function validateToon(input) {
  if (typeof input !== 'string') {
    return { valid: false, error: 'Input must be a string' };
  }
  try {
    const data = decode(input);
    return { valid: true, data };
  } catch (err) {
    return { valid: false, error: err.message };
  }
}

Bir Express rotasında veya kuyruk tüketicisinde kullanım aynıdır — validateToon()'u çağırın, valid'e göre dallanın ve ya data ile devam edin ya da error dizesiyle 400 döndürün / mesajı ölü mektuba gönderin. try/catch deseni çağıran kodu temiz ve öngörülebilir tutar.

js
// Example: queue consumer
queue.process('ingest-toon', async (job) => {
  const result = validateToon(job.data.payload);
  if (!result.valid) {
    console.error('Rejecting malformed TOON:', result.error);
    return; // dead-letter, skip, or throw depending on your queue
  }
  await db.insert(result.data);
});

Express için TOON Middleware Oluşturma

express.json(), application/json gövdelerini ayrıştırır ve sonucu req.body'ye koyar. İşte application/toon için aynı şey. Rota işleyicilerinizden önce ekleyin ve yığının geri kalanı farkı anlamaz.

js
import { decode } from '@toon-format/toon';

/**
 * Express middleware: parses application/toon request bodies
 * and attaches the decoded value to req.body.
 */
export function toonBodyParser(req, res, next) {
  const contentType = req.headers['content-type'] ?? '';
  if (!contentType.includes('application/toon')) {
    return next(); // not our content type, pass through
  }

  let body = '';
  req.setEncoding('utf8');
  req.on('data', (chunk) => { body += chunk; });
  req.on('end', () => {
    try {
      req.body = decode(body);
      next();
    } catch (err) {
      res.status(400).json({ error: 'Invalid TOON body', detail: err.message });
    }
  });
  req.on('error', (err) => {
    res.status(500).json({ error: 'Request stream error', detail: err.message });
  });
}

// Wire it up:
// app.use(toonBodyParser);
// app.post('/api/import', (req, res) => {
//   // req.body is already the decoded JS value
//   res.json({ received: Array.isArray(req.body) ? req.body.length : 1 });
// });

LLM'ye Göndermeden Önce Veritabanı Sonuçlarını TOON'a Dönüştürme

TOON'un bunun için oluşturulduğu desendir. Veritabanını sorguladınız, satır dizisi aldınız, TOON'a kodladınız ve doğrudan istemin içine bıraktınız. LLM tüm yapıyı JSON'ın anahtar tekrarı yükü olmadan alır. İşte node-postgres (pg) kullanan gerçekçi bir ardışık düzen:

js
import pg from 'pg';
import { encode } from '@toon-format/toon';

const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });

async function buildOrderPrompt(customerId) {
  // Step 1: query the database
  const { rows } = await pool.query(
    `SELECT order_id, created_at, status, total_cents, item_count
       FROM orders
      WHERE customer_id = $1
      ORDER BY created_at DESC
      LIMIT 50`,
    [customerId]
  );

  if (rows.length === 0) {
    return null;
  }

  // Step 2: encode rows to TOON
  // encode() handles all quoting automatically — no pre-processing needed
  const toonData = encode(rows, { indent: 2 });

  // Step 3: build the prompt
  return [
    'Analyse the following order history for a customer support case.',
    'Data is in TOON tabular format: name[count]{col1,col2,...}: followed by one row per line.',
    '',
    toonData,
    '',
    'Summarise any patterns that suggest the customer has a recurring issue.'
  ].join('\n');
}

// Calling code:
const prompt = await buildOrderPrompt('cust_8821');
if (prompt) {
  const reply = await callLlm(prompt); // your LLM client here
  console.log(reply);
}

Aynı desen herhangi bir SQL istemcisi veya ORM için geçerlidir — Prisma, Drizzle, Knex, Sequelize — sorgunuz düz JS nesneleri döndürdüğü sürece. encode() anahtar adlarını ilk satırdan alır ve bunları sütun başlıkları olarak kullanır; sonraki satırlar virgülle ayrılmış değerler olarak yazılır. JSON dizisi olarak ~1.500 tokena mal olacak 50 satırlık sonuç kümesi tipik olarak TOON olarak ~600-700 tokena mal olur.

Hataları ve Uç Durumları Ele Alma

Göndermeden önce bilmeniz gereken birkaç şey:

  • LLM hatalı biçimlendirilmiş TOON döndürür. Modeller, özellikle ilk denemede her zaman bir formatı mükemmel şekilde yeniden üretmez. decode()'u try/catch içine alın (veya yukarıdaki validateToon()'u kullanın). Başarısız olursa ham yanıtı kaydedin, çağırana bir hata döndürün ve — yapılandırılmış çıktıya güvenilir biçimde ihtiyaç duyuyorsanız — açık bir düzeltme istemi ile yeniden deneyin: "Son yanıtınız geçerli TOON değildi. Lütfen yeniden biçimlendirin."
  • Virgül veya iki nokta üst üste içeren değerler. TOON değerleri ayırmak için virgül ve nesne sözdiziminde iki nokta üst üste kullanır — her ikisi de anlamlı karakterlerdir. encode() bunları otomatik olarak algılar ve etkilenen değeri çift tırnak içine alır. Verilerinizi önceden işlemenize gerek yoktur; ham dizileri iletin.
  • Null ve undefined. encode(), nullnull olarak serileştirir (tırnaksız, açık) ve undefined özelliklerini tamamen atlar — JSON.stringify() ile aynı davranış. Çözümlemede, tırnaksız null, JS null olarak döndürülür.
  • Boş diziler. encode([]) geçerli bir boş TOON dizisi döndürür. decode() onu temiz şekilde geri döndürür. LLM isteminiz boş veri kümesi içermemesi gerekiyorsa yukarı akışta koruma uygulayın.
  • Çok büyük sonuç kümeleri. Kütüphanede sabit bir sınır yoktur, ancak LLM'lerin bağlam penceresi sınırları vardır. Kodlamadan önce sorgularınızı sayfalara bölün veya LIMIT uygulayın — çoğu istem için 100-200 satır makul bir üst sınırdır.
Depolamadan önce doğrulayın. Ardışık düzeniniz harici bir kaynaktan TOON kabul ediyorsa (webhook, kuyruk, API istemcisi) ve çözülmüş sonucu bir veritabanında depoluyorsa, her zaman önce validateToon()'u çalıştırın. Hatalı biçimlendirilmiş bir payload'ın veritabanı katmanına ulaşmasına izin vermek, sınırda yakalamaktan çok daha zor hata ayıklama yapar.

Özet

Bu makaledeki desenler gerçek bir Node.js kod tabanına TOON entegre etmek için ihtiyacınız olan çoğu şeyi kapsar: dosya G/Ç için fs, güvenli sınır ayrıştırma için bir validateToon() sarmalayıcısı, application/toon gövdeleri için kullanıma hazır bir Express middleware ve SQL satırlarını token verimli LLM girdisine dönüştüren bir DB-to-istem ardışık düzeni. Kütüphanenin kendisi — @toon-format/toon — yolunuza çıkmaz: iki fonksiyon, yapılandırma yok, geçersiz girişte fırlatır. Geliştirme sırasında çıktıları kontrol etmek için TOON Doğrulayıcı'yı, kodlanmış veriyi incelemek için TOON Biçimleyici'yi, mevcut veri kümelerini bir isteme yapıştırmadan önce dönüştürmek için JSON'dan TOON'a'yı ve çözülmüş yanıtı JSON bekleyen bir aşağı akış sistemine iletmeniz gerekiyorsa TOON'dan JSON'a'yı kullanın.