chore: import upstream snapshot with attribution
publish / version_or_publish (push) Has been cancelled
storybook-build / changes (push) Has been cancelled
storybook-build / :storybook-build (push) Has been cancelled
Sync Gradio Skills to Hugging Face / sync-skills (push) Has been cancelled
functional / changes (push) Has been cancelled
functional / build-frontend (push) Has been cancelled
functional / functional-test-SSR=false (push) Has been cancelled
functional / functional-reload (push) Has been cancelled
js / changes (push) Has been cancelled
js / js-test (push) Has been cancelled
docs-build / changes (push) Has been cancelled
docs-build / docs-build (push) Has been cancelled
docs-build / website-build (push) Has been cancelled
functional / functional-test-SSR=true (push) Has been cancelled
hygiene / hygiene-test (push) Has been cancelled
python / changes (push) Has been cancelled
python / build (push) Has been cancelled
python / test-ubuntu-latest-flaky (push) Has been cancelled
python / test-ubuntu-latest-not-flaky (push) Has been cancelled
python / test-windows-latest-flaky (push) Has been cancelled
python / test-windows-latest-not-flaky (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:17:32 +08:00
commit adf0d17497
3085 changed files with 456962 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
export { createSvelteTable } from "./table.svelte.js";
export { createSvelteVirtualizer, type VirtualItem } from "./virtual.svelte.js";
export {
createColumnHelper,
getCoreRowModel,
getSortedRowModel,
getFilteredRowModel,
type ColumnDef,
type TableOptions,
type Table,
type Header,
type Cell,
type Row,
type SortingState,
type ColumnFiltersState,
type ColumnPinningState,
type FilterFn,
type SortingFn,
type CellContext,
type HeaderContext
} from "@tanstack/table-core";
@@ -0,0 +1,121 @@
import {
createTable,
type RowData,
type TableOptions,
type TableOptionsResolved,
type TableState
} from "@tanstack/table-core";
/**
* Merges objects while preserving property getters for lazy evaluation.
* Properties are defined as getters that look up values from sources in
* reverse order at access time. This is critical: it means reading a
* property from the merged result doesn't happen until the property is
* actually accessed, not when mergeObjects is called.
*/
export function mergeObjects(...sources: any): any {
const target: Record<string, any> = {};
for (let i = 0; i < sources.length; i++) {
let source = sources[i];
if (typeof source === "function") source = source();
if (source) {
const descriptors = Object.getOwnPropertyDescriptors(source);
for (const key in descriptors) {
if (key in target) continue;
Object.defineProperty(target, key, {
enumerable: true,
get() {
for (let j = sources.length - 1; j >= 0; j--) {
let s = sources[j];
if (typeof s === "function") s = s();
const v = (s || {})[key];
if (v !== undefined) return v;
}
}
});
}
}
}
return target;
}
/**
* Creates a reactive TanStack Table for Svelte 5.
*
* The reactivity works through mergeObjects' lazy getters:
* - $effect.pre calls table.setOptions() with a merged object
* - The merged object has lazy getters for `data`, `columns`, `state`, etc.
* - TanStack stores this object but doesn't deep-read all properties immediately
* - When getRowModel() is called (in $derived), TanStack reads `data` and `columns`
* through the lazy getters, which read the reactive $state/$derived values
* - onStateChange fires when TanStack mutates its own state → bumps version
* - version is read by getRowModel/getHeaderGroups → $derived re-evaluates
*/
export function createSvelteTable<TData extends RowData>(
options: TableOptions<TData>
) {
const resolvedOptions: TableOptionsResolved<TData> = mergeObjects(
{
state: {},
onStateChange() {},
renderFallbackValue: null,
mergeOptions: (
defaultOptions: TableOptions<TData>,
opts: Partial<TableOptions<TData>>
) => {
return mergeObjects(defaultOptions, opts);
}
},
options
);
const table = createTable(resolvedOptions);
let state = $state<Partial<TableState>>(table.initialState);
let version = $state(0);
function updateOptions(): void {
table.setOptions(() => {
// Always merge from resolvedOptions instead of prev to prevent
// unbounded getter chains. Using prev would add a new mergeObjects
// layer on every call; properties not in the overrides would have
// to traverse every previous layer, causing stack overflow.
// TanStack's setOptions already re-applies feature defaults via
// mergeOptions, so we don't lose any internal defaults.
return mergeObjects(resolvedOptions, options, {
state: mergeObjects(state, options.state || {}),
onStateChange: (updater: any) => {
if (updater instanceof Function) state = updater(state);
else state = mergeObjects(state, updater);
version += 1;
options.onStateChange?.(updater);
}
});
});
}
// Initial sync
updateOptions();
// Re-sync when options change. Because mergeObjects uses lazy getters,
// this effect's tracked dependencies are only the properties that
// table.setOptions() eagerly reads (which is minimal — mostly just
// checking if the options object reference changed).
$effect.pre(() => {
updateOptions();
});
return {
getRowModel: () => {
void version;
return table.getRowModel();
},
getHeaderGroups: () => {
void version;
return table.getHeaderGroups();
},
getColumn: (id: string) => {
void version;
return table.getColumn(id);
}
};
}
@@ -0,0 +1,105 @@
import {
Virtualizer,
elementScroll,
observeElementOffset,
observeElementRect,
type PartialKeys,
type VirtualizerOptions
} from "@tanstack/virtual-core";
import { untrack } from "svelte";
export type { VirtualItem } from "@tanstack/virtual-core";
/**
* Creates a reactive TanStack Virtualizer for Svelte 5.
*
* Returns a getter function that returns the virtualizer instance.
* Call the getter inside $derived or template expressions to create
* reactive dependencies on the virtualizer state.
*/
export function createSvelteVirtualizer<
TScrollElement extends Element,
TItemElement extends Element
>(
options: PartialKeys<
VirtualizerOptions<TScrollElement, TItemElement>,
"observeElementRect" | "observeElementOffset" | "scrollToFn"
>
): {
instance: Virtualizer<TScrollElement, TItemElement>;
virtualItems: () => ReturnType<
Virtualizer<TScrollElement, TItemElement>["getVirtualItems"]
>;
totalSize: () => number;
} {
let version = $state(0);
const virtualizer = new Virtualizer<TScrollElement, TItemElement>({
observeElementRect: observeElementRect,
observeElementOffset: observeElementOffset,
scrollToFn: elementScroll,
...options,
onChange: (instance, sync) => {
if (sync) {
version += 1;
} else {
queueMicrotask(() => {
version += 1;
});
}
options.onChange?.(instance, sync);
}
});
$effect(() => {
const cleanup = virtualizer._didMount();
untrack(() => {
version += 1;
});
return cleanup;
});
let prev_count = 0;
$effect(() => {
const current_count = options.count;
virtualizer.setOptions({
observeElementRect: observeElementRect,
observeElementOffset: observeElementOffset,
scrollToFn: elementScroll,
...options,
onChange: (instance, sync) => {
if (sync) {
version += 1;
} else {
queueMicrotask(() => {
version += 1;
});
}
options.onChange?.(instance, sync);
}
});
if (prev_count === 0 && current_count > 0) {
virtualizer.measure();
}
prev_count = current_count;
});
$effect.pre(() => {
void version;
virtualizer._willUpdate();
});
return {
instance: virtualizer,
virtualItems: () => {
void version;
return virtualizer.getVirtualItems();
},
totalSize: () => {
void version;
return virtualizer.getTotalSize();
}
};
}