@embedpdf/plugin-search 1.0.0 → 1.0.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.
package/dist/index.cjs CHANGED
@@ -70,6 +70,7 @@ var SearchPlugin = class extends import_core.BasePlugin {
70
70
  this.searchResult$ = (0, import_core.createBehaviorEmitter)();
71
71
  this.searchActiveResultChange$ = (0, import_core.createBehaviorEmitter)();
72
72
  this.searchResultState$ = (0, import_core.createBehaviorEmitter)();
73
+ this.searchState$ = (0, import_core.createBehaviorEmitter)();
73
74
  this.engine = engine;
74
75
  this.loader = this.registry.getPlugin("loader").provides();
75
76
  this.loader.onDocumentLoaded(this.handleDocumentLoaded.bind(this));
@@ -77,13 +78,13 @@ var SearchPlugin = class extends import_core.BasePlugin {
77
78
  }
78
79
  handleDocumentLoaded(doc) {
79
80
  this.currentDocument = doc;
80
- if (this.getState().active) {
81
+ if (this.state.active) {
81
82
  this.startSearchSession();
82
83
  }
83
84
  }
84
85
  handleLoaderEvent(event) {
85
86
  if (event.type === "error" || event.type === "start" && this.currentDocument) {
86
- if (this.getState().active) {
87
+ if (this.state.active) {
87
88
  this.stopSearchSession();
88
89
  }
89
90
  this.currentDocument = void 0;
@@ -102,6 +103,7 @@ var SearchPlugin = class extends import_core.BasePlugin {
102
103
  showAllResults: newState.showAllResults,
103
104
  active: newState.active
104
105
  });
106
+ this.searchState$.emit(newState);
105
107
  }
106
108
  buildCapability() {
107
109
  return {
@@ -112,25 +114,22 @@ var SearchPlugin = class extends import_core.BasePlugin {
112
114
  previousResult: this.previousResult.bind(this),
113
115
  goToResult: this.goToResult.bind(this),
114
116
  setShowAllResults: (showAll) => this.dispatch(setShowAllResults(showAll)),
115
- getShowAllResults: () => this.getState().showAllResults,
117
+ getShowAllResults: () => this.state.showAllResults,
116
118
  onSearchResult: this.searchResult$.on,
117
119
  onSearchStart: this.searchStart$.on,
118
120
  onSearchStop: this.searchStop$.on,
119
121
  onActiveResultChange: this.searchActiveResultChange$.on,
120
122
  onSearchResultStateChange: this.searchResultState$.on,
121
- onStateChange: (handler) => {
122
- const unsubscribe = this.subscribe((_, state) => handler(state));
123
- return unsubscribe;
124
- },
125
- getFlags: () => this.getState().flags,
126
- setFlags: (flags) => this.setFlags(flags)
123
+ onStateChange: this.searchState$.on,
124
+ getFlags: () => this.state.flags,
125
+ setFlags: (flags) => this.setFlags(flags),
126
+ getState: () => this.state
127
127
  };
128
128
  }
129
129
  setFlags(flags) {
130
- const state = this.getState();
131
130
  this.dispatch(setSearchFlags(flags));
132
- if (state.active) {
133
- this.searchAllPages(state.query, true);
131
+ if (this.state.active) {
132
+ this.searchAllPages(this.state.query, true);
134
133
  }
135
134
  }
136
135
  notifySearchStart() {
@@ -158,9 +157,8 @@ var SearchPlugin = class extends import_core.BasePlugin {
158
157
  }
159
158
  async searchAllPages(keyword, force = false) {
160
159
  const trimmedKeyword = keyword.trim();
161
- const state = this.getState();
162
- if (state.query === trimmedKeyword && !force) {
163
- return { results: state.results, total: state.total };
160
+ if (this.state.query === trimmedKeyword && !force) {
161
+ return { results: this.state.results, total: this.state.total };
164
162
  }
165
163
  this.dispatch(startSearch(trimmedKeyword));
166
164
  if (!trimmedKeyword) {
@@ -171,11 +169,11 @@ var SearchPlugin = class extends import_core.BasePlugin {
171
169
  this.dispatch(setSearchResults([], 0, -1));
172
170
  return { results: [], total: 0 };
173
171
  }
174
- if (!state.active) {
172
+ if (!this.state.active) {
175
173
  this.startSearchSession();
176
174
  }
177
175
  return new Promise((resolve) => {
178
- this.engine.searchAllPages(this.currentDocument, trimmedKeyword, state.flags).wait(
176
+ this.engine.searchAllPages(this.currentDocument, trimmedKeyword, this.state.flags).wait(
179
177
  (results) => {
180
178
  const activeResultIndex = results.total > 0 ? 0 : -1;
181
179
  this.dispatch(setSearchResults(results.results, results.total, activeResultIndex));
@@ -194,24 +192,21 @@ var SearchPlugin = class extends import_core.BasePlugin {
194
192
  });
195
193
  }
196
194
  nextResult() {
197
- const state = this.getState();
198
- if (state.results.length === 0) {
195
+ if (this.state.results.length === 0) {
199
196
  return -1;
200
197
  }
201
- const nextIndex = state.activeResultIndex >= state.results.length - 1 ? 0 : state.activeResultIndex + 1;
198
+ const nextIndex = this.state.activeResultIndex >= this.state.results.length - 1 ? 0 : this.state.activeResultIndex + 1;
202
199
  return this.goToResult(nextIndex);
203
200
  }
204
201
  previousResult() {
205
- const state = this.getState();
206
- if (state.results.length === 0) {
202
+ if (this.state.results.length === 0) {
207
203
  return -1;
208
204
  }
209
- const prevIndex = state.activeResultIndex <= 0 ? state.results.length - 1 : state.activeResultIndex - 1;
205
+ const prevIndex = this.state.activeResultIndex <= 0 ? this.state.results.length - 1 : this.state.activeResultIndex - 1;
210
206
  return this.goToResult(prevIndex);
211
207
  }
212
208
  goToResult(index) {
213
- const state = this.getState();
214
- if (state.results.length === 0 || index < 0 || index >= state.results.length) {
209
+ if (this.state.results.length === 0 || index < 0 || index >= this.state.results.length) {
215
210
  return -1;
216
211
  }
217
212
  this.dispatch(setActiveResultIndex(index));
@@ -219,7 +214,7 @@ var SearchPlugin = class extends import_core.BasePlugin {
219
214
  return index;
220
215
  }
221
216
  async destroy() {
222
- if (this.getState().active && this.currentDocument) {
217
+ if (this.state.active && this.currentDocument) {
223
218
  this.stopSearchSession();
224
219
  }
225
220
  this.searchResult$.clear();
@@ -227,6 +222,7 @@ var SearchPlugin = class extends import_core.BasePlugin {
227
222
  this.searchStop$.clear();
228
223
  this.searchActiveResultChange$.clear();
229
224
  this.searchResultState$.clear();
225
+ this.searchState$.clear();
230
226
  }
231
227
  };
232
228
  SearchPlugin.id = "search";
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/lib/search-plugin.ts","../src/lib/actions.ts","../src/lib/manifest.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["export * from './lib';\n","import { BasePlugin, createBehaviorEmitter, PluginRegistry } from '@embedpdf/core';\nimport {\n MatchFlag,\n PdfDocumentObject,\n SearchAllPagesResult,\n TaskError,\n PdfEngine,\n} from '@embedpdf/models';\nimport { SearchPluginConfig, SearchCapability, SearchState, SearchResultState } from './types';\nimport { LoaderCapability, LoaderEvent, LoaderPlugin } from '@embedpdf/plugin-loader';\nimport {\n startSearchSession,\n stopSearchSession,\n setSearchFlags,\n setShowAllResults,\n startSearch,\n setSearchResults,\n setActiveResultIndex,\n SearchAction,\n} from './actions';\n\nexport class SearchPlugin extends BasePlugin<\n SearchPluginConfig,\n SearchCapability,\n SearchState,\n SearchAction\n> {\n static readonly id = 'search' as const;\n private loader: LoaderCapability;\n private currentDocument?: PdfDocumentObject;\n private engine: PdfEngine;\n\n private readonly searchStop$ = createBehaviorEmitter();\n private readonly searchStart$ = createBehaviorEmitter();\n private readonly searchResult$ = createBehaviorEmitter<SearchAllPagesResult>();\n private readonly searchActiveResultChange$ = createBehaviorEmitter<number>();\n private readonly searchResultState$ = createBehaviorEmitter<SearchResultState>();\n\n constructor(id: string, registry: PluginRegistry, engine: PdfEngine) {\n super(id, registry);\n this.engine = engine;\n this.loader = this.registry.getPlugin<LoaderPlugin>('loader')!.provides();\n\n this.loader.onDocumentLoaded(this.handleDocumentLoaded.bind(this));\n this.loader.onLoaderEvent(this.handleLoaderEvent.bind(this));\n }\n\n private handleDocumentLoaded(doc: PdfDocumentObject): void {\n this.currentDocument = doc;\n if (this.getState().active) {\n this.startSearchSession();\n }\n }\n\n private handleLoaderEvent(event: LoaderEvent): void {\n if (event.type === 'error' || (event.type === 'start' && this.currentDocument)) {\n if (this.getState().active) {\n this.stopSearchSession();\n }\n this.currentDocument = undefined;\n }\n }\n\n async initialize(config: SearchPluginConfig): Promise<void> {\n this.dispatch(setSearchFlags(config.flags || []));\n this.dispatch(\n setShowAllResults(config.showAllResults !== undefined ? config.showAllResults : true),\n );\n }\n\n override onStoreUpdated(_prevState: SearchState, newState: SearchState): void {\n this.searchResultState$.emit({\n results: newState.results,\n activeResultIndex: newState.activeResultIndex,\n showAllResults: newState.showAllResults,\n active: newState.active,\n });\n }\n\n protected buildCapability(): SearchCapability {\n return {\n startSearch: this.startSearchSession.bind(this),\n stopSearch: this.stopSearchSession.bind(this),\n searchAllPages: this.searchAllPages.bind(this),\n nextResult: this.nextResult.bind(this),\n previousResult: this.previousResult.bind(this),\n goToResult: this.goToResult.bind(this),\n setShowAllResults: (showAll) => this.dispatch(setShowAllResults(showAll)),\n getShowAllResults: () => this.getState().showAllResults,\n onSearchResult: this.searchResult$.on,\n onSearchStart: this.searchStart$.on,\n onSearchStop: this.searchStop$.on,\n onActiveResultChange: this.searchActiveResultChange$.on,\n onSearchResultStateChange: this.searchResultState$.on,\n onStateChange: (handler) => {\n const unsubscribe = this.subscribe((_, state) => handler(state));\n return unsubscribe;\n },\n getFlags: () => this.getState().flags,\n setFlags: (flags) => this.setFlags(flags),\n };\n }\n\n private setFlags(flags: MatchFlag[]): void {\n const state = this.getState();\n this.dispatch(setSearchFlags(flags));\n if (state.active) {\n this.searchAllPages(state.query, true);\n }\n }\n\n private notifySearchStart(): void {\n this.searchStart$.emit();\n }\n\n private notifySearchStop(): void {\n this.searchStop$.emit();\n }\n\n private notifyActiveResultChange(index: number): void {\n this.searchActiveResultChange$.emit(index);\n }\n\n private startSearchSession(): void {\n if (!this.currentDocument) {\n return;\n }\n this.dispatch(startSearchSession());\n this.notifySearchStart();\n }\n\n private stopSearchSession(): void {\n if (!this.currentDocument || !this.getState().active) {\n return;\n }\n this.dispatch(stopSearchSession());\n this.notifySearchStop();\n }\n\n private async searchAllPages(\n keyword: string,\n force: boolean = false,\n ): Promise<SearchAllPagesResult> {\n const trimmedKeyword = keyword.trim();\n const state = this.getState();\n\n if (state.query === trimmedKeyword && !force) {\n return { results: state.results, total: state.total };\n }\n\n this.dispatch(startSearch(trimmedKeyword));\n\n if (!trimmedKeyword) {\n this.dispatch(setSearchResults([], 0, -1));\n return { results: [], total: 0 };\n }\n if (!this.currentDocument) {\n this.dispatch(setSearchResults([], 0, -1));\n return { results: [], total: 0 };\n }\n\n if (!state.active) {\n this.startSearchSession();\n }\n\n return new Promise<SearchAllPagesResult>((resolve) => {\n this.engine.searchAllPages(this.currentDocument!, trimmedKeyword, state.flags).wait(\n (results) => {\n const activeResultIndex = results.total > 0 ? 0 : -1;\n this.dispatch(setSearchResults(results.results, results.total, activeResultIndex));\n this.searchResult$.emit(results);\n if (results.total > 0) {\n this.notifyActiveResultChange(0);\n }\n resolve(results);\n },\n (error: TaskError<any>) => {\n console.error('Error during search:', error);\n this.dispatch(setSearchResults([], 0, -1));\n resolve({ results: [], total: 0 });\n },\n );\n });\n }\n\n private nextResult(): number {\n const state = this.getState();\n if (state.results.length === 0) {\n return -1;\n }\n const nextIndex =\n state.activeResultIndex >= state.results.length - 1 ? 0 : state.activeResultIndex + 1;\n return this.goToResult(nextIndex);\n }\n\n private previousResult(): number {\n const state = this.getState();\n if (state.results.length === 0) {\n return -1;\n }\n const prevIndex =\n state.activeResultIndex <= 0 ? state.results.length - 1 : state.activeResultIndex - 1;\n return this.goToResult(prevIndex);\n }\n\n private goToResult(index: number): number {\n const state = this.getState();\n if (state.results.length === 0 || index < 0 || index >= state.results.length) {\n return -1;\n }\n this.dispatch(setActiveResultIndex(index));\n this.notifyActiveResultChange(index);\n return index;\n }\n\n async destroy(): Promise<void> {\n if (this.getState().active && this.currentDocument) {\n this.stopSearchSession();\n }\n this.searchResult$.clear();\n this.searchStart$.clear();\n this.searchStop$.clear();\n this.searchActiveResultChange$.clear();\n this.searchResultState$.clear();\n }\n}\n","import { Action } from '@embedpdf/core';\nimport { MatchFlag, SearchResult } from '@embedpdf/models';\n\n// Action Types\nexport const START_SEARCH_SESSION = 'START_SEARCH_SESSION';\nexport const STOP_SEARCH_SESSION = 'STOP_SEARCH_SESSION';\nexport const SET_SEARCH_FLAGS = 'SET_SEARCH_FLAGS';\nexport const SET_SHOW_ALL_RESULTS = 'SET_SHOW_ALL_RESULTS';\nexport const START_SEARCH = 'START_SEARCH';\nexport const SET_SEARCH_RESULTS = 'SET_SEARCH_RESULTS';\nexport const SET_ACTIVE_RESULT_INDEX = 'SET_ACTIVE_RESULT_INDEX';\n\n// Action Interfaces\nexport interface StartSearchSessionAction extends Action {\n type: typeof START_SEARCH_SESSION;\n}\n\nexport interface StopSearchSessionAction extends Action {\n type: typeof STOP_SEARCH_SESSION;\n}\n\nexport interface SetSearchFlagsAction extends Action {\n type: typeof SET_SEARCH_FLAGS;\n payload: MatchFlag[];\n}\n\nexport interface SetShowAllResultsAction extends Action {\n type: typeof SET_SHOW_ALL_RESULTS;\n payload: boolean;\n}\n\nexport interface StartSearchAction extends Action {\n type: typeof START_SEARCH;\n payload: string;\n}\n\nexport interface SetSearchResultsAction extends Action {\n type: typeof SET_SEARCH_RESULTS;\n payload: {\n results: SearchResult[];\n total: number;\n activeResultIndex: number;\n };\n}\n\nexport interface SetActiveResultIndexAction extends Action {\n type: typeof SET_ACTIVE_RESULT_INDEX;\n payload: number;\n}\n\n// Union Type for All Actions\nexport type SearchAction =\n | StartSearchSessionAction\n | StopSearchSessionAction\n | SetSearchFlagsAction\n | SetShowAllResultsAction\n | StartSearchAction\n | SetSearchResultsAction\n | SetActiveResultIndexAction;\n\n// Action Creators\nexport function startSearchSession(): StartSearchSessionAction {\n return { type: START_SEARCH_SESSION };\n}\n\nexport function stopSearchSession(): StopSearchSessionAction {\n return { type: STOP_SEARCH_SESSION };\n}\n\nexport function setSearchFlags(flags: MatchFlag[]): SetSearchFlagsAction {\n return { type: SET_SEARCH_FLAGS, payload: flags };\n}\n\nexport function setShowAllResults(showAll: boolean): SetShowAllResultsAction {\n return { type: SET_SHOW_ALL_RESULTS, payload: showAll };\n}\n\nexport function startSearch(query: string): StartSearchAction {\n return { type: START_SEARCH, payload: query };\n}\n\nexport function setSearchResults(\n results: SearchResult[],\n total: number,\n activeResultIndex: number,\n): SetSearchResultsAction {\n return { type: SET_SEARCH_RESULTS, payload: { results, total, activeResultIndex } };\n}\n\nexport function setActiveResultIndex(index: number): SetActiveResultIndexAction {\n return { type: SET_ACTIVE_RESULT_INDEX, payload: index };\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { SearchPluginConfig } from './types';\n\nexport const SEARCH_PLUGIN_ID = 'search';\n\nexport const manifest: PluginManifest<SearchPluginConfig> = {\n id: SEARCH_PLUGIN_ID,\n name: 'Search Plugin',\n version: '1.0.0',\n provides: ['search'],\n requires: ['loader'],\n optional: [],\n defaultConfig: {\n enabled: true,\n flags: [],\n },\n};\n","import { Reducer } from '@embedpdf/core';\nimport { SearchState } from './types';\nimport {\n START_SEARCH_SESSION,\n STOP_SEARCH_SESSION,\n SET_SEARCH_FLAGS,\n SET_SHOW_ALL_RESULTS,\n START_SEARCH,\n SET_SEARCH_RESULTS,\n SET_ACTIVE_RESULT_INDEX,\n SearchAction,\n} from './actions';\n\nexport const initialState: SearchState = {\n flags: [],\n results: [],\n total: 0,\n activeResultIndex: -1,\n showAllResults: true,\n query: '',\n loading: false,\n active: false,\n};\n\nexport const searchReducer: Reducer<SearchState, SearchAction> = (state = initialState, action) => {\n switch (action.type) {\n case START_SEARCH_SESSION:\n return { ...state, active: true };\n\n case STOP_SEARCH_SESSION:\n return {\n ...state,\n results: [],\n total: 0,\n activeResultIndex: -1,\n query: '',\n loading: false,\n active: false,\n };\n\n case SET_SEARCH_FLAGS:\n return { ...state, flags: action.payload };\n\n case SET_SHOW_ALL_RESULTS:\n return { ...state, showAllResults: action.payload };\n\n case START_SEARCH:\n return { ...state, loading: true, query: action.payload };\n\n case SET_SEARCH_RESULTS:\n return {\n ...state,\n results: action.payload.results,\n total: action.payload.total,\n activeResultIndex: action.payload.activeResultIndex,\n loading: false,\n };\n\n case SET_ACTIVE_RESULT_INDEX:\n return { ...state, activeResultIndex: action.payload };\n\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { SearchPlugin } from './search-plugin';\nimport { manifest, SEARCH_PLUGIN_ID } from './manifest';\nimport { SearchPluginConfig, SearchState } from './types';\nimport { searchReducer, initialState } from './reducer';\nimport { SearchAction } from './actions';\n\nexport const SearchPluginPackage: PluginPackage<\n SearchPlugin,\n SearchPluginConfig,\n SearchState,\n SearchAction\n> = {\n manifest,\n create: (registry, engine) => new SearchPlugin(SEARCH_PLUGIN_ID, registry, engine),\n reducer: searchReducer,\n initialState,\n};\n\nexport * from './search-plugin';\nexport * from './types';\nexport * from './manifest';\nexport { initialState };\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/lib/search-plugin.ts","../src/lib/actions.ts","../src/lib/manifest.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["export * from './lib';\n","import { BasePlugin, createBehaviorEmitter, PluginRegistry } from '@embedpdf/core';\nimport {\n MatchFlag,\n PdfDocumentObject,\n SearchAllPagesResult,\n TaskError,\n PdfEngine,\n} from '@embedpdf/models';\nimport { SearchPluginConfig, SearchCapability, SearchState, SearchResultState } from './types';\nimport { LoaderCapability, LoaderEvent, LoaderPlugin } from '@embedpdf/plugin-loader';\nimport {\n startSearchSession,\n stopSearchSession,\n setSearchFlags,\n setShowAllResults,\n startSearch,\n setSearchResults,\n setActiveResultIndex,\n SearchAction,\n} from './actions';\n\nexport class SearchPlugin extends BasePlugin<\n SearchPluginConfig,\n SearchCapability,\n SearchState,\n SearchAction\n> {\n static readonly id = 'search' as const;\n private loader: LoaderCapability;\n private currentDocument?: PdfDocumentObject;\n private engine: PdfEngine;\n\n private readonly searchStop$ = createBehaviorEmitter();\n private readonly searchStart$ = createBehaviorEmitter();\n private readonly searchResult$ = createBehaviorEmitter<SearchAllPagesResult>();\n private readonly searchActiveResultChange$ = createBehaviorEmitter<number>();\n private readonly searchResultState$ = createBehaviorEmitter<SearchResultState>();\n private readonly searchState$ = createBehaviorEmitter<SearchState>();\n\n constructor(id: string, registry: PluginRegistry, engine: PdfEngine) {\n super(id, registry);\n this.engine = engine;\n this.loader = this.registry.getPlugin<LoaderPlugin>('loader')!.provides();\n\n this.loader.onDocumentLoaded(this.handleDocumentLoaded.bind(this));\n this.loader.onLoaderEvent(this.handleLoaderEvent.bind(this));\n }\n\n private handleDocumentLoaded(doc: PdfDocumentObject): void {\n this.currentDocument = doc;\n if (this.state.active) {\n this.startSearchSession();\n }\n }\n\n private handleLoaderEvent(event: LoaderEvent): void {\n if (event.type === 'error' || (event.type === 'start' && this.currentDocument)) {\n if (this.state.active) {\n this.stopSearchSession();\n }\n this.currentDocument = undefined;\n }\n }\n\n async initialize(config: SearchPluginConfig): Promise<void> {\n this.dispatch(setSearchFlags(config.flags || []));\n this.dispatch(\n setShowAllResults(config.showAllResults !== undefined ? config.showAllResults : true),\n );\n }\n\n override onStoreUpdated(_prevState: SearchState, newState: SearchState): void {\n this.searchResultState$.emit({\n results: newState.results,\n activeResultIndex: newState.activeResultIndex,\n showAllResults: newState.showAllResults,\n active: newState.active,\n });\n this.searchState$.emit(newState);\n }\n\n protected buildCapability(): SearchCapability {\n return {\n startSearch: this.startSearchSession.bind(this),\n stopSearch: this.stopSearchSession.bind(this),\n searchAllPages: this.searchAllPages.bind(this),\n nextResult: this.nextResult.bind(this),\n previousResult: this.previousResult.bind(this),\n goToResult: this.goToResult.bind(this),\n setShowAllResults: (showAll) => this.dispatch(setShowAllResults(showAll)),\n getShowAllResults: () => this.state.showAllResults,\n onSearchResult: this.searchResult$.on,\n onSearchStart: this.searchStart$.on,\n onSearchStop: this.searchStop$.on,\n onActiveResultChange: this.searchActiveResultChange$.on,\n onSearchResultStateChange: this.searchResultState$.on,\n onStateChange: this.searchState$.on,\n getFlags: () => this.state.flags,\n setFlags: (flags) => this.setFlags(flags),\n getState: () => this.state,\n };\n }\n\n private setFlags(flags: MatchFlag[]): void {\n this.dispatch(setSearchFlags(flags));\n if (this.state.active) {\n this.searchAllPages(this.state.query, true);\n }\n }\n\n private notifySearchStart(): void {\n this.searchStart$.emit();\n }\n\n private notifySearchStop(): void {\n this.searchStop$.emit();\n }\n\n private notifyActiveResultChange(index: number): void {\n this.searchActiveResultChange$.emit(index);\n }\n\n private startSearchSession(): void {\n if (!this.currentDocument) {\n return;\n }\n this.dispatch(startSearchSession());\n this.notifySearchStart();\n }\n\n private stopSearchSession(): void {\n if (!this.currentDocument || !this.getState().active) {\n return;\n }\n this.dispatch(stopSearchSession());\n this.notifySearchStop();\n }\n\n private async searchAllPages(\n keyword: string,\n force: boolean = false,\n ): Promise<SearchAllPagesResult> {\n const trimmedKeyword = keyword.trim();\n\n if (this.state.query === trimmedKeyword && !force) {\n return { results: this.state.results, total: this.state.total };\n }\n\n this.dispatch(startSearch(trimmedKeyword));\n\n if (!trimmedKeyword) {\n this.dispatch(setSearchResults([], 0, -1));\n return { results: [], total: 0 };\n }\n if (!this.currentDocument) {\n this.dispatch(setSearchResults([], 0, -1));\n return { results: [], total: 0 };\n }\n\n if (!this.state.active) {\n this.startSearchSession();\n }\n\n return new Promise<SearchAllPagesResult>((resolve) => {\n this.engine.searchAllPages(this.currentDocument!, trimmedKeyword, this.state.flags).wait(\n (results) => {\n const activeResultIndex = results.total > 0 ? 0 : -1;\n this.dispatch(setSearchResults(results.results, results.total, activeResultIndex));\n this.searchResult$.emit(results);\n if (results.total > 0) {\n this.notifyActiveResultChange(0);\n }\n resolve(results);\n },\n (error: TaskError<any>) => {\n console.error('Error during search:', error);\n this.dispatch(setSearchResults([], 0, -1));\n resolve({ results: [], total: 0 });\n },\n );\n });\n }\n\n private nextResult(): number {\n if (this.state.results.length === 0) {\n return -1;\n }\n const nextIndex =\n this.state.activeResultIndex >= this.state.results.length - 1\n ? 0\n : this.state.activeResultIndex + 1;\n return this.goToResult(nextIndex);\n }\n\n private previousResult(): number {\n if (this.state.results.length === 0) {\n return -1;\n }\n const prevIndex =\n this.state.activeResultIndex <= 0\n ? this.state.results.length - 1\n : this.state.activeResultIndex - 1;\n return this.goToResult(prevIndex);\n }\n\n private goToResult(index: number): number {\n if (this.state.results.length === 0 || index < 0 || index >= this.state.results.length) {\n return -1;\n }\n this.dispatch(setActiveResultIndex(index));\n this.notifyActiveResultChange(index);\n return index;\n }\n\n async destroy(): Promise<void> {\n if (this.state.active && this.currentDocument) {\n this.stopSearchSession();\n }\n this.searchResult$.clear();\n this.searchStart$.clear();\n this.searchStop$.clear();\n this.searchActiveResultChange$.clear();\n this.searchResultState$.clear();\n this.searchState$.clear();\n }\n}\n","import { Action } from '@embedpdf/core';\nimport { MatchFlag, SearchResult } from '@embedpdf/models';\n\n// Action Types\nexport const START_SEARCH_SESSION = 'START_SEARCH_SESSION';\nexport const STOP_SEARCH_SESSION = 'STOP_SEARCH_SESSION';\nexport const SET_SEARCH_FLAGS = 'SET_SEARCH_FLAGS';\nexport const SET_SHOW_ALL_RESULTS = 'SET_SHOW_ALL_RESULTS';\nexport const START_SEARCH = 'START_SEARCH';\nexport const SET_SEARCH_RESULTS = 'SET_SEARCH_RESULTS';\nexport const SET_ACTIVE_RESULT_INDEX = 'SET_ACTIVE_RESULT_INDEX';\n\n// Action Interfaces\nexport interface StartSearchSessionAction extends Action {\n type: typeof START_SEARCH_SESSION;\n}\n\nexport interface StopSearchSessionAction extends Action {\n type: typeof STOP_SEARCH_SESSION;\n}\n\nexport interface SetSearchFlagsAction extends Action {\n type: typeof SET_SEARCH_FLAGS;\n payload: MatchFlag[];\n}\n\nexport interface SetShowAllResultsAction extends Action {\n type: typeof SET_SHOW_ALL_RESULTS;\n payload: boolean;\n}\n\nexport interface StartSearchAction extends Action {\n type: typeof START_SEARCH;\n payload: string;\n}\n\nexport interface SetSearchResultsAction extends Action {\n type: typeof SET_SEARCH_RESULTS;\n payload: {\n results: SearchResult[];\n total: number;\n activeResultIndex: number;\n };\n}\n\nexport interface SetActiveResultIndexAction extends Action {\n type: typeof SET_ACTIVE_RESULT_INDEX;\n payload: number;\n}\n\n// Union Type for All Actions\nexport type SearchAction =\n | StartSearchSessionAction\n | StopSearchSessionAction\n | SetSearchFlagsAction\n | SetShowAllResultsAction\n | StartSearchAction\n | SetSearchResultsAction\n | SetActiveResultIndexAction;\n\n// Action Creators\nexport function startSearchSession(): StartSearchSessionAction {\n return { type: START_SEARCH_SESSION };\n}\n\nexport function stopSearchSession(): StopSearchSessionAction {\n return { type: STOP_SEARCH_SESSION };\n}\n\nexport function setSearchFlags(flags: MatchFlag[]): SetSearchFlagsAction {\n return { type: SET_SEARCH_FLAGS, payload: flags };\n}\n\nexport function setShowAllResults(showAll: boolean): SetShowAllResultsAction {\n return { type: SET_SHOW_ALL_RESULTS, payload: showAll };\n}\n\nexport function startSearch(query: string): StartSearchAction {\n return { type: START_SEARCH, payload: query };\n}\n\nexport function setSearchResults(\n results: SearchResult[],\n total: number,\n activeResultIndex: number,\n): SetSearchResultsAction {\n return { type: SET_SEARCH_RESULTS, payload: { results, total, activeResultIndex } };\n}\n\nexport function setActiveResultIndex(index: number): SetActiveResultIndexAction {\n return { type: SET_ACTIVE_RESULT_INDEX, payload: index };\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { SearchPluginConfig } from './types';\n\nexport const SEARCH_PLUGIN_ID = 'search';\n\nexport const manifest: PluginManifest<SearchPluginConfig> = {\n id: SEARCH_PLUGIN_ID,\n name: 'Search Plugin',\n version: '1.0.0',\n provides: ['search'],\n requires: ['loader'],\n optional: [],\n defaultConfig: {\n enabled: true,\n flags: [],\n },\n};\n","import { Reducer } from '@embedpdf/core';\nimport { SearchState } from './types';\nimport {\n START_SEARCH_SESSION,\n STOP_SEARCH_SESSION,\n SET_SEARCH_FLAGS,\n SET_SHOW_ALL_RESULTS,\n START_SEARCH,\n SET_SEARCH_RESULTS,\n SET_ACTIVE_RESULT_INDEX,\n SearchAction,\n} from './actions';\n\nexport const initialState: SearchState = {\n flags: [],\n results: [],\n total: 0,\n activeResultIndex: -1,\n showAllResults: true,\n query: '',\n loading: false,\n active: false,\n};\n\nexport const searchReducer: Reducer<SearchState, SearchAction> = (state = initialState, action) => {\n switch (action.type) {\n case START_SEARCH_SESSION:\n return { ...state, active: true };\n\n case STOP_SEARCH_SESSION:\n return {\n ...state,\n results: [],\n total: 0,\n activeResultIndex: -1,\n query: '',\n loading: false,\n active: false,\n };\n\n case SET_SEARCH_FLAGS:\n return { ...state, flags: action.payload };\n\n case SET_SHOW_ALL_RESULTS:\n return { ...state, showAllResults: action.payload };\n\n case START_SEARCH:\n return { ...state, loading: true, query: action.payload };\n\n case SET_SEARCH_RESULTS:\n return {\n ...state,\n results: action.payload.results,\n total: action.payload.total,\n activeResultIndex: action.payload.activeResultIndex,\n loading: false,\n };\n\n case SET_ACTIVE_RESULT_INDEX:\n return { ...state, activeResultIndex: action.payload };\n\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { SearchPlugin } from './search-plugin';\nimport { manifest, SEARCH_PLUGIN_ID } from './manifest';\nimport { SearchPluginConfig, SearchState } from './types';\nimport { searchReducer, initialState } from './reducer';\nimport { SearchAction } from './actions';\n\nexport const SearchPluginPackage: PluginPackage<\n SearchPlugin,\n SearchPluginConfig,\n SearchState,\n SearchAction\n> = {\n manifest,\n create: (registry, engine) => new SearchPlugin(SEARCH_PLUGIN_ID, registry, engine),\n reducer: searchReducer,\n initialState,\n};\n\nexport * from './search-plugin';\nexport * from './types';\nexport * from './manifest';\nexport { initialState };\n"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -144,7 +144,12 @@ interface SearchCapability {
144
144
  * @param handler - Handler function called when state changes
145
145
  * @returns Function to unsubscribe the handler
146
146
  */
147
- onStateChange: (handler: (state: SearchState) => void) => () => void;
147
+ onStateChange: EventHook<SearchState>;
148
+ /**
149
+ * Get the current search state
150
+ * @returns The current search state
151
+ */
152
+ getState: () => SearchState;
148
153
  }
149
154
 
150
155
  declare const START_SEARCH_SESSION = "START_SEARCH_SESSION";
@@ -196,6 +201,7 @@ declare class SearchPlugin extends BasePlugin<SearchPluginConfig, SearchCapabili
196
201
  private readonly searchResult$;
197
202
  private readonly searchActiveResultChange$;
198
203
  private readonly searchResultState$;
204
+ private readonly searchState$;
199
205
  constructor(id: string, registry: PluginRegistry, engine: PdfEngine);
200
206
  private handleDocumentLoaded;
201
207
  private handleLoaderEvent;
package/dist/index.d.ts CHANGED
@@ -144,7 +144,12 @@ interface SearchCapability {
144
144
  * @param handler - Handler function called when state changes
145
145
  * @returns Function to unsubscribe the handler
146
146
  */
147
- onStateChange: (handler: (state: SearchState) => void) => () => void;
147
+ onStateChange: EventHook<SearchState>;
148
+ /**
149
+ * Get the current search state
150
+ * @returns The current search state
151
+ */
152
+ getState: () => SearchState;
148
153
  }
149
154
 
150
155
  declare const START_SEARCH_SESSION = "START_SEARCH_SESSION";
@@ -196,6 +201,7 @@ declare class SearchPlugin extends BasePlugin<SearchPluginConfig, SearchCapabili
196
201
  private readonly searchResult$;
197
202
  private readonly searchActiveResultChange$;
198
203
  private readonly searchResultState$;
204
+ private readonly searchState$;
199
205
  constructor(id: string, registry: PluginRegistry, engine: PdfEngine);
200
206
  private handleDocumentLoaded;
201
207
  private handleLoaderEvent;
package/dist/index.js CHANGED
@@ -40,6 +40,7 @@ var SearchPlugin = class extends BasePlugin {
40
40
  this.searchResult$ = createBehaviorEmitter();
41
41
  this.searchActiveResultChange$ = createBehaviorEmitter();
42
42
  this.searchResultState$ = createBehaviorEmitter();
43
+ this.searchState$ = createBehaviorEmitter();
43
44
  this.engine = engine;
44
45
  this.loader = this.registry.getPlugin("loader").provides();
45
46
  this.loader.onDocumentLoaded(this.handleDocumentLoaded.bind(this));
@@ -47,13 +48,13 @@ var SearchPlugin = class extends BasePlugin {
47
48
  }
48
49
  handleDocumentLoaded(doc) {
49
50
  this.currentDocument = doc;
50
- if (this.getState().active) {
51
+ if (this.state.active) {
51
52
  this.startSearchSession();
52
53
  }
53
54
  }
54
55
  handleLoaderEvent(event) {
55
56
  if (event.type === "error" || event.type === "start" && this.currentDocument) {
56
- if (this.getState().active) {
57
+ if (this.state.active) {
57
58
  this.stopSearchSession();
58
59
  }
59
60
  this.currentDocument = void 0;
@@ -72,6 +73,7 @@ var SearchPlugin = class extends BasePlugin {
72
73
  showAllResults: newState.showAllResults,
73
74
  active: newState.active
74
75
  });
76
+ this.searchState$.emit(newState);
75
77
  }
76
78
  buildCapability() {
77
79
  return {
@@ -82,25 +84,22 @@ var SearchPlugin = class extends BasePlugin {
82
84
  previousResult: this.previousResult.bind(this),
83
85
  goToResult: this.goToResult.bind(this),
84
86
  setShowAllResults: (showAll) => this.dispatch(setShowAllResults(showAll)),
85
- getShowAllResults: () => this.getState().showAllResults,
87
+ getShowAllResults: () => this.state.showAllResults,
86
88
  onSearchResult: this.searchResult$.on,
87
89
  onSearchStart: this.searchStart$.on,
88
90
  onSearchStop: this.searchStop$.on,
89
91
  onActiveResultChange: this.searchActiveResultChange$.on,
90
92
  onSearchResultStateChange: this.searchResultState$.on,
91
- onStateChange: (handler) => {
92
- const unsubscribe = this.subscribe((_, state) => handler(state));
93
- return unsubscribe;
94
- },
95
- getFlags: () => this.getState().flags,
96
- setFlags: (flags) => this.setFlags(flags)
93
+ onStateChange: this.searchState$.on,
94
+ getFlags: () => this.state.flags,
95
+ setFlags: (flags) => this.setFlags(flags),
96
+ getState: () => this.state
97
97
  };
98
98
  }
99
99
  setFlags(flags) {
100
- const state = this.getState();
101
100
  this.dispatch(setSearchFlags(flags));
102
- if (state.active) {
103
- this.searchAllPages(state.query, true);
101
+ if (this.state.active) {
102
+ this.searchAllPages(this.state.query, true);
104
103
  }
105
104
  }
106
105
  notifySearchStart() {
@@ -128,9 +127,8 @@ var SearchPlugin = class extends BasePlugin {
128
127
  }
129
128
  async searchAllPages(keyword, force = false) {
130
129
  const trimmedKeyword = keyword.trim();
131
- const state = this.getState();
132
- if (state.query === trimmedKeyword && !force) {
133
- return { results: state.results, total: state.total };
130
+ if (this.state.query === trimmedKeyword && !force) {
131
+ return { results: this.state.results, total: this.state.total };
134
132
  }
135
133
  this.dispatch(startSearch(trimmedKeyword));
136
134
  if (!trimmedKeyword) {
@@ -141,11 +139,11 @@ var SearchPlugin = class extends BasePlugin {
141
139
  this.dispatch(setSearchResults([], 0, -1));
142
140
  return { results: [], total: 0 };
143
141
  }
144
- if (!state.active) {
142
+ if (!this.state.active) {
145
143
  this.startSearchSession();
146
144
  }
147
145
  return new Promise((resolve) => {
148
- this.engine.searchAllPages(this.currentDocument, trimmedKeyword, state.flags).wait(
146
+ this.engine.searchAllPages(this.currentDocument, trimmedKeyword, this.state.flags).wait(
149
147
  (results) => {
150
148
  const activeResultIndex = results.total > 0 ? 0 : -1;
151
149
  this.dispatch(setSearchResults(results.results, results.total, activeResultIndex));
@@ -164,24 +162,21 @@ var SearchPlugin = class extends BasePlugin {
164
162
  });
165
163
  }
166
164
  nextResult() {
167
- const state = this.getState();
168
- if (state.results.length === 0) {
165
+ if (this.state.results.length === 0) {
169
166
  return -1;
170
167
  }
171
- const nextIndex = state.activeResultIndex >= state.results.length - 1 ? 0 : state.activeResultIndex + 1;
168
+ const nextIndex = this.state.activeResultIndex >= this.state.results.length - 1 ? 0 : this.state.activeResultIndex + 1;
172
169
  return this.goToResult(nextIndex);
173
170
  }
174
171
  previousResult() {
175
- const state = this.getState();
176
- if (state.results.length === 0) {
172
+ if (this.state.results.length === 0) {
177
173
  return -1;
178
174
  }
179
- const prevIndex = state.activeResultIndex <= 0 ? state.results.length - 1 : state.activeResultIndex - 1;
175
+ const prevIndex = this.state.activeResultIndex <= 0 ? this.state.results.length - 1 : this.state.activeResultIndex - 1;
180
176
  return this.goToResult(prevIndex);
181
177
  }
182
178
  goToResult(index) {
183
- const state = this.getState();
184
- if (state.results.length === 0 || index < 0 || index >= state.results.length) {
179
+ if (this.state.results.length === 0 || index < 0 || index >= this.state.results.length) {
185
180
  return -1;
186
181
  }
187
182
  this.dispatch(setActiveResultIndex(index));
@@ -189,7 +184,7 @@ var SearchPlugin = class extends BasePlugin {
189
184
  return index;
190
185
  }
191
186
  async destroy() {
192
- if (this.getState().active && this.currentDocument) {
187
+ if (this.state.active && this.currentDocument) {
193
188
  this.stopSearchSession();
194
189
  }
195
190
  this.searchResult$.clear();
@@ -197,6 +192,7 @@ var SearchPlugin = class extends BasePlugin {
197
192
  this.searchStop$.clear();
198
193
  this.searchActiveResultChange$.clear();
199
194
  this.searchResultState$.clear();
195
+ this.searchState$.clear();
200
196
  }
201
197
  };
202
198
  SearchPlugin.id = "search";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/search-plugin.ts","../src/lib/actions.ts","../src/lib/manifest.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["import { BasePlugin, createBehaviorEmitter, PluginRegistry } from '@embedpdf/core';\nimport {\n MatchFlag,\n PdfDocumentObject,\n SearchAllPagesResult,\n TaskError,\n PdfEngine,\n} from '@embedpdf/models';\nimport { SearchPluginConfig, SearchCapability, SearchState, SearchResultState } from './types';\nimport { LoaderCapability, LoaderEvent, LoaderPlugin } from '@embedpdf/plugin-loader';\nimport {\n startSearchSession,\n stopSearchSession,\n setSearchFlags,\n setShowAllResults,\n startSearch,\n setSearchResults,\n setActiveResultIndex,\n SearchAction,\n} from './actions';\n\nexport class SearchPlugin extends BasePlugin<\n SearchPluginConfig,\n SearchCapability,\n SearchState,\n SearchAction\n> {\n static readonly id = 'search' as const;\n private loader: LoaderCapability;\n private currentDocument?: PdfDocumentObject;\n private engine: PdfEngine;\n\n private readonly searchStop$ = createBehaviorEmitter();\n private readonly searchStart$ = createBehaviorEmitter();\n private readonly searchResult$ = createBehaviorEmitter<SearchAllPagesResult>();\n private readonly searchActiveResultChange$ = createBehaviorEmitter<number>();\n private readonly searchResultState$ = createBehaviorEmitter<SearchResultState>();\n\n constructor(id: string, registry: PluginRegistry, engine: PdfEngine) {\n super(id, registry);\n this.engine = engine;\n this.loader = this.registry.getPlugin<LoaderPlugin>('loader')!.provides();\n\n this.loader.onDocumentLoaded(this.handleDocumentLoaded.bind(this));\n this.loader.onLoaderEvent(this.handleLoaderEvent.bind(this));\n }\n\n private handleDocumentLoaded(doc: PdfDocumentObject): void {\n this.currentDocument = doc;\n if (this.getState().active) {\n this.startSearchSession();\n }\n }\n\n private handleLoaderEvent(event: LoaderEvent): void {\n if (event.type === 'error' || (event.type === 'start' && this.currentDocument)) {\n if (this.getState().active) {\n this.stopSearchSession();\n }\n this.currentDocument = undefined;\n }\n }\n\n async initialize(config: SearchPluginConfig): Promise<void> {\n this.dispatch(setSearchFlags(config.flags || []));\n this.dispatch(\n setShowAllResults(config.showAllResults !== undefined ? config.showAllResults : true),\n );\n }\n\n override onStoreUpdated(_prevState: SearchState, newState: SearchState): void {\n this.searchResultState$.emit({\n results: newState.results,\n activeResultIndex: newState.activeResultIndex,\n showAllResults: newState.showAllResults,\n active: newState.active,\n });\n }\n\n protected buildCapability(): SearchCapability {\n return {\n startSearch: this.startSearchSession.bind(this),\n stopSearch: this.stopSearchSession.bind(this),\n searchAllPages: this.searchAllPages.bind(this),\n nextResult: this.nextResult.bind(this),\n previousResult: this.previousResult.bind(this),\n goToResult: this.goToResult.bind(this),\n setShowAllResults: (showAll) => this.dispatch(setShowAllResults(showAll)),\n getShowAllResults: () => this.getState().showAllResults,\n onSearchResult: this.searchResult$.on,\n onSearchStart: this.searchStart$.on,\n onSearchStop: this.searchStop$.on,\n onActiveResultChange: this.searchActiveResultChange$.on,\n onSearchResultStateChange: this.searchResultState$.on,\n onStateChange: (handler) => {\n const unsubscribe = this.subscribe((_, state) => handler(state));\n return unsubscribe;\n },\n getFlags: () => this.getState().flags,\n setFlags: (flags) => this.setFlags(flags),\n };\n }\n\n private setFlags(flags: MatchFlag[]): void {\n const state = this.getState();\n this.dispatch(setSearchFlags(flags));\n if (state.active) {\n this.searchAllPages(state.query, true);\n }\n }\n\n private notifySearchStart(): void {\n this.searchStart$.emit();\n }\n\n private notifySearchStop(): void {\n this.searchStop$.emit();\n }\n\n private notifyActiveResultChange(index: number): void {\n this.searchActiveResultChange$.emit(index);\n }\n\n private startSearchSession(): void {\n if (!this.currentDocument) {\n return;\n }\n this.dispatch(startSearchSession());\n this.notifySearchStart();\n }\n\n private stopSearchSession(): void {\n if (!this.currentDocument || !this.getState().active) {\n return;\n }\n this.dispatch(stopSearchSession());\n this.notifySearchStop();\n }\n\n private async searchAllPages(\n keyword: string,\n force: boolean = false,\n ): Promise<SearchAllPagesResult> {\n const trimmedKeyword = keyword.trim();\n const state = this.getState();\n\n if (state.query === trimmedKeyword && !force) {\n return { results: state.results, total: state.total };\n }\n\n this.dispatch(startSearch(trimmedKeyword));\n\n if (!trimmedKeyword) {\n this.dispatch(setSearchResults([], 0, -1));\n return { results: [], total: 0 };\n }\n if (!this.currentDocument) {\n this.dispatch(setSearchResults([], 0, -1));\n return { results: [], total: 0 };\n }\n\n if (!state.active) {\n this.startSearchSession();\n }\n\n return new Promise<SearchAllPagesResult>((resolve) => {\n this.engine.searchAllPages(this.currentDocument!, trimmedKeyword, state.flags).wait(\n (results) => {\n const activeResultIndex = results.total > 0 ? 0 : -1;\n this.dispatch(setSearchResults(results.results, results.total, activeResultIndex));\n this.searchResult$.emit(results);\n if (results.total > 0) {\n this.notifyActiveResultChange(0);\n }\n resolve(results);\n },\n (error: TaskError<any>) => {\n console.error('Error during search:', error);\n this.dispatch(setSearchResults([], 0, -1));\n resolve({ results: [], total: 0 });\n },\n );\n });\n }\n\n private nextResult(): number {\n const state = this.getState();\n if (state.results.length === 0) {\n return -1;\n }\n const nextIndex =\n state.activeResultIndex >= state.results.length - 1 ? 0 : state.activeResultIndex + 1;\n return this.goToResult(nextIndex);\n }\n\n private previousResult(): number {\n const state = this.getState();\n if (state.results.length === 0) {\n return -1;\n }\n const prevIndex =\n state.activeResultIndex <= 0 ? state.results.length - 1 : state.activeResultIndex - 1;\n return this.goToResult(prevIndex);\n }\n\n private goToResult(index: number): number {\n const state = this.getState();\n if (state.results.length === 0 || index < 0 || index >= state.results.length) {\n return -1;\n }\n this.dispatch(setActiveResultIndex(index));\n this.notifyActiveResultChange(index);\n return index;\n }\n\n async destroy(): Promise<void> {\n if (this.getState().active && this.currentDocument) {\n this.stopSearchSession();\n }\n this.searchResult$.clear();\n this.searchStart$.clear();\n this.searchStop$.clear();\n this.searchActiveResultChange$.clear();\n this.searchResultState$.clear();\n }\n}\n","import { Action } from '@embedpdf/core';\nimport { MatchFlag, SearchResult } from '@embedpdf/models';\n\n// Action Types\nexport const START_SEARCH_SESSION = 'START_SEARCH_SESSION';\nexport const STOP_SEARCH_SESSION = 'STOP_SEARCH_SESSION';\nexport const SET_SEARCH_FLAGS = 'SET_SEARCH_FLAGS';\nexport const SET_SHOW_ALL_RESULTS = 'SET_SHOW_ALL_RESULTS';\nexport const START_SEARCH = 'START_SEARCH';\nexport const SET_SEARCH_RESULTS = 'SET_SEARCH_RESULTS';\nexport const SET_ACTIVE_RESULT_INDEX = 'SET_ACTIVE_RESULT_INDEX';\n\n// Action Interfaces\nexport interface StartSearchSessionAction extends Action {\n type: typeof START_SEARCH_SESSION;\n}\n\nexport interface StopSearchSessionAction extends Action {\n type: typeof STOP_SEARCH_SESSION;\n}\n\nexport interface SetSearchFlagsAction extends Action {\n type: typeof SET_SEARCH_FLAGS;\n payload: MatchFlag[];\n}\n\nexport interface SetShowAllResultsAction extends Action {\n type: typeof SET_SHOW_ALL_RESULTS;\n payload: boolean;\n}\n\nexport interface StartSearchAction extends Action {\n type: typeof START_SEARCH;\n payload: string;\n}\n\nexport interface SetSearchResultsAction extends Action {\n type: typeof SET_SEARCH_RESULTS;\n payload: {\n results: SearchResult[];\n total: number;\n activeResultIndex: number;\n };\n}\n\nexport interface SetActiveResultIndexAction extends Action {\n type: typeof SET_ACTIVE_RESULT_INDEX;\n payload: number;\n}\n\n// Union Type for All Actions\nexport type SearchAction =\n | StartSearchSessionAction\n | StopSearchSessionAction\n | SetSearchFlagsAction\n | SetShowAllResultsAction\n | StartSearchAction\n | SetSearchResultsAction\n | SetActiveResultIndexAction;\n\n// Action Creators\nexport function startSearchSession(): StartSearchSessionAction {\n return { type: START_SEARCH_SESSION };\n}\n\nexport function stopSearchSession(): StopSearchSessionAction {\n return { type: STOP_SEARCH_SESSION };\n}\n\nexport function setSearchFlags(flags: MatchFlag[]): SetSearchFlagsAction {\n return { type: SET_SEARCH_FLAGS, payload: flags };\n}\n\nexport function setShowAllResults(showAll: boolean): SetShowAllResultsAction {\n return { type: SET_SHOW_ALL_RESULTS, payload: showAll };\n}\n\nexport function startSearch(query: string): StartSearchAction {\n return { type: START_SEARCH, payload: query };\n}\n\nexport function setSearchResults(\n results: SearchResult[],\n total: number,\n activeResultIndex: number,\n): SetSearchResultsAction {\n return { type: SET_SEARCH_RESULTS, payload: { results, total, activeResultIndex } };\n}\n\nexport function setActiveResultIndex(index: number): SetActiveResultIndexAction {\n return { type: SET_ACTIVE_RESULT_INDEX, payload: index };\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { SearchPluginConfig } from './types';\n\nexport const SEARCH_PLUGIN_ID = 'search';\n\nexport const manifest: PluginManifest<SearchPluginConfig> = {\n id: SEARCH_PLUGIN_ID,\n name: 'Search Plugin',\n version: '1.0.0',\n provides: ['search'],\n requires: ['loader'],\n optional: [],\n defaultConfig: {\n enabled: true,\n flags: [],\n },\n};\n","import { Reducer } from '@embedpdf/core';\nimport { SearchState } from './types';\nimport {\n START_SEARCH_SESSION,\n STOP_SEARCH_SESSION,\n SET_SEARCH_FLAGS,\n SET_SHOW_ALL_RESULTS,\n START_SEARCH,\n SET_SEARCH_RESULTS,\n SET_ACTIVE_RESULT_INDEX,\n SearchAction,\n} from './actions';\n\nexport const initialState: SearchState = {\n flags: [],\n results: [],\n total: 0,\n activeResultIndex: -1,\n showAllResults: true,\n query: '',\n loading: false,\n active: false,\n};\n\nexport const searchReducer: Reducer<SearchState, SearchAction> = (state = initialState, action) => {\n switch (action.type) {\n case START_SEARCH_SESSION:\n return { ...state, active: true };\n\n case STOP_SEARCH_SESSION:\n return {\n ...state,\n results: [],\n total: 0,\n activeResultIndex: -1,\n query: '',\n loading: false,\n active: false,\n };\n\n case SET_SEARCH_FLAGS:\n return { ...state, flags: action.payload };\n\n case SET_SHOW_ALL_RESULTS:\n return { ...state, showAllResults: action.payload };\n\n case START_SEARCH:\n return { ...state, loading: true, query: action.payload };\n\n case SET_SEARCH_RESULTS:\n return {\n ...state,\n results: action.payload.results,\n total: action.payload.total,\n activeResultIndex: action.payload.activeResultIndex,\n loading: false,\n };\n\n case SET_ACTIVE_RESULT_INDEX:\n return { ...state, activeResultIndex: action.payload };\n\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { SearchPlugin } from './search-plugin';\nimport { manifest, SEARCH_PLUGIN_ID } from './manifest';\nimport { SearchPluginConfig, SearchState } from './types';\nimport { searchReducer, initialState } from './reducer';\nimport { SearchAction } from './actions';\n\nexport const SearchPluginPackage: PluginPackage<\n SearchPlugin,\n SearchPluginConfig,\n SearchState,\n SearchAction\n> = {\n manifest,\n create: (registry, engine) => new SearchPlugin(SEARCH_PLUGIN_ID, registry, engine),\n reducer: searchReducer,\n initialState,\n};\n\nexport * from './search-plugin';\nexport * from './types';\nexport * from './manifest';\nexport { initialState };\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/lib/search-plugin.ts","../src/lib/actions.ts","../src/lib/manifest.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["import { BasePlugin, createBehaviorEmitter, PluginRegistry } from '@embedpdf/core';\nimport {\n MatchFlag,\n PdfDocumentObject,\n SearchAllPagesResult,\n TaskError,\n PdfEngine,\n} from '@embedpdf/models';\nimport { SearchPluginConfig, SearchCapability, SearchState, SearchResultState } from './types';\nimport { LoaderCapability, LoaderEvent, LoaderPlugin } from '@embedpdf/plugin-loader';\nimport {\n startSearchSession,\n stopSearchSession,\n setSearchFlags,\n setShowAllResults,\n startSearch,\n setSearchResults,\n setActiveResultIndex,\n SearchAction,\n} from './actions';\n\nexport class SearchPlugin extends BasePlugin<\n SearchPluginConfig,\n SearchCapability,\n SearchState,\n SearchAction\n> {\n static readonly id = 'search' as const;\n private loader: LoaderCapability;\n private currentDocument?: PdfDocumentObject;\n private engine: PdfEngine;\n\n private readonly searchStop$ = createBehaviorEmitter();\n private readonly searchStart$ = createBehaviorEmitter();\n private readonly searchResult$ = createBehaviorEmitter<SearchAllPagesResult>();\n private readonly searchActiveResultChange$ = createBehaviorEmitter<number>();\n private readonly searchResultState$ = createBehaviorEmitter<SearchResultState>();\n private readonly searchState$ = createBehaviorEmitter<SearchState>();\n\n constructor(id: string, registry: PluginRegistry, engine: PdfEngine) {\n super(id, registry);\n this.engine = engine;\n this.loader = this.registry.getPlugin<LoaderPlugin>('loader')!.provides();\n\n this.loader.onDocumentLoaded(this.handleDocumentLoaded.bind(this));\n this.loader.onLoaderEvent(this.handleLoaderEvent.bind(this));\n }\n\n private handleDocumentLoaded(doc: PdfDocumentObject): void {\n this.currentDocument = doc;\n if (this.state.active) {\n this.startSearchSession();\n }\n }\n\n private handleLoaderEvent(event: LoaderEvent): void {\n if (event.type === 'error' || (event.type === 'start' && this.currentDocument)) {\n if (this.state.active) {\n this.stopSearchSession();\n }\n this.currentDocument = undefined;\n }\n }\n\n async initialize(config: SearchPluginConfig): Promise<void> {\n this.dispatch(setSearchFlags(config.flags || []));\n this.dispatch(\n setShowAllResults(config.showAllResults !== undefined ? config.showAllResults : true),\n );\n }\n\n override onStoreUpdated(_prevState: SearchState, newState: SearchState): void {\n this.searchResultState$.emit({\n results: newState.results,\n activeResultIndex: newState.activeResultIndex,\n showAllResults: newState.showAllResults,\n active: newState.active,\n });\n this.searchState$.emit(newState);\n }\n\n protected buildCapability(): SearchCapability {\n return {\n startSearch: this.startSearchSession.bind(this),\n stopSearch: this.stopSearchSession.bind(this),\n searchAllPages: this.searchAllPages.bind(this),\n nextResult: this.nextResult.bind(this),\n previousResult: this.previousResult.bind(this),\n goToResult: this.goToResult.bind(this),\n setShowAllResults: (showAll) => this.dispatch(setShowAllResults(showAll)),\n getShowAllResults: () => this.state.showAllResults,\n onSearchResult: this.searchResult$.on,\n onSearchStart: this.searchStart$.on,\n onSearchStop: this.searchStop$.on,\n onActiveResultChange: this.searchActiveResultChange$.on,\n onSearchResultStateChange: this.searchResultState$.on,\n onStateChange: this.searchState$.on,\n getFlags: () => this.state.flags,\n setFlags: (flags) => this.setFlags(flags),\n getState: () => this.state,\n };\n }\n\n private setFlags(flags: MatchFlag[]): void {\n this.dispatch(setSearchFlags(flags));\n if (this.state.active) {\n this.searchAllPages(this.state.query, true);\n }\n }\n\n private notifySearchStart(): void {\n this.searchStart$.emit();\n }\n\n private notifySearchStop(): void {\n this.searchStop$.emit();\n }\n\n private notifyActiveResultChange(index: number): void {\n this.searchActiveResultChange$.emit(index);\n }\n\n private startSearchSession(): void {\n if (!this.currentDocument) {\n return;\n }\n this.dispatch(startSearchSession());\n this.notifySearchStart();\n }\n\n private stopSearchSession(): void {\n if (!this.currentDocument || !this.getState().active) {\n return;\n }\n this.dispatch(stopSearchSession());\n this.notifySearchStop();\n }\n\n private async searchAllPages(\n keyword: string,\n force: boolean = false,\n ): Promise<SearchAllPagesResult> {\n const trimmedKeyword = keyword.trim();\n\n if (this.state.query === trimmedKeyword && !force) {\n return { results: this.state.results, total: this.state.total };\n }\n\n this.dispatch(startSearch(trimmedKeyword));\n\n if (!trimmedKeyword) {\n this.dispatch(setSearchResults([], 0, -1));\n return { results: [], total: 0 };\n }\n if (!this.currentDocument) {\n this.dispatch(setSearchResults([], 0, -1));\n return { results: [], total: 0 };\n }\n\n if (!this.state.active) {\n this.startSearchSession();\n }\n\n return new Promise<SearchAllPagesResult>((resolve) => {\n this.engine.searchAllPages(this.currentDocument!, trimmedKeyword, this.state.flags).wait(\n (results) => {\n const activeResultIndex = results.total > 0 ? 0 : -1;\n this.dispatch(setSearchResults(results.results, results.total, activeResultIndex));\n this.searchResult$.emit(results);\n if (results.total > 0) {\n this.notifyActiveResultChange(0);\n }\n resolve(results);\n },\n (error: TaskError<any>) => {\n console.error('Error during search:', error);\n this.dispatch(setSearchResults([], 0, -1));\n resolve({ results: [], total: 0 });\n },\n );\n });\n }\n\n private nextResult(): number {\n if (this.state.results.length === 0) {\n return -1;\n }\n const nextIndex =\n this.state.activeResultIndex >= this.state.results.length - 1\n ? 0\n : this.state.activeResultIndex + 1;\n return this.goToResult(nextIndex);\n }\n\n private previousResult(): number {\n if (this.state.results.length === 0) {\n return -1;\n }\n const prevIndex =\n this.state.activeResultIndex <= 0\n ? this.state.results.length - 1\n : this.state.activeResultIndex - 1;\n return this.goToResult(prevIndex);\n }\n\n private goToResult(index: number): number {\n if (this.state.results.length === 0 || index < 0 || index >= this.state.results.length) {\n return -1;\n }\n this.dispatch(setActiveResultIndex(index));\n this.notifyActiveResultChange(index);\n return index;\n }\n\n async destroy(): Promise<void> {\n if (this.state.active && this.currentDocument) {\n this.stopSearchSession();\n }\n this.searchResult$.clear();\n this.searchStart$.clear();\n this.searchStop$.clear();\n this.searchActiveResultChange$.clear();\n this.searchResultState$.clear();\n this.searchState$.clear();\n }\n}\n","import { Action } from '@embedpdf/core';\nimport { MatchFlag, SearchResult } from '@embedpdf/models';\n\n// Action Types\nexport const START_SEARCH_SESSION = 'START_SEARCH_SESSION';\nexport const STOP_SEARCH_SESSION = 'STOP_SEARCH_SESSION';\nexport const SET_SEARCH_FLAGS = 'SET_SEARCH_FLAGS';\nexport const SET_SHOW_ALL_RESULTS = 'SET_SHOW_ALL_RESULTS';\nexport const START_SEARCH = 'START_SEARCH';\nexport const SET_SEARCH_RESULTS = 'SET_SEARCH_RESULTS';\nexport const SET_ACTIVE_RESULT_INDEX = 'SET_ACTIVE_RESULT_INDEX';\n\n// Action Interfaces\nexport interface StartSearchSessionAction extends Action {\n type: typeof START_SEARCH_SESSION;\n}\n\nexport interface StopSearchSessionAction extends Action {\n type: typeof STOP_SEARCH_SESSION;\n}\n\nexport interface SetSearchFlagsAction extends Action {\n type: typeof SET_SEARCH_FLAGS;\n payload: MatchFlag[];\n}\n\nexport interface SetShowAllResultsAction extends Action {\n type: typeof SET_SHOW_ALL_RESULTS;\n payload: boolean;\n}\n\nexport interface StartSearchAction extends Action {\n type: typeof START_SEARCH;\n payload: string;\n}\n\nexport interface SetSearchResultsAction extends Action {\n type: typeof SET_SEARCH_RESULTS;\n payload: {\n results: SearchResult[];\n total: number;\n activeResultIndex: number;\n };\n}\n\nexport interface SetActiveResultIndexAction extends Action {\n type: typeof SET_ACTIVE_RESULT_INDEX;\n payload: number;\n}\n\n// Union Type for All Actions\nexport type SearchAction =\n | StartSearchSessionAction\n | StopSearchSessionAction\n | SetSearchFlagsAction\n | SetShowAllResultsAction\n | StartSearchAction\n | SetSearchResultsAction\n | SetActiveResultIndexAction;\n\n// Action Creators\nexport function startSearchSession(): StartSearchSessionAction {\n return { type: START_SEARCH_SESSION };\n}\n\nexport function stopSearchSession(): StopSearchSessionAction {\n return { type: STOP_SEARCH_SESSION };\n}\n\nexport function setSearchFlags(flags: MatchFlag[]): SetSearchFlagsAction {\n return { type: SET_SEARCH_FLAGS, payload: flags };\n}\n\nexport function setShowAllResults(showAll: boolean): SetShowAllResultsAction {\n return { type: SET_SHOW_ALL_RESULTS, payload: showAll };\n}\n\nexport function startSearch(query: string): StartSearchAction {\n return { type: START_SEARCH, payload: query };\n}\n\nexport function setSearchResults(\n results: SearchResult[],\n total: number,\n activeResultIndex: number,\n): SetSearchResultsAction {\n return { type: SET_SEARCH_RESULTS, payload: { results, total, activeResultIndex } };\n}\n\nexport function setActiveResultIndex(index: number): SetActiveResultIndexAction {\n return { type: SET_ACTIVE_RESULT_INDEX, payload: index };\n}\n","import { PluginManifest } from '@embedpdf/core';\nimport { SearchPluginConfig } from './types';\n\nexport const SEARCH_PLUGIN_ID = 'search';\n\nexport const manifest: PluginManifest<SearchPluginConfig> = {\n id: SEARCH_PLUGIN_ID,\n name: 'Search Plugin',\n version: '1.0.0',\n provides: ['search'],\n requires: ['loader'],\n optional: [],\n defaultConfig: {\n enabled: true,\n flags: [],\n },\n};\n","import { Reducer } from '@embedpdf/core';\nimport { SearchState } from './types';\nimport {\n START_SEARCH_SESSION,\n STOP_SEARCH_SESSION,\n SET_SEARCH_FLAGS,\n SET_SHOW_ALL_RESULTS,\n START_SEARCH,\n SET_SEARCH_RESULTS,\n SET_ACTIVE_RESULT_INDEX,\n SearchAction,\n} from './actions';\n\nexport const initialState: SearchState = {\n flags: [],\n results: [],\n total: 0,\n activeResultIndex: -1,\n showAllResults: true,\n query: '',\n loading: false,\n active: false,\n};\n\nexport const searchReducer: Reducer<SearchState, SearchAction> = (state = initialState, action) => {\n switch (action.type) {\n case START_SEARCH_SESSION:\n return { ...state, active: true };\n\n case STOP_SEARCH_SESSION:\n return {\n ...state,\n results: [],\n total: 0,\n activeResultIndex: -1,\n query: '',\n loading: false,\n active: false,\n };\n\n case SET_SEARCH_FLAGS:\n return { ...state, flags: action.payload };\n\n case SET_SHOW_ALL_RESULTS:\n return { ...state, showAllResults: action.payload };\n\n case START_SEARCH:\n return { ...state, loading: true, query: action.payload };\n\n case SET_SEARCH_RESULTS:\n return {\n ...state,\n results: action.payload.results,\n total: action.payload.total,\n activeResultIndex: action.payload.activeResultIndex,\n loading: false,\n };\n\n case SET_ACTIVE_RESULT_INDEX:\n return { ...state, activeResultIndex: action.payload };\n\n default:\n return state;\n }\n};\n","import { PluginPackage } from '@embedpdf/core';\nimport { SearchPlugin } from './search-plugin';\nimport { manifest, SEARCH_PLUGIN_ID } from './manifest';\nimport { SearchPluginConfig, SearchState } from './types';\nimport { searchReducer, initialState } from './reducer';\nimport { SearchAction } from './actions';\n\nexport const SearchPluginPackage: PluginPackage<\n SearchPlugin,\n SearchPluginConfig,\n SearchState,\n SearchAction\n> = {\n manifest,\n create: (registry, engine) => new SearchPlugin(SEARCH_PLUGIN_ID, registry, engine),\n reducer: searchReducer,\n initialState,\n};\n\nexport * from './search-plugin';\nexport * from './types';\nexport * from './manifest';\nexport { initialState };\n"],"mappings":"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","names":[]}
@@ -22,18 +22,40 @@ var preact_exports = {};
22
22
  __export(preact_exports, {
23
23
  SearchLayer: () => SearchLayer,
24
24
  useSearch: () => useSearch,
25
- useSearchCapability: () => useSearchCapability
25
+ useSearchCapability: () => useSearchCapability,
26
+ useSearchPlugin: () => useSearchPlugin
26
27
  });
27
28
  module.exports = __toCommonJS(preact_exports);
28
29
 
29
30
  // src/preact/hooks/use-search.ts
30
31
  var import_preact = require("@embedpdf/core/preact");
31
32
  var import_plugin_search = require("@embedpdf/plugin-search");
32
- var useSearch = () => (0, import_preact.usePlugin)(import_plugin_search.SearchPlugin.id);
33
+ var import_hooks = require("preact/hooks");
34
+ var useSearchPlugin = () => (0, import_preact.usePlugin)(import_plugin_search.SearchPlugin.id);
33
35
  var useSearchCapability = () => (0, import_preact.useCapability)(import_plugin_search.SearchPlugin.id);
36
+ var useSearch = () => {
37
+ const { provides } = useSearchCapability();
38
+ const [searchState, setSearchState] = (0, import_hooks.useState)({
39
+ flags: [],
40
+ results: [],
41
+ total: 0,
42
+ activeResultIndex: 0,
43
+ showAllResults: true,
44
+ query: "",
45
+ loading: false,
46
+ active: false
47
+ });
48
+ (0, import_hooks.useEffect)(() => {
49
+ return provides?.onStateChange((state) => setSearchState(state));
50
+ }, [provides]);
51
+ return {
52
+ state: searchState,
53
+ provides
54
+ };
55
+ };
34
56
 
35
57
  // src/preact/components/search-layer.tsx
36
- var import_hooks = require("preact/hooks");
58
+ var import_hooks2 = require("preact/hooks");
37
59
  var import_jsx_runtime = require("preact/jsx-runtime");
38
60
  function SearchLayer({
39
61
  pageIndex,
@@ -44,8 +66,8 @@ function SearchLayer({
44
66
  ...props
45
67
  }) {
46
68
  const { provides: searchProvides } = useSearchCapability();
47
- const [searchResultState, setSearchResultState] = (0, import_hooks.useState)(null);
48
- (0, import_hooks.useEffect)(() => {
69
+ const [searchResultState, setSearchResultState] = (0, import_hooks2.useState)(null);
70
+ (0, import_hooks2.useEffect)(() => {
49
71
  return searchProvides?.onSearchResultStateChange((state) => {
50
72
  setSearchResultState(state);
51
73
  });
@@ -88,6 +110,7 @@ function SearchLayer({
88
110
  0 && (module.exports = {
89
111
  SearchLayer,
90
112
  useSearch,
91
- useSearchCapability
113
+ useSearchCapability,
114
+ useSearchPlugin
92
115
  });
93
116
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/preact/index.ts","../../src/preact/hooks/use-search.ts","../../src/preact/components/search-layer.tsx"],"sourcesContent":["export * from './hooks';\nexport * from './components';\n","import { useCapability, usePlugin } from '@embedpdf/core/preact';\nimport { SearchPlugin } from '@embedpdf/plugin-search';\n\nexport const useSearch = () => usePlugin<SearchPlugin>(SearchPlugin.id);\nexport const useSearchCapability = () => useCapability<SearchPlugin>(SearchPlugin.id);\n","/** @jsxImportSource preact */\nimport { ComponentChildren, Fragment, JSX } from 'preact';\nimport { useEffect, useRef, useState } from 'preact/hooks';\nimport { SearchResultState } from '@embedpdf/plugin-search';\n\nimport { useSearchCapability } from '../hooks';\n\ntype SearchLayoutProps = Omit<JSX.HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n style?: JSX.CSSProperties;\n};\n\nexport function SearchLayer({\n pageIndex,\n scale,\n style,\n highlightColor = '#FFFF00',\n activeHighlightColor = '#FFBF00',\n ...props\n}: SearchLayoutProps) {\n const { provides: searchProvides } = useSearchCapability();\n const [searchResultState, setSearchResultState] = useState<SearchResultState | null>(null);\n\n useEffect(() => {\n return searchProvides?.onSearchResultStateChange((state) => {\n setSearchResultState(state);\n });\n }, [searchProvides]);\n\n if (!searchResultState) {\n return null;\n }\n\n // Filter results for current page while preserving original indices\n const pageResults = searchResultState.results\n .map((result, originalIndex) => ({ result, originalIndex }))\n .filter(({ result }) => result.pageIndex === pageIndex);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {pageResults.map(({ result, originalIndex }) =>\n result.rects.map((rect) => (\n <div\n style={{\n position: 'absolute',\n top: rect.origin.y * scale,\n left: rect.origin.x * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n backgroundColor:\n originalIndex === searchResultState.activeResultIndex\n ? activeHighlightColor\n : highlightColor,\n mixBlendMode: 'multiply',\n transform: 'scale(1.02)',\n transformOrigin: 'center',\n transition: 'opacity .3s ease-in-out',\n opacity: 1,\n }}\n ></div>\n )),\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,oBAAyC;AACzC,2BAA6B;AAEtB,IAAM,YAAY,UAAM,yBAAwB,kCAAa,EAAE;AAC/D,IAAM,sBAAsB,UAAM,6BAA4B,kCAAa,EAAE;;;ACFpF,mBAA4C;AAgDlC;AAnCH,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,uBAAuB;AAAA,EACvB,GAAG;AACL,GAAsB;AACpB,QAAM,EAAE,UAAU,eAAe,IAAI,oBAAoB;AACzD,QAAM,CAAC,mBAAmB,oBAAoB,QAAI,uBAAmC,IAAI;AAEzF,8BAAU,MAAM;AACd,WAAO,gBAAgB,0BAA0B,CAAC,UAAU;AAC1D,2BAAqB,KAAK;AAAA,IAC5B,CAAC;AAAA,EACH,GAAG,CAAC,cAAc,CAAC;AAEnB,MAAI,CAAC,mBAAmB;AACtB,WAAO;AAAA,EACT;AAGA,QAAM,cAAc,kBAAkB,QACnC,IAAI,CAAC,QAAQ,mBAAmB,EAAE,QAAQ,cAAc,EAAE,EAC1D,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,cAAc,SAAS;AAExD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA,MAEH,sBAAY;AAAA,QAAI,CAAC,EAAE,QAAQ,cAAc,MACxC,OAAO,MAAM,IAAI,CAAC,SAChB;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,KAAK,KAAK,OAAO,IAAI;AAAA,cACrB,MAAM,KAAK,OAAO,IAAI;AAAA,cACtB,OAAO,KAAK,KAAK,QAAQ;AAAA,cACzB,QAAQ,KAAK,KAAK,SAAS;AAAA,cAC3B,iBACE,kBAAkB,kBAAkB,oBAChC,uBACA;AAAA,cACN,cAAc;AAAA,cACd,WAAW;AAAA,cACX,iBAAiB;AAAA,cACjB,YAAY;AAAA,cACZ,SAAS;AAAA,YACX;AAAA;AAAA,QACD,CACF;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/preact/index.ts","../../src/preact/hooks/use-search.ts","../../src/preact/components/search-layer.tsx"],"sourcesContent":["export * from './hooks';\nexport * from './components';\n","import { useCapability, usePlugin } from '@embedpdf/core/preact';\nimport { SearchPlugin, SearchState } from '@embedpdf/plugin-search';\nimport { useEffect, useState } from 'preact/hooks';\n\nexport const useSearchPlugin = () => usePlugin<SearchPlugin>(SearchPlugin.id);\nexport const useSearchCapability = () => useCapability<SearchPlugin>(SearchPlugin.id);\n\nexport const useSearch = () => {\n const { provides } = useSearchCapability();\n const [searchState, setSearchState] = useState<SearchState>({\n flags: [],\n results: [],\n total: 0,\n activeResultIndex: 0,\n showAllResults: true,\n query: '',\n loading: false,\n active: false,\n });\n\n useEffect(() => {\n return provides?.onStateChange((state) => setSearchState(state));\n }, [provides]);\n\n return {\n state: searchState,\n provides,\n };\n};\n","/** @jsxImportSource preact */\nimport { ComponentChildren, Fragment, JSX } from 'preact';\nimport { useEffect, useRef, useState } from 'preact/hooks';\nimport { SearchResultState } from '@embedpdf/plugin-search';\n\nimport { useSearchCapability } from '../hooks';\n\ntype SearchLayoutProps = Omit<JSX.HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n style?: JSX.CSSProperties;\n};\n\nexport function SearchLayer({\n pageIndex,\n scale,\n style,\n highlightColor = '#FFFF00',\n activeHighlightColor = '#FFBF00',\n ...props\n}: SearchLayoutProps) {\n const { provides: searchProvides } = useSearchCapability();\n const [searchResultState, setSearchResultState] = useState<SearchResultState | null>(null);\n\n useEffect(() => {\n return searchProvides?.onSearchResultStateChange((state) => {\n setSearchResultState(state);\n });\n }, [searchProvides]);\n\n if (!searchResultState) {\n return null;\n }\n\n // Filter results for current page while preserving original indices\n const pageResults = searchResultState.results\n .map((result, originalIndex) => ({ result, originalIndex }))\n .filter(({ result }) => result.pageIndex === pageIndex);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {pageResults.map(({ result, originalIndex }) =>\n result.rects.map((rect) => (\n <div\n style={{\n position: 'absolute',\n top: rect.origin.y * scale,\n left: rect.origin.x * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n backgroundColor:\n originalIndex === searchResultState.activeResultIndex\n ? activeHighlightColor\n : highlightColor,\n mixBlendMode: 'multiply',\n transform: 'scale(1.02)',\n transformOrigin: 'center',\n transition: 'opacity .3s ease-in-out',\n opacity: 1,\n }}\n ></div>\n )),\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,oBAAyC;AACzC,2BAA0C;AAC1C,mBAAoC;AAE7B,IAAM,kBAAkB,UAAM,yBAAwB,kCAAa,EAAE;AACrE,IAAM,sBAAsB,UAAM,6BAA4B,kCAAa,EAAE;AAE7E,IAAM,YAAY,MAAM;AAC7B,QAAM,EAAE,SAAS,IAAI,oBAAoB;AACzC,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAsB;AAAA,IAC1D,OAAO,CAAC;AAAA,IACR,SAAS,CAAC;AAAA,IACV,OAAO;AAAA,IACP,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,OAAO;AAAA,IACP,SAAS;AAAA,IACT,QAAQ;AAAA,EACV,CAAC;AAED,8BAAU,MAAM;AACd,WAAO,UAAU,cAAc,CAAC,UAAU,eAAe,KAAK,CAAC;AAAA,EACjE,GAAG,CAAC,QAAQ,CAAC;AAEb,SAAO;AAAA,IACL,OAAO;AAAA,IACP;AAAA,EACF;AACF;;;AC1BA,IAAAA,gBAA4C;AAgDlC;AAnCH,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,uBAAuB;AAAA,EACvB,GAAG;AACL,GAAsB;AACpB,QAAM,EAAE,UAAU,eAAe,IAAI,oBAAoB;AACzD,QAAM,CAAC,mBAAmB,oBAAoB,QAAI,wBAAmC,IAAI;AAEzF,+BAAU,MAAM;AACd,WAAO,gBAAgB,0BAA0B,CAAC,UAAU;AAC1D,2BAAqB,KAAK;AAAA,IAC5B,CAAC;AAAA,EACH,GAAG,CAAC,cAAc,CAAC;AAEnB,MAAI,CAAC,mBAAmB;AACtB,WAAO;AAAA,EACT;AAGA,QAAM,cAAc,kBAAkB,QACnC,IAAI,CAAC,QAAQ,mBAAmB,EAAE,QAAQ,cAAc,EAAE,EAC1D,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,cAAc,SAAS;AAExD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA,MAEH,sBAAY;AAAA,QAAI,CAAC,EAAE,QAAQ,cAAc,MACxC,OAAO,MAAM,IAAI,CAAC,SAChB;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,KAAK,KAAK,OAAO,IAAI;AAAA,cACrB,MAAM,KAAK,OAAO,IAAI;AAAA,cACtB,OAAO,KAAK,KAAK,QAAQ;AAAA,cACzB,QAAQ,KAAK,KAAK,SAAS;AAAA,cAC3B,iBACE,kBAAkB,kBAAkB,oBAChC,uBACA;AAAA,cACN,cAAc;AAAA,cACd,WAAW;AAAA,cACX,iBAAiB;AAAA,cACjB,YAAY;AAAA,cACZ,SAAS;AAAA,YACX;AAAA;AAAA,QACD,CACF;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;","names":["import_hooks"]}
@@ -1,8 +1,8 @@
1
1
  import * as _embedpdf_plugin_search from '@embedpdf/plugin-search';
2
- import { SearchPlugin } from '@embedpdf/plugin-search';
2
+ import { SearchPlugin, SearchState } from '@embedpdf/plugin-search';
3
3
  import { JSX } from 'preact';
4
4
 
5
- declare const useSearch: () => {
5
+ declare const useSearchPlugin: () => {
6
6
  plugin: SearchPlugin | null;
7
7
  isLoading: boolean;
8
8
  ready: Promise<void>;
@@ -12,6 +12,10 @@ declare const useSearchCapability: () => {
12
12
  isLoading: boolean;
13
13
  ready: Promise<void>;
14
14
  };
15
+ declare const useSearch: () => {
16
+ state: SearchState;
17
+ provides: Readonly<_embedpdf_plugin_search.SearchCapability> | null;
18
+ };
15
19
 
16
20
  /** @jsxImportSource preact */
17
21
 
@@ -24,4 +28,4 @@ type SearchLayoutProps = Omit<JSX.HTMLAttributes<HTMLDivElement>, 'style'> & {
24
28
  };
25
29
  declare function SearchLayer({ pageIndex, scale, style, highlightColor, activeHighlightColor, ...props }: SearchLayoutProps): JSX.Element | null;
26
30
 
27
- export { SearchLayer, useSearch, useSearchCapability };
31
+ export { SearchLayer, useSearch, useSearchCapability, useSearchPlugin };
@@ -1,8 +1,8 @@
1
1
  import * as _embedpdf_plugin_search from '@embedpdf/plugin-search';
2
- import { SearchPlugin } from '@embedpdf/plugin-search';
2
+ import { SearchPlugin, SearchState } from '@embedpdf/plugin-search';
3
3
  import { JSX } from 'preact';
4
4
 
5
- declare const useSearch: () => {
5
+ declare const useSearchPlugin: () => {
6
6
  plugin: SearchPlugin | null;
7
7
  isLoading: boolean;
8
8
  ready: Promise<void>;
@@ -12,6 +12,10 @@ declare const useSearchCapability: () => {
12
12
  isLoading: boolean;
13
13
  ready: Promise<void>;
14
14
  };
15
+ declare const useSearch: () => {
16
+ state: SearchState;
17
+ provides: Readonly<_embedpdf_plugin_search.SearchCapability> | null;
18
+ };
15
19
 
16
20
  /** @jsxImportSource preact */
17
21
 
@@ -24,4 +28,4 @@ type SearchLayoutProps = Omit<JSX.HTMLAttributes<HTMLDivElement>, 'style'> & {
24
28
  };
25
29
  declare function SearchLayer({ pageIndex, scale, style, highlightColor, activeHighlightColor, ...props }: SearchLayoutProps): JSX.Element | null;
26
30
 
27
- export { SearchLayer, useSearch, useSearchCapability };
31
+ export { SearchLayer, useSearch, useSearchCapability, useSearchPlugin };
@@ -1,11 +1,32 @@
1
1
  // src/preact/hooks/use-search.ts
2
2
  import { useCapability, usePlugin } from "@embedpdf/core/preact";
3
3
  import { SearchPlugin } from "@embedpdf/plugin-search";
4
- var useSearch = () => usePlugin(SearchPlugin.id);
4
+ import { useEffect, useState } from "preact/hooks";
5
+ var useSearchPlugin = () => usePlugin(SearchPlugin.id);
5
6
  var useSearchCapability = () => useCapability(SearchPlugin.id);
7
+ var useSearch = () => {
8
+ const { provides } = useSearchCapability();
9
+ const [searchState, setSearchState] = useState({
10
+ flags: [],
11
+ results: [],
12
+ total: 0,
13
+ activeResultIndex: 0,
14
+ showAllResults: true,
15
+ query: "",
16
+ loading: false,
17
+ active: false
18
+ });
19
+ useEffect(() => {
20
+ return provides?.onStateChange((state) => setSearchState(state));
21
+ }, [provides]);
22
+ return {
23
+ state: searchState,
24
+ provides
25
+ };
26
+ };
6
27
 
7
28
  // src/preact/components/search-layer.tsx
8
- import { useEffect, useState } from "preact/hooks";
29
+ import { useEffect as useEffect2, useState as useState2 } from "preact/hooks";
9
30
  import { jsx } from "preact/jsx-runtime";
10
31
  function SearchLayer({
11
32
  pageIndex,
@@ -16,8 +37,8 @@ function SearchLayer({
16
37
  ...props
17
38
  }) {
18
39
  const { provides: searchProvides } = useSearchCapability();
19
- const [searchResultState, setSearchResultState] = useState(null);
20
- useEffect(() => {
40
+ const [searchResultState, setSearchResultState] = useState2(null);
41
+ useEffect2(() => {
21
42
  return searchProvides?.onSearchResultStateChange((state) => {
22
43
  setSearchResultState(state);
23
44
  });
@@ -59,6 +80,7 @@ function SearchLayer({
59
80
  export {
60
81
  SearchLayer,
61
82
  useSearch,
62
- useSearchCapability
83
+ useSearchCapability,
84
+ useSearchPlugin
63
85
  };
64
86
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/preact/hooks/use-search.ts","../../src/preact/components/search-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/preact';\nimport { SearchPlugin } from '@embedpdf/plugin-search';\n\nexport const useSearch = () => usePlugin<SearchPlugin>(SearchPlugin.id);\nexport const useSearchCapability = () => useCapability<SearchPlugin>(SearchPlugin.id);\n","/** @jsxImportSource preact */\nimport { ComponentChildren, Fragment, JSX } from 'preact';\nimport { useEffect, useRef, useState } from 'preact/hooks';\nimport { SearchResultState } from '@embedpdf/plugin-search';\n\nimport { useSearchCapability } from '../hooks';\n\ntype SearchLayoutProps = Omit<JSX.HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n style?: JSX.CSSProperties;\n};\n\nexport function SearchLayer({\n pageIndex,\n scale,\n style,\n highlightColor = '#FFFF00',\n activeHighlightColor = '#FFBF00',\n ...props\n}: SearchLayoutProps) {\n const { provides: searchProvides } = useSearchCapability();\n const [searchResultState, setSearchResultState] = useState<SearchResultState | null>(null);\n\n useEffect(() => {\n return searchProvides?.onSearchResultStateChange((state) => {\n setSearchResultState(state);\n });\n }, [searchProvides]);\n\n if (!searchResultState) {\n return null;\n }\n\n // Filter results for current page while preserving original indices\n const pageResults = searchResultState.results\n .map((result, originalIndex) => ({ result, originalIndex }))\n .filter(({ result }) => result.pageIndex === pageIndex);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {pageResults.map(({ result, originalIndex }) =>\n result.rects.map((rect) => (\n <div\n style={{\n position: 'absolute',\n top: rect.origin.y * scale,\n left: rect.origin.x * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n backgroundColor:\n originalIndex === searchResultState.activeResultIndex\n ? activeHighlightColor\n : highlightColor,\n mixBlendMode: 'multiply',\n transform: 'scale(1.02)',\n transformOrigin: 'center',\n transition: 'opacity .3s ease-in-out',\n opacity: 1,\n }}\n ></div>\n )),\n )}\n </div>\n );\n}\n"],"mappings":";AAAA,SAAS,eAAe,iBAAiB;AACzC,SAAS,oBAAoB;AAEtB,IAAM,YAAY,MAAM,UAAwB,aAAa,EAAE;AAC/D,IAAM,sBAAsB,MAAM,cAA4B,aAAa,EAAE;;;ACFpF,SAAS,WAAmB,gBAAgB;AAgDlC;AAnCH,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,uBAAuB;AAAA,EACvB,GAAG;AACL,GAAsB;AACpB,QAAM,EAAE,UAAU,eAAe,IAAI,oBAAoB;AACzD,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,SAAmC,IAAI;AAEzF,YAAU,MAAM;AACd,WAAO,gBAAgB,0BAA0B,CAAC,UAAU;AAC1D,2BAAqB,KAAK;AAAA,IAC5B,CAAC;AAAA,EACH,GAAG,CAAC,cAAc,CAAC;AAEnB,MAAI,CAAC,mBAAmB;AACtB,WAAO;AAAA,EACT;AAGA,QAAM,cAAc,kBAAkB,QACnC,IAAI,CAAC,QAAQ,mBAAmB,EAAE,QAAQ,cAAc,EAAE,EAC1D,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,cAAc,SAAS;AAExD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA,MAEH,sBAAY;AAAA,QAAI,CAAC,EAAE,QAAQ,cAAc,MACxC,OAAO,MAAM,IAAI,CAAC,SAChB;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,KAAK,KAAK,OAAO,IAAI;AAAA,cACrB,MAAM,KAAK,OAAO,IAAI;AAAA,cACtB,OAAO,KAAK,KAAK,QAAQ;AAAA,cACzB,QAAQ,KAAK,KAAK,SAAS;AAAA,cAC3B,iBACE,kBAAkB,kBAAkB,oBAChC,uBACA;AAAA,cACN,cAAc;AAAA,cACd,WAAW;AAAA,cACX,iBAAiB;AAAA,cACjB,YAAY;AAAA,cACZ,SAAS;AAAA,YACX;AAAA;AAAA,QACD,CACF;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/preact/hooks/use-search.ts","../../src/preact/components/search-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/preact';\nimport { SearchPlugin, SearchState } from '@embedpdf/plugin-search';\nimport { useEffect, useState } from 'preact/hooks';\n\nexport const useSearchPlugin = () => usePlugin<SearchPlugin>(SearchPlugin.id);\nexport const useSearchCapability = () => useCapability<SearchPlugin>(SearchPlugin.id);\n\nexport const useSearch = () => {\n const { provides } = useSearchCapability();\n const [searchState, setSearchState] = useState<SearchState>({\n flags: [],\n results: [],\n total: 0,\n activeResultIndex: 0,\n showAllResults: true,\n query: '',\n loading: false,\n active: false,\n });\n\n useEffect(() => {\n return provides?.onStateChange((state) => setSearchState(state));\n }, [provides]);\n\n return {\n state: searchState,\n provides,\n };\n};\n","/** @jsxImportSource preact */\nimport { ComponentChildren, Fragment, JSX } from 'preact';\nimport { useEffect, useRef, useState } from 'preact/hooks';\nimport { SearchResultState } from '@embedpdf/plugin-search';\n\nimport { useSearchCapability } from '../hooks';\n\ntype SearchLayoutProps = Omit<JSX.HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n style?: JSX.CSSProperties;\n};\n\nexport function SearchLayer({\n pageIndex,\n scale,\n style,\n highlightColor = '#FFFF00',\n activeHighlightColor = '#FFBF00',\n ...props\n}: SearchLayoutProps) {\n const { provides: searchProvides } = useSearchCapability();\n const [searchResultState, setSearchResultState] = useState<SearchResultState | null>(null);\n\n useEffect(() => {\n return searchProvides?.onSearchResultStateChange((state) => {\n setSearchResultState(state);\n });\n }, [searchProvides]);\n\n if (!searchResultState) {\n return null;\n }\n\n // Filter results for current page while preserving original indices\n const pageResults = searchResultState.results\n .map((result, originalIndex) => ({ result, originalIndex }))\n .filter(({ result }) => result.pageIndex === pageIndex);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {pageResults.map(({ result, originalIndex }) =>\n result.rects.map((rect) => (\n <div\n style={{\n position: 'absolute',\n top: rect.origin.y * scale,\n left: rect.origin.x * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n backgroundColor:\n originalIndex === searchResultState.activeResultIndex\n ? activeHighlightColor\n : highlightColor,\n mixBlendMode: 'multiply',\n transform: 'scale(1.02)',\n transformOrigin: 'center',\n transition: 'opacity .3s ease-in-out',\n opacity: 1,\n }}\n ></div>\n )),\n )}\n </div>\n );\n}\n"],"mappings":";AAAA,SAAS,eAAe,iBAAiB;AACzC,SAAS,oBAAiC;AAC1C,SAAS,WAAW,gBAAgB;AAE7B,IAAM,kBAAkB,MAAM,UAAwB,aAAa,EAAE;AACrE,IAAM,sBAAsB,MAAM,cAA4B,aAAa,EAAE;AAE7E,IAAM,YAAY,MAAM;AAC7B,QAAM,EAAE,SAAS,IAAI,oBAAoB;AACzC,QAAM,CAAC,aAAa,cAAc,IAAI,SAAsB;AAAA,IAC1D,OAAO,CAAC;AAAA,IACR,SAAS,CAAC;AAAA,IACV,OAAO;AAAA,IACP,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,OAAO;AAAA,IACP,SAAS;AAAA,IACT,QAAQ;AAAA,EACV,CAAC;AAED,YAAU,MAAM;AACd,WAAO,UAAU,cAAc,CAAC,UAAU,eAAe,KAAK,CAAC;AAAA,EACjE,GAAG,CAAC,QAAQ,CAAC;AAEb,SAAO;AAAA,IACL,OAAO;AAAA,IACP;AAAA,EACF;AACF;;;AC1BA,SAAS,aAAAA,YAAmB,YAAAC,iBAAgB;AAgDlC;AAnCH,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,uBAAuB;AAAA,EACvB,GAAG;AACL,GAAsB;AACpB,QAAM,EAAE,UAAU,eAAe,IAAI,oBAAoB;AACzD,QAAM,CAAC,mBAAmB,oBAAoB,IAAIC,UAAmC,IAAI;AAEzF,EAAAC,WAAU,MAAM;AACd,WAAO,gBAAgB,0BAA0B,CAAC,UAAU;AAC1D,2BAAqB,KAAK;AAAA,IAC5B,CAAC;AAAA,EACH,GAAG,CAAC,cAAc,CAAC;AAEnB,MAAI,CAAC,mBAAmB;AACtB,WAAO;AAAA,EACT;AAGA,QAAM,cAAc,kBAAkB,QACnC,IAAI,CAAC,QAAQ,mBAAmB,EAAE,QAAQ,cAAc,EAAE,EAC1D,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,cAAc,SAAS;AAExD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA,MAEH,sBAAY;AAAA,QAAI,CAAC,EAAE,QAAQ,cAAc,MACxC,OAAO,MAAM,IAAI,CAAC,SAChB;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,KAAK,KAAK,OAAO,IAAI;AAAA,cACrB,MAAM,KAAK,OAAO,IAAI;AAAA,cACtB,OAAO,KAAK,KAAK,QAAQ;AAAA,cACzB,QAAQ,KAAK,KAAK,SAAS;AAAA,cAC3B,iBACE,kBAAkB,kBAAkB,oBAChC,uBACA;AAAA,cACN,cAAc;AAAA,cACd,WAAW;AAAA,cACX,iBAAiB;AAAA,cACjB,YAAY;AAAA,cACZ,SAAS;AAAA,YACX;AAAA;AAAA,QACD,CACF;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;","names":["useEffect","useState","useState","useEffect"]}
@@ -22,18 +22,40 @@ var react_exports = {};
22
22
  __export(react_exports, {
23
23
  SearchLayer: () => SearchLayer,
24
24
  useSearch: () => useSearch,
25
- useSearchCapability: () => useSearchCapability
25
+ useSearchCapability: () => useSearchCapability,
26
+ useSearchPlugin: () => useSearchPlugin
26
27
  });
27
28
  module.exports = __toCommonJS(react_exports);
28
29
 
29
30
  // src/react/hooks/use-search.ts
30
31
  var import_react = require("@embedpdf/core/react");
31
32
  var import_plugin_search = require("@embedpdf/plugin-search");
32
- var useSearch = () => (0, import_react.usePlugin)(import_plugin_search.SearchPlugin.id);
33
+ var import_react2 = require("react");
34
+ var useSearchPlugin = () => (0, import_react.usePlugin)(import_plugin_search.SearchPlugin.id);
33
35
  var useSearchCapability = () => (0, import_react.useCapability)(import_plugin_search.SearchPlugin.id);
36
+ var useSearch = () => {
37
+ const { provides } = useSearchCapability();
38
+ const [searchState, setSearchState] = (0, import_react2.useState)({
39
+ flags: [],
40
+ results: [],
41
+ total: 0,
42
+ activeResultIndex: 0,
43
+ showAllResults: true,
44
+ query: "",
45
+ loading: false,
46
+ active: false
47
+ });
48
+ (0, import_react2.useEffect)(() => {
49
+ return provides?.onStateChange((state) => setSearchState(state));
50
+ }, [provides]);
51
+ return {
52
+ state: searchState,
53
+ provides
54
+ };
55
+ };
34
56
 
35
57
  // src/react/components/search-layer.tsx
36
- var import_react2 = require("react");
58
+ var import_react3 = require("react");
37
59
  var import_jsx_runtime = require("react/jsx-runtime");
38
60
  function SearchLayer({
39
61
  pageIndex,
@@ -44,8 +66,8 @@ function SearchLayer({
44
66
  ...props
45
67
  }) {
46
68
  const { provides: searchProvides } = useSearchCapability();
47
- const [searchResultState, setSearchResultState] = (0, import_react2.useState)(null);
48
- (0, import_react2.useEffect)(() => {
69
+ const [searchResultState, setSearchResultState] = (0, import_react3.useState)(null);
70
+ (0, import_react3.useEffect)(() => {
49
71
  return searchProvides?.onSearchResultStateChange((state) => {
50
72
  setSearchResultState(state);
51
73
  });
@@ -88,6 +110,7 @@ function SearchLayer({
88
110
  0 && (module.exports = {
89
111
  SearchLayer,
90
112
  useSearch,
91
- useSearchCapability
113
+ useSearchCapability,
114
+ useSearchPlugin
92
115
  });
93
116
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react/index.ts","../../src/react/hooks/use-search.ts","../../src/react/components/search-layer.tsx"],"sourcesContent":["export * from './hooks';\nexport * from './components';\n","import { useCapability, usePlugin } from '@embedpdf/core/react';\nimport { SearchPlugin } from '@embedpdf/plugin-search';\n\nexport const useSearch = () => usePlugin<SearchPlugin>(SearchPlugin.id);\nexport const useSearchCapability = () => useCapability<SearchPlugin>(SearchPlugin.id);\n","import { useEffect, useState } from 'react';\nimport { SearchResultState } from '@embedpdf/plugin-search';\n\nimport { useSearchCapability } from '../hooks';\n\ntype SearchLayoutProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n style?: React.CSSProperties;\n};\n\nexport function SearchLayer({\n pageIndex,\n scale,\n style,\n highlightColor = '#FFFF00',\n activeHighlightColor = '#FFBF00',\n ...props\n}: SearchLayoutProps) {\n const { provides: searchProvides } = useSearchCapability();\n const [searchResultState, setSearchResultState] = useState<SearchResultState | null>(null);\n\n useEffect(() => {\n return searchProvides?.onSearchResultStateChange((state) => {\n setSearchResultState(state);\n });\n }, [searchProvides]);\n\n if (!searchResultState) {\n return null;\n }\n\n // Filter results for current page while preserving original indices\n const pageResults = searchResultState.results\n .map((result, originalIndex) => ({ result, originalIndex }))\n .filter(({ result }) => result.pageIndex === pageIndex);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {pageResults.map(({ result, originalIndex }) =>\n result.rects.map((rect) => (\n <div\n style={{\n position: 'absolute',\n top: rect.origin.y * scale,\n left: rect.origin.x * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n backgroundColor:\n originalIndex === searchResultState.activeResultIndex\n ? activeHighlightColor\n : highlightColor,\n mixBlendMode: 'multiply',\n transform: 'scale(1.02)',\n transformOrigin: 'center',\n transition: 'opacity .3s ease-in-out',\n opacity: 1,\n }}\n ></div>\n )),\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAAyC;AACzC,2BAA6B;AAEtB,IAAM,YAAY,UAAM,wBAAwB,kCAAa,EAAE;AAC/D,IAAM,sBAAsB,UAAM,4BAA4B,kCAAa,EAAE;;;ACJpF,IAAAA,gBAAoC;AAgD1B;AAnCH,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,uBAAuB;AAAA,EACvB,GAAG;AACL,GAAsB;AACpB,QAAM,EAAE,UAAU,eAAe,IAAI,oBAAoB;AACzD,QAAM,CAAC,mBAAmB,oBAAoB,QAAI,wBAAmC,IAAI;AAEzF,+BAAU,MAAM;AACd,WAAO,gBAAgB,0BAA0B,CAAC,UAAU;AAC1D,2BAAqB,KAAK;AAAA,IAC5B,CAAC;AAAA,EACH,GAAG,CAAC,cAAc,CAAC;AAEnB,MAAI,CAAC,mBAAmB;AACtB,WAAO;AAAA,EACT;AAGA,QAAM,cAAc,kBAAkB,QACnC,IAAI,CAAC,QAAQ,mBAAmB,EAAE,QAAQ,cAAc,EAAE,EAC1D,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,cAAc,SAAS;AAExD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA,MAEH,sBAAY;AAAA,QAAI,CAAC,EAAE,QAAQ,cAAc,MACxC,OAAO,MAAM,IAAI,CAAC,SAChB;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,KAAK,KAAK,OAAO,IAAI;AAAA,cACrB,MAAM,KAAK,OAAO,IAAI;AAAA,cACtB,OAAO,KAAK,KAAK,QAAQ;AAAA,cACzB,QAAQ,KAAK,KAAK,SAAS;AAAA,cAC3B,iBACE,kBAAkB,kBAAkB,oBAChC,uBACA;AAAA,cACN,cAAc;AAAA,cACd,WAAW;AAAA,cACX,iBAAiB;AAAA,cACjB,YAAY;AAAA,cACZ,SAAS;AAAA,YACX;AAAA;AAAA,QACD,CACF;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;","names":["import_react"]}
1
+ {"version":3,"sources":["../../src/react/index.ts","../../src/react/hooks/use-search.ts","../../src/react/components/search-layer.tsx"],"sourcesContent":["export * from './hooks';\nexport * from './components';\n","import { useCapability, usePlugin } from '@embedpdf/core/react';\nimport { SearchPlugin, SearchState } from '@embedpdf/plugin-search';\nimport { useEffect, useState } from 'react';\n\nexport const useSearchPlugin = () => usePlugin<SearchPlugin>(SearchPlugin.id);\nexport const useSearchCapability = () => useCapability<SearchPlugin>(SearchPlugin.id);\n\nexport const useSearch = () => {\n const { provides } = useSearchCapability();\n const [searchState, setSearchState] = useState<SearchState>({\n flags: [],\n results: [],\n total: 0,\n activeResultIndex: 0,\n showAllResults: true,\n query: '',\n loading: false,\n active: false,\n });\n\n useEffect(() => {\n return provides?.onStateChange((state) => setSearchState(state));\n }, [provides]);\n\n return {\n state: searchState,\n provides,\n };\n};\n","import { useEffect, useState } from 'react';\nimport { SearchResultState } from '@embedpdf/plugin-search';\n\nimport { useSearchCapability } from '../hooks';\n\ntype SearchLayoutProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n style?: React.CSSProperties;\n};\n\nexport function SearchLayer({\n pageIndex,\n scale,\n style,\n highlightColor = '#FFFF00',\n activeHighlightColor = '#FFBF00',\n ...props\n}: SearchLayoutProps) {\n const { provides: searchProvides } = useSearchCapability();\n const [searchResultState, setSearchResultState] = useState<SearchResultState | null>(null);\n\n useEffect(() => {\n return searchProvides?.onSearchResultStateChange((state) => {\n setSearchResultState(state);\n });\n }, [searchProvides]);\n\n if (!searchResultState) {\n return null;\n }\n\n // Filter results for current page while preserving original indices\n const pageResults = searchResultState.results\n .map((result, originalIndex) => ({ result, originalIndex }))\n .filter(({ result }) => result.pageIndex === pageIndex);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {pageResults.map(({ result, originalIndex }) =>\n result.rects.map((rect) => (\n <div\n style={{\n position: 'absolute',\n top: rect.origin.y * scale,\n left: rect.origin.x * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n backgroundColor:\n originalIndex === searchResultState.activeResultIndex\n ? activeHighlightColor\n : highlightColor,\n mixBlendMode: 'multiply',\n transform: 'scale(1.02)',\n transformOrigin: 'center',\n transition: 'opacity .3s ease-in-out',\n opacity: 1,\n }}\n ></div>\n )),\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBAAyC;AACzC,2BAA0C;AAC1C,IAAAA,gBAAoC;AAE7B,IAAM,kBAAkB,UAAM,wBAAwB,kCAAa,EAAE;AACrE,IAAM,sBAAsB,UAAM,4BAA4B,kCAAa,EAAE;AAE7E,IAAM,YAAY,MAAM;AAC7B,QAAM,EAAE,SAAS,IAAI,oBAAoB;AACzC,QAAM,CAAC,aAAa,cAAc,QAAI,wBAAsB;AAAA,IAC1D,OAAO,CAAC;AAAA,IACR,SAAS,CAAC;AAAA,IACV,OAAO;AAAA,IACP,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,OAAO;AAAA,IACP,SAAS;AAAA,IACT,QAAQ;AAAA,EACV,CAAC;AAED,+BAAU,MAAM;AACd,WAAO,UAAU,cAAc,CAAC,UAAU,eAAe,KAAK,CAAC;AAAA,EACjE,GAAG,CAAC,QAAQ,CAAC;AAEb,SAAO;AAAA,IACL,OAAO;AAAA,IACP;AAAA,EACF;AACF;;;AC5BA,IAAAC,gBAAoC;AAgD1B;AAnCH,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,uBAAuB;AAAA,EACvB,GAAG;AACL,GAAsB;AACpB,QAAM,EAAE,UAAU,eAAe,IAAI,oBAAoB;AACzD,QAAM,CAAC,mBAAmB,oBAAoB,QAAI,wBAAmC,IAAI;AAEzF,+BAAU,MAAM;AACd,WAAO,gBAAgB,0BAA0B,CAAC,UAAU;AAC1D,2BAAqB,KAAK;AAAA,IAC5B,CAAC;AAAA,EACH,GAAG,CAAC,cAAc,CAAC;AAEnB,MAAI,CAAC,mBAAmB;AACtB,WAAO;AAAA,EACT;AAGA,QAAM,cAAc,kBAAkB,QACnC,IAAI,CAAC,QAAQ,mBAAmB,EAAE,QAAQ,cAAc,EAAE,EAC1D,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,cAAc,SAAS;AAExD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA,MAEH,sBAAY;AAAA,QAAI,CAAC,EAAE,QAAQ,cAAc,MACxC,OAAO,MAAM,IAAI,CAAC,SAChB;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,KAAK,KAAK,OAAO,IAAI;AAAA,cACrB,MAAM,KAAK,OAAO,IAAI;AAAA,cACtB,OAAO,KAAK,KAAK,QAAQ;AAAA,cACzB,QAAQ,KAAK,KAAK,SAAS;AAAA,cAC3B,iBACE,kBAAkB,kBAAkB,oBAChC,uBACA;AAAA,cACN,cAAc;AAAA,cACd,WAAW;AAAA,cACX,iBAAiB;AAAA,cACjB,YAAY;AAAA,cACZ,SAAS;AAAA,YACX;AAAA;AAAA,QACD,CACF;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;","names":["import_react","import_react"]}
@@ -1,8 +1,8 @@
1
1
  import * as _embedpdf_plugin_search from '@embedpdf/plugin-search';
2
- import { SearchPlugin } from '@embedpdf/plugin-search';
2
+ import { SearchPlugin, SearchState } from '@embedpdf/plugin-search';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
 
5
- declare const useSearch: () => {
5
+ declare const useSearchPlugin: () => {
6
6
  plugin: SearchPlugin | null;
7
7
  isLoading: boolean;
8
8
  ready: Promise<void>;
@@ -12,6 +12,10 @@ declare const useSearchCapability: () => {
12
12
  isLoading: boolean;
13
13
  ready: Promise<void>;
14
14
  };
15
+ declare const useSearch: () => {
16
+ state: SearchState;
17
+ provides: Readonly<_embedpdf_plugin_search.SearchCapability> | null;
18
+ };
15
19
 
16
20
  type SearchLayoutProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'style'> & {
17
21
  pageIndex: number;
@@ -22,4 +26,4 @@ type SearchLayoutProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'style'> & {
22
26
  };
23
27
  declare function SearchLayer({ pageIndex, scale, style, highlightColor, activeHighlightColor, ...props }: SearchLayoutProps): react_jsx_runtime.JSX.Element | null;
24
28
 
25
- export { SearchLayer, useSearch, useSearchCapability };
29
+ export { SearchLayer, useSearch, useSearchCapability, useSearchPlugin };
@@ -1,8 +1,8 @@
1
1
  import * as _embedpdf_plugin_search from '@embedpdf/plugin-search';
2
- import { SearchPlugin } from '@embedpdf/plugin-search';
2
+ import { SearchPlugin, SearchState } from '@embedpdf/plugin-search';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
 
5
- declare const useSearch: () => {
5
+ declare const useSearchPlugin: () => {
6
6
  plugin: SearchPlugin | null;
7
7
  isLoading: boolean;
8
8
  ready: Promise<void>;
@@ -12,6 +12,10 @@ declare const useSearchCapability: () => {
12
12
  isLoading: boolean;
13
13
  ready: Promise<void>;
14
14
  };
15
+ declare const useSearch: () => {
16
+ state: SearchState;
17
+ provides: Readonly<_embedpdf_plugin_search.SearchCapability> | null;
18
+ };
15
19
 
16
20
  type SearchLayoutProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'style'> & {
17
21
  pageIndex: number;
@@ -22,4 +26,4 @@ type SearchLayoutProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'style'> & {
22
26
  };
23
27
  declare function SearchLayer({ pageIndex, scale, style, highlightColor, activeHighlightColor, ...props }: SearchLayoutProps): react_jsx_runtime.JSX.Element | null;
24
28
 
25
- export { SearchLayer, useSearch, useSearchCapability };
29
+ export { SearchLayer, useSearch, useSearchCapability, useSearchPlugin };
@@ -1,11 +1,32 @@
1
1
  // src/react/hooks/use-search.ts
2
2
  import { useCapability, usePlugin } from "@embedpdf/core/react";
3
3
  import { SearchPlugin } from "@embedpdf/plugin-search";
4
- var useSearch = () => usePlugin(SearchPlugin.id);
4
+ import { useEffect, useState } from "react";
5
+ var useSearchPlugin = () => usePlugin(SearchPlugin.id);
5
6
  var useSearchCapability = () => useCapability(SearchPlugin.id);
7
+ var useSearch = () => {
8
+ const { provides } = useSearchCapability();
9
+ const [searchState, setSearchState] = useState({
10
+ flags: [],
11
+ results: [],
12
+ total: 0,
13
+ activeResultIndex: 0,
14
+ showAllResults: true,
15
+ query: "",
16
+ loading: false,
17
+ active: false
18
+ });
19
+ useEffect(() => {
20
+ return provides?.onStateChange((state) => setSearchState(state));
21
+ }, [provides]);
22
+ return {
23
+ state: searchState,
24
+ provides
25
+ };
26
+ };
6
27
 
7
28
  // src/react/components/search-layer.tsx
8
- import { useEffect, useState } from "react";
29
+ import { useEffect as useEffect2, useState as useState2 } from "react";
9
30
  import { jsx } from "react/jsx-runtime";
10
31
  function SearchLayer({
11
32
  pageIndex,
@@ -16,8 +37,8 @@ function SearchLayer({
16
37
  ...props
17
38
  }) {
18
39
  const { provides: searchProvides } = useSearchCapability();
19
- const [searchResultState, setSearchResultState] = useState(null);
20
- useEffect(() => {
40
+ const [searchResultState, setSearchResultState] = useState2(null);
41
+ useEffect2(() => {
21
42
  return searchProvides?.onSearchResultStateChange((state) => {
22
43
  setSearchResultState(state);
23
44
  });
@@ -59,6 +80,7 @@ function SearchLayer({
59
80
  export {
60
81
  SearchLayer,
61
82
  useSearch,
62
- useSearchCapability
83
+ useSearchCapability,
84
+ useSearchPlugin
63
85
  };
64
86
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react/hooks/use-search.ts","../../src/react/components/search-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/react';\nimport { SearchPlugin } from '@embedpdf/plugin-search';\n\nexport const useSearch = () => usePlugin<SearchPlugin>(SearchPlugin.id);\nexport const useSearchCapability = () => useCapability<SearchPlugin>(SearchPlugin.id);\n","import { useEffect, useState } from 'react';\nimport { SearchResultState } from '@embedpdf/plugin-search';\n\nimport { useSearchCapability } from '../hooks';\n\ntype SearchLayoutProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n style?: React.CSSProperties;\n};\n\nexport function SearchLayer({\n pageIndex,\n scale,\n style,\n highlightColor = '#FFFF00',\n activeHighlightColor = '#FFBF00',\n ...props\n}: SearchLayoutProps) {\n const { provides: searchProvides } = useSearchCapability();\n const [searchResultState, setSearchResultState] = useState<SearchResultState | null>(null);\n\n useEffect(() => {\n return searchProvides?.onSearchResultStateChange((state) => {\n setSearchResultState(state);\n });\n }, [searchProvides]);\n\n if (!searchResultState) {\n return null;\n }\n\n // Filter results for current page while preserving original indices\n const pageResults = searchResultState.results\n .map((result, originalIndex) => ({ result, originalIndex }))\n .filter(({ result }) => result.pageIndex === pageIndex);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {pageResults.map(({ result, originalIndex }) =>\n result.rects.map((rect) => (\n <div\n style={{\n position: 'absolute',\n top: rect.origin.y * scale,\n left: rect.origin.x * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n backgroundColor:\n originalIndex === searchResultState.activeResultIndex\n ? activeHighlightColor\n : highlightColor,\n mixBlendMode: 'multiply',\n transform: 'scale(1.02)',\n transformOrigin: 'center',\n transition: 'opacity .3s ease-in-out',\n opacity: 1,\n }}\n ></div>\n )),\n )}\n </div>\n );\n}\n"],"mappings":";AAAA,SAAS,eAAe,iBAAiB;AACzC,SAAS,oBAAoB;AAEtB,IAAM,YAAY,MAAM,UAAwB,aAAa,EAAE;AAC/D,IAAM,sBAAsB,MAAM,cAA4B,aAAa,EAAE;;;ACJpF,SAAS,WAAW,gBAAgB;AAgD1B;AAnCH,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,uBAAuB;AAAA,EACvB,GAAG;AACL,GAAsB;AACpB,QAAM,EAAE,UAAU,eAAe,IAAI,oBAAoB;AACzD,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,SAAmC,IAAI;AAEzF,YAAU,MAAM;AACd,WAAO,gBAAgB,0BAA0B,CAAC,UAAU;AAC1D,2BAAqB,KAAK;AAAA,IAC5B,CAAC;AAAA,EACH,GAAG,CAAC,cAAc,CAAC;AAEnB,MAAI,CAAC,mBAAmB;AACtB,WAAO;AAAA,EACT;AAGA,QAAM,cAAc,kBAAkB,QACnC,IAAI,CAAC,QAAQ,mBAAmB,EAAE,QAAQ,cAAc,EAAE,EAC1D,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,cAAc,SAAS;AAExD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA,MAEH,sBAAY;AAAA,QAAI,CAAC,EAAE,QAAQ,cAAc,MACxC,OAAO,MAAM,IAAI,CAAC,SAChB;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,KAAK,KAAK,OAAO,IAAI;AAAA,cACrB,MAAM,KAAK,OAAO,IAAI;AAAA,cACtB,OAAO,KAAK,KAAK,QAAQ;AAAA,cACzB,QAAQ,KAAK,KAAK,SAAS;AAAA,cAC3B,iBACE,kBAAkB,kBAAkB,oBAChC,uBACA;AAAA,cACN,cAAc;AAAA,cACd,WAAW;AAAA,cACX,iBAAiB;AAAA,cACjB,YAAY;AAAA,cACZ,SAAS;AAAA,YACX;AAAA;AAAA,QACD,CACF;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/react/hooks/use-search.ts","../../src/react/components/search-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/react';\nimport { SearchPlugin, SearchState } from '@embedpdf/plugin-search';\nimport { useEffect, useState } from 'react';\n\nexport const useSearchPlugin = () => usePlugin<SearchPlugin>(SearchPlugin.id);\nexport const useSearchCapability = () => useCapability<SearchPlugin>(SearchPlugin.id);\n\nexport const useSearch = () => {\n const { provides } = useSearchCapability();\n const [searchState, setSearchState] = useState<SearchState>({\n flags: [],\n results: [],\n total: 0,\n activeResultIndex: 0,\n showAllResults: true,\n query: '',\n loading: false,\n active: false,\n });\n\n useEffect(() => {\n return provides?.onStateChange((state) => setSearchState(state));\n }, [provides]);\n\n return {\n state: searchState,\n provides,\n };\n};\n","import { useEffect, useState } from 'react';\nimport { SearchResultState } from '@embedpdf/plugin-search';\n\nimport { useSearchCapability } from '../hooks';\n\ntype SearchLayoutProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n style?: React.CSSProperties;\n};\n\nexport function SearchLayer({\n pageIndex,\n scale,\n style,\n highlightColor = '#FFFF00',\n activeHighlightColor = '#FFBF00',\n ...props\n}: SearchLayoutProps) {\n const { provides: searchProvides } = useSearchCapability();\n const [searchResultState, setSearchResultState] = useState<SearchResultState | null>(null);\n\n useEffect(() => {\n return searchProvides?.onSearchResultStateChange((state) => {\n setSearchResultState(state);\n });\n }, [searchProvides]);\n\n if (!searchResultState) {\n return null;\n }\n\n // Filter results for current page while preserving original indices\n const pageResults = searchResultState.results\n .map((result, originalIndex) => ({ result, originalIndex }))\n .filter(({ result }) => result.pageIndex === pageIndex);\n\n return (\n <div\n style={{\n ...style,\n }}\n {...props}\n >\n {pageResults.map(({ result, originalIndex }) =>\n result.rects.map((rect) => (\n <div\n style={{\n position: 'absolute',\n top: rect.origin.y * scale,\n left: rect.origin.x * scale,\n width: rect.size.width * scale,\n height: rect.size.height * scale,\n backgroundColor:\n originalIndex === searchResultState.activeResultIndex\n ? activeHighlightColor\n : highlightColor,\n mixBlendMode: 'multiply',\n transform: 'scale(1.02)',\n transformOrigin: 'center',\n transition: 'opacity .3s ease-in-out',\n opacity: 1,\n }}\n ></div>\n )),\n )}\n </div>\n );\n}\n"],"mappings":";AAAA,SAAS,eAAe,iBAAiB;AACzC,SAAS,oBAAiC;AAC1C,SAAS,WAAW,gBAAgB;AAE7B,IAAM,kBAAkB,MAAM,UAAwB,aAAa,EAAE;AACrE,IAAM,sBAAsB,MAAM,cAA4B,aAAa,EAAE;AAE7E,IAAM,YAAY,MAAM;AAC7B,QAAM,EAAE,SAAS,IAAI,oBAAoB;AACzC,QAAM,CAAC,aAAa,cAAc,IAAI,SAAsB;AAAA,IAC1D,OAAO,CAAC;AAAA,IACR,SAAS,CAAC;AAAA,IACV,OAAO;AAAA,IACP,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,OAAO;AAAA,IACP,SAAS;AAAA,IACT,QAAQ;AAAA,EACV,CAAC;AAED,YAAU,MAAM;AACd,WAAO,UAAU,cAAc,CAAC,UAAU,eAAe,KAAK,CAAC;AAAA,EACjE,GAAG,CAAC,QAAQ,CAAC;AAEb,SAAO;AAAA,IACL,OAAO;AAAA,IACP;AAAA,EACF;AACF;;;AC5BA,SAAS,aAAAA,YAAW,YAAAC,iBAAgB;AAgD1B;AAnCH,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,uBAAuB;AAAA,EACvB,GAAG;AACL,GAAsB;AACpB,QAAM,EAAE,UAAU,eAAe,IAAI,oBAAoB;AACzD,QAAM,CAAC,mBAAmB,oBAAoB,IAAIC,UAAmC,IAAI;AAEzF,EAAAC,WAAU,MAAM;AACd,WAAO,gBAAgB,0BAA0B,CAAC,UAAU;AAC1D,2BAAqB,KAAK;AAAA,IAC5B,CAAC;AAAA,EACH,GAAG,CAAC,cAAc,CAAC;AAEnB,MAAI,CAAC,mBAAmB;AACtB,WAAO;AAAA,EACT;AAGA,QAAM,cAAc,kBAAkB,QACnC,IAAI,CAAC,QAAQ,mBAAmB,EAAE,QAAQ,cAAc,EAAE,EAC1D,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,cAAc,SAAS;AAExD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,GAAG;AAAA,MACL;AAAA,MACC,GAAG;AAAA,MAEH,sBAAY;AAAA,QAAI,CAAC,EAAE,QAAQ,cAAc,MACxC,OAAO,MAAM,IAAI,CAAC,SAChB;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,KAAK,KAAK,OAAO,IAAI;AAAA,cACrB,MAAM,KAAK,OAAO,IAAI;AAAA,cACtB,OAAO,KAAK,KAAK,QAAQ;AAAA,cACzB,QAAQ,KAAK,KAAK,SAAS;AAAA,cAC3B,iBACE,kBAAkB,kBAAkB,oBAChC,uBACA;AAAA,cACN,cAAc;AAAA,cACd,WAAW;AAAA,cACX,iBAAiB;AAAA,cACjB,YAAY;AAAA,cACZ,SAAS;AAAA,YACX;AAAA;AAAA,QACD,CACF;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;","names":["useEffect","useState","useState","useEffect"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@embedpdf/plugin-search",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -23,21 +23,21 @@
23
23
  }
24
24
  },
25
25
  "dependencies": {
26
- "@embedpdf/models": "1.0.0"
26
+ "@embedpdf/models": "1.0.1"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/react": "^18.2.0",
30
30
  "tsup": "^8.0.0",
31
31
  "typescript": "^5.0.0",
32
- "@embedpdf/plugin-loader": "1.0.0",
33
- "@embedpdf/core": "1.0.0"
32
+ "@embedpdf/core": "1.0.1",
33
+ "@embedpdf/plugin-loader": "1.0.1"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "react": ">=16.8.0",
37
37
  "react-dom": ">=16.8.0",
38
38
  "preact": "^10.26.4",
39
- "@embedpdf/core": "1.0.0",
40
- "@embedpdf/plugin-loader": "1.0.0"
39
+ "@embedpdf/core": "1.0.1",
40
+ "@embedpdf/plugin-loader": "1.0.1"
41
41
  },
42
42
  "files": [
43
43
  "dist",