reduce indirection

pull/16748/head
Rich Harris 4 days ago
parent a2860bbd9f
commit 429591b1f9

@ -94,7 +94,7 @@ function close(head, body, payload) {
cleanup(); cleanup();
} }
head += payload.global.head.get_title(); head += payload.global.get_title();
body = BLOCK_OPEN + body + BLOCK_CLOSE; // this inserts a fake boundary so hydration matches body = BLOCK_OPEN + body + BLOCK_CLOSE; // this inserts a fake boundary so hydration matches
@ -698,7 +698,7 @@ export function build_title(payload, children) {
payload.compact({ payload.compact({
start: i, start: i,
fn: ({ head }) => { fn: ({ head }) => {
payload.global.head.set_title(head, path); payload.global.set_title(head, path);
// since we can only ever render the title in this chunk, and title rendering is handled specially, // since we can only ever render the title in this chunk, and title rendering is handled specially,
// we can just ditch the results after we've saved them globally // we can just ditch the results after we've saved them globally
return { head: '', body: '' }; return { head: '', body: '' };

@ -368,28 +368,22 @@ export class TreeState {
/** @readonly @type {() => string} */ /** @readonly @type {() => string} */
uid; uid;
/** @readonly @type {TreeHeadState} */
head;
/** @readonly @type {Set<{ hash: string; code: string }>} */ /** @readonly @type {Set<{ hash: string; code: string }>} */
css = new Set(); css = new Set();
/** @type {{ path: number[], value: string }} */
#title = { path: [], value: '' };
/** /**
* @param {'sync' | 'async'} mode * @param {'sync' | 'async'} mode
* @param {string} [id_prefix] * @param {string} [id_prefix]
*/ */
constructor(mode, id_prefix = '') { constructor(mode, id_prefix = '') {
this.mode = mode; this.mode = mode;
this.uid = props_id_generator(id_prefix);
this.head = new TreeHeadState();
}
}
export class TreeHeadState { let uid = 1;
/** this.uid = () => `${id_prefix}s${uid++}`;
* @type {{ path: number[], value: string }} }
*/
#title = { path: [], value: '' };
get_title() { get_title() {
return this.#title.value; return this.#title.value;
@ -421,13 +415,3 @@ export class TreeHeadState {
} }
} }
} }
/**
* Creates an ID generator
* @param {string} prefix
* @returns {() => string}
*/
function props_id_generator(prefix) {
let uid = 1;
return () => `${prefix}s${uid++}`;
}

@ -1,5 +1,5 @@
import { assert, expect, test } from 'vitest'; import { assert, expect, test } from 'vitest';
import { Payload, TreeState, TreeHeadState } from './payload.js'; import { Payload, TreeState } from './payload.js';
test('collects synchronous body content by default', () => { test('collects synchronous body content by default', () => {
const payload = new Payload(new TreeState('sync')); const payload = new Payload(new TreeState('sync'));
@ -170,7 +170,7 @@ test('subsume replaces tree content and state from other', () => {
$$payload.push('body'); $$payload.push('body');
}); });
b.global.css.add({ hash: 'h', code: 'c' }); b.global.css.add({ hash: 'h', code: 'c' });
b.global.head.set_title('Title', [1]); b.global.set_title('Title', [1]);
b.local.select_value = 'B'; b.local.select_value = 'B';
b.promises.initial = Promise.resolve(); b.promises.initial = Promise.resolve();
@ -192,7 +192,7 @@ test('subsume refuses to switch modes', () => {
$$payload.push('body'); $$payload.push('body');
}); });
b.global.css.add({ hash: 'h', code: 'c' }); b.global.css.add({ hash: 'h', code: 'c' });
b.global.head.set_title('Title', [1]); b.global.set_title('Title', [1]);
b.local.select_value = 'B'; b.local.select_value = 'B';
b.promises.initial = Promise.resolve(); b.promises.initial = Promise.resolve();
@ -206,31 +206,31 @@ test('TreeState uid generator uses prefix', () => {
assert.equal(state.uid(), 'id-s1'); assert.equal(state.uid(), 'id-s1');
}); });
test('TreeHeadState title ordering favors later lexicographic paths', () => { test('TreeState title ordering favors later lexicographic paths', () => {
const head = new TreeHeadState(() => ''); const state = new TreeState('sync');
head.set_title('A', [1]); state.set_title('A', [1]);
assert.equal(head.get_title(), 'A'); assert.equal(state.get_title(), 'A');
// equal path -> unchanged // equal path -> unchanged
head.set_title('B', [1]); state.set_title('B', [1]);
assert.equal(head.get_title(), 'A'); assert.equal(state.get_title(), 'A');
// earlier -> unchanged // earlier -> unchanged
head.set_title('C', [0, 9]); state.set_title('C', [0, 9]);
assert.equal(head.get_title(), 'A'); assert.equal(state.get_title(), 'A');
// later -> update // later -> update
head.set_title('D', [2]); state.set_title('D', [2]);
assert.equal(head.get_title(), 'D'); assert.equal(state.get_title(), 'D');
// longer but same prefix -> update // longer but same prefix -> update
head.set_title('E', [2, 0]); state.set_title('E', [2, 0]);
assert.equal(head.get_title(), 'E'); assert.equal(state.get_title(), 'E');
// shorter (earlier) than current with same prefix -> unchanged // shorter (earlier) than current with same prefix -> unchanged
head.set_title('F', [2]); state.set_title('F', [2]);
assert.equal(head.get_title(), 'E'); assert.equal(state.get_title(), 'E');
}); });
test('push accepts async functions in async context', async () => { test('push accepts async functions in async context', async () => {

Loading…
Cancel
Save