Skip to content

Commit 7c67527

Browse files
committed
split out utilities
1 parent 6d7e55d commit 7c67527

File tree

3 files changed

+67
-48
lines changed

3 files changed

+67
-48
lines changed

src/debounce.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Debounces a function call and collects items during the debounce period.
3+
*
4+
* @param fn - The function to debounce. Will be called with an array of all collected items.
5+
* @param timeoutMs - The maximum delay in milliseconds before invoking the function.
6+
* @returns A function that accepts a single item and schedules a debounced invocation.
7+
*
8+
* Guarantees:
9+
* 1. Each item added will be included exactly once in a call to fn
10+
* 2. Items are preserved in order of addition
11+
* 3. If a timer is already running, adding an item will not reset the timer
12+
*
13+
* Example timeline:
14+
* t=0: add(A) → timer starts
15+
* t=10: add(B) → timer continues
16+
* t=500: timer fires → fn([A,B])
17+
*/
18+
export function debounce<T>(fn: (items: T[]) => void, timeoutMs: number) {
19+
let timeout: NodeJS.Timeout | null = null;
20+
let items: T[] = [];
21+
22+
return (item: T) => {
23+
items.push(item);
24+
25+
if (timeout === null)
26+
timeout = setTimeout(() => {
27+
fn(items);
28+
items = [];
29+
timeout = null;
30+
}, timeoutMs);
31+
};
32+
}

src/deduplicate.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/** Keeps only the last occurrence of each item in the array */
2+
export function deduplicate<T, Y>(arr: T[], getKey: (item: T) => Y): void {
3+
const keyPositions = new Map<Y, number>();
4+
let writeAt = 0;
5+
6+
for (let readAt = 0; readAt < arr.length; readAt++) {
7+
const item = arr[readAt];
8+
const key = getKey(item);
9+
const keyPos = keyPositions.get(key) ?? writeAt++;
10+
keyPositions.set(key, keyPos);
11+
arr[keyPos] = item;
12+
}
13+
14+
arr.length = writeAt;
15+
}

src/spreadsheet.ts

Lines changed: 20 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ import "@univerjs/ui/lib/index.css";
2121
import "@univerjs/docs-ui/lib/index.css";
2222
import "@univerjs/sheets-ui/lib/index.css";
2323
import "@univerjs/sheets-formula-ui/lib/index.css";
24+
import type { IEventParamConfig } from "@univerjs/presets";
25+
import { debounce } from "./debounce";
26+
import { deduplicate } from "./deduplicate";
2427

2528
const univerPresets = import("@univerjs/presets");
2629
const univerPresetsSheets = import("@univerjs/presets/preset-sheets-core");
@@ -144,25 +147,6 @@ interface UpdateParams {
144147
errorModal: ReturnType<typeof setupErrorModal>;
145148
}
146149

147-
function debounce<T>(fn: (items: T[]) => Promise<void>, timeoutMs: number) {
148-
let timeout: NodeJS.Timeout | null = null;
149-
let items: T[] = [];
150-
151-
return (item: T) => {
152-
if (timeout) {
153-
clearTimeout(timeout);
154-
}
155-
156-
items.push(item);
157-
158-
timeout = setTimeout(async () => {
159-
const currentItems = items;
160-
items = [];
161-
await fn(currentItems);
162-
}, timeoutMs);
163-
};
164-
}
165-
166150
const performUpdate = async (params: UpdateParams) => {
167151
const { update_link, x, y, value, customId, errorModal } = params;
168152
if (!update_link) return;
@@ -254,21 +238,25 @@ async function renderSpreadsheet(
254238
};
255239
if (DEBUG) console.log("sqlpage-spreadsheet: creating sheet", sheet);
256240

257-
univerAPI.createUniverSheet(sheet);
241+
univerAPI.createWorkbook(sheet);
258242

259243
const { update_link } = props;
260-
univerAPI.onCommandExecuted(({ id, params }) => {
261-
// To debug:
262-
// console.log(id, params);
263-
if (update_link && id === SetRangeValuesMutation.id) {
264-
handleSetRangeValues(
265-
params as ISetRangeValuesMutationParams,
266-
update_link,
267-
errorModal,
268-
cellIdMap,
269-
);
270-
}
271-
});
244+
univerAPI.addEvent(
245+
"CommandExecuted",
246+
// @ts-ignore: https://github.com/dream-num/univer/issues/4504
247+
({ id, params }: IEventParamConfig["CommandExecuted"]) => {
248+
// To debug:
249+
// console.log(id, params);
250+
if (update_link && id === SetRangeValuesMutation.id) {
251+
handleSetRangeValues(
252+
params as ISetRangeValuesMutationParams,
253+
update_link,
254+
errorModal,
255+
cellIdMap,
256+
);
257+
}
258+
},
259+
);
272260
}
273261

274262
function handleSetRangeValues(
@@ -354,19 +342,3 @@ const elem = elems[elems.length - 1];
354342
if (!(elem instanceof HTMLElement))
355343
throw new Error("No spreadsheet elements found");
356344
renderSpreadsheetToElement(elem);
357-
358-
/** Keeps only the last occurrence of each item in the array */
359-
function deduplicate<T, Y>(arr: T[], getKey: (item: T) => Y): void {
360-
const keyPositions = new Map<Y, number>();
361-
let writeAt = 0;
362-
363-
for (let readAt = 0; readAt < arr.length; readAt++) {
364-
const item = arr[readAt];
365-
const key = getKey(item);
366-
const keyPos = keyPositions.get(key) ?? writeAt++;
367-
keyPositions.set(key, keyPos);
368-
arr[keyPos] = item;
369-
}
370-
371-
arr.length = writeAt;
372-
}

0 commit comments

Comments
 (0)