ThatAIguyA world of ideas

THE CONSCIOUSNESS ATLAS
Read. Experiment. Follow the evidence.

ConsciousnessLearn · Explore · Joseph Anady

Janady13/feedthejoe / src/adapters/observer.js

Source identity, revision, and recovered contents.

GitHub sourceSource text recovered

Source identity

FieldRecorded value
Source typeGitHub source
Original recordJanady13/feedthejoe / src/adapters/observer.js
DateNot specified in source
RepositoryJanady13/feedthejoe
Revision0e608a2b515a959bf35d2783428766624400ca3c
Branchmain
Path or archive membersrc/adapters/observer.js
Original SHA-256e6d2bb43ccad68b61dfde1204cb04759a305e7bdffefccb2cff0b4593dff283a
Git blob SHA58d92458f465b0446606ad666efe50e3245fa196
Reading-copy SHA-256e6d2bb43ccad68b61dfde1204cb04759a305e7bdffefccb2cff0b4593dff283a

Original source ↗

Recovered source transcript

/** * Signal capture: turn browsing behaviour into normalised events. * * This is the only file that knows what a scroll or a viewport is. The core * receives {kind, itemId, completion} and nothing else, which is why the ranker * can be tested without a DOM. * * The hard part is honesty. It is easy to build a capture layer that flatters * the model — count every card that crossed the viewport as a "read" and the * feed will look brilliantly engaging while learning nothing. Three rules keep * it truthful: * * 1. Dwell only accrues while the tab is actually foregrounded. A page left * open overnight must not register as the most compelling thing on the site. * 2. Dwell is measured against estimated read time, so a long item cannot win * simply by being long. * 3. Passing through fast is recorded as a SKIP, not as nothing. A model that * can only learn from positives drifts toward whatever it showed first. */ import { Signal, completionRatio } from '../core/signal/signals.js'; /** A card must be this visible before its dwell clock starts. */ const VISIBLE_RATIO = 0.55; /** Below this dwell, leaving the viewport counts as a skip rather than a read. */ const SKIP_SECONDS = 1.1; /** Above this completion ratio we call it a read. */ const READ_RATIO = 0.45; /** * @param {object} opts * @param {HTMLElement} opts.root Container holding the cards. * @param {Map<string, object>} opts.index itemId -> item (for wordCount). * @param {(e: import('../ports/types.js').SignalEvent) => void} opts.onSignal * @returns {{observe: (el: Element) => void, disconnect: () => void}} */ export function createObserver({ root, index, onSignal }) { /** @type {Map<string, {enteredAt: number, dwell: number, seen: boolean}>} */ const tracked = new Map(); let foregrounded = document.visibilityState === 'visible'; const stateFor = (id) => { let s = tracked.get(id); if (!s) { s = { enteredAt: 0, dwell: 0, seen: false }; tracked.set(id, s); } return s; }; /** Stop the clock on a card and emit whatever that dwell earned. */ function settle(id) { const s = tracked.get(id); if (!s || s.enteredAt === 0) return; s.dwell += (performance.now() - s.enteredAt) / 1000; s.enteredAt = 0; const item = index.get(id); if (!item) return; if (s.dwell < SKIP_SECONDS) { onSignal({ kind: Signal.SKIP, itemId: id }); return; } const ratio = completionRatio(s.dwell, item.wordCount); if (ratio >= READ_RATIO) { // A return visit to something already read is the stronger signal. onSignal(s.seen ? { kind: Signal.REWATCH, itemId: id } : { kind: Signal.COMPLETION, itemId: id, completion: ratio }); s.seen = true; } s.dwell = 0; } const io = new IntersectionObserver((entries) => { for (const entry of entries) { const id = entry.target.dataset.itemId; if (!id) continue; if (entry.isIntersecting && entry.intersectionRatio >= VISIBLE_RATIO) { if (foregrounded) stateFor(id).enteredAt = performance.now(); } else { settle(id); } } }, { threshold: [0, VISIBLE_RATIO, 1] }); // Rule 1: the clock stops with the tab. Without this, "left the laptop open" // becomes the strongest engagement signal on the site. function onVisibility() { foregrounded = document.visibilityState === 'visible'; if (!foregrounded) { for (const [id, s] of tracked) { if (s.enteredAt !== 0) { s.dwell += (performance.now() - s.enteredAt) / 1000; s.enteredAt = 0; } } } else { for (const el of root.querySelectorAll('[data-item-id]')) { const r = el.getBoundingClientRect(); const vis = r.top < innerHeight * 0.6 && r.bottom > innerHeight * 0.4; if (vis) stateFor(el.dataset.itemId).enteredAt = performance.now(); } } } document.addEventListener('visibilitychange', onVisibility); // Copying a link is an intent to show someone else — the closest honest // analogue to a share on a surface with no share button. function onCopy() { const sel = document.getSelection(); if (!sel || sel.isCollapsed) return; const node = sel.anchorNode instanceof Element ? sel.anchorNode : sel.anchorNode?.parentElement; const card = node?.closest?.('[data-item-id]'); if (card?.dataset.itemId) onSignal({ kind: Signal.SHARE, itemId: card.dataset.itemId }); } document.addEventListener('copy', onCopy); function onClick(ev) { const card = ev.target instanceof Element ? ev.target.closest('[data-item-id]') : null; if (!card) return; if (ev.target.closest('a[href]')) onSignal({ kind: Signal.EXPAND, itemId: card.dataset.itemId }); } root.addEventListener('click', onClick); // A departing visitor's last card never fires an intersection change, so its // dwell would be lost. pagehide is the reliable terminal event (unload is not, // and it breaks bfcache). const onPageHide = () => { for (const id of tracked.keys()) settle(id); }; addEventListener('pagehide', onPageHide); return { observe(el) { io.observe(el); }, disconnect() { io.disconnect(); document.removeEventListener('visibilitychange', onVisibility); document.removeEventListener('copy', onCopy); root.removeEventListener('click', onClick); removeEventListener('pagehide', onPageHide); }, }; }

Search equations, builds, manuscript text, and recovered sources.