specnav-core 0.2.4 → 0.3.0
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/CHANGELOG.md +12 -0
- package/dist/index.js +149 -72
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +149 -72
- package/dist/index.mjs.map +1 -1
- package/dist/morpher.d.cts +0 -3
- package/dist/morpher.d.ts +0 -3
- package/dist/morpher.js +149 -72
- package/dist/morpher.js.map +1 -1
- package/dist/morpher.mjs +149 -72
- package/dist/morpher.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -360,6 +360,129 @@ function createCacheManager(config, callbacks) {
|
|
|
360
360
|
return new CacheManager(config, callbacks);
|
|
361
361
|
}
|
|
362
362
|
|
|
363
|
+
// src/morpher/fingerprint.ts
|
|
364
|
+
function fnv1a(str) {
|
|
365
|
+
let hash = 2166136261;
|
|
366
|
+
for (let i = 0; i < str.length; i++) {
|
|
367
|
+
hash ^= str.charCodeAt(i);
|
|
368
|
+
hash = hash * 16777619 >>> 0;
|
|
369
|
+
}
|
|
370
|
+
return hash.toString(36);
|
|
371
|
+
}
|
|
372
|
+
function fingerprintNode(node) {
|
|
373
|
+
const tag = node.tagName.toLowerCase();
|
|
374
|
+
const attrs = Array.from(node.attributes).sort((a, b) => a.name.localeCompare(b.name)).map((a) => `${a.name}=${a.value}`).join("|");
|
|
375
|
+
const text = node.childNodes.length === 0 ? node.textContent ?? "" : "";
|
|
376
|
+
const childHashes = Array.from(node.children).map(fingerprintNode).join(",");
|
|
377
|
+
return fnv1a(`${tag}[${attrs}]{${text}}(${childHashes})`);
|
|
378
|
+
}
|
|
379
|
+
var FINGERPRINT_KEY = "__specnav_fp__";
|
|
380
|
+
function stampFingerprints(root) {
|
|
381
|
+
const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
|
|
382
|
+
let node = walker.currentNode;
|
|
383
|
+
while (node) {
|
|
384
|
+
node[FINGERPRINT_KEY] = fingerprintNode(node);
|
|
385
|
+
node = walker.nextNode();
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
function fingerprintMatches(current, incoming) {
|
|
389
|
+
const currentFp = current[FINGERPRINT_KEY];
|
|
390
|
+
if (!currentFp) return false;
|
|
391
|
+
return currentFp === fingerprintNode(incoming);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// src/morpher/identity.ts
|
|
395
|
+
function fnv1a2(str) {
|
|
396
|
+
let hash = 2166136261;
|
|
397
|
+
for (let i = 0; i < str.length; i++) {
|
|
398
|
+
hash ^= str.charCodeAt(i);
|
|
399
|
+
hash = hash * 16777619 >>> 0;
|
|
400
|
+
}
|
|
401
|
+
return hash.toString(36);
|
|
402
|
+
}
|
|
403
|
+
function buildIdentityVector(node, depth = 0) {
|
|
404
|
+
const classes = Array.from(node.classList).sort().join(" ");
|
|
405
|
+
const volatileAttrs = /* @__PURE__ */ new Set(["style", "class", "aria-expanded", "aria-selected"]);
|
|
406
|
+
const stableAttrs = Array.from(node.attributes).filter((a) => !volatileAttrs.has(a.name) && a.name !== "id").sort((a, b) => a.name.localeCompare(b.name)).map((a) => `${a.name}=${a.value}`).join("|");
|
|
407
|
+
return {
|
|
408
|
+
tagName: node.tagName.toLowerCase(),
|
|
409
|
+
id: node.id || null,
|
|
410
|
+
key: node.getAttribute("data-key"),
|
|
411
|
+
classSignature: fnv1a2(classes),
|
|
412
|
+
attrSignature: fnv1a2(stableAttrs),
|
|
413
|
+
textFingerprint: node.children.length === 0 ? (node.textContent ?? "").slice(0, 64) : null,
|
|
414
|
+
childCount: node.childElementCount,
|
|
415
|
+
childTagSequence: Array.from(node.children).slice(0, 5).map((c) => c.tagName.toLowerCase()).join(">"),
|
|
416
|
+
domPosition: Array.from(node.parentElement?.children ?? []).indexOf(node),
|
|
417
|
+
role: node.getAttribute("role")
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
function identityScore(a, b) {
|
|
421
|
+
if (a.tagName !== b.tagName) return 0;
|
|
422
|
+
let score = 0;
|
|
423
|
+
let totalWeight = 0;
|
|
424
|
+
const checks = [
|
|
425
|
+
[a.id, b.id, 40],
|
|
426
|
+
[a.key, b.key, 35],
|
|
427
|
+
[a.classSignature, b.classSignature, 15],
|
|
428
|
+
[a.attrSignature, b.attrSignature, 20],
|
|
429
|
+
[a.textFingerprint, b.textFingerprint, 15],
|
|
430
|
+
[a.childCount, b.childCount, 10],
|
|
431
|
+
[a.childTagSequence, b.childTagSequence, 15],
|
|
432
|
+
[a.domPosition, b.domPosition, 5],
|
|
433
|
+
[a.role, b.role, 10]
|
|
434
|
+
];
|
|
435
|
+
for (const [av, bv, weight] of checks) {
|
|
436
|
+
if (av !== null && bv !== null) {
|
|
437
|
+
totalWeight += weight;
|
|
438
|
+
if (av === bv) score += weight;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return totalWeight === 0 ? 0 : score / totalWeight;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// src/morpher/matcher.ts
|
|
445
|
+
function matchSiblings(currentChildren, incomingChildren) {
|
|
446
|
+
const n = currentChildren.length;
|
|
447
|
+
const m = incomingChildren.length;
|
|
448
|
+
const THRESHOLD = 0.4;
|
|
449
|
+
const scores = Array.from(
|
|
450
|
+
{ length: n },
|
|
451
|
+
(_, i) => Array.from(
|
|
452
|
+
{ length: m },
|
|
453
|
+
(_2, j) => identityScore(
|
|
454
|
+
buildIdentityVector(currentChildren[i]),
|
|
455
|
+
buildIdentityVector(incomingChildren[j])
|
|
456
|
+
)
|
|
457
|
+
)
|
|
458
|
+
);
|
|
459
|
+
const matched = /* @__PURE__ */ new Map();
|
|
460
|
+
const usedIncoming = /* @__PURE__ */ new Set();
|
|
461
|
+
const order = currentChildren.map((_, i) => i).sort((a, b) => {
|
|
462
|
+
const bestA = Math.max(...scores[a] ?? [0]);
|
|
463
|
+
const bestB = Math.max(...scores[b] ?? [0]);
|
|
464
|
+
return bestB - bestA;
|
|
465
|
+
});
|
|
466
|
+
for (const i of order) {
|
|
467
|
+
const row = scores[i];
|
|
468
|
+
let bestJ = -1;
|
|
469
|
+
let bestScore = THRESHOLD;
|
|
470
|
+
for (let j = 0; j < m; j++) {
|
|
471
|
+
if (!usedIncoming.has(j) && (row[j] ?? 0) > bestScore) {
|
|
472
|
+
bestScore = row[j];
|
|
473
|
+
bestJ = j;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
if (bestJ >= 0) {
|
|
477
|
+
matched.set(currentChildren[i], incomingChildren[bestJ]);
|
|
478
|
+
usedIncoming.add(bestJ);
|
|
479
|
+
} else {
|
|
480
|
+
matched.set(currentChildren[i], null);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
return matched;
|
|
484
|
+
}
|
|
485
|
+
|
|
363
486
|
// src/morpher.ts
|
|
364
487
|
var DEFAULT_CONFIG3 = {
|
|
365
488
|
preserveScroll: true,
|
|
@@ -372,23 +495,12 @@ var DOMmorpher = class {
|
|
|
372
495
|
}
|
|
373
496
|
morph(from, to) {
|
|
374
497
|
const ctx = this.createContext();
|
|
498
|
+
if (!from.__specnav_fp__) {
|
|
499
|
+
stampFingerprints(from);
|
|
500
|
+
}
|
|
375
501
|
requestAnimationFrame(() => {
|
|
376
502
|
this.morphElement(from, to, ctx);
|
|
377
503
|
this.restoreContext(ctx);
|
|
378
|
-
this.executeScripts(from);
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
executeScripts(element) {
|
|
382
|
-
const scripts = element.querySelectorAll("script");
|
|
383
|
-
scripts.forEach((oldScript) => {
|
|
384
|
-
if (!oldScript.src && oldScript.textContent) {
|
|
385
|
-
const newScript = document.createElement("script");
|
|
386
|
-
Array.from(oldScript.attributes).forEach((attr) => {
|
|
387
|
-
newScript.setAttribute(attr.name, attr.value);
|
|
388
|
-
});
|
|
389
|
-
newScript.textContent = oldScript.textContent;
|
|
390
|
-
oldScript.parentNode?.replaceChild(newScript, oldScript);
|
|
391
|
-
}
|
|
392
504
|
});
|
|
393
505
|
}
|
|
394
506
|
createContext() {
|
|
@@ -431,6 +543,9 @@ var DOMmorpher = class {
|
|
|
431
543
|
});
|
|
432
544
|
}
|
|
433
545
|
morphElement(from, to, ctx) {
|
|
546
|
+
if (fingerprintMatches(from, to)) {
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
434
549
|
this.syncAttributes(from, to);
|
|
435
550
|
this.morphChildren(from, to, ctx);
|
|
436
551
|
}
|
|
@@ -451,70 +566,32 @@ var DOMmorpher = class {
|
|
|
451
566
|
}
|
|
452
567
|
}
|
|
453
568
|
morphChildren(from, to, ctx) {
|
|
454
|
-
const fromChildren = Array.from(from.
|
|
455
|
-
const toChildren = Array.from(to.
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
const toNode = toChildren[toIndex];
|
|
460
|
-
const fromNode = fromChildren[fromIndex];
|
|
461
|
-
if (!fromNode) {
|
|
462
|
-
from.appendChild(toNode.cloneNode(true));
|
|
463
|
-
toIndex++;
|
|
464
|
-
continue;
|
|
569
|
+
const fromChildren = Array.from(from.children);
|
|
570
|
+
const toChildren = Array.from(to.children);
|
|
571
|
+
if (fromChildren.length === 0 && toChildren.length === 0) {
|
|
572
|
+
if (from.textContent !== to.textContent) {
|
|
573
|
+
from.textContent = to.textContent;
|
|
465
574
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
}
|
|
474
|
-
fromIndex++;
|
|
475
|
-
toIndex++;
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
const matchMap = matchSiblings(fromChildren, toChildren);
|
|
578
|
+
const processedIncoming = /* @__PURE__ */ new Set();
|
|
579
|
+
for (const [currentChild, incomingChild] of matchMap) {
|
|
580
|
+
if (!incomingChild) {
|
|
581
|
+
from.removeChild(currentChild);
|
|
476
582
|
} else {
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
fromIndex + 1,
|
|
480
|
-
toNode
|
|
481
|
-
);
|
|
482
|
-
if (matchIndex !== -1) {
|
|
483
|
-
for (let i = fromIndex; i < matchIndex; i++) {
|
|
484
|
-
from.removeChild(fromChildren[i]);
|
|
485
|
-
}
|
|
486
|
-
fromIndex = matchIndex;
|
|
487
|
-
} else {
|
|
488
|
-
from.insertBefore(toNode.cloneNode(true), fromNode);
|
|
489
|
-
toIndex++;
|
|
490
|
-
}
|
|
583
|
+
this.morphElement(currentChild, incomingChild, ctx);
|
|
584
|
+
processedIncoming.add(incomingChild);
|
|
491
585
|
}
|
|
492
586
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
if (a.nodeType !== b.nodeType) return false;
|
|
500
|
-
if (a.nodeType === Node.ELEMENT_NODE) {
|
|
501
|
-
const aEl = a;
|
|
502
|
-
const bEl = b;
|
|
503
|
-
if (aEl.tagName !== bEl.tagName) return false;
|
|
504
|
-
const aId = aEl.getAttribute("id");
|
|
505
|
-
const bId = bEl.getAttribute("id");
|
|
506
|
-
if (aId && bId) return aId === bId;
|
|
507
|
-
return true;
|
|
508
|
-
}
|
|
509
|
-
return true;
|
|
510
|
-
}
|
|
511
|
-
findMatchingNode(nodes, startIndex, target) {
|
|
512
|
-
for (let i = startIndex; i < nodes.length; i++) {
|
|
513
|
-
if (this.nodesMatch(nodes[i], target)) {
|
|
514
|
-
return i;
|
|
587
|
+
for (let j = 0; j < toChildren.length; j++) {
|
|
588
|
+
const incomingChild = toChildren[j];
|
|
589
|
+
if (!processedIncoming.has(incomingChild)) {
|
|
590
|
+
const cloned = incomingChild.cloneNode(true);
|
|
591
|
+
const refNode = from.children[j] || null;
|
|
592
|
+
from.insertBefore(cloned, refNode);
|
|
515
593
|
}
|
|
516
594
|
}
|
|
517
|
-
return -1;
|
|
518
595
|
}
|
|
519
596
|
};
|
|
520
597
|
function createMorpher(config) {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/trajectory.ts","../src/cache.ts","../src/morpher.ts","../src/speculator.ts","../src/graph.ts","../src/adaptive.ts","../src/performance.ts"],"names":["DEFAULT_CONFIG"],"mappings":"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","file":"index.mjs","sourcesContent":["import type {\n PointerSample,\n Velocity,\n LinkRect,\n TrajectoryConfig,\n} from \"./types\";\n\nconst DEFAULT_CONFIG: TrajectoryConfig = {\n lookaheadMs: 120,\n minVelocity: 0.2,\n sampleRate: 50,\n cancelOnDeviation: true,\n};\n\nexport class TrajectoryEngine {\n private samples: PointerSample[] = [];\n private links: Map<HTMLAnchorElement, LinkRect> = new Map();\n private config: TrajectoryConfig;\n private lastPrediction: string | null = null;\n private sampleInterval: number | null = null;\n private onPrediction?: (href: string) => void;\n private onCancel?: (href: string) => void;\n private cooldownMap = new Map<string, number>();\n private updateDebounceTimer: number | null = null;\n\n constructor(\n config: Partial<TrajectoryConfig> = {},\n callbacks?: {\n onPrediction?: (href: string) => void;\n onCancel?: (href: string) => void;\n }\n ) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.onPrediction = callbacks?.onPrediction;\n this.onCancel = callbacks?.onCancel;\n }\n\n start(): void {\n if (typeof window === \"undefined\") return;\n\n window.addEventListener(\"pointermove\", this.handlePointerMove);\n this.sampleInterval = window.setInterval(\n () => this.processSamples(),\n this.config.sampleRate\n );\n }\n\n stop(): void {\n if (typeof window === \"undefined\") return;\n\n window.removeEventListener(\"pointermove\", this.handlePointerMove);\n if (this.sampleInterval) {\n clearInterval(this.sampleInterval);\n this.sampleInterval = null;\n }\n if (this.updateDebounceTimer) {\n clearTimeout(this.updateDebounceTimer);\n this.updateDebounceTimer = null;\n }\n \n // Clean up memory\n this.samples = [];\n this.links.clear();\n this.cooldownMap.clear();\n this.lastPrediction = null;\n }\n\n registerLink(href: string, element: HTMLAnchorElement): void {\n const rect = element.getBoundingClientRect();\n this.links.set(element, { href, rect, element });\n }\n\n unregisterLink(element: HTMLAnchorElement): void {\n this.links.delete(element);\n }\n\n updateLinkPositions(): void {\n // Debounce to prevent excessive reflows\n if (this.updateDebounceTimer) {\n clearTimeout(this.updateDebounceTimer);\n }\n\n this.updateDebounceTimer = window.setTimeout(() => {\n this.links.forEach((link, element) => {\n const rect = element.getBoundingClientRect();\n this.links.set(element, { ...link, rect });\n });\n this.updateDebounceTimer = null;\n }, 100);\n }\n\n private handlePointerMove = (e: PointerEvent): void => {\n this.samples.push({\n x: e.clientX,\n y: e.clientY,\n t: e.timeStamp,\n });\n\n // Keep only last 10 samples for smoothing\n if (this.samples.length > 10) {\n this.samples.shift();\n }\n };\n\n private processSamples(): void {\n if (this.samples.length < 4) return;\n\n const velocity = this.computeVelocity();\n const speed = Math.sqrt(velocity.vx ** 2 + velocity.vy ** 2);\n\n if (speed < this.config.minVelocity) {\n if (this.lastPrediction && this.config.cancelOnDeviation) {\n this.onCancel?.(this.lastPrediction);\n this.lastPrediction = null;\n }\n return;\n }\n\n const target = this.predictTarget(velocity);\n\n if (target && target.href !== this.lastPrediction) {\n // Check cooldown\n const now = Date.now();\n const lastTime = this.cooldownMap.get(target.href) ?? 0;\n const cooldown = 500; // 500ms cooldown per href\n \n if (now - lastTime < cooldown) {\n return; // Still in cooldown\n }\n\n if (this.lastPrediction && this.config.cancelOnDeviation) {\n this.onCancel?.(this.lastPrediction);\n }\n \n this.lastPrediction = target.href;\n this.cooldownMap.set(target.href, now);\n this.onPrediction?.(target.href);\n } else if (!target && this.lastPrediction && this.config.cancelOnDeviation) {\n this.onCancel?.(this.lastPrediction);\n this.lastPrediction = null;\n }\n }\n\n private computeVelocity(): Velocity {\n const recent = this.samples.slice(-4);\n const dt = recent[recent.length - 1]!.t - recent[0]!.t;\n\n if (dt === 0) return { vx: 0, vy: 0 };\n\n const dx = recent[recent.length - 1]!.x - recent[0]!.x;\n const dy = recent[recent.length - 1]!.y - recent[0]!.y;\n\n return {\n vx: dx / dt,\n vy: dy / dt,\n };\n }\n\n private projectRay(velocity: Velocity): { x: number; y: number } {\n const origin = this.samples[this.samples.length - 1]!;\n return {\n x: origin.x + velocity.vx * this.config.lookaheadMs,\n y: origin.y + velocity.vy * this.config.lookaheadMs,\n };\n }\n\n private predictTarget(velocity: Velocity): LinkRect | null {\n const tip = this.projectRay(velocity);\n\n for (const link of this.links.values()) {\n if (this.rectContains(link.rect, tip)) {\n return link;\n }\n }\n\n return null;\n }\n\n private rectContains(rect: DOMRect, point: { x: number; y: number }): boolean {\n return (\n point.x >= rect.left &&\n point.x <= rect.right &&\n point.y >= rect.top &&\n point.y <= rect.bottom\n );\n }\n}\n\nexport function createTrajectoryEngine(\n config?: Partial<TrajectoryConfig>,\n callbacks?: {\n onPrediction?: (href: string) => void;\n onCancel?: (href: string) => void;\n }\n): TrajectoryEngine {\n return new TrajectoryEngine(config, callbacks);\n}\n","import type { CacheConfig, CachedPage, CacheLayer } from \"./types\";\n\nconst DEFAULT_CONFIG: CacheConfig = {\n memory: {\n enabled: true,\n maxPages: 10,\n },\n serviceWorker: {\n enabled: true,\n ttl: 300,\n cacheName: \"specnav-v1\",\n crossTabSync: true,\n broadcastChannel: \"specnav-sync\",\n },\n edge: {\n enabled: true,\n maxAge: 60,\n staleWhileRevalidate: 300,\n },\n exclude: [],\n};\n\nexport class CacheManager {\n private config: CacheConfig;\n private memoryCache: Map<string, CachedPage> = new Map();\n private accessOrder: string[] = [];\n private broadcastChannel?: BroadcastChannel;\n private onCacheHit?: (href: string, layer: CacheLayer) => void;\n\n constructor(\n config: Partial<CacheConfig> = {},\n callbacks?: { onCacheHit?: (href: string, layer: CacheLayer) => void }\n ) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.onCacheHit = callbacks?.onCacheHit;\n\n if (\n this.config.serviceWorker.enabled &&\n this.config.serviceWorker.crossTabSync &&\n typeof BroadcastChannel !== \"undefined\"\n ) {\n this.broadcastChannel = new BroadcastChannel(\n this.config.serviceWorker.broadcastChannel\n );\n this.broadcastChannel.onmessage = this.handleBroadcast;\n }\n }\n\n async get(href: string): Promise<string | null> {\n if (this.isExcluded(href)) return null;\n\n // L1: Memory cache\n const memoryHit = this.getFromMemory(href);\n if (memoryHit) {\n this.onCacheHit?.(href, 1);\n return memoryHit;\n }\n\n // L2: Service Worker cache\n if (this.config.serviceWorker.enabled) {\n const swHit = await this.getFromServiceWorker(href);\n if (swHit) {\n this.onCacheHit?.(href, 2);\n this.setInMemory(href, swHit);\n return swHit;\n }\n }\n\n return null;\n }\n\n async set(href: string, html: string): Promise<void> {\n if (this.isExcluded(href)) return;\n\n // Sanitize href to prevent cache poisoning\n const sanitizedHref = this.sanitizeHref(href);\n if (!sanitizedHref) return;\n\n // Validate HTML doesn't contain dangerous inline scripts\n if (this.containsDangerousContent(html)) {\n console.warn(`Refusing to cache potentially dangerous content from ${sanitizedHref}`);\n return;\n }\n\n const page: CachedPage = {\n href: sanitizedHref,\n html,\n timestamp: Date.now(),\n ttl: this.config.serviceWorker.ttl,\n };\n\n // L1: Memory\n if (this.config.memory.enabled) {\n this.setInMemory(sanitizedHref, html);\n }\n\n // L2: Service Worker\n if (this.config.serviceWorker.enabled) {\n await this.setInServiceWorker(page);\n this.broadcastSet(sanitizedHref);\n }\n }\n\n private containsDangerousContent(html: string): boolean {\n // Check for inline event handlers and javascript: URLs\n const dangerousPatterns = [\n /on\\w+\\s*=\\s*[\"'][^\"']*[\"']/i, // Inline event handlers\n /javascript:/i, // javascript: URLs\n ];\n\n // Check for inline scripts, but exclude safe types\n const scriptRegex = /<script([^>]*)>([\\s\\S]*?)<\\/script>/gi;\n let match;\n while ((match = scriptRegex.exec(html)) !== null) {\n const attrs = match[1] || \"\";\n const content = match[2] || \"\";\n \n // Allow scripts with src attribute\n if (/src\\s*=/.test(attrs)) continue;\n \n // Allow safe script types (JSON data, templates)\n if (/type\\s*=\\s*[\"']?(application\\/json|application\\/ld\\+json|text\\/template)[\"']?/i.test(attrs)) continue;\n \n // Allow Next.js scripts\n if (/id\\s*=\\s*[\"'](__NEXT_DATA__|_R_)[\"']/i.test(attrs)) continue;\n if (/data-nscript\\s*=/i.test(attrs)) continue;\n \n // Allow module scripts (Next.js uses these for hydration)\n if (/type\\s*=\\s*[\"']?module[\"']?/i.test(attrs)) continue;\n \n // Allow Next.js hydration scripts (self.__next_f, self.__next_r)\n if (/self\\.__next_[fr]/.test(content)) continue;\n \n // If we get here, it's an inline script without safe type\n return true;\n }\n\n return dangerousPatterns.some(pattern => pattern.test(html));\n }\n\n private sanitizeHref(href: string): string | null {\n try {\n const url = new URL(href, window.location.origin);\n // Only allow same-origin URLs\n if (url.origin !== window.location.origin) return null;\n return url.pathname + url.search + url.hash;\n } catch {\n return null;\n }\n }\n\n clear(href?: string): void {\n if (href) {\n this.memoryCache.delete(href);\n this.accessOrder = this.accessOrder.filter((h) => h !== href);\n this.clearFromServiceWorker(href);\n } else {\n this.memoryCache.clear();\n this.accessOrder = [];\n this.clearAllServiceWorker();\n }\n }\n\n getSize(): number {\n return this.memoryCache.size;\n }\n\n destroy(): void {\n this.memoryCache.clear();\n this.accessOrder = [];\n this.broadcastChannel?.close();\n }\n\n private getFromMemory(href: string): string | null {\n const page = this.memoryCache.get(href);\n if (!page) return null;\n\n // Update LRU order\n this.accessOrder = this.accessOrder.filter((h) => h !== href);\n this.accessOrder.push(href);\n\n return page.html;\n }\n\n private setInMemory(href: string, html: string): void {\n // Prevent memory exhaustion - limit individual page size\n const maxPageSize = 5 * 1024 * 1024; // 5MB per page\n if (html.length > maxPageSize) {\n console.warn(`Page ${href} exceeds max size, not caching`);\n return;\n }\n\n this.memoryCache.set(href, {\n href,\n html,\n timestamp: Date.now(),\n ttl: this.config.serviceWorker.ttl,\n });\n\n // Deduplicate before adding to accessOrder\n const existingIndex = this.accessOrder.indexOf(href);\n if (existingIndex !== -1) {\n this.accessOrder.splice(existingIndex, 1);\n }\n this.accessOrder.push(href);\n\n // LRU eviction\n if (this.memoryCache.size > this.config.memory.maxPages) {\n const oldest = this.accessOrder.shift();\n if (oldest) this.memoryCache.delete(oldest);\n }\n }\n\n private async getFromServiceWorker(href: string): Promise<string | null> {\n if (typeof caches === \"undefined\") return null;\n\n try {\n const cache = await caches.open(this.config.serviceWorker.cacheName);\n const response = await cache.match(href);\n\n if (!response) return null;\n\n const data = await response.json();\n const page = data as CachedPage;\n\n // Check TTL\n const age = Date.now() - page.timestamp;\n if (age > page.ttl * 1000) {\n await cache.delete(href);\n return null;\n }\n\n return page.html;\n } catch {\n return null;\n }\n }\n\n private async setInServiceWorker(page: CachedPage): Promise<void> {\n if (typeof caches === \"undefined\") return;\n\n try {\n const cache = await caches.open(this.config.serviceWorker.cacheName);\n const response = new Response(JSON.stringify(page), {\n headers: {\n \"Content-Type\": \"application/json\",\n \"Cache-Control\": `max-age=${this.config.edge.maxAge}, stale-while-revalidate=${this.config.edge.staleWhileRevalidate}`,\n },\n });\n await cache.put(page.href, response);\n } catch {\n // Silently fail\n }\n }\n\n private async clearFromServiceWorker(href: string): Promise<void> {\n if (typeof caches === \"undefined\") return;\n\n try {\n const cache = await caches.open(this.config.serviceWorker.cacheName);\n await cache.delete(href);\n } catch {\n // Silently fail\n }\n }\n\n private async clearAllServiceWorker(): Promise<void> {\n if (typeof caches === \"undefined\") return;\n\n try {\n await caches.delete(this.config.serviceWorker.cacheName);\n } catch {\n // Silently fail\n }\n }\n\n private isExcluded(href: string): boolean {\n return this.config.exclude.some((pattern) => {\n if (typeof pattern === \"string\") {\n return pattern.includes(\"*\")\n ? new RegExp(pattern.replace(/\\*/g, \".*\")).test(href)\n : href === pattern;\n }\n return pattern.test(href);\n });\n }\n\n private broadcastSet(href: string): void {\n this.broadcastChannel?.postMessage({ type: \"set\", href });\n }\n\n private handleBroadcast = (event: MessageEvent): void => {\n if (event.data.type === \"set\") {\n // Invalidate memory cache to force fetch from SW\n this.memoryCache.delete(event.data.href);\n }\n };\n}\n\nexport function createCacheManager(\n config?: Partial<CacheConfig>,\n callbacks?: { onCacheHit?: (href: string, layer: CacheLayer) => void }\n): CacheManager {\n return new CacheManager(config, callbacks);\n}\n","import type { MorphConfig } from \"./types\";\n\nconst DEFAULT_CONFIG: MorphConfig = {\n preserveScroll: true,\n preserveFocus: true,\n};\n\ninterface MorphContext {\n config: MorphConfig;\n focusedElement: Element | null;\n scrollPositions: Map<Element, { top: number; left: number }>;\n}\n\nexport class DOMmorpher {\n private config: MorphConfig;\n\n constructor(config: Partial<MorphConfig> = {}) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n morph(from: Element, to: Element): void {\n const ctx = this.createContext();\n requestAnimationFrame(() => {\n this.morphElement(from, to, ctx);\n this.restoreContext(ctx);\n this.executeScripts(from);\n });\n }\n\n private executeScripts(element: Element): void {\n const scripts = element.querySelectorAll(\"script\");\n scripts.forEach((oldScript) => {\n // Only execute inline scripts (not external ones with src)\n if (!oldScript.src && oldScript.textContent) {\n const newScript = document.createElement(\"script\");\n \n // Copy attributes\n Array.from(oldScript.attributes).forEach((attr) => {\n newScript.setAttribute(attr.name, attr.value);\n });\n \n // Copy content\n newScript.textContent = oldScript.textContent;\n \n // Replace old script with new one to trigger execution\n oldScript.parentNode?.replaceChild(newScript, oldScript);\n }\n });\n }\n\n private createContext(): MorphContext {\n const ctx: MorphContext = {\n config: this.config,\n focusedElement: null,\n scrollPositions: new Map(),\n };\n\n if (this.config.preserveFocus) {\n ctx.focusedElement = document.activeElement;\n }\n\n if (this.config.preserveScroll) {\n this.captureScrollPositions(document.body, ctx.scrollPositions);\n }\n\n return ctx;\n }\n\n private restoreContext(ctx: MorphContext): void {\n if (ctx.config.preserveFocus && ctx.focusedElement) {\n const element = ctx.focusedElement as HTMLElement;\n if (element.focus && document.body.contains(element)) {\n element.focus();\n }\n }\n\n if (ctx.config.preserveScroll) {\n ctx.scrollPositions.forEach((pos, element) => {\n element.scrollTop = pos.top;\n element.scrollLeft = pos.left;\n });\n }\n }\n\n private captureScrollPositions(\n element: Element,\n positions: Map<Element, { top: number; left: number }>\n ): void {\n if (element.scrollTop > 0 || element.scrollLeft > 0) {\n positions.set(element, {\n top: element.scrollTop,\n left: element.scrollLeft,\n });\n }\n\n Array.from(element.children).forEach((child) => {\n this.captureScrollPositions(child, positions);\n });\n }\n\n private morphElement(from: Element, to: Element, ctx: MorphContext): void {\n // Sync attributes\n this.syncAttributes(from, to);\n\n // Morph children\n this.morphChildren(from, to, ctx);\n }\n\n private syncAttributes(from: Element, to: Element): void {\n const fromAttrs = from.attributes;\n const toAttrs = to.attributes;\n\n // Remove attributes not in target\n for (let i = fromAttrs.length - 1; i >= 0; i--) {\n const attr = fromAttrs[i]!;\n if (!to.hasAttribute(attr.name)) {\n from.removeAttribute(attr.name);\n }\n }\n\n // Add/update attributes from target\n for (let i = 0; i < toAttrs.length; i++) {\n const attr = toAttrs[i]!;\n if (from.getAttribute(attr.name) !== attr.value) {\n from.setAttribute(attr.name, attr.value);\n }\n }\n }\n\n private morphChildren(from: Element, to: Element, ctx: MorphContext): void {\n const fromChildren = Array.from(from.childNodes);\n const toChildren = Array.from(to.childNodes);\n\n let fromIndex = 0;\n let toIndex = 0;\n\n while (toIndex < toChildren.length) {\n const toNode = toChildren[toIndex]!;\n const fromNode = fromChildren[fromIndex];\n\n if (!fromNode) {\n // Append new node\n from.appendChild(toNode.cloneNode(true));\n toIndex++;\n continue;\n }\n\n if (this.nodesMatch(fromNode, toNode)) {\n // Nodes match - recurse or update text\n if (fromNode.nodeType === Node.TEXT_NODE) {\n if (fromNode.nodeValue !== toNode.nodeValue) {\n fromNode.nodeValue = toNode.nodeValue;\n }\n } else if (fromNode.nodeType === Node.ELEMENT_NODE) {\n this.morphElement(fromNode as Element, toNode as Element, ctx);\n }\n fromIndex++;\n toIndex++;\n } else {\n // Try to find matching node ahead\n const matchIndex = this.findMatchingNode(\n fromChildren,\n fromIndex + 1,\n toNode\n );\n\n if (matchIndex !== -1) {\n // Remove nodes before match\n for (let i = fromIndex; i < matchIndex; i++) {\n from.removeChild(fromChildren[i]!);\n }\n fromIndex = matchIndex;\n } else {\n // Insert new node\n from.insertBefore(toNode.cloneNode(true), fromNode);\n toIndex++;\n }\n }\n }\n\n // Remove remaining old nodes\n while (fromIndex < fromChildren.length) {\n from.removeChild(fromChildren[fromIndex]!);\n fromIndex++;\n }\n }\n\n private nodesMatch(a: Node, b: Node): boolean {\n if (a.nodeType !== b.nodeType) return false;\n\n if (a.nodeType === Node.ELEMENT_NODE) {\n const aEl = a as Element;\n const bEl = b as Element;\n\n if (aEl.tagName !== bEl.tagName) return false;\n\n const aId = aEl.getAttribute(\"id\");\n const bId = bEl.getAttribute(\"id\");\n\n if (aId && bId) return aId === bId;\n\n return true;\n }\n\n return true;\n }\n\n private findMatchingNode(\n nodes: Node[],\n startIndex: number,\n target: Node\n ): number {\n for (let i = startIndex; i < nodes.length; i++) {\n if (this.nodesMatch(nodes[i]!, target)) {\n return i;\n }\n }\n return -1;\n }\n}\n\nexport function createMorpher(config?: Partial<MorphConfig>): DOMmorpher {\n return new DOMmorpher(config);\n}\n\nexport function morph(\n from: Element,\n to: Element,\n config?: Partial<MorphConfig>\n): void {\n const morpher = createMorpher(config);\n morpher.morph(from, to);\n}\n","interface SpeculatedPage {\n href: string;\n html: string;\n container: HTMLElement;\n timestamp: number;\n}\n\n/**\n * SpeculativeRenderer pre-renders pages in detached DOM containers.\n * \n * LIMITATIONS:\n * - This implementation uses innerHTML, NOT React rendering. The speculated content\n * is raw HTML set on a disconnected DOM node, not a fully rendered React component tree.\n * - For true React speculative rendering, the container must be appended to the document\n * (hidden via CSS) and ReactDOM.createRoot(container).render(...) must be called.\n * - Current implementation is suitable for static HTML morphing but may produce different\n * results than a real React render for dynamic components.\n */\nexport class SpeculativeRenderer {\n private speculations: Map<string, SpeculatedPage> = new Map();\n private maxSpeculations: number;\n\n constructor(maxSpeculations = 3) {\n this.maxSpeculations = maxSpeculations;\n }\n\n async speculate(href: string, html: string): Promise<void> {\n if (this.speculations.has(href)) return;\n\n // Evict oldest if at capacity\n if (this.speculations.size >= this.maxSpeculations) {\n const oldest = Array.from(this.speculations.values()).sort(\n (a, b) => a.timestamp - b.timestamp\n )[0];\n if (oldest) this.cancel(oldest.href);\n }\n\n const container = this.createDetachedContainer();\n container.innerHTML = html;\n\n this.speculations.set(href, {\n href,\n html,\n container,\n timestamp: Date.now(),\n });\n }\n\n get(href: string): HTMLElement | null {\n const speculation = this.speculations.get(href);\n return speculation?.container ?? null;\n }\n\n cancel(href: string): void {\n const speculation = this.speculations.get(href);\n if (speculation) {\n speculation.container.remove();\n this.speculations.delete(href);\n }\n }\n\n cancelAll(): void {\n this.speculations.forEach((spec) => spec.container.remove());\n this.speculations.clear();\n }\n\n has(href: string): boolean {\n return this.speculations.has(href);\n }\n\n private createDetachedContainer(): HTMLElement {\n const container = document.createElement(\"div\");\n container.style.display = \"none\";\n container.setAttribute(\"data-specnav-speculation\", \"true\");\n return container;\n }\n}\n\nexport function createSpeculativeRenderer(\n maxSpeculations?: number\n): SpeculativeRenderer {\n return new SpeculativeRenderer(maxSpeculations);\n}\n","import type { GraphConfig, NavigationGraph } from \"./types\";\n\nconst DEFAULT_CONFIG: GraphConfig = {\n enabled: true,\n minConfidence: 0.6,\n sessionWeight: 0.7,\n storageKey: \"specnav-graph\",\n maxNodes: 50,\n};\n\nexport class NavigationGraphLearner {\n private config: GraphConfig;\n private graph: NavigationGraph = {};\n private sessionGraph: NavigationGraph = {};\n\n constructor(config: Partial<GraphConfig> = {}) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n if (this.config.enabled) {\n this.loadGraph();\n }\n }\n\n recordNavigation(fromHref: string, toHref: string): void {\n if (!this.config.enabled) return;\n\n // Update session graph\n if (!this.sessionGraph[fromHref]) {\n this.sessionGraph[fromHref] = {};\n }\n const current = this.sessionGraph[fromHref]![toHref] ?? 0;\n this.sessionGraph[fromHref]![toHref] = current + 1;\n\n // Update persistent graph\n if (!this.graph[fromHref]) {\n this.graph[fromHref] = {};\n }\n const persistentCurrent = this.graph[fromHref]![toHref] ?? 0;\n this.graph[fromHref]![toHref] = persistentCurrent + 1;\n\n this.saveGraph();\n }\n\n getPredictions(fromHref: string): string[] {\n if (!this.config.enabled) return [];\n\n const sessionEdges = this.sessionGraph[fromHref] ?? {};\n const persistentEdges = this.graph[fromHref] ?? {};\n\n // Merge session and persistent with weighting\n const merged: Record<string, number> = {};\n\n Object.entries(persistentEdges).forEach(([href, count]) => {\n merged[href] = count * (1 - this.config.sessionWeight);\n });\n\n Object.entries(sessionEdges).forEach(([href, count]) => {\n merged[href] = (merged[href] ?? 0) + count * this.config.sessionWeight;\n });\n\n // Calculate total for normalization\n const total = Object.values(merged).reduce((sum, val) => sum + val, 0);\n if (total === 0) return [];\n\n // Convert to confidence scores and filter\n const predictions = Object.entries(merged)\n .map(([href, count]) => ({\n href,\n confidence: count / total,\n }))\n .filter((p) => p.confidence >= this.config.minConfidence)\n .sort((a, b) => b.confidence - a.confidence)\n .map((p) => p.href);\n\n return predictions;\n }\n\n getGraph(): NavigationGraph {\n return { ...this.graph };\n }\n\n clearGraph(): void {\n this.graph = {};\n this.sessionGraph = {};\n this.saveGraph();\n }\n\n private loadGraph(): void {\n if (typeof localStorage === \"undefined\") return;\n\n try {\n const stored = localStorage.getItem(this.config.storageKey);\n if (stored) {\n this.graph = JSON.parse(stored);\n this.pruneGraph();\n }\n } catch {\n // Silently fail\n }\n }\n\n private saveGraph(): void {\n if (typeof localStorage === \"undefined\") return;\n\n try {\n this.pruneGraph();\n const serialized = JSON.stringify(this.graph);\n \n // Check size before saving (localStorage typically has 5-10MB limit)\n if (serialized.length > 4 * 1024 * 1024) { // 4MB safety limit\n console.warn(\"Navigation graph too large, pruning more aggressively\");\n // Prune to half the max nodes (use local variable)\n const reducedMaxNodes = Math.floor(this.config.maxNodes / 2);\n const originalMaxNodes = this.config.maxNodes;\n this.config.maxNodes = reducedMaxNodes;\n this.pruneGraph();\n this.config.maxNodes = originalMaxNodes; // Restore original\n }\n \n localStorage.setItem(this.config.storageKey, JSON.stringify(this.graph));\n } catch (error) {\n // Handle quota exceeded error\n if (error instanceof Error && error.name === \"QuotaExceededError\") {\n console.warn(\"localStorage quota exceeded, clearing navigation graph\");\n this.clearGraph();\n }\n }\n }\n\n private pruneGraph(): void {\n const nodes = Object.keys(this.graph);\n if (nodes.length <= this.config.maxNodes) return;\n\n // Calculate total transitions per node\n const nodeCounts = nodes.map((node) => ({\n node,\n count: Object.values(this.graph[node]!).reduce(\n (sum, val) => sum + val,\n 0\n ),\n }));\n\n // Sort by count and keep top maxNodes\n nodeCounts.sort((a, b) => b.count - a.count);\n const toKeep = new Set(\n nodeCounts.slice(0, this.config.maxNodes).map((n) => n.node)\n );\n\n // Remove nodes not in top set\n Object.keys(this.graph).forEach((node) => {\n if (!toKeep.has(node)) {\n delete this.graph[node];\n }\n });\n }\n}\n\nexport function createNavigationGraphLearner(\n config?: Partial<GraphConfig>\n): NavigationGraphLearner {\n return new NavigationGraphLearner(config);\n}\n\nexport function getNavigationGraph(\n storageKey = \"specnav-graph\"\n): NavigationGraph {\n if (typeof localStorage === \"undefined\") return {};\n\n try {\n const stored = localStorage.getItem(storageKey);\n return stored ? JSON.parse(stored) : {};\n } catch {\n return {};\n }\n}\n","import type { AdaptiveConfig, Strategy } from \"./types\";\n\nconst DEFAULT_CONFIG: AdaptiveConfig = {\n batteryThreshold: 0.2,\n connectionTypes: {\n slow: [\"2g\", \"3g\", \"slow-2g\"],\n fast: [\"4g\"],\n },\n respectSaveData: true,\n respectReducedMotion: true,\n};\n\nexport class AdaptiveMode {\n private config: AdaptiveConfig;\n private battery: any = null;\n private connection: any = null;\n private initPromise: Promise<void>;\n\n constructor(config: Partial<AdaptiveConfig> = {}) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.initPromise = this.initialize();\n }\n\n async waitForInit(): Promise<void> {\n await this.initPromise;\n }\n\n private async initialize(): Promise<void> {\n if (typeof navigator === \"undefined\") return;\n\n // Battery API\n if (\"getBattery\" in navigator) {\n try {\n this.battery = await (navigator as any).getBattery();\n } catch {\n // Not available\n }\n }\n\n // Network Information API\n if (\"connection\" in navigator || \"mozConnection\" in navigator || \"webkitConnection\" in navigator) {\n this.connection =\n (navigator as any).connection ||\n (navigator as any).mozConnection ||\n (navigator as any).webkitConnection;\n }\n }\n\n getStrategy(baseStrategy: Strategy): Strategy {\n if (baseStrategy === \"off\") return \"off\";\n if (baseStrategy !== \"auto\") return baseStrategy;\n\n // Check Save-Data\n if (this.config.respectSaveData && this.hasSaveData()) {\n return \"off\";\n }\n\n // Check battery\n if (this.isLowBattery()) {\n return \"conservative\";\n }\n\n // Check connection\n if (this.isSlowConnection()) {\n return \"conservative\";\n }\n\n return \"aggressive\";\n }\n\n shouldPrefetch(): boolean {\n if (this.config.respectSaveData && this.hasSaveData()) {\n return false;\n }\n\n if (this.isLowBattery()) {\n return false;\n }\n\n return true;\n }\n\n shouldSpeculate(): boolean {\n if (!this.shouldPrefetch()) {\n return false;\n }\n\n if (this.isSlowConnection()) {\n return false;\n }\n\n return true;\n }\n\n shouldUseTransitions(): boolean {\n if (!this.config.respectReducedMotion) return true;\n\n if (typeof window === \"undefined\") return true;\n\n return !window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n }\n\n private hasSaveData(): boolean {\n if (typeof navigator === \"undefined\") return false;\n\n return (\n (navigator as any).connection?.saveData === true ||\n (navigator as any).mozConnection?.saveData === true ||\n (navigator as any).webkitConnection?.saveData === true\n );\n }\n\n private isLowBattery(): boolean {\n if (!this.battery) return false;\n\n return (\n !this.battery.charging &&\n this.battery.level < this.config.batteryThreshold\n );\n }\n\n private isSlowConnection(): boolean {\n if (!this.connection) return false;\n\n const effectiveType = this.connection.effectiveType;\n if (!effectiveType) return false;\n\n return this.config.connectionTypes.slow.includes(effectiveType);\n }\n\n isFastConnection(): boolean {\n if (!this.connection) return true; // Assume fast if unknown\n\n const effectiveType = this.connection.effectiveType;\n if (!effectiveType) return true;\n\n return this.config.connectionTypes.fast.includes(effectiveType);\n }\n\n getBatteryLevel(): number | null {\n return this.battery?.level ?? null;\n }\n\n getConnectionType(): string | null {\n return this.connection?.effectiveType ?? null;\n }\n}\n\nexport function createAdaptiveMode(\n config?: Partial<AdaptiveConfig>\n): AdaptiveMode {\n return new AdaptiveMode(config);\n}\n","// Performance monitoring utilities\n\nexport interface PerformanceMetrics {\n navigationTime: number;\n cacheHit: boolean;\n cacheLayer?: 1 | 2 | 3;\n speculativeHit: boolean;\n fetchTime?: number;\n morphTime?: number;\n}\n\nexport class PerformanceMonitor {\n private metrics: PerformanceMetrics[] = [];\n private maxMetrics = 100;\n\n recordNavigation(metrics: PerformanceMetrics): void {\n this.metrics.push(metrics);\n \n // Keep only last N metrics\n if (this.metrics.length > this.maxMetrics) {\n this.metrics.shift();\n }\n }\n\n getAverageNavigationTime(): number {\n if (this.metrics.length === 0) return 0;\n const sum = this.metrics.reduce((acc, m) => acc + m.navigationTime, 0);\n return sum / this.metrics.length;\n }\n\n getCacheHitRate(): number {\n if (this.metrics.length === 0) return 0;\n const hits = this.metrics.filter(m => m.cacheHit).length;\n return hits / this.metrics.length;\n }\n\n getSpeculativeHitRate(): number {\n if (this.metrics.length === 0) return 0;\n const hits = this.metrics.filter(m => m.speculativeHit).length;\n return hits / this.metrics.length;\n }\n\n getMetrics(): PerformanceMetrics[] {\n return [...this.metrics];\n }\n\n clear(): void {\n this.metrics = [];\n }\n}\n\nexport const performanceMonitor = new PerformanceMonitor();\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/trajectory.ts","../src/cache.ts","../src/morpher/fingerprint.ts","../src/morpher/identity.ts","../src/morpher/matcher.ts","../src/morpher.ts","../src/speculator.ts","../src/graph.ts","../src/adaptive.ts","../src/performance.ts"],"names":["DEFAULT_CONFIG","fnv1a","_"],"mappings":"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","file":"index.mjs","sourcesContent":["import type {\n PointerSample,\n Velocity,\n LinkRect,\n TrajectoryConfig,\n} from \"./types\";\n\nconst DEFAULT_CONFIG: TrajectoryConfig = {\n lookaheadMs: 120,\n minVelocity: 0.2,\n sampleRate: 50,\n cancelOnDeviation: true,\n};\n\nexport class TrajectoryEngine {\n private samples: PointerSample[] = [];\n private links: Map<HTMLAnchorElement, LinkRect> = new Map();\n private config: TrajectoryConfig;\n private lastPrediction: string | null = null;\n private sampleInterval: number | null = null;\n private onPrediction?: (href: string) => void;\n private onCancel?: (href: string) => void;\n private cooldownMap = new Map<string, number>();\n private updateDebounceTimer: number | null = null;\n\n constructor(\n config: Partial<TrajectoryConfig> = {},\n callbacks?: {\n onPrediction?: (href: string) => void;\n onCancel?: (href: string) => void;\n }\n ) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.onPrediction = callbacks?.onPrediction;\n this.onCancel = callbacks?.onCancel;\n }\n\n start(): void {\n if (typeof window === \"undefined\") return;\n\n window.addEventListener(\"pointermove\", this.handlePointerMove);\n this.sampleInterval = window.setInterval(\n () => this.processSamples(),\n this.config.sampleRate\n );\n }\n\n stop(): void {\n if (typeof window === \"undefined\") return;\n\n window.removeEventListener(\"pointermove\", this.handlePointerMove);\n if (this.sampleInterval) {\n clearInterval(this.sampleInterval);\n this.sampleInterval = null;\n }\n if (this.updateDebounceTimer) {\n clearTimeout(this.updateDebounceTimer);\n this.updateDebounceTimer = null;\n }\n \n // Clean up memory\n this.samples = [];\n this.links.clear();\n this.cooldownMap.clear();\n this.lastPrediction = null;\n }\n\n registerLink(href: string, element: HTMLAnchorElement): void {\n const rect = element.getBoundingClientRect();\n this.links.set(element, { href, rect, element });\n }\n\n unregisterLink(element: HTMLAnchorElement): void {\n this.links.delete(element);\n }\n\n updateLinkPositions(): void {\n // Debounce to prevent excessive reflows\n if (this.updateDebounceTimer) {\n clearTimeout(this.updateDebounceTimer);\n }\n\n this.updateDebounceTimer = window.setTimeout(() => {\n this.links.forEach((link, element) => {\n const rect = element.getBoundingClientRect();\n this.links.set(element, { ...link, rect });\n });\n this.updateDebounceTimer = null;\n }, 100);\n }\n\n private handlePointerMove = (e: PointerEvent): void => {\n this.samples.push({\n x: e.clientX,\n y: e.clientY,\n t: e.timeStamp,\n });\n\n // Keep only last 10 samples for smoothing\n if (this.samples.length > 10) {\n this.samples.shift();\n }\n };\n\n private processSamples(): void {\n if (this.samples.length < 4) return;\n\n const velocity = this.computeVelocity();\n const speed = Math.sqrt(velocity.vx ** 2 + velocity.vy ** 2);\n\n if (speed < this.config.minVelocity) {\n if (this.lastPrediction && this.config.cancelOnDeviation) {\n this.onCancel?.(this.lastPrediction);\n this.lastPrediction = null;\n }\n return;\n }\n\n const target = this.predictTarget(velocity);\n\n if (target && target.href !== this.lastPrediction) {\n // Check cooldown\n const now = Date.now();\n const lastTime = this.cooldownMap.get(target.href) ?? 0;\n const cooldown = 500; // 500ms cooldown per href\n \n if (now - lastTime < cooldown) {\n return; // Still in cooldown\n }\n\n if (this.lastPrediction && this.config.cancelOnDeviation) {\n this.onCancel?.(this.lastPrediction);\n }\n \n this.lastPrediction = target.href;\n this.cooldownMap.set(target.href, now);\n this.onPrediction?.(target.href);\n } else if (!target && this.lastPrediction && this.config.cancelOnDeviation) {\n this.onCancel?.(this.lastPrediction);\n this.lastPrediction = null;\n }\n }\n\n private computeVelocity(): Velocity {\n const recent = this.samples.slice(-4);\n const dt = recent[recent.length - 1]!.t - recent[0]!.t;\n\n if (dt === 0) return { vx: 0, vy: 0 };\n\n const dx = recent[recent.length - 1]!.x - recent[0]!.x;\n const dy = recent[recent.length - 1]!.y - recent[0]!.y;\n\n return {\n vx: dx / dt,\n vy: dy / dt,\n };\n }\n\n private projectRay(velocity: Velocity): { x: number; y: number } {\n const origin = this.samples[this.samples.length - 1]!;\n return {\n x: origin.x + velocity.vx * this.config.lookaheadMs,\n y: origin.y + velocity.vy * this.config.lookaheadMs,\n };\n }\n\n private predictTarget(velocity: Velocity): LinkRect | null {\n const tip = this.projectRay(velocity);\n\n for (const link of this.links.values()) {\n if (this.rectContains(link.rect, tip)) {\n return link;\n }\n }\n\n return null;\n }\n\n private rectContains(rect: DOMRect, point: { x: number; y: number }): boolean {\n return (\n point.x >= rect.left &&\n point.x <= rect.right &&\n point.y >= rect.top &&\n point.y <= rect.bottom\n );\n }\n}\n\nexport function createTrajectoryEngine(\n config?: Partial<TrajectoryConfig>,\n callbacks?: {\n onPrediction?: (href: string) => void;\n onCancel?: (href: string) => void;\n }\n): TrajectoryEngine {\n return new TrajectoryEngine(config, callbacks);\n}\n","import type { CacheConfig, CachedPage, CacheLayer } from \"./types\";\n\nconst DEFAULT_CONFIG: CacheConfig = {\n memory: {\n enabled: true,\n maxPages: 10,\n },\n serviceWorker: {\n enabled: true,\n ttl: 300,\n cacheName: \"specnav-v1\",\n crossTabSync: true,\n broadcastChannel: \"specnav-sync\",\n },\n edge: {\n enabled: true,\n maxAge: 60,\n staleWhileRevalidate: 300,\n },\n exclude: [],\n};\n\nexport class CacheManager {\n private config: CacheConfig;\n private memoryCache: Map<string, CachedPage> = new Map();\n private accessOrder: string[] = [];\n private broadcastChannel?: BroadcastChannel;\n private onCacheHit?: (href: string, layer: CacheLayer) => void;\n\n constructor(\n config: Partial<CacheConfig> = {},\n callbacks?: { onCacheHit?: (href: string, layer: CacheLayer) => void }\n ) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.onCacheHit = callbacks?.onCacheHit;\n\n if (\n this.config.serviceWorker.enabled &&\n this.config.serviceWorker.crossTabSync &&\n typeof BroadcastChannel !== \"undefined\"\n ) {\n this.broadcastChannel = new BroadcastChannel(\n this.config.serviceWorker.broadcastChannel\n );\n this.broadcastChannel.onmessage = this.handleBroadcast;\n }\n }\n\n async get(href: string): Promise<string | null> {\n if (this.isExcluded(href)) return null;\n\n // L1: Memory cache\n const memoryHit = this.getFromMemory(href);\n if (memoryHit) {\n this.onCacheHit?.(href, 1);\n return memoryHit;\n }\n\n // L2: Service Worker cache\n if (this.config.serviceWorker.enabled) {\n const swHit = await this.getFromServiceWorker(href);\n if (swHit) {\n this.onCacheHit?.(href, 2);\n this.setInMemory(href, swHit);\n return swHit;\n }\n }\n\n return null;\n }\n\n async set(href: string, html: string): Promise<void> {\n if (this.isExcluded(href)) return;\n\n // Sanitize href to prevent cache poisoning\n const sanitizedHref = this.sanitizeHref(href);\n if (!sanitizedHref) return;\n\n // Validate HTML doesn't contain dangerous inline scripts\n if (this.containsDangerousContent(html)) {\n console.warn(`Refusing to cache potentially dangerous content from ${sanitizedHref}`);\n return;\n }\n\n const page: CachedPage = {\n href: sanitizedHref,\n html,\n timestamp: Date.now(),\n ttl: this.config.serviceWorker.ttl,\n };\n\n // L1: Memory\n if (this.config.memory.enabled) {\n this.setInMemory(sanitizedHref, html);\n }\n\n // L2: Service Worker\n if (this.config.serviceWorker.enabled) {\n await this.setInServiceWorker(page);\n this.broadcastSet(sanitizedHref);\n }\n }\n\n private containsDangerousContent(html: string): boolean {\n // Check for inline event handlers and javascript: URLs\n const dangerousPatterns = [\n /on\\w+\\s*=\\s*[\"'][^\"']*[\"']/i, // Inline event handlers\n /javascript:/i, // javascript: URLs\n ];\n\n // Check for inline scripts, but exclude safe types\n const scriptRegex = /<script([^>]*)>([\\s\\S]*?)<\\/script>/gi;\n let match;\n while ((match = scriptRegex.exec(html)) !== null) {\n const attrs = match[1] || \"\";\n const content = match[2] || \"\";\n \n // Allow scripts with src attribute\n if (/src\\s*=/.test(attrs)) continue;\n \n // Allow safe script types (JSON data, templates)\n if (/type\\s*=\\s*[\"']?(application\\/json|application\\/ld\\+json|text\\/template)[\"']?/i.test(attrs)) continue;\n \n // Allow Next.js scripts\n if (/id\\s*=\\s*[\"'](__NEXT_DATA__|_R_)[\"']/i.test(attrs)) continue;\n if (/data-nscript\\s*=/i.test(attrs)) continue;\n \n // Allow module scripts (Next.js uses these for hydration)\n if (/type\\s*=\\s*[\"']?module[\"']?/i.test(attrs)) continue;\n \n // Allow Next.js hydration scripts (self.__next_f, self.__next_r)\n if (/self\\.__next_[fr]/.test(content)) continue;\n \n // If we get here, it's an inline script without safe type\n return true;\n }\n\n return dangerousPatterns.some(pattern => pattern.test(html));\n }\n\n private sanitizeHref(href: string): string | null {\n try {\n const url = new URL(href, window.location.origin);\n // Only allow same-origin URLs\n if (url.origin !== window.location.origin) return null;\n return url.pathname + url.search + url.hash;\n } catch {\n return null;\n }\n }\n\n clear(href?: string): void {\n if (href) {\n this.memoryCache.delete(href);\n this.accessOrder = this.accessOrder.filter((h) => h !== href);\n this.clearFromServiceWorker(href);\n } else {\n this.memoryCache.clear();\n this.accessOrder = [];\n this.clearAllServiceWorker();\n }\n }\n\n getSize(): number {\n return this.memoryCache.size;\n }\n\n destroy(): void {\n this.memoryCache.clear();\n this.accessOrder = [];\n this.broadcastChannel?.close();\n }\n\n private getFromMemory(href: string): string | null {\n const page = this.memoryCache.get(href);\n if (!page) return null;\n\n // Update LRU order\n this.accessOrder = this.accessOrder.filter((h) => h !== href);\n this.accessOrder.push(href);\n\n return page.html;\n }\n\n private setInMemory(href: string, html: string): void {\n // Prevent memory exhaustion - limit individual page size\n const maxPageSize = 5 * 1024 * 1024; // 5MB per page\n if (html.length > maxPageSize) {\n console.warn(`Page ${href} exceeds max size, not caching`);\n return;\n }\n\n this.memoryCache.set(href, {\n href,\n html,\n timestamp: Date.now(),\n ttl: this.config.serviceWorker.ttl,\n });\n\n // Deduplicate before adding to accessOrder\n const existingIndex = this.accessOrder.indexOf(href);\n if (existingIndex !== -1) {\n this.accessOrder.splice(existingIndex, 1);\n }\n this.accessOrder.push(href);\n\n // LRU eviction\n if (this.memoryCache.size > this.config.memory.maxPages) {\n const oldest = this.accessOrder.shift();\n if (oldest) this.memoryCache.delete(oldest);\n }\n }\n\n private async getFromServiceWorker(href: string): Promise<string | null> {\n if (typeof caches === \"undefined\") return null;\n\n try {\n const cache = await caches.open(this.config.serviceWorker.cacheName);\n const response = await cache.match(href);\n\n if (!response) return null;\n\n const data = await response.json();\n const page = data as CachedPage;\n\n // Check TTL\n const age = Date.now() - page.timestamp;\n if (age > page.ttl * 1000) {\n await cache.delete(href);\n return null;\n }\n\n return page.html;\n } catch {\n return null;\n }\n }\n\n private async setInServiceWorker(page: CachedPage): Promise<void> {\n if (typeof caches === \"undefined\") return;\n\n try {\n const cache = await caches.open(this.config.serviceWorker.cacheName);\n const response = new Response(JSON.stringify(page), {\n headers: {\n \"Content-Type\": \"application/json\",\n \"Cache-Control\": `max-age=${this.config.edge.maxAge}, stale-while-revalidate=${this.config.edge.staleWhileRevalidate}`,\n },\n });\n await cache.put(page.href, response);\n } catch {\n // Silently fail\n }\n }\n\n private async clearFromServiceWorker(href: string): Promise<void> {\n if (typeof caches === \"undefined\") return;\n\n try {\n const cache = await caches.open(this.config.serviceWorker.cacheName);\n await cache.delete(href);\n } catch {\n // Silently fail\n }\n }\n\n private async clearAllServiceWorker(): Promise<void> {\n if (typeof caches === \"undefined\") return;\n\n try {\n await caches.delete(this.config.serviceWorker.cacheName);\n } catch {\n // Silently fail\n }\n }\n\n private isExcluded(href: string): boolean {\n return this.config.exclude.some((pattern) => {\n if (typeof pattern === \"string\") {\n return pattern.includes(\"*\")\n ? new RegExp(pattern.replace(/\\*/g, \".*\")).test(href)\n : href === pattern;\n }\n return pattern.test(href);\n });\n }\n\n private broadcastSet(href: string): void {\n this.broadcastChannel?.postMessage({ type: \"set\", href });\n }\n\n private handleBroadcast = (event: MessageEvent): void => {\n if (event.data.type === \"set\") {\n // Invalidate memory cache to force fetch from SW\n this.memoryCache.delete(event.data.href);\n }\n };\n}\n\nexport function createCacheManager(\n config?: Partial<CacheConfig>,\n callbacks?: { onCacheHit?: (href: string, layer: CacheLayer) => void }\n): CacheManager {\n return new CacheManager(config, callbacks);\n}\n","type NodeFingerprint = string;\n\nfunction fnv1a(str: string): string {\n let hash = 0x811c9dc5;\n for (let i = 0; i < str.length; i++) {\n hash ^= str.charCodeAt(i);\n hash = (hash * 0x01000193) >>> 0;\n }\n return hash.toString(36);\n}\n\nfunction fingerprintNode(node: Element): NodeFingerprint {\n const tag = node.tagName.toLowerCase();\n const attrs = Array.from(node.attributes)\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((a) => `${a.name}=${a.value}`)\n .join(\"|\");\n const text = node.childNodes.length === 0 ? node.textContent ?? \"\" : \"\";\n const childHashes = Array.from(node.children).map(fingerprintNode).join(\",\");\n\n return fnv1a(`${tag}[${attrs}]{${text}}(${childHashes})`);\n}\n\nconst FINGERPRINT_KEY = \"__specnav_fp__\";\n\nexport function stampFingerprints(root: Element): void {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);\n let node = walker.currentNode as Element;\n while (node) {\n (node as any)[FINGERPRINT_KEY] = fingerprintNode(node);\n node = walker.nextNode() as Element;\n }\n}\n\nexport function fingerprintMatches(current: Element, incoming: Element): boolean {\n const currentFp = (current as any)[FINGERPRINT_KEY];\n if (!currentFp) return false;\n return currentFp === fingerprintNode(incoming);\n}\n\nexport { FINGERPRINT_KEY };\n","function fnv1a(str: string): string {\n let hash = 0x811c9dc5;\n for (let i = 0; i < str.length; i++) {\n hash ^= str.charCodeAt(i);\n hash = (hash * 0x01000193) >>> 0;\n }\n return hash.toString(36);\n}\n\ninterface IdentityVector {\n tagName: string;\n id: string | null;\n key: string | null;\n classSignature: string;\n attrSignature: string;\n textFingerprint: string | null;\n childCount: number;\n childTagSequence: string;\n domPosition: number;\n role: string | null;\n}\n\nexport function buildIdentityVector(node: Element, depth = 0): IdentityVector {\n const classes = Array.from(node.classList).sort().join(\" \");\n const volatileAttrs = new Set([\"style\", \"class\", \"aria-expanded\", \"aria-selected\"]);\n const stableAttrs = Array.from(node.attributes)\n .filter((a) => !volatileAttrs.has(a.name) && a.name !== \"id\")\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((a) => `${a.name}=${a.value}`)\n .join(\"|\");\n\n return {\n tagName: node.tagName.toLowerCase(),\n id: node.id || null,\n key: node.getAttribute(\"data-key\"),\n classSignature: fnv1a(classes),\n attrSignature: fnv1a(stableAttrs),\n textFingerprint:\n node.children.length === 0 ? (node.textContent ?? \"\").slice(0, 64) : null,\n childCount: node.childElementCount,\n childTagSequence: Array.from(node.children)\n .slice(0, 5)\n .map((c) => c.tagName.toLowerCase())\n .join(\">\"),\n domPosition: Array.from(node.parentElement?.children ?? []).indexOf(node),\n role: node.getAttribute(\"role\"),\n };\n}\n\nexport function identityScore(a: IdentityVector, b: IdentityVector): number {\n if (a.tagName !== b.tagName) return 0;\n\n let score = 0;\n let totalWeight = 0;\n\n const checks: Array<[unknown, unknown, number]> = [\n [a.id, b.id, 40],\n [a.key, b.key, 35],\n [a.classSignature, b.classSignature, 15],\n [a.attrSignature, b.attrSignature, 20],\n [a.textFingerprint, b.textFingerprint, 15],\n [a.childCount, b.childCount, 10],\n [a.childTagSequence, b.childTagSequence, 15],\n [a.domPosition, b.domPosition, 5],\n [a.role, b.role, 10],\n ];\n\n for (const [av, bv, weight] of checks) {\n if (av !== null && bv !== null) {\n totalWeight += weight;\n if (av === bv) score += weight;\n }\n }\n\n return totalWeight === 0 ? 0 : score / totalWeight;\n}\n","import { buildIdentityVector, identityScore } from \"./identity\";\n\nexport function matchSiblings(\n currentChildren: Element[],\n incomingChildren: Element[]\n): Map<Element, Element | null> {\n const n = currentChildren.length;\n const m = incomingChildren.length;\n const THRESHOLD = 0.4;\n\n const scores: number[][] = Array.from({ length: n }, (_, i) =>\n Array.from({ length: m }, (_, j) =>\n identityScore(\n buildIdentityVector(currentChildren[i]!),\n buildIdentityVector(incomingChildren[j]!)\n )\n )\n );\n\n const matched = new Map<Element, Element | null>();\n const usedIncoming = new Set<number>();\n\n const order = currentChildren\n .map((_, i) => i)\n .sort((a, b) => {\n const bestA = Math.max(...(scores[a] ?? [0]));\n const bestB = Math.max(...(scores[b] ?? [0]));\n return bestB - bestA;\n });\n\n for (const i of order) {\n const row = scores[i]!;\n let bestJ = -1;\n let bestScore = THRESHOLD;\n\n for (let j = 0; j < m; j++) {\n if (!usedIncoming.has(j) && (row[j] ?? 0) > bestScore) {\n bestScore = row[j]!;\n bestJ = j;\n }\n }\n\n if (bestJ >= 0) {\n matched.set(currentChildren[i]!, incomingChildren[bestJ]!);\n usedIncoming.add(bestJ);\n } else {\n matched.set(currentChildren[i]!, null);\n }\n }\n\n return matched;\n}\n","import type { MorphConfig } from \"./types\";\nimport { stampFingerprints, fingerprintMatches } from \"./morpher/fingerprint\";\nimport { matchSiblings } from \"./morpher/matcher\";\n\nconst DEFAULT_CONFIG: MorphConfig = {\n preserveScroll: true,\n preserveFocus: true,\n};\n\ninterface MorphContext {\n config: MorphConfig;\n focusedElement: Element | null;\n scrollPositions: Map<Element, { top: number; left: number }>;\n}\n\nexport class DOMmorpher {\n private config: MorphConfig;\n\n constructor(config: Partial<MorphConfig> = {}) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n morph(from: Element, to: Element): void {\n const ctx = this.createContext();\n \n // Stamp fingerprints on first use\n if (!(from as any).__specnav_fp__) {\n stampFingerprints(from);\n }\n \n requestAnimationFrame(() => {\n this.morphElement(from, to, ctx);\n this.restoreContext(ctx);\n });\n }\n\n private createContext(): MorphContext {\n const ctx: MorphContext = {\n config: this.config,\n focusedElement: null,\n scrollPositions: new Map(),\n };\n\n if (this.config.preserveFocus) {\n ctx.focusedElement = document.activeElement;\n }\n\n if (this.config.preserveScroll) {\n this.captureScrollPositions(document.body, ctx.scrollPositions);\n }\n\n return ctx;\n }\n\n private restoreContext(ctx: MorphContext): void {\n if (ctx.config.preserveFocus && ctx.focusedElement) {\n const element = ctx.focusedElement as HTMLElement;\n if (element.focus && document.body.contains(element)) {\n element.focus();\n }\n }\n\n if (ctx.config.preserveScroll) {\n ctx.scrollPositions.forEach((pos, element) => {\n element.scrollTop = pos.top;\n element.scrollLeft = pos.left;\n });\n }\n }\n\n private captureScrollPositions(\n element: Element,\n positions: Map<Element, { top: number; left: number }>\n ): void {\n if (element.scrollTop > 0 || element.scrollLeft > 0) {\n positions.set(element, {\n top: element.scrollTop,\n left: element.scrollLeft,\n });\n }\n\n Array.from(element.children).forEach((child) => {\n this.captureScrollPositions(child, positions);\n });\n }\n\n private morphElement(from: Element, to: Element, ctx: MorphContext): void {\n // O(1) fingerprint check - skip entire subtree if unchanged\n if (fingerprintMatches(from, to)) {\n return;\n }\n\n // Sync attributes\n this.syncAttributes(from, to);\n\n // Morph children using semantic matching\n this.morphChildren(from, to, ctx);\n }\n\n private syncAttributes(from: Element, to: Element): void {\n const fromAttrs = from.attributes;\n const toAttrs = to.attributes;\n\n for (let i = fromAttrs.length - 1; i >= 0; i--) {\n const attr = fromAttrs[i]!;\n if (!to.hasAttribute(attr.name)) {\n from.removeAttribute(attr.name);\n }\n }\n\n for (let i = 0; i < toAttrs.length; i++) {\n const attr = toAttrs[i]!;\n if (from.getAttribute(attr.name) !== attr.value) {\n from.setAttribute(attr.name, attr.value);\n }\n }\n }\n\n private morphChildren(from: Element, to: Element, ctx: MorphContext): void {\n const fromChildren = Array.from(from.children);\n const toChildren = Array.from(to.children);\n\n // Handle text-only nodes\n if (fromChildren.length === 0 && toChildren.length === 0) {\n if (from.textContent !== to.textContent) {\n from.textContent = to.textContent;\n }\n return;\n }\n\n // Use semantic matching instead of positional\n const matchMap = matchSiblings(fromChildren, toChildren);\n\n // Process matched pairs\n const processedIncoming = new Set<Element>();\n \n for (const [currentChild, incomingChild] of matchMap) {\n if (!incomingChild) {\n // Remove unmatched current node\n from.removeChild(currentChild);\n } else {\n // Recurse into matched pair\n this.morphElement(currentChild, incomingChild, ctx);\n processedIncoming.add(incomingChild);\n }\n }\n\n // Insert new incoming nodes that had no match\n for (let j = 0; j < toChildren.length; j++) {\n const incomingChild = toChildren[j]!;\n if (!processedIncoming.has(incomingChild)) {\n const cloned = incomingChild.cloneNode(true) as Element;\n const refNode = from.children[j] || null;\n from.insertBefore(cloned, refNode);\n }\n }\n }\n}\n\nexport function createMorpher(config?: Partial<MorphConfig>): DOMmorpher {\n return new DOMmorpher(config);\n}\n\nexport function morph(\n from: Element,\n to: Element,\n config?: Partial<MorphConfig>\n): void {\n const morpher = createMorpher(config);\n morpher.morph(from, to);\n}\n","interface SpeculatedPage {\n href: string;\n html: string;\n container: HTMLElement;\n timestamp: number;\n}\n\n/**\n * SpeculativeRenderer pre-renders pages in detached DOM containers.\n * \n * LIMITATIONS:\n * - This implementation uses innerHTML, NOT React rendering. The speculated content\n * is raw HTML set on a disconnected DOM node, not a fully rendered React component tree.\n * - For true React speculative rendering, the container must be appended to the document\n * (hidden via CSS) and ReactDOM.createRoot(container).render(...) must be called.\n * - Current implementation is suitable for static HTML morphing but may produce different\n * results than a real React render for dynamic components.\n */\nexport class SpeculativeRenderer {\n private speculations: Map<string, SpeculatedPage> = new Map();\n private maxSpeculations: number;\n\n constructor(maxSpeculations = 3) {\n this.maxSpeculations = maxSpeculations;\n }\n\n async speculate(href: string, html: string): Promise<void> {\n if (this.speculations.has(href)) return;\n\n // Evict oldest if at capacity\n if (this.speculations.size >= this.maxSpeculations) {\n const oldest = Array.from(this.speculations.values()).sort(\n (a, b) => a.timestamp - b.timestamp\n )[0];\n if (oldest) this.cancel(oldest.href);\n }\n\n const container = this.createDetachedContainer();\n container.innerHTML = html;\n\n this.speculations.set(href, {\n href,\n html,\n container,\n timestamp: Date.now(),\n });\n }\n\n get(href: string): HTMLElement | null {\n const speculation = this.speculations.get(href);\n return speculation?.container ?? null;\n }\n\n cancel(href: string): void {\n const speculation = this.speculations.get(href);\n if (speculation) {\n speculation.container.remove();\n this.speculations.delete(href);\n }\n }\n\n cancelAll(): void {\n this.speculations.forEach((spec) => spec.container.remove());\n this.speculations.clear();\n }\n\n has(href: string): boolean {\n return this.speculations.has(href);\n }\n\n private createDetachedContainer(): HTMLElement {\n const container = document.createElement(\"div\");\n container.style.display = \"none\";\n container.setAttribute(\"data-specnav-speculation\", \"true\");\n return container;\n }\n}\n\nexport function createSpeculativeRenderer(\n maxSpeculations?: number\n): SpeculativeRenderer {\n return new SpeculativeRenderer(maxSpeculations);\n}\n","import type { GraphConfig, NavigationGraph } from \"./types\";\n\nconst DEFAULT_CONFIG: GraphConfig = {\n enabled: true,\n minConfidence: 0.6,\n sessionWeight: 0.7,\n storageKey: \"specnav-graph\",\n maxNodes: 50,\n};\n\nexport class NavigationGraphLearner {\n private config: GraphConfig;\n private graph: NavigationGraph = {};\n private sessionGraph: NavigationGraph = {};\n\n constructor(config: Partial<GraphConfig> = {}) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n if (this.config.enabled) {\n this.loadGraph();\n }\n }\n\n recordNavigation(fromHref: string, toHref: string): void {\n if (!this.config.enabled) return;\n\n // Update session graph\n if (!this.sessionGraph[fromHref]) {\n this.sessionGraph[fromHref] = {};\n }\n const current = this.sessionGraph[fromHref]![toHref] ?? 0;\n this.sessionGraph[fromHref]![toHref] = current + 1;\n\n // Update persistent graph\n if (!this.graph[fromHref]) {\n this.graph[fromHref] = {};\n }\n const persistentCurrent = this.graph[fromHref]![toHref] ?? 0;\n this.graph[fromHref]![toHref] = persistentCurrent + 1;\n\n this.saveGraph();\n }\n\n getPredictions(fromHref: string): string[] {\n if (!this.config.enabled) return [];\n\n const sessionEdges = this.sessionGraph[fromHref] ?? {};\n const persistentEdges = this.graph[fromHref] ?? {};\n\n // Merge session and persistent with weighting\n const merged: Record<string, number> = {};\n\n Object.entries(persistentEdges).forEach(([href, count]) => {\n merged[href] = count * (1 - this.config.sessionWeight);\n });\n\n Object.entries(sessionEdges).forEach(([href, count]) => {\n merged[href] = (merged[href] ?? 0) + count * this.config.sessionWeight;\n });\n\n // Calculate total for normalization\n const total = Object.values(merged).reduce((sum, val) => sum + val, 0);\n if (total === 0) return [];\n\n // Convert to confidence scores and filter\n const predictions = Object.entries(merged)\n .map(([href, count]) => ({\n href,\n confidence: count / total,\n }))\n .filter((p) => p.confidence >= this.config.minConfidence)\n .sort((a, b) => b.confidence - a.confidence)\n .map((p) => p.href);\n\n return predictions;\n }\n\n getGraph(): NavigationGraph {\n return { ...this.graph };\n }\n\n clearGraph(): void {\n this.graph = {};\n this.sessionGraph = {};\n this.saveGraph();\n }\n\n private loadGraph(): void {\n if (typeof localStorage === \"undefined\") return;\n\n try {\n const stored = localStorage.getItem(this.config.storageKey);\n if (stored) {\n this.graph = JSON.parse(stored);\n this.pruneGraph();\n }\n } catch {\n // Silently fail\n }\n }\n\n private saveGraph(): void {\n if (typeof localStorage === \"undefined\") return;\n\n try {\n this.pruneGraph();\n const serialized = JSON.stringify(this.graph);\n \n // Check size before saving (localStorage typically has 5-10MB limit)\n if (serialized.length > 4 * 1024 * 1024) { // 4MB safety limit\n console.warn(\"Navigation graph too large, pruning more aggressively\");\n // Prune to half the max nodes (use local variable)\n const reducedMaxNodes = Math.floor(this.config.maxNodes / 2);\n const originalMaxNodes = this.config.maxNodes;\n this.config.maxNodes = reducedMaxNodes;\n this.pruneGraph();\n this.config.maxNodes = originalMaxNodes; // Restore original\n }\n \n localStorage.setItem(this.config.storageKey, JSON.stringify(this.graph));\n } catch (error) {\n // Handle quota exceeded error\n if (error instanceof Error && error.name === \"QuotaExceededError\") {\n console.warn(\"localStorage quota exceeded, clearing navigation graph\");\n this.clearGraph();\n }\n }\n }\n\n private pruneGraph(): void {\n const nodes = Object.keys(this.graph);\n if (nodes.length <= this.config.maxNodes) return;\n\n // Calculate total transitions per node\n const nodeCounts = nodes.map((node) => ({\n node,\n count: Object.values(this.graph[node]!).reduce(\n (sum, val) => sum + val,\n 0\n ),\n }));\n\n // Sort by count and keep top maxNodes\n nodeCounts.sort((a, b) => b.count - a.count);\n const toKeep = new Set(\n nodeCounts.slice(0, this.config.maxNodes).map((n) => n.node)\n );\n\n // Remove nodes not in top set\n Object.keys(this.graph).forEach((node) => {\n if (!toKeep.has(node)) {\n delete this.graph[node];\n }\n });\n }\n}\n\nexport function createNavigationGraphLearner(\n config?: Partial<GraphConfig>\n): NavigationGraphLearner {\n return new NavigationGraphLearner(config);\n}\n\nexport function getNavigationGraph(\n storageKey = \"specnav-graph\"\n): NavigationGraph {\n if (typeof localStorage === \"undefined\") return {};\n\n try {\n const stored = localStorage.getItem(storageKey);\n return stored ? JSON.parse(stored) : {};\n } catch {\n return {};\n }\n}\n","import type { AdaptiveConfig, Strategy } from \"./types\";\n\nconst DEFAULT_CONFIG: AdaptiveConfig = {\n batteryThreshold: 0.2,\n connectionTypes: {\n slow: [\"2g\", \"3g\", \"slow-2g\"],\n fast: [\"4g\"],\n },\n respectSaveData: true,\n respectReducedMotion: true,\n};\n\nexport class AdaptiveMode {\n private config: AdaptiveConfig;\n private battery: any = null;\n private connection: any = null;\n private initPromise: Promise<void>;\n\n constructor(config: Partial<AdaptiveConfig> = {}) {\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.initPromise = this.initialize();\n }\n\n async waitForInit(): Promise<void> {\n await this.initPromise;\n }\n\n private async initialize(): Promise<void> {\n if (typeof navigator === \"undefined\") return;\n\n // Battery API\n if (\"getBattery\" in navigator) {\n try {\n this.battery = await (navigator as any).getBattery();\n } catch {\n // Not available\n }\n }\n\n // Network Information API\n if (\"connection\" in navigator || \"mozConnection\" in navigator || \"webkitConnection\" in navigator) {\n this.connection =\n (navigator as any).connection ||\n (navigator as any).mozConnection ||\n (navigator as any).webkitConnection;\n }\n }\n\n getStrategy(baseStrategy: Strategy): Strategy {\n if (baseStrategy === \"off\") return \"off\";\n if (baseStrategy !== \"auto\") return baseStrategy;\n\n // Check Save-Data\n if (this.config.respectSaveData && this.hasSaveData()) {\n return \"off\";\n }\n\n // Check battery\n if (this.isLowBattery()) {\n return \"conservative\";\n }\n\n // Check connection\n if (this.isSlowConnection()) {\n return \"conservative\";\n }\n\n return \"aggressive\";\n }\n\n shouldPrefetch(): boolean {\n if (this.config.respectSaveData && this.hasSaveData()) {\n return false;\n }\n\n if (this.isLowBattery()) {\n return false;\n }\n\n return true;\n }\n\n shouldSpeculate(): boolean {\n if (!this.shouldPrefetch()) {\n return false;\n }\n\n if (this.isSlowConnection()) {\n return false;\n }\n\n return true;\n }\n\n shouldUseTransitions(): boolean {\n if (!this.config.respectReducedMotion) return true;\n\n if (typeof window === \"undefined\") return true;\n\n return !window.matchMedia(\"(prefers-reduced-motion: reduce)\").matches;\n }\n\n private hasSaveData(): boolean {\n if (typeof navigator === \"undefined\") return false;\n\n return (\n (navigator as any).connection?.saveData === true ||\n (navigator as any).mozConnection?.saveData === true ||\n (navigator as any).webkitConnection?.saveData === true\n );\n }\n\n private isLowBattery(): boolean {\n if (!this.battery) return false;\n\n return (\n !this.battery.charging &&\n this.battery.level < this.config.batteryThreshold\n );\n }\n\n private isSlowConnection(): boolean {\n if (!this.connection) return false;\n\n const effectiveType = this.connection.effectiveType;\n if (!effectiveType) return false;\n\n return this.config.connectionTypes.slow.includes(effectiveType);\n }\n\n isFastConnection(): boolean {\n if (!this.connection) return true; // Assume fast if unknown\n\n const effectiveType = this.connection.effectiveType;\n if (!effectiveType) return true;\n\n return this.config.connectionTypes.fast.includes(effectiveType);\n }\n\n getBatteryLevel(): number | null {\n return this.battery?.level ?? null;\n }\n\n getConnectionType(): string | null {\n return this.connection?.effectiveType ?? null;\n }\n}\n\nexport function createAdaptiveMode(\n config?: Partial<AdaptiveConfig>\n): AdaptiveMode {\n return new AdaptiveMode(config);\n}\n","// Performance monitoring utilities\n\nexport interface PerformanceMetrics {\n navigationTime: number;\n cacheHit: boolean;\n cacheLayer?: 1 | 2 | 3;\n speculativeHit: boolean;\n fetchTime?: number;\n morphTime?: number;\n}\n\nexport class PerformanceMonitor {\n private metrics: PerformanceMetrics[] = [];\n private maxMetrics = 100;\n\n recordNavigation(metrics: PerformanceMetrics): void {\n this.metrics.push(metrics);\n \n // Keep only last N metrics\n if (this.metrics.length > this.maxMetrics) {\n this.metrics.shift();\n }\n }\n\n getAverageNavigationTime(): number {\n if (this.metrics.length === 0) return 0;\n const sum = this.metrics.reduce((acc, m) => acc + m.navigationTime, 0);\n return sum / this.metrics.length;\n }\n\n getCacheHitRate(): number {\n if (this.metrics.length === 0) return 0;\n const hits = this.metrics.filter(m => m.cacheHit).length;\n return hits / this.metrics.length;\n }\n\n getSpeculativeHitRate(): number {\n if (this.metrics.length === 0) return 0;\n const hits = this.metrics.filter(m => m.speculativeHit).length;\n return hits / this.metrics.length;\n }\n\n getMetrics(): PerformanceMetrics[] {\n return [...this.metrics];\n }\n\n clear(): void {\n this.metrics = [];\n }\n}\n\nexport const performanceMonitor = new PerformanceMonitor();\n"]}
|
package/dist/morpher.d.cts
CHANGED
|
@@ -4,15 +4,12 @@ declare class DOMmorpher {
|
|
|
4
4
|
private config;
|
|
5
5
|
constructor(config?: Partial<MorphConfig>);
|
|
6
6
|
morph(from: Element, to: Element): void;
|
|
7
|
-
private executeScripts;
|
|
8
7
|
private createContext;
|
|
9
8
|
private restoreContext;
|
|
10
9
|
private captureScrollPositions;
|
|
11
10
|
private morphElement;
|
|
12
11
|
private syncAttributes;
|
|
13
12
|
private morphChildren;
|
|
14
|
-
private nodesMatch;
|
|
15
|
-
private findMatchingNode;
|
|
16
13
|
}
|
|
17
14
|
declare function createMorpher(config?: Partial<MorphConfig>): DOMmorpher;
|
|
18
15
|
declare function morph(from: Element, to: Element, config?: Partial<MorphConfig>): void;
|
package/dist/morpher.d.ts
CHANGED
|
@@ -4,15 +4,12 @@ declare class DOMmorpher {
|
|
|
4
4
|
private config;
|
|
5
5
|
constructor(config?: Partial<MorphConfig>);
|
|
6
6
|
morph(from: Element, to: Element): void;
|
|
7
|
-
private executeScripts;
|
|
8
7
|
private createContext;
|
|
9
8
|
private restoreContext;
|
|
10
9
|
private captureScrollPositions;
|
|
11
10
|
private morphElement;
|
|
12
11
|
private syncAttributes;
|
|
13
12
|
private morphChildren;
|
|
14
|
-
private nodesMatch;
|
|
15
|
-
private findMatchingNode;
|
|
16
13
|
}
|
|
17
14
|
declare function createMorpher(config?: Partial<MorphConfig>): DOMmorpher;
|
|
18
15
|
declare function morph(from: Element, to: Element, config?: Partial<MorphConfig>): void;
|