viberag 0.3.2 → 0.4.0
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 +2 -2
- package/dist/cli/app.d.ts +3 -0
- package/dist/cli/app.js +100 -102
- package/dist/cli/commands/handlers.d.ts +8 -6
- package/dist/cli/commands/handlers.js +90 -32
- package/dist/cli/commands/useCommands.d.ts +20 -0
- package/dist/cli/commands/useCommands.js +189 -0
- package/dist/cli/commands/useRagCommands.d.ts +2 -5
- package/dist/cli/commands/useRagCommands.js +11 -18
- package/dist/cli/components/InitWizard.js +66 -27
- package/dist/cli/components/McpSetupWizard.js +23 -4
- package/dist/cli/components/SlotRow.d.ts +22 -0
- package/dist/cli/components/SlotRow.js +55 -0
- package/dist/cli/components/StatusBar.d.ts +14 -0
- package/dist/cli/components/StatusBar.js +156 -0
- package/dist/cli/contexts/DaemonStatusContext.d.ts +38 -0
- package/dist/cli/contexts/DaemonStatusContext.js +106 -0
- package/dist/cli/hooks/useStatusPolling.d.ts +34 -0
- package/dist/cli/hooks/useStatusPolling.js +121 -0
- package/dist/cli/store/app/selectors.d.ts +87 -0
- package/dist/cli/store/app/selectors.js +28 -0
- package/dist/cli/store/app/slice.d.ts +1013 -0
- package/dist/cli/store/app/slice.js +112 -0
- package/dist/cli/store/hooks.d.ts +22 -0
- package/dist/cli/store/hooks.js +17 -0
- package/dist/cli/store/store.d.ts +17 -0
- package/dist/cli/store/store.js +18 -0
- package/dist/cli/store/wizard/selectors.d.ts +115 -0
- package/dist/cli/store/wizard/selectors.js +36 -0
- package/dist/cli/store/wizard/slice.d.ts +523 -0
- package/dist/cli/store/wizard/slice.js +119 -0
- package/dist/cli/utils/error-handler.d.ts +55 -0
- package/dist/cli/utils/error-handler.js +92 -0
- package/dist/client/auto-start.d.ts +42 -0
- package/dist/client/auto-start.js +250 -0
- package/dist/client/connection.d.ts +48 -0
- package/dist/client/connection.js +200 -0
- package/dist/client/index.d.ts +93 -0
- package/dist/client/index.js +209 -0
- package/dist/client/types.d.ts +105 -0
- package/dist/client/types.js +7 -0
- package/dist/common/components/SlotRow.d.ts +22 -0
- package/dist/common/components/SlotRow.js +53 -0
- package/dist/common/components/StatusBar.js +82 -31
- package/dist/common/types.d.ts +12 -13
- package/dist/daemon/handlers.d.ts +15 -0
- package/dist/daemon/handlers.js +157 -0
- package/dist/daemon/index.d.ts +21 -0
- package/dist/daemon/index.js +123 -0
- package/dist/daemon/lib/chunker/bounded-channel.d.ts +51 -0
- package/dist/daemon/lib/chunker/bounded-channel.js +138 -0
- package/dist/daemon/lib/chunker/index.d.ts +135 -0
- package/dist/daemon/lib/chunker/index.js +1370 -0
- package/dist/daemon/lib/chunker/types.d.ts +77 -0
- package/dist/daemon/lib/chunker/types.js +50 -0
- package/dist/daemon/lib/config.d.ts +73 -0
- package/dist/daemon/lib/config.js +149 -0
- package/dist/daemon/lib/constants.d.ts +75 -0
- package/dist/daemon/lib/constants.js +114 -0
- package/dist/daemon/lib/gitignore.d.ts +57 -0
- package/dist/daemon/lib/gitignore.js +246 -0
- package/dist/daemon/lib/logger.d.ts +51 -0
- package/dist/daemon/lib/logger.js +167 -0
- package/dist/daemon/lib/manifest.d.ts +58 -0
- package/dist/daemon/lib/manifest.js +116 -0
- package/dist/daemon/lib/merkle/diff.d.ts +32 -0
- package/dist/daemon/lib/merkle/diff.js +107 -0
- package/dist/daemon/lib/merkle/hash.d.ts +40 -0
- package/dist/daemon/lib/merkle/hash.js +180 -0
- package/dist/daemon/lib/merkle/index.d.ts +71 -0
- package/dist/daemon/lib/merkle/index.js +309 -0
- package/dist/daemon/lib/merkle/node.d.ts +55 -0
- package/dist/daemon/lib/merkle/node.js +82 -0
- package/dist/daemon/lifecycle.d.ts +50 -0
- package/dist/daemon/lifecycle.js +142 -0
- package/dist/daemon/owner.d.ts +175 -0
- package/dist/daemon/owner.js +609 -0
- package/dist/daemon/protocol.d.ts +100 -0
- package/dist/daemon/protocol.js +163 -0
- package/dist/daemon/providers/api-utils.d.ts +130 -0
- package/dist/daemon/providers/api-utils.js +248 -0
- package/dist/daemon/providers/gemini.d.ts +39 -0
- package/dist/daemon/providers/gemini.js +205 -0
- package/dist/daemon/providers/index.d.ts +14 -0
- package/dist/daemon/providers/index.js +14 -0
- package/dist/daemon/providers/local-4b.d.ts +28 -0
- package/dist/daemon/providers/local-4b.js +51 -0
- package/dist/daemon/providers/local.d.ts +36 -0
- package/dist/daemon/providers/local.js +166 -0
- package/dist/daemon/providers/mistral.d.ts +35 -0
- package/dist/daemon/providers/mistral.js +160 -0
- package/dist/daemon/providers/mock.d.ts +35 -0
- package/dist/daemon/providers/mock.js +69 -0
- package/dist/daemon/providers/openai.d.ts +41 -0
- package/dist/daemon/providers/openai.js +190 -0
- package/dist/daemon/providers/types.d.ts +68 -0
- package/dist/daemon/providers/types.js +6 -0
- package/dist/daemon/providers/validate.d.ts +30 -0
- package/dist/daemon/providers/validate.js +162 -0
- package/dist/daemon/server.d.ts +79 -0
- package/dist/daemon/server.js +293 -0
- package/dist/daemon/services/index.d.ts +11 -0
- package/dist/daemon/services/index.js +16 -0
- package/dist/daemon/services/indexing.d.ts +117 -0
- package/dist/daemon/services/indexing.js +573 -0
- package/dist/daemon/services/search/filters.d.ts +21 -0
- package/dist/daemon/services/search/filters.js +106 -0
- package/dist/daemon/services/search/fts.d.ts +32 -0
- package/dist/daemon/services/search/fts.js +61 -0
- package/dist/daemon/services/search/hybrid.d.ts +17 -0
- package/dist/daemon/services/search/hybrid.js +58 -0
- package/dist/daemon/services/search/index.d.ts +108 -0
- package/dist/daemon/services/search/index.js +417 -0
- package/dist/daemon/services/search/types.d.ts +126 -0
- package/dist/daemon/services/search/types.js +4 -0
- package/dist/daemon/services/search/vector.d.ts +25 -0
- package/dist/daemon/services/search/vector.js +44 -0
- package/dist/daemon/services/storage/index.d.ts +110 -0
- package/dist/daemon/services/storage/index.js +378 -0
- package/dist/daemon/services/storage/schema.d.ts +24 -0
- package/dist/daemon/services/storage/schema.js +51 -0
- package/dist/daemon/services/storage/types.d.ts +105 -0
- package/dist/daemon/services/storage/types.js +71 -0
- package/dist/daemon/services/types.d.ts +192 -0
- package/dist/daemon/services/types.js +53 -0
- package/dist/daemon/services/watcher.d.ts +98 -0
- package/dist/daemon/services/watcher.js +386 -0
- package/dist/daemon/state.d.ts +119 -0
- package/dist/daemon/state.js +161 -0
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +44 -60
- package/dist/mcp/server.d.ts +10 -14
- package/dist/mcp/server.js +75 -74
- package/dist/mcp/services/lazy-loader.d.ts +23 -0
- package/dist/mcp/services/lazy-loader.js +34 -0
- package/dist/mcp/warmup.d.ts +3 -3
- package/dist/mcp/warmup.js +39 -40
- package/dist/mcp/watcher.d.ts +5 -7
- package/dist/mcp/watcher.js +73 -64
- package/dist/rag/config/index.d.ts +2 -0
- package/dist/rag/constants.d.ts +30 -0
- package/dist/rag/constants.js +38 -0
- package/dist/rag/embeddings/api-utils.d.ts +121 -0
- package/dist/rag/embeddings/api-utils.js +259 -0
- package/dist/rag/embeddings/gemini.d.ts +4 -12
- package/dist/rag/embeddings/gemini.js +22 -72
- package/dist/rag/embeddings/index.d.ts +5 -3
- package/dist/rag/embeddings/index.js +5 -2
- package/dist/rag/embeddings/local-4b.d.ts +2 -2
- package/dist/rag/embeddings/local-4b.js +1 -1
- package/dist/rag/embeddings/local.d.ts +10 -3
- package/dist/rag/embeddings/local.js +58 -12
- package/dist/rag/embeddings/mistral.d.ts +4 -12
- package/dist/rag/embeddings/mistral.js +22 -72
- package/dist/rag/embeddings/mock.d.ts +35 -0
- package/dist/rag/embeddings/mock.js +69 -0
- package/dist/rag/embeddings/openai.d.ts +11 -13
- package/dist/rag/embeddings/openai.js +47 -75
- package/dist/rag/embeddings/types.d.ts +27 -1
- package/dist/rag/embeddings/validate.d.ts +9 -1
- package/dist/rag/embeddings/validate.js +17 -4
- package/dist/rag/index.d.ts +2 -2
- package/dist/rag/index.js +1 -1
- package/dist/rag/indexer/bounded-channel.d.ts +51 -0
- package/dist/rag/indexer/bounded-channel.js +138 -0
- package/dist/rag/indexer/indexer.d.ts +4 -14
- package/dist/rag/indexer/indexer.js +246 -169
- package/dist/rag/indexer/types.d.ts +1 -0
- package/dist/rag/logger/index.d.ts +22 -0
- package/dist/rag/logger/index.js +78 -1
- package/dist/rag/manifest/index.js +1 -2
- package/dist/rag/search/index.js +1 -1
- package/dist/rag/storage/schema.d.ts +2 -4
- package/dist/rag/storage/schema.js +3 -5
- package/dist/store/app/selectors.d.ts +87 -0
- package/dist/store/app/selectors.js +28 -0
- package/dist/store/app/slice.d.ts +1013 -0
- package/dist/store/app/slice.js +112 -0
- package/dist/store/hooks.d.ts +22 -0
- package/dist/store/hooks.js +17 -0
- package/dist/store/index.d.ts +12 -0
- package/dist/store/index.js +18 -0
- package/dist/store/indexing/listeners.d.ts +25 -0
- package/dist/store/indexing/listeners.js +46 -0
- package/dist/store/indexing/selectors.d.ts +195 -0
- package/dist/store/indexing/selectors.js +69 -0
- package/dist/store/indexing/slice.d.ts +309 -0
- package/dist/store/indexing/slice.js +113 -0
- package/dist/store/slot-progress/listeners.d.ts +23 -0
- package/dist/store/slot-progress/listeners.js +33 -0
- package/dist/store/slot-progress/selectors.d.ts +67 -0
- package/dist/store/slot-progress/selectors.js +36 -0
- package/dist/store/slot-progress/slice.d.ts +246 -0
- package/dist/store/slot-progress/slice.js +70 -0
- package/dist/store/store.d.ts +17 -0
- package/dist/store/store.js +18 -0
- package/dist/store/warmup/selectors.d.ts +109 -0
- package/dist/store/warmup/selectors.js +44 -0
- package/dist/store/warmup/slice.d.ts +137 -0
- package/dist/store/warmup/slice.js +72 -0
- package/dist/store/watcher/selectors.d.ts +115 -0
- package/dist/store/watcher/selectors.js +52 -0
- package/dist/store/watcher/slice.d.ts +269 -0
- package/dist/store/watcher/slice.js +100 -0
- package/dist/store/wizard/selectors.d.ts +115 -0
- package/dist/store/wizard/selectors.js +36 -0
- package/dist/store/wizard/slice.d.ts +523 -0
- package/dist/store/wizard/slice.js +119 -0
- package/package.json +10 -2
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Redux slice for warmup state.
|
|
3
|
+
*
|
|
4
|
+
* Manages the state of the embedding provider warmup process.
|
|
5
|
+
* The WarmupManager dispatches actions to this slice to track status.
|
|
6
|
+
*/
|
|
7
|
+
import { createSlice } from '@reduxjs/toolkit';
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Initial State
|
|
10
|
+
// ============================================================================
|
|
11
|
+
const initialState = {
|
|
12
|
+
status: 'not_started',
|
|
13
|
+
provider: null,
|
|
14
|
+
startedAt: null,
|
|
15
|
+
readyAt: null,
|
|
16
|
+
elapsedMs: null,
|
|
17
|
+
error: null,
|
|
18
|
+
};
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// Slice
|
|
21
|
+
// ============================================================================
|
|
22
|
+
export const warmupSlice = createSlice({
|
|
23
|
+
name: 'warmup',
|
|
24
|
+
initialState,
|
|
25
|
+
reducers: {
|
|
26
|
+
/**
|
|
27
|
+
* Project is not initialized.
|
|
28
|
+
*/
|
|
29
|
+
setNotInitialized: state => {
|
|
30
|
+
state.status = 'not_initialized';
|
|
31
|
+
state.provider = null;
|
|
32
|
+
state.startedAt = null;
|
|
33
|
+
state.readyAt = null;
|
|
34
|
+
state.elapsedMs = null;
|
|
35
|
+
state.error = null;
|
|
36
|
+
},
|
|
37
|
+
/**
|
|
38
|
+
* Start warmup process.
|
|
39
|
+
*/
|
|
40
|
+
start: (state, action) => {
|
|
41
|
+
state.status = 'initializing';
|
|
42
|
+
state.provider = action.payload.provider;
|
|
43
|
+
state.startedAt = new Date().toISOString();
|
|
44
|
+
state.readyAt = null;
|
|
45
|
+
state.elapsedMs = null;
|
|
46
|
+
state.error = null;
|
|
47
|
+
},
|
|
48
|
+
/**
|
|
49
|
+
* Warmup completed successfully.
|
|
50
|
+
*/
|
|
51
|
+
ready: (state, action) => {
|
|
52
|
+
state.status = 'ready';
|
|
53
|
+
state.readyAt = new Date().toISOString();
|
|
54
|
+
state.elapsedMs = action.payload.elapsedMs;
|
|
55
|
+
state.error = null;
|
|
56
|
+
},
|
|
57
|
+
/**
|
|
58
|
+
* Warmup failed with error.
|
|
59
|
+
*/
|
|
60
|
+
failed: (state, action) => {
|
|
61
|
+
state.status = 'failed';
|
|
62
|
+
state.elapsedMs = action.payload.elapsedMs;
|
|
63
|
+
state.error = action.payload.error;
|
|
64
|
+
},
|
|
65
|
+
/**
|
|
66
|
+
* Reset state for retry.
|
|
67
|
+
*/
|
|
68
|
+
reset: () => initialState,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
export const WarmupActions = warmupSlice.actions;
|
|
72
|
+
export const warmupReducer = warmupSlice.reducer;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memoized selectors for watcher state.
|
|
3
|
+
*/
|
|
4
|
+
import type { WatcherState, WatcherStatus } from './slice.js';
|
|
5
|
+
type RootState = {
|
|
6
|
+
watcher: WatcherState;
|
|
7
|
+
};
|
|
8
|
+
export declare const selectWatcherState: (state: RootState) => WatcherState;
|
|
9
|
+
export declare const selectWatcherStatus: (state: RootState) => WatcherStatus;
|
|
10
|
+
export declare const selectFilesWatched: (state: RootState) => number;
|
|
11
|
+
export declare const selectPendingPaths: (state: RootState) => string[];
|
|
12
|
+
export declare const selectLastIndexUpdate: (state: RootState) => string | null;
|
|
13
|
+
export declare const selectIsIndexUpToDate: (state: RootState) => boolean;
|
|
14
|
+
export declare const selectWatcherError: (state: RootState) => string | null;
|
|
15
|
+
/**
|
|
16
|
+
* Check if watcher is active (any status except stopped).
|
|
17
|
+
*/
|
|
18
|
+
export declare const selectIsWatching: ((state: RootState) => boolean) & {
|
|
19
|
+
clearCache: () => void;
|
|
20
|
+
resultsCount: () => number;
|
|
21
|
+
resetResultsCount: () => void;
|
|
22
|
+
} & {
|
|
23
|
+
resultFunc: (resultFuncArgs_0: WatcherStatus) => boolean;
|
|
24
|
+
memoizedResultFunc: ((resultFuncArgs_0: WatcherStatus) => boolean) & {
|
|
25
|
+
clearCache: () => void;
|
|
26
|
+
resultsCount: () => number;
|
|
27
|
+
resetResultsCount: () => void;
|
|
28
|
+
};
|
|
29
|
+
lastResult: () => boolean;
|
|
30
|
+
dependencies: [(state: RootState) => WatcherStatus];
|
|
31
|
+
recomputations: () => number;
|
|
32
|
+
resetRecomputations: () => void;
|
|
33
|
+
dependencyRecomputations: () => number;
|
|
34
|
+
resetDependencyRecomputations: () => void;
|
|
35
|
+
} & {
|
|
36
|
+
memoize: typeof import("reselect").weakMapMemoize;
|
|
37
|
+
argsMemoize: typeof import("reselect").weakMapMemoize;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Check if watcher is busy (debouncing or batching).
|
|
41
|
+
* Note: Indexing status is tracked by the indexing slice, not here.
|
|
42
|
+
* Use selectIsIndexing() from indexing/selectors.ts to check if indexing is in progress.
|
|
43
|
+
*/
|
|
44
|
+
export declare const selectIsWatcherBusy: ((state: RootState) => boolean) & {
|
|
45
|
+
clearCache: () => void;
|
|
46
|
+
resultsCount: () => number;
|
|
47
|
+
resetResultsCount: () => void;
|
|
48
|
+
} & {
|
|
49
|
+
resultFunc: (resultFuncArgs_0: WatcherStatus) => boolean;
|
|
50
|
+
memoizedResultFunc: ((resultFuncArgs_0: WatcherStatus) => boolean) & {
|
|
51
|
+
clearCache: () => void;
|
|
52
|
+
resultsCount: () => number;
|
|
53
|
+
resetResultsCount: () => void;
|
|
54
|
+
};
|
|
55
|
+
lastResult: () => boolean;
|
|
56
|
+
dependencies: [(state: RootState) => WatcherStatus];
|
|
57
|
+
recomputations: () => number;
|
|
58
|
+
resetRecomputations: () => void;
|
|
59
|
+
dependencyRecomputations: () => number;
|
|
60
|
+
resetDependencyRecomputations: () => void;
|
|
61
|
+
} & {
|
|
62
|
+
memoize: typeof import("reselect").weakMapMemoize;
|
|
63
|
+
argsMemoize: typeof import("reselect").weakMapMemoize;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Get pending change count.
|
|
67
|
+
*/
|
|
68
|
+
export declare const selectPendingChangeCount: ((state: RootState) => number) & {
|
|
69
|
+
clearCache: () => void;
|
|
70
|
+
resultsCount: () => number;
|
|
71
|
+
resetResultsCount: () => void;
|
|
72
|
+
} & {
|
|
73
|
+
resultFunc: (resultFuncArgs_0: string[]) => number;
|
|
74
|
+
memoizedResultFunc: ((resultFuncArgs_0: string[]) => number) & {
|
|
75
|
+
clearCache: () => void;
|
|
76
|
+
resultsCount: () => number;
|
|
77
|
+
resetResultsCount: () => void;
|
|
78
|
+
};
|
|
79
|
+
lastResult: () => number;
|
|
80
|
+
dependencies: [(state: RootState) => string[]];
|
|
81
|
+
recomputations: () => number;
|
|
82
|
+
resetRecomputations: () => void;
|
|
83
|
+
dependencyRecomputations: () => number;
|
|
84
|
+
resetDependencyRecomputations: () => void;
|
|
85
|
+
} & {
|
|
86
|
+
memoize: typeof import("reselect").weakMapMemoize;
|
|
87
|
+
argsMemoize: typeof import("reselect").weakMapMemoize;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Get display-friendly status text.
|
|
91
|
+
* Note: Indexing status text should come from the indexing slice,
|
|
92
|
+
* not from here. Use selectIndexingDisplay() from indexing/selectors.ts.
|
|
93
|
+
*/
|
|
94
|
+
export declare const selectWatcherStatusText: ((state: RootState) => string) & {
|
|
95
|
+
clearCache: () => void;
|
|
96
|
+
resultsCount: () => number;
|
|
97
|
+
resetResultsCount: () => void;
|
|
98
|
+
} & {
|
|
99
|
+
resultFunc: (resultFuncArgs_0: WatcherState) => string;
|
|
100
|
+
memoizedResultFunc: ((resultFuncArgs_0: WatcherState) => string) & {
|
|
101
|
+
clearCache: () => void;
|
|
102
|
+
resultsCount: () => number;
|
|
103
|
+
resetResultsCount: () => void;
|
|
104
|
+
};
|
|
105
|
+
lastResult: () => string;
|
|
106
|
+
dependencies: [(state: RootState) => WatcherState];
|
|
107
|
+
recomputations: () => number;
|
|
108
|
+
resetRecomputations: () => void;
|
|
109
|
+
dependencyRecomputations: () => number;
|
|
110
|
+
resetDependencyRecomputations: () => void;
|
|
111
|
+
} & {
|
|
112
|
+
memoize: typeof import("reselect").weakMapMemoize;
|
|
113
|
+
argsMemoize: typeof import("reselect").weakMapMemoize;
|
|
114
|
+
};
|
|
115
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Memoized selectors for watcher state.
|
|
3
|
+
*/
|
|
4
|
+
import { createSelector } from '@reduxjs/toolkit';
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// Basic Selectors
|
|
7
|
+
// ============================================================================
|
|
8
|
+
export const selectWatcherState = (state) => state.watcher;
|
|
9
|
+
export const selectWatcherStatus = (state) => state.watcher.status;
|
|
10
|
+
export const selectFilesWatched = (state) => state.watcher.filesWatched;
|
|
11
|
+
export const selectPendingPaths = (state) => state.watcher.pendingPaths;
|
|
12
|
+
export const selectLastIndexUpdate = (state) => state.watcher.lastIndexUpdate;
|
|
13
|
+
export const selectIsIndexUpToDate = (state) => state.watcher.indexUpToDate;
|
|
14
|
+
export const selectWatcherError = (state) => state.watcher.lastError;
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Memoized Selectors
|
|
17
|
+
// ============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Check if watcher is active (any status except stopped).
|
|
20
|
+
*/
|
|
21
|
+
export const selectIsWatching = createSelector([selectWatcherStatus], (status) => status !== 'stopped');
|
|
22
|
+
/**
|
|
23
|
+
* Check if watcher is busy (debouncing or batching).
|
|
24
|
+
* Note: Indexing status is tracked by the indexing slice, not here.
|
|
25
|
+
* Use selectIsIndexing() from indexing/selectors.ts to check if indexing is in progress.
|
|
26
|
+
*/
|
|
27
|
+
export const selectIsWatcherBusy = createSelector([selectWatcherStatus], (status) => status === 'debouncing' || status === 'batching');
|
|
28
|
+
/**
|
|
29
|
+
* Get pending change count.
|
|
30
|
+
*/
|
|
31
|
+
export const selectPendingChangeCount = createSelector([selectPendingPaths], (paths) => paths.length);
|
|
32
|
+
/**
|
|
33
|
+
* Get display-friendly status text.
|
|
34
|
+
* Note: Indexing status text should come from the indexing slice,
|
|
35
|
+
* not from here. Use selectIndexingDisplay() from indexing/selectors.ts.
|
|
36
|
+
*/
|
|
37
|
+
export const selectWatcherStatusText = createSelector([selectWatcherState], (state) => {
|
|
38
|
+
switch (state.status) {
|
|
39
|
+
case 'stopped':
|
|
40
|
+
return 'Stopped';
|
|
41
|
+
case 'starting':
|
|
42
|
+
return 'Starting...';
|
|
43
|
+
case 'watching':
|
|
44
|
+
return state.indexUpToDate
|
|
45
|
+
? `Watching ${state.filesWatched} files`
|
|
46
|
+
: `Watching ${state.filesWatched} files (pending changes)`;
|
|
47
|
+
case 'debouncing':
|
|
48
|
+
return `Debouncing (${state.pendingPaths.length} changes)`;
|
|
49
|
+
case 'batching':
|
|
50
|
+
return `Batching (${state.pendingPaths.length} changes)`;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Redux slice for file watcher state.
|
|
3
|
+
*
|
|
4
|
+
* Tracks the observable state of the file watcher for auto-indexing.
|
|
5
|
+
* The FileWatcher class dispatches actions to this slice to report status.
|
|
6
|
+
*/
|
|
7
|
+
import { type PayloadAction } from '@reduxjs/toolkit';
|
|
8
|
+
/**
|
|
9
|
+
* WatcherStatus tracks ONLY watcher-specific concerns:
|
|
10
|
+
* - stopped: Watcher not running
|
|
11
|
+
* - starting: Watcher initializing
|
|
12
|
+
* - watching: Actively watching, ready to detect changes
|
|
13
|
+
* - debouncing: Change detected, waiting for more changes
|
|
14
|
+
* - batching: Debounce done, collecting final batch before triggering index
|
|
15
|
+
*
|
|
16
|
+
* Note: 'indexing' is NOT included here. Whether indexing is in progress
|
|
17
|
+
* is tracked by the `indexing` slice (single source of truth).
|
|
18
|
+
* Use selectIsIndexing() from indexing/selectors.ts to check indexing status.
|
|
19
|
+
*/
|
|
20
|
+
export type WatcherStatus = 'stopped' | 'starting' | 'watching' | 'debouncing' | 'batching';
|
|
21
|
+
export interface WatcherState {
|
|
22
|
+
/** Current watcher status */
|
|
23
|
+
status: WatcherStatus;
|
|
24
|
+
/** Number of files being watched */
|
|
25
|
+
filesWatched: number;
|
|
26
|
+
/** Paths of pending changes (limited to first 10) */
|
|
27
|
+
pendingPaths: string[];
|
|
28
|
+
/** ISO timestamp of last index update */
|
|
29
|
+
lastIndexUpdate: string | null;
|
|
30
|
+
/** Whether the index is up to date */
|
|
31
|
+
indexUpToDate: boolean;
|
|
32
|
+
/** Last error message if any */
|
|
33
|
+
lastError: string | null;
|
|
34
|
+
}
|
|
35
|
+
export declare const watcherSlice: import("@reduxjs/toolkit").Slice<WatcherState, {
|
|
36
|
+
/**
|
|
37
|
+
* Watcher is starting up.
|
|
38
|
+
*/
|
|
39
|
+
starting: (state: {
|
|
40
|
+
status: WatcherStatus;
|
|
41
|
+
filesWatched: number;
|
|
42
|
+
pendingPaths: string[];
|
|
43
|
+
lastIndexUpdate: string | null;
|
|
44
|
+
indexUpToDate: boolean;
|
|
45
|
+
lastError: string | null;
|
|
46
|
+
}) => void;
|
|
47
|
+
/**
|
|
48
|
+
* Watcher is ready and watching.
|
|
49
|
+
*/
|
|
50
|
+
ready: (state: {
|
|
51
|
+
status: WatcherStatus;
|
|
52
|
+
filesWatched: number;
|
|
53
|
+
pendingPaths: string[];
|
|
54
|
+
lastIndexUpdate: string | null;
|
|
55
|
+
indexUpToDate: boolean;
|
|
56
|
+
lastError: string | null;
|
|
57
|
+
}, action: PayloadAction<{
|
|
58
|
+
filesWatched: number;
|
|
59
|
+
}>) => void;
|
|
60
|
+
/**
|
|
61
|
+
* File change detected, entering debounce period.
|
|
62
|
+
*/
|
|
63
|
+
debouncing: (state: {
|
|
64
|
+
status: WatcherStatus;
|
|
65
|
+
filesWatched: number;
|
|
66
|
+
pendingPaths: string[];
|
|
67
|
+
lastIndexUpdate: string | null;
|
|
68
|
+
indexUpToDate: boolean;
|
|
69
|
+
lastError: string | null;
|
|
70
|
+
}, action: PayloadAction<{
|
|
71
|
+
pendingPaths: string[];
|
|
72
|
+
}>) => void;
|
|
73
|
+
/**
|
|
74
|
+
* Debounce complete, entering batch window.
|
|
75
|
+
*/
|
|
76
|
+
batching: (state: {
|
|
77
|
+
status: WatcherStatus;
|
|
78
|
+
filesWatched: number;
|
|
79
|
+
pendingPaths: string[];
|
|
80
|
+
lastIndexUpdate: string | null;
|
|
81
|
+
indexUpToDate: boolean;
|
|
82
|
+
lastError: string | null;
|
|
83
|
+
}) => void;
|
|
84
|
+
/**
|
|
85
|
+
* Index update completed successfully.
|
|
86
|
+
* Transitions from batching back to watching.
|
|
87
|
+
*/
|
|
88
|
+
indexed: (state: {
|
|
89
|
+
status: WatcherStatus;
|
|
90
|
+
filesWatched: number;
|
|
91
|
+
pendingPaths: string[];
|
|
92
|
+
lastIndexUpdate: string | null;
|
|
93
|
+
indexUpToDate: boolean;
|
|
94
|
+
lastError: string | null;
|
|
95
|
+
}, action: PayloadAction<{
|
|
96
|
+
chunksAdded: number;
|
|
97
|
+
chunksDeleted: number;
|
|
98
|
+
}>) => void;
|
|
99
|
+
/**
|
|
100
|
+
* Index update failed.
|
|
101
|
+
*/
|
|
102
|
+
indexFailed: (state: {
|
|
103
|
+
status: WatcherStatus;
|
|
104
|
+
filesWatched: number;
|
|
105
|
+
pendingPaths: string[];
|
|
106
|
+
lastIndexUpdate: string | null;
|
|
107
|
+
indexUpToDate: boolean;
|
|
108
|
+
lastError: string | null;
|
|
109
|
+
}, action: PayloadAction<{
|
|
110
|
+
error: string;
|
|
111
|
+
}>) => void;
|
|
112
|
+
/**
|
|
113
|
+
* File was added (increment count).
|
|
114
|
+
*/
|
|
115
|
+
fileAdded: (state: {
|
|
116
|
+
status: WatcherStatus;
|
|
117
|
+
filesWatched: number;
|
|
118
|
+
pendingPaths: string[];
|
|
119
|
+
lastIndexUpdate: string | null;
|
|
120
|
+
indexUpToDate: boolean;
|
|
121
|
+
lastError: string | null;
|
|
122
|
+
}) => void;
|
|
123
|
+
/**
|
|
124
|
+
* File was deleted (decrement count).
|
|
125
|
+
*/
|
|
126
|
+
fileDeleted: (state: {
|
|
127
|
+
status: WatcherStatus;
|
|
128
|
+
filesWatched: number;
|
|
129
|
+
pendingPaths: string[];
|
|
130
|
+
lastIndexUpdate: string | null;
|
|
131
|
+
indexUpToDate: boolean;
|
|
132
|
+
lastError: string | null;
|
|
133
|
+
}) => void;
|
|
134
|
+
/**
|
|
135
|
+
* Error occurred in watcher.
|
|
136
|
+
*/
|
|
137
|
+
error: (state: {
|
|
138
|
+
status: WatcherStatus;
|
|
139
|
+
filesWatched: number;
|
|
140
|
+
pendingPaths: string[];
|
|
141
|
+
lastIndexUpdate: string | null;
|
|
142
|
+
indexUpToDate: boolean;
|
|
143
|
+
lastError: string | null;
|
|
144
|
+
}, action: PayloadAction<{
|
|
145
|
+
error: string;
|
|
146
|
+
}>) => void;
|
|
147
|
+
/**
|
|
148
|
+
* Watcher stopped.
|
|
149
|
+
*/
|
|
150
|
+
stopped: () => WatcherState;
|
|
151
|
+
}, "watcher", "watcher", import("@reduxjs/toolkit").SliceSelectors<WatcherState>>;
|
|
152
|
+
export declare const WatcherActions: import("@reduxjs/toolkit").CaseReducerActions<{
|
|
153
|
+
/**
|
|
154
|
+
* Watcher is starting up.
|
|
155
|
+
*/
|
|
156
|
+
starting: (state: {
|
|
157
|
+
status: WatcherStatus;
|
|
158
|
+
filesWatched: number;
|
|
159
|
+
pendingPaths: string[];
|
|
160
|
+
lastIndexUpdate: string | null;
|
|
161
|
+
indexUpToDate: boolean;
|
|
162
|
+
lastError: string | null;
|
|
163
|
+
}) => void;
|
|
164
|
+
/**
|
|
165
|
+
* Watcher is ready and watching.
|
|
166
|
+
*/
|
|
167
|
+
ready: (state: {
|
|
168
|
+
status: WatcherStatus;
|
|
169
|
+
filesWatched: number;
|
|
170
|
+
pendingPaths: string[];
|
|
171
|
+
lastIndexUpdate: string | null;
|
|
172
|
+
indexUpToDate: boolean;
|
|
173
|
+
lastError: string | null;
|
|
174
|
+
}, action: PayloadAction<{
|
|
175
|
+
filesWatched: number;
|
|
176
|
+
}>) => void;
|
|
177
|
+
/**
|
|
178
|
+
* File change detected, entering debounce period.
|
|
179
|
+
*/
|
|
180
|
+
debouncing: (state: {
|
|
181
|
+
status: WatcherStatus;
|
|
182
|
+
filesWatched: number;
|
|
183
|
+
pendingPaths: string[];
|
|
184
|
+
lastIndexUpdate: string | null;
|
|
185
|
+
indexUpToDate: boolean;
|
|
186
|
+
lastError: string | null;
|
|
187
|
+
}, action: PayloadAction<{
|
|
188
|
+
pendingPaths: string[];
|
|
189
|
+
}>) => void;
|
|
190
|
+
/**
|
|
191
|
+
* Debounce complete, entering batch window.
|
|
192
|
+
*/
|
|
193
|
+
batching: (state: {
|
|
194
|
+
status: WatcherStatus;
|
|
195
|
+
filesWatched: number;
|
|
196
|
+
pendingPaths: string[];
|
|
197
|
+
lastIndexUpdate: string | null;
|
|
198
|
+
indexUpToDate: boolean;
|
|
199
|
+
lastError: string | null;
|
|
200
|
+
}) => void;
|
|
201
|
+
/**
|
|
202
|
+
* Index update completed successfully.
|
|
203
|
+
* Transitions from batching back to watching.
|
|
204
|
+
*/
|
|
205
|
+
indexed: (state: {
|
|
206
|
+
status: WatcherStatus;
|
|
207
|
+
filesWatched: number;
|
|
208
|
+
pendingPaths: string[];
|
|
209
|
+
lastIndexUpdate: string | null;
|
|
210
|
+
indexUpToDate: boolean;
|
|
211
|
+
lastError: string | null;
|
|
212
|
+
}, action: PayloadAction<{
|
|
213
|
+
chunksAdded: number;
|
|
214
|
+
chunksDeleted: number;
|
|
215
|
+
}>) => void;
|
|
216
|
+
/**
|
|
217
|
+
* Index update failed.
|
|
218
|
+
*/
|
|
219
|
+
indexFailed: (state: {
|
|
220
|
+
status: WatcherStatus;
|
|
221
|
+
filesWatched: number;
|
|
222
|
+
pendingPaths: string[];
|
|
223
|
+
lastIndexUpdate: string | null;
|
|
224
|
+
indexUpToDate: boolean;
|
|
225
|
+
lastError: string | null;
|
|
226
|
+
}, action: PayloadAction<{
|
|
227
|
+
error: string;
|
|
228
|
+
}>) => void;
|
|
229
|
+
/**
|
|
230
|
+
* File was added (increment count).
|
|
231
|
+
*/
|
|
232
|
+
fileAdded: (state: {
|
|
233
|
+
status: WatcherStatus;
|
|
234
|
+
filesWatched: number;
|
|
235
|
+
pendingPaths: string[];
|
|
236
|
+
lastIndexUpdate: string | null;
|
|
237
|
+
indexUpToDate: boolean;
|
|
238
|
+
lastError: string | null;
|
|
239
|
+
}) => void;
|
|
240
|
+
/**
|
|
241
|
+
* File was deleted (decrement count).
|
|
242
|
+
*/
|
|
243
|
+
fileDeleted: (state: {
|
|
244
|
+
status: WatcherStatus;
|
|
245
|
+
filesWatched: number;
|
|
246
|
+
pendingPaths: string[];
|
|
247
|
+
lastIndexUpdate: string | null;
|
|
248
|
+
indexUpToDate: boolean;
|
|
249
|
+
lastError: string | null;
|
|
250
|
+
}) => void;
|
|
251
|
+
/**
|
|
252
|
+
* Error occurred in watcher.
|
|
253
|
+
*/
|
|
254
|
+
error: (state: {
|
|
255
|
+
status: WatcherStatus;
|
|
256
|
+
filesWatched: number;
|
|
257
|
+
pendingPaths: string[];
|
|
258
|
+
lastIndexUpdate: string | null;
|
|
259
|
+
indexUpToDate: boolean;
|
|
260
|
+
lastError: string | null;
|
|
261
|
+
}, action: PayloadAction<{
|
|
262
|
+
error: string;
|
|
263
|
+
}>) => void;
|
|
264
|
+
/**
|
|
265
|
+
* Watcher stopped.
|
|
266
|
+
*/
|
|
267
|
+
stopped: () => WatcherState;
|
|
268
|
+
}, "watcher">;
|
|
269
|
+
export declare const watcherReducer: import("redux").Reducer<WatcherState>;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Redux slice for file watcher state.
|
|
3
|
+
*
|
|
4
|
+
* Tracks the observable state of the file watcher for auto-indexing.
|
|
5
|
+
* The FileWatcher class dispatches actions to this slice to report status.
|
|
6
|
+
*/
|
|
7
|
+
import { createSlice } from '@reduxjs/toolkit';
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Initial State
|
|
10
|
+
// ============================================================================
|
|
11
|
+
const initialState = {
|
|
12
|
+
status: 'stopped',
|
|
13
|
+
filesWatched: 0,
|
|
14
|
+
pendingPaths: [],
|
|
15
|
+
lastIndexUpdate: null,
|
|
16
|
+
indexUpToDate: true,
|
|
17
|
+
lastError: null,
|
|
18
|
+
};
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// Slice
|
|
21
|
+
// ============================================================================
|
|
22
|
+
export const watcherSlice = createSlice({
|
|
23
|
+
name: 'watcher',
|
|
24
|
+
initialState,
|
|
25
|
+
reducers: {
|
|
26
|
+
/**
|
|
27
|
+
* Watcher is starting up.
|
|
28
|
+
*/
|
|
29
|
+
starting: state => {
|
|
30
|
+
state.status = 'starting';
|
|
31
|
+
state.lastError = null;
|
|
32
|
+
},
|
|
33
|
+
/**
|
|
34
|
+
* Watcher is ready and watching.
|
|
35
|
+
*/
|
|
36
|
+
ready: (state, action) => {
|
|
37
|
+
state.status = 'watching';
|
|
38
|
+
state.filesWatched = action.payload.filesWatched;
|
|
39
|
+
state.lastError = null;
|
|
40
|
+
},
|
|
41
|
+
/**
|
|
42
|
+
* File change detected, entering debounce period.
|
|
43
|
+
*/
|
|
44
|
+
debouncing: (state, action) => {
|
|
45
|
+
state.status = 'debouncing';
|
|
46
|
+
state.pendingPaths = action.payload.pendingPaths.slice(0, 10);
|
|
47
|
+
state.indexUpToDate = false;
|
|
48
|
+
},
|
|
49
|
+
/**
|
|
50
|
+
* Debounce complete, entering batch window.
|
|
51
|
+
*/
|
|
52
|
+
batching: state => {
|
|
53
|
+
state.status = 'batching';
|
|
54
|
+
},
|
|
55
|
+
/**
|
|
56
|
+
* Index update completed successfully.
|
|
57
|
+
* Transitions from batching back to watching.
|
|
58
|
+
*/
|
|
59
|
+
indexed: (state, action) => {
|
|
60
|
+
state.status = 'watching';
|
|
61
|
+
state.lastIndexUpdate = new Date().toISOString();
|
|
62
|
+
state.indexUpToDate = true;
|
|
63
|
+
state.pendingPaths = [];
|
|
64
|
+
state.lastError = null;
|
|
65
|
+
// Log to action payload for debugging, not stored in state
|
|
66
|
+
void action.payload;
|
|
67
|
+
},
|
|
68
|
+
/**
|
|
69
|
+
* Index update failed.
|
|
70
|
+
*/
|
|
71
|
+
indexFailed: (state, action) => {
|
|
72
|
+
state.status = 'watching';
|
|
73
|
+
state.lastError = action.payload.error;
|
|
74
|
+
},
|
|
75
|
+
/**
|
|
76
|
+
* File was added (increment count).
|
|
77
|
+
*/
|
|
78
|
+
fileAdded: state => {
|
|
79
|
+
state.filesWatched++;
|
|
80
|
+
},
|
|
81
|
+
/**
|
|
82
|
+
* File was deleted (decrement count).
|
|
83
|
+
*/
|
|
84
|
+
fileDeleted: state => {
|
|
85
|
+
state.filesWatched = Math.max(0, state.filesWatched - 1);
|
|
86
|
+
},
|
|
87
|
+
/**
|
|
88
|
+
* Error occurred in watcher.
|
|
89
|
+
*/
|
|
90
|
+
error: (state, action) => {
|
|
91
|
+
state.lastError = action.payload.error;
|
|
92
|
+
},
|
|
93
|
+
/**
|
|
94
|
+
* Watcher stopped.
|
|
95
|
+
*/
|
|
96
|
+
stopped: () => initialState,
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
export const WatcherActions = watcherSlice.actions;
|
|
100
|
+
export const watcherReducer = watcherSlice.reducer;
|