@embedpdf/plugin-search 1.4.1 → 2.0.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +324 -199
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/actions.d.ts +58 -22
  6. package/dist/lib/index.d.ts +2 -2
  7. package/dist/lib/reducer.d.ts +2 -1
  8. package/dist/lib/search-plugin.d.ts +8 -8
  9. package/dist/lib/types.d.ts +76 -63
  10. package/dist/preact/adapter.d.ts +1 -1
  11. package/dist/preact/index.cjs +1 -1
  12. package/dist/preact/index.cjs.map +1 -1
  13. package/dist/preact/index.js +49 -18
  14. package/dist/preact/index.js.map +1 -1
  15. package/dist/react/adapter.d.ts +1 -1
  16. package/dist/react/index.cjs +1 -1
  17. package/dist/react/index.cjs.map +1 -1
  18. package/dist/react/index.js +49 -18
  19. package/dist/react/index.js.map +1 -1
  20. package/dist/shared/components/search-layer.d.ts +3 -2
  21. package/dist/shared/hooks/use-search.d.ts +4 -4
  22. package/dist/shared-preact/components/search-layer.d.ts +3 -2
  23. package/dist/shared-preact/hooks/use-search.d.ts +4 -4
  24. package/dist/shared-react/components/search-layer.d.ts +3 -2
  25. package/dist/shared-react/hooks/use-search.d.ts +4 -4
  26. package/dist/svelte/components/SearchLayer.svelte.d.ts +4 -3
  27. package/dist/svelte/hooks/use-search.svelte.d.ts +11 -5
  28. package/dist/svelte/index.cjs +1 -1
  29. package/dist/svelte/index.cjs.map +1 -1
  30. package/dist/svelte/index.js +69 -35
  31. package/dist/svelte/index.js.map +1 -1
  32. package/dist/vue/components/search-layer.vue.d.ts +4 -2
  33. package/dist/vue/hooks/use-search.d.ts +9 -64
  34. package/dist/vue/index.cjs +1 -1
  35. package/dist/vue/index.cjs.map +1 -1
  36. package/dist/vue/index.js +77 -32
  37. package/dist/vue/index.js.map +1 -1
  38. package/package.json +5 -7
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/lib/actions.ts","../src/lib/search-plugin.ts","../src/lib/manifest.ts","../src/lib/reducer.ts","../src/lib/index.ts"],"sourcesContent":["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 APPEND_SEARCH_RESULTS = 'APPEND_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 AppendSearchResultsAction extends Action {\n type: typeof APPEND_SEARCH_RESULTS;\n payload: {\n results: SearchResult[];\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 | AppendSearchResultsAction\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 appendSearchResults(results: SearchResult[]): AppendSearchResultsAction {\n return { type: APPEND_SEARCH_RESULTS, payload: { results } };\n}\n\nexport function setActiveResultIndex(index: number): SetActiveResultIndexAction {\n return { type: SET_ACTIVE_RESULT_INDEX, payload: index };\n}\n","import { BasePlugin, createBehaviorEmitter, PluginRegistry } from '@embedpdf/core';\nimport {\n MatchFlag,\n PdfDocumentObject,\n SearchAllPagesResult,\n PdfEngine,\n PdfTask,\n PdfPageSearchProgress,\n PdfTaskHelper,\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 appendSearchResults,\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\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 // keep reference to current running task (optional abort handling if your PdfTask supports it)\n private currentTask?: ReturnType<PdfEngine['searchAllPages']>;\n\n constructor(id: string, registry: PluginRegistry) {\n super(id, registry);\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) return;\n this.dispatch(startSearchSession());\n this.notifySearchStart();\n }\n\n private stopSearchSession(): void {\n if (!this.currentDocument || !this.state.active) return;\n // optional: abort current task if PdfTask supports it\n try {\n // @ts-expect-error: optional abort if available\n this.currentTask?.abort?.({ type: 'abort', code: 'cancelled', message: 'search stopped' });\n } catch {}\n this.currentTask = undefined;\n\n this.dispatch(stopSearchSession());\n this.notifySearchStop();\n }\n\n private searchAllPages(\n keyword: string,\n force: boolean = false,\n ): PdfTask<SearchAllPagesResult, PdfPageSearchProgress> {\n const trimmedKeyword = keyword.trim();\n\n if (this.state.query === trimmedKeyword && !force) {\n return PdfTaskHelper.resolve<SearchAllPagesResult, PdfPageSearchProgress>({\n results: this.state.results,\n total: this.state.total,\n });\n }\n\n // stop previous task if still running\n if (this.currentTask) {\n try {\n // @ts-expect-error: optional abort if available\n this.currentTask.abort?.({ type: 'abort', code: 'superseded', message: 'new search' });\n } catch {}\n this.currentTask = undefined;\n }\n\n this.dispatch(startSearch(trimmedKeyword));\n\n if (!trimmedKeyword || !this.currentDocument) {\n this.dispatch(setSearchResults([], 0, -1));\n return PdfTaskHelper.resolve<SearchAllPagesResult, PdfPageSearchProgress>({\n results: [],\n total: 0,\n });\n }\n\n if (!this.state.active) {\n this.startSearchSession();\n }\n\n const task = (this.currentTask = this.engine.searchAllPages(\n this.currentDocument!,\n trimmedKeyword,\n { flags: this.state.flags },\n ));\n\n task.onProgress((p) => {\n if (p?.results?.length) {\n this.dispatch(appendSearchResults(p.results));\n // set first active result as soon as we have something\n if (this.state.activeResultIndex === -1) {\n this.dispatch(setActiveResultIndex(0));\n this.notifyActiveResultChange(0);\n }\n }\n });\n\n task.wait(\n (results) => {\n this.currentTask = undefined;\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 },\n (error) => {\n this.currentTask = undefined;\n console.error('Error during search:', error);\n this.dispatch(setSearchResults([], 0, -1));\n },\n );\n\n return task;\n }\n\n private nextResult(): number {\n if (this.state.results.length === 0) return -1;\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) return -1;\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 { 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 APPEND_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 {\n ...state,\n loading: true,\n query: action.payload,\n // clear old results on new search start\n results: [],\n total: 0,\n activeResultIndex: -1,\n };\n\n case APPEND_SEARCH_RESULTS: {\n const newResults = [...state.results, ...action.payload.results];\n const firstHitIndex =\n state.activeResultIndex === -1 && newResults.length > 0 ? 0 : state.activeResultIndex;\n return {\n ...state,\n results: newResults,\n total: newResults.length, // total-so-far\n activeResultIndex: firstHitIndex,\n // keep loading true until final SET_SEARCH_RESULTS\n loading: true,\n };\n }\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) => new SearchPlugin(SEARCH_PLUGIN_ID, registry),\n reducer: searchReducer,\n initialState,\n};\n\nexport * from './search-plugin';\nexport * from './types';\nexport * from './manifest';\nexport { initialState };\n"],"names":["_a"],"mappings":";;AAIO,MAAM,uBAAuB;AAC7B,MAAM,sBAAsB;AAC5B,MAAM,mBAAmB;AACzB,MAAM,uBAAuB;AAC7B,MAAM,eAAe;AACrB,MAAM,qBAAqB;AAC3B,MAAM,wBAAwB;AAC9B,MAAM,0BAA0B;AA2DhC,SAAS,qBAA+C;AACtD,SAAA,EAAE,MAAM,qBAAqB;AACtC;AAEO,SAAS,oBAA6C;AACpD,SAAA,EAAE,MAAM,oBAAoB;AACrC;AAEO,SAAS,eAAe,OAA0C;AACvE,SAAO,EAAE,MAAM,kBAAkB,SAAS,MAAM;AAClD;AAEO,SAAS,kBAAkB,SAA2C;AAC3E,SAAO,EAAE,MAAM,sBAAsB,SAAS,QAAQ;AACxD;AAEO,SAAS,YAAY,OAAkC;AAC5D,SAAO,EAAE,MAAM,cAAc,SAAS,MAAM;AAC9C;AAEgB,SAAA,iBACd,SACA,OACA,mBACwB;AACjB,SAAA,EAAE,MAAM,oBAAoB,SAAS,EAAE,SAAS,OAAO,oBAAoB;AACpF;AAEO,SAAS,oBAAoB,SAAoD;AACtF,SAAO,EAAE,MAAM,uBAAuB,SAAS,EAAE,UAAU;AAC7D;AAEO,SAAS,qBAAqB,OAA2C;AAC9E,SAAO,EAAE,MAAM,yBAAyB,SAAS,MAAM;AACzD;AChFO,MAAM,gBAAN,MAAM,sBAAqB,WAKhC;AAAA,EAeA,YAAY,IAAY,UAA0B;AAChD,UAAM,IAAI,QAAQ;AAXpB,SAAiB,cAAc,sBAAsB;AACrD,SAAiB,eAAe,sBAAsB;AACtD,SAAiB,gBAAgB,sBAA4C;AAC7E,SAAiB,4BAA4B,sBAA8B;AAC3E,SAAiB,qBAAqB,sBAAyC;AAC/E,SAAiB,eAAe,sBAAmC;AAOjE,SAAK,SAAS,KAAK,SAAS,UAAwB,QAAQ,EAAG,SAAS;AAExE,SAAK,OAAO,iBAAiB,KAAK,qBAAqB,KAAK,IAAI,CAAC;AACjE,SAAK,OAAO,cAAc,KAAK,kBAAkB,KAAK,IAAI,CAAC;AAAA,EAAA;AAAA,EAGrD,qBAAqB,KAA8B;AACzD,SAAK,kBAAkB;AACnB,QAAA,KAAK,MAAM,QAAQ;AACrB,WAAK,mBAAmB;AAAA,IAAA;AAAA,EAC1B;AAAA,EAGM,kBAAkB,OAA0B;AAClD,QAAI,MAAM,SAAS,WAAY,MAAM,SAAS,WAAW,KAAK,iBAAkB;AAC1E,UAAA,KAAK,MAAM,QAAQ;AACrB,aAAK,kBAAkB;AAAA,MAAA;AAEzB,WAAK,kBAAkB;AAAA,IAAA;AAAA,EACzB;AAAA,EAGF,MAAM,WAAW,QAA2C;AAC1D,SAAK,SAAS,eAAe,OAAO,SAAS,CAAE,CAAA,CAAC;AAC3C,SAAA;AAAA,MACH,kBAAkB,OAAO,mBAAmB,SAAY,OAAO,iBAAiB,IAAI;AAAA,IACtF;AAAA,EAAA;AAAA,EAGO,eAAe,YAAyB,UAA6B;AAC5E,SAAK,mBAAmB,KAAK;AAAA,MAC3B,SAAS,SAAS;AAAA,MAClB,mBAAmB,SAAS;AAAA,MAC5B,gBAAgB,SAAS;AAAA,MACzB,QAAQ,SAAS;AAAA,IAAA,CAClB;AACI,SAAA,aAAa,KAAK,QAAQ;AAAA,EAAA;AAAA,EAGvB,kBAAoC;AACrC,WAAA;AAAA,MACL,aAAa,KAAK,mBAAmB,KAAK,IAAI;AAAA,MAC9C,YAAY,KAAK,kBAAkB,KAAK,IAAI;AAAA,MAC5C,gBAAgB,KAAK,eAAe,KAAK,IAAI;AAAA,MAC7C,YAAY,KAAK,WAAW,KAAK,IAAI;AAAA,MACrC,gBAAgB,KAAK,eAAe,KAAK,IAAI;AAAA,MAC7C,YAAY,KAAK,WAAW,KAAK,IAAI;AAAA,MACrC,mBAAmB,CAAC,YAAY,KAAK,SAAS,kBAAkB,OAAO,CAAC;AAAA,MACxE,mBAAmB,MAAM,KAAK,MAAM;AAAA,MACpC,gBAAgB,KAAK,cAAc;AAAA,MACnC,eAAe,KAAK,aAAa;AAAA,MACjC,cAAc,KAAK,YAAY;AAAA,MAC/B,sBAAsB,KAAK,0BAA0B;AAAA,MACrD,2BAA2B,KAAK,mBAAmB;AAAA,MACnD,eAAe,KAAK,aAAa;AAAA,MACjC,UAAU,MAAM,KAAK,MAAM;AAAA,MAC3B,UAAU,CAAC,UAAU,KAAK,SAAS,KAAK;AAAA,MACxC,UAAU,MAAM,KAAK;AAAA,IACvB;AAAA,EAAA;AAAA,EAGM,SAAS,OAA0B;AACpC,SAAA,SAAS,eAAe,KAAK,CAAC;AAC/B,QAAA,KAAK,MAAM,QAAQ;AACrB,WAAK,eAAe,KAAK,MAAM,OAAO,IAAI;AAAA,IAAA;AAAA,EAC5C;AAAA,EAGM,oBAA0B;AAChC,SAAK,aAAa,KAAK;AAAA,EAAA;AAAA,EAGjB,mBAAyB;AAC/B,SAAK,YAAY,KAAK;AAAA,EAAA;AAAA,EAGhB,yBAAyB,OAAqB;AAC/C,SAAA,0BAA0B,KAAK,KAAK;AAAA,EAAA;AAAA,EAGnC,qBAA2B;AAC7B,QAAA,CAAC,KAAK,gBAAiB;AACtB,SAAA,SAAS,oBAAoB;AAClC,SAAK,kBAAkB;AAAA,EAAA;AAAA,EAGjB,oBAA0B;;AAChC,QAAI,CAAC,KAAK,mBAAmB,CAAC,KAAK,MAAM,OAAQ;AAE7C,QAAA;AAEG,uBAAA,gBAAA,mBAAa,UAAb,4BAAqB,EAAE,MAAM,SAAS,MAAM,aAAa,SAAS;IAAkB,QACnF;AAAA,IAAA;AACR,SAAK,cAAc;AAEd,SAAA,SAAS,mBAAmB;AACjC,SAAK,iBAAiB;AAAA,EAAA;AAAA,EAGhB,eACN,SACA,QAAiB,OACqC;;AAChD,UAAA,iBAAiB,QAAQ,KAAK;AAEpC,QAAI,KAAK,MAAM,UAAU,kBAAkB,CAAC,OAAO;AACjD,aAAO,cAAc,QAAqD;AAAA,QACxE,SAAS,KAAK,MAAM;AAAA,QACpB,OAAO,KAAK,MAAM;AAAA,MAAA,CACnB;AAAA,IAAA;AAIH,QAAI,KAAK,aAAa;AAChB,UAAA;AAEG,yBAAA,aAAY,UAAZ,4BAAoB,EAAE,MAAM,SAAS,MAAM,cAAc,SAAS;MAAc,QAC/E;AAAA,MAAA;AACR,WAAK,cAAc;AAAA,IAAA;AAGhB,SAAA,SAAS,YAAY,cAAc,CAAC;AAEzC,QAAI,CAAC,kBAAkB,CAAC,KAAK,iBAAiB;AAC5C,WAAK,SAAS,iBAAiB,CAAI,GAAA,GAAG,EAAE,CAAC;AACzC,aAAO,cAAc,QAAqD;AAAA,QACxE,SAAS,CAAC;AAAA,QACV,OAAO;AAAA,MAAA,CACR;AAAA,IAAA;AAGC,QAAA,CAAC,KAAK,MAAM,QAAQ;AACtB,WAAK,mBAAmB;AAAA,IAAA;AAG1B,UAAM,OAAQ,KAAK,cAAc,KAAK,OAAO;AAAA,MAC3C,KAAK;AAAA,MACL;AAAA,MACA,EAAE,OAAO,KAAK,MAAM,MAAM;AAAA,IAC5B;AAEK,SAAA,WAAW,CAAC,MAAM;;AACjB,WAAAA,MAAA,uBAAG,YAAH,gBAAAA,IAAY,QAAQ;AACtB,aAAK,SAAS,oBAAoB,EAAE,OAAO,CAAC;AAExC,YAAA,KAAK,MAAM,sBAAsB,IAAI;AAClC,eAAA,SAAS,qBAAqB,CAAC,CAAC;AACrC,eAAK,yBAAyB,CAAC;AAAA,QAAA;AAAA,MACjC;AAAA,IACF,CACD;AAEI,SAAA;AAAA,MACH,CAAC,YAAY;AACX,aAAK,cAAc;AACnB,cAAM,oBAAoB,QAAQ,QAAQ,IAAI,IAAI;AAClD,aAAK,SAAS,iBAAiB,QAAQ,SAAS,QAAQ,OAAO,iBAAiB,CAAC;AAC5E,aAAA,cAAc,KAAK,OAAO;AAC3B,YAAA,QAAQ,QAAQ,GAAG;AACrB,eAAK,yBAAyB,CAAC;AAAA,QAAA;AAAA,MAEnC;AAAA,MACA,CAAC,UAAU;AACT,aAAK,cAAc;AACX,gBAAA,MAAM,wBAAwB,KAAK;AAC3C,aAAK,SAAS,iBAAiB,CAAI,GAAA,GAAG,EAAE,CAAC;AAAA,MAAA;AAAA,IAE7C;AAEO,WAAA;AAAA,EAAA;AAAA,EAGD,aAAqB;AAC3B,QAAI,KAAK,MAAM,QAAQ,WAAW,EAAU,QAAA;AAC5C,UAAM,YACJ,KAAK,MAAM,qBAAqB,KAAK,MAAM,QAAQ,SAAS,IACxD,IACA,KAAK,MAAM,oBAAoB;AAC9B,WAAA,KAAK,WAAW,SAAS;AAAA,EAAA;AAAA,EAG1B,iBAAyB;AAC/B,QAAI,KAAK,MAAM,QAAQ,WAAW,EAAU,QAAA;AAC5C,UAAM,YACJ,KAAK,MAAM,qBAAqB,IAC5B,KAAK,MAAM,QAAQ,SAAS,IAC5B,KAAK,MAAM,oBAAoB;AAC9B,WAAA,KAAK,WAAW,SAAS;AAAA,EAAA;AAAA,EAG1B,WAAW,OAAuB;AACpC,QAAA,KAAK,MAAM,QAAQ,WAAW,KAAK,QAAQ,KAAK,SAAS,KAAK,MAAM,QAAQ,QAAQ;AAC/E,aAAA;AAAA,IAAA;AAEJ,SAAA,SAAS,qBAAqB,KAAK,CAAC;AACzC,SAAK,yBAAyB,KAAK;AAC5B,WAAA;AAAA,EAAA;AAAA,EAGT,MAAM,UAAyB;AAC7B,QAAI,KAAK,MAAM,UAAU,KAAK,iBAAiB;AAC7C,WAAK,kBAAkB;AAAA,IAAA;AAEzB,SAAK,cAAc,MAAM;AACzB,SAAK,aAAa,MAAM;AACxB,SAAK,YAAY,MAAM;AACvB,SAAK,0BAA0B,MAAM;AACrC,SAAK,mBAAmB,MAAM;AAC9B,SAAK,aAAa,MAAM;AAAA,EAAA;AAE5B;AAlOE,cAAgB,KAAK;AANhB,IAAM,eAAN;ACrBA,MAAM,mBAAmB;AAEzB,MAAM,WAA+C;AAAA,EAC1D,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU,CAAC,QAAQ;AAAA,EACnB,UAAU,CAAC,QAAQ;AAAA,EACnB,UAAU,CAAC;AAAA,EACX,eAAe;AAAA,IACb,SAAS;AAAA,IACT,OAAO,CAAA;AAAA,EAAC;AAEZ;ACFO,MAAM,eAA4B;AAAA,EACvC,OAAO,CAAC;AAAA,EACR,SAAS,CAAC;AAAA,EACV,OAAO;AAAA,EACP,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,OAAO;AAAA,EACP,SAAS;AAAA,EACT,QAAQ;AACV;AAEO,MAAM,gBAAoD,CAAC,QAAQ,cAAc,WAAW;AACjG,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,QAAQ,KAAK;AAAA,IAElC,KAAK;AACI,aAAA;AAAA,QACL,GAAG;AAAA,QACH,SAAS,CAAC;AAAA,QACV,OAAO;AAAA,QACP,mBAAmB;AAAA,QACnB,OAAO;AAAA,QACP,SAAS;AAAA,QACT,QAAQ;AAAA,MACV;AAAA,IAEF,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,OAAO,OAAO,QAAQ;AAAA,IAE3C,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,gBAAgB,OAAO,QAAQ;AAAA,IAEpD,KAAK;AACI,aAAA;AAAA,QACL,GAAG;AAAA,QACH,SAAS;AAAA,QACT,OAAO,OAAO;AAAA;AAAA,QAEd,SAAS,CAAC;AAAA,QACV,OAAO;AAAA,QACP,mBAAmB;AAAA,MACrB;AAAA,IAEF,KAAK,uBAAuB;AACpB,YAAA,aAAa,CAAC,GAAG,MAAM,SAAS,GAAG,OAAO,QAAQ,OAAO;AACzD,YAAA,gBACJ,MAAM,sBAAsB,MAAM,WAAW,SAAS,IAAI,IAAI,MAAM;AAC/D,aAAA;AAAA,QACL,GAAG;AAAA,QACH,SAAS;AAAA,QACT,OAAO,WAAW;AAAA;AAAA,QAClB,mBAAmB;AAAA;AAAA,QAEnB,SAAS;AAAA,MACX;AAAA,IAAA;AAAA,IAGF,KAAK;AACI,aAAA;AAAA,QACL,GAAG;AAAA,QACH,SAAS,OAAO,QAAQ;AAAA,QACxB,OAAO,OAAO,QAAQ;AAAA,QACtB,mBAAmB,OAAO,QAAQ;AAAA,QAClC,SAAS;AAAA,MACX;AAAA,IAEF,KAAK;AACH,aAAO,EAAE,GAAG,OAAO,mBAAmB,OAAO,QAAQ;AAAA,IAEvD;AACS,aAAA;AAAA,EAAA;AAEb;AChFO,MAAM,sBAKT;AAAA,EACF;AAAA,EACA,QAAQ,CAAC,aAAa,IAAI,aAAa,kBAAkB,QAAQ;AAAA,EACjE,SAAS;AAAA,EACT;AACF;"}
1
+ {"version":3,"file":"index.js","sources":["../src/lib/actions.ts","../src/lib/reducer.ts","../src/lib/search-plugin.ts","../src/lib/manifest.ts","../src/lib/index.ts"],"sourcesContent":["import { Action } from '@embedpdf/core';\nimport { MatchFlag, SearchResult } from '@embedpdf/models';\nimport { SearchDocumentState } from './types';\n\n// Action Types\nexport const INIT_SEARCH_STATE = 'SEARCH/INIT_STATE';\nexport const CLEANUP_SEARCH_STATE = 'SEARCH/CLEANUP_STATE';\nexport const START_SEARCH_SESSION = 'SEARCH/START_SEARCH_SESSION';\nexport const STOP_SEARCH_SESSION = 'SEARCH/STOP_SEARCH_SESSION';\nexport const SET_SEARCH_FLAGS = 'SEARCH/SET_SEARCH_FLAGS';\nexport const SET_SHOW_ALL_RESULTS = 'SEARCH/SET_SHOW_ALL_RESULTS';\nexport const START_SEARCH = 'SEARCH/START_SEARCH';\nexport const SET_SEARCH_RESULTS = 'SEARCH/SET_SEARCH_RESULTS';\nexport const APPEND_SEARCH_RESULTS = 'SEARCH/APPEND_SEARCH_RESULTS';\nexport const SET_ACTIVE_RESULT_INDEX = 'SEARCH/SET_ACTIVE_RESULT_INDEX';\n\n// Action Interfaces\nexport interface InitSearchStateAction extends Action {\n type: typeof INIT_SEARCH_STATE;\n payload: { documentId: string; state: SearchDocumentState };\n}\n\nexport interface CleanupSearchStateAction extends Action {\n type: typeof CLEANUP_SEARCH_STATE;\n payload: string; // documentId\n}\n\nexport interface StartSearchSessionAction extends Action {\n type: typeof START_SEARCH_SESSION;\n payload: { documentId: string };\n}\n\nexport interface StopSearchSessionAction extends Action {\n type: typeof STOP_SEARCH_SESSION;\n payload: { documentId: string };\n}\n\nexport interface SetSearchFlagsAction extends Action {\n type: typeof SET_SEARCH_FLAGS;\n payload: { documentId: string; flags: MatchFlag[] };\n}\n\nexport interface SetShowAllResultsAction extends Action {\n type: typeof SET_SHOW_ALL_RESULTS;\n payload: { documentId: string; showAll: boolean };\n}\n\nexport interface StartSearchAction extends Action {\n type: typeof START_SEARCH;\n payload: { documentId: string; query: string };\n}\n\nexport interface SetSearchResultsAction extends Action {\n type: typeof SET_SEARCH_RESULTS;\n payload: {\n documentId: string;\n results: SearchResult[];\n total: number;\n activeResultIndex: number;\n };\n}\n\nexport interface AppendSearchResultsAction extends Action {\n type: typeof APPEND_SEARCH_RESULTS;\n payload: {\n documentId: string;\n results: SearchResult[];\n };\n}\n\nexport interface SetActiveResultIndexAction extends Action {\n type: typeof SET_ACTIVE_RESULT_INDEX;\n payload: { documentId: string; index: number };\n}\n\n// Union Type for All Actions\nexport type SearchAction =\n | InitSearchStateAction\n | CleanupSearchStateAction\n | StartSearchSessionAction\n | StopSearchSessionAction\n | SetSearchFlagsAction\n | SetShowAllResultsAction\n | StartSearchAction\n | SetSearchResultsAction\n | AppendSearchResultsAction\n | SetActiveResultIndexAction;\n\n// Action Creators\nexport function initSearchState(\n documentId: string,\n state: SearchDocumentState,\n): InitSearchStateAction {\n return { type: INIT_SEARCH_STATE, payload: { documentId, state } };\n}\n\nexport function cleanupSearchState(documentId: string): CleanupSearchStateAction {\n return { type: CLEANUP_SEARCH_STATE, payload: documentId };\n}\n\nexport function startSearchSession(documentId: string): StartSearchSessionAction {\n return { type: START_SEARCH_SESSION, payload: { documentId } };\n}\n\nexport function stopSearchSession(documentId: string): StopSearchSessionAction {\n return { type: STOP_SEARCH_SESSION, payload: { documentId } };\n}\n\nexport function setSearchFlags(documentId: string, flags: MatchFlag[]): SetSearchFlagsAction {\n return { type: SET_SEARCH_FLAGS, payload: { documentId, flags } };\n}\n\nexport function setShowAllResults(documentId: string, showAll: boolean): SetShowAllResultsAction {\n return { type: SET_SHOW_ALL_RESULTS, payload: { documentId, showAll } };\n}\n\nexport function startSearch(documentId: string, query: string): StartSearchAction {\n return { type: START_SEARCH, payload: { documentId, query } };\n}\n\nexport function setSearchResults(\n documentId: string,\n results: SearchResult[],\n total: number,\n activeResultIndex: number,\n): SetSearchResultsAction {\n return { type: SET_SEARCH_RESULTS, payload: { documentId, results, total, activeResultIndex } };\n}\n\nexport function appendSearchResults(\n documentId: string,\n results: SearchResult[],\n): AppendSearchResultsAction {\n return { type: APPEND_SEARCH_RESULTS, payload: { documentId, results } };\n}\n\nexport function setActiveResultIndex(\n documentId: string,\n index: number,\n): SetActiveResultIndexAction {\n return { type: SET_ACTIVE_RESULT_INDEX, payload: { documentId, index } };\n}\n","import { Reducer } from '@embedpdf/core';\nimport { SearchDocumentState, 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 APPEND_SEARCH_RESULTS,\n SET_ACTIVE_RESULT_INDEX,\n SearchAction,\n INIT_SEARCH_STATE,\n CLEANUP_SEARCH_STATE,\n} from './actions';\nimport { MatchFlag } from '@embedpdf/models';\n\nexport const initialSearchDocumentState: SearchDocumentState = {\n flags: [] as MatchFlag[],\n results: [],\n total: 0,\n activeResultIndex: -1,\n showAllResults: true,\n query: '',\n loading: false,\n active: false,\n};\n\nexport const initialState: SearchState = {\n documents: {},\n};\n\nconst updateDocState = (\n state: SearchState,\n documentId: string,\n newDocState: Partial<SearchDocumentState>,\n): SearchState => {\n const oldDocState = state.documents[documentId] || initialSearchDocumentState;\n return {\n ...state,\n documents: {\n ...state.documents,\n [documentId]: {\n ...oldDocState,\n ...newDocState,\n },\n },\n };\n};\n\nexport const searchReducer: Reducer<SearchState, SearchAction> = (state = initialState, action) => {\n switch (action.type) {\n case INIT_SEARCH_STATE:\n return {\n ...state,\n documents: {\n ...state.documents,\n [action.payload.documentId]: action.payload.state,\n },\n };\n\n case CLEANUP_SEARCH_STATE: {\n const documentId = action.payload;\n const { [documentId]: removed, ...remaining } = state.documents;\n return {\n ...state,\n documents: remaining,\n };\n }\n\n case START_SEARCH_SESSION:\n return updateDocState(state, action.payload.documentId, { active: true });\n\n case STOP_SEARCH_SESSION:\n return updateDocState(state, action.payload.documentId, {\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 updateDocState(state, action.payload.documentId, { flags: action.payload.flags });\n\n case SET_SHOW_ALL_RESULTS:\n return updateDocState(state, action.payload.documentId, {\n showAllResults: action.payload.showAll,\n });\n\n case START_SEARCH:\n return updateDocState(state, action.payload.documentId, {\n loading: true,\n query: action.payload.query,\n // clear old results on new search start\n results: [],\n total: 0,\n activeResultIndex: -1,\n });\n\n case APPEND_SEARCH_RESULTS: {\n const { documentId, results } = action.payload;\n const docState = state.documents[documentId];\n if (!docState) return state;\n\n const newResults = [...docState.results, ...results];\n const firstHitIndex =\n docState.activeResultIndex === -1 && newResults.length > 0 ? 0 : docState.activeResultIndex;\n return updateDocState(state, documentId, {\n results: newResults,\n total: newResults.length, // total-so-far\n activeResultIndex: firstHitIndex,\n // keep loading true until final SET_SEARCH_RESULTS\n loading: true,\n });\n }\n\n case SET_SEARCH_RESULTS: {\n const { documentId, results, total, activeResultIndex } = action.payload;\n return updateDocState(state, documentId, {\n results,\n total,\n activeResultIndex,\n loading: false,\n });\n }\n\n case SET_ACTIVE_RESULT_INDEX:\n return updateDocState(state, action.payload.documentId, {\n activeResultIndex: action.payload.index,\n });\n\n default:\n return state;\n }\n};\n","import { BasePlugin, createBehaviorEmitter, Listener, PluginRegistry } from '@embedpdf/core';\nimport {\n MatchFlag,\n SearchAllPagesResult,\n PdfEngine,\n PdfTask,\n PdfPageSearchProgress,\n PdfTaskHelper,\n PdfErrorCode,\n} from '@embedpdf/models';\nimport {\n SearchPluginConfig,\n SearchCapability,\n SearchState,\n SearchResultState,\n SearchScope,\n SearchResultEvent,\n SearchStartEvent,\n SearchStopEvent,\n ActiveResultChangeEvent,\n SearchResultStateEvent,\n SearchStateEvent,\n SearchDocumentState,\n} from './types';\nimport {\n startSearchSession,\n stopSearchSession,\n setSearchFlags,\n setShowAllResults,\n startSearch,\n setSearchResults,\n setActiveResultIndex,\n appendSearchResults,\n SearchAction,\n initSearchState,\n cleanupSearchState,\n} from './actions';\nimport { initialSearchDocumentState } from './reducer';\n\nexport class SearchPlugin extends BasePlugin<\n SearchPluginConfig,\n SearchCapability,\n SearchState,\n SearchAction\n> {\n static readonly id = 'search' as const;\n\n // Event emitters are now global and include documentId\n private readonly searchStop$ = createBehaviorEmitter<SearchStopEvent>();\n private readonly searchStart$ = createBehaviorEmitter<SearchStartEvent>();\n private readonly searchResult$ = createBehaviorEmitter<SearchResultEvent>();\n private readonly searchActiveResultChange$ = createBehaviorEmitter<ActiveResultChangeEvent>();\n private readonly searchResultState$ = createBehaviorEmitter<SearchResultStateEvent>();\n private readonly searchState$ = createBehaviorEmitter<SearchStateEvent>();\n\n // Keep reference to current running tasks per document\n private currentTask = new Map<string, ReturnType<PdfEngine['searchAllPages']>>();\n private pluginConfig: SearchPluginConfig;\n\n constructor(id: string, registry: PluginRegistry, config: SearchPluginConfig) {\n super(id, registry);\n this.pluginConfig = config;\n // We no longer need to listen to the loader.\n // Document lifecycle is handled by BasePlugin hooks.\n }\n\n protected override onDocumentLoadingStarted(documentId: string): void {\n const initialState = {\n ...initialSearchDocumentState,\n flags: this.pluginConfig.flags || [],\n showAllResults: this.pluginConfig.showAllResults ?? true,\n };\n this.dispatch(initSearchState(documentId, initialState));\n }\n\n protected override onDocumentClosed(documentId: string): void {\n this.stopSearchSession(documentId); // Ensure any running search is stopped\n this.dispatch(cleanupSearchState(documentId));\n this.currentTask.delete(documentId);\n }\n\n async initialize(): Promise<void> {\n // Config is now handled in onDocumentLoadingStarted\n }\n\n override onStoreUpdated(prevState: SearchState, newState: SearchState): void {\n for (const documentId in newState.documents) {\n const prevDocState = prevState.documents[documentId];\n const newDocState = newState.documents[documentId];\n\n if (prevDocState !== newDocState) {\n // Emit per-document state\n this.searchState$.emit({ documentId, state: newDocState });\n\n // Emit reactive result state\n if (\n !prevDocState ||\n prevDocState.results !== newDocState.results ||\n prevDocState.activeResultIndex !== newDocState.activeResultIndex ||\n prevDocState.showAllResults !== newDocState.showAllResults ||\n prevDocState.active !== newDocState.active\n ) {\n this.searchResultState$.emit({\n documentId,\n state: {\n results: newDocState.results,\n activeResultIndex: newDocState.activeResultIndex,\n showAllResults: newDocState.showAllResults,\n active: newDocState.active,\n },\n });\n }\n }\n }\n }\n\n protected buildCapability(): SearchCapability {\n const getDocId = (documentId?: string) => documentId ?? this.getActiveDocumentId();\n const getDocState = (docId?: string) => {\n const id = getDocId(docId);\n const state = this.state.documents[id];\n if (!state) throw new Error(`Search state not found for document ${id}`);\n return state;\n };\n\n return {\n startSearch: (docId) => this.startSearchSession(getDocId(docId)),\n stopSearch: (docId) => this.stopSearchSession(getDocId(docId)),\n searchAllPages: (keyword, docId) => this.searchAllPages(keyword, getDocId(docId)),\n nextResult: (docId) => this.nextResult(getDocId(docId)),\n previousResult: (docId) => this.previousResult(getDocId(docId)),\n goToResult: (index, docId) => this.goToResult(index, getDocId(docId)),\n setShowAllResults: (showAll, docId) =>\n this.dispatch(setShowAllResults(getDocId(docId), showAll)),\n getShowAllResults: (docId) => getDocState(docId).showAllResults,\n getFlags: (docId) => getDocState(docId).flags,\n setFlags: (flags, docId) => this.setFlags(flags, getDocId(docId)),\n getState: (docId) => getDocState(docId),\n forDocument: this.createSearchScope.bind(this),\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 };\n }\n\n private createSearchScope(documentId: string): SearchScope {\n const getDocState = () => {\n const state = this.state.documents[documentId];\n if (!state) throw new Error(`Search state not found for document ${documentId}`);\n return state;\n };\n\n return {\n startSearch: () => this.startSearchSession(documentId),\n stopSearch: () => this.stopSearchSession(documentId),\n searchAllPages: (keyword) => this.searchAllPages(keyword, documentId),\n nextResult: () => this.nextResult(documentId),\n previousResult: () => this.previousResult(documentId),\n goToResult: (index) => this.goToResult(index, documentId),\n setShowAllResults: (showAll) => this.dispatch(setShowAllResults(documentId, showAll)),\n getShowAllResults: () => getDocState().showAllResults,\n getFlags: () => getDocState().flags,\n setFlags: (flags) => this.setFlags(flags, documentId),\n getState: getDocState,\n onSearchResult: (listener: Listener<SearchAllPagesResult>) =>\n this.searchResult$.on((event) => {\n if (event.documentId === documentId) listener(event.results);\n }),\n onSearchStart: (listener: Listener<void>) =>\n this.searchStart$.on((event) => {\n if (event.documentId === documentId) listener();\n }),\n onSearchStop: (listener: Listener<void>) =>\n this.searchStop$.on((event) => {\n if (event.documentId === documentId) listener();\n }),\n onActiveResultChange: (listener: Listener<number>) =>\n this.searchActiveResultChange$.on((event) => {\n if (event.documentId === documentId) listener(event.index);\n }),\n onSearchResultStateChange: (listener: Listener<SearchResultState>) =>\n this.searchResultState$.on((event) => {\n if (event.documentId === documentId) listener(event.state);\n }),\n onStateChange: (listener: Listener<SearchDocumentState>) =>\n this.searchState$.on((event) => {\n if (event.documentId === documentId) listener(event.state);\n }),\n };\n }\n\n private setFlags(flags: MatchFlag[], documentId: string): void {\n this.dispatch(setSearchFlags(documentId, flags));\n const docState = this.state.documents[documentId];\n if (docState?.active) {\n this.searchAllPages(docState.query, documentId, true);\n }\n }\n\n private notifySearchStart(documentId: string): void {\n this.searchStart$.emit({ documentId });\n }\n\n private notifySearchStop(documentId: string): void {\n this.searchStop$.emit({ documentId });\n }\n\n private notifyActiveResultChange(documentId: string, index: number): void {\n this.searchActiveResultChange$.emit({ documentId, index });\n }\n\n private startSearchSession(documentId: string): void {\n const coreDoc = this.getCoreDocument(documentId);\n if (!coreDoc) return;\n this.dispatch(startSearchSession(documentId));\n this.notifySearchStart(documentId);\n }\n\n private stopSearchSession(documentId: string): void {\n const docState = this.state.documents[documentId];\n if (!docState?.active) return;\n\n const task = this.currentTask.get(documentId);\n if (task) {\n try {\n task.abort?.({ code: PdfErrorCode.Cancelled, message: 'search stopped' });\n } catch {}\n this.currentTask.delete(documentId);\n }\n\n this.dispatch(stopSearchSession(documentId));\n this.notifySearchStop(documentId);\n }\n\n private searchAllPages(\n keyword: string,\n documentId: string,\n force: boolean = false,\n ): PdfTask<SearchAllPagesResult, PdfPageSearchProgress> {\n const docState = this.state.documents[documentId];\n if (!docState) {\n return PdfTaskHelper.reject({\n code: PdfErrorCode.NotFound,\n message: 'Search state not initialized',\n });\n }\n const coreDoc = this.getCoreDocument(documentId);\n if (!coreDoc?.document) {\n return PdfTaskHelper.reject({ code: PdfErrorCode.NotFound, message: 'Document not loaded' });\n }\n\n const trimmedKeyword = keyword.trim();\n\n if (docState.query === trimmedKeyword && !force) {\n return PdfTaskHelper.resolve<SearchAllPagesResult, PdfPageSearchProgress>({\n results: docState.results,\n total: docState.total,\n });\n }\n\n // stop previous task if still running\n const oldTask = this.currentTask.get(documentId);\n if (oldTask) {\n try {\n oldTask.abort?.({ code: PdfErrorCode.Cancelled, message: 'new search' });\n } catch {}\n this.currentTask.delete(documentId);\n }\n\n this.dispatch(startSearch(documentId, trimmedKeyword));\n\n if (!trimmedKeyword) {\n this.dispatch(setSearchResults(documentId, [], 0, -1));\n return PdfTaskHelper.resolve<SearchAllPagesResult, PdfPageSearchProgress>({\n results: [],\n total: 0,\n });\n }\n\n if (!docState.active) {\n this.startSearchSession(documentId);\n }\n\n const task = this.engine.searchAllPages(coreDoc.document, trimmedKeyword, {\n flags: docState.flags,\n });\n this.currentTask.set(documentId, task);\n\n task.onProgress((p) => {\n if (p?.results?.length) {\n // Check if the task is still the current one before dispatching\n if (this.currentTask.get(documentId) === task) {\n this.dispatch(appendSearchResults(documentId, p.results));\n // set first active result as soon as we have something\n if (this.state.documents[documentId].activeResultIndex === -1) {\n this.dispatch(setActiveResultIndex(documentId, 0));\n this.notifyActiveResultChange(documentId, 0);\n }\n }\n }\n });\n\n task.wait(\n (results) => {\n this.currentTask.delete(documentId);\n const activeResultIndex = results.total > 0 ? 0 : -1;\n this.dispatch(\n setSearchResults(documentId, results.results, results.total, activeResultIndex),\n );\n this.searchResult$.emit({ documentId, results });\n if (results.total > 0) {\n this.notifyActiveResultChange(documentId, 0);\n }\n },\n (error) => {\n // Only clear results if the error wasn't an abort\n if (error?.reason?.code !== PdfErrorCode.Cancelled) {\n console.error('Error during search:', error);\n this.dispatch(setSearchResults(documentId, [], 0, -1));\n }\n this.currentTask.delete(documentId);\n },\n );\n\n return task;\n }\n\n private nextResult(documentId: string): number {\n const docState = this.state.documents[documentId];\n if (!docState || docState.results.length === 0) return -1;\n const nextIndex =\n docState.activeResultIndex >= docState.results.length - 1\n ? 0\n : docState.activeResultIndex + 1;\n return this.goToResult(nextIndex, documentId);\n }\n\n private previousResult(documentId: string): number {\n const docState = this.state.documents[documentId];\n if (!docState || docState.results.length === 0) return -1;\n const prevIndex =\n docState.activeResultIndex <= 0\n ? docState.results.length - 1\n : docState.activeResultIndex - 1;\n return this.goToResult(prevIndex, documentId);\n }\n\n private goToResult(index: number, documentId: string): number {\n const docState = this.state.documents[documentId];\n if (\n !docState ||\n docState.results.length === 0 ||\n index < 0 ||\n index >= docState.results.length\n ) {\n return -1;\n }\n this.dispatch(setActiveResultIndex(documentId, index));\n this.notifyActiveResultChange(documentId, index);\n return index;\n }\n\n async destroy(): Promise<void> {\n for (const documentId of Object.keys(this.state.documents)) {\n this.stopSearchSession(documentId);\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 super.destroy();\n }\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: [],\n optional: [],\n defaultConfig: {\n enabled: true,\n flags: [],\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, initialSearchDocumentState } 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, config) => new SearchPlugin(SEARCH_PLUGIN_ID, registry, config),\n reducer: searchReducer,\n initialState,\n};\n\nexport * from './search-plugin';\nexport * from './types';\nexport * from './manifest';\nexport { initialState, initialSearchDocumentState };\n"],"names":["initialState","_a"],"mappings":"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"}
@@ -1,34 +1,64 @@
1
1
  import { Action } from '@embedpdf/core';
