Skip to content

Commit

Permalink
Remove internal adapter connecting Svelte to core
Browse files Browse the repository at this point in the history
  • Loading branch information
inokawa committed Nov 30, 2024
1 parent d739d69 commit 6494113
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 322 deletions.
11 changes: 7 additions & 4 deletions rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const terserPlugin = ({ vue } = {}) =>
},
});

const svelteDir = path.dirname(pkg.exports["./svelte"].default);
const corePath = "./lib/core/index.js";

/** @type { import('rollup').RollupOptions[] } */
export default [
Expand Down Expand Up @@ -136,10 +136,10 @@ export default [
},
// svelte
{
input: "src/svelte/core.ts",
input: "src/core/index.ts",
output: [
{
file: path.join(svelteDir, "core.js"),
file: corePath,
format: "esm",
// sourcemap: true,
},
Expand All @@ -152,7 +152,10 @@ export default [
exclude: ["**/*.{spec,stories}.*"],
}),
terserPlugin(),
svelteCopy({ dir: svelteDir }),
svelteCopy({
dir: path.dirname(pkg.exports["./svelte"].default),
coreDts: path.join(path.dirname(corePath), "index.d.ts"),
}),
],
external,
},
Expand Down
5 changes: 3 additions & 2 deletions scripts/rollup-plugin-svelte-copy.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import tsconfig from "../tsconfig.json" with { type: "json" };
/**
* @type { (arg:{dir:string}) => import('rollup').InputPluginOption }
*/
export const svelteCopy = ({ dir }) => {
export const svelteCopy = ({ dir, coreDts }) => {
const require = createRequire(import.meta.url);

const svelteShimsPath = require.resolve("svelte2tsx/svelte-shims-v4.d.ts");
Expand All @@ -22,13 +22,14 @@ export const svelteCopy = ({ dir }) => {
return {
name: "svelte-copy",
buildEnd: () => {
writeFileSync(coreDts, "// @ts-nocheck\n" + readFileSync(coreDts));
for (const filename of globSync(`${dir}/[!index]*.d.ts`)) {
writeFileSync(filename, "// @ts-nocheck\n" + readFileSync(filename));
}

const svelteCodes = [];

for (const filename of globSync("./src/svelte/[!core.ts]*")) {
for (const filename of globSync("./src/svelte/*")) {
if (filename.endsWith(".svelte")) {
const code = readFileSync(filename, "utf8");
writeFileSync(join(dir, basename(filename)), code);
Expand Down
2 changes: 1 addition & 1 deletion src/svelte/ListItem.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts" generics="T">
import { type Snippet, onDestroy } from "svelte";
import { isRTLDocument, type ItemResizeObserver } from "./core";
import { isRTLDocument, type ItemResizeObserver } from "../core";
import { styleToString } from "./utils";
import type { SvelteHTMLElements } from "svelte/elements";
Expand Down
148 changes: 70 additions & 78 deletions src/svelte/Virtualizer.svelte
Original file line number Diff line number Diff line change
@@ -1,32 +1,17 @@
<script lang="ts" generics="T">
import { onMount, onDestroy } from "svelte";
import {
ACTION_ITEMS_LENGTH_CHANGE,
ACTION_START_OFFSET_CHANGE,
type StateVersion,
CHANGE_ITEM_LENGTH,
createVirtualizer,
FIX_SCROLL_JUMP,
GET_ITEM_OFFSET,
GET_JUMP_COUNT,
GET_RANGE,
GET_IS_SCROLLING,
GET_SCROLL_OFFSET,
GET_SCROLL_SIZE,
GET_TOTAL_SIZE,
GET_VIEWPORT_SIZE,
IS_ITEM_HIDDEN,
OBSERVE_ITEM_RESIZE,
ON_MOUNT,
ON_UN_MOUNT,
SCROLL_BY,
SCROLL_TO,
SCROLL_TO_INDEX,
CHANGE_START_MARGIN,
GET_START_SPACER_SIZE,
GET_ITEMS_LENGTH,
GET_ITEM_SIZE,
FIND_START_INDEX,
FIND_END_INDEX,
} from "./core";
UPDATE_SCROLL_END_EVENT,
UPDATE_SCROLL_EVENT,
UPDATE_VIRTUAL_STATE,
createResizer,
createScroller,
createVirtualStore,
getScrollSize as _getScrollSize,
} from "../core";
import { defaultGetKey, styleToString, iterRange } from "./utils";
import ListItem from "./ListItem.svelte";
import type { VirtualizerHandle, VirtualizerProps } from "./Virtualizer.type";
Expand All @@ -49,17 +34,24 @@
onscrollend,
}: Props = $props();
const virtualizer = createVirtualizer(
const store = createVirtualStore(
data.length,
itemSize,
overscan,
horizontal,
(v) => {
rerender = v;
},
(offset) => {
onscroll && onscroll(offset);
},
undefined,
undefined,
!itemSize
);
const resizer = createResizer(store, horizontal);
const scroller = createScroller(store, horizontal);
const unsubscribeStore = store._subscribe(UPDATE_VIRTUAL_STATE, () => {
rerender = store._getStateVersion();
});
const unsubscribeOnScroll = store._subscribe(UPDATE_SCROLL_EVENT, () => {
onscroll && onscroll(store._getScrollOffset());
});
const unsubscribeOnScrollEnd = store._subscribe(
UPDATE_SCROLL_END_EVENT,
() => {
onscrollend && onscrollend();
}
Expand All @@ -69,71 +61,71 @@
let rerender: StateVersion = $state([]);
let range = $derived(rerender && virtualizer[GET_RANGE]());
let isScrolling = $derived(rerender && virtualizer[GET_IS_SCROLLING]());
let totalSize = $derived(rerender && virtualizer[GET_TOTAL_SIZE]());
let jumpCount = $derived(rerender && virtualizer[GET_JUMP_COUNT]());
let range = $derived(rerender && store._getRange());
let isScrolling = $derived(rerender && store._isScrolling());
let totalSize = $derived(rerender && store._getTotalSize());
let jumpCount = $derived(rerender && store._getJumpCount());
onMount(() => {
const assignRef = (scrollable: HTMLElement) => {
resizer._observeRoot(scrollable);
scroller._observe(scrollable);
};
if (scrollRef) {
virtualizer[ON_MOUNT](scrollRef);
assignRef(scrollRef);
} else {
virtualizer[ON_MOUNT](containerRef!.parentElement!);
assignRef(containerRef!.parentElement!);
}
});
onDestroy(() => {
virtualizer[ON_UN_MOUNT]();
unsubscribeStore();
unsubscribeOnScroll();
unsubscribeOnScrollEnd();
resizer._dispose();
scroller._dispose();
});
$effect.pre(() => {
if (data.length !== virtualizer[GET_ITEMS_LENGTH]()) {
virtualizer[CHANGE_ITEM_LENGTH](data.length, shift);
if (data.length !== store._getItemsLength()) {
store._update(ACTION_ITEMS_LENGTH_CHANGE, [data.length, shift]);
}
});
$effect.pre(() => {
if (startMargin !== virtualizer[GET_START_SPACER_SIZE]()) {
virtualizer[CHANGE_START_MARGIN](startMargin);
if (startMargin !== store._getStartSpacerSize()) {
store._update(ACTION_START_OFFSET_CHANGE, startMargin);
}
});
let prevJumpCount: number | undefined;
$effect(() => {
if (prevJumpCount === jumpCount) return;
prevJumpCount = jumpCount;
virtualizer[FIX_SCROLL_JUMP]();
scroller._fixScrollJump();
});
export const getScrollOffset = virtualizer[
GET_SCROLL_OFFSET
] satisfies VirtualizerHandle["getScrollOffset"] as VirtualizerHandle["getScrollOffset"];
export const getScrollSize = virtualizer[
GET_SCROLL_SIZE
] satisfies VirtualizerHandle["getScrollSize"] as VirtualizerHandle["getScrollSize"];
export const getViewportSize = virtualizer[
GET_VIEWPORT_SIZE
] satisfies VirtualizerHandle["getViewportSize"] as VirtualizerHandle["getViewportSize"];
export const findStartIndex = virtualizer[
FIND_START_INDEX
] satisfies VirtualizerHandle["findStartIndex"] as VirtualizerHandle["findStartIndex"];
export const findEndIndex = virtualizer[
FIND_END_INDEX
] satisfies VirtualizerHandle["findEndIndex"] as VirtualizerHandle["findEndIndex"];
export const getItemOffset = virtualizer[
GET_ITEM_OFFSET
] satisfies VirtualizerHandle["getItemOffset"] as VirtualizerHandle["getItemOffset"];
export const getItemSize = virtualizer[
GET_ITEM_SIZE
] satisfies VirtualizerHandle["getItemSize"] as VirtualizerHandle["getItemSize"];
export const scrollToIndex = virtualizer[
SCROLL_TO_INDEX
] satisfies VirtualizerHandle["scrollToIndex"] as VirtualizerHandle["scrollToIndex"];
export const scrollTo = virtualizer[
SCROLL_TO
] satisfies VirtualizerHandle["scrollTo"] as VirtualizerHandle["scrollTo"];
export const scrollBy = virtualizer[
SCROLL_BY
] satisfies VirtualizerHandle["scrollBy"] as VirtualizerHandle["scrollBy"];
export const getScrollOffset =
store._getScrollOffset satisfies VirtualizerHandle["getScrollOffset"] as VirtualizerHandle["getScrollOffset"];
export const getScrollSize = (() =>
_getScrollSize(
store
)) satisfies VirtualizerHandle["getScrollSize"] as VirtualizerHandle["getScrollSize"];
export const getViewportSize =
store._getViewportSize satisfies VirtualizerHandle["getViewportSize"] as VirtualizerHandle["getViewportSize"];
export const findStartIndex =
store._findStartIndex satisfies VirtualizerHandle["findStartIndex"] as VirtualizerHandle["findStartIndex"];
export const findEndIndex =
store._findEndIndex satisfies VirtualizerHandle["findEndIndex"] as VirtualizerHandle["findEndIndex"];
export const getItemOffset =
store._getItemOffset satisfies VirtualizerHandle["getItemOffset"] as VirtualizerHandle["getItemOffset"];
export const getItemSize =
store._getItemSize satisfies VirtualizerHandle["getItemSize"] as VirtualizerHandle["getItemSize"];
export const scrollToIndex =
scroller._scrollToIndex satisfies VirtualizerHandle["scrollToIndex"] as VirtualizerHandle["scrollToIndex"];
export const scrollTo =
scroller._scrollTo satisfies VirtualizerHandle["scrollTo"] as VirtualizerHandle["scrollTo"];
export const scrollBy =
scroller._scrollBy satisfies VirtualizerHandle["scrollBy"] as VirtualizerHandle["scrollBy"];
let containerStyle = $derived(
styleToString({
Expand Down Expand Up @@ -161,10 +153,10 @@
{item}
{index}
as={itemAs}
offset={rerender && virtualizer[GET_ITEM_OFFSET](index)}
hide={rerender && virtualizer[IS_ITEM_HIDDEN](index)}
offset={rerender && store._getItemOffset(index)}
hide={rerender && store._isUnmeasuredItem(index)}
{horizontal}
resizer={virtualizer[OBSERVE_ITEM_RESIZE]}
resizer={resizer._observeItem}
/>
{/each}
</svelte:element>
Loading

0 comments on commit 6494113

Please sign in to comment.