mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-09-11 21:39:01 +00:00
4e04148f13
* feat(web): localSearch MiniSearch store (TASK-1363)
Build the client-side full-text search foundation for Phase 3 of the
local-first read model: a per-workspace MiniSearch index that mirrors
`localIndex` and provides sub-millisecond ranked search over titles +
parsed fields. No UI changes — TASK-1364 wires the collection page and
TASK-1365 wires the global CommandPalette.
- New `web/src/lib/stores/localSearch.svelte.ts`: per-workspace
MiniSearch index keyed by workspace slug (module-level plain Map —
search results are derived on demand via `.search()`, not subscribed
to). Indexed fields with boosts: title (3x), ref (2x), item_number
(2x), tags, parent_ref, parent_title, collection_slug, and a
flattened `fields` blob so status / priority / assignee names land
as searchable terms. Custom tokenizer splits on whitespace + `-_./`
so `TASK-5` indexes as both `task` and `5`. Public API: `rebuild`,
`upsert`, `remove`, `reset`, `search(ws, q, opts?)`, `size`.
Returns `{ id, score }[]` ranked by descending score; callers
resolve to full rows via `localIndex` (O(1) Map lookup).
- `localIndex` mutation paths now mirror writes into the MiniSearch
index: `applyDelta`, `upsert`, `remove`, `removeByCollection`,
`reset` (and the 403-purge error path in `bootstrap`). The cold
`/items-index` snapshot and the warm IDB hydrate trigger a single
bulk `localSearch.rebuild(...)` instead of N per-row upserts —
measurably cheaper at workspace boot.
- SSR-safe: every entry point gates on `typeof window !== 'undefined'`
so SvelteKit prerender / SSR can't build a server-side index.
- Add `minisearch@7.2.0` (~10KB gz) as an exact-pinned dependency.
Parent: PLAN-1343 (DOC-1342 Phase 3a).
* fix(web): broaden localSearch tokenizer per Codex review (round 1)
Codex round 1 P2: the previous tokenizer only split on whitespace + a
narrow set of separators (`-_./`), so values like `foo:bar`,
`foo,bar`, and `foo(bar)` indexed as a single token. Searches for
`bar` or `foo bar` would miss valid matches.
Broaden to split on any non-letter/non-digit character (`/[^\p{L}\p{N}]+/u`).
This matches MiniSearch's default `SPACE_OR_PUNCTUATION` shape — catches
whitespace, dashes, dots, slashes, colons, commas, parens, brackets,
underscores, etc. — while preserving the `TASK-5` → ['task', '5']
behavior the original regex aimed for.
62 lines
1.8 KiB
JSON
62 lines
1.8 KiB
JSON
{
|
|
"name": "web",
|
|
"private": true,
|
|
"version": "0.0.1",
|
|
"license": "Apache-2.0",
|
|
"type": "module",
|
|
"scripts": {
|
|
"dev": "vite dev",
|
|
"build": "vite build",
|
|
"preview": "vite preview",
|
|
"prepare": "svelte-kit sync || echo ''",
|
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
"test:e2e": "playwright test",
|
|
"test:e2e:ui": "playwright test --ui",
|
|
"test:e2e:install": "playwright install --with-deps chromium"
|
|
},
|
|
"devDependencies": {
|
|
"@playwright/test": "^1.59.1",
|
|
"@sveltejs/adapter-auto": "^7.0.1",
|
|
"@sveltejs/adapter-static": "^3.0.10",
|
|
"@sveltejs/kit": "^2.59.1",
|
|
"@sveltejs/vite-plugin-svelte": "^7.1.2",
|
|
"@types/qrcode": "^1.5.6",
|
|
"marked": "^18.0.3",
|
|
"svelte": "^5.55.5",
|
|
"svelte-check": "^4.4.7",
|
|
"typescript": "^6.0.3",
|
|
"vite": "^8.0.11"
|
|
},
|
|
"overrides": {
|
|
"cookie": "^0.7.2"
|
|
},
|
|
"dependencies": {
|
|
"@tiptap/core": "^3.22.5",
|
|
"@tiptap/extension-bubble-menu": "^3.22.5",
|
|
"@tiptap/extension-code-block-lowlight": "^3.22.5",
|
|
"@tiptap/extension-collaboration": "3.22.5",
|
|
"@tiptap/extension-collaboration-caret": "3.22.5",
|
|
"@tiptap/extension-link": "^3.22.5",
|
|
"@tiptap/extension-placeholder": "^3.22.5",
|
|
"@tiptap/extension-table": "^3.22.5",
|
|
"@tiptap/extension-task-item": "^3.22.5",
|
|
"@tiptap/extension-task-list": "^3.22.5",
|
|
"@tiptap/pm": "^3.20.4",
|
|
"@tiptap/starter-kit": "^3.22.5",
|
|
"@tiptap/suggestion": "^3.22.5",
|
|
"@tiptap/y-tiptap": "^3.0.3",
|
|
"diff": "^9.0.0",
|
|
"dompurify": "^3.4.2",
|
|
"idb": "^8.0.3",
|
|
"lowlight": "^3.3.0",
|
|
"mermaid": "^11.14.0",
|
|
"minisearch": "7.2.0",
|
|
"qrcode": "^1.5.4",
|
|
"svelte-dnd-action": "^0.9.69",
|
|
"tiptap-markdown": "^0.9.0",
|
|
"y-protocols": "^1.0.7",
|
|
"yjs": "^13.6.30"
|
|
}
|
|
}
|