---
title: "Migrasi legacy JSONEval"
description: "Panduan migrasi dari engine TypeScript JSONEval legacy ke implementasi baru JSONEval-RS untuk semua binding platform."
---

# Cara migrasi dari paket legacy JSONEval

Panduan ini menjelaskan cara memperbarui basis kode React Native, Node.js, atau web browser Anda dari engine TypeScript `@qsi/json-eval` versi lama (legacy) ke implementasi baru dengan binding Rust yang disatukan (unified).

Suite `@json-eval-rs` memisahkan platform binding untuk memaksimalkan kecepatan. Wrapper web menangani inisialisasi WebAssembly secara asinkron, sementara React Native melakukan proses pemuatan module secara sinkron melalui JSI. Namun, keduanya menyediakan API JavaScript asinkron yang sama persis.

---

## Bagian 1. Instansiasi dan konfigurasi

Paket legacy menginisialisasi parameter konfigurasi secara langsung di dalam constructor menggunakan argumen posisional (berurutan). API yang baru merapikannya dengan mengelompokkannya ke dalam satu objek konfig `options`.

### Inisialisasi legacy (`@qsi/json-eval`)
```typescript
// Legacy: Diperlukan argumen posisional
import { JSONEval } from "@qsi/json-eval";
const evaluator = new JSONEval(schema, context, autoEvaluate, data, customFunctions, tzOffset);
```

### Inisialisasi web baru (`@json-eval-rs/bundler`, `@json-eval-rs/vanilla`, `@json-eval-rs/node`)
Aplikasi web menggunakan wrapper yang akan memuat file memori modul WebAssembly. Karena WASM mewajibkan proses setup yang asinkron, Anda dibebaskan untuk mengatur kapan evaluator harus dinisialisasi.

```typescript
// Import secara eksplisit berdasarkan wrapper platform Anda
import { JSONEval } from "@json-eval-rs/bundler"; // Vite, Webpack, Next.js, Rollup
// import { JSONEval } from "@json-eval-rs/node"; // Backend & SSR

const evaluator = new JSONEval({
  schema: schema,
  context: context, // opsional
  data: data        // opsional
});

// WASM membutuhkan inisialisasi.
// Jika Anda memanggil `await evaluator.evaluate()`, `init()` akan berjalan otomatis.
// Disarankan untuk memanggilnya secara manual jika ingin mempercepat waktu (pre-load):
await evaluator.init(); 
```

### Inisialisasi React Native baru (`@json-eval-rs/react-native`)
React Native menggunakan JSI (JavaScript Interface) untuk mengambil engine langsung dari native module (memori), menghilangkan kebutuhan untuk pemeriksaan setup `.init()` asinkron secara mutlak.

```typescript
import { JSONEval } from "@json-eval-rs/react-native";

// Constructor sinkron otomatis mengekstrak modul referensi sistem asinkron backend JSI.
const evaluator = new JSONEval({
  schema: schema,
  context: context,
  data: data
});

// Evaluator siap mengeksekusi seketika. Tidak memerlukan `.init()`.
```

---

## Bagian 2. Urutan eksekusi data variabel

Metode `evaluate()` versi lama mengubah isi internal memori class secara eksplisit tanpa mengembalikan nilai yang memadai. Praktik tersebut akan membuat sistem framework modern seperti React kesulitan melacak variabel. API update package Rust model memisahkan antara mutasi internal memory Rust vs pengeluaran serialisasi obyeknya. Ini juga mereduksi beban data parse JavaScript bridge yang melayang ke native code.

### Eksekusi evaluasi penuh (`evaluate` vs `evaluateOnly`)

Pertimbangkan output variable result mana yang Anda inginkan setelah evaluasi selesai:

- **`evaluateOnly({ data, context, paths })`**: Melakukan operasi ubah schema data di dalam internal C++/Rust dan lalu me-return response `void`. Cara eksekusi sepihak ini terbukti jauh lebih cepat karena mencegah serialisasi node JSON Tree menyeberang arsitektur JSI/Bridge JS. Pakailah apabila Anda ingin memanggil spesifik get var extraction kemudian hari apabila anda sudah di UI flow.
- **`evaluate({ data, context, paths })`**: Eksekutorial standar. Engine evaluator memroses root json data tree tersebut lalu mereturn data payload format Javascript `Object` yang melambangkan status skema saat itu.