2
2
  import { MatchFlag, SearchResult } from '@embedpdf/models';
3
- export declare const START_SEARCH_SESSION = "START_SEARCH_SESSION";
4
- export declare const STOP_SEARCH_SESSION = "STOP_SEARCH_SESSION";
5
- export declare const SET_SEARCH_FLAGS = "SET_SEARCH_FLAGS";
6
- export declare const SET_SHOW_ALL_RESULTS = "SET_SHOW_ALL_RESULTS";
7
- export declare const START_SEARCH = "START_SEARCH";
8
- export declare const SET_SEARCH_RESULTS = "SET_SEARCH_RESULTS";
9
- export declare const APPEND_SEARCH_RESULTS = "APPEND_SEARCH_RESULTS";
10
- export declare const SET_ACTIVE_RESULT_INDEX = "SET_ACTIVE_RESULT_INDEX";
3
+ import { SearchDocumentState } from './types';
4
+ export declare const INIT_SEARCH_STATE = "SEARCH/INIT_STATE";
5
+ export declare const CLEANUP_SEARCH_STATE = "SEARCH/CLEANUP_STATE";
6
+ export declare const START_SEARCH_SESSION = "SEARCH/START_SEARCH_SESSION";
7
+ export declare const STOP_SEARCH_SESSION = "SEARCH/STOP_SEARCH_SESSION";
8
+ export declare const SET_SEARCH_FLAGS = "SEARCH/SET_SEARCH_FLAGS";
9
+ export declare const SET_SHOW_ALL_RESULTS = "SEARCH/SET_SHOW_ALL_RESULTS";
10
+ export declare const START_SEARCH = "SEARCH/START_SEARCH";
11
+ export declare const SET_SEARCH_RESULTS = "SEARCH/SET_SEARCH_RESULTS";
12
+ export declare const APPEND_SEARCH_RESULTS = "SEARCH/APPEND_SEARCH_RESULTS";
13
+ export declare const SET_ACTIVE_RESULT_INDEX = "SEARCH/SET_ACTIVE_RESULT_INDEX";
14
+ export interface InitSearchStateAction extends Action {
15
+ type: typeof INIT_SEARCH_STATE;
16
+ payload: {
17
+ documentId: string;
18
+ state: SearchDocumentState;
19
+ };
20
+ }
21
+ export interface CleanupSearchStateAction extends Action {
22
+ type: typeof CLEANUP_SEARCH_STATE;
23
+ payload: string;
24
+ }
11
25
  export interface StartSearchSessionAction extends Action {
12
26
  type: typeof START_SEARCH_SESSION;
27
+ payload: {
28
+ documentId: string;
29
+ };
13
30
  }
