@wyxos/vibe 3.0.3 → 3.0.5

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.
package/README.md CHANGED
@@ -65,20 +65,27 @@ async function resolve({ cursor, pageSize }: VibeResolveParams): Promise<VibeRes
65
65
  </template>
66
66
  ```
67
67
 
68
- Optional auto-mode pacing props:
68
+ Optional pacing props:
69
69
 
70
70
  ```vue
71
71
  <VibeLayout
72
72
  :resolve="resolve"
73
- :fill-delay-ms="1000"
74
- :fill-delay-step-ms="250"
73
+ :fill-delay-ms="2000"
74
+ :fill-delay-step-ms="1000"
75
+ :show-end-badge="false"
76
+ :show-status-badges="false"
77
+ surface-mode="fullscreen"
75
78
  />
76
79
  ```
77
80
 
78
81
  - `fill-delay-ms`: base delay before the first chained fill request
79
82
  - `fill-delay-step-ms`: extra delay added for each additional chained fill request in the same fill cycle
83
+ - defaults: `2000` and `1000`
84
+ - `show-end-badge`: controls the fullscreen `End reached` badge when the feed is exhausted
85
+ - `show-status-badges`: controls the built-in lifecycle status overlays in list and fullscreen
86
+ - `surface-mode`: optionally lets the parent drive the desktop fullscreen/list surface explicitly
80
87
 
81
- Optional auto-mode feed strategy:
88
+ Optional feed strategy:
82
89
 
83
90
  ```vue
84
91
  <VibeLayout
@@ -90,12 +97,30 @@ Optional auto-mode feed strategy:
90
97
  - `dynamic` is the default
91
98
  - `static` reloads the current boundary cursor before advancing when the currently visible boundary page is underfilled
92
99
 
100
+ Optional seeded hydration:
101
+
102
+ ```vue
103
+ <VibeLayout
104
+ :resolve="resolve"
105
+ :initial-state="{
106
+ cursor: 'page-10',
107
+ items: restoredItems,
108
+ nextCursor: 'page-11',
109
+ previousCursor: 'page-9',
110
+ activeIndex: 4,
111
+ }"
112
+ />
113
+ ```
114
+
115
+ - use `initialState` when the app already knows a restored slice of the feed
116
+ - `resolve` is optional if you only need a seeded snapshot
117
+ - when `resolve` is present, Vibe continues paging from the seeded cursors
118
+
93
119
  ## What Vibe does
94
120
 
95
121
  - Desktop masonry list with virtualization and staged page growth
96
122
  - Fullscreen viewer with swipe, wheel, keyboard, and custom media controls
97
- - Auto-loading mode with internal pagination ownership
98
- - Controlled mode for advanced/manual integrations
123
+ - Library-owned loading and pagination, optionally seeded from `initialState`
99
124
  - Remove, restore, and undo by item `id`
100
125
  - Grid customization through slots for icons, overlays, and footer UI
101
126
  - Built-in loading and preload error states, including explicit `404` when known
@@ -129,9 +154,7 @@ Notes:
129
154
  - Grid layout prefers `preview.width/height`, then root `width/height`, then a square fallback tile
130
155
  - `other` is intentionally broad so the consuming app can layer its own subtypes and icon logic on top
131
156
 
132
- ## Loading modes
133
-
134
- ### Auto mode
157
+ ## Loading
135
158
 
136
159
  Use `resolve` when you want Vibe to own the paging loop:
137
160
 
@@ -167,7 +190,7 @@ async function resolve({ cursor, pageSize }: VibeResolveParams): Promise<VibeRes
167
190
  </template>
168
191
  ```
169
192
 
170
- In this mode, Vibe owns:
193
+ Vibe owns:
171
194
 
172
195
  - loaded items
173
196
  - active index
@@ -176,7 +199,7 @@ In this mode, Vibe owns:
176
199
  - duplicate cursor protection
177
200
  - initial retry state
178
201
 
179
- Auto mode also supports two feed strategies:
202
+ Vibe also supports two feed strategies:
180
203
 
181
204
  - `dynamic`:
182
205
  - default behavior
@@ -184,48 +207,25 @@ Auto mode also supports two feed strategies:
184
207
  - it waits `fillDelayMs`, then `fillDelayMs + fillDelayStepMs`, and so on for each chained request
185
208
  - it keeps accumulating results until the collected count reaches `pageSize` or there is no further cursor
186
209
  - then it commits that batch into the layout once
210
+ - when the trailing edge is exhausted, another bottom-edge attempt reloads the trailing cursor so newly available pages can be discovered
187
211
  - `static`:
188
212
  - before advancing at the bottom or top, Vibe checks whether the current boundary page is underfilled after local removals
189
213
  - if it is, Vibe reloads that same cursor in place first
190
214
  - only once that boundary page is full again will the next edge hit advance to the next or previous cursor
191
215
 
192
- ### Controlled mode
193
-
194
- Use controlled mode when the app needs to own item aggregation or paging policy:
216
+ You can also seed the viewer from a known snapshot:
195
217
 
196
218
  ```vue
