Skip to content

Commit

Permalink
feat: Typing improvements to preload PR (#7841)
Browse files Browse the repository at this point in the history
* feat: Improve typings on data-sveltekit attributes

* feat: improved constants

* Update packages/kit/src/runtime/client/utils.js

Co-authored-by: gtmnayan <50981692+gtm-nayan@users.noreply.github.com>

* remove dev guard from validateAttributeValue

* snake_case

* dot notation

* shorter name so prettier doesnt butcher the code

* shorter name

* get typechecking working

* neaten

* oops

* tweak

Co-authored-by: Rich Harris <richard.a.harris@gmail.com>
Co-authored-by: gtmnayan <50981692+gtm-nayan@users.noreply.github.com>
Co-authored-by: Rich Harris <hello@rich-harris.dev>
  • Loading branch information
4 people authored Nov 28, 2022
1 parent e3428a2 commit bd470a3
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 63 deletions.
6 changes: 3 additions & 3 deletions packages/kit/src/runtime/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { HttpError, Redirect } from '../control.js';
import { stores } from './singletons.js';
import { unwrap_promises } from '../../utils/promises.js';
import * as devalue from 'devalue';
import { INDEX_KEY, PRIORITY_PAGE, PRIORITY_VIEWPORT, SCROLL_KEY } from './constants.js';
import { INDEX_KEY, PRELOAD_PRIORITIES, SCROLL_KEY } from './constants.js';

const routes = parse(nodes, server_loads, dictionary, matchers);

Expand Down Expand Up @@ -1236,11 +1236,11 @@ export function create_client({ target, base }) {

if (external) continue;

if (options.preload_code === PRIORITY_VIEWPORT) {
if (options.preload_code === PRELOAD_PRIORITIES.viewport) {
observer.observe(a);
}

if (options.preload_code === PRIORITY_PAGE) {
if (options.preload_code === PRELOAD_PRIORITIES.page) {
preload_code(/** @type {URL} */ (url).pathname);
}
}
Expand Down
11 changes: 7 additions & 4 deletions packages/kit/src/runtime/client/constants.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
export const SCROLL_KEY = 'sveltekit:scroll';
export const INDEX_KEY = 'sveltekit:index';

export const PRIORITY_TAP = 1;
export const PRIORITY_HOVER = 2;
export const PRIORITY_VIEWPORT = 3;
export const PRIORITY_PAGE = 4;
export const PRELOAD_PRIORITIES = /** @type {const} */ ({
tap: 1,
hover: 2,
viewport: 3,
page: 4,
off: -1
});
85 changes: 45 additions & 40 deletions packages/kit/src/runtime/client/utils.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { writable } from 'svelte/store';
import { assets } from '../paths.js';
import { version } from '../env.js';
import { PRIORITY_HOVER, PRIORITY_PAGE, PRIORITY_TAP, PRIORITY_VIEWPORT } from './constants.js';
import { PRELOAD_PRIORITIES } from './constants.js';

/* global __SVELTEKIT_APP_VERSION_FILE__, __SVELTEKIT_APP_VERSION_POLL_INTERVAL__ */

Expand All @@ -26,34 +26,54 @@ export function scroll_state() {

const warned = new WeakSet();

/** @typedef {keyof typeof valid_link_options} LinkOptionName */

const valid_link_options = /** @type {const} */ ({
'preload-code': ['', 'off', 'tap', 'hover', 'viewport', 'page'],
'preload-data': ['', 'off', 'tap', 'hover'],
noscroll: ['', 'off'],
reload: ['', 'off']
});

/**
* @template {LinkOptionName} T
* @param {Element} element
* @param {string} name
* @param {string | null} value
* @param {string[]} options
* @param {T} name
*/
function validate(element, name, value, options) {
if (warned.has(element)) return;
if (value === null) return;
if (!options.includes(value)) {
warned.add(element);
function link_option(element, name) {
const value = /** @type {typeof valid_link_options[T][number] | null} */ (
element.getAttribute(`data-sveltekit-${name}`)
);

return __SVELTEKIT_DEV__ ? validate_link_option(element, name, value) : value;
}

/**
* @template {LinkOptionName} T
* @template {typeof valid_link_options[T][number] | null} U
* @param {Element} element
* @param {T} name
* @param {U} value
*/
function validate_link_option(element, name, value) {
if (warned.has(element) || value === null) return /** @type {U} */ (null);

// @ts-expect-error - includes is dumb
if (!valid_link_options[name].includes(value)) {
console.error(
`Unexpected value for ${name} — should be one of ${options
`Unexpected value for ${name} — should be one of ${valid_link_options[name]
.map((option) => JSON.stringify(option))
.join(', ')}`,
element
);
}

return value;
}

/** @type {Record<string, number>} */
const levels = {
tap: PRIORITY_TAP,
hover: PRIORITY_HOVER,
viewport: PRIORITY_VIEWPORT,
page: PRIORITY_PAGE,
'': PRIORITY_HOVER,
off: -1
...PRELOAD_PRIORITIES,
'': PRELOAD_PRIORITIES.hover
};

/**
Expand All @@ -64,16 +84,16 @@ export function find_anchor(element, base) {
/** @type {HTMLAnchorElement | SVGAElement | undefined} */
let a;

/** @type {string | null} */
/** @type {typeof valid_link_options['noscroll'][number] | null} */
let noscroll = null;

/** @type {string | null} */
/** @type {typeof valid_link_options['preload-code'][number] | null} */
let preload_code = null;

/** @type {string | null} */
/** @type {typeof valid_link_options['preload-data'][number] | null} */
let preload_data = null;

/** @type {string | null} */
/** @type {typeof valid_link_options['reload'][number] | null} */
let reload = null;

while (element !== document.documentElement) {
Expand All @@ -83,25 +103,10 @@ export function find_anchor(element, base) {
}

if (a) {
if (preload_code === null) preload_code = element.getAttribute('data-sveltekit-preload-code');
if (preload_data === null) preload_data = element.getAttribute('data-sveltekit-preload-data');
if (noscroll === null) noscroll = element.getAttribute('data-sveltekit-noscroll');
if (reload === null) reload = element.getAttribute('data-sveltekit-reload');

if (__SVELTEKIT_DEV__) {
validate(element, 'data-sveltekit-preload-data', preload_data, ['', 'off', 'tap', 'hover']);
validate(element, 'data-sveltekit-preload-code', preload_code, [
'',
'off',
'tap',
'hover',
'viewport',
'page'
]);

validate(element, 'data-sveltekit-preload-data', noscroll, ['', 'off']);
validate(element, 'data-sveltekit-preload-data', reload, ['', 'off']);
}
if (preload_code === null) preload_code = link_option(element, 'preload-code');
if (preload_data === null) preload_data = link_option(element, 'preload-data');
if (noscroll === null) noscroll = link_option(element, 'noscroll');
if (reload === null) reload = link_option(element, 'reload');
}

// @ts-expect-error handle shadow roots
Expand Down
16 changes: 0 additions & 16 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit bd470a3

Please sign in to comment.