### Kalkulasi referensi bersandar dependensi logika (`evaluateDependents`)

Library JSON eval framework versi dahulu memaksa rendering cascade evaluation tidak bisa ditebak karena mengandalkan manual property arrays `calledBy` di node fields JSON data schema Anda yang merusak struktur tree json objects nodes mappingnya. Tool package generasi selanjutnya mengembalikkan hasil balasan object event properties terupdate list targets events array array events pointer pointer dependensi nya:

```typescript
// Eksekusi trigger recalculasi hanya untuk field dan target variable child child nya saja:
const dependentDiffArray = await evaluator.evaluateDependents({
  changedPaths: ["properties.patientData.value"]
});

// Response API membalas field terlarik khusus (diff arrays target):
// contoh object output payload: [{ $ref: "transitiveField.value", value: 10, transitive: true, clear: false }]
```

---

## Bagian 3. Penarikan obyek payload subset bagian root parameter 

Proses JSON Evaluation versi dahulu selalu membajak performa HP/Browser app sebab pengembang harus menarik semua file array objek document root memakai `getEvaluatedSchema()` ataupun memutar JS Loop functions logic client side utilitas `_jpath(obj, path)` pada obyek. 

Library binding unified terbaru menawarkan fetch pointer untuk spesifik obyek schema target dan ini tidak harus memanggil struktur tree parameter global induk serialisasinya sama sekali.

| Metode getter baru   | Padanan legacy lama | Keterangan fungsi  |
|-----------------|-----------------|-------------|
| `getEvaluatedSchema({ skipLayout: false })` | `getEvaluatedSchema()` | Menghasilkan struktur penuh payload object JS Javascript Root. |
| `getEvaluatedSchemaWithoutParams({ ... })` | `getSchema()` | Mencabut header meta logic `$params` untuk object return murni variable saja. |
| `getEvaluatedSchemaByPath({ path })` | `_jpath(obj, path)` | Singular getter. Mengambil property obyek pada format skema pointer array. Hemat daya JS memory JSON stringify secara dramatis di node. |
| `getEvaluatedSchemaByPaths({ paths, format })` | (List Looping `_jpath`) | Fungsi mass-extrator getter variabel point target json pointers objects nodes (mapping output arrays `0`, flat obj `1`, collection arrays index format struct map `2`). |
| `getSchemaByPath({ path })` (atau `.get()`) | `_jpath(obj, path)` | Memungut mapping JSON pointer def statis mentah (schema definisi saja tidak ada data). |

---

## Bagian 4. Konfigurasi struktur data tes (Data validation logic error json output arrays paths)

Validation node evaluator sekarang mengeksekusinya tidak dari flag eksekusi evaluasi yang senyap melampirkan pesan output validasinya secara aneh pada data. Model JSON Validation module terkini otomatis menghasilkan hasil Object Mapping node-by-node error dictionary paths parameter data error list properties object JSON output return list mapping variables logic di Javascript return values message rules mapping field errors payload:

### Fungsi proses validasi standar API array payload json properties map properties json logic nodes (`validate`)

```typescript
// Legacy style variable format data parameter list arguments options legacy options methods arg variables fields paths strings properties arrays:
// const { hasError, error } = evaluator.validate(data, context, paths);

// Paket Terbaru Unified Validation API payload parameters JSON argument mapping returns mapping keys JSON result paths:
const result = await evaluator.validate({
  data: data,
  context: context
});

if (result.has_error || result.hasError) { 
  // Object dictionary values dipasangkan mapping ke list pointer strings properties node paths jadi tidak perlu mencari-cari variable child.
  console.log(result.error["properties.name.value"].message); 
}
```

---

## Bagian 5. Modifikasi logic fungsi API engine utilitas compiler evaluator properties statis

Module backend Core engine dari parser JSON evaluation JS ini membuka function node terpisah pada modul rust core ini fitur engine-nya tanpa bergantung ke parent node objects memory mapping instance JSON evaluation var struct node methods ini:

