How a JSON or JSON-like language enables the next generation of safe human and AI-generated UIs አግኙን በ , እኔ በ AI-generated code የተፈጥሮ JavaScript አንድ ደህንነት ችግር ነው, እና አንድ framework ምንም የ JavaScript ጥንካሬ ቁጥጥር ኮድ ሊሆን ይችላል ያውቃል. ወይም A (ኤምኤምኤም) ጋር (JPRX ከሆነ), የእኛን መተግበሪያዎችን ለመፍጠር አንድ የ LLM ያረጋግጣል. የ AI-Generated UI መኖሪያ ቤት አዲሱ የኮምፒውተር ቤት የ JSON Pointer መደበኛ ስዕሎች ይህ መተግበሪያ ኢንዱስትሪ መደበኛዎች ላይ የተመሠረተ ከሆነ በተጨማሪም ይረዳል, ይህም የ LLMs በሽያጭ ወቅት መውሰድ የሚፈልጉትን ብዙ ማረጋገጫ እና ለምሳሌዎች አሉ. cCOM እና JPRX ይህን ያደርጋሉ; እነርሱ JSON Pointers, JSON Schema, እና XPath ከ ኮምፒዩተሮች እና ስቴትስ ያካትታል. የ cDOM እና JPRX ን እንዴት ይሰራል ለማሳየት የቀድሞው ጽሑፍ ውስጥ, እኔ አንድ ተንቀሳቃሽ መለያ ይጠቀሙ, ነገር ግን ተመሳሳይ ይሆናል: ተንቀሳቃሽ መለያዎች እና To-Do Lists ቀላል ናቸው. እያንዳንዱ ቅርጸት አንድ ሻጋታ ላይ ተስማሚ ጊዜ ቀላል ይሆናል. JSON ላይ የተመሠረተ ቅርጸት በእርግጥ ተስማሚ ነው ለማረጋገጥ, ከባድ ሁኔታ, ከባድ ቅርጸት, እና የተለያየ የሥራ ቅርጸቶች ጋር አንድ ችግር አለብዎት. አንድ የኮምፒተር አለብዎት. የኮሌክትሮኒክስ በእርግጥ አስቸጋሪ ናቸው: መተግበሪያዎች: አንድ ቀጣይ ቁጥር መተግበሪያ ወይም አንድ የአሁኑ ቁጥር መተግበሪያ ነው? የ "+" ከዚያም "-" ከዚያም "*" ምንም ተመሳሳይ ተመሳሳይ ጊዜ ምን ይሆናል? DRY Logic: በ 0-9 ግምገማዎች ውስጥ በ 10 መተግበሪያዎች መካከል ኮድ የተለያዩን እንዴት ያንካትታል? ስለዚህ, Claude Opus በመጠቀም አንድ ሙሉ በሙሉ ተግባራዊ, የ iOS-ስማርት ኮምፒውተር ለመፍጠር እፈልጋለሁ. - ብቻ deklarative cDOM እና JPRX አጠቃቀም. zero custom JavaScript functions የቴክኖሎጂ ማረጋገጫ ከሁለቱም ዝቅተኛ ፍላጎት ጋር የቴክኖሎጂ ማረጋገጫ ማረጋገጫ ማረጋገጫ ማግኘት ይችላሉ ምክንያቱም የ cDOM እና JPRX ብቻ አዲስ ቅናሽ አይሆንም. ኮድ በ cDOMC, የ cDOM የተመሠረተ ስሪት ነው. አንድ መደበኛ cDOM አስተያየቶች አጠቃቀም አይችልም እና መሳሪያዎች እና JPRX ስሪትዎች ላይ ቅርጸት ያስፈልጋል. የ cDOM ጋር እና ምንም አስተያየቶች ጋር ይተካል ጊዜ, cDOM እንደ መደበኛ JSON ሊተካል ይችላል. { div: { class: "calculator", // A calculator feels stateless, but it's actually a strict state machine. // You're never just "typing a number"; you're either entering the first operand, // waiting for an operator, or entering the next operand. onmount: =state({ display: "0", // What you see on the screen expr: "", // History string, (e.g. "8 + 5 =") prev: "", // value stored before an operation op: "", // the active operator waiting: false // true when expecting a new number vs operator },{ name: "c", // the root name of our state, so we can express things like: /c/display schema: "polymorphic", // allow type changes, e.g. "0" or 0 scope: $this // scope the path to the current element }), children: [ // Display area { div: { class: "display", children: [ { div: { class: "expression",children[=/c/expr] }}, { div: { class: "result",children[=/c/display] }} ] } }, // Button grid { div: { class: "buttons", children: [ // Row 1: AC, ±, %, ÷ { button: { class: "btn btn-clear", onclick: =/c = { display: "0", expr: "", prev: "", op: "", waiting: false }, children: ["AC"] } }, { button: { class: "btn btn-function", onclick: =/c = { display: negate(/c/display), waiting: true, expr: "" }, children: ["±"] } }, { button: { class: "btn btn-function", onclick: =/c = { display: toPercent(/c/display), waiting: true, expr: "" }, children: ["%"] } }, // Divison is our first operator. This is where it gets tricky. // When you click `+`, you can't just link `prev` to `display`. // If you did, `prev` would update every time you selected a new digit for the**second**number, // breaking the math. We need a snapshot of the value at that exact moment. // Excel solves this with INDIRECT, effectively dereferencing a cell. JPRX borrows the same concept: { button: { class: "btn btn-operator", onclick: =/c = { prev: indirect(/c/display), // Capture the value right now expr: concat(/c/display, " ÷"), op: "/", waiting: true }, children: ["÷"] } }, // Row 2: 7, 8, 9, × // I have 10 number buttons. Do I write 10 handlers? Do I write a loop? In React or Vue, // you'd probably map over an array. With JPRX, the DOM is the data key and although map is available, // I represent the calculator using literals in this example. In a future article I will cover map. // By giving each button an `id` (e.g., `id: "7"`), we write a uniform logic expression that adapts // to whichever element triggered it. We just reference $this.id in JPRX and use an xpath to get the text // content for the child node, #../@id. In cDOM (not JPRX) '#' delimits the start of an xpath expression { button: { id: "7", class: "btn btn-number", onclick: =/c = { display: if(/c/waiting, $this.id, if(/c/display==0, $this.id, concat(/c/display, $this.id))), waiting: false }, children: [#../@id] // use xpath (starting char #) to get the text for the button from parent id } }, // Here's what is happening: // Waiting for input? (e.g., just hit `+`) → Replace the display with the button's ID. // Displaying "0"? → Replace it (avoids "07"). // Otherwise: → Append the button's ID. // This is replicated identically for every number button. No loops, no external helper functions. { button: { id: "8", class: "btn btn-number", onclick: =/c = { display: if(/c/waiting, $this.id, if(/c/display==0), $this.id, concat(/c/display, $this.id))), waiting: false }, children: [#../@id] } }, { button: { id: "9", class: "btn btn-number", onclick: =/c = { display: if(/c/waiting, $this.id, if(/c/display==0, $this.id, concat(/c/display, $this.id))), waiting: false }, children: [#../@id] } }, { button: { class: "btn btn-operator", onclick: =/c = { prev: indirect(/c/display), expr: concat(/c/display, " ×"), op: "*", waiting: true }, children: ["×"] } }, // Row 3: 4, 5, 6, − { button: { id: "4", class: "btn btn-number", onclick: =/c = { display: if(/c/waiting, $this.id, if(/c/display==0, $this.id, concat(/c/display, $this.id))), waiting: false }, children: [#../@id] } }, { button: { id: "5", class: "btn btn-number", onclick: =/c = { display: if(/c/waiting, $this.id, if(/c/display==0, $this.id, concat(/c/display, $this.id))), waiting: false }, children: [#../@id] } }, { button: { id: "6", class: "btn btn-number", onclick: =/c = { display: if(/c/waiting, $this.id, if(/c/display==0, $this.id, concat(/c/display, $this.id))), waiting: false }, children: [#../@id] } }, { button: { class: "btn btn-operator", onclick: =/c = { prev: indirect(/c/display), expr: concat(/c/display, " −"), op: "-", waiting: true }, children: ["−"] } }, // Row 4: 1, 2, 3, +, use set and eq just to demonstrate equivalence with = and == // the buttons below use 'set' in place of the infix operator '=', just to show a different way of doing things { button: { id: "1", class: "btn btn-number", onclick: =set(/c, { display: if(/c/waiting, $this.id, if(eq(/c/display, "0"), $this.id, concat(/c/display, $this.id))), waiting: false }), children: [#../@id] } }, { button: { id: "2", class: "btn btn-number", onclick: =set(/c, { display: if(/c/waiting, $this.id, if(eq(/c/display, "0"), $this.id, concat(/c/display, $this.id))), waiting: false }), children: [#../@id] } }, { button: { id: "3", class: "btn btn-number", onclick: =set(/c, { display: if(/c/waiting, $this.id, if(eq(/c/display, "0"), $this.id, concat(/c/display, $this.id))), waiting: false }), children: [#../@id] } }, { button: { class: "btn btn-operator", onclick: =set(/c, { prev: indirect(/c/display), expr: concat(/c/display, " +"), op: "+", waiting: true }), children: ["+"] } }, // Row 5: 0, ., = { button: { id: "0", class: "btn btn-number btn-wide", onclick: =set(/c, { display: if(/c/waiting, $this.id, if(eq(/c/display, "0"), "0", concat(/c/display, $this.id))), waiting: false }), children: [#../@id] } }, { button: { class: "btn btn-number", onclick: =set(/c, { display: if(/c/waiting, "0.", if(contains(/c/display, "."), /c/display, concat(/c/display, "."))), waiting: false }), children: ["."] } }, // Finally, the math. We need to say: // 1. Take the snapshot we stored // 2. Apply the current operator // 3. combine it with what's on screen now // This is the job of calc(). If prev == 8 and op == * and display = 5, then calc would be evaluated as calc("8 * 5") // To keep the syntax a little cleaner we also use $(<path>) as a shorthand for indirect. { button: { class: "btn btn-equals", onclick: =set(/c, { display: if(eq(/c/op, ""), /c/display, calc(concat("$('/c/prev') ", /c/op, " $('/c/display')"))), expr: concat(/c/expr, " ", /c/display, " ="), prev: "", op: "", waiting: true }), children: ["="] } } ] } }, // Branding { div: { class: "branding", children: [ { span: { children: [ "Built with ", { a: { href: "https://github.com/anywhichway/lightview", target: "_blank", children: ["Lightview"] } }, " cDOM • No custom JS!" ] } } ] } } ] } } በ Lightview Hypermedia በመጠቀም cDOM መጫን Lightview እንደ Hypermedia ችሎታ ያቀርባል በመጠቀም ይቻላል በአጠቃላይ እያንዳንዱ ክፍሎች ላይ ነው. HTMX src አጠቃቀም a አጠቃቀም ፋይል : cDOM src <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content="A beautiful calculator built with Lightview cDOM and JPRX reactive expressions - no custom JavaScript!"> <title>Calculator | Lightview cDOM</title> <link rel="stylesheet" href="calculator.css"> <!-- Load Lightview scripts --> <script src="/lightview.js"></script> <!-- DOM as JSON and reactivity support --> <script src="/lightview-x.js"></script> <!-- hypermedia support --> <script src="/lightview-cdom.js"></script> <-- cDOM/JPRX support --> </head> <body> <!-- The calculator cDOM is loaded via Lightview's hypermedia src attribute --> <div id="app" src="./calculator.cdomc"></div> </body> </html> የ መሳሪያዎች እንደ HTML ይሰራሉ ወይም መለያ - Lightview ራስ-ሰር ያግኙ የፕላስቲክ መሣሪያዎች, የፕላስቲክ መሣሪያዎች, የፕላስቲክ መሣሪያዎች, የፕላስቲክ መሣሪያዎች, የፕላስቲክ መሣሪያዎች, የፕላስቲክ መሣሪያዎች, የፕላስቲክ መሣሪያዎች, የፕላስቲክ መሣሪያዎች, የፕላስቲክ መሣሪያዎች, የፕላስቲክ መሣሪያዎች, የፕላስቲክ መሣሪያዎች, የፕላስቲክ መሣሪያዎች, የፕላስቲክ መሣሪያዎች, የፕላስቲክ መሣሪያዎች, የፕላስቲክ መሣሪያዎች src <img> <script> .cdomc ለምን በዚህ መንገድ ለመፍጠር? እርስዎ መመልከት ይችላሉ ይጠይቃል : concat("$('/c/prev') ...") በዓለም ውስጥ አንተ ብቻ መጻፍ አይችልም parseFloat(prev) + parseFloat(curr) ? እርስዎ አንድ ሰው ኮድ መጻፍ ከሆነ? እርስዎ የሚፈልጉት ይችላሉ. Lightview እንደዚህ ምክንያት መደበኛ JS መቆጣጠሪያዎችን ያቀርባል. ነገር ግን እርስዎ መዋቅር ለመፍጠር አንድ deklarative, JSON-መሠረተ መንገዶች ላይ ያካትታሉ, ብጁ ኮድ አይችሉም ነገሮች ይሰጣሉ: AI Agents Sandboxing: ይህ ቁጥጥር አካባቢ ውስጥ ይሰራል. የ Logic 'windows' መዳረሻ አይችሉም, የዓለም አቀፍ ማውረድ ጥያቄዎች ሊሆን አይችሉም, ወይም በእርግጠኝነት ሁለተኛ ኮድ ይሰራል. ይህ በእርግጠኝነት የ LLM የተፈጥሮ የ UI Logic 'hot swap' ለማግኘት ደህንነት ያደርጋል. ተንቀሳቃሽነት: ይህ ሙሉ UI—የሎጋክ እና ሁሉም—እውነተኛ ውሂብ ብቻ ነው. ይህ በ Server, በ Database ውስጥ የተጠበቀ ሊሆን ይችላል, ወይም በ AI ሞዴል ከ streaming ሊሆን ይችላል. የምስክር ወረቀት: ይህ የ LLMs የተሻለ እንዴት ነው, የአሜሪካ ግምገማዎች እና ግምገማ መዋቅር መካከል ቀላል ክፍያ ይጠቀማል. ይህ ኮምፒውተር "Declarative" ምንም "የመደጋሚ" መውሰድ አለብዎት ያረጋግጣል. ለስላሳ ትክክለኛዎች - ስቴትስ, conditionals, እና path-based referencing - እርስዎ በዲትስራክሬሽን ለመውሰድ ምንም ጊዜ ምንም ጥንካሬ, የኮምፒውተር ተኳሃኝዎችን ለመፍጠር ይችላሉ. አብዛኞቹ ፎቶ ይህ ተከታታይ ብቻ አንድ አዲስ ካፒታል ስለ አይደለም. ይህ የ AI ልምድ ለማግኘት ትክክክለኛ አጠቃቀም ደረጃ ለማግኘት ነው. በ , እኛ የ LLMs የክብደት ስኬት መጻፍ ሊሆን ይችላል ፡፡ እና "Data as UI" ልምድ ያውቃል ፡፡ የ AI-Generated UI መኖሪያ ቤት በዚህ ጽሑፍ ውስጥ, "Data as UI" በ "xpath" በመጠቀም የ state, context, data snapshots, math, and DOM navigation without executing a single line of custom JavaScript. የ cDOM መዋቅር ያካትታል. የ JPRX መዋቅር ያካትታል. የ compilation እና የ UI ምንም ደህንነቱ የተጠበቀ ምልክቶች አጠቃቀም ነው. እርስዎ ይሞክሩ ሙሉ የኮሌክትሮኒክስ በ: የመስመር ላይ ንድፍ: https://lightview.dev/docs/calculator.html የክፍያ ኮድ: https://github.com/anywhichway/lightview/blob/main/docs/calculator.html https://lightview.dev/docs/calculator.html https://github.com/anywhichway/lightview/blob/main/docs/calculator.html