11import type { Detail } from "jsr:@vim-fall/core@^0.3.0/item" ;
2- import { brotli } from "jsr:@deno-library/compress@^0.5.6" ;
32
43import type { PickerContext } from "./picker.ts" ;
54
65/**
7- * In-memory storage for compressed picker sessions.
6+ * In-memory storage for picker sessions.
87 * Sessions are stored in chronological order (oldest first).
98 */
109// deno-lint-ignore no-explicit-any
11- const sessions : PickerSessionCompressed < any > [ ] = [ ] ;
10+ const sessions : PickerSession < any > [ ] = [ ] ;
1211
1312/**
1413 * Maximum number of sessions to keep in memory.
@@ -28,88 +27,24 @@ export type PickerSession<T extends Detail> = {
2827 readonly context : PickerContext < T > ;
2928} ;
3029
31- /**
32- * Compressed version of PickerSession where the context is stored as binary data.
33- * This reduces memory usage when storing multiple sessions.
34- * @template T - The type of item detail in the picker
35- */
36- export type PickerSessionCompressed < T extends Detail > =
37- & Omit < PickerSession < T > , "context" >
38- & {
39- /** Brotli-compressed binary representation of the context */
40- context : Uint8Array ;
41- } ;
42-
43- /**
44- * Compresses a picker session by converting its context to brotli-compressed binary data.
45- * This is used internally to reduce memory usage when storing sessions.
46- * @template T - The type of item detail in the picker
47- * @param session - The session to compress
48- * @returns A promise that resolves to the compressed session
49- */
50- async function compressPickerSession < T extends Detail > (
51- session : PickerSession < T > ,
52- ) : Promise < PickerSessionCompressed < T > > {
53- const encoder = new TextEncoder ( ) ;
54- // Convert Set to Array for JSON serialization
55- const contextForSerialization = {
56- ...session . context ,
57- selection : Array . from ( session . context . selection ) ,
58- } ;
59- return {
60- ...session ,
61- context : await brotli . compress (
62- encoder . encode ( JSON . stringify ( contextForSerialization ) ) ,
63- ) ,
64- } ;
65- }
66-
67- /**
68- * Decompresses a picker session by converting its binary context back to structured data.
69- * @template T - The type of item detail in the picker
70- * @param compressed - The compressed session to decompress
71- * @returns A promise that resolves to the decompressed session
72- */
73- export async function decompressPickerSession < T extends Detail > (
74- compressed : PickerSessionCompressed < T > ,
75- ) : Promise < PickerSession < T > > {
76- const decoder = new TextDecoder ( ) ;
77- const decompressedContext = JSON . parse (
78- decoder . decode ( await brotli . uncompress ( compressed . context ) ) ,
79- ) ;
80- // Convert selection array back to Set
81- return {
82- ...compressed ,
83- context : {
84- ...decompressedContext ,
85- selection : new Set ( decompressedContext . selection ) ,
86- } ,
87- } ;
88- }
89-
9030/**
9131 * Lists all stored picker sessions in reverse chronological order (newest first).
92- * @returns A readonly array of compressed sessions
32+ * @returns A readonly array of sessions
9333 */
94- export function listPickerSessions ( ) : readonly PickerSessionCompressed <
95- Detail
96- > [ ] {
34+ export function listPickerSessions ( ) : readonly PickerSession < Detail > [ ] {
9735 return sessions . slice ( ) . reverse ( ) ; // Return a copy in reverse order
9836}
9937
10038/**
10139 * Saves a picker session to the in-memory storage.
102- * The session is compressed before storage to reduce memory usage.
10340 * If the storage exceeds MAX_SESSION_COUNT, the oldest session is removed.
10441 * @template T - The type of item detail in the picker
10542 * @param session - The session to save
106- * @returns A promise that resolves when the session is saved
10743 */
108- export async function savePickerSession < T extends Detail > (
44+ export function savePickerSession < T extends Detail > (
10945 session : PickerSession < T > ,
110- ) : Promise < void > {
111- const compressed = await compressPickerSession ( session ) ;
112- sessions . push ( compressed ) ;
46+ ) : void {
47+ sessions . push ( session ) ;
11348 if ( sessions . length > MAX_SESSION_COUNT ) {
11449 sessions . shift ( ) ; // Keep only the last MAX_SESSION_COUNT sessions
11550 }
@@ -130,29 +65,25 @@ export type LoadPickerSessionOptions = {
13065 * @template T - The type of item detail in the picker
13166 * @param indexFromLatest - The index from the latest session (0 = most recent, 1 = second most recent, etc.)
13267 * @param options - Options to filter sessions
133- * @returns A promise that resolves to the decompressed session, or undefined if not found
68+ * @returns The session, or undefined if not found
13469 * @example
13570 * ```ts
13671 * // Load the most recent session
137- * const session1 = await loadPickerSession();
72+ * const session1 = loadPickerSession();
13873 *
13974 * // Load the second most recent session
140- * const session2 = await loadPickerSession({ number: 2 });
75+ * const session2 = loadPickerSession({ number: 2 });
14176 *
14277 * // Load the most recent session with name "file"
143- * const session3 = await loadPickerSession({ name: "file", number: 1 });
78+ * const session3 = loadPickerSession({ name: "file", number: 1 });
14479 * ```
14580 */
146- export async function loadPickerSession < T extends Detail > (
81+ export function loadPickerSession < T extends Detail > (
14782 { name, number : indexFromLatest } : LoadPickerSessionOptions = { } ,
148- ) : Promise < PickerSession < T > | undefined > {
83+ ) : PickerSession < T > | undefined {
14984 const filteredSessions = name
15085 ? sessions . filter ( ( s ) => s . name === name )
15186 : sessions ;
15287 const index = filteredSessions . length - ( indexFromLatest ?? 1 ) ;
153- const compressed = filteredSessions . at ( index ) ;
154- if ( ! compressed ) {
155- return undefined ;
156- }
157- return await decompressPickerSession ( compressed ) ;
88+ return filteredSessions . at ( index ) as PickerSession < T > | undefined ;
15889}
0 commit comments