197
- <script setup lang="ts">
198
- import { ref } from 'vue'
199
- import { VibeLayout, type VibeViewerItem } from '@wyxos/vibe'
200
-
201
- const items = ref<VibeViewerItem[]>([])
202
- const activeIndex = ref(0)
203
- const loading = ref(false)
204
- const hasNextPage = ref(true)
205
- const hasPreviousPage = ref(false)
206
-
207
- async function requestNextPage() {
208
- // app-owned fetch and append
209
- }
210
-
211
- async function requestPreviousPage() {
212
- // app-owned fetch and prepend
213
- }
214
- </script>
215
-
216
- <template>
217
- <VibeLayout
218
- :items="items"
219
- :active-index="activeIndex"
220
- :loading="loading"
221
- :has-next-page="hasNextPage"
222
- :has-previous-page="hasPreviousPage"
223
- pagination-detail="P10-12 · V11"
224
- :request-next-page="requestNextPage"
225
- :request-previous-page="requestPreviousPage"
226
- @update:active-index="activeIndex = $event"
227
- />
228
- </template>
219
+ <VibeLayout
220
+ :resolve="resolve"
221
+ :initial-state="{
222
+ cursor: 'page-10',
223
+ items: restoredItems,
224
+ nextCursor: 'page-11',
225
+ previousCursor: 'page-9',
226
+ activeIndex: 4,
227
+ }"
228
+ />
229
229
  ```
230
230
 
231
231
  ## Slots
@@ -323,14 +323,14 @@ type VibeStatus = {
323
323
  fillTargetCount: number | null
324
324
  hasNextPage: boolean
325
325
  hasPreviousPage: boolean
326
- isAutoMode: boolean
327
326
  itemCount: number
328
327
  loadState: 'failed' | 'loaded' | 'loading'
329
- mode: 'dynamic' | 'static' | null
328
+ mode: 'dynamic' | 'static'
330
329
  nextCursor: string | null
331
- phase: 'failed' | 'filling' | 'idle' | 'loading' | 'reloading'
330
+ phase: 'failed' | 'filling' | 'idle' | 'initializing' | 'loading' | 'refreshing'
332
331
  previousCursor: string | null
333
332
  removedCount: number
333
+ removedIds: readonly string[]
334
334
  surfaceMode: 'fullscreen' | 'list'
335
335
  }
336
336
  ```
@@ -341,6 +341,7 @@ Example:
341
341
  vibe.value?.remove(['item-2', 'item-5'])
342
342
  vibe.value?.undo()
343
343
  console.log(vibe.value?.status.itemCount)
