lightview 2.4.4 → 2.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AI-GUIDANCE.md +25 -10
- package/build_tmp/lightview-cdom.js +3934 -0
- package/build_tmp/lightview-router.js +185 -0
- package/build_tmp/lightview-x.js +1739 -0
- package/build_tmp/lightview.js +740 -0
- package/docs/assets/styles/site.css +16 -7
- package/docs/benchmarks/bau-tagged-fragment.js +41 -0
- package/docs/cdom.html +127 -88
- package/docs/dom-benchmark.html +131 -4
- package/docs/getting-started/index.html +40 -0
- package/docs/index.html +40 -31
- package/package.json +2 -2
package/docs/dom-benchmark.html
CHANGED
|
@@ -161,9 +161,14 @@
|
|
|
161
161
|
class="btn btn-outline btn-benchmark border-slate-300">Run Raw oDOM</button>
|
|
162
162
|
<button onclick="runBenchmark('vDOM')"
|
|
163
163
|
class="btn btn-outline btn-benchmark border-slate-300">Run Lightview vDOM</button>
|
|
164
|
+
<button onclick="runBenchmark('JurisODOM')"
|
|
165
|
+
class="btn btn-outline btn-benchmark border-slate-300">Run JurisJS oDOM</button>
|
|
164
166
|
<button onclick="runBenchmark('TaggedScript')"
|
|
165
167
|
class="btn btn-outline btn-benchmark border-slate-300">Run Lightview Tagged
|
|
166
168
|
Script</button>
|
|
169
|
+
<button onclick="runBenchmark('BauTaggedScript')"
|
|
170
|
+
class="btn btn-outline btn-benchmark border-slate-300">Run Bau Tagged
|
|
171
|
+
Script</button>
|
|
167
172
|
<div class="divider"></div>
|
|
168
173
|
<button onclick="runAll()" class="btn btn-primary text-white">Run All Benchmarks</button>
|
|
169
174
|
<button onclick="clearTarget()" class="btn btn-ghost">Clear Target</button>
|
|
@@ -303,6 +308,31 @@
|
|
|
303
308
|
</div>
|
|
304
309
|
</div>
|
|
305
310
|
|
|
311
|
+
<div class="result-card" id="res-JurisODOM">
|
|
312
|
+
<div class="flex justify-between items-start mb-2">
|
|
313
|
+
<h3 class="font-bold text-slate-500 uppercase text-xs tracking-widest">JurisJS oDOM</h3>
|
|
314
|
+
<div class="flex flex-col items-end gap-1">
|
|
315
|
+
<div class="badge badge-outline badge-xs opacity-50"><span class="size">--</span> KB
|
|
316
|
+
</div>
|
|
317
|
+
<div class="badge badge-accent badge-xs text-white opacity-70"><span
|
|
318
|
+
class="gzip-size">--</span> KB gzip</div>
|
|
319
|
+
<div class="badge badge-ghost badge-sm opacity-50">ms</div>
|
|
320
|
+
</div>
|
|
321
|
+
</div>
|
|
322
|
+
<div class="text-3xl font-black text-slate-800 mb-4"><span class="time">--</span></div>
|
|
323
|
+
|
|
324
|
+
<div class="grid grid-cols-4 gap-2 text-[10px] uppercase font-bold text-slate-400 mb-3">
|
|
325
|
+
<div>Min <span class="min block text-slate-600">--</span></div>
|
|
326
|
+
<div>Avg <span class="avg block text-slate-600">--</span></div>
|
|
327
|
+
<div>Max <span class="max block text-slate-600">--</span></div>
|
|
328
|
+
<div class="text-right">±SD <span class="std block text-slate-600">--</span></div>
|
|
329
|
+
</div>
|
|
330
|
+
|
|
331
|
+
<div class="progress-bar-custom">
|
|
332
|
+
<div class="progress-fill" id="fill-JurisODOM"></div>
|
|
333
|
+
</div>
|
|
334
|
+
</div>
|
|
335
|
+
|
|
306
336
|
<div class="result-card" id="res-TaggedScript">
|
|
307
337
|
<div class="flex justify-between items-start mb-2">
|
|
308
338
|
<h3 class="font-bold text-slate-500 uppercase text-xs tracking-widest">Lightview Tagged
|
|
@@ -328,6 +358,32 @@
|
|
|
328
358
|
<div class="progress-fill" id="fill-TaggedScript"></div>
|
|
329
359
|
</div>
|
|
330
360
|
</div>
|
|
361
|
+
|
|
362
|
+
<div class="result-card" id="res-BauTaggedScript">
|
|
363
|
+
<div class="flex justify-between items-start mb-2">
|
|
364
|
+
<h3 class="font-bold text-slate-500 uppercase text-xs tracking-widest">Bau Tagged
|
|
365
|
+
Script</h3>
|
|
366
|
+
<div class="flex flex-col items-end gap-1">
|
|
367
|
+
<div class="badge badge-outline badge-xs opacity-50"><span class="size">--</span> KB
|
|
368
|
+
</div>
|
|
369
|
+
<div class="badge badge-accent badge-xs text-white opacity-70"><span
|
|
370
|
+
class="gzip-size">--</span> KB gzip</div>
|
|
371
|
+
<div class="badge badge-ghost badge-sm opacity-50">ms</div>
|
|
372
|
+
</div>
|
|
373
|
+
</div>
|
|
374
|
+
<div class="text-3xl font-black text-slate-800 mb-4"><span class="time">--</span></div>
|
|
375
|
+
|
|
376
|
+
<div class="grid grid-cols-4 gap-2 text-[10px] uppercase font-bold text-slate-400 mb-3">
|
|
377
|
+
<div>Min <span class="min block text-slate-600">--</span></div>
|
|
378
|
+
<div>Avg <span class="avg block text-slate-600">--</span></div>
|
|
379
|
+
<div>Max <span class="max block text-slate-600">--</span></div>
|
|
380
|
+
<div class="text-right">±SD <span class="std block text-slate-600">--</span></div>
|
|
381
|
+
</div>
|
|
382
|
+
|
|
383
|
+
<div class="progress-bar-custom">
|
|
384
|
+
<div class="progress-fill" id="fill-BauTaggedScript"></div>
|
|
385
|
+
</div>
|
|
386
|
+
</div>
|
|
331
387
|
</div>
|
|
332
388
|
|
|
333
389
|
<div class="card bg-white shadow-sm border border-slate-200">
|
|
@@ -347,6 +403,7 @@
|
|
|
347
403
|
<!-- Core Libraries -->
|
|
348
404
|
<script src="/lightview.js"></script>
|
|
349
405
|
<script src="/lightview-x.js"></script>
|
|
406
|
+
<script src="https://cdn.jsdelivr.net/npm/juris@0.9.0/juris.min.js"></script>
|
|
350
407
|
|
|
351
408
|
<script>
|
|
352
409
|
function generateHTML(count) {
|
|
@@ -468,6 +525,55 @@
|
|
|
468
525
|
return el;
|
|
469
526
|
}
|
|
470
527
|
|
|
528
|
+
function odomToDOM_Juris(onode) {
|
|
529
|
+
if (typeof onode !== 'object' || onode === null) {
|
|
530
|
+
return document.createTextNode(onode);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// Create a temporary container for Juris to render into
|
|
534
|
+
const tempContainer = document.createElement('div');
|
|
535
|
+
|
|
536
|
+
// Temporarily disable all console methods to prevent Juris logging from affecting benchmark
|
|
537
|
+
const originalConsole = {
|
|
538
|
+
log: console.log,
|
|
539
|
+
dir: console.dir,
|
|
540
|
+
warn: console.warn,
|
|
541
|
+
error: console.error,
|
|
542
|
+
info: console.info,
|
|
543
|
+
debug: console.debug
|
|
544
|
+
};
|
|
545
|
+
const noop = () => { };
|
|
546
|
+
console.log = noop;
|
|
547
|
+
console.dir = noop;
|
|
548
|
+
console.warn = noop;
|
|
549
|
+
console.error = noop;
|
|
550
|
+
console.info = noop;
|
|
551
|
+
console.debug = noop;
|
|
552
|
+
|
|
553
|
+
try {
|
|
554
|
+
// Create a Juris instance with the oDOM structure as the layout
|
|
555
|
+
const jurisInstance = new Juris({
|
|
556
|
+
debug: false, // Disable logging for performance
|
|
557
|
+
layout: onode
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
// Render to the temporary container
|
|
561
|
+
jurisInstance.render(tempContainer);
|
|
562
|
+
} finally {
|
|
563
|
+
// Restore original console methods
|
|
564
|
+
console.log = originalConsole.log;
|
|
565
|
+
console.dir = originalConsole.dir;
|
|
566
|
+
console.warn = originalConsole.warn;
|
|
567
|
+
console.error = originalConsole.error;
|
|
568
|
+
console.info = originalConsole.info;
|
|
569
|
+
console.debug = originalConsole.debug;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// Return the first child (the actual rendered content)
|
|
573
|
+
return tempContainer.firstChild || tempContainer;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
|
|
471
577
|
async function getGzipSize(str) {
|
|
472
578
|
try {
|
|
473
579
|
const stream = new Blob([str]).stream();
|
|
@@ -518,7 +624,7 @@
|
|
|
518
624
|
function clearTarget() {
|
|
519
625
|
target.replaceChildren();
|
|
520
626
|
target.innerHTML = '<div class="p-8 text-center text-slate-400 italic">Target is empty.</div>';
|
|
521
|
-
['innerHTML', 'DOMParser', 'vDOM', 'RawVDOM', 'RawoDOM', 'TaggedScript'].forEach(id => {
|
|
627
|
+
['innerHTML', 'DOMParser', 'vDOM', 'RawVDOM', 'RawoDOM', 'JurisODOM', 'TaggedScript', 'BauTaggedScript'].forEach(id => {
|
|
522
628
|
const card = document.getElementById(`res-${id}`);
|
|
523
629
|
card.classList.remove('active');
|
|
524
630
|
card.querySelector('.time').innerText = '--';
|
|
@@ -568,6 +674,12 @@
|
|
|
568
674
|
const domEl = odomToDOM(json);
|
|
569
675
|
target.replaceChildren(domEl);
|
|
570
676
|
time = performance.now() - start;
|
|
677
|
+
} else if (type === 'JurisODOM') {
|
|
678
|
+
const start = performance.now();
|
|
679
|
+
const json = JSON.parse(data);
|
|
680
|
+
const domEl = odomToDOM_Juris(json);
|
|
681
|
+
target.replaceChildren(domEl);
|
|
682
|
+
time = performance.now() - start;
|
|
571
683
|
} else if (type === 'TaggedScript') {
|
|
572
684
|
const existing = document.getElementById('tagged-script-tag');
|
|
573
685
|
if (existing) existing.remove();
|
|
@@ -580,6 +692,19 @@
|
|
|
580
692
|
document.body.appendChild(script);
|
|
581
693
|
});
|
|
582
694
|
time = window.__taggedBenchmarkTime;
|
|
695
|
+
} else if (type === 'BauTaggedScript') {
|
|
696
|
+
const existing = document.getElementById('bau-tagged-script-tag');
|
|
697
|
+
if (existing) existing.remove();
|
|
698
|
+
|
|
699
|
+
await new Promise(resolve => {
|
|
700
|
+
window.__resolveBauTaggedBenchmark = resolve;
|
|
701
|
+
const script = document.createElement('script');
|
|
702
|
+
script.type = 'module';
|
|
703
|
+
script.id = 'bau-tagged-script-tag';
|
|
704
|
+
script.src = `./benchmarks/bau-tagged-fragment.js?count=${count}&t=${Date.now()}`;
|
|
705
|
+
document.body.appendChild(script);
|
|
706
|
+
});
|
|
707
|
+
time = window.__bauTaggedBenchmarkTime;
|
|
583
708
|
}
|
|
584
709
|
return time;
|
|
585
710
|
}
|
|
@@ -592,10 +717,10 @@
|
|
|
592
717
|
let data = preGeneratedData;
|
|
593
718
|
|
|
594
719
|
// 1. Preparation phase (outside of timing)
|
|
595
|
-
if (!data && type !== 'TaggedScript') {
|
|
720
|
+
if (!data && type !== 'TaggedScript' && type !== 'BauTaggedScript') {
|
|
596
721
|
if (type === 'innerHTML' || type === 'DOMParser') data = generateHTML(count);
|
|
597
722
|
if (type === 'vDOM' || type === 'RawVDOM') data = generateVDOM(count);
|
|
598
|
-
if (type === 'RawoDOM') data = generateODOM(count);
|
|
723
|
+
if (type === 'RawoDOM' || type === 'JurisODOM') data = generateODOM(count);
|
|
599
724
|
}
|
|
600
725
|
|
|
601
726
|
console.log(`Starting ${cycles} cycles for ${type}...`);
|
|
@@ -628,7 +753,9 @@
|
|
|
628
753
|
{ id: 'RawVDOM', data: vdomData },
|
|
629
754
|
{ id: 'RawoDOM', data: odomData },
|
|
630
755
|
{ id: 'vDOM', data: vdomData },
|
|
631
|
-
{ id: '
|
|
756
|
+
{ id: 'JurisODOM', data: odomData },
|
|
757
|
+
{ id: 'TaggedScript', data: null },
|
|
758
|
+
{ id: 'BauTaggedScript', data: null }
|
|
632
759
|
];
|
|
633
760
|
|
|
634
761
|
for (const config of configs) {
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
<button class="btn btn-secondary step-btn" onclick="switchStep(4)">4. Hypermedia</button>
|
|
16
16
|
<button class="btn btn-secondary step-btn" onclick="switchStep(5)">5. Components</button>
|
|
17
17
|
<button class="btn btn-secondary step-btn" onclick="switchStep(6)">6. Gating</button>
|
|
18
|
+
<button class="btn btn-secondary step-btn" onclick="switchStep(7)">7. cDOM</button>
|
|
18
19
|
</div>
|
|
19
20
|
|
|
20
21
|
<!-- Tutorial Layout: Preview on top, Code & Concepts below -->
|
|
@@ -679,6 +680,45 @@ $('#app').content(App);`,
|
|
|
679
680
|
<li style="margin-bottom: 0.75rem;"><strong>Write your own</strong> — Write your own functions and add the to <code>globalThis</code> to make them available to all templates. They have access to <code>this</code> (the element) and can accept arguments like <code>event</code>.</li>
|
|
680
681
|
</ul>
|
|
681
682
|
<p><strong>Try it:</strong> Click the Spam Me button rapidly, or type quickly into the search box to see the limiters in action!</p>`
|
|
683
|
+
},
|
|
684
|
+
7: {
|
|
685
|
+
options: {
|
|
686
|
+
autoRun: true
|
|
687
|
+
},
|
|
688
|
+
code: `// STEP 7: cDOM - Compressed DOM & JPRX
|
|
689
|
+
await import('/lightview-cdom.js');
|
|
690
|
+
const { parseJPRX, hydrate } = globalThis.LightviewCDOM;
|
|
691
|
+
const { $ } = Lightview;
|
|
692
|
+
|
|
693
|
+
const cdomString = \`{
|
|
694
|
+
div: {
|
|
695
|
+
onmount: =signal(0,"count"),
|
|
696
|
+
children: [
|
|
697
|
+
{ h3: ["Standard JPRX Counter"] },
|
|
698
|
+
{ p: { children: ["Count: ", =/count] }},
|
|
699
|
+
{ div: { children: [
|
|
700
|
+
{ button: { onclick: =decrement(/count), children: ["-"] } },
|
|
701
|
+
{ button: { onclick: =/count++, children: ["+"] } }
|
|
702
|
+
]}}
|
|
703
|
+
]
|
|
704
|
+
}
|
|
705
|
+
}\`;
|
|
706
|
+
|
|
707
|
+
const hydrated = hydrate(parseJPRX(cdomString));
|
|
708
|
+
$('#app').content(hydrated);`,
|
|
709
|
+
concepts: `
|
|
710
|
+
<h3 style="margin-top: 0; color: var(--site-primary);">Step 7: cDOM & JPRX</h3>
|
|
711
|
+
<p><strong><a href="/docs/cdom.html">cDOM</a></strong> (compressed DOM) combined with <strong><a href="/docs/cdom.html#JPRX">JPRX</a></strong> (JSON Path Reactive eXpressions) allows you to define entire reactive UIs as pure JSON-compatible strings.</p>
|
|
712
|
+
|
|
713
|
+
<h4>Key Concepts:</h4>
|
|
714
|
+
<ul style="padding-left: 1.25rem; color: var(--site-text-secondary);">
|
|
715
|
+
<li style="margin-bottom: 0.75rem;"><strong>Portability</strong> — Since the UI is a string, it can be easily stored in databases, sent over the wire, or generated by an LLM without security risks of <code>eval()</code>.</li>
|
|
716
|
+
<li style="margin-bottom: 0.75rem;"><strong>JPRX Expressions</strong> — Use <code>=</code> to denote reactive expressions within the string. For example, <code>=/count</code> binds to a signal.</li>
|
|
717
|
+
<li style="margin-bottom: 0.75rem;"><strong>Flexible Syntax</strong> — Operators and helpers can be called as functions (<code>=decrement(/count)</code>) or using prefix (<code>=--/count</code>), infix (<code>=/count - 1</code>), or postfix (<code>=/count--</code>) notation.</li>
|
|
718
|
+
<li style="margin-bottom: 0.75rem;"><strong>Hydration</strong> — <code>hydrate()</code> turns the parsed JPRX into a live, reactive DOM tree.</li>
|
|
719
|
+
</ul>
|
|
720
|
+
<p><strong>Try it:</strong> Edit the <code>cdomString</code> to change the labels or add new elements!</p>
|
|
721
|
+
`
|
|
682
722
|
}
|
|
683
723
|
};
|
|
684
724
|
|
package/docs/index.html
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
More power. Less energy.
|
|
12
12
|
<br>
|
|
13
13
|
<a id="link-hero-ai-safe" href="#ai-safe"
|
|
14
|
-
style="color: var(--site-primary); font-size: 1.25rem; font-weight: 700; text-decoration: none; display: inline-block; margin-top: 0.
|
|
14
|
+
style="color: var(--site-primary); font-size: 1.25rem; font-weight: 700; text-decoration: none; display: inline-block; margin-top: 0.25rem; border-bottom: 2px solid var(--site-primary); padding-bottom: 2px;">AI
|
|
15
15
|
Safe</a>
|
|
16
16
|
</p>
|
|
17
17
|
<div class="hero-actions">
|
|
@@ -23,12 +23,15 @@
|
|
|
23
23
|
<div class="hero-stat-label">Build Steps</div>
|
|
24
24
|
</div>
|
|
25
25
|
<div class="hero-stat">
|
|
26
|
-
<div class="hero-stat-value"
|
|
26
|
+
<div class="hero-stat-value"><a id="link-hero-ways-to-build"
|
|
27
|
+
href="http://localhost:3000/docs/api/elements"
|
|
28
|
+
style="color: inherit; text-decoration: none;">5</a></div>
|
|
27
29
|
<div class="hero-stat-label">Ways to Build</div>
|
|
28
30
|
</div>
|
|
29
31
|
<div class="hero-stat">
|
|
30
32
|
<div class="hero-stat-value">40+</div>
|
|
31
|
-
<div class="hero-stat-label"
|
|
33
|
+
<div class="hero-stat-label"><a id="link-hero-components" href="http://localhost:3000/docs/components/"
|
|
34
|
+
style="color: inherit; text-decoration: none;">Components</a></div>
|
|
32
35
|
</div>
|
|
33
36
|
</div>
|
|
34
37
|
</div>
|
|
@@ -38,79 +41,84 @@
|
|
|
38
41
|
<section class="section">
|
|
39
42
|
<div class="section-content">
|
|
40
43
|
<div class="section-header">
|
|
41
|
-
<h2 class="section-title">
|
|
42
|
-
<p class="section-subtitle">
|
|
43
|
-
Have fun, stay light.
|
|
44
|
-
</p>
|
|
44
|
+
<h2 class="section-title">Why Lightview</h2>
|
|
45
45
|
</div>
|
|
46
46
|
<div class="feature-grid">
|
|
47
|
-
<
|
|
47
|
+
<a id="link-feature-signals" href="./api/signals.html" class="feature-card">
|
|
48
48
|
<div class="feature-icon">
|
|
49
49
|
<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
|
|
50
50
|
<circle cx="12" cy="12" r="10" />
|
|
51
51
|
<path d="M12 6v6l4 2" />
|
|
52
52
|
</svg>
|
|
53
53
|
</div>
|
|
54
|
-
<h3
|
|
55
|
-
State Reactivity</a></h3>
|
|
54
|
+
<h3 class="feature-title">Signals and Object State Reactivity</h3>
|
|
56
55
|
<p class="feature-description">
|
|
57
|
-
Fine-grained reactivity with signals and
|
|
58
|
-
DOM diffing needed.
|
|
56
|
+
Fine-grained reactivity with signals and object state. Updates propagate automatically—no virtual
|
|
57
|
+
DOM diffing needed. Arrays and Dates are directly reactive without destructing or copying. As a
|
|
58
|
+
bonus, session and local storage are also supported.
|
|
59
59
|
</p>
|
|
60
|
-
</
|
|
61
|
-
<
|
|
60
|
+
</a>
|
|
61
|
+
<a id="link-feature-elements" href="./api/elements.html" class="feature-card">
|
|
62
62
|
<div class="feature-icon">
|
|
63
63
|
<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
|
|
64
64
|
<rect x="3" y="3" width="18" height="18" rx="2" />
|
|
65
65
|
<path d="M3 9h18M9 21V9" />
|
|
66
66
|
</svg>
|
|
67
67
|
</div>
|
|
68
|
-
<h3
|
|
69
|
-
</h3>
|
|
68
|
+
<h3 class="feature-title">Multiple Syntaxes</h3>
|
|
70
69
|
<p class="feature-description">
|
|
71
70
|
Tagged API, vDOM, Object DOM, HTML. Pick your style—they all work together.
|
|
72
71
|
</p>
|
|
73
|
-
</
|
|
74
|
-
<
|
|
72
|
+
</a>
|
|
73
|
+
<a id="link-feature-hypermedia" href="/docs/hypermedia/" class="feature-card">
|
|
75
74
|
<div class="feature-icon">
|
|
76
75
|
<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
|
|
77
76
|
<path
|
|
78
77
|
d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.66 0 3-4 3-9s-1.34-9-3-9m0 18c-1.66 0-3-4-3-9s1.34-9 3-9" />
|
|
79
78
|
</svg>
|
|
80
79
|
</div>
|
|
81
|
-
<h3
|
|
82
|
-
Ready</a></h3>
|
|
80
|
+
<h3 class="feature-title">Hypermedia Ready</h3>
|
|
83
81
|
<p class="feature-description">
|
|
84
82
|
Fetch HTML, vDOM, or Object DOM with the <code>src</code> attribute. HTMX-like patterns for
|
|
85
83
|
<code>src</code> and <code>href</code> built right
|
|
86
84
|
in.
|
|
87
85
|
</p>
|
|
88
|
-
</
|
|
89
|
-
<
|
|
86
|
+
</a>
|
|
87
|
+
<a id="link-feature-components" href="./components/index.html" class="feature-card">
|
|
90
88
|
<div class="feature-icon">
|
|
91
89
|
<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
|
|
92
90
|
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5" />
|
|
93
91
|
</svg>
|
|
94
92
|
</div>
|
|
95
|
-
<h3
|
|
96
|
-
Library</a></h3>
|
|
93
|
+
<h3 class="feature-title">Component Library</h3>
|
|
97
94
|
<p class="feature-description">
|
|
98
95
|
Beautiful, accessible components ready to use. Buttons, modals, forms, charts, and more.
|
|
99
96
|
</p>
|
|
100
|
-
</
|
|
101
|
-
<
|
|
97
|
+
</a>
|
|
98
|
+
<a id="link-feature-zerobuild" href="./getting-started/index.html" class="feature-card">
|
|
102
99
|
<div class="feature-icon">
|
|
103
100
|
<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
|
|
104
101
|
<path
|
|
105
102
|
d="M14.7 6.3a1 1 0 000 1.4l1.6 1.6a1 1 0 001.4 0l3.77-3.77a6 6 0 01-7.94 7.94l-6.91 6.91a2.12 2.12 0 01-3-3l6.91-6.91a6 6 0 017.94-7.94l-3.76 3.76z" />
|
|
106
103
|
</svg>
|
|
107
104
|
</div>
|
|
108
|
-
<h3
|
|
109
|
-
Step</a></h3>
|
|
105
|
+
<h3 class="feature-title">Zero Build Step</h3>
|
|
110
106
|
<p class="feature-description">
|
|
111
107
|
No bundler required. Drop in a script tag and start building. Works everywhere.
|
|
112
108
|
</p>
|
|
113
|
-
</
|
|
109
|
+
</a>
|
|
110
|
+
<a id="link-feature-aisafe" href="#ai-safe" class="feature-card">
|
|
111
|
+
<div class="feature-icon">
|
|
112
|
+
<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
|
|
113
|
+
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
|
|
114
|
+
</svg>
|
|
115
|
+
</div>
|
|
116
|
+
<h3 class="feature-title">AI Safe</h3>
|
|
117
|
+
<p class="feature-description">
|
|
118
|
+
Build reactive UIs with pure JSON or JSON like data. No eval(), no risky code generation. Safe for
|
|
119
|
+
AI agents.
|
|
120
|
+
</p>
|
|
121
|
+
</a>
|
|
114
122
|
|
|
115
123
|
</div>
|
|
116
124
|
</div>
|
|
@@ -150,7 +158,8 @@
|
|
|
150
158
|
<h3 style="color: white; font-size: 1.5rem; margin-bottom: 1rem;">Execution Safety</h3>
|
|
151
159
|
<p style="color: rgba(255, 255, 255, 0.75); line-height: 1.6;">AI-generated UIs usually require
|
|
152
160
|
risky JavaScript strings. cDOM creates reactive interfaces using <strong>pure JSON
|
|
153
|
-
data</strong> and <a id="link-ai-safe-cdom-helpers"
|
|
161
|
+
or JSON like data</strong> and <a id="link-ai-safe-cdom-helpers"
|
|
162
|
+
href="/docs/cdom.html#helpers"
|
|
154
163
|
style="color: #a78bfa; text-decoration: underline; font-weight: 600;">over 50 built-in
|
|
155
164
|
functions</a> that bring spreadsheet-like
|
|
156
165
|
functionality to the DOM. No <code>eval()</code>, no <code>new Function()</code>, and <strong>no
|
|
@@ -223,7 +232,7 @@
|
|
|
223
232
|
<section class="section">
|
|
224
233
|
<div class="section-content">
|
|
225
234
|
<div class="section-header">
|
|
226
|
-
<h2 class="section-title">
|
|
235
|
+
<h2 class="section-title">Lighten Up.</h2>
|
|
227
236
|
<p class="section-subtitle">
|
|
228
237
|
Get started in minutes. No npm install. No webpack or vite build process. Just code.
|
|
229
238
|
</p>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lightview",
|
|
3
|
-
"version": "2.4.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.4.7",
|
|
4
|
+
"description": "A reactive UI library with features of Bau, Juris, and HTMX plus safe LLM UI generation",
|
|
5
5
|
"main": "lightview.js",
|
|
6
6
|
"workspaces": [
|
|
7
7
|
"jprx"
|