Skip to content

Commit d04d44e

Browse files
committed
perf(toc): reduce bundle size by deprecating store in favor of simpler callback
1 parent dcdc972 commit d04d44e

3 files changed

Lines changed: 11 additions & 15 deletions

File tree

.changeset/chilly-cars-matter.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@svelte-put/toc': patch
3+
---
4+
5+
deprecate internal svelte store (for tracking active item) in favor of simple callback for smaller bundle size

packages/actions/toc/src/lib/toc.action.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import { tick } from 'svelte';
22
// eslint-disable-next-line @typescript-eslint/no-unused-vars
33
import type { Action, ActionReturn } from 'svelte/action';
4-
import { writable } from 'svelte/store';
54

65
import { ATTRIBUTES, EVENTS, cache, intersectionObserverCallback } from './toc.internal';
7-
import type { ActiveTocItemStore } from './toc.internal';
86
import { compare, resolve } from './toc.parameters';
97
import type {
108
ResolvedTocParameters,
@@ -97,13 +95,12 @@ export const toc: Action<HTMLElement, UserTocParameters, TocAttributes> = functi
9795
let resolved = resolve(parameters);
9896

9997
let items: TocCacheItem['items'] = {};
100-
const activeTocItemStore = writable<string | undefined>(undefined) satisfies ActiveTocItemStore;
10198

10299
// stay minimal by reusing as few `IntersectionObserver` as possible
103100
// only create new `IntersectionObserver` for each new `threshold`
104101
const observers: Record<number, IntersectionObserver> = {};
105102

106-
const activeTocItemStoreUnsubscribe = activeTocItemStore.subscribe((activeTocItemId) => {
103+
function updateActiveTocItem(activeTocItemId?: string) {
107104
if (activeTocItemId) {
108105
const detail: TocChangeEventDetails = {
109106
id: resolved.id,
@@ -112,7 +109,7 @@ export const toc: Action<HTMLElement, UserTocParameters, TocAttributes> = functi
112109
node.dispatchEvent(new CustomEvent(EVENTS.change, { detail }));
113110
resolved.store?.set({ ...detail, items });
114111
}
115-
});
112+
}
116113

117114
tick().then(async () => {
118115
const { id, selector, anchor, observe, scrollMarginTop } = resolved;
@@ -228,7 +225,7 @@ export const toc: Action<HTMLElement, UserTocParameters, TocAttributes> = functi
228225
if (observers[threshold]) {
229226
observer = observers[threshold];
230227
} else {
231-
observer = new IntersectionObserver(intersectionObserverCallback(activeTocItemStore), {
228+
observer = new IntersectionObserver(intersectionObserverCallback(updateActiveTocItem), {
232229
threshold,
233230
rootMargin,
234231
root,
@@ -271,7 +268,6 @@ export const toc: Action<HTMLElement, UserTocParameters, TocAttributes> = functi
271268
// - re-run operations
272269
},
273270
destroy() {
274-
activeTocItemStoreUnsubscribe();
275271
for (const observer of Object.values(observers)) {
276272
observer.disconnect();
277273
}

packages/actions/toc/src/lib/toc.internal.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,17 @@ export const EVENTS = {
3535
*/
3636
export const cache: Record<string, TocCacheItem> = {};
3737

38-
/**
39-
* @internal
40-
*/
41-
export type ActiveTocItemStore = Writable<string | undefined>;
42-
4338
/**
4439
* @internal
4540
*/
4641
export const intersectionObserverCallback: (
47-
store: ActiveTocItemStore,
48-
) => IntersectionObserverCallback = (store) => {
42+
callback: (activeTocItemId?: string) => void,
43+
) => IntersectionObserverCallback = (callback) => {
4944
return (entries) => {
5045
for (const entry of entries) {
5146
const tocId = entry.target.getAttribute(ATTRIBUTES.observeFor);
5247
if (tocId && entry.isIntersecting) {
53-
store.set(tocId);
48+
callback(tocId);
5449
}
5550
}
5651
};

0 commit comments

Comments
 (0)