@shaxpir/duiduidui-models 1.37.4 → 1.38.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -96,38 +96,27 @@ export declare class Device extends Content {
96
96
  */
97
97
  get searchHistory(): SearchHistory;
98
98
  /**
99
- * Gets the current search state (at the cursor position), or undefined if history is empty.
99
+ * Gets the current search state (top of stack), or undefined if history is empty.
100
100
  */
101
101
  get currentSearchState(): SearchState | undefined;
102
102
  /**
103
103
  * Returns true if back navigation is possible.
104
- * Skips over empty entries to find a non-empty one.
104
+ * True whenever there is any previous entry below the top of the stack.
105
105
  */
106
106
  get canGoBack(): boolean;
107
- /**
108
- * Returns true if forward navigation is possible.
109
- * Skips over empty entries to find a non-empty one.
110
- */
111
- get canGoForward(): boolean;
112
107
  /**
113
108
  * Pushes a new search state onto the history stack.
114
- * - Deduplicates: won't push if identical to current state
115
- * - Discards forward history (entries after cursor)
109
+ * - Deduplicates: won't push if identical to current top
116
110
  * - Respects max entries limit (drops oldest when full)
117
111
  *
118
- * @returns The new search state at the cursor, or undefined if deduplicated
112
+ * @returns The new search state, or undefined if deduplicated
119
113
  */
120
114
  pushSearchState(state: SearchState): SearchState | undefined;
121
115
  /**
122
- * Navigates back in search history, skipping over empty entries.
123
- * @returns The search state at the new cursor position, or undefined if can't go back
116
+ * Navigates back in search history by popping the top entry.
117
+ * @returns The search state at the new top of stack, or undefined if can't go back
124
118
  */
125
119
  goBack(): SearchState | undefined;
126
- /**
127
- * Navigates forward in search history, skipping over empty entries.
128
- * @returns The search state at the new cursor position, or undefined if can't go forward
129
- */
130
- goForward(): SearchState | undefined;
131
120
  /**
132
121
  * Clears the entire search history stack.
133
122
  */
@@ -320,90 +320,59 @@ class Device extends Content_1.Content {
320
320
  return this.payload.search_history;
321
321
  }
322
322
  /**
323
- * Gets the current search state (at the cursor position), or undefined if history is empty.
323
+ * Gets the current search state (top of stack), or undefined if history is empty.
324
324
  */
325
325
  get currentSearchState() {
326
326
  this.checkDisposed("Device.currentSearchState");
327
327
  const history = this.searchHistory;
328
- if (history.cursor < 0 || history.cursor >= history.entries.length) {
328
+ if (history.entries.length === 0) {
329
329
  return undefined;
330
330
  }
331
- return history.entries[history.cursor];
331
+ return history.entries[history.entries.length - 1];
332
332
  }
333
333
  /**
334
334
  * Returns true if back navigation is possible.
335
- * Skips over empty entries to find a non-empty one.
335
+ * True whenever there is any previous entry below the top of the stack.
336
336
  */
337
337
  get canGoBack() {
338
338
  this.checkDisposed("Device.canGoBack");
339
339
  const history = this.searchHistory;
340
- // Look for any non-empty entry before the cursor
341
- for (let i = history.cursor - 1; i >= 0; i--) {
342
- if (!(0, SearchState_1.isEmptySearchState)(history.entries[i])) {
343
- return true;
344
- }
345
- }
346
- return false;
347
- }
348
- /**
349
- * Returns true if forward navigation is possible.
350
- * Skips over empty entries to find a non-empty one.
351
- */
352
- get canGoForward() {
353
- this.checkDisposed("Device.canGoForward");
354
- const history = this.searchHistory;
355
- // Look for any non-empty entry after the cursor
356
- for (let i = history.cursor + 1; i < history.entries.length; i++) {
357
- if (!(0, SearchState_1.isEmptySearchState)(history.entries[i])) {
358
- return true;
359
- }
360
- }
361
- return false;
340
+ return history.entries.length >= 2;
362
341
  }
363
342
  /**
364
343
  * Pushes a new search state onto the history stack.
365
- * - Deduplicates: won't push if identical to current state
366
- * - Discards forward history (entries after cursor)
344
+ * - Deduplicates: won't push if identical to current top
367
345
  * - Respects max entries limit (drops oldest when full)
368
346
  *
369
- * @returns The new search state at the cursor, or undefined if deduplicated
347
+ * @returns The new search state, or undefined if deduplicated
370
348
  */
371
349
  pushSearchState(state) {
372
350
  this.checkDisposed("Device.pushSearchState");
373
351
  const history = this.searchHistory;
374
- // Deduplicate: don't push if identical to current state
375
- const currentState = history.cursor >= 0 && history.cursor < history.entries.length
376
- ? history.entries[history.cursor]
352
+ // Deduplicate: don't push if identical to current top
353
+ const currentState = history.entries.length > 0
354
+ ? history.entries[history.entries.length - 1]
377
355
  : undefined;
378
356
  if ((0, SearchState_1.areSearchStatesEqual)(state, currentState)) {
379
357
  return undefined;
380
358
  }
381
- // Build new entries array
382
- // Discard any entries after the current cursor (browser-style)
383
- let newEntries = history.cursor >= 0
384
- ? history.entries.slice(0, history.cursor + 1)
385
- : [];
386
- // Add the new state
387
- newEntries.push(state);
359
+ let newEntries = [...history.entries, state];
388
360
  // Enforce max entries limit - drop oldest entries
389
- let newCursor = newEntries.length - 1;
390
361
  if (newEntries.length > SearchState_1.SEARCH_HISTORY_MAX_ENTRIES) {
391
362
  const overflow = newEntries.length - SearchState_1.SEARCH_HISTORY_MAX_ENTRIES;
392
363
  newEntries = newEntries.slice(overflow);
393
- newCursor = newEntries.length - 1;
394
364
  }
395
365
  // Commit the update
396
366
  const batch = new Operation_1.BatchOperation(this);
397
367
  batch.setPathValue(['payload', 'search_history'], {
398
368
  entries: newEntries,
399
- cursor: newCursor
400
369
  });
401
370
  batch.commit();
402
371
  return state;
403
372
  }
404
373
  /**
405
- * Navigates back in search history, skipping over empty entries.
406
- * @returns The search state at the new cursor position, or undefined if can't go back
374
+ * Navigates back in search history by popping the top entry.
375
+ * @returns The search state at the new top of stack, or undefined if can't go back
407
376
  */
408
377
  goBack() {
409
378
  this.checkDisposed("Device.goBack");
@@ -411,41 +380,13 @@ class Device extends Content_1.Content {
411
380
  return undefined;
412
381
  }
413
382
  const history = this.searchHistory;
414
- // Find the first non-empty entry before the cursor
415
- let newCursor = history.cursor - 1;
416
- while (newCursor >= 0 && (0, SearchState_1.isEmptySearchState)(history.entries[newCursor])) {
417
- newCursor--;
418
- }
419
- if (newCursor < 0) {
420
- return undefined;
421
- }
383
+ const newEntries = history.entries.slice(0, -1);
422
384
  const batch = new Operation_1.BatchOperation(this);
423
- batch.setPathValue(['payload', 'search_history', 'cursor'], newCursor);
424
- batch.commit();
425
- return history.entries[newCursor];
426
- }
427
- /**
428
- * Navigates forward in search history, skipping over empty entries.
429
- * @returns The search state at the new cursor position, or undefined if can't go forward
430
- */
431
- goForward() {
432
- this.checkDisposed("Device.goForward");
433
- if (!this.canGoForward) {
434
- return undefined;
435
- }
436
- const history = this.searchHistory;
437
- // Find the first non-empty entry after the cursor
438
- let newCursor = history.cursor + 1;
439
- while (newCursor < history.entries.length && (0, SearchState_1.isEmptySearchState)(history.entries[newCursor])) {
440
- newCursor++;
441
- }
442
- if (newCursor >= history.entries.length) {
443
- return undefined;
444
- }
445
- const batch = new Operation_1.BatchOperation(this);
446
- batch.setPathValue(['payload', 'search_history', 'cursor'], newCursor);
385
+ batch.setPathValue(['payload', 'search_history'], {
386
+ entries: newEntries,
387
+ });
447
388
  batch.commit();
448
- return history.entries[newCursor];
389
+ return newEntries[newEntries.length - 1];
449
390
  }
450
391
  /**
451
392
  * Clears the entire search history stack.
@@ -21,20 +21,19 @@ export interface SearchState {
21
21
  */
22
22
  export declare const SEARCH_HISTORY_MAX_ENTRIES = 50;
23
23
  /**
24
- * Search history with browser-style back/forward navigation.
24
+ * Search history as a simple stack (push/pop).
25
25
  *
26
- * - `entries`: Stack of search states
27
- * - `cursor`: Current position in the stack (0-indexed)
26
+ * - `entries`: Stack of search states, current state is the last entry
28
27
  *
29
28
  * Navigation behavior:
30
- * - Back: decrements cursor (if cursor > 0)
31
- * - Forward: increments cursor (if cursor < entries.length - 1)
32
- * - New search: discards entries after cursor, pushes new entry, cursor moves to end
29
+ * - Back: pops the last entry, returns the new top
30
+ * - New search: pushes new entry onto the end
33
31
  * - Clear: empties the entire stack
34
32
  */
35
33
  export interface SearchHistory {
36
34
  entries: SearchState[];
37
- cursor: number;
35
+ /** @deprecated No longer used — current state is always the last entry. Kept for backwards compatibility with existing persisted data. */
36
+ cursor?: number;
38
37
  }
39
38
  /**
40
39
  * Creates an empty search history.
@@ -15,7 +15,6 @@ exports.SEARCH_HISTORY_MAX_ENTRIES = 50;
15
15
  function createEmptySearchHistory() {
16
16
  return {
17
17
  entries: [],
18
- cursor: -1
19
18
  };
20
19
  }
21
20
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shaxpir/duiduidui-models",
3
- "version": "1.37.4",
3
+ "version": "1.38.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/shaxpir/duiduidui-models"