- **Isolasi static rules expression json tree eval logic eksekusi pointer variables JSON objects rules string arguments logic logic test function evaluator map rules expression object arguments boolean tests object object eval nodes logic properties compiler evaluation mapping arguments evaluate logic logic function execution JSON node method boolean method logic JSON array logic method object node eval static method function eval compiler evaluation boolean evaluation static JS test object boolean nodes arrays boolean json boolean (`evaluateLogic`)**:
```typescript
JSONEval.evaluateLogic({ "==": [1, 1] }); // true (kompilasi static direct var test static json object tests params methods evaluate eval objects mapping methods boolean eval node values)
```
- **Pengeksekusian stop interupsi manual function promise backend JSI (`cancel()`)**: Anda memegang remote pembatal eval parsing node di memory logic form node backend JSON payload properties struct object methods JS JS eval object js mem. Set trigger untuk stop mematikan processing json evaluate memory array promise evaluate memory array data mem `await evaluator.cancel()` di logic backend JS API evaluator method object execution mapping properties memory data object test function node mem method memory method js method parser.

---

## Bagian 6. Form bersarang (*managed subform*) yang tertangani dengan utuh

Bila menggunakan codebase `@qsi/json-eval` versi pertama (legacy), Anda akan menyadari bahwa modul tersebut kesulitan memisahkan data sub-komponen saat melakukan iterasi node array. Untuk mengatasinya, developer terpaksa memisahkan deklarasi class evaluator secara manual (`JSONEval` instance) di setiap loop mapping komponen frontend, sehingga array root seolah-olah diputus dari parent-nya.

### Pengaturan inisialisasi secara manual di versi legacy
```typescript
// Legacy: Memisahkan bagian sub-schema property array ke dalam bentuk class object evaluator yang berdiri sendiri.
const subformTemplate = parentSchema.properties.riders.items;
const detachedJse = new JSONEval(subformTemplate, mainContext, false, subformData);

detachedJse.evaluate(subformData, mainContext);
```

### Rutinitas modern untuk manajemen subform
Engine versi terbaru kini dapat menyelesaikan resolusi subform secara internal menggunakan identifier path. Instance core melacak dokumen array secara native sehingga Anda tidak perlu memecah struktur array tree di sisi memori JavaScript.

Dengan mengarahkan variabel `activeSubformPath` secara persis ke spesifik node yang dituju (misal index ke-`0` dari array objek bernama `riders`), Anda dapat membatasi cakupan wilayah komputasi evaluasinya:

```typescript
// Modern: Membatasi jalannya evaluasi secara native.
const activeSubformPath = "#/properties/riders/0";

await evaluator.evaluateSubform(activeSubformPath, formPayload, mainContext);

const diffs = await evaluator.evaluateDependentsSubform(
  activeSubformPath, 
  ["properties.benefit.value"], // Letak fields yang dimodifikasi di dalam scope area ini 
  formPayload, 
  mainContext, 
  true // set evaluasi cascade otomatis
);

const validationData = await evaluator.validateSubform(activeSubformPath, formPayload, mainContext);

// Extrapolasi map memori definition untuk child data ditarik tanpa overhead parent document
const nodeSchema = await evaluator.getEvaluatedSchemaSubform(activeSubformPath, true);
const childData = await evaluator.getSchemaValueSubform(activeSubformPath);
```

Fungsi endpoint subform ini (`evaluateSubform`, `validateSubform`, dsb.) dirancang agar rendering komponen array yang kompleks dieksekusi secara independen dan efisien.

---

## Bagian 7. Kiat optimasi performa

Saat melakukan migrasi, hindari sekadar menjiplak loop iterasi dari skrip legacy ke framework baru. Rust API memberikan Anda alat penarikan data yang jauh lebih efisien:

- **Bypass ekstra data parameter yang berlebih**: Gunakan API `getEvaluatedSchemaWithoutParams` dibanding `getEvaluatedSchema` secara penuh. Menghilangkan backend variabel `$params` akan mengurangi beban parsing payload serialization secara masif.
- **Hanya panggil data field yang diperlukan**: Dahulu merupakan hal umum untuk memanggil semua objek full JSON tree hanya untuk mengecek field spesifik boolean, sehingga memakan memory RAM tinggi. Anda wajib menggantinya ke method terarah (pointer locator) yakni `getEvaluatedSchemaByPath(_paths)`. Hal ini menghindari lonjakan memori (memory spikes) re-rendering karena fungsi hanya akan mengekstrak byte nodes spesifik dari memori variabel yang Anda referensikan.
