@jay-framework/stack-server-build 0.25.3 → 0.25.5
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/dist/index.d.ts +3 -0
- package/dist/index.js +144 -4
- package/package.json +13 -13
package/dist/index.d.ts
CHANGED
|
@@ -117,6 +117,9 @@ interface GenerateClientScriptOptions {
|
|
|
117
117
|
slowViewState?: object;
|
|
118
118
|
/** Route pattern (e.g., /products/kitan{/:category}) for freeze entries */
|
|
119
119
|
routePattern?: string;
|
|
120
|
+
/** Project-relative path of the page's jay-html (DL#219) — reported by the source-editing
|
|
121
|
+
* inspector as the file the matched `lines` live in. */
|
|
122
|
+
sourceFile?: string;
|
|
120
123
|
}
|
|
121
124
|
/**
|
|
122
125
|
* Shared fragments generated by buildScriptFragments().
|
package/dist/index.js
CHANGED
|
@@ -420,8 +420,9 @@ function buildPageReloadHmrScript() {
|
|
|
420
420
|
});
|
|
421
421
|
}`;
|
|
422
422
|
}
|
|
423
|
-
function buildFreezeScript(routePattern) {
|
|
423
|
+
function buildFreezeScript(routePattern, sourceFile) {
|
|
424
424
|
const routePatternLiteral = routePattern ? `'${routePattern}'` : "undefined";
|
|
425
|
+
const sourceFileLiteral = sourceFile ? JSON.stringify(sourceFile) : "undefined";
|
|
425
426
|
return `
|
|
426
427
|
// Page Freeze (DL#127, DL#128 iframe addendum)
|
|
427
428
|
// Sticky embed mode: URL param sets a session cookie so in-iframe navigation preserves it
|
|
@@ -476,13 +477,152 @@ function buildFreezeScript(routePattern) {
|
|
|
476
477
|
}
|
|
477
478
|
}
|
|
478
479
|
|
|
480
|
+
// Source-editing inspector (DL#219). Resolves a viewport point/rect to the jay-dev-* source
|
|
481
|
+
// markers emitted when the dev server runs with sourceEditing on. Harmless without markers —
|
|
482
|
+
// it simply finds no jay-dev-src and replies node:null. Reply carries source LOCATORS (line
|
|
483
|
+
// ranges + route) plus runtime identities (forEach record id, region name + static props);
|
|
484
|
+
// the agent reads bound expressions / collection / if-conditions from the jay-html itself.
|
|
485
|
+
function __jayParseLines(s) {
|
|
486
|
+
if (!s) return null;
|
|
487
|
+
const parts = s.split(':');
|
|
488
|
+
return { from: parseInt(parts[0], 10), to: parseInt(parts[1], 10) };
|
|
489
|
+
}
|
|
490
|
+
function __jayLines(el) {
|
|
491
|
+
return __jayParseLines(el.getAttribute('jay-dev-src'));
|
|
492
|
+
}
|
|
493
|
+
// A significant enclosing frame: a forEach item root or a region boundary. Returns null for
|
|
494
|
+
// plain wrapper elements (the agent reconstructs those from source via node.lines).
|
|
495
|
+
function __jayFrame(el) {
|
|
496
|
+
const item = el.getAttribute('jay-dev-item');
|
|
497
|
+
if (item) return { kind: 'forEach', lines: __jayLines(el), itemId: item };
|
|
498
|
+
const region = el.getAttribute('jay-dev-region');
|
|
499
|
+
if (region) {
|
|
500
|
+
// Region lines live in jay-dev-region-src (the <jay:…> tag's range), distinct from the
|
|
501
|
+
// root element's own jay-dev-src.
|
|
502
|
+
const frame = { kind: 'region', lines: __jayParseLines(el.getAttribute('jay-dev-region-src')), name: region };
|
|
503
|
+
const rawProps = el.getAttribute('jay-dev-region-props');
|
|
504
|
+
if (rawProps) { try { frame.props = JSON.parse(decodeURIComponent(rawProps)); } catch (e) {} }
|
|
505
|
+
return frame;
|
|
506
|
+
}
|
|
507
|
+
return null;
|
|
508
|
+
}
|
|
509
|
+
// One-level HTML of an element: its open tag (authored attrs only, jay-* stripped), its direct
|
|
510
|
+
// children shown as empty tags (grandchildren elided with …), and its text — so the agent sees
|
|
511
|
+
// exactly what was clicked inside generated content without the whole subtree.
|
|
512
|
+
function __jayOneLevelHtml(el) {
|
|
513
|
+
if (!el || !el.tagName) return '';
|
|
514
|
+
const tag = el.tagName.toLowerCase();
|
|
515
|
+
let attrs = '';
|
|
516
|
+
for (let i = 0; i < el.attributes.length; i++) {
|
|
517
|
+
const a = el.attributes[i];
|
|
518
|
+
if (a.name.indexOf('jay-') === 0) continue; // strip jay-dev-* / jay-coordinate
|
|
519
|
+
attrs += ' ' + a.name + '="' + a.value + '"';
|
|
520
|
+
}
|
|
521
|
+
let inner = '';
|
|
522
|
+
const kids = el.childNodes || [];
|
|
523
|
+
for (let i = 0; i < kids.length; i++) {
|
|
524
|
+
const c = kids[i];
|
|
525
|
+
if (c.nodeType === 3) inner += (c.textContent || '');
|
|
526
|
+
else if (c.nodeType === 1) {
|
|
527
|
+
const ct = c.tagName.toLowerCase();
|
|
528
|
+
inner += '<' + ct + '>' + (c.childNodes && c.childNodes.length ? '…' : '') + '</' + ct + '>';
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
if (inner.length > 300) inner = inner.slice(0, 300) + '…';
|
|
532
|
+
return '<' + tag + attrs + '>' + inner + '</' + tag + '>';
|
|
533
|
+
}
|
|
534
|
+
function __jayResolveElement(el) {
|
|
535
|
+
if (!el) return null;
|
|
536
|
+
// Walk el up to (but excluding) <body>.
|
|
537
|
+
const entries = [];
|
|
538
|
+
let cur = el;
|
|
539
|
+
while (cur && cur.nodeType === 1 && cur.tagName && cur.tagName.toLowerCase() !== 'body') {
|
|
540
|
+
entries.push(cur);
|
|
541
|
+
cur = cur.parentElement;
|
|
542
|
+
}
|
|
543
|
+
// Source anchor = nearest element at/above el carrying a source marker (its line range).
|
|
544
|
+
let sourceEl = null;
|
|
545
|
+
for (let i = 0; i < entries.length; i++) {
|
|
546
|
+
if (entries[i].getAttribute('jay-dev-src')) { sourceEl = entries[i]; break; }
|
|
547
|
+
}
|
|
548
|
+
if (!sourceEl) return null;
|
|
549
|
+
// Stack = only the significant enclosing frames (forEach + region), innermost → outermost.
|
|
550
|
+
const stack = [];
|
|
551
|
+
for (let i = 0; i < entries.length; i++) {
|
|
552
|
+
const f = __jayFrame(entries[i]);
|
|
553
|
+
if (f) stack.push(f);
|
|
554
|
+
}
|
|
555
|
+
// node describes the ACTUAL element el (what the pointer hit / the rect chose). html — a
|
|
556
|
+
// one-level rendering (open tag with authored attrs, direct children as empty tags, inline
|
|
557
|
+
// text; grandchildren + long text elided) — is the single content field: it carries the tag,
|
|
558
|
+
// attributes (src/href/value), and value, bounded in size. lines come from the source anchor;
|
|
559
|
+
// for bound/generated content (an html-string value) el has no jay-dev-src of its own, so
|
|
560
|
+
// lines point to the ENCLOSING binding (the editable source) and contentFromBinding flags it.
|
|
561
|
+
const r = el.getBoundingClientRect();
|
|
562
|
+
const node = {
|
|
563
|
+
lines: __jayLines(sourceEl),
|
|
564
|
+
tag: el.tagName ? el.tagName.toLowerCase() : '',
|
|
565
|
+
html: __jayOneLevelHtml(el),
|
|
566
|
+
rect: { x: r.x, y: r.y, width: r.width, height: r.height },
|
|
567
|
+
};
|
|
568
|
+
const childEls = Array.prototype.slice.call(el.children || []);
|
|
569
|
+
const childrenGenerated =
|
|
570
|
+
childEls.length > 0 && childEls.every((c) => !c.getAttribute('jay-dev-src'));
|
|
571
|
+
if (!el.getAttribute('jay-dev-src') || childrenGenerated) {
|
|
572
|
+
node.contentFromBinding = true;
|
|
573
|
+
}
|
|
574
|
+
return { node, stack };
|
|
575
|
+
}
|
|
576
|
+
function __jayInspectPoint(x, y) {
|
|
577
|
+
return __jayResolveElement(document.elementFromPoint(x, y));
|
|
578
|
+
}
|
|
579
|
+
function __jayInspectRect(x, y, w, h) {
|
|
580
|
+
const sel = { left: x, top: y, right: x + w, bottom: y + h };
|
|
581
|
+
const marked = Array.prototype.slice.call(document.querySelectorAll('[jay-dev-src]'));
|
|
582
|
+
let best = null, bestArea = -1;
|
|
583
|
+
for (let i = 0; i < marked.length; i++) {
|
|
584
|
+
const el = marked[i];
|
|
585
|
+
const r = el.getBoundingClientRect();
|
|
586
|
+
const elArea = r.width * r.height;
|
|
587
|
+
if (elArea <= 0) continue;
|
|
588
|
+
const ix = Math.max(0, Math.min(sel.right, r.right) - Math.max(sel.left, r.left));
|
|
589
|
+
const iy = Math.max(0, Math.min(sel.bottom, r.bottom) - Math.max(sel.top, r.top));
|
|
590
|
+
// Rect rule (DL#219): keep elements the box mostly encloses (overlap over the ELEMENT's
|
|
591
|
+
// own area >= 0.8), then pick the LARGEST — the element the box was drawn around. A tight
|
|
592
|
+
// box only clears the threshold for the small element; a big box clears it for the
|
|
593
|
+
// container too, and largest-area returns the container (not its first child).
|
|
594
|
+
if ((ix * iy) / elArea >= 0.8 && elArea > bestArea) {
|
|
595
|
+
bestArea = elArea;
|
|
596
|
+
best = el;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
if (best) return __jayResolveElement(best);
|
|
600
|
+
return __jayInspectPoint(x + w / 2, y + h / 2);
|
|
601
|
+
}
|
|
602
|
+
|
|
479
603
|
if (__jayEmbedMode) {
|
|
480
604
|
// Notify parent of the current route on load (DL#128 route addendum)
|
|
481
605
|
window.parent.postMessage({ type: 'jay:route', route: window.location.pathname, routePattern: ${routePatternLiteral} }, '*');
|
|
482
606
|
|
|
483
|
-
// Embed mode: parent triggers freeze via postMessage
|
|
607
|
+
// Embed mode: parent triggers freeze / inspect via postMessage
|
|
484
608
|
window.addEventListener('message', (e) => {
|
|
485
|
-
|
|
609
|
+
const d = e.data;
|
|
610
|
+
if (!d) return;
|
|
611
|
+
if (d.type === 'jay:requestFreeze') { __jayDoFreeze(); return; }
|
|
612
|
+
if (d.type === 'jay:inspectPoint' || d.type === 'jay:inspectRect') {
|
|
613
|
+
const result = d.type === 'jay:inspectPoint'
|
|
614
|
+
? __jayInspectPoint(d.x, d.y)
|
|
615
|
+
: __jayInspectRect(d.x, d.y, d.width, d.height);
|
|
616
|
+
window.parent.postMessage({
|
|
617
|
+
type: 'jay:inspectResult',
|
|
618
|
+
requestId: d.requestId,
|
|
619
|
+
file: ${sourceFileLiteral},
|
|
620
|
+
route: window.location.pathname,
|
|
621
|
+
routePattern: ${routePatternLiteral},
|
|
622
|
+
node: result ? result.node : null, // node.rect is the matched element's on-screen box
|
|
623
|
+
stack: result ? result.stack : [],
|
|
624
|
+
}, '*');
|
|
625
|
+
}
|
|
486
626
|
});
|
|
487
627
|
} else {
|
|
488
628
|
// Standalone: Alt+S / Option+S keyboard shortcut
|
|
@@ -507,7 +647,7 @@ function buildAutomationWrap(options, mode) {
|
|
|
507
647
|
}
|
|
508
648
|
const appendLine = appendDom ? `
|
|
509
649
|
target.appendChild(wrapped.element.dom);` : "";
|
|
510
|
-
const freezeScript = buildFreezeScript(options.routePattern);
|
|
650
|
+
const freezeScript = buildFreezeScript(options.routePattern, options.sourceFile);
|
|
511
651
|
if (hasSlowViewState) {
|
|
512
652
|
return `
|
|
513
653
|
// Wrap with automation for dev tooling
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jay-framework/stack-server-build",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.5",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.mts",
|
|
@@ -24,22 +24,22 @@
|
|
|
24
24
|
"test:watch": "vitest"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@jay-framework/compiler-jay-html": "^0.25.
|
|
28
|
-
"@jay-framework/compiler-shared": "^0.25.
|
|
29
|
-
"@jay-framework/component": "^0.25.
|
|
30
|
-
"@jay-framework/fullstack-component": "^0.25.
|
|
31
|
-
"@jay-framework/logger": "^0.25.
|
|
32
|
-
"@jay-framework/runtime": "^0.25.
|
|
33
|
-
"@jay-framework/ssr-runtime": "^0.25.
|
|
34
|
-
"@jay-framework/stack-route-scanner": "^0.25.
|
|
35
|
-
"@jay-framework/stack-server-runtime": "^0.25.
|
|
36
|
-
"@jay-framework/view-state-merge": "^0.25.
|
|
27
|
+
"@jay-framework/compiler-jay-html": "^0.25.5",
|
|
28
|
+
"@jay-framework/compiler-shared": "^0.25.5",
|
|
29
|
+
"@jay-framework/component": "^0.25.5",
|
|
30
|
+
"@jay-framework/fullstack-component": "^0.25.5",
|
|
31
|
+
"@jay-framework/logger": "^0.25.5",
|
|
32
|
+
"@jay-framework/runtime": "^0.25.5",
|
|
33
|
+
"@jay-framework/ssr-runtime": "^0.25.5",
|
|
34
|
+
"@jay-framework/stack-route-scanner": "^0.25.5",
|
|
35
|
+
"@jay-framework/stack-server-runtime": "^0.25.5",
|
|
36
|
+
"@jay-framework/view-state-merge": "^0.25.5",
|
|
37
37
|
"node-html-parser": "^6.1.12",
|
|
38
38
|
"yaml": "^2.3.4"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@jay-framework/dev-environment": "^0.25.
|
|
42
|
-
"@jay-framework/rollup-plugin": "^0.25.
|
|
41
|
+
"@jay-framework/dev-environment": "^0.25.5",
|
|
42
|
+
"@jay-framework/rollup-plugin": "^0.25.5",
|
|
43
43
|
"@types/node": "^22.15.21",
|
|
44
44
|
"rimraf": "^5.0.5",
|
|
45
45
|
"tsup": "^8.0.1",
|