344
+ console.log(vibe.value?.status.removedIds)
344
345
  ```
345
346
 
346
347
  ## Events
@@ -348,6 +349,7 @@ console.log(vibe.value?.status.itemCount)
348
349
  `VibeLayout` emits:
349
350
 
350
351
  - `update:activeIndex`
352
+ - `update:surfaceMode`
351
353
  - `asset-loads`
352
354
  - `asset-errors`
353
355
 
@@ -2,15 +2,23 @@ import type { Component } from 'vue';
2
2
  import type { VibeViewerItem } from './viewer';
3
3
  import type { VibeAssetErrorReporter, VibeAssetLoadReporter } from './viewer-core/assetErrors';
4
4
  import type { VibeFullscreenStatusSlotProps, VibeSurfaceSlotProps } from './viewer-core/surfaceSlots';
5
- import type { VibeControlledProps } from './viewer-core/useViewer';
5
+ import type { VibeLoadPhase } from './viewer-core/useViewer';
6
6
  import './viewer-core/fullscreenMediaBar.css';
7
- type __VLS_Props = VibeControlledProps & {
7
+ interface FullscreenSurfaceProps {
8
8
  active?: boolean;
9
+ activeIndex?: number;
10
+ errorMessage?: string | null;
11
+ hasNextPage?: boolean;
12
+ items: VibeViewerItem[];
13
+ loading?: boolean;
14
+ paginationDetail?: string | null;
15
+ phase?: VibeLoadPhase | null;
9
16
  reportAssetError?: VibeAssetErrorReporter | null;
10
17
  reportAssetLoad?: VibeAssetLoadReporter | null;
11
18
  showBackToList?: boolean;
19
+ showEndBadge?: boolean;
12
20
  showStatusBadges?: boolean;
13
- };
21
+ }
14
22
  type __VLS_Slots = {
15
23
  'fullscreen-aside'?: (props: VibeSurfaceSlotProps) => unknown;
16
24
  'fullscreen-header-actions'?: (props: VibeSurfaceSlotProps) => unknown;
@@ -21,18 +29,21 @@ type __VLS_Slots = {
21
29
  item: VibeViewerItem;
22
30
  }) => unknown;
23
31
  };
24
- declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
32
+ declare const __VLS_base: import("vue").DefineComponent<FullscreenSurfaceProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
25
33
  "update:activeIndex": (value: number) => any;
26
34
  "back-to-list": () => any;
27
- }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
35
+ }, string, import("vue").PublicProps, Readonly<FullscreenSurfaceProps> & Readonly<{
28
36
  "onUpdate:activeIndex"?: ((value: number) => any) | undefined;
29
37
  "onBack-to-list"?: (() => any) | undefined;
30
38
  }>, {
31
39
  loading: boolean;
32
- activeIndex: number;
33
- hasNextPage: boolean;
34
40
  paginationDetail: string | null;
41
+ showEndBadge: boolean;
35
42
  showStatusBadges: boolean;
43
+ activeIndex: number;
44
+ errorMessage: string | null;
45
+ hasNextPage: boolean;
46
+ phase: VibeLoadPhase | null;
36
47
  showBackToList: boolean;
37
48
  active: boolean;
38
49
  reportAssetError: VibeAssetErrorReporter | null;
@@ -1,12 +1,13 @@
1
1
  import { type Component } from 'vue';
2
2
  import type { VibeViewerItem } from './viewer';
3
- import type { VibeEmptyStateSlotProps, VibeFullscreenStatusSlotProps, VibeGridStatusSlotProps, VibeSurfaceSlotProps } from './viewer-core/surfaceSlots';
3
+ import { type VibeAssetErrorEvent, type VibeAssetLoadEvent } from './viewer-core/assetErrors';
4
+ import type { VibeFullscreenStatusSlotProps, VibeGridStatusSlotProps, VibeSurfaceSlotProps } from './viewer-core/surfaceSlots';
5
+ import type { VibeHandle, VibeProps } from './viewer-core/useViewer';
4
6
  type __VLS_Slots = {
5
7
  'fullscreen-aside'?: (props: VibeSurfaceSlotProps) => unknown;
6
8
  'fullscreen-header-actions'?: (props: VibeSurfaceSlotProps) => unknown;
7
9
  'fullscreen-overlay'?: (props: VibeSurfaceSlotProps) => unknown;
8
10
  'fullscreen-status'?: (props: VibeFullscreenStatusSlotProps) => unknown;
9
- 'empty-state'?: (props: VibeEmptyStateSlotProps) => unknown;
10
11
  'grid-footer'?: () => unknown;
11
12
  'grid-item-overlay'?: (props: {
12
13
  active: boolean;
@@ -22,7 +23,17 @@ type __VLS_Slots = {
22
23
  item: VibeViewerItem;
23
24
  }) => unknown;
24
25
  };
25
- declare const __VLS_base: import("vue").DefineSetupFnComponent<Record<string, any>, {}, {}, Record<string, any> & {}, import("vue").PublicProps>;
26
+ declare const __VLS_base: import("vue").DefineComponent<VibeProps, VibeHandle, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
27
+ "update:activeIndex": (value: number) => any;
28
+ "update:surfaceMode": (value: "fullscreen" | "list") => any;
29
+ "asset-errors": (errors: VibeAssetErrorEvent[]) => any;
30
+ "asset-loads": (loads: VibeAssetLoadEvent[]) => any;
31
+ }, string, import("vue").PublicProps, Readonly<VibeProps> & Readonly<{
32
+ "onUpdate:activeIndex"?: ((value: number) => any) | undefined;
33
+ "onUpdate:surfaceMode"?: ((value: "fullscreen" | "list") => any) | undefined;
34
+ "onAsset-errors"?: ((errors: VibeAssetErrorEvent[]) => any) | undefined;
35
+ "onAsset-loads"?: ((loads: VibeAssetLoadEvent[]) => any) | undefined;
36
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
26
37
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
27
38
  declare const _default: typeof __VLS_export;
28
39
  export default _default;
@@ -1,10 +1,8 @@
1
1
  import type { Component } from 'vue';
2
2
  import type { VibeViewerItem } from './viewer';
3
3
  import type { VibeAssetErrorReporter, VibeAssetLoadReporter } from './viewer-core/assetErrors';
4
- import { type VibeAssetLoadQueue } from './viewer-core/useAssetLoadQueue';
5
4
  type __VLS_Props = {
6
5
  active?: boolean;
7
- assetLoadQueue?: VibeAssetLoadQueue | null;
8
6
  index?: number;
9
7
  item: VibeViewerItem;
10
8
  reportAssetError?: VibeAssetErrorReporter | null;
@@ -34,7 +32,6 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
34
32
  reportAssetError: VibeAssetErrorReporter | null;
35
33
  reportAssetLoad: VibeAssetLoadReporter | null;
36
34
  index: number;
37
- assetLoadQueue: VibeAssetLoadQueue | null;
38
35
  surfaceActive: boolean;
39
36
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
40
37
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -2,23 +2,24 @@ import type { Component } from 'vue';
2
2
  import type { VibeViewerItem } from './viewer';
3
3
  import type { VibeAssetErrorReporter, VibeAssetLoadReporter } from './viewer-core/assetErrors';
4
4
  import type { VibeGridStatusSlotProps } from './viewer-core/surfaceSlots';
5
- import type { VibeAssetLoadQueue } from './viewer-core/useAssetLoadQueue';
5
+ import type { VibeLoadPhase } from './viewer-core/useViewer';
6
6
  type __VLS_Props = {
7
7
  active?: boolean;
8
8
  activeIndex?: number;
9
- assetLoadQueue?: VibeAssetLoadQueue | null;
9
+ allowExhaustedNextPageRefresh?: boolean;
10
10
  commitPendingAppend?: (() => void | Promise<void>) | null;
11
+ errorMessage?: string | null;
11
12
  hasNextPage?: boolean;
12
13
  hasPreviousPage?: boolean;
13
14
  items: VibeViewerItem[];
14
15
  loading?: boolean;
15
16
  pendingAppendItems?: VibeViewerItem[];
16
17
  paginationDetail?: string | null;
18
+ phase?: VibeLoadPhase | null;
17
19
  reportAssetError?: VibeAssetErrorReporter | null;
18
20
  reportAssetLoad?: VibeAssetLoadReporter | null;
19
21
  requestNextPage?: (() => void | Promise<void>) | null;
20
22
  requestPreviousPage?: (() => void | Promise<void>) | null;
21
- restoreToken: number;
22
23
  showStatusBadges?: boolean;
23
24
  };
24
25
  type __VLS_Slots = {
@@ -45,19 +46,21 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
45
46
  "onOpen-fullscreen"?: ((index: number) => any) | undefined;
46
47
  }>, {
47
48
  loading: boolean;
49
+ paginationDetail: string | null;
50
+ showStatusBadges: boolean;
48
51
  activeIndex: number;
52
+ errorMessage: string | null;
49
53
  hasNextPage: boolean;
54
+ phase: VibeLoadPhase | null;
50
55
  hasPreviousPage: boolean;
51
- paginationDetail: string | null;
52
- requestNextPage: (() => void | Promise<void>) | null;
53
- requestPreviousPage: (() => void | Promise<void>) | null;
54
- showStatusBadges: boolean;
55
56
  active: boolean;
56
57
  reportAssetError: VibeAssetErrorReporter | null;
57
58
  reportAssetLoad: VibeAssetLoadReporter | null;
58
- assetLoadQueue: VibeAssetLoadQueue | null;
59
+ allowExhaustedNextPageRefresh: boolean;
59
60
  commitPendingAppend: (() => void | Promise<void>) | null;
60
61
  pendingAppendItems: VibeViewerItem[];
62
+ requestNextPage: (() => void | Promise<void>) | null;
63
+ requestPreviousPage: (() => void | Promise<void>) | null;
61
64
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
62
65
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
63
66
  declare const _default: typeof __VLS_export;
@@ -13,7 +13,7 @@ export type ResolveFn = (params: {
13
13
  previousPage?: string | null;
14
14
  }>;
15
15
  export type VibeAutoDirection = 'backward' | 'forward';
16
- export declare function isActiveLoadPhase(phase: VibeLoadPhase): phase is "filling" | "loading" | "reloading";
16
+ export declare function isActiveLoadPhase(phase: VibeLoadPhase): phase is "filling" | "initializing" | "refreshing" | "loading";
17
17
  export declare function normalizePageSize(value: number | undefined): number;
18
18
  export declare function getCursorKey(cursor: string | null): string;
19
19
  export declare function clamp(value: number, min: number, max: number): number;
@@ -1,5 +1,5 @@
1
- export declare const DEFAULT_DYNAMIC_FILL_DELAY_MS = 1000;
2
- export declare const DEFAULT_DYNAMIC_FILL_DELAY_STEP_MS = 250;
1
+ export declare const DEFAULT_DYNAMIC_FILL_DELAY_MS = 2000;
2
+ export declare const DEFAULT_DYNAMIC_FILL_DELAY_STEP_MS = 1000;
3
3
  export declare function getDynamicFillDelayMs(fillRequestIndex: number, baseDelayMs?: number, stepDelayMs?: number): number;
4
4
  export declare function normalizeDynamicFillDelayMs(value: number | undefined, fallback: number): number;
5
5
  export declare function useFillDelayCountdown(): {
@@ -2,7 +2,7 @@ export interface VibeRemoveResult {
2
2
  ids: string[];
3
3
  }
4
4
  export type VibeFeedMode = 'dynamic' | 'static';
5
- export type VibeLoadPhase = 'failed' | 'filling' | 'idle' | 'loading' | 'reloading';
5
+ export type VibeLoadPhase = 'failed' | 'filling' | 'idle' | 'initializing' | 'loading' | 'refreshing';
6
6
  export type VibeSurfaceMode = 'fullscreen' | 'list';
7
7
  export interface VibeStatus {
8
8
  activeIndex: number;
@@ -13,14 +13,14 @@ export interface VibeStatus {
13
13
  fillTargetCount: number | null;
14
14
  hasNextPage: boolean;
15
15
  hasPreviousPage: boolean;
16
- isAutoMode: boolean;
17
16
  itemCount: number;
18
17
  loadState: 'failed' | 'loaded' | 'loading';
19
- mode: VibeFeedMode | null;
18
+ mode: VibeFeedMode;
20
19
  nextCursor: string | null;
21
20
  phase: VibeLoadPhase;
22
21
  previousCursor: string | null;
23
22
  removedCount: number;
23
+ removedIds: readonly string[];
24
24
  surfaceMode: VibeSurfaceMode;
25
25
  }
26
26
  export interface VibeHandle {
@@ -7,7 +7,7 @@ export type VibeSurfaceSlotProps = {
7
7
  paginationDetail: string | null;
8
8
  total: number;
9
9
  };
10
- export type VibeSurfaceStatusKind = 'end' | 'loading-more';
10
+ export type VibeSurfaceStatusKind = 'end' | 'failed' | 'filling' | 'initializing' | 'loading-more' | 'refreshing';
11
11
  export type VibeFullscreenStatusSlotProps = VibeSurfaceSlotProps & {
12
12
  kind: VibeSurfaceStatusKind;
13
13
  message: string;
@@ -20,8 +20,3 @@ export type VibeGridStatusSlotProps = {
20
20
  paginationDetail: string | null;
21
21
  total: number;
22
22
  };
23
- export type VibeEmptyStateSlotProps = {
24
- canRetry: boolean;
25
- loading: boolean;
26
- retry: () => void | Promise<void>;
27
- };
@@ -0,0 +1,18 @@
1
+ import type { VibeLoadPhase } from './removalState';
2
+ import type { VibeSurfaceStatusKind } from './surfaceSlots';
3
+ export interface VibeSurfaceStatus {
4
+ kind: VibeSurfaceStatusKind;
5
+ message: string;
6
+ }
7
+ export declare function resolveVibeSurfacePhase(options: {
8
+ itemCount: number;
9
+ loading: boolean;
10
+ phase?: VibeLoadPhase | null;
11
+ }): VibeLoadPhase;
12
+ export declare function getVibeSurfaceStatus(options: {
13
+ errorMessage?: string | null;
14
+ hasItems: boolean;
15
+ hasNextPage: boolean;
16
+ phase: VibeLoadPhase;
17
+ surface: 'fullscreen' | 'grid';
18
+ }): VibeSurfaceStatus | null;
@@ -14,10 +14,9 @@ export interface VibeAssetLoadLease {
14
14
  refresh: () => void;
15
15
  release: () => void;
16
16
  }
17
- export interface VibeAssetLoadQueue {
18
- getLimits: () => VibeAssetLoadQueueLimits;
17
+ export declare function createAssetLoadQueue(limits?: VibeAssetLoadQueueLimits): {
19
18
  request: (options: VibeAssetLoadRequest) => VibeAssetLoadLease;
20
- setLimits: (limits?: Partial<VibeAssetLoadQueueLimits> | null) => void;
21
- }
22
- export declare function resolveAssetLoadQueueLimits(limits?: Partial<VibeAssetLoadQueueLimits> | null): VibeAssetLoadQueueLimits;
23
- export declare function createAssetLoadQueue(initialLimits?: Partial<VibeAssetLoadQueueLimits> | null): VibeAssetLoadQueue;
19
+ };
20
+ export declare const defaultAssetLoadQueue: {
21
+ request: (options: VibeAssetLoadRequest) => VibeAssetLoadLease;
22
+ };
@@ -23,6 +23,7 @@ export declare function useAutoResolveSource(options: {
23
23
  activeIndex: import("vue").ComputedRef<number>;
24
24
  canRetryInitialLoad: import("vue").ComputedRef<boolean>;
25
25
  cancel: () => void;
26
+ canRefreshTrailingBoundary: import("vue").ComputedRef<boolean>;
26
27
  commitPendingAppend: () => Promise<void>;
27
28
  currentCursor: import("vue").ComputedRef<string | null>;
28
29
  errorMessage: Ref<string | null, string | null>;
@@ -1,11 +1,9 @@
1
1
  import type { VibeSurfaceMode } from './removalState';
2
2
  import { type VibeEmit, type VibeProps } from './useDataSource';
3
3
  export declare const DESKTOP_BREAKPOINT_PX = 1024;
4
- type VibeControllerEmit = VibeEmit & ((event: 'update:surfaceMode', value: VibeSurfaceMode) => void);
5
- export declare function useController(props: Readonly<VibeProps>, emit: VibeControllerEmit): {
4
+ export declare function useController(props: Readonly<VibeProps>, emit: VibeEmit): {
6
5
  cancel: () => void;
7
6
  isDesktop: import("vue").ComputedRef<boolean>;
8
- listRestoreToken: import("vue").Ref<number, number>;
9
7
  loadNext: () => Promise<void>;
10
8
  loadPrevious: () => Promise<void>;
11
9
  openFullscreen: (index: number) => void;
@@ -21,37 +19,37 @@ export declare function useController(props: Readonly<VibeProps>, emit: VibeCont
21
19
  readonly fillTargetCount: number | null;
22
20
  readonly hasNextPage: boolean;
23
21
  readonly hasPreviousPage: boolean;
24
- readonly isAutoMode: boolean;
25
22
  readonly itemCount: number;
26
23
  readonly loadState: "failed" | "loaded" | "loading";
27
- readonly mode: import("./removalState").VibeFeedMode | null;
24
+ readonly mode: import("./removalState").VibeFeedMode;
28
25
  readonly nextCursor: string | null;
29
26
  readonly phase: import("./removalState").VibeLoadPhase;
30
27
  readonly previousCursor: string | null;
31
28
  readonly removedCount: number;
29
+ readonly removedIds: readonly string[];
32
30
  readonly surfaceMode: VibeSurfaceMode;
33
31
  };
34
32
  surfaceMode: import("vue").ComputedRef<VibeSurfaceMode>;
35
33
  activeIndex: import("vue").ComputedRef<number>;
34
+ canRefreshExhaustedNextPage: import("vue").ComputedRef<boolean>;
36
35
  canRetryInitialLoad: import("vue").ComputedRef<boolean>;
37
36
  clearRemoved: () => void;
38
37
  commitPendingAppend: () => Promise<void>;
39
38
  currentCursor: import("vue").ComputedRef<string | null>;
40
- errorMessage: import("vue").ComputedRef<string | null>;
41
- fillCollectedCount: import("vue").ComputedRef<number | null>;
42
- fillDelayRemainingMs: import("vue").ComputedRef<number | null>;
43
- fillTargetCount: import("vue").ComputedRef<number | null>;
39
+ errorMessage: import("vue").Ref<string | null, string | null>;
40
+ fillCollectedCount: import("vue").Ref<number | null, number | null>;
41
+ fillDelayRemainingMs: import("vue").Ref<number | null, number | null>;
42
+ fillTargetCount: import("vue").Ref<number | null, number | null>;
44
43
  getRemovedIds: () => string[];
45
44
  hasNextPage: import("vue").ComputedRef<boolean>;
46
45
  hasPreviousPage: import("vue").ComputedRef<boolean>;
47
- isAutoMode: import("vue").ComputedRef<boolean>;
48
46
  items: import("vue").ComputedRef<import("../viewer").VibeViewerItem[]>;
49
47
  loading: import("vue").ComputedRef<boolean>;
50
- mode: import("vue").ComputedRef<import("./removalState").VibeFeedMode | null>;
48
+ mode: import("vue").ComputedRef<import("./removalState").VibeFeedMode>;
51
49
  nextCursor: import("vue").ComputedRef<string | null>;
52
50
  paginationDetail: import("vue").ComputedRef<string | null>;
53
51
  pendingAppendItems: import("vue").ComputedRef<import("../viewer").VibeViewerItem[]>;
54
- phase: import("vue").ComputedRef<import("./removalState").VibeLoadPhase>;
52
+ phase: import("vue").Ref<import("./removalState").VibeLoadPhase, import("./removalState").VibeLoadPhase>;
55
53
  prefetchNextPage: () => Promise<void>;
56
54
  prefetchPreviousPage: () => Promise<void>;
57
55
  previousCursor: import("vue").ComputedRef<string | null>;
@@ -69,4 +67,3 @@ export declare function useController(props: Readonly<VibeProps>, emit: VibeCont
69
67
  ids: string[];
70
68
  } | null;
71
69
  };
72
- export {};
@@ -1,8 +1,6 @@
1
1
  import type { VibeViewerItem } from '../viewer';
2
- import { type VibeSurfaceMode } from './removalState';
3
- import type { VibeAssetLoadQueueLimits } from './useAssetLoadQueue';
4
2
  export type { VibeHandle, VibeRemoveResult } from './removalState';
5
- export type { VibeFeedMode, VibeLoadPhase } from './removalState';
3
+ export type { VibeFeedMode, VibeLoadPhase, VibeSurfaceMode } from './removalState';
6
4
  export interface VibeResolveParams {
7
5
  cursor: string | null;
8
6
  pageSize: number;
@@ -20,71 +18,47 @@ export interface VibeInitialState {
20
18
  previousCursor?: string | null;
21
19
  activeIndex?: number;
22
20
  }
23
- interface VibeSharedProps {
24
- assetLoadLimits?: Partial<VibeAssetLoadQueueLimits>;
25
- hasPreviousPage?: boolean;
26
- paginationDetail?: string | null;
27
- requestNextPage?: (() => void | Promise<void>) | null;
28
- requestPreviousPage?: (() => void | Promise<void>) | null;
29
- showStatusBadges?: boolean;
30
- surfaceMode?: VibeSurfaceMode;
31
- }
32
- export interface VibeControlledProps extends VibeSharedProps {
33
- items: VibeViewerItem[];
34
- activeIndex?: number;
35
- fillDelayMs?: never;
36
- fillDelayStepMs?: never;
37
- initialState?: never;
38
- loading?: boolean;
39
- hasNextPage?: boolean;
40
- mode?: never;
41
- resolve?: never;
42
- initialCursor?: never;
43
- pageSize?: never;
44
- }
45
- export interface VibeAutoProps extends VibeSharedProps {
46
- resolve: (params: VibeResolveParams) => Promise<VibeResolveResult>;
21
+ export interface VibeProps {
47
22
  fillDelayMs?: number;
48
23
  fillDelayStepMs?: number;
49
24
  initialCursor?: string | null;
50
25
  initialState?: VibeInitialState;
51
26
  mode?: import('./removalState').VibeFeedMode;
52
27
  pageSize?: number;
53
- items?: never;
54
- activeIndex?: never;
55
- hasPreviousPage?: never;
56
- loading?: never;
57
- hasNextPage?: never;
58
- paginationDetail?: never;
59
- requestNextPage?: never;
60
- requestPreviousPage?: never;
28
+ paginationDetail?: string | null;
29
+ resolve?: (params: VibeResolveParams) => Promise<VibeResolveResult>;
30
+ showEndBadge?: boolean;
31
+ showStatusBadges?: boolean;
32
+ surfaceMode?: import('./removalState').VibeSurfaceMode;
33
+ }
34
+ export interface VibeEmit {
35
+ (event: 'update:activeIndex', value: number): void;
36
+ (event: 'update:surfaceMode', value: import('./removalState').VibeSurfaceMode): void;
61
37
  }
62
- export type VibeProps = VibeControlledProps | VibeAutoProps;
63
- export type VibeEmit = (event: 'update:activeIndex', value: number) => void;
64
38
  export declare function useDataSource(props: Readonly<VibeProps>, emit: VibeEmit): {
65
39
  activeIndex: import("vue").ComputedRef<number>;
40
+ canRefreshExhaustedNextPage: import("vue").ComputedRef<boolean>;
66
41
  canRetryInitialLoad: import("vue").ComputedRef<boolean>;
67
42
  cancel: () => void;
68
43
  clearRemoved: () => void;
69
44
  commitPendingAppend: () => Promise<void>;
70
45
  currentCursor: import("vue").ComputedRef<string | null>;
71
- errorMessage: import("vue").ComputedRef<string | null>;
72
- fillCollectedCount: import("vue").ComputedRef<number | null>;
73
- fillDelayRemainingMs: import("vue").ComputedRef<number | null>;
74
- fillTargetCount: import("vue").ComputedRef<number | null>;
46
+ errorMessage: import("vue").Ref<string | null, string | null>;
47
+ fillCollectedCount: import("vue").Ref<number | null, number | null>;
48
+ fillDelayRemainingMs: import("vue").Ref<number | null, number | null>;
49
+ fillTargetCount: import("vue").Ref<number | null, number | null>;
75
50
  getRemovedIds: () => string[];
76
51
  hasNextPage: import("vue").ComputedRef<boolean>;
77
52
  hasPreviousPage: import("vue").ComputedRef<boolean>;
78
- isAutoMode: import("vue").ComputedRef<boolean>;
79
53
  items: import("vue").ComputedRef<VibeViewerItem[]>;
80
54
  loading: import("vue").ComputedRef<boolean>;
81
55
  loadNext: () => Promise<void>;
82
56
  loadPrevious: () => Promise<void>;
83
- mode: import("vue").ComputedRef<import("./removalState").VibeFeedMode | null>;
57
+ mode: import("vue").ComputedRef<import("./removalState").VibeFeedMode>;
84
58
  nextCursor: import("vue").ComputedRef<string | null>;
85
59
  paginationDetail: import("vue").ComputedRef<string | null>;
86
60
  pendingAppendItems: import("vue").ComputedRef<VibeViewerItem[]>;
87
- phase: import("vue").ComputedRef<import("./removalState").VibeLoadPhase>;
61
+ phase: import("vue").Ref<import("./removalState").VibeLoadPhase, import("./removalState").VibeLoadPhase>;
88
62
  prefetchNextPage: () => Promise<void>;
89
63
  prefetchPreviousPage: () => Promise<void>;
90
64
  previousCursor: import("vue").ComputedRef<string | null>;
@@ -2,6 +2,7 @@ import { type Ref } from 'vue';
2
2
  import type { VibeViewerItem } from '../viewer';
3
3
  export declare function useVibeMasonryList(options: {
4
4
  active: Ref<boolean>;
5
+ allowExhaustedNextPageRefresh: Ref<boolean>;
5
6
  items: Ref<VibeViewerItem[]>;
6
7
  activeIndex: Ref<number>;
7
8
  loading: Ref<boolean>;
@@ -12,12 +13,10 @@ export declare function useVibeMasonryList(options: {
12
13
  commitPendingAppend: Ref<(() => void | Promise<void>) | null | undefined>;
13
14
  requestNextPage: Ref<(() => void | Promise<void>) | null | undefined>;
14
15
  requestPreviousPage: Ref<(() => void | Promise<void>) | null | undefined>;
15
- restoreToken: Ref<number>;
16
16
  setActiveIndex: (index: number) => void;
17
17
  }): {
18
18
  columnWidth: import("vue").ComputedRef<number>;
19
19
  containerHeight: import("vue").ComputedRef<number>;
20
- footerStatusMessage: import("vue").ComputedRef<"Loading the first page" | "Loading more items" | "End of list" | null>;
21
20
  getCardStyle: (index: number) => {
22
21
  height: string;
23
22
  width: string;