14
31
  export interface StopSearchSessionAction extends Action {
15
32
  type: typeof STOP_SEARCH_SESSION;
33
+ payload: {
34
+ documentId: string;
35
+ };
16
36
  }
17
37
  export interface SetSearchFlagsAction extends Action {
18
38
  type: typeof SET_SEARCH_FLAGS;
19
- payload: MatchFlag[];
39
+ payload: {
40
+ documentId: string;
41
+ flags: MatchFlag[];
42
+ };
20
43
  }
21
44
  export interface SetShowAllResultsAction extends Action {
22
45
  type: typeof SET_SHOW_ALL_RESULTS;
23
- payload: boolean;
46
+ payload: {
47
+ documentId: string;
48
+ showAll: boolean;
49
+ };
24
50
  }
25
51
  export interface StartSearchAction extends Action {
26
52
  type: typeof START_SEARCH;
27
- payload: string;
53
+ payload: {
54
+ documentId: string;
55
+ query: string;
56
+ };
28
57
  }
29
58
  export interface SetSearchResultsAction extends Action {
30
59
  type: typeof SET_SEARCH_RESULTS;
31
60
  payload: {
61
+ documentId: string;
32
62
  results: SearchResult[];
33
63
  total: number;
34
64
  activeResultIndex: number;
@@ -37,19 +67,25 @@ export interface SetSearchResultsAction extends Action {
37
67
  export interface AppendSearchResultsAction extends Action {
38
68
  type: typeof APPEND_SEARCH_RESULTS;
39
69
  payload: {
70
+ documentId: string;
40
71
  results: SearchResult[];
41
72
  };
42
73
  }
43
74
  export interface SetActiveResultIndexAction extends Action {
44
75
  type: typeof SET_ACTIVE_RESULT_INDEX;
45
- payload: number;
46
- }
47
- export type SearchAction = StartSearchSessionAction | StopSearchSessionAction | SetSearchFlagsAction | SetShowAllResultsAction | StartSearchAction | SetSearchResultsAction | AppendSearchResultsAction | SetActiveResultIndexAction;
48
- export declare function startSearchSession(): StartSearchSessionAction;
49
- export declare function stopSearchSession(): StopSearchSessionAction;
50
- export declare function setSearchFlags(flags: MatchFlag[]): SetSearchFlagsAction;
51
- export declare function setShowAllResults(showAll: boolean): SetShowAllResultsAction;
52
- export declare function startSearch(query: string): StartSearchAction;
53
- export declare function setSearchResults(results: SearchResult[], total: number, activeResultIndex: number): SetSearchResultsAction;
54
- export declare function appendSearchResults(results: SearchResult[]): AppendSearchResultsAction;
55
- export declare function setActiveResultIndex(index: number): SetActiveResultIndexAction;
76
+ payload: {
77
+ documentId: string;
78
+ index: number;
79
+ };
80
+ }
81
+ export type SearchAction = InitSearchStateAction | CleanupSearchStateAction | StartSearchSessionAction | StopSearchSessionAction | SetSearchFlagsAction | SetShowAllResultsAction | StartSearchAction | SetSearchResultsAction | AppendSearchResultsAction | SetActiveResultIndexAction;
82
+ export declare function initSearchState(documentId: string, state: SearchDocumentState): InitSearchStateAction;
83
+ export declare function cleanupSearchState(documentId: string): CleanupSearchStateAction;
84
+ export declare function startSearchSession(documentId: string): StartSearchSessionAction;
85
+ export declare function stopSearchSession(documentId: string): StopSearchSessionAction;
86
+ export declare function setSearchFlags(documentId: string, flags: MatchFlag[]): SetSearchFlagsAction;
87
+ export declare function setShowAllResults(documentId: string, showAll: boolean): SetShowAllResultsAction;
88
+ export declare function startSearch(documentId: string, query: string): StartSearchAction;
89
+ export declare function setSearchResults(documentId: string, results: SearchResult[], total: number, activeResultIndex: number): SetSearchResultsAction;
90
+ export declare function appendSearchResults(documentId: string, results: SearchResult[]): AppendSearchResultsAction;
91
+ export declare function setActiveResultIndex(documentId: string, index: number): SetActiveResultIndexAction;
@@ -1,10 +1,10 @@
1
1
  import { PluginPackage } from '@embedpdf/core';
2
2
  import { SearchPlugin } from './search-plugin';
3
3
  import { SearchPluginConfig, SearchState } from './types';
4
- import { initialState } from './reducer';
4
+ import { initialState, initialSearchDocumentState } from './reducer';
5
5
  import { SearchAction } from './actions';
6
6
  export declare const SearchPluginPackage: PluginPackage<SearchPlugin, SearchPluginConfig, SearchState, SearchAction>;
7
7
  export * from './search-plugin';
8
8
  export * from './types';
9
9
  export * from './manifest';
10
- export { initialState };
10
+ export { initialState, initialSearchDocumentState };
@@ -1,5 +1,6 @@
1
1
  import { Reducer } from '@embedpdf/core';
2
- import { SearchState } from './types';
2
+ import { SearchDocumentState, SearchState } from './types';
3
3
  import { SearchAction } from './actions';
4
+ export declare const initialSearchDocumentState: SearchDocumentState;
4
5
  export declare const initialState: SearchState;
5
6
  export declare const searchReducer: Reducer<SearchState, SearchAction>;
@@ -3,21 +3,21 @@ import { SearchPluginConfig, SearchCapability, SearchState } from './types';
3
3
  import { SearchAction } from './actions';
4
4
  export declare class SearchPlugin extends BasePlugin<SearchPluginConfig, SearchCapability, SearchState, SearchAction> {
5
5
  static readonly id: "search";
6
- private loader;
7
- private currentDocument?;
8
6
  private readonly searchStop$;
9
7
  private readonly searchStart$;
10
8
  private readonly searchResult$;
11
9
  private readonly searchActiveResultChange$;
12
10
  private readonly searchResultState$;
13
11
  private readonly searchState$;
14
- private currentTask?;
15
- constructor(id: string, registry: PluginRegistry);
16
- private handleDocumentLoaded;
17
- private handleLoaderEvent;
18
- initialize(config: SearchPluginConfig): Promise<void>;
19
- onStoreUpdated(_prevState: SearchState, newState: SearchState): void;
12
+ private currentTask;
13
+ private pluginConfig;
14
+ constructor(id: string, registry: PluginRegistry, config: SearchPluginConfig);
15
+ protected onDocumentLoadingStarted(documentId: string): void;
16
+ protected onDocumentClosed(documentId: string): void;
17
+ initialize(): Promise<void>;
18
+ onStoreUpdated(prevState: SearchState, newState: SearchState): void;
20
19
  protected buildCapability(): SearchCapability;
20
+ private createSearchScope;
21
21
  private setFlags;
22
22
  private notifySearchStart;
23
23
  private notifySearchStop;
@@ -8,11 +8,19 @@ export interface SearchPluginConfig extends BasePluginConfig {
8
8
  */
9
9
  showAllResults?: boolean;
10
10
  }
11
- export interface SearchResultState {
11
+ /**
12
+ * This is the state for a *single* document
13
+ */
14
+ export interface SearchDocumentState {
15
+ flags: MatchFlag[];
12
16
  /**
13
17
  * Current search results from last search operation
14
18
  */
15
19
  results: SearchResult[];
20
+ /**
21
+ * Total number of search results
22
+ */
23
+ total: number;
16
24
  /**
17
25
  * Current active result index (0-based)
18
26
  */
@@ -21,21 +29,33 @@ export interface SearchResultState {
21
29
  * Whether to show all search results or only the active one
22
30
  */
23
31
  showAllResults: boolean;
32
+ /**
33
+ * Current search query
34
+ */
35
+ query: string;
36
+ /**
37
+ * Whether a search operation is in progress
38
+ */
39
+ loading: boolean;
24
40
  /**
25
41
  * Whether search is currently active
26
42
  */
27
43
  active: boolean;
28
44
  }
45
+ /**
46
+ * This is the combined state for the plugin
47
+ */
29
48
  export interface SearchState {
30
- flags: MatchFlag[];
49
+ documents: Record<string, SearchDocumentState>;
50
+ }
51
+ /**
52
+ * This is the payload for the reactive result state
53
+ */
54
+ export interface SearchResultState {
31
55
  /**
32
56
  * Current search results from last search operation
33
57
  */
34
58
  results: SearchResult[];
35
- /**
36
- * Total number of search results
37
- */
38
- total: number;
39
59
  /**
40
60
  * Current active result index (0-based)
41
61
  */
@@ -44,20 +64,34 @@ export interface SearchState {
44
64
  * Whether to show all search results or only the active one
45
65
  */
46
66
  showAllResults: boolean;
47
- /**
48
- * Current search query
49
- */
50
- query: string;
51
- /**
52
- * Whether a search operation is in progress
53
- */
54
- loading: boolean;
55
67
  /**
56
68
  * Whether search is currently active
57
69
  */
58
70
  active: boolean;
59
71
  }
60
- export interface SearchCapability {
72
+ export interface SearchResultEvent {
73
+ documentId: string;
74
+ results: SearchAllPagesResult;
75
+ }
76
+ export interface SearchStartEvent {
77
+ documentId: string;
78
+ }
79
+ export interface SearchStopEvent {
80
+ documentId: string;
81
+ }
82
+ export interface ActiveResultChangeEvent {
83
+ documentId: string;
84
+ index: number;
85
+ }
86
+ export interface SearchResultStateEvent {
87
+ documentId: string;
88
+ state: SearchResultState;
89
+ }
90
+ export interface SearchStateEvent {
91
+ documentId: string;
92
+ state: SearchDocumentState;
93
+ }
94
+ export interface SearchScope {
61
95
  /**
62
96
  * Start a search session
63
97
  */
@@ -68,85 +102,64 @@ export interface SearchCapability {
68
102
  stopSearch: () => void;
69
103
  /**
70
104
  * Search for all occurrences of the keyword throughout the document
71
- * @param keyword - Text to search for
72
- * @returns Promise that resolves to all search results or empty result if none found
73
105
  */
74
106
  searchAllPages: (keyword: string) => PdfTask<SearchAllPagesResult, PdfPageSearchProgress>;
75
107
  /**
76
108
  * Navigate to the next search result
77
- * @returns The new active result index
78
109
  */
79
110
  nextResult: () => number;
80
111
  /**
81
112
  * Navigate to the previous search result
82
- * @returns The new active result index
83
113
  */
84
114
  previousResult: () => number;
85
115
  /**
86
116
  * Go to a specific search result by index
87
- * @param index - The index of the result to go to
88
- * @returns The new active result index
89
117
  */
90
118
  goToResult: (index: number) => number;
91
119
  /**
92
120
  * Toggle visibility of all search results
93
- * @param showAll - Whether to show all results or only the active one
94
121
  */
95
122
  setShowAllResults: (showAll: boolean) => void;
96
123
  /**
97
124
  * Get current state of search results visibility
98
- * @returns Whether all results are visible
99
125
  */
100
126
  getShowAllResults: () => boolean;
101
- /**
102
- * Subscribe to search results
103
- * @param handler - Handler function to receive search results
104
- * @returns Function to unsubscribe the handler
105
- */
106
- onSearchResult: EventHook<SearchAllPagesResult>;
107
- /**
108
- * Subscribe to search session start events
109
- * @param handler - Handler function called when search session starts
110
- * @returns Function to unsubscribe the handler
111
- */
112
- onSearchStart: EventHook;
113
- /**
114
- * Subscribe to search session stop events
115
- * @param handler - Handler function called when search session stops
116
- * @returns Function to unsubscribe the handler
117
- */
118
- onSearchStop: EventHook;
119
- /**
120
- * Subscribe to active result change events
121
- * @param handler - Handler function called when active result changes
122
- * @returns Function to unsubscribe the handler
123
- */
124
- onActiveResultChange: EventHook<number>;
125
- /**
126
- * Subscribe to search result state change events
127
- * @param handler - Handler function called when search state changes
128
- * @returns Function to unsubscribe the handler
129
- */
130
- onSearchResultStateChange: EventHook<SearchResultState>;
131
127
  /**
132
128
  * Get the current search flags
133
- * @returns Array of active search flags
134
129
  */
135
130
  getFlags: () => MatchFlag[];
136
131
  /**
137
132
  * Set the search flags
138
- * @param flags - Array of search flags to use
139
133
  */
140
134
  setFlags: (flags: MatchFlag[]) => void;
141
- /**
142
- * Subscribe to state change events
143
- * @param handler - Handler function called when state changes
144
- * @returns Function to unsubscribe the handler
145
- */
146
- onStateChange: EventHook<SearchState>;
147
135
  /**
148
136
  * Get the current search state
149
- * @returns The current search state
150
137
  */
151
- getState: () => SearchState;
138
+ getState: () => SearchDocumentState;
139
+ onSearchResult: EventHook<SearchAllPagesResult>;
140
+ onSearchStart: EventHook<void>;
141
+ onSearchStop: EventHook<void>;
142
+ onActiveResultChange: EventHook<number>;
143
+ onSearchResultStateChange: EventHook<SearchResultState>;
144
+ onStateChange: EventHook<SearchDocumentState>;
145
+ }
146
+ export interface SearchCapability {
147
+ startSearch: (documentId?: string) => void;
148
+ stopSearch: (documentId?: string) => void;
149
+ searchAllPages: (keyword: string, documentId?: string) => PdfTask<SearchAllPagesResult, PdfPageSearchProgress>;
150
+ nextResult: (documentId?: string) => number;
151
+ previousResult: (documentId?: string) => number;
152
+ goToResult: (index: number, documentId?: string) => number;
153
+ setShowAllResults: (showAll: boolean, documentId?: string) => void;
154
+ getShowAllResults: (documentId?: string) => boolean;
155
+ getFlags: (documentId?: string) => MatchFlag[];
156
+ setFlags: (flags: MatchFlag[], documentId?: string) => void;
157
+ getState: (documentId?: string) => SearchDocumentState;
158
+ forDocument(documentId: string): SearchScope;
159
+ onSearchResult: EventHook<SearchResultEvent>;
160
+ onSearchStart: EventHook<SearchStartEvent>;
161
+ onSearchStop: EventHook<SearchStopEvent>;
162
+ onActiveResultChange: EventHook<ActiveResultChangeEvent>;
163
+ onSearchResultStateChange: EventHook<SearchResultStateEvent>;
164
+ onStateChange: EventHook<SearchStateEvent>;
152
165
  }
@@ -1,5 +1,5 @@
1
1
  export { Fragment } from 'preact';
2
- export { useEffect, useRef, useState } from 'preact/hooks';
2
+ export { useEffect, useRef, useState, useMemo } from 'preact/hooks';
3
3
  export type { ComponentChildren as ReactNode } from 'preact';
4
4
  export type CSSProperties = import('preact').JSX.CSSProperties;
5
5
  export type HTMLAttributes<T = any> = import('preact').JSX.HTMLAttributes<T extends EventTarget ? T : never>;
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/preact"),t=require("@embedpdf/plugin-search");require("preact");const r=require("preact/hooks"),i=require("preact/jsx-runtime"),s=()=>e.useCapability(t.SearchPlugin.id);exports.SearchLayer=function({pageIndex:e,scale:t,style:o,highlightColor:a="#FFFF00",activeHighlightColor:n="#FFBF00",...l}){const{provides:u}=s(),[c,p]=r.useState(null);if(r.useEffect((()=>null==u?void 0:u.onSearchResultStateChange((e=>{p(e)}))),[u]),!c)return null;const d=c.results.map(((e,t)=>({result:e,originalIndex:t}))).filter((({result:t})=>t.pageIndex===e));return i.jsx("div",{style:{...o},...l,children:d.map((({result:e,originalIndex:r})=>e.rects.map(((e,s)=>i.jsx("div",{style:{position:"absolute",top:e.origin.y*t,left:e.origin.x*t,width:e.size.width*t,height:e.size.height*t,backgroundColor:r===c.activeResultIndex?n:a,mixBlendMode:"multiply",transform:"scale(1.02)",transformOrigin:"center",transition:"opacity .3s ease-in-out",opacity:1}},`${r}-${s}`)))))})},exports.useSearch=()=>{const{provides:e}=s(),[i,o]=r.useState(t.initialState);return r.useEffect((()=>null==e?void 0:e.onStateChange((e=>o(e)))),[e]),{state:i,provides:e}},exports.useSearchCapability=s,exports.useSearchPlugin=()=>e.usePlugin(t.SearchPlugin.id),Object.keys(t).forEach((e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})}));
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("@embedpdf/core/preact"),t=require("@embedpdf/plugin-search");require("preact");const r=require("preact/hooks"),i=require("preact/jsx-runtime"),s=()=>e.useCapability(t.SearchPlugin.id);exports.SearchLayer=function({documentId:t,pageIndex:o,scale:l,style:n,highlightColor:a="#FFFF00",activeHighlightColor:u="#FFBF00",...c}){const{provides:d}=s(),[p,h]=r.useState(null),g=e.useDocumentState(t),f=r.useMemo(()=>null==d?void 0:d.forDocument(t),[d,t]),m=r.useMemo(()=>void 0!==l?l:(null==g?void 0:g.scale)??1,[l,null==g?void 0:g.scale]);if(r.useEffect(()=>{if(!f)return void h(null);const e=f.getState();return h({results:e.results,activeResultIndex:e.activeResultIndex,showAllResults:e.showAllResults,active:e.active}),f.onSearchResultStateChange(e=>{h(e)})},[f]),!p||!p.active)return null;const v=p.results.map((e,t)=>({result:e,originalIndex:t})).filter(({result:e})=>e.pageIndex===o).filter(({originalIndex:e})=>p.showAllResults||e===p.activeResultIndex);return i.jsx("div",{style:{...n,pointerEvents:"none"},...c,children:v.map(({result:e,originalIndex:t})=>e.rects.map((e,r)=>i.jsx("div",{style:{position:"absolute",top:e.origin.y*m,left:e.origin.x*m,width:e.size.width*m,height:e.size.height*m,backgroundColor:t===p.activeResultIndex?u:a,mixBlendMode:"multiply",transform:"scale(1.02)",transformOrigin:"center",transition:"opacity .3s ease-in-out",opacity:1}},`${t}-${r}`)))})},exports.useSearch=e=>{const{provides:i}=s(),[o,l]=r.useState(t.initialSearchDocumentState),n=r.useMemo(()=>null==i?void 0:i.forDocument(e),[i,e]);return r.useEffect(()=>{if(n)return l(n.getState()),n.onStateChange(e=>l(e));l(t.initialSearchDocumentState)},[n]),{state:o,provides:n??null}},exports.useSearchCapability=s,exports.useSearchPlugin=()=>e.usePlugin(t.SearchPlugin.id),Object.keys(t).forEach(e=>{"default"===e||Object.prototype.hasOwnProperty.call(exports,e)||Object.defineProperty(exports,e,{enumerable:!0,get:()=>t[e]})});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-search.ts","../../src/shared/components/search-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport { initialState, SearchPlugin, SearchState } from '@embedpdf/plugin-search';\nimport { useEffect, useState } from '@framework';\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>(initialState);\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, HTMLAttributes, CSSProperties } from '@framework';\nimport { SearchResultState } from '@embedpdf/plugin-search';\n\nimport { useSearchCapability } from '../hooks';\n\ntype SearchLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n pageIndex: number;\n scale: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n style?: 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, rectIndex) => (\n <div\n key={`${originalIndex}-${rectIndex}`}\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"],"names":["useSearchCapability","useCapability","SearchPlugin","id","pageIndex","scale","style","highlightColor","activeHighlightColor","props","provides","searchProvides","searchResultState","setSearchResultState","useState","useEffect","onSearchResultStateChange","state","pageResults","results","map","result","originalIndex","filter","jsxRuntime","jsx","children","rects","rect","rectIndex","position","top","origin","y","left","x","width","size","height","backgroundColor","activeResultIndex","mixBlendMode","transform","transformOrigin","transition","opacity","searchState","setSearchState","initialState","onStateChange","usePlugin"],"mappings":"gPAKaA,EAAsB,IAAMC,gBAA4BC,EAAAA,aAAaC,wBCQ3E,UAAqBC,UAC1BA,EAAAC,MACAA,EAAAC,MACAA,EAAAC,eACAA,EAAiB,UAAAC,qBACjBA,EAAuB,aACpBC,IAEH,MAAQC,SAAUC,GAAmBX,KAC9BY,EAAmBC,GAAwBC,EAAAA,SAAmC,MAQrF,GANAC,EAAAA,WAAU,IACD,MAAAJ,OAAA,EAAAA,EAAgBK,2BAA2BC,IAChDJ,EAAqBI,EAAK,KAE3B,CAACN,KAECC,EACI,OAAA,KAIT,MAAMM,EAAcN,EAAkBO,QACnCC,KAAI,CAACC,EAAQC,MAAqBD,SAAQC,oBAC1CC,QAAO,EAAGF,YAAaA,EAAOjB,YAAcA,IAG7C,OAAAoB,EAAAC,IAAC,MAAA,CACCnB,MAAO,IACFA,MAEDG,EAEHiB,SAAYR,EAAAE,KAAI,EAAGC,SAAQC,mBAC1BD,EAAOM,MAAMP,KAAI,CAACQ,EAAMC,IACtBL,EAAAC,IAAC,MAAA,CAECnB,MAAO,CACLwB,SAAU,WACVC,IAAKH,EAAKI,OAAOC,EAAI5B,EACrB6B,KAAMN,EAAKI,OAAOG,EAAI9B,EACtB+B,MAAOR,EAAKS,KAAKD,MAAQ/B,EACzBiC,OAAQV,EAAKS,KAAKC,OAASjC,EAC3BkC,gBACEjB,IAAkBV,EAAkB4B,kBAChChC,EACAD,EACNkC,aAAc,WACdC,UAAW,cACXC,gBAAiB,SACjBC,WAAY,0BACZC,QAAS,IAfN,GAAGvB,KAAiBO,UAsBrC,oBDhEyB,KACjB,MAAAnB,SAAEA,GAAaV,KACd8C,EAAaC,GAAkBjC,EAAAA,SAAsBkC,EAAAA,cAMrD,OAJPjC,EAAAA,WAAU,IACS,MAAVL,OAAU,EAAAA,EAAAuC,eAAehC,GAAU8B,EAAe9B,MACxD,CAACP,IAEG,CACLO,MAAO6B,EACPpC,WACF,wDAd6B,IAAMwC,YAAwBhD,EAAAA,aAAaC"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/shared/hooks/use-search.ts","../../src/shared/components/search-layer.tsx"],"sourcesContent":["import { useCapability, usePlugin } from '@embedpdf/core/@framework';\nimport {\n SearchPlugin,\n SearchDocumentState,\n SearchScope,\n initialSearchDocumentState,\n} from '@embedpdf/plugin-search';\nimport { useEffect, useMemo, useState } from '@framework';\n\nexport const useSearchPlugin = () => usePlugin<SearchPlugin>(SearchPlugin.id);\nexport const useSearchCapability = () => useCapability<SearchPlugin>(SearchPlugin.id);\n\nexport const useSearch = (\n documentId: string,\n): {\n state: SearchDocumentState;\n provides: SearchScope | null;\n} => {\n const { provides } = useSearchCapability();\n const [searchState, setSearchState] = useState<SearchDocumentState>(initialSearchDocumentState);\n\n const scope = useMemo(() => provides?.forDocument(documentId), [provides, documentId]);\n\n useEffect(() => {\n if (!scope) {\n setSearchState(initialSearchDocumentState);\n return;\n }\n // Set initial state\n setSearchState(scope.getState());\n // Subscribe to changes\n return scope.onStateChange((state) => setSearchState(state));\n }, [scope]);\n\n return {\n state: searchState,\n provides: scope ?? null,\n };\n};\n","import { useEffect, useMemo, useState, HTMLAttributes, CSSProperties } from '@framework';\nimport { useDocumentState } from '@embedpdf/core/@framework';\nimport { SearchResultState } from '@embedpdf/plugin-search';\n\nimport { useSearchCapability } from '../hooks';\n\ntype SearchLayoutProps = Omit<HTMLAttributes<HTMLDivElement>, 'style'> & {\n documentId: string;\n pageIndex: number;\n scale?: number;\n highlightColor?: string;\n activeHighlightColor?: string;\n style?: CSSProperties;\n};\n\nexport function SearchLayer({\n documentId,\n pageIndex,\n scale: scaleOverride,\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 const documentState = useDocumentState(documentId);\n\n const scope = useMemo(\n () => searchProvides?.forDocument(documentId),\n [searchProvides, documentId],\n );\n\n const actualScale = useMemo(() => {\n if (scaleOverride !== undefined) return scaleOverride;\n return documentState?.scale ?? 1;\n }, [scaleOverride, documentState?.scale]);\n\n useEffect(() => {\n if (!scope) {\n setSearchResultState(null);\n return;\n }\n // Set initial state\n const currentState = scope.getState();\n setSearchResultState({\n results: currentState.results,\n activeResultIndex: currentState.activeResultIndex,\n showAllResults: currentState.showAllResults,\n active: currentState.active,\n });\n // Subscribe to changes\n return scope.onSearchResultStateChange((state) => {\n setSearchResultState(state);\n });\n }, [scope]);\n\n if (!searchResultState || !searchResultState.active) {\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 // Decide which results to show\n const resultsToShow = pageResults.filter(\n ({ originalIndex }) =>\n searchResultState.showAllResults || originalIndex === searchResultState.activeResultIndex,\n );\n\n return (\n <div\n style={{\n ...style,\n pointerEvents: 'none',\n }}\n {...props}\n >\n {resultsToShow.map(({ result, originalIndex }) =>\n result.rects.map((rect, rectIndex) => (\n <div\n key={`${originalIndex}-${rectIndex}`}\n style={{\n position: 'absolute',\n top: rect.origin.y * actualScale,\n left: rect.origin.x * actualScale,\n width: rect.size.width * actualScale,\n height: rect.size.height * actualScale,\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"],"names":["useSearchCapability","useCapability","SearchPlugin","id","documentId","pageIndex","scale","scaleOverride","style","highlightColor","activeHighlightColor","props","provides","searchProvides","searchResultState","setSearchResultState","useState","documentState","useDocumentState","scope","useMemo","forDocument","actualScale","useEffect","currentState","getState","results","activeResultIndex","showAllResults","active","onSearchResultStateChange","state","resultsToShow","map","result","originalIndex","filter","jsx","pointerEvents","children","rects","rect","rectIndex","position","top","origin","y","left","x","width","size","height","backgroundColor","mixBlendMode","transform","transformOrigin","transition","opacity","searchState","setSearchState","initialSearchDocumentState","onStateChange","usePlugin"],"mappings":"gPAUaA,EAAsB,IAAMC,gBAA4BC,EAAAA,aAAaC,wBCK3E,UAAqBC,WAC1BA,EAAAC,UACAA,EACAC,MAAOC,EAAAC,MACPA,EAAAC,eACAA,EAAiB,UAAAC,qBACjBA,EAAuB,aACpBC,IAEH,MAAQC,SAAUC,GAAmBb,KAC9Bc,EAAmBC,GAAwBC,EAAAA,SAAmC,MAC/EC,EAAgBC,EAAAA,iBAAiBd,GAEjCe,EAAQC,EAAAA,QACZ,UAAMP,WAAgBQ,YAAYjB,GAClC,CAACS,EAAgBT,IAGbkB,EAAcF,EAAAA,QAAQ,SACJ,IAAlBb,EAAoCA,SACjCU,WAAeX,QAAS,EAC9B,CAACC,EAAe,MAAAU,OAAA,EAAAA,EAAeX,QAqBlC,GAnBAiB,EAAAA,UAAU,KACR,IAAKJ,EAEH,YADAJ,EAAqB,MAIvB,MAAMS,EAAeL,EAAMM,WAQ3B,OAPAV,EAAqB,CACnBW,QAASF,EAAaE,QACtBC,kBAAmBH,EAAaG,kBAChCC,eAAgBJ,EAAaI,eAC7BC,OAAQL,EAAaK,SAGhBV,EAAMW,0BAA2BC,IACtChB,EAAqBgB,MAEtB,CAACZ,KAECL,IAAsBA,EAAkBe,OAC3C,OAAO,KAIT,MAKMG,EALclB,EAAkBY,QACnCO,IAAI,CAACC,EAAQC,MAAqBD,SAAQC,mBAC1CC,OAAO,EAAGF,YAAaA,EAAO7B,YAAcA,GAGb+B,OAChC,EAAGD,mBACDrB,EAAkBc,gBAAkBO,IAAkBrB,EAAkBa,mBAG5E,OACEU,EAAAA,IAAC,MAAA,CACC7B,MAAO,IACFA,EACH8B,cAAe,WAEb3B,EAEH4B,SAAAP,EAAcC,IAAI,EAAGC,SAAQC,mBAC5BD,EAAOM,MAAMP,IAAI,CAACQ,EAAMC,IACtBL,EAAAA,IAAC,MAAA,CAEC7B,MAAO,CACLmC,SAAU,WACVC,IAAKH,EAAKI,OAAOC,EAAIxB,EACrByB,KAAMN,EAAKI,OAAOG,EAAI1B,EACtB2B,MAAOR,EAAKS,KAAKD,MAAQ3B,EACzB6B,OAAQV,EAAKS,KAAKC,OAAS7B,EAC3B8B,gBACEjB,IAAkBrB,EAAkBa,kBAChCjB,EACAD,EACN4C,aAAc,WACdC,UAAW,cACXC,gBAAiB,SACjBC,WAAY,0BACZC,QAAS,IAfN,GAAGtB,KAAiBO,QAsBrC,oBD5FEtC,IAKA,MAAMQ,SAAEA,GAAaZ,KACd0D,EAAaC,GAAkB3C,EAAAA,SAA8B4C,EAAAA,4BAE9DzC,EAAQC,UAAQ,IAAM,MAAAR,OAAA,EAAAA,EAAUS,YAAYjB,GAAa,CAACQ,EAAUR,IAa1E,OAXAmB,EAAAA,UAAU,KACR,GAAKJ,EAOL,OAFAwC,EAAexC,EAAMM,YAEdN,EAAM0C,cAAe9B,GAAU4B,EAAe5B,IANnD4B,EAAeC,EAAAA,6BAOhB,CAACzC,IAEG,CACLY,MAAO2B,EACP9C,SAAUO,GAAS,6DA3BQ,IAAM2C,YAAwB5D,EAAAA,aAAaC"}