@keepkit/core 0.26.2 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -38,7 +38,7 @@ const list = useKeepList({
38
38
 
39
39
  保存対象の公開状態は`KeepItem.status`(`expired`、`removed`、`private`など)と`statusReason`で保持できます。`KeepProvider`の`validateItem` / `resolveItem`を指定すると、引数なしの`revalidateItems()`で検証できます。`revalidateItems`に`removeStatuses`を渡すと検出したアイテムを保存一覧から削除します。`SyncStorageAdapter`は`userId`、`tenantId`、`maxRetries`、`retryDelayMs`、`retryBackoff`に対応し、`retrySync()`で失敗後の同期を再開できます。
40
40
 
41
- v0.26.2では、UI層に一覧・管理・同期UIをまとめる`KeepWorkspace`と型付きの`keep.Workspace`を追加しました。Tailwind CSS v4統合とホストテーマ変数との衝突回避も引き続き利用できます。coreでは既存の保存順プレイリスト、`useKeepNavigator`、`reorderKeepItems` / `moveKeepItem`、URL状態codec、ユーザー/テナント分離、`createKeepKitPreset`、認証付き同期を引き続き利用できます。
41
+ v0.27.0では、`KeepCollection`の構成例を確認できる`apps/collection-demo`を追加しました。coreでは既存の保存順プレイリスト、`useKeepNavigator`、`reorderKeepItems` / `moveKeepItem`、URL状態codec、ユーザー/テナント分離、`createKeepKitPreset`、認証付き同期を引き続き利用できます。
42
42
 
43
43
  `createAuthenticatedSyncKit`は、リクエストごとの`getAuthToken`、注入可能なpush/pull transport、401/403時の再認証callback、永続オフラインキュー、`setScope`による安全なユーザー/テナント切替を提供します。詳細は[`examples/authenticated-sync`](../../examples/authenticated-sync/README.md)を参照してください。
44
44
 
@@ -83,7 +83,7 @@ Use `@keepkit/core/core` for framework-neutral code, `@keepkit/core/react` for R
83
83
 
84
84
  `KeepItem.status` and `statusReason` preserve source availability such as `expired`, `removed`, and `private`. Configure `KeepProvider` with `validateItem` / `resolveItem` to make `revalidateItems()` use those hooks by default. Pass `removeStatuses` to remove detected items from storage. `SyncStorageAdapter` supports scoped queues with `userId` and `tenantId`, configurable retries/backoff, and explicit `retrySync()` recovery.
85
85
 
86
- v0.26.2 adds `KeepWorkspace` and the typed `keep.Workspace` to the UI layer for composed collection, management, and sync interfaces. Tailwind CSS v4 integration and host-theme isolation remain available. Core continues to provide persisted playlist ordering with `useKeepNavigator`, `reorderKeepItems`, and `moveKeepItem`, URL state codecs, user/tenant isolation, `createKeepKitPreset({ mode: "local" | "sync" | "backup" })`, and token-aware authenticated sync.
86
+ v0.27.0 adds `apps/collection-demo` for exploring `KeepCollection` configurations. Core continues to provide persisted playlist ordering with `useKeepNavigator`, `reorderKeepItems`, and `moveKeepItem`, URL state codecs, user/tenant isolation, `createKeepKitPreset({ mode: "local" | "sync" | "backup" })`, and token-aware authenticated sync.
87
87
 
88
88
  `createAuthenticatedSyncKit` provides a per-request `getAuthToken`, injectable push/pull transport, 401/403 reauthentication callbacks, persistent offline queues, and `setScope` for safe user or tenant changes. See [`examples/authenticated-sync`](../../examples/authenticated-sync/README.md) for a recipe.
89
89
 
@@ -387,4 +387,4 @@ export {
387
387
  reconcileKeepItems,
388
388
  KeepStore
389
389
  };
390
- //# sourceMappingURL=chunk-CLDYMSOF.js.map
390
+ //# sourceMappingURL=chunk-O6FNZ5N2.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/features/items/navigation.ts","../src/features/persistence/migration.ts","../src/features/persistence/backup.ts","../src/features/items/query.ts","../src/features/items/revalidation.ts","../src/features/store/store.ts"],"sourcesContent":["import type { KeepItem } from \"./types\";\n\nexport type KeepNavigationState<TMeta = Record<string, unknown>> = {\n items: KeepItem<TMeta>[];\n currentIndex: number;\n currentPosition: number | null;\n currentItem: KeepItem<TMeta> | null;\n hasNext: boolean;\n hasPrev: boolean;\n nextItem: KeepItem<TMeta> | null;\n prevItem: KeepItem<TMeta> | null;\n};\n\n/** Return items in their persisted custom order, leaving legacy items stable. */\nexport function orderKeepItems<TMeta>(items: readonly KeepItem<TMeta>[]): KeepItem<TMeta>[] {\n if (!items.some((item) => item.order !== undefined)) return [...items];\n return items\n .map((item, index) => ({ item, index }))\n .sort((left, right) => {\n const leftOrder = left.item.order;\n const rightOrder = right.item.order;\n if (leftOrder === undefined && rightOrder !== undefined) return 1;\n if (leftOrder !== undefined && rightOrder === undefined) return -1;\n if (leftOrder !== undefined && rightOrder !== undefined && leftOrder !== rightOrder) {\n return leftOrder - rightOrder;\n }\n return left.index - right.index;\n })\n .map(({ item }) => item);\n}\n\n/** Derive the previous/current/next view for a list and an item id or index. */\nexport function getKeepNavigationState<TMeta = Record<string, unknown>>(\n source: readonly KeepItem<TMeta>[],\n current?: string | number,\n): KeepNavigationState<TMeta> {\n const items = orderKeepItems(source);\n const currentIndex =\n typeof current === \"number\"\n ? Number.isInteger(current) && current >= 0 && current < items.length\n ? current\n : -1\n : current === undefined\n ? -1\n : items.findIndex((item) => item.id === current);\n const currentItem = currentIndex >= 0 ? (items[currentIndex] ?? null) : null;\n return {\n items,\n currentIndex,\n currentPosition: currentIndex >= 0 ? currentIndex + 1 : null,\n currentItem,\n hasNext: currentIndex >= 0 && currentIndex < items.length - 1,\n hasPrev: currentIndex > 0,\n nextItem: currentIndex >= 0 ? (items[currentIndex + 1] ?? null) : null,\n prevItem: currentIndex > 0 ? (items[currentIndex - 1] ?? null) : null,\n };\n}\n\n/** Apply a partial or complete id order and assign stable zero-based positions. */\nexport function reorderKeepItems<TMeta = Record<string, unknown>>(\n source: readonly KeepItem<TMeta>[],\n orderedIds: readonly string[],\n): KeepItem<TMeta>[] {\n const byId = new Map(source.map((item) => [item.id, item]));\n const seen = new Set<string>();\n for (const id of orderedIds) {\n if (!byId.has(id)) throw new Error(`Cannot reorder unknown Keep item \"${id}\".`);\n if (seen.has(id)) throw new Error(`Cannot reorder Keep items with duplicate id \"${id}\".`);\n seen.add(id);\n }\n const current = orderKeepItems(source);\n const sequence = [...orderedIds, ...current.map((item) => item.id).filter((id) => !seen.has(id))];\n return sequence.map((id, order) => {\n const item = byId.get(id);\n if (!item) throw new Error(`Cannot reorder unknown Keep item \"${id}\".`);\n return { ...item, order };\n });\n}\n\n/** Move one item within the current custom/legacy order. */\nexport function moveKeepItem<TMeta = Record<string, unknown>>(\n source: readonly KeepItem<TMeta>[],\n id: string,\n targetIndex: number,\n): KeepItem<TMeta>[] {\n const items = orderKeepItems(source);\n const currentIndex = items.findIndex((item) => item.id === id);\n if (currentIndex < 0) throw new Error(`Cannot move unknown Keep item \"${id}\".`);\n if (!Number.isInteger(targetIndex)) throw new Error(\"Keep item targetIndex must be an integer.\");\n const nextIndex = Math.min(Math.max(0, targetIndex), items.length - 1);\n const [item] = items.splice(currentIndex, 1);\n items.splice(nextIndex, 0, item);\n return reorderKeepItems(\n items,\n items.map((entry) => entry.id),\n );\n}\n","import type { KeepItem, StorageAdapter } from \"../items/types\";\n\n/** Merge anonymous local items into a signed-in or remote adapter. */\nexport async function mergeKeepItems<TMeta>(\n localItems: KeepItem<TMeta>[],\n target: StorageAdapter<TMeta>,\n): Promise<KeepItem<TMeta>[]> {\n if (target.merge) return target.merge(localItems);\n\n const remoteItems = await target.getAll();\n const byId = new Map(remoteItems.map((item) => [item.id, item]));\n for (const localItem of localItems) {\n const remoteItem = byId.get(localItem.id);\n if (!remoteItem || localItem.updatedAt > remoteItem.updatedAt) {\n byId.set(localItem.id, localItem);\n }\n }\n\n const merged = [...byId.values()].sort((a, b) => b.updatedAt - a.updatedAt);\n await Promise.all(merged.map((item) => target.set(item)));\n return merged;\n}\n\n/** Read anonymous items, merge them into the target, then clear the source. */\nexport async function migrateKeepItems<TMeta>(\n source: StorageAdapter<TMeta>,\n target: StorageAdapter<TMeta>,\n): Promise<KeepItem<TMeta>[]> {\n const localItems = await source.getAll();\n const merged = await mergeKeepItems(localItems, target);\n await source.clear();\n return merged;\n}\n","import type { KeepInvalidItemPolicy, KeepItem, KeepSchema, StorageAdapter } from \"../items/types\";\nimport { mergeKeepItems } from \"./migration\";\nimport { validateKeepItem } from \"./schema\";\n\nexport const KEEP_BACKUP_FORMAT = \"keepkit\";\nexport const KEEP_BACKUP_VERSION = 1;\n\nexport type KeepBackup<TMeta = Record<string, unknown>> = {\n format: typeof KEEP_BACKUP_FORMAT;\n version: typeof KEEP_BACKUP_VERSION;\n exportedAt: number;\n items: KeepItem<TMeta>[];\n};\n\nexport type ImportItemsOptions<TMeta = unknown> = {\n mode?: \"replace\" | \"merge\";\n schema?: KeepSchema<TMeta>;\n invalidItemPolicy?: KeepInvalidItemPolicy;\n onInvalidItem?: (error: unknown, item: KeepItem<unknown>) => void;\n};\n\nexport type ImportItemsResult<TMeta = Record<string, unknown>> = {\n mode: \"replace\" | \"merge\";\n imported: number;\n failed: number;\n total: number;\n items: KeepItem<TMeta>[];\n};\n\nexport class KeepBackupParseError extends Error {\n readonly cause?: unknown;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message);\n this.name = \"KeepBackupParseError\";\n if (options?.cause !== undefined) this.cause = options.cause;\n }\n}\n\nexport class KeepBackupImportError extends Error {\n readonly mode: \"replace\" | \"merge\";\n readonly imported: number;\n readonly failed: number;\n readonly cause?: unknown;\n\n constructor(\n message: string,\n options: {\n mode: \"replace\" | \"merge\";\n imported: number;\n failed: number;\n cause?: unknown;\n },\n ) {\n super(message);\n this.name = \"KeepBackupImportError\";\n this.mode = options.mode;\n this.imported = options.imported;\n this.failed = options.failed;\n if (options.cause !== undefined) this.cause = options.cause;\n }\n}\n\n/** Serialize all adapter data into a versioned JSON backup. */\nexport async function exportItems<TMeta>(adapter: StorageAdapter<TMeta>): Promise<string> {\n const backup: KeepBackup<TMeta> = {\n format: KEEP_BACKUP_FORMAT,\n version: KEEP_BACKUP_VERSION,\n exportedAt: Date.now(),\n items: await adapter.getAll(),\n };\n return JSON.stringify(backup, null, 2);\n}\n\n/** Validate and restore a backup, either replacing or merging existing data. */\nexport async function importItems<TMeta>(\n adapter: StorageAdapter<TMeta>,\n data: string | KeepBackup<TMeta>,\n options: ImportItemsOptions<TMeta> = {},\n): Promise<ImportItemsResult<TMeta>> {\n const backup = parseBackup<TMeta>(data);\n const mode = options.mode ?? \"merge\";\n const validItems: KeepItem<TMeta>[] = [];\n let failed = 0;\n for (const item of backup.items) {\n if (!options.schema) {\n validItems.push(item);\n continue;\n }\n try {\n validItems.push(await validateKeepItem(item, options.schema));\n } catch (cause) {\n options.onInvalidItem?.(cause, item);\n if ((options.invalidItemPolicy ?? \"error\") === \"drop\") {\n failed += 1;\n continue;\n }\n throw cause;\n }\n }\n let items: KeepItem<TMeta>[];\n\n if (mode === \"merge\") {\n try {\n items = await mergeKeepItems(validItems, adapter);\n } catch (cause) {\n throw new KeepBackupImportError(\"KeepKit could not merge the backup.\", {\n mode,\n imported: 0,\n failed: validItems.length + failed,\n cause,\n });\n }\n } else {\n let imported = 0;\n try {\n await adapter.clear();\n for (const item of validItems) {\n await adapter.set(item);\n imported += 1;\n }\n items = await adapter.getAll();\n } catch (cause) {\n throw new KeepBackupImportError(\"KeepKit could not replace the stored items.\", {\n mode,\n imported,\n failed: validItems.length + failed - imported,\n cause,\n });\n }\n }\n\n return { mode, imported: validItems.length, failed, total: items.length, items };\n}\n\nfunction parseBackup<TMeta>(data: string | KeepBackup<TMeta>): KeepBackup<TMeta> {\n let value: unknown = data;\n if (typeof data === \"string\") {\n try {\n value = JSON.parse(data);\n } catch (cause) {\n throw new KeepBackupParseError(\"KeepKit backup is not valid JSON.\", { cause });\n }\n }\n\n if (!isRecord(value)) throw new KeepBackupParseError(\"KeepKit backup must be an object.\");\n if (value.format !== KEEP_BACKUP_FORMAT || value.version !== KEEP_BACKUP_VERSION) {\n throw new KeepBackupParseError(\"KeepKit backup format or version is unsupported.\");\n }\n if (typeof value.exportedAt !== \"number\" || !Number.isFinite(value.exportedAt)) {\n throw new KeepBackupParseError(\"KeepKit backup has an invalid export timestamp.\");\n }\n if (!Array.isArray(value.items) || !value.items.every(isKeepItem)) {\n throw new KeepBackupParseError(\"KeepKit backup contains invalid items.\");\n }\n return value as KeepBackup<TMeta>;\n}\n\nfunction isKeepItem(value: unknown): value is KeepItem {\n if (!isRecord(value)) return false;\n return (\n typeof value.id === \"string\" &&\n typeof value.savedAt === \"number\" &&\n Number.isFinite(value.savedAt) &&\n typeof value.updatedAt === \"number\" &&\n Number.isFinite(value.updatedAt) &&\n \"meta\" in value &&\n (value.order === undefined || (typeof value.order === \"number\" && Number.isFinite(value.order))) &&\n (value.archived === undefined || typeof value.archived === \"boolean\") &&\n (value.pinned === undefined || typeof value.pinned === \"boolean\") &&\n (value.collectionId === undefined || typeof value.collectionId === \"string\") &&\n (value.targetType === undefined || typeof value.targetType === \"string\") &&\n (value.note === undefined || typeof value.note === \"string\") &&\n (value.schemaVersion === undefined ||\n (typeof value.schemaVersion === \"number\" && Number.isFinite(value.schemaVersion))) &&\n (value.revision === undefined || typeof value.revision === \"string\") &&\n (value.metaUpdatedAt === undefined ||\n (typeof value.metaUpdatedAt === \"number\" && Number.isFinite(value.metaUpdatedAt))) &&\n (value.status === undefined ||\n value.status === \"available\" ||\n value.status === \"expired\" ||\n value.status === \"removed\" ||\n value.status === \"deleted\" ||\n value.status === \"private\" ||\n value.status === \"unknown\") &&\n (value.statusReason === undefined || typeof value.statusReason === \"string\") &&\n (value.scope === undefined || isSyncScope(value.scope)) &&\n (value.tags === undefined || (Array.isArray(value.tags) && value.tags.every((tag) => typeof tag === \"string\")))\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isSyncScope(value: unknown): boolean {\n return (\n isRecord(value) &&\n (value.userId === undefined || typeof value.userId === \"string\") &&\n (value.tenantId === undefined || typeof value.tenantId === \"string\")\n );\n}\n","import { orderKeepItems } from \"./navigation\";\nimport type { KeepItem } from \"./types\";\n\nexport type KeepListQuery<TMeta = Record<string, unknown>> = {\n targetType?: string;\n tags?: string[];\n /** Defaults to active (not archived) items; true selects archived items. */\n archived?: boolean;\n /** Optional explicit archive scope. When provided, this takes precedence over `archived`. */\n archiveScope?: \"active\" | \"archived\" | \"all\";\n collectionId?: string;\n pinnedFirst?: boolean;\n sort?: {\n by: \"savedAt\" | \"updatedAt\";\n direction?: \"asc\" | \"desc\";\n };\n search?: {\n query?: string;\n mode?: \"and\" | \"or\";\n tokenize?: boolean;\n fields?: Array<\"note\" | \"meta\" | \"tags\">;\n };\n pagination?: {\n page?: number;\n pageSize?: number;\n };\n filter?: (item: KeepItem<TMeta>) => boolean;\n savedBetween?: readonly [Date | number, Date | number];\n};\n\nexport type QueryKeepItemsResult<TMeta = Record<string, unknown>> = {\n items: KeepItem<TMeta>[];\n totalCount: number;\n tagCounts: Record<string, number>;\n page: number;\n pageCount: number;\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n};\n\n/** Apply the collection query and one-based pagination without React. */\nexport function queryKeepItems<TMeta = Record<string, unknown>>(\n source: KeepItem<TMeta>[],\n query: KeepListQuery<TMeta> = {},\n): QueryKeepItemsResult<TMeta> {\n const filtered = source.filter((item) => {\n const [from, to] = query.savedBetween ?? [];\n const savedAt = item.savedAt;\n const lowerBound = from === undefined ? undefined : toTimestamp(from);\n const upperBound = to === undefined ? undefined : toTimestamp(to);\n return (\n (query.targetType === undefined || item.targetType === query.targetType) &&\n (query.tags === undefined || query.tags.every((tag) => item.tags?.includes(tag))) &&\n matchesArchiveScope(item, query) &&\n (query.collectionId === undefined || item.collectionId === query.collectionId) &&\n (lowerBound === undefined || savedAt >= lowerBound) &&\n (upperBound === undefined || savedAt <= upperBound) &&\n matchesSearch(item, query.search) &&\n (query.filter?.(item) ?? true)\n );\n });\n const tagCounts = getTagCounts(filtered);\n const sortBy = query.sort?.by;\n const direction = query.sort?.direction === \"asc\" ? 1 : -1;\n const sortedBase = sortBy\n ? filtered\n .map((item, index) => ({ item, index }))\n .sort((a, b) => (a.item[sortBy] - b.item[sortBy]) * direction || a.index - b.index)\n .map(({ item }) => item)\n : orderKeepItems(filtered);\n const sorted = query.pinnedFirst\n ? [...sortedBase.filter((item) => item.pinned === true), ...sortedBase.filter((item) => item.pinned !== true)]\n : sortedBase;\n const pageSize = Math.max(1, query.pagination?.pageSize ?? (sorted.length || 1));\n const pageCount = Math.max(1, Math.ceil(sorted.length / pageSize));\n const page = Math.min(Math.max(1, query.pagination?.page ?? 1), pageCount);\n const offset = (page - 1) * pageSize;\n\n return {\n items: sorted.slice(offset, offset + pageSize),\n totalCount: sorted.length,\n tagCounts,\n page,\n pageCount,\n hasNextPage: page < pageCount,\n hasPreviousPage: page > 1,\n };\n}\n\nfunction matchesArchiveScope<TMeta>(item: KeepItem<TMeta>, query: KeepListQuery<TMeta>): boolean {\n if (query.archiveScope === \"all\") return true;\n if (query.archiveScope === \"archived\") return item.archived === true;\n if (query.archiveScope === \"active\") return item.archived !== true;\n return query.archived === true ? item.archived === true : item.archived !== true;\n}\n\nexport function getTagCounts<TMeta = Record<string, unknown>>(items: KeepItem<TMeta>[]): Record<string, number> {\n const counts: Record<string, number> = {};\n for (const item of items) {\n for (const tag of item.tags ?? []) counts[tag] = (counts[tag] ?? 0) + 1;\n }\n return Object.fromEntries(Object.entries(counts).sort(([a], [b]) => a.localeCompare(b)));\n}\n\nfunction matchesSearch<TMeta>(item: KeepItem<TMeta>, search?: KeepListQuery<TMeta>[\"search\"]): boolean {\n const query = search?.query;\n if (!query?.trim()) return true;\n const fields = search?.fields ?? [\"note\", \"meta\", \"tags\"];\n const values = fields.map((field) => {\n if (field === \"note\") return item.note ?? \"\";\n if (field === \"tags\") return (item.tags ?? []).join(\" \");\n try {\n return JSON.stringify(item.meta) ?? \"\";\n } catch {\n return String(item.meta);\n }\n });\n const text = values.join(\" \").toLocaleLowerCase();\n const normalized = query.trim().toLocaleLowerCase();\n const needles = search?.tokenize === false ? [normalized] : normalized.split(/\\s+/).filter(Boolean);\n const matches = needles.map((needle) => text.includes(needle));\n return search?.mode === \"or\" ? matches.some(Boolean) : matches.every(Boolean);\n}\n\nfunction toTimestamp(value: Date | number): number {\n return value instanceof Date ? value.getTime() : value;\n}\n","import type { KeepItem, KeepItemStatus, StorageAdapter } from \"./types\";\n\nexport type { KeepItemStatus } from \"./types\";\n\nexport type KeepItemRevalidationResult<TMeta = Record<string, unknown>> =\n | { status: \"available\"; meta?: TMeta }\n | { status: Exclude<KeepItemStatus, \"available\">; reason?: string };\n\nexport type KeepItemRevalidator<TMeta = Record<string, unknown>> = (\n item: KeepItem<TMeta>,\n) =>\n | KeepItemRevalidationResult<TMeta>\n | KeepItemRevalidationResult<TMeta>[\"status\"]\n | Promise<KeepItemRevalidationResult<TMeta> | KeepItemRevalidationResult<TMeta>[\"status\"]>;\n\nexport type KeepItemResolver<TMeta = Record<string, unknown>> = (\n item: KeepItem<TMeta>,\n result: KeepItemRevalidationResult<TMeta>,\n) => KeepItem<TMeta> | undefined | Promise<KeepItem<TMeta> | undefined>;\n\nexport type KeepItemMetadataRefresher<TMeta = Record<string, unknown>> = (\n item: KeepItem<TMeta>,\n) => TMeta | Promise<TMeta>;\n\n/** Return whether source metadata should be fetched again based on its age. */\nexport function isKeepItemMetadataStale<TMeta>(\n item: KeepItem<TMeta>,\n maxAgeMs: number,\n now: () => number = Date.now,\n): boolean {\n return item.metaUpdatedAt === undefined || now() - item.metaUpdatedAt >= maxAgeMs;\n}\n\nexport type KeepItemRevalidationRecord<TMeta = Record<string, unknown>> = {\n item: KeepItem<TMeta>;\n status: KeepItemStatus;\n reason?: string;\n updated: boolean;\n};\n\nexport type RevalidateKeepItemsOptions<TMeta = Record<string, unknown>> = {\n /** Statuses that should be removed after they are detected. Detection is the default. */\n removeStatuses?: Array<Exclude<KeepItemStatus, \"available\">>;\n now?: () => number;\n resolveItem?: KeepItemResolver<TMeta>;\n};\n\nexport type KeepAutoRevalidationOptions<TMeta = Record<string, unknown>> = {\n /** Revalidate after the provider hydrates. Defaults to true when validateItem is supplied. */\n onMount?: boolean;\n /** Revalidate when the browser returns online. Defaults to true. */\n onReconnect?: boolean;\n /** Revalidate repeatedly while mounted. Disabled by default. */\n intervalMs?: number;\n removeStatuses?: Array<Exclude<KeepItemStatus, \"available\">>;\n revalidator?: KeepItemRevalidator<TMeta>;\n};\n\nexport type KeepItemRevalidationSummary<TMeta = Record<string, unknown>> = {\n items: KeepItem<TMeta>[];\n checked: number;\n updated: number;\n removed: number;\n updatedItems: KeepItem<TMeta>[];\n removedIds: string[];\n results: KeepItemRevalidationRecord<TMeta>[];\n};\n\n/** Revalidate saved items without coupling the checker to a network client. */\nexport async function revalidateKeepItems<TMeta = Record<string, unknown>>(\n source: KeepItem<TMeta>[],\n revalidator: KeepItemRevalidator<TMeta>,\n options: RevalidateKeepItemsOptions<TMeta> = {},\n): Promise<KeepItemRevalidationSummary<TMeta>> {\n const removeStatuses = new Set(options.removeStatuses ?? []);\n const now = options.now ?? Date.now;\n const items: KeepItem<TMeta>[] = [];\n const updatedItems: KeepItem<TMeta>[] = [];\n const removedIds: string[] = [];\n const results: KeepItemRevalidationRecord<TMeta>[] = [];\n\n for (const item of source) {\n const rawResult = await revalidator(item);\n const result: KeepItemRevalidationResult<TMeta> = typeof rawResult === \"string\" ? { status: rawResult } : rawResult;\n const reason = result.status === \"available\" ? undefined : result.reason;\n const defaultResolved = {\n ...item,\n status: result.status,\n ...(result.status === \"available\" ? { statusReason: undefined } : { statusReason: reason }),\n };\n const resolved = options.resolveItem\n ? await (options.resolveItem as KeepItemResolver<TMeta>)(item, result)\n : defaultResolved;\n if (resolved === undefined) {\n removedIds.push(item.id);\n results.push({ item, status: result.status, reason, updated: false });\n continue;\n }\n if (result.status === \"available\") {\n const timestamp = now();\n const availableItem = clearItemStatus(resolved);\n const updated =\n result.meta === undefined\n ? availableItem\n : { ...availableItem, meta: result.meta, metaUpdatedAt: timestamp, updatedAt: timestamp };\n const didUpdate = updated !== item;\n items.push(updated);\n if (didUpdate) updatedItems.push(updated);\n results.push({ item: updated, status: \"available\", updated: didUpdate });\n continue;\n }\n\n const withStatus = { ...resolved, status: result.status, ...(reason ? { statusReason: reason } : {}) };\n const shouldRemove = removeStatuses.has(result.status);\n if (shouldRemove) removedIds.push(item.id);\n else items.push(withStatus);\n if (!shouldRemove && withStatus !== item) updatedItems.push(withStatus);\n results.push({ item: withStatus, status: result.status, reason, updated: !shouldRemove && withStatus !== item });\n }\n\n return {\n items,\n checked: source.length,\n updated: updatedItems.length,\n removed: removedIds.length,\n updatedItems,\n removedIds,\n results,\n };\n}\n\n/** Revalidate and persist saved items for framework-neutral applications. */\nexport async function reconcileKeepItems<TMeta = Record<string, unknown>>(\n storage: StorageAdapter<TMeta>,\n revalidator: KeepItemRevalidator<TMeta>,\n options: RevalidateKeepItemsOptions<TMeta> = {},\n): Promise<KeepItemRevalidationSummary<TMeta>> {\n const source = await storage.getAll();\n const summary = await revalidateKeepItems(source, revalidator, options);\n if (summary.updatedItems.length > 0) await persistItems(storage, summary.updatedItems);\n if (summary.removedIds.length > 0) await removeItems(storage, summary.removedIds);\n return summary;\n}\n\nasync function persistItems<TMeta>(storage: StorageAdapter<TMeta>, items: KeepItem<TMeta>[]): Promise<void> {\n if (storage.setMany) {\n await storage.setMany(items);\n return;\n }\n for (const item of items) await storage.set(item);\n}\n\nasync function removeItems<TMeta>(storage: StorageAdapter<TMeta>, ids: string[]): Promise<void> {\n if (storage.removeMany) {\n await storage.removeMany(ids);\n return;\n }\n for (const id of ids) await storage.remove(id);\n}\n\nfunction clearItemStatus<TMeta>(item: KeepItem<TMeta>): KeepItem<TMeta> {\n const next = { ...item };\n delete next.status;\n delete next.statusReason;\n return next;\n}\n","import type {\n KeepItemMetadataRefresher,\n KeepItemRevalidationSummary,\n KeepItemRevalidator,\n RevalidateKeepItemsOptions,\n} from \"../items/revalidation\";\nimport type { KeepChangeContext, KeepItem, KeepUndoState } from \"../items/types\";\n\nexport type KeepStoreState<TMeta = Record<string, unknown>> = {\n items: KeepItem<TMeta>[];\n isLoading: boolean;\n isHydrated: boolean;\n isMutating: boolean;\n error: unknown | null;\n lastChange?: KeepChangeContext<TMeta>;\n undo?: KeepUndoState;\n};\n\nexport type KeepStoreActions<TMeta = Record<string, unknown>> = {\n saveItem: (item: KeepItem<TMeta>) => Promise<void>;\n updateNote: (id: string, note?: string) => Promise<void>;\n updateTags: (id: string, tags?: string[]) => Promise<void>;\n toggleArchive: (id: string) => Promise<void>;\n archiveItem: (id: string) => Promise<void>;\n unarchiveItem: (id: string) => Promise<void>;\n togglePin: (id: string) => Promise<void>;\n moveToCollection: (id: string, collectionId?: string) => Promise<void>;\n updateTagsBatch: (ids: string[], tags?: string[]) => Promise<void>;\n addTagsBatch: (ids: string[], tags: string[]) => Promise<void>;\n removeTagsBatch: (ids: string[], tags: string[]) => Promise<void>;\n removeItem: (id: string) => Promise<void>;\n removeItems: (ids: string[]) => Promise<void>;\n removeItemWithUndo: (id: string) => Promise<void>;\n removeItemsWithUndo: (ids: string[]) => Promise<void>;\n undoLastRemoval: () => Promise<void>;\n clear: () => Promise<void>;\n refresh: () => Promise<void>;\n refreshItemMetadata: (id: string, refresh: KeepItemMetadataRefresher<TMeta>) => Promise<void>;\n revalidateItems: (\n revalidator: KeepItemRevalidator<TMeta>,\n options?: RevalidateKeepItemsOptions<TMeta>,\n ) => Promise<KeepItemRevalidationSummary<TMeta>>;\n reorderItems: (orderedIds: string[]) => Promise<void>;\n moveItem: (id: string, targetIndex: number) => Promise<void>;\n};\n\nexport class KeepStore<TMeta = Record<string, unknown>> {\n private state: KeepStoreState<TMeta>;\n private readonly listeners = new Set<() => void>();\n\n constructor(initialState: KeepStoreState<TMeta>) {\n this.state = initialState;\n }\n\n getSnapshot = (): KeepStoreState<TMeta> => this.state;\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n };\n\n setState(next: Partial<KeepStoreState<TMeta>>): void {\n let changed = false;\n for (const key of Object.keys(next) as Array<keyof KeepStoreState<TMeta>>) {\n if (!Object.is(this.state[key], next[key])) {\n changed = true;\n break;\n }\n }\n if (!changed) return;\n this.state = { ...this.state, ...next };\n for (const listener of this.listeners) listener();\n }\n}\n"],"mappings":"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","names":["item"]}
1
+ {"version":3,"sources":["../src/features/items/navigation.ts","../src/features/persistence/migration.ts","../src/features/persistence/backup.ts","../src/features/items/query.ts","../src/features/items/revalidation.ts","../src/features/store/store.ts"],"sourcesContent":["import type { KeepItem } from \"./types\";\n\nexport type KeepNavigationState<TMeta = Record<string, unknown>> = {\n items: KeepItem<TMeta>[];\n currentIndex: number;\n currentPosition: number | null;\n currentItem: KeepItem<TMeta> | null;\n hasNext: boolean;\n hasPrev: boolean;\n nextItem: KeepItem<TMeta> | null;\n prevItem: KeepItem<TMeta> | null;\n};\n\n/** Return items in their persisted custom order, leaving legacy items stable. */\nexport function orderKeepItems<TMeta>(items: readonly KeepItem<TMeta>[]): KeepItem<TMeta>[] {\n if (!items.some((item) => item.order !== undefined)) return [...items];\n return items\n .map((item, index) => ({ item, index }))\n .sort((left, right) => {\n const leftOrder = left.item.order;\n const rightOrder = right.item.order;\n if (leftOrder === undefined && rightOrder !== undefined) return 1;\n if (leftOrder !== undefined && rightOrder === undefined) return -1;\n if (leftOrder !== undefined && rightOrder !== undefined && leftOrder !== rightOrder) {\n return leftOrder - rightOrder;\n }\n return left.index - right.index;\n })\n .map(({ item }) => item);\n}\n\n/** Derive the previous/current/next view for a list and an item id or index. */\nexport function getKeepNavigationState<TMeta = Record<string, unknown>>(\n source: readonly KeepItem<TMeta>[],\n current?: string | number,\n): KeepNavigationState<TMeta> {\n const items = orderKeepItems(source);\n const currentIndex =\n typeof current === \"number\"\n ? Number.isInteger(current) && current >= 0 && current < items.length\n ? current\n : -1\n : current === undefined\n ? -1\n : items.findIndex((item) => item.id === current);\n const currentItem = currentIndex >= 0 ? (items[currentIndex] ?? null) : null;\n return {\n items,\n currentIndex,\n currentPosition: currentIndex >= 0 ? currentIndex + 1 : null,\n currentItem,\n hasNext: currentIndex >= 0 && currentIndex < items.length - 1,\n hasPrev: currentIndex > 0,\n nextItem: currentIndex >= 0 ? (items[currentIndex + 1] ?? null) : null,\n prevItem: currentIndex > 0 ? (items[currentIndex - 1] ?? null) : null,\n };\n}\n\n/** Apply a partial or complete id order and assign stable zero-based positions. */\nexport function reorderKeepItems<TMeta = Record<string, unknown>>(\n source: readonly KeepItem<TMeta>[],\n orderedIds: readonly string[],\n): KeepItem<TMeta>[] {\n const byId = new Map(source.map((item) => [item.id, item]));\n const seen = new Set<string>();\n for (const id of orderedIds) {\n if (!byId.has(id)) throw new Error(`Cannot reorder unknown Keep item \"${id}\".`);\n if (seen.has(id)) throw new Error(`Cannot reorder Keep items with duplicate id \"${id}\".`);\n seen.add(id);\n }\n const current = orderKeepItems(source);\n const sequence = [...orderedIds, ...current.map((item) => item.id).filter((id) => !seen.has(id))];\n return sequence.map((id, order) => {\n const item = byId.get(id);\n if (!item) throw new Error(`Cannot reorder unknown Keep item \"${id}\".`);\n return { ...item, order };\n });\n}\n\n/** Move one item within the current custom/legacy order. */\nexport function moveKeepItem<TMeta = Record<string, unknown>>(\n source: readonly KeepItem<TMeta>[],\n id: string,\n targetIndex: number,\n): KeepItem<TMeta>[] {\n const items = orderKeepItems(source);\n const currentIndex = items.findIndex((item) => item.id === id);\n if (currentIndex < 0) throw new Error(`Cannot move unknown Keep item \"${id}\".`);\n if (!Number.isInteger(targetIndex)) throw new Error(\"Keep item targetIndex must be an integer.\");\n const nextIndex = Math.min(Math.max(0, targetIndex), items.length - 1);\n const [item] = items.splice(currentIndex, 1);\n items.splice(nextIndex, 0, item);\n return reorderKeepItems(\n items,\n items.map((entry) => entry.id),\n );\n}\n","import type { KeepItem, StorageAdapter } from \"../items/types\";\n\n/** Merge anonymous local items into a signed-in or remote adapter. */\nexport async function mergeKeepItems<TMeta>(\n localItems: KeepItem<TMeta>[],\n target: StorageAdapter<TMeta>,\n): Promise<KeepItem<TMeta>[]> {\n if (target.merge) return target.merge(localItems);\n\n const remoteItems = await target.getAll();\n const byId = new Map(remoteItems.map((item) => [item.id, item]));\n for (const localItem of localItems) {\n const remoteItem = byId.get(localItem.id);\n if (!remoteItem || localItem.updatedAt > remoteItem.updatedAt) {\n byId.set(localItem.id, localItem);\n }\n }\n\n const merged = [...byId.values()].sort((a, b) => b.updatedAt - a.updatedAt);\n await Promise.all(merged.map((item) => target.set(item)));\n return merged;\n}\n\n/** Read anonymous items, merge them into the target, then clear the source. */\nexport async function migrateKeepItems<TMeta>(\n source: StorageAdapter<TMeta>,\n target: StorageAdapter<TMeta>,\n): Promise<KeepItem<TMeta>[]> {\n const localItems = await source.getAll();\n const merged = await mergeKeepItems(localItems, target);\n await source.clear();\n return merged;\n}\n","import type { KeepInvalidItemPolicy, KeepItem, KeepSchema, StorageAdapter } from \"../items/types\";\nimport { mergeKeepItems } from \"./migration\";\nimport { validateKeepItem } from \"./schema\";\n\nexport const KEEP_BACKUP_FORMAT = \"keepkit\";\nexport const KEEP_BACKUP_VERSION = 1;\n\nexport type KeepBackup<TMeta = Record<string, unknown>> = {\n format: typeof KEEP_BACKUP_FORMAT;\n version: typeof KEEP_BACKUP_VERSION;\n exportedAt: number;\n items: KeepItem<TMeta>[];\n};\n\nexport type ImportItemsOptions<TMeta = unknown> = {\n mode?: \"replace\" | \"merge\";\n schema?: KeepSchema<TMeta>;\n invalidItemPolicy?: KeepInvalidItemPolicy;\n onInvalidItem?: (error: unknown, item: KeepItem<unknown>) => void;\n};\n\nexport type ImportItemsResult<TMeta = Record<string, unknown>> = {\n mode: \"replace\" | \"merge\";\n imported: number;\n failed: number;\n total: number;\n items: KeepItem<TMeta>[];\n};\n\nexport class KeepBackupParseError extends Error {\n readonly cause?: unknown;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message);\n this.name = \"KeepBackupParseError\";\n if (options?.cause !== undefined) this.cause = options.cause;\n }\n}\n\nexport class KeepBackupImportError extends Error {\n readonly mode: \"replace\" | \"merge\";\n readonly imported: number;\n readonly failed: number;\n readonly cause?: unknown;\n\n constructor(\n message: string,\n options: {\n mode: \"replace\" | \"merge\";\n imported: number;\n failed: number;\n cause?: unknown;\n },\n ) {\n super(message);\n this.name = \"KeepBackupImportError\";\n this.mode = options.mode;\n this.imported = options.imported;\n this.failed = options.failed;\n if (options.cause !== undefined) this.cause = options.cause;\n }\n}\n\n/** Serialize all adapter data into a versioned JSON backup. */\nexport async function exportItems<TMeta>(adapter: StorageAdapter<TMeta>): Promise<string> {\n const backup: KeepBackup<TMeta> = {\n format: KEEP_BACKUP_FORMAT,\n version: KEEP_BACKUP_VERSION,\n exportedAt: Date.now(),\n items: await adapter.getAll(),\n };\n return JSON.stringify(backup, null, 2);\n}\n\n/** Validate and restore a backup, either replacing or merging existing data. */\nexport async function importItems<TMeta>(\n adapter: StorageAdapter<TMeta>,\n data: string | KeepBackup<TMeta>,\n options: ImportItemsOptions<TMeta> = {},\n): Promise<ImportItemsResult<TMeta>> {\n const backup = parseBackup<TMeta>(data);\n const mode = options.mode ?? \"merge\";\n const validItems: KeepItem<TMeta>[] = [];\n let failed = 0;\n for (const item of backup.items) {\n if (!options.schema) {\n validItems.push(item);\n continue;\n }\n try {\n validItems.push(await validateKeepItem(item, options.schema));\n } catch (cause) {\n options.onInvalidItem?.(cause, item);\n if ((options.invalidItemPolicy ?? \"error\") === \"drop\") {\n failed += 1;\n continue;\n }\n throw cause;\n }\n }\n let items: KeepItem<TMeta>[];\n\n if (mode === \"merge\") {\n try {\n items = await mergeKeepItems(validItems, adapter);\n } catch (cause) {\n throw new KeepBackupImportError(\"KeepKit could not merge the backup.\", {\n mode,\n imported: 0,\n failed: validItems.length + failed,\n cause,\n });\n }\n } else {\n let imported = 0;\n try {\n await adapter.clear();\n for (const item of validItems) {\n await adapter.set(item);\n imported += 1;\n }\n items = await adapter.getAll();\n } catch (cause) {\n throw new KeepBackupImportError(\"KeepKit could not replace the stored items.\", {\n mode,\n imported,\n failed: validItems.length + failed - imported,\n cause,\n });\n }\n }\n\n return { mode, imported: validItems.length, failed, total: items.length, items };\n}\n\nfunction parseBackup<TMeta>(data: string | KeepBackup<TMeta>): KeepBackup<TMeta> {\n let value: unknown = data;\n if (typeof data === \"string\") {\n try {\n value = JSON.parse(data);\n } catch (cause) {\n throw new KeepBackupParseError(\"KeepKit backup is not valid JSON.\", { cause });\n }\n }\n\n if (!isRecord(value)) throw new KeepBackupParseError(\"KeepKit backup must be an object.\");\n if (value.format !== KEEP_BACKUP_FORMAT || value.version !== KEEP_BACKUP_VERSION) {\n throw new KeepBackupParseError(\"KeepKit backup format or version is unsupported.\");\n }\n if (typeof value.exportedAt !== \"number\" || !Number.isFinite(value.exportedAt)) {\n throw new KeepBackupParseError(\"KeepKit backup has an invalid export timestamp.\");\n }\n if (!Array.isArray(value.items) || !value.items.every(isKeepItem)) {\n throw new KeepBackupParseError(\"KeepKit backup contains invalid items.\");\n }\n return value as KeepBackup<TMeta>;\n}\n\nfunction isKeepItem(value: unknown): value is KeepItem {\n if (!isRecord(value)) return false;\n return (\n typeof value.id === \"string\" &&\n typeof value.savedAt === \"number\" &&\n Number.isFinite(value.savedAt) &&\n typeof value.updatedAt === \"number\" &&\n Number.isFinite(value.updatedAt) &&\n \"meta\" in value &&\n (value.order === undefined || (typeof value.order === \"number\" && Number.isFinite(value.order))) &&\n (value.archived === undefined || typeof value.archived === \"boolean\") &&\n (value.pinned === undefined || typeof value.pinned === \"boolean\") &&\n (value.collectionId === undefined || typeof value.collectionId === \"string\") &&\n (value.targetType === undefined || typeof value.targetType === \"string\") &&\n (value.note === undefined || typeof value.note === \"string\") &&\n (value.schemaVersion === undefined ||\n (typeof value.schemaVersion === \"number\" && Number.isFinite(value.schemaVersion))) &&\n (value.revision === undefined || typeof value.revision === \"string\") &&\n (value.metaUpdatedAt === undefined ||\n (typeof value.metaUpdatedAt === \"number\" && Number.isFinite(value.metaUpdatedAt))) &&\n (value.status === undefined ||\n value.status === \"available\" ||\n value.status === \"expired\" ||\n value.status === \"removed\" ||\n value.status === \"deleted\" ||\n value.status === \"private\" ||\n value.status === \"unknown\") &&\n (value.statusReason === undefined || typeof value.statusReason === \"string\") &&\n (value.scope === undefined || isSyncScope(value.scope)) &&\n (value.tags === undefined || (Array.isArray(value.tags) && value.tags.every((tag) => typeof tag === \"string\")))\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isSyncScope(value: unknown): boolean {\n return (\n isRecord(value) &&\n (value.userId === undefined || typeof value.userId === \"string\") &&\n (value.tenantId === undefined || typeof value.tenantId === \"string\")\n );\n}\n","import { orderKeepItems } from \"./navigation\";\nimport type { KeepItem } from \"./types\";\n\nexport type KeepListQuery<TMeta = Record<string, unknown>> = {\n targetType?: string;\n tags?: string[];\n /** Defaults to active (not archived) items; true selects archived items. */\n archived?: boolean;\n /** Optional explicit archive scope. When provided, this takes precedence over `archived`. */\n archiveScope?: \"active\" | \"archived\" | \"all\";\n collectionId?: string;\n pinnedFirst?: boolean;\n sort?: {\n by: \"savedAt\" | \"updatedAt\";\n direction?: \"asc\" | \"desc\";\n };\n search?: {\n query?: string;\n mode?: \"and\" | \"or\";\n tokenize?: boolean;\n fields?: Array<\"note\" | \"meta\" | \"tags\">;\n };\n pagination?: {\n page?: number;\n pageSize?: number;\n };\n filter?: (item: KeepItem<TMeta>) => boolean;\n savedBetween?: readonly [Date | number, Date | number];\n};\n\nexport type QueryKeepItemsResult<TMeta = Record<string, unknown>> = {\n items: KeepItem<TMeta>[];\n totalCount: number;\n tagCounts: Record<string, number>;\n page: number;\n pageCount: number;\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n};\n\n/** Apply the collection query and one-based pagination without React. */\nexport function queryKeepItems<TMeta = Record<string, unknown>>(\n source: KeepItem<TMeta>[],\n query: KeepListQuery<TMeta> = {},\n): QueryKeepItemsResult<TMeta> {\n const filtered = source.filter((item) => {\n const [from, to] = query.savedBetween ?? [];\n const savedAt = item.savedAt;\n const lowerBound = from === undefined ? undefined : toTimestamp(from);\n const upperBound = to === undefined ? undefined : toTimestamp(to);\n return (\n (query.targetType === undefined || item.targetType === query.targetType) &&\n (query.tags === undefined || query.tags.every((tag) => item.tags?.includes(tag))) &&\n matchesArchiveScope(item, query) &&\n (query.collectionId === undefined || item.collectionId === query.collectionId) &&\n (lowerBound === undefined || savedAt >= lowerBound) &&\n (upperBound === undefined || savedAt <= upperBound) &&\n matchesSearch(item, query.search) &&\n (query.filter?.(item) ?? true)\n );\n });\n const tagCounts = getTagCounts(filtered);\n const sortBy = query.sort?.by;\n const direction = query.sort?.direction === \"asc\" ? 1 : -1;\n const sortedBase = sortBy\n ? filtered\n .map((item, index) => ({ item, index }))\n .sort((a, b) => (a.item[sortBy] - b.item[sortBy]) * direction || a.index - b.index)\n .map(({ item }) => item)\n : orderKeepItems(filtered);\n const sorted = query.pinnedFirst\n ? [...sortedBase.filter((item) => item.pinned === true), ...sortedBase.filter((item) => item.pinned !== true)]\n : sortedBase;\n const pageSize = Math.max(1, query.pagination?.pageSize ?? (sorted.length || 1));\n const pageCount = Math.max(1, Math.ceil(sorted.length / pageSize));\n const page = Math.min(Math.max(1, query.pagination?.page ?? 1), pageCount);\n const offset = (page - 1) * pageSize;\n\n return {\n items: sorted.slice(offset, offset + pageSize),\n totalCount: sorted.length,\n tagCounts,\n page,\n pageCount,\n hasNextPage: page < pageCount,\n hasPreviousPage: page > 1,\n };\n}\n\nfunction matchesArchiveScope<TMeta>(item: KeepItem<TMeta>, query: KeepListQuery<TMeta>): boolean {\n if (query.archiveScope === \"all\") return true;\n if (query.archiveScope === \"archived\") return item.archived === true;\n if (query.archiveScope === \"active\") return item.archived !== true;\n return query.archived === true ? item.archived === true : item.archived !== true;\n}\n\nexport function getTagCounts<TMeta = Record<string, unknown>>(items: KeepItem<TMeta>[]): Record<string, number> {\n const counts: Record<string, number> = {};\n for (const item of items) {\n for (const tag of item.tags ?? []) counts[tag] = (counts[tag] ?? 0) + 1;\n }\n return Object.fromEntries(Object.entries(counts).sort(([a], [b]) => a.localeCompare(b)));\n}\n\nfunction matchesSearch<TMeta>(item: KeepItem<TMeta>, search?: KeepListQuery<TMeta>[\"search\"]): boolean {\n const query = search?.query;\n if (!query?.trim()) return true;\n const fields = search?.fields ?? [\"note\", \"meta\", \"tags\"];\n const values = fields.map((field) => {\n if (field === \"note\") return item.note ?? \"\";\n if (field === \"tags\") return (item.tags ?? []).join(\" \");\n try {\n return JSON.stringify(item.meta) ?? \"\";\n } catch {\n return String(item.meta);\n }\n });\n const text = values.join(\" \").toLocaleLowerCase();\n const normalized = query.trim().toLocaleLowerCase();\n const needles = search?.tokenize === false ? [normalized] : normalized.split(/\\s+/).filter(Boolean);\n const matches = needles.map((needle) => text.includes(needle));\n return search?.mode === \"or\" ? matches.some(Boolean) : matches.every(Boolean);\n}\n\nfunction toTimestamp(value: Date | number): number {\n return value instanceof Date ? value.getTime() : value;\n}\n","import type { KeepItem, KeepItemStatus, StorageAdapter } from \"./types\";\n\nexport type { KeepItemStatus } from \"./types\";\n\nexport type KeepItemRevalidationResult<TMeta = Record<string, unknown>> =\n | { status: \"available\"; meta?: TMeta }\n | { status: Exclude<KeepItemStatus, \"available\">; reason?: string };\n\nexport type KeepItemRevalidator<TMeta = Record<string, unknown>> = (\n item: KeepItem<TMeta>,\n) =>\n | KeepItemRevalidationResult<TMeta>\n | KeepItemRevalidationResult<TMeta>[\"status\"]\n | Promise<KeepItemRevalidationResult<TMeta> | KeepItemRevalidationResult<TMeta>[\"status\"]>;\n\nexport type KeepItemResolver<TMeta = Record<string, unknown>> = (\n item: KeepItem<TMeta>,\n result: KeepItemRevalidationResult<TMeta>,\n) => KeepItem<TMeta> | undefined | Promise<KeepItem<TMeta> | undefined>;\n\nexport type KeepItemMetadataRefresher<TMeta = Record<string, unknown>> = (\n item: KeepItem<TMeta>,\n) => TMeta | Promise<TMeta>;\n\n/** Return whether source metadata should be fetched again based on its age. */\nexport function isKeepItemMetadataStale<TMeta>(\n item: KeepItem<TMeta>,\n maxAgeMs: number,\n now: () => number = Date.now,\n): boolean {\n return item.metaUpdatedAt === undefined || now() - item.metaUpdatedAt >= maxAgeMs;\n}\n\nexport type KeepItemRevalidationRecord<TMeta = Record<string, unknown>> = {\n item: KeepItem<TMeta>;\n status: KeepItemStatus;\n reason?: string;\n updated: boolean;\n};\n\nexport type RevalidateKeepItemsOptions<TMeta = Record<string, unknown>> = {\n /** Statuses that should be removed after they are detected. Detection is the default. */\n removeStatuses?: Array<Exclude<KeepItemStatus, \"available\">>;\n now?: () => number;\n resolveItem?: KeepItemResolver<TMeta>;\n};\n\nexport type KeepAutoRevalidationOptions<TMeta = Record<string, unknown>> = {\n /** Revalidate after the provider hydrates. Defaults to true when validateItem is supplied. */\n onMount?: boolean;\n /** Revalidate when the browser returns online. Defaults to true. */\n onReconnect?: boolean;\n /** Revalidate repeatedly while mounted. Disabled by default. */\n intervalMs?: number;\n removeStatuses?: Array<Exclude<KeepItemStatus, \"available\">>;\n revalidator?: KeepItemRevalidator<TMeta>;\n};\n\nexport type KeepItemRevalidationSummary<TMeta = Record<string, unknown>> = {\n items: KeepItem<TMeta>[];\n checked: number;\n updated: number;\n removed: number;\n updatedItems: KeepItem<TMeta>[];\n removedIds: string[];\n results: KeepItemRevalidationRecord<TMeta>[];\n};\n\n/** Revalidate saved items without coupling the checker to a network client. */\nexport async function revalidateKeepItems<TMeta = Record<string, unknown>>(\n source: KeepItem<TMeta>[],\n revalidator: KeepItemRevalidator<TMeta>,\n options: RevalidateKeepItemsOptions<TMeta> = {},\n): Promise<KeepItemRevalidationSummary<TMeta>> {\n const removeStatuses = new Set(options.removeStatuses ?? []);\n const now = options.now ?? Date.now;\n const items: KeepItem<TMeta>[] = [];\n const updatedItems: KeepItem<TMeta>[] = [];\n const removedIds: string[] = [];\n const results: KeepItemRevalidationRecord<TMeta>[] = [];\n\n for (const item of source) {\n const rawResult = await revalidator(item);\n const result: KeepItemRevalidationResult<TMeta> = typeof rawResult === \"string\" ? { status: rawResult } : rawResult;\n const reason = result.status === \"available\" ? undefined : result.reason;\n const defaultResolved = {\n ...item,\n status: result.status,\n ...(result.status === \"available\" ? { statusReason: undefined } : { statusReason: reason }),\n };\n const resolved = options.resolveItem\n ? await (options.resolveItem as KeepItemResolver<TMeta>)(item, result)\n : defaultResolved;\n if (resolved === undefined) {\n removedIds.push(item.id);\n results.push({ item, status: result.status, reason, updated: false });\n continue;\n }\n if (result.status === \"available\") {\n const timestamp = now();\n const availableItem = clearItemStatus(resolved);\n const updated =\n result.meta === undefined\n ? availableItem\n : { ...availableItem, meta: result.meta, metaUpdatedAt: timestamp, updatedAt: timestamp };\n const didUpdate = updated !== item;\n items.push(updated);\n if (didUpdate) updatedItems.push(updated);\n results.push({ item: updated, status: \"available\", updated: didUpdate });\n continue;\n }\n\n const withStatus = { ...resolved, status: result.status, ...(reason ? { statusReason: reason } : {}) };\n const shouldRemove = removeStatuses.has(result.status);\n if (shouldRemove) removedIds.push(item.id);\n else items.push(withStatus);\n if (!shouldRemove && withStatus !== item) updatedItems.push(withStatus);\n results.push({ item: withStatus, status: result.status, reason, updated: !shouldRemove && withStatus !== item });\n }\n\n return {\n items,\n checked: source.length,\n updated: updatedItems.length,\n removed: removedIds.length,\n updatedItems,\n removedIds,\n results,\n };\n}\n\n/** Revalidate and persist saved items for framework-neutral applications. */\nexport async function reconcileKeepItems<TMeta = Record<string, unknown>>(\n storage: StorageAdapter<TMeta>,\n revalidator: KeepItemRevalidator<TMeta>,\n options: RevalidateKeepItemsOptions<TMeta> = {},\n): Promise<KeepItemRevalidationSummary<TMeta>> {\n const source = await storage.getAll();\n const summary = await revalidateKeepItems(source, revalidator, options);\n if (summary.updatedItems.length > 0) await persistItems(storage, summary.updatedItems);\n if (summary.removedIds.length > 0) await removeItems(storage, summary.removedIds);\n return summary;\n}\n\nasync function persistItems<TMeta>(storage: StorageAdapter<TMeta>, items: KeepItem<TMeta>[]): Promise<void> {\n if (storage.setMany) {\n await storage.setMany(items);\n return;\n }\n for (const item of items) await storage.set(item);\n}\n\nasync function removeItems<TMeta>(storage: StorageAdapter<TMeta>, ids: string[]): Promise<void> {\n if (storage.removeMany) {\n await storage.removeMany(ids);\n return;\n }\n for (const id of ids) await storage.remove(id);\n}\n\nfunction clearItemStatus<TMeta>(item: KeepItem<TMeta>): KeepItem<TMeta> {\n const next = { ...item };\n delete next.status;\n delete next.statusReason;\n return next;\n}\n","import type {\n KeepItemMetadataRefresher,\n KeepItemRevalidationSummary,\n KeepItemRevalidator,\n RevalidateKeepItemsOptions,\n} from \"../items/revalidation\";\nimport type { KeepChangeContext, KeepItem, KeepUndoState } from \"../items/types\";\n\nexport type KeepCollectionMeta = { name: string };\n\nexport type KeepStoreState<TMeta = Record<string, unknown>> = {\n items: KeepItem<TMeta>[];\n collections: Record<string, KeepCollectionMeta>;\n isLoading: boolean;\n isHydrated: boolean;\n isMutating: boolean;\n error: unknown | null;\n lastChange?: KeepChangeContext<TMeta>;\n undo?: KeepUndoState;\n};\n\nexport type KeepStoreActions<TMeta = Record<string, unknown>> = {\n saveItem: (item: KeepItem<TMeta>) => Promise<void>;\n updateNote: (id: string, note?: string) => Promise<void>;\n updateTags: (id: string, tags?: string[]) => Promise<void>;\n toggleArchive: (id: string) => Promise<void>;\n archiveItem: (id: string) => Promise<void>;\n unarchiveItem: (id: string) => Promise<void>;\n togglePin: (id: string) => Promise<void>;\n moveToCollection: (id: string, collectionId?: string) => Promise<void>;\n createCollection: (id: string, name: string) => Promise<void>;\n renameCollection: (id: string, name: string) => Promise<void>;\n removeCollection: (id: string) => Promise<void>;\n updateTagsBatch: (ids: string[], tags?: string[]) => Promise<void>;\n addTagsBatch: (ids: string[], tags: string[]) => Promise<void>;\n removeTagsBatch: (ids: string[], tags: string[]) => Promise<void>;\n removeItem: (id: string) => Promise<void>;\n removeItems: (ids: string[]) => Promise<void>;\n removeItemWithUndo: (id: string) => Promise<void>;\n removeItemsWithUndo: (ids: string[]) => Promise<void>;\n undoLastRemoval: () => Promise<void>;\n clear: () => Promise<void>;\n refresh: () => Promise<void>;\n refreshItemMetadata: (id: string, refresh: KeepItemMetadataRefresher<TMeta>) => Promise<void>;\n revalidateItems: (\n revalidator: KeepItemRevalidator<TMeta>,\n options?: RevalidateKeepItemsOptions<TMeta>,\n ) => Promise<KeepItemRevalidationSummary<TMeta>>;\n reorderItems: (orderedIds: string[]) => Promise<void>;\n moveItem: (id: string, targetIndex: number) => Promise<void>;\n};\n\nexport class KeepStore<TMeta = Record<string, unknown>> {\n private state: KeepStoreState<TMeta>;\n private readonly listeners = new Set<() => void>();\n\n constructor(initialState: KeepStoreState<TMeta>) {\n this.state = initialState;\n }\n\n getSnapshot = (): KeepStoreState<TMeta> => this.state;\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n };\n\n setState(next: Partial<KeepStoreState<TMeta>>): void {\n let changed = false;\n for (const key of Object.keys(next) as Array<keyof KeepStoreState<TMeta>>) {\n if (!Object.is(this.state[key], next[key])) {\n changed = true;\n break;\n }\n }\n if (!changed) return;\n this.state = { ...this.state, ...next };\n for (const listener of this.listeners) listener();\n }\n}\n"],"mappings":"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","names":["item"]}
package/dist/core.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { D as DEFAULT_KEEP_URL_PARAMS, I as ImportItemsOptions, a as ImportItemsResult, K as KEEP_BACKUP_FORMAT, b as KEEP_BACKUP_VERSION, c as KeepAutoRevalidationOptions, d as KeepBackup, e as KeepBackupImportError, f as KeepBackupParseError, g as KeepItemMetadataRefresher, h as KeepItemResolver, i as KeepItemRevalidationRecord, j as KeepItemRevalidationResult, k as KeepItemRevalidationSummary, l as KeepItemRevalidator, m as KeepListQuery, n as KeepNavigationState, o as KeepStore, p as KeepStoreActions, q as KeepStoreState, r as KeepUrlParamNames, s as KeepUrlState, t as KeepUrlSyncOptions, Q as QueryKeepItemsResult, R as RevalidateKeepItemsOptions, u as decodeKeepListQuery, v as encodeKeepListQuery, w as exportItems, x as getKeepNavigationState, y as getTagCounts, z as importItems, A as isKeepItemMetadataStale, B as mergeKeepListQueryFromUrl, C as moveKeepItem, E as orderKeepItems, F as queryKeepItems, G as reconcileKeepItems, H as reorderKeepItems, J as revalidateKeepItems, L as serializeKeepListQuery } from './store-DN1HyI8k.js';
1
+ export { D as DEFAULT_KEEP_URL_PARAMS, I as ImportItemsOptions, a as ImportItemsResult, K as KEEP_BACKUP_FORMAT, b as KEEP_BACKUP_VERSION, c as KeepAutoRevalidationOptions, d as KeepBackup, e as KeepBackupImportError, f as KeepBackupParseError, g as KeepCollectionMeta, h as KeepItemMetadataRefresher, i as KeepItemResolver, j as KeepItemRevalidationRecord, k as KeepItemRevalidationResult, l as KeepItemRevalidationSummary, m as KeepItemRevalidator, n as KeepListQuery, o as KeepNavigationState, p as KeepStore, q as KeepStoreActions, r as KeepStoreState, s as KeepUrlParamNames, t as KeepUrlState, u as KeepUrlSyncOptions, Q as QueryKeepItemsResult, R as RevalidateKeepItemsOptions, v as decodeKeepListQuery, w as encodeKeepListQuery, x as exportItems, y as getKeepNavigationState, z as getTagCounts, A as importItems, B as isKeepItemMetadataStale, C as mergeKeepListQueryFromUrl, E as moveKeepItem, F as orderKeepItems, G as queryKeepItems, H as reconcileKeepItems, J as reorderKeepItems, L as revalidateKeepItems, M as serializeKeepListQuery } from './store-pfMOz7sn.js';
2
2
  import { K as KeepScope } from './scope-kVcPskvM.js';
3
3
  export { S as ScopedStorageAdapter, a as ScopedSyncQueueAdapter, c as createScopedStorageAdapter, g as getKeepScopeKey, i as isSameKeepScope } from './scope-kVcPskvM.js';
4
4
  import { R as RemoteSyncDriver, a as StorageAdapter, K as KeepItem, d as KeepPluginContext, e as KeepPlugin, c as SyncOperation, S as SyncScope, f as SyncCapableStorageAdapter, g as RemoteSyncResult, h as KeepSyncAuthError } from './types-6ex9EBjM.js';
package/dist/core.js CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  reconcileKeepItems,
18
18
  reorderKeepItems,
19
19
  revalidateKeepItems
20
- } from "./chunk-CLDYMSOF.js";
20
+ } from "./chunk-O6FNZ5N2.js";
21
21
  import {
22
22
  KeepSchemaValidationError,
23
23
  parseKeepMeta,
package/dist/react.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { g as KeepItemMetadataRefresher, l as KeepItemRevalidator, h as KeepItemResolver, c as KeepAutoRevalidationOptions, R as RevalidateKeepItemsOptions, k as KeepItemRevalidationSummary, I as ImportItemsOptions, a as ImportItemsResult, o as KeepStore, p as KeepStoreActions, m as KeepListQuery, n as KeepNavigationState } from './store-DN1HyI8k.js';
2
- export { j as KeepItemRevalidationResult, r as KeepUrlParamNames, s as KeepUrlState, t as KeepUrlSyncOptions, A as isKeepItemMetadataStale } from './store-DN1HyI8k.js';
1
+ import { h as KeepItemMetadataRefresher, m as KeepItemRevalidator, i as KeepItemResolver, c as KeepAutoRevalidationOptions, g as KeepCollectionMeta, R as RevalidateKeepItemsOptions, l as KeepItemRevalidationSummary, I as ImportItemsOptions, a as ImportItemsResult, p as KeepStore, q as KeepStoreActions, n as KeepListQuery, o as KeepNavigationState } from './store-pfMOz7sn.js';
2
+ export { k as KeepItemRevalidationResult, s as KeepUrlParamNames, t as KeepUrlState, u as KeepUrlSyncOptions, B as isKeepItemMetadataStale } from './store-pfMOz7sn.js';
3
3
  import { r as KeepItemInput, K as KeepItem, p as KeepEventHandlers, a as StorageAdapter, e as KeepPlugin, t as KeepSchema, q as KeepInvalidItemPolicy, j as KeepChangeContext, D as KeepSyncState, F as KeepUndoState } from './types-6ex9EBjM.js';
4
4
  export { s as KeepItemStatus } from './types-6ex9EBjM.js';
5
5
  export { K as KeepScope, S as ScopedStorageAdapter } from './scope-kVcPskvM.js';
@@ -90,6 +90,7 @@ declare class KeepErrorBoundary extends Component<KeepErrorBoundaryProps, KeepEr
90
90
 
91
91
  type KeepContextValue<TMeta = Record<string, unknown>> = {
92
92
  items: KeepItem<TMeta>[];
93
+ collections: Record<string, KeepCollectionMeta>;
93
94
  isLoading: boolean;
94
95
  isHydrated: boolean;
95
96
  isMutating: boolean;
@@ -105,6 +106,9 @@ type KeepContextValue<TMeta = Record<string, unknown>> = {
105
106
  unarchiveItem: (id: string) => Promise<void>;
106
107
  togglePin: (id: string) => Promise<void>;
107
108
  moveToCollection: (id: string, collectionId?: string) => Promise<void>;
109
+ createCollection: (id: string, name: string) => Promise<void>;
110
+ renameCollection: (id: string, name: string) => Promise<void>;
111
+ removeCollection: (id: string) => Promise<void>;
108
112
  updateTagsBatch: (ids: string[], tags?: string[]) => Promise<void>;
109
113
  addTagsBatch: (ids: string[], tags: string[]) => Promise<void>;
110
114
  removeTagsBatch: (ids: string[], tags: string[]) => Promise<void>;
@@ -165,7 +169,7 @@ type UseKeepCollectionsOptions = {
165
169
  orderBy?: "name" | "count";
166
170
  };
167
171
  type UseKeepCollectionsResult = KeepCollectionSummary[];
168
- /** Derive de-duplicated collection choices from the provider's complete saved-item snapshot. */
172
+ /** Derive de-duplicated collection choices from the provider's saved items and explicit collections. */
169
173
  declare function useKeepCollections<TMeta = Record<string, unknown>>(options?: UseKeepCollectionsOptions): UseKeepCollectionsResult;
170
174
 
171
175
  type UseKeepListResult<TMeta = Record<string, unknown>> = {
package/dist/react.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  queryKeepItems,
11
11
  reorderKeepItems,
12
12
  revalidateKeepItems
13
- } from "./chunk-CLDYMSOF.js";
13
+ } from "./chunk-O6FNZ5N2.js";
14
14
  import {
15
15
  parseKeepMeta
16
16
  } from "./chunk-5W4QSJHV.js";
@@ -150,6 +150,7 @@ function KeepProviderContent({
150
150
  if (!storeRef.current) {
151
151
  storeRef.current = new KeepStore({
152
152
  items: initialItems ? [...initialItems] : [],
153
+ collections: {},
153
154
  isLoading: true,
154
155
  isHydrated: false,
155
156
  isMutating: false,
@@ -160,7 +161,7 @@ function KeepProviderContent({
160
161
  }
161
162
  const store = storeRef.current;
162
163
  const state = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
163
- const { items, isLoading, isHydrated, isMutating, error, lastChange, undo: storedUndo } = state;
164
+ const { items, collections, isLoading, isHydrated, isMutating, error, lastChange, undo: storedUndo } = state;
164
165
  const undo = storedUndo ?? EMPTY_UNDO_STATE;
165
166
  const itemsRef = useRef(items);
166
167
  const pluginsRef = useRef(plugins);
@@ -507,6 +508,48 @@ function KeepProviderContent({
507
508
  },
508
509
  [runMutation, storage]
509
510
  );
511
+ const createCollection = useCallback(
512
+ async (id, name) => {
513
+ const trimmedId = id.trim();
514
+ const trimmedName = name.trim();
515
+ if (!trimmedId || !trimmedName) throw new Error("Collection id and name are required.");
516
+ const current = store.getSnapshot().collections;
517
+ if (current[trimmedId]) throw new Error(`Collection "${trimmedId}" already exists.`);
518
+ store.setState({ collections: { ...current, [trimmedId]: { name: trimmedName } } });
519
+ },
520
+ [store]
521
+ );
522
+ const renameCollection = useCallback(
523
+ async (id, name) => {
524
+ const trimmedName = name.trim();
525
+ if (!trimmedName) throw new Error("Collection name is required.");
526
+ const current = store.getSnapshot().collections;
527
+ if (!current[id]) throw new Error(`Collection "${id}" does not exist.`);
528
+ store.setState({ collections: { ...current, [id]: { name: trimmedName } } });
529
+ },
530
+ [store]
531
+ );
532
+ const removeCollection = useCallback(
533
+ async (id) => {
534
+ const current = store.getSnapshot().collections;
535
+ if (!current[id]) throw new Error(`Collection "${id}" does not exist.`);
536
+ const { [id]: _removed, ...remaining } = current;
537
+ store.setState({ collections: remaining });
538
+ const affected = itemsRef.current.filter((item) => item.collectionId === id);
539
+ if (affected.length > 0) {
540
+ const nextItems = itemsRef.current.map(
541
+ (item) => item.collectionId === id ? { ...item, collectionId: void 0, updatedAt: Date.now() } : item
542
+ );
543
+ itemsRef.current = nextItems;
544
+ store.setState({ items: nextItems });
545
+ for (const item of affected) {
546
+ const { collectionId: _, ...withoutCollection } = item;
547
+ await storage.set({ ...withoutCollection, collectionId: void 0, updatedAt: Date.now() });
548
+ }
549
+ }
550
+ },
551
+ [storage, store]
552
+ );
510
553
  const updateTagsBatch = useCallback(
511
554
  async (ids, tags) => {
512
555
  const idSet = new Set(ids);
@@ -837,6 +880,7 @@ function KeepProviderContent({
837
880
  const value = useMemo(
838
881
  () => ({
839
882
  items,
883
+ collections,
840
884
  isLoading,
841
885
  isHydrated,
842
886
  isMutating,
@@ -852,6 +896,9 @@ function KeepProviderContent({
852
896
  unarchiveItem,
853
897
  togglePin,
854
898
  moveToCollection,
899
+ createCollection,
900
+ renameCollection,
901
+ removeCollection,
855
902
  updateTagsBatch,
856
903
  addTagsBatch,
857
904
  removeTagsBatch,
@@ -873,6 +920,7 @@ function KeepProviderContent({
873
920
  }),
874
921
  [
875
922
  clear,
923
+ collections,
876
924
  error,
877
925
  lastChange,
878
926
  flushSync,
@@ -896,6 +944,9 @@ function KeepProviderContent({
896
944
  unarchiveItem,
897
945
  togglePin,
898
946
  moveToCollection,
947
+ createCollection,
948
+ renameCollection,
949
+ removeCollection,
899
950
  updateTagsBatch,
900
951
  addTagsBatch,
901
952
  removeTagsBatch,
@@ -918,6 +969,9 @@ function KeepProviderContent({
918
969
  unarchiveItem,
919
970
  togglePin,
920
971
  moveToCollection,
972
+ createCollection,
973
+ renameCollection,
974
+ removeCollection,
921
975
  updateTagsBatch,
922
976
  addTagsBatch,
923
977
  removeTagsBatch,
@@ -936,10 +990,13 @@ function KeepProviderContent({
936
990
  [
937
991
  addTagsBatch,
938
992
  clear,
993
+ createCollection,
939
994
  refresh,
995
+ removeCollection,
940
996
  removeItem,
941
997
  removeItems,
942
998
  removeTagsBatch,
999
+ renameCollection,
943
1000
  saveItem,
944
1001
  updateNote,
945
1002
  updateTags,
@@ -1196,10 +1253,13 @@ function getMetaTitle(meta) {
1196
1253
  // src/react/hooks/useKeepCollections.ts
1197
1254
  import { useMemo as useMemo2 } from "react";
1198
1255
  function useKeepCollections(options = {}) {
1199
- const { items } = useKeepContext();
1256
+ const { items, collections: explicitCollections } = useKeepContext();
1200
1257
  const { orderBy = "name", targetType } = options;
1201
1258
  return useMemo2(() => {
1202
1259
  const collections = /* @__PURE__ */ new Map();
1260
+ for (const [id, meta] of Object.entries(explicitCollections ?? {})) {
1261
+ collections.set(id, { id, name: meta.name, count: 0 });
1262
+ }
1203
1263
  for (const item of items) {
1204
1264
  if (targetType !== void 0 && item.targetType !== targetType) continue;
1205
1265
  const collection = getCollection(item);
@@ -1215,7 +1275,7 @@ function useKeepCollections(options = {}) {
1215
1275
  if (orderBy === "count" && left.count !== right.count) return right.count - left.count;
1216
1276
  return left.name.localeCompare(right.name) || left.id.localeCompare(right.id);
1217
1277
  });
1218
- }, [items, orderBy, targetType]);
1278
+ }, [items, explicitCollections, orderBy, targetType]);
1219
1279
  }
1220
1280
  function getCollection(item) {
1221
1281
  const id = item.collectionId?.trim();
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react/components/KeepButton.tsx","../src/react/hooks/useKeepItem.ts","../src/react/components/KeepProvider.tsx","../src/react/components/KeepErrorBoundary.tsx","../src/react/hooks/useKeepStoreSelector.ts","../src/react/hooks/useKeepCollections.ts","../src/react/hooks/useKeepList.ts","../src/react/hooks/useKeepNavigator.ts","../src/react/hooks/useKeepShortcut.ts","../src/react/createKeepKit.tsx"],"sourcesContent":["import {\n type ButtonHTMLAttributes,\n Children,\n cloneElement,\n type HTMLAttributes,\n isValidElement,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n type RefCallback,\n} from \"react\";\nimport type { KeepItemInput } from \"../../features/items/types\";\nimport { useKeepItem } from \"../hooks/useKeepItem\";\n\nexport type KeepButtonItem<TMeta = Record<string, unknown>> = KeepItemInput<TMeta>;\n\ntype KeepButtonSharedProps<TMeta> = {\n item: KeepButtonItem<TMeta>;\n children?: ReactNode | ((state: KeepButtonState<TMeta>) => ReactNode);\n savedLabel?: ReactNode;\n unsavedLabel?: ReactNode;\n savedAriaLabel?: string;\n unsavedAriaLabel?: string;\n getAriaLabel?: (state: KeepButtonState<TMeta>) => string;\n disabled?: boolean;\n onToggleError?: (error: unknown) => void;\n ref?: Ref<HTMLElement> | { readonly current: unknown };\n};\n\nexport type KeepButtonProps<TMeta = Record<string, unknown>> = KeepButtonSharedProps<TMeta> &\n (\n | (Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\" | \"onClick\" | \"aria-pressed\"> & {\n asChild?: false;\n onClick?: (event: MouseEvent<HTMLButtonElement>) => void;\n })\n | (Omit<HTMLAttributes<HTMLElement>, \"children\" | \"onClick\" | \"aria-pressed\"> & {\n asChild: true;\n children: ReactElement | ((state: KeepButtonState<TMeta>) => ReactElement);\n onClick?: (event: MouseEvent<HTMLElement>) => void;\n })\n );\n\nexport type KeepButtonState<TMeta = Record<string, unknown>> = {\n item: ReturnType<typeof useKeepItem<TMeta>>[\"item\"];\n isSaved: boolean;\n isLoading: boolean;\n isMutating: boolean;\n error: unknown | null;\n save: () => Promise<void>;\n remove: () => Promise<void>;\n toggle: () => Promise<void>;\n updateNote: (note?: string) => Promise<void>;\n updateTags: (tags?: string[]) => Promise<void>;\n};\n\n/** A style-free accessible save toggle. Consumers provide all visual styling. */\nexport function KeepButton<TMeta = Record<string, unknown>>({\n item,\n children,\n savedLabel = \"Saved\",\n unsavedLabel = \"Save\",\n savedAriaLabel,\n unsavedAriaLabel,\n getAriaLabel,\n asChild = false,\n onToggleError,\n onClick,\n disabled,\n ref: providedRef,\n ...buttonProps\n}: KeepButtonProps<TMeta>) {\n const state = useKeepItem(item);\n const { isSaved, toggle } = state;\n const isDisabled = disabled ?? state.isMutating;\n\n async function handleClick(event: MouseEvent<HTMLElement>) {\n if (isDisabled) return;\n if (asChild) {\n (onClick as ((event: MouseEvent<HTMLElement>) => void) | undefined)?.(event);\n } else {\n (onClick as ((event: MouseEvent<HTMLButtonElement>) => void) | undefined)?.(\n event as MouseEvent<HTMLButtonElement>,\n );\n }\n if (event.defaultPrevented) return;\n try {\n await toggle();\n } catch (error) {\n onToggleError?.(error);\n }\n }\n\n const content =\n typeof children === \"function\" ? children(state) : (children ?? (isSaved ? savedLabel : unsavedLabel));\n function handleElementClick(event: MouseEvent<HTMLElement>) {\n if (isDisabled) return;\n if (asChild && isValidElement<{ onClick?: (event: MouseEvent<HTMLElement>) => void }>(content)) {\n content.props.onClick?.(event);\n }\n if (!event.defaultPrevented) void handleClick(event);\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLElement>) {\n if (asChild && isValidElement<{ onKeyDown?: (event: KeyboardEvent<HTMLElement>) => void }>(content)) {\n content.props.onKeyDown?.(event);\n }\n (buttonProps as { onKeyDown?: (event: KeyboardEvent<HTMLElement>) => void }).onKeyDown?.(event);\n if (!event.defaultPrevented && !isDisabled && asChild && (event.key === \"Enter\" || event.key === \" \")) {\n void handleClick(event as unknown as MouseEvent<HTMLElement>);\n event.preventDefault();\n }\n }\n\n const child = asChild ? Children.only(content) : undefined;\n if (asChild && !isValidElement(child)) {\n throw new Error(\"KeepButton with asChild requires a single React element child.\");\n }\n const childRef = asChild && isValidElement(child) ? (child.props as { ref?: Ref<HTMLElement> }).ref : undefined;\n\n const commonProps = {\n ...buttonProps,\n \"aria-pressed\": isSaved,\n \"data-state\": state.error ? \"error\" : isSaved ? \"saved\" : \"unsaved\",\n \"data-loading\": state.isLoading || state.isMutating ? \"true\" : undefined,\n \"data-disabled\": isDisabled ? \"true\" : undefined,\n \"aria-label\":\n (\"aria-label\" in buttonProps ? buttonProps[\"aria-label\"] : undefined) ??\n getAriaLabel?.(state) ??\n (isSaved ? savedAriaLabel : unsavedAriaLabel) ??\n getAccessibleLabel(isSaved, item, asChild),\n ...(asChild\n ? {\n \"aria-disabled\": isDisabled,\n role: buttonProps.role ?? \"button\",\n tabIndex: isDisabled ? -1 : (buttonProps.tabIndex ?? 0),\n }\n : { disabled: isDisabled }),\n onClick: handleElementClick,\n onKeyDown: handleKeyDown,\n ...(asChild ? { ref: composeRefs(childRef, providedRef) } : {}),\n };\n\n if (asChild) {\n return cloneElement(child as ReactElement, commonProps);\n }\n\n return (\n <button\n {...commonProps}\n ref={providedRef as Ref<HTMLButtonElement>}\n type={\"type\" in buttonProps ? (buttonProps.type ?? \"button\") : \"button\"}\n >\n {content}\n </button>\n );\n}\n\nfunction composeRefs<T>(...refs: Array<Ref<T> | { readonly current: unknown } | null | undefined>): RefCallback<T> {\n return (value) => {\n for (const ref of refs) {\n if (typeof ref === \"function\") ref(value);\n else if (ref) (ref as { current: T | null }).current = value;\n }\n };\n}\n\nfunction getAccessibleLabel<TMeta>(isSaved: boolean, item: KeepButtonItem<TMeta>, asChild: boolean): string {\n if (!asChild) return isSaved ? \"Remove saved item\" : \"Save item\";\n const title = getMetaTitle(item.meta);\n const subject = title ? `${item.targetType ?? \"item\"}: ${title}` : (item.targetType ?? \"item\");\n return `${isSaved ? \"Remove\" : \"Save\"} ${subject}`;\n}\n\nfunction getMetaTitle<TMeta>(meta: TMeta): string | undefined {\n if (typeof meta !== \"object\" || meta === null || !(\"title\" in meta)) return undefined;\n const title = (meta as { title?: unknown }).title;\n return typeof title === \"string\" && title.trim() ? title.trim() : undefined;\n}\n","import { useCallback } from \"react\";\nimport type { KeepItemMetadataRefresher } from \"../../features/items/revalidation\";\nimport type { KeepItem, KeepItemInput } from \"../../features/items/types\";\nimport { useKeepStore } from \"../components/KeepProvider\";\nimport { useKeepStoreSelector } from \"./useKeepStoreSelector\";\n\nexport type UseKeepItemResult<TMeta = Record<string, unknown>> = {\n item: KeepItem<TMeta> | undefined;\n isSaved: boolean;\n isLoading: boolean;\n isMutating: boolean;\n error: unknown | null;\n save: () => Promise<void>;\n remove: () => Promise<void>;\n removeWithUndo: () => Promise<void>;\n undo: () => Promise<void>;\n toggle: () => Promise<void>;\n updateNote: (note?: string) => Promise<void>;\n updateTags: (tags?: string[]) => Promise<void>;\n toggleArchive: () => Promise<void>;\n archiveItem: () => Promise<void>;\n unarchiveItem: () => Promise<void>;\n archive: () => Promise<void>;\n unarchive: () => Promise<void>;\n togglePin: () => Promise<void>;\n moveToCollection: (collectionId?: string) => Promise<void>;\n refreshMetadata: (refresh: KeepItemMetadataRefresher<TMeta>) => Promise<void>;\n};\n\n/** Read and mutate one saved item from its complete minimal input description. */\nexport function useKeepItem<TMeta = Record<string, unknown>>(input?: KeepItemInput<TMeta>): UseKeepItemResult<TMeta> {\n const { store, actions } = useKeepStore<TMeta>();\n const id = input?.id ?? \"\";\n const item = useKeepStoreSelector(\n store,\n useCallback((state) => state.items.find((current) => current.id === id), [id]),\n );\n const isLoading = useKeepStoreSelector(\n store,\n useCallback((state) => state.isLoading, []),\n );\n const isMutating = useKeepStoreSelector(\n store,\n useCallback((state) => state.isMutating, []),\n );\n const error = useKeepStoreSelector(\n store,\n useCallback((state) => state.error, []),\n );\n const currentOrder = item?.order;\n\n const save = useCallback(async () => {\n if (!input) throw new Error(\"An item input is required to save an item.\");\n const now = Date.now();\n await actions.saveItem({\n ...input,\n ...(currentOrder === undefined ? {} : { order: currentOrder }),\n savedAt: item?.savedAt ?? now,\n updatedAt: now,\n });\n }, [actions, currentOrder, input, item?.savedAt]);\n\n const remove = useCallback(() => actions.removeItem(id), [actions, id]);\n const removeWithUndo = useCallback(() => actions.removeItemWithUndo(id), [actions, id]);\n const toggle = useCallback(() => (item ? remove() : save()), [item, remove, save]);\n const updateNote = useCallback((note?: string) => actions.updateNote(id, note), [actions, id]);\n const updateTags = useCallback((tags?: string[]) => actions.updateTags(id, tags), [actions, id]);\n const toggleArchive = useCallback(() => actions.toggleArchive(id), [actions, id]);\n const archive = useCallback(() => actions.archiveItem(id), [actions, id]);\n const unarchive = useCallback(() => actions.unarchiveItem(id), [actions, id]);\n const togglePin = useCallback(() => actions.togglePin(id), [actions, id]);\n const moveToCollection = useCallback(\n (collectionId?: string) => actions.moveToCollection(id, collectionId),\n [actions, id],\n );\n const refreshMetadata = useCallback(\n (refresh: KeepItemMetadataRefresher<TMeta>) => actions.refreshItemMetadata(id, refresh),\n [actions, id],\n );\n\n return {\n item,\n isSaved: Boolean(item),\n isLoading,\n isMutating,\n error,\n save,\n remove,\n removeWithUndo,\n undo: actions.undoLastRemoval,\n toggle,\n updateNote,\n updateTags,\n toggleArchive,\n archiveItem: archive,\n unarchiveItem: unarchive,\n archive,\n unarchive,\n togglePin,\n moveToCollection,\n refreshMetadata,\n };\n}\n","import {\n createContext,\n type PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from \"react\";\nimport { moveKeepItem, orderKeepItems, reorderKeepItems } from \"../../features/items/navigation\";\nimport type { KeepAutoRevalidationOptions, KeepItemResolver } from \"../../features/items/revalidation\";\nimport {\n type KeepItemMetadataRefresher,\n type KeepItemRevalidationSummary,\n type KeepItemRevalidator,\n type RevalidateKeepItemsOptions,\n revalidateKeepItems,\n} from \"../../features/items/revalidation\";\nimport type {\n KeepAction,\n KeepChangeContext,\n KeepErrorContext,\n KeepErrorHandler,\n KeepEventHandlers,\n KeepInvalidItemPolicy,\n KeepItem,\n KeepPlugin,\n KeepSchema,\n KeepSyncState,\n KeepUndoState,\n StorageAdapter,\n SyncCapableStorageAdapter,\n} from \"../../features/items/types\";\nimport { normalizeKeepTags } from \"../../features/items/types\";\nimport {\n exportItems,\n type ImportItemsOptions,\n type ImportItemsResult,\n importItems,\n} from \"../../features/persistence/backup\";\nimport { parseKeepMeta } from \"../../features/persistence/schema\";\nimport { KeepStore, type KeepStoreActions } from \"../../features/store/store\";\nimport { createBrowserStorageAdapter } from \"../../storage\";\nimport { KeepErrorBoundary, type KeepErrorBoundaryProps } from \"./KeepErrorBoundary\";\n\nexport type KeepContextValue<TMeta = Record<string, unknown>> = {\n items: KeepItem<TMeta>[];\n isLoading: boolean;\n isHydrated: boolean;\n isMutating: boolean;\n error: unknown | null;\n lastChange?: KeepChangeContext<TMeta>;\n syncState: KeepSyncState<TMeta>;\n undo: KeepUndoState;\n saveItem: (item: KeepItem<TMeta>) => Promise<void>;\n updateNote: (id: string, note?: string) => Promise<void>;\n updateTags: (id: string, tags?: string[]) => Promise<void>;\n toggleArchive: (id: string) => Promise<void>;\n archiveItem: (id: string) => Promise<void>;\n unarchiveItem: (id: string) => Promise<void>;\n togglePin: (id: string) => Promise<void>;\n moveToCollection: (id: string, collectionId?: string) => Promise<void>;\n updateTagsBatch: (ids: string[], tags?: string[]) => Promise<void>;\n addTagsBatch: (ids: string[], tags: string[]) => Promise<void>;\n removeTagsBatch: (ids: string[], tags: string[]) => Promise<void>;\n removeItem: (id: string) => Promise<void>;\n removeItems: (ids: string[]) => Promise<void>;\n removeItemWithUndo: (id: string) => Promise<void>;\n removeItemsWithUndo: (ids: string[]) => Promise<void>;\n undoLastRemoval: () => Promise<void>;\n clear: () => Promise<void>;\n refresh: () => Promise<void>;\n flushSync: () => Promise<void>;\n resolveSyncConflict: (id: string, resolution: \"local\" | \"remote\" | \"manual\", item?: KeepItem<TMeta>) => Promise<void>;\n refreshItemMetadata: (id: string, refresh: KeepItemMetadataRefresher<TMeta>) => Promise<void>;\n revalidateItems: (\n revalidator?: KeepItemRevalidator<TMeta>,\n options?: RevalidateKeepItemsOptions<TMeta>,\n ) => Promise<KeepItemRevalidationSummary<TMeta>>;\n reorderItems: (orderedIds: string[]) => Promise<void>;\n moveItem: (id: string, targetIndex: number) => Promise<void>;\n exportBackup: () => Promise<string>;\n importBackup: (\n data: string,\n options?: Pick<ImportItemsOptions<TMeta>, \"mode\" | \"invalidItemPolicy\" | \"onInvalidItem\">,\n ) => Promise<ImportItemsResult<TMeta>>;\n};\n\nexport type KeepProviderProps<TMeta = Record<string, unknown>> = PropsWithChildren<\n KeepEventHandlers<TMeta> & {\n storage?: StorageAdapter<TMeta>;\n /**\n * Optional server-provided snapshot rendered before the client adapter\n * finishes hydrating. The adapter remains the source of truth after the\n * first refresh.\n */\n initialItems?: KeepItem<TMeta>[];\n plugins?: KeepPlugin<TMeta>[];\n schemaVersion?: number;\n schema?: KeepSchema<TMeta>;\n invalidItemPolicy?: KeepInvalidItemPolicy;\n onInvalidItem?: (error: unknown, item: KeepItem<unknown>) => void;\n migrateMeta?: (\n meta: unknown,\n fromVersion: number,\n toVersion: number,\n item: KeepItem<TMeta>,\n ) => TMeta | Promise<TMeta>;\n /** Render this content when a descendant or provider render unexpectedly throws. */\n fallback?: KeepErrorBoundaryProps[\"fallback\"];\n onBoundaryError?: KeepErrorBoundaryProps[\"onError\"];\n boundaryResetKey?: unknown;\n validateItem?: KeepItemRevalidator<TMeta>;\n resolveItem?: KeepItemResolver<TMeta>;\n autoRevalidation?: KeepAutoRevalidationOptions<TMeta>;\n undoTimeoutMs?: number;\n }\n>;\n\nconst defaultStorage = createBrowserStorageAdapter();\nconst KeepContext = createContext<KeepContextValue<unknown> | null>(null);\nconst KeepStoreContext = createContext<KeepStoreAccess<unknown> | null>(null);\n\ntype KeepStoreAccess<TMeta> = {\n store: KeepStore<TMeta>;\n actions: KeepStoreActions<TMeta>;\n};\n\ntype MutationPlan<TMeta> = {\n next: KeepItem<TMeta>[];\n persist: () => Promise<void>;\n onSuccess?: () => void;\n pluginContext?: {\n action: KeepAction;\n id?: string;\n item?: KeepItem<TMeta>;\n items?: KeepItem<TMeta>[];\n };\n};\n\nexport function KeepProvider<TMeta = Record<string, unknown>>({\n storage = defaultStorage as StorageAdapter<TMeta>,\n initialItems,\n onSave,\n onRemove,\n onNoteUpdate,\n onTagsUpdate,\n onChange,\n onUndo,\n onError,\n plugins = [],\n schemaVersion,\n schema,\n invalidItemPolicy = \"error\",\n onInvalidItem,\n migrateMeta,\n fallback,\n onBoundaryError,\n boundaryResetKey,\n validateItem,\n resolveItem,\n autoRevalidation,\n undoTimeoutMs,\n children,\n}: KeepProviderProps<TMeta>) {\n const content = (\n <KeepProviderContent<TMeta>\n storage={storage}\n initialItems={initialItems}\n onSave={onSave}\n onRemove={onRemove}\n onNoteUpdate={onNoteUpdate}\n onTagsUpdate={onTagsUpdate}\n onChange={onChange}\n onUndo={onUndo}\n onError={onError}\n plugins={plugins}\n schemaVersion={schemaVersion}\n schema={schema}\n invalidItemPolicy={invalidItemPolicy}\n onInvalidItem={onInvalidItem}\n migrateMeta={migrateMeta}\n validateItem={validateItem}\n resolveItem={resolveItem}\n autoRevalidation={autoRevalidation}\n undoTimeoutMs={undoTimeoutMs}\n >\n {children}\n </KeepProviderContent>\n );\n if (fallback === undefined && onBoundaryError === undefined) return content;\n return (\n <KeepErrorBoundary fallback={fallback} onError={onBoundaryError} resetKey={boundaryResetKey}>\n {content}\n </KeepErrorBoundary>\n );\n}\n\nfunction KeepProviderContent<TMeta = Record<string, unknown>>({\n storage = defaultStorage as StorageAdapter<TMeta>,\n initialItems,\n onSave,\n onRemove,\n onNoteUpdate,\n onTagsUpdate,\n onChange,\n onUndo,\n onError,\n plugins = [],\n schemaVersion,\n schema,\n invalidItemPolicy = \"error\",\n onInvalidItem,\n migrateMeta,\n validateItem,\n resolveItem,\n autoRevalidation,\n undoTimeoutMs = 5000,\n children,\n}: KeepProviderProps<TMeta>) {\n const storeRef = useRef<KeepStore<TMeta> | null>(null);\n if (!storeRef.current) {\n storeRef.current = new KeepStore<TMeta>({\n items: initialItems ? [...initialItems] : [],\n isLoading: true,\n isHydrated: false,\n isMutating: false,\n error: null,\n lastChange: undefined,\n undo: { canUndo: false, ids: [] },\n });\n }\n const store = storeRef.current;\n const state = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n const { items, isLoading, isHydrated, isMutating, error, lastChange, undo: storedUndo } = state;\n const undo = storedUndo ?? EMPTY_UNDO_STATE;\n const itemsRef = useRef(items);\n const pluginsRef = useRef(plugins);\n pluginsRef.current = plugins;\n const handlersRef = useRef({ onSave, onRemove, onNoteUpdate, onTagsUpdate, onChange, onUndo, onError });\n handlersRef.current = { onSave, onRemove, onNoteUpdate, onTagsUpdate, onChange, onUndo, onError };\n const migrationRef = useRef({\n schemaVersion,\n migrateMeta,\n schema,\n invalidItemPolicy,\n onInvalidItem,\n });\n migrationRef.current = { schemaVersion, migrateMeta, schema, invalidItemPolicy, onInvalidItem };\n const operationTailRef = useRef<Promise<unknown>>(Promise.resolve());\n const pendingRefreshesRef = useRef(0);\n const pendingMutationsRef = useRef(0);\n const undoRef = useRef<\n { items: KeepItem<TMeta>[]; expiresAt: number; timer?: ReturnType<typeof setTimeout> } | undefined\n >(undefined);\n const autoRevalidationRef = useRef<KeepAutoRevalidationOptions<TMeta> | undefined>(autoRevalidation);\n autoRevalidationRef.current = autoRevalidation;\n const didMountRevalidateRef = useRef(false);\n const syncStorage = isSyncCapableStorage(storage) ? storage : undefined;\n const getSyncState = useCallback(() => syncStorage?.getSyncState() ?? IDLE_SYNC_STATE, [syncStorage]);\n const subscribeSync = useCallback(\n (listener: () => void) => syncStorage?.subscribeSync(listener) ?? (() => undefined),\n [syncStorage],\n );\n const syncState = useSyncExternalStore(subscribeSync, getSyncState, getSyncState);\n\n const reportError = useCallback(\n (cause: unknown, context: KeepErrorContext) => {\n store.setState({ error: cause });\n handlersRef.current.onError?.(cause, context);\n for (const plugin of pluginsRef.current) plugin.onError?.(cause, context);\n },\n [store],\n );\n\n const setItems = useCallback(\n (next: KeepItem<TMeta>[]) => {\n itemsRef.current = next;\n store.setState({ items: next });\n },\n [store],\n );\n\n const runBeforePlugins = useCallback(async (context: NonNullable<MutationPlan<TMeta>[\"pluginContext\"]>) => {\n for (const plugin of pluginsRef.current) await plugin.before?.(context);\n return context;\n }, []);\n\n const runAfterPlugins = useCallback(async (context: NonNullable<MutationPlan<TMeta>[\"pluginContext\"]>) => {\n for (const plugin of pluginsRef.current) await plugin.after?.(context);\n }, []);\n\n const enqueueOperation = useCallback(<T,>(operation: () => Promise<T>): Promise<T> => {\n const run = operationTailRef.current.then(operation, operation);\n operationTailRef.current = run.then(\n () => undefined,\n () => undefined,\n );\n return run;\n }, []);\n\n const refresh = useCallback(async () => {\n pendingRefreshesRef.current += 1;\n store.setState({ isLoading: true });\n\n try {\n await enqueueOperation(async () => {\n try {\n let next = await storage.getAll();\n let needsMigrationPersist = false;\n if (migrationRef.current.schemaVersion !== undefined) {\n const migrated = await Promise.all(\n next.map(async (item) => {\n const currentSchemaVersion = migrationRef.current.schemaVersion as number;\n if (item.schemaVersion === currentSchemaVersion) return item;\n const meta = migrationRef.current.migrateMeta\n ? await migrationRef.current.migrateMeta(\n item.meta,\n item.schemaVersion ?? 0,\n currentSchemaVersion,\n item,\n )\n : item.meta;\n return { ...item, meta, schemaVersion: currentSchemaVersion };\n }),\n );\n if (migrated.some((item, index) => item !== next[index])) {\n next = migrated;\n needsMigrationPersist = true;\n }\n }\n if (migrationRef.current.schema) {\n const validated: KeepItem<TMeta>[] = [];\n for (const item of next) {\n try {\n validated.push(await parseKeepMetaItem(item, migrationRef.current.schema));\n } catch (cause) {\n migrationRef.current.onInvalidItem?.(cause, item);\n if (migrationRef.current.invalidItemPolicy === \"drop\") continue;\n throw cause;\n }\n }\n next = validated;\n }\n if (needsMigrationPersist) {\n if (storage.setMany) await storage.setMany(next);\n else for (const item of next) await storage.set(item);\n }\n setItems(next);\n store.setState({ error: null });\n } catch (cause) {\n reportError(cause, { action: \"refresh\" });\n }\n });\n } finally {\n pendingRefreshesRef.current -= 1;\n if (pendingRefreshesRef.current === 0) store.setState({ isLoading: false });\n store.setState({ isHydrated: true });\n }\n }, [enqueueOperation, reportError, setItems, storage, store]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n useEffect(() => {\n if (!storage.subscribe) return;\n return storage.subscribe(() => void refresh());\n }, [refresh, storage]);\n\n useEffect(() => {\n if (!isScopeAwareStorage(storage)) return;\n return storage.subscribeScope(() => {\n undoRef.current?.timer && clearTimeout(undoRef.current.timer);\n undoRef.current = undefined;\n itemsRef.current = [];\n store.setState({ items: [], isHydrated: false, isLoading: true, error: null, undo: EMPTY_UNDO_STATE });\n void refresh();\n });\n }, [refresh, storage, store]);\n\n const runMutation = useCallback(\n (\n action: Exclude<KeepAction, \"refresh\">,\n id: string | undefined,\n createPlan: (previous: KeepItem<TMeta>[]) => MutationPlan<TMeta> | undefined,\n ): Promise<void> => {\n pendingMutationsRef.current += 1;\n store.setState({ isMutating: true });\n\n const run = enqueueOperation(async () => {\n const previous = itemsRef.current;\n const plan = createPlan(previous);\n if (!plan) return;\n\n try {\n if (plan.pluginContext) await runBeforePlugins(plan.pluginContext);\n setItems(plan.next);\n store.setState({ error: null });\n await plan.persist();\n plan.onSuccess?.();\n if (plan.pluginContext) await runAfterPlugins(plan.pluginContext);\n if (plan.pluginContext) {\n const change: KeepChangeContext<TMeta> = { ...plan.pluginContext, phase: \"local\" };\n store.setState({ lastChange: change });\n void Promise.resolve(handlersRef.current.onChange?.(change)).catch((cause) =>\n reportError(cause, { action, id }),\n );\n }\n } catch (cause) {\n setItems(previous);\n reportError(cause, { action, id });\n throw cause;\n }\n });\n\n return run.finally(() => {\n pendingMutationsRef.current -= 1;\n if (pendingMutationsRef.current === 0) store.setState({ isMutating: false });\n });\n },\n [enqueueOperation, reportError, runAfterPlugins, runBeforePlugins, setItems, store],\n );\n\n const saveItem = useCallback(\n async (item: KeepItem<TMeta>) => {\n let normalizedItem: KeepItem<TMeta>;\n try {\n const meta = migrationRef.current.schema\n ? await parseKeepMeta(migrationRef.current.schema, item.meta)\n : item.meta;\n normalizedItem = {\n ...item,\n meta,\n tags: normalizeKeepTags(item.tags),\n ...(migrationRef.current.schemaVersion === undefined\n ? {}\n : { schemaVersion: migrationRef.current.schemaVersion }),\n };\n } catch (cause) {\n reportError(cause, { action: \"save\", id: item.id });\n throw cause;\n }\n await runMutation(\"save\", normalizedItem.id, (previous) => {\n const current = previous.find((item) => item.id === normalizedItem.id);\n const hasCustomOrder = previous.some((item) => item.order !== undefined);\n const nextItem = {\n ...normalizedItem,\n ...(normalizedItem.order === undefined && current?.order !== undefined ? { order: current.order } : {}),\n ...(normalizedItem.order === undefined && !current && hasCustomOrder\n ? { order: previous.reduce((max, item) => Math.max(max, item.order ?? -1), -1) + 1 }\n : {}),\n };\n const withoutCurrent = previous.filter((item) => item.id !== nextItem.id);\n const next = hasCustomOrder\n ? reorderKeepItems(\n [...withoutCurrent, nextItem],\n orderKeepItems(previous).map((item) => (item.id === nextItem.id ? nextItem.id : item.id)),\n )\n : [...withoutCurrent, nextItem].sort((a, b) => b.updatedAt - a.updatedAt);\n return {\n next,\n persist: () => storage.set(nextItem),\n onSuccess: () => handlersRef.current.onSave?.(nextItem),\n pluginContext: { action: \"save\", id: nextItem.id, item: nextItem },\n };\n });\n },\n [reportError, runMutation, storage],\n );\n\n const reorderItems = useCallback(\n async (orderedIds: string[]) => {\n await runMutation(\"reorder\", undefined, (previous) => {\n const next = reorderKeepItems(previous, orderedIds);\n const changedItems = next.filter(\n (item, index) => item.id !== previous[index]?.id || item.order !== previous[index]?.order,\n );\n return {\n next,\n persist: async () => {\n try {\n if (storage.setMany) await storage.setMany(changedItems);\n else for (const item of changedItems) await storage.set(item);\n } catch (cause) {\n await restoreItems(storage, previous);\n throw cause;\n }\n },\n pluginContext: { action: \"reorder\", items: changedItems },\n };\n });\n },\n [runMutation, storage],\n );\n\n const moveItem = useCallback(\n async (id: string, targetIndex: number) => {\n await runMutation(\"reorder\", id, (previous) => {\n const next = moveKeepItem(previous, id, targetIndex);\n const changedItems = next.filter(\n (item, index) => item.id !== previous[index]?.id || item.order !== previous[index]?.order,\n );\n return {\n next,\n persist: async () => {\n try {\n if (storage.setMany) await storage.setMany(changedItems);\n else for (const item of changedItems) await storage.set(item);\n } catch (cause) {\n await restoreItems(storage, previous);\n throw cause;\n }\n },\n pluginContext: { action: \"reorder\", id, items: changedItems },\n };\n });\n },\n [runMutation, storage],\n );\n\n const updateNote = useCallback(\n async (id: string, note?: string) => {\n const nextNote = note?.trim() || undefined;\n await runMutation(\"updateNote\", id, (previous) => {\n const current = previous.find((item) => item.id === id);\n if (!current) return undefined;\n const next = { ...current, note: nextNote, updatedAt: Date.now() };\n return {\n next: previous.map((item) => (item.id === id ? next : item)),\n persist: () => storage.set(next),\n onSuccess: () => handlersRef.current.onNoteUpdate?.(id, nextNote),\n pluginContext: { action: \"updateNote\", id, item: next },\n };\n });\n },\n [runMutation, storage],\n );\n\n const updateTags = useCallback(\n async (id: string, tags?: string[]) => {\n const nextTags = normalizeKeepTags(tags);\n await runMutation(\"updateTags\", id, (previous) => {\n const current = previous.find((item) => item.id === id);\n if (!current) return undefined;\n const next = { ...current, tags: nextTags, updatedAt: Date.now() };\n return {\n next: previous.map((item) => (item.id === id ? next : item)),\n persist: () => storage.set(next),\n onSuccess: () => handlersRef.current.onTagsUpdate?.(id, nextTags),\n pluginContext: { action: \"updateTags\", id, item: next },\n };\n });\n },\n [runMutation, storage],\n );\n\n const setArchive = useCallback(\n async (id: string, archived: boolean) => {\n await runMutation(\"archive\", id, (previous) => {\n const current = previous.find((item) => item.id === id);\n if (!current) return undefined;\n const next = { ...current, archived, updatedAt: Date.now() };\n return {\n next: previous.map((item) => (item.id === id ? next : item)),\n persist: () => storage.set(next),\n pluginContext: { action: \"archive\", id, item: next },\n };\n });\n },\n [runMutation, storage],\n );\n\n const toggleArchive = useCallback(\n (id: string) => {\n const item = itemsRef.current.find((current) => current.id === id);\n return setArchive(id, item?.archived !== true);\n },\n [setArchive],\n );\n const archiveItem = useCallback((id: string) => setArchive(id, true), [setArchive]);\n const unarchiveItem = useCallback((id: string) => setArchive(id, false), [setArchive]);\n\n const togglePin = useCallback(\n async (id: string) => {\n await runMutation(\"pin\", id, (previous) => {\n const current = previous.find((item) => item.id === id);\n if (!current) return undefined;\n const next = { ...current, pinned: current.pinned !== true, updatedAt: Date.now() };\n return {\n next: previous.map((item) => (item.id === id ? next : item)),\n persist: () => storage.set(next),\n pluginContext: { action: \"pin\", id, item: next },\n };\n });\n },\n [runMutation, storage],\n );\n\n const moveToCollection = useCallback(\n async (id: string, collectionId?: string) => {\n const nextCollectionId = collectionId?.trim() || undefined;\n await runMutation(\"collection\", id, (previous) => {\n const current = previous.find((item) => item.id === id);\n if (!current) return undefined;\n const { collectionId: _oldCollectionId, ...withoutCollection } = current;\n const next = {\n ...withoutCollection,\n ...(nextCollectionId ? { collectionId: nextCollectionId } : {}),\n updatedAt: Date.now(),\n };\n return {\n next: previous.map((item) => (item.id === id ? next : item)),\n persist: () => storage.set(next),\n pluginContext: { action: \"collection\", id, item: next },\n };\n });\n },\n [runMutation, storage],\n );\n\n const updateTagsBatch = useCallback(\n async (ids: string[], tags?: string[]) => {\n const idSet = new Set(ids);\n const nextTags = normalizeKeepTags(tags);\n await runMutation(\"updateTagsBatch\", undefined, (previous) => {\n const currentItems = previous.filter((item) => idSet.has(item.id));\n if (currentItems.length === 0) return undefined;\n const updatedItems = currentItems.map((item) => ({\n ...item,\n tags: nextTags,\n updatedAt: Date.now(),\n }));\n const updatedById = new Map(updatedItems.map((item) => [item.id, item]));\n return {\n next: previous.map((item) => updatedById.get(item.id) ?? item),\n persist: async () => {\n if (storage.setMany) {\n await storage.setMany(updatedItems);\n return;\n }\n const completed: KeepItem<TMeta>[] = [];\n try {\n for (const item of updatedItems) {\n await storage.set(item);\n completed.push(item);\n }\n } catch (cause) {\n const previousById = new Map(currentItems.map((item) => [item.id, item]));\n await Promise.allSettled(\n completed.map((item) => {\n const previousItem = previousById.get(item.id);\n return previousItem ? storage.set(previousItem) : Promise.resolve();\n }),\n );\n throw cause;\n }\n },\n onSuccess: () => {\n updatedItems.forEach((item) => {\n handlersRef.current.onTagsUpdate?.(item.id, nextTags);\n });\n },\n pluginContext: { action: \"updateTagsBatch\", items: updatedItems },\n };\n });\n },\n [runMutation, storage],\n );\n\n const addTagsBatch = useCallback(\n async (ids: string[], tags: string[]) => {\n const additions = normalizeKeepTags(tags) ?? [];\n const idSet = new Set(ids);\n const currentItems = itemsRef.current.filter((item) => idSet.has(item.id));\n await Promise.all(\n currentItems.map((item) => updateTags(item.id, normalizeKeepTags([...(item.tags ?? []), ...additions]))),\n );\n },\n [updateTags],\n );\n\n const removeTagsBatch = useCallback(\n async (ids: string[], tags: string[]) => {\n const removals = new Set(normalizeKeepTags(tags) ?? []);\n const idSet = new Set(ids);\n const currentItems = itemsRef.current.filter((item) => idSet.has(item.id));\n await Promise.all(\n currentItems.map((item) =>\n updateTags(item.id, normalizeKeepTags((item.tags ?? []).filter((tag) => !removals.has(tag)))),\n ),\n );\n },\n [updateTags],\n );\n\n const removeItem = useCallback(\n async (id: string) => {\n await runMutation(\"remove\", id, (previous) => {\n const current = previous.find((item) => item.id === id);\n if (!current) return undefined;\n return {\n next: previous.filter((item) => item.id !== id),\n persist: () => storage.remove(id),\n onSuccess: () => handlersRef.current.onRemove?.(current),\n pluginContext: { action: \"remove\", id, item: current },\n };\n });\n },\n [runMutation, storage],\n );\n\n const removeItems = useCallback(\n async (ids: string[]) => {\n const idSet = new Set(ids);\n await runMutation(\"removeBatch\", undefined, (previous) => {\n const removedItems = previous.filter((item) => idSet.has(item.id));\n if (removedItems.length === 0) return undefined;\n return {\n next: previous.filter((item) => !idSet.has(item.id)),\n persist: async () => {\n if (storage.removeMany) {\n await storage.removeMany(removedItems.map((item) => item.id));\n return;\n }\n const completed: KeepItem<TMeta>[] = [];\n try {\n for (const item of removedItems) {\n await storage.remove(item.id);\n completed.push(item);\n }\n } catch (cause) {\n await Promise.allSettled(completed.map((item) => storage.set(item)));\n throw cause;\n }\n },\n onSuccess: () => {\n removedItems.forEach((item) => {\n handlersRef.current.onRemove?.(item);\n });\n },\n pluginContext: { action: \"removeBatch\", items: removedItems },\n };\n });\n },\n [runMutation, storage],\n );\n\n const rememberUndo = useCallback(\n (removedItems: KeepItem<TMeta>[]) => {\n undoRef.current?.timer && clearTimeout(undoRef.current.timer);\n const startedAt = Date.now();\n const expiresAt = startedAt + Math.max(0, undoTimeoutMs);\n const timer = setTimeout(\n () => {\n undoRef.current = undefined;\n store.setState({ undo: { canUndo: false, ids: [] } });\n },\n Math.max(0, undoTimeoutMs),\n );\n undoRef.current = { items: removedItems, expiresAt, timer };\n store.setState({ undo: { canUndo: true, ids: removedItems.map((item) => item.id), startedAt, expiresAt } });\n },\n [store, undoTimeoutMs],\n );\n\n const removeItemWithUndo = useCallback(\n async (id: string) => {\n const item = itemsRef.current.find((current) => current.id === id);\n await removeItem(id);\n if (item) rememberUndo([item]);\n },\n [rememberUndo, removeItem],\n );\n\n const removeItemsWithUndo = useCallback(\n async (ids: string[]) => {\n const idSet = new Set(ids);\n const removedItems = itemsRef.current.filter((item) => idSet.has(item.id));\n await removeItems(ids);\n if (removedItems.length > 0) rememberUndo(removedItems);\n },\n [rememberUndo, removeItems],\n );\n\n const undoLastRemoval = useCallback(async () => {\n const pending = undoRef.current;\n if (!pending || pending.expiresAt < Date.now()) {\n undoRef.current = undefined;\n store.setState({ undo: { canUndo: false, ids: [] } });\n return;\n }\n if (pending.timer) clearTimeout(pending.timer);\n undoRef.current = undefined;\n store.setState({ undo: { canUndo: false, ids: [] } });\n await runMutation(\"undo\", undefined, (previous) => {\n const restored = new Map(pending.items.map((item) => [item.id, item]));\n const next = [...previous.filter((item) => !restored.has(item.id)), ...pending.items].sort(\n (a, b) => b.updatedAt - a.updatedAt,\n );\n return {\n next,\n persist: async () => {\n if (storage.setMany) await storage.setMany(pending.items);\n else for (const item of pending.items) await storage.set(item);\n },\n onSuccess: () => handlersRef.current.onUndo?.(pending.items),\n pluginContext: { action: \"undo\", items: pending.items },\n };\n });\n }, [runMutation, storage, store]);\n\n useEffect(() => {\n if (syncState.status !== \"error\" || !undoRef.current) return;\n void undoLastRemoval();\n }, [syncState.status, undoLastRemoval]);\n\n const clear = useCallback(\n () =>\n runMutation(\"clear\", undefined, (_previous) => ({\n next: [],\n persist: () => storage.clear(),\n pluginContext: { action: \"clear\", items: [] },\n })),\n [runMutation, storage],\n );\n\n const revalidateItems = useCallback(\n async (\n revalidator: KeepItemRevalidator<TMeta> | undefined,\n options: RevalidateKeepItemsOptions<TMeta> = {},\n ): Promise<KeepItemRevalidationSummary<TMeta>> => {\n pendingMutationsRef.current += 1;\n store.setState({ isMutating: true });\n const run = enqueueOperation(async () => {\n const previous = itemsRef.current;\n let persistenceStarted = false;\n try {\n const activeRevalidator = revalidator ?? validateItem;\n if (!activeRevalidator)\n throw new Error(\"KeepProvider.revalidateItems requires a revalidator or validateItem.\");\n const summary = await revalidateKeepItems(previous, activeRevalidator, {\n ...options,\n resolveItem: options.resolveItem ?? resolveItem,\n });\n const pluginContext = { action: \"revalidate\" as const, items: summary.updatedItems };\n await runBeforePlugins(pluginContext);\n if (summary.updatedItems.length > 0) {\n persistenceStarted = true;\n if (storage.setMany) await storage.setMany(summary.updatedItems);\n else for (const item of summary.updatedItems) await storage.set(item);\n }\n if (summary.removedIds.length > 0) {\n persistenceStarted = true;\n if (storage.removeMany) await storage.removeMany(summary.removedIds);\n else for (const id of summary.removedIds) await storage.remove(id);\n }\n setItems(summary.items);\n store.setState({ error: null });\n const removedIdSet = new Set(summary.removedIds);\n for (const result of summary.results) {\n if (removedIdSet.has(result.item.id)) handlersRef.current.onRemove?.(result.item);\n }\n await runAfterPlugins(pluginContext);\n void Promise.resolve(handlersRef.current.onChange?.({ ...pluginContext, phase: \"local\" })).catch((cause) =>\n reportError(cause, { action: \"revalidate\" }),\n );\n return summary;\n } catch (cause) {\n if (persistenceStarted) await restoreItems(storage, previous);\n setItems(previous);\n reportError(cause, { action: \"revalidate\" });\n throw cause;\n }\n });\n return run.finally(() => {\n pendingMutationsRef.current -= 1;\n if (pendingMutationsRef.current === 0) store.setState({ isMutating: false });\n });\n },\n [\n enqueueOperation,\n reportError,\n resolveItem,\n runAfterPlugins,\n runBeforePlugins,\n setItems,\n storage,\n store,\n validateItem,\n ],\n );\n\n useEffect(() => {\n const settings = autoRevalidationRef.current;\n const activeRevalidator = settings?.revalidator ?? validateItem;\n if (!settings || !activeRevalidator) return;\n const run = () =>\n void revalidateItems(activeRevalidator, { removeStatuses: settings.removeStatuses }).catch(() => undefined);\n if (isHydrated && settings.onMount !== false && !didMountRevalidateRef.current) {\n didMountRevalidateRef.current = true;\n run();\n }\n const interval = settings.intervalMs && settings.intervalMs > 0 ? setInterval(run, settings.intervalMs) : undefined;\n const onOnline = () => {\n if (settings.onReconnect !== false) run();\n };\n if (typeof window !== \"undefined\" && settings.onReconnect !== false) {\n window.addEventListener(\"online\", onOnline);\n }\n return () => {\n if (interval) clearInterval(interval);\n if (typeof window !== \"undefined\") window.removeEventListener(\"online\", onOnline);\n };\n }, [isHydrated, revalidateItems, validateItem]);\n\n const refreshItemMetadata = useCallback(\n async (id: string, refresh: KeepItemMetadataRefresher<TMeta>): Promise<void> => {\n if (!itemsRef.current.some((item) => item.id === id)) {\n throw new Error(`Cannot refresh metadata for missing item \"${id}\".`);\n }\n await revalidateItems(async (item) => {\n if (item.id !== id) return \"available\";\n return { status: \"available\", meta: await refresh(item) };\n });\n },\n [revalidateItems],\n );\n const flushSync = useCallback(() => (syncStorage ? syncStorage.flushSync() : Promise.resolve()), [syncStorage]);\n const resolveSyncConflict = useCallback(\n (id: string, resolution: \"local\" | \"remote\" | \"manual\", item?: KeepItem<TMeta>) => {\n if (!syncStorage?.resolveSyncConflict) {\n return Promise.reject(new Error(\"The configured storage does not support sync conflict resolution.\"));\n }\n return syncStorage.resolveSyncConflict(id, resolution, item);\n },\n [syncStorage],\n );\n const exportBackup = useCallback(() => exportItems(storage), [storage]);\n const importBackup = useCallback(\n async (\n data: string,\n options: Pick<ImportItemsOptions<TMeta>, \"mode\" | \"invalidItemPolicy\" | \"onInvalidItem\"> = {},\n ): Promise<ImportItemsResult<TMeta>> => {\n pendingMutationsRef.current += 1;\n store.setState({ isMutating: true });\n const run = enqueueOperation(async () => {\n try {\n const result = await importItems(storage, data, {\n ...options,\n schema: migrationRef.current.schema,\n invalidItemPolicy: options.invalidItemPolicy ?? migrationRef.current.invalidItemPolicy,\n onInvalidItem: options.onInvalidItem ?? migrationRef.current.onInvalidItem,\n });\n setItems(result.items);\n store.setState({ error: null });\n return result;\n } catch (cause) {\n reportError(cause, { action: \"import\" });\n throw cause;\n }\n });\n return run.finally(() => {\n pendingMutationsRef.current -= 1;\n if (pendingMutationsRef.current === 0) store.setState({ isMutating: false });\n });\n },\n [enqueueOperation, reportError, setItems, storage, store],\n );\n\n const value = useMemo<KeepContextValue<TMeta>>(\n () => ({\n items,\n isLoading,\n isHydrated,\n isMutating,\n error,\n lastChange,\n syncState,\n undo,\n saveItem,\n updateNote,\n updateTags,\n toggleArchive,\n archiveItem,\n unarchiveItem,\n togglePin,\n moveToCollection,\n updateTagsBatch,\n addTagsBatch,\n removeTagsBatch,\n removeItem,\n removeItems,\n removeItemWithUndo,\n removeItemsWithUndo,\n undoLastRemoval,\n clear,\n refresh,\n flushSync,\n resolveSyncConflict,\n refreshItemMetadata,\n revalidateItems,\n reorderItems,\n moveItem,\n exportBackup,\n importBackup,\n }),\n [\n clear,\n error,\n lastChange,\n flushSync,\n resolveSyncConflict,\n isHydrated,\n isLoading,\n isMutating,\n items,\n syncState,\n undo,\n refresh,\n removeItem,\n saveItem,\n removeItemWithUndo,\n removeItemsWithUndo,\n undoLastRemoval,\n updateNote,\n updateTags,\n toggleArchive,\n archiveItem,\n unarchiveItem,\n togglePin,\n moveToCollection,\n updateTagsBatch,\n addTagsBatch,\n removeTagsBatch,\n removeItems,\n refreshItemMetadata,\n revalidateItems,\n reorderItems,\n moveItem,\n exportBackup,\n importBackup,\n ],\n );\n\n const actions = useMemo<KeepStoreActions<TMeta>>(\n () => ({\n saveItem,\n updateNote,\n updateTags,\n toggleArchive,\n archiveItem,\n unarchiveItem,\n togglePin,\n moveToCollection,\n updateTagsBatch,\n addTagsBatch,\n removeTagsBatch,\n removeItem,\n removeItems,\n removeItemWithUndo,\n removeItemsWithUndo,\n undoLastRemoval,\n clear,\n refresh,\n refreshItemMetadata,\n revalidateItems,\n reorderItems,\n moveItem,\n }),\n [\n addTagsBatch,\n clear,\n refresh,\n removeItem,\n removeItems,\n removeTagsBatch,\n saveItem,\n updateNote,\n updateTags,\n toggleArchive,\n archiveItem,\n unarchiveItem,\n togglePin,\n moveToCollection,\n updateTagsBatch,\n refreshItemMetadata,\n revalidateItems,\n reorderItems,\n moveItem,\n removeItemWithUndo,\n removeItemsWithUndo,\n undoLastRemoval,\n ],\n );\n const storeAccess = useMemo<KeepStoreAccess<TMeta>>(() => ({ store, actions }), [actions, store]);\n\n return (\n <KeepStoreContext.Provider value={storeAccess as KeepStoreAccess<unknown>}>\n <KeepContext.Provider value={value as unknown as KeepContextValue<unknown>}>{children}</KeepContext.Provider>\n </KeepStoreContext.Provider>\n );\n}\n\nconst IDLE_SYNC_STATE: KeepSyncState<never> = Object.freeze({\n status: \"idle\",\n pendingCount: 0,\n conflictIds: [],\n conflicts: [],\n});\n\nconst EMPTY_UNDO_STATE: KeepUndoState = Object.freeze({ canUndo: false, ids: [] });\n\nfunction isSyncCapableStorage<TMeta>(storage: StorageAdapter<TMeta>): storage is SyncCapableStorageAdapter<TMeta> {\n return (\n \"getSyncState\" in storage &&\n typeof storage.getSyncState === \"function\" &&\n \"subscribeSync\" in storage &&\n typeof storage.subscribeSync === \"function\" &&\n \"flushSync\" in storage &&\n typeof storage.flushSync === \"function\"\n );\n}\n\nfunction isScopeAwareStorage<TMeta>(\n storage: StorageAdapter<TMeta>,\n): storage is StorageAdapter<TMeta> & { subscribeScope: (listener: () => void) => () => void } {\n return \"subscribeScope\" in storage && typeof storage.subscribeScope === \"function\";\n}\n\nasync function parseKeepMetaItem<TMeta>(item: KeepItem<unknown>, schema: KeepSchema<TMeta>): Promise<KeepItem<TMeta>> {\n return { ...item, meta: await parseKeepMeta(schema, item.meta) };\n}\n\nasync function restoreItems<TMeta>(storage: StorageAdapter<TMeta>, items: KeepItem<TMeta>[]): Promise<void> {\n try {\n if (storage.setMany) {\n await storage.setMany(items);\n return;\n }\n for (const item of items) await storage.set(item);\n } catch {\n // The original operation's error is more useful to the caller than a best-effort rollback error.\n }\n}\n\nexport function useKeepContext<TMeta = Record<string, unknown>>(): KeepContextValue<TMeta> {\n const context = useContext(KeepContext);\n if (!context) throw new Error(\"Keep hooks must be used inside a KeepProvider\");\n return context as unknown as KeepContextValue<TMeta>;\n}\n\nexport function useKeepStore<TMeta = Record<string, unknown>>(): KeepStoreAccess<TMeta> {\n const context = useContext(KeepStoreContext);\n if (!context) throw new Error(\"Keep hooks must be used inside a KeepProvider\");\n return context as unknown as KeepStoreAccess<TMeta>;\n}\n\nexport type { KeepErrorHandler };\n","import { Component, type ErrorInfo, type ReactNode } from \"react\";\n\nexport type KeepErrorBoundaryProps = {\n children?: ReactNode;\n fallback?: ReactNode | ((error: unknown) => ReactNode);\n onError?: (error: unknown, info: ErrorInfo) => void;\n /** Change this value to retry rendering after an error has been handled. */\n resetKey?: unknown;\n};\n\ntype KeepErrorBoundaryState = { error: unknown | null };\n\n/** Prevents an unexpected render error from taking down the host application. */\nexport class KeepErrorBoundary extends Component<KeepErrorBoundaryProps, KeepErrorBoundaryState> {\n state: KeepErrorBoundaryState = { error: null };\n\n static getDerivedStateFromError(error: unknown): KeepErrorBoundaryState {\n return { error };\n }\n\n componentDidCatch(error: unknown, info: ErrorInfo) {\n this.props.onError?.(error, info);\n }\n\n componentDidUpdate(previousProps: KeepErrorBoundaryProps) {\n if (this.state.error !== null && previousProps.resetKey !== this.props.resetKey) {\n this.setState({ error: null });\n }\n }\n\n render() {\n if (this.state.error !== null) {\n return typeof this.props.fallback === \"function\"\n ? this.props.fallback(this.state.error)\n : (this.props.fallback ?? null);\n }\n return this.props.children;\n }\n}\n","import { useCallback, useRef, useSyncExternalStore } from \"react\";\nimport type { KeepStore, KeepStoreState } from \"../../features/store/store\";\n\nexport function useKeepStoreSelector<TMeta, TSelected>(\n store: KeepStore<TMeta>,\n selector: (state: KeepStoreState<TMeta>) => TSelected,\n): TSelected {\n const cacheRef = useRef<{\n snapshot: KeepStoreState<TMeta>;\n selector: (state: KeepStoreState<TMeta>) => TSelected;\n selected: TSelected;\n } | null>(null);\n const getSelectedSnapshot = useCallback(() => {\n const snapshot = store.getSnapshot();\n const cached = cacheRef.current;\n if (cached?.snapshot === snapshot && cached.selector === selector) return cached.selected;\n const selected = selector(snapshot);\n cacheRef.current = { snapshot, selector, selected };\n return selected;\n }, [selector, store]);\n\n return useSyncExternalStore(store.subscribe, getSelectedSnapshot, getSelectedSnapshot);\n}\n","import { useMemo } from \"react\";\nimport type { KeepItem } from \"../../features/items/types\";\nimport { useKeepContext } from \"../components/KeepProvider\";\n\nexport type KeepCollectionSummary = {\n id: string;\n name: string;\n count: number;\n};\n\nexport type UseKeepCollectionsOptions = {\n targetType?: string;\n orderBy?: \"name\" | \"count\";\n};\n\nexport type UseKeepCollectionsResult = KeepCollectionSummary[];\n\n/** Derive de-duplicated collection choices from the provider's complete saved-item snapshot. */\nexport function useKeepCollections<TMeta = Record<string, unknown>>(\n options: UseKeepCollectionsOptions = {},\n): UseKeepCollectionsResult {\n const { items } = useKeepContext<TMeta>();\n const { orderBy = \"name\", targetType } = options;\n return useMemo(() => {\n const collections = new Map<string, KeepCollectionSummary>();\n for (const item of items) {\n if (targetType !== undefined && item.targetType !== targetType) continue;\n const collection = getCollection(item);\n if (!collection) continue;\n const current = collections.get(collection.id);\n collections.set(collection.id, {\n id: collection.id,\n name: current?.name ?? collection.name,\n count: (current?.count ?? 0) + 1,\n });\n }\n return [...collections.values()].sort((left, right) => {\n if (orderBy === \"count\" && left.count !== right.count) return right.count - left.count;\n return left.name.localeCompare(right.name) || left.id.localeCompare(right.id);\n });\n }, [items, orderBy, targetType]);\n}\n\nfunction getCollection<TMeta>(item: KeepItem<TMeta>): { id: string; name: string } | undefined {\n const id = item.collectionId?.trim();\n if (id) return { id, name: id };\n if (!isRecord(item.meta)) return undefined;\n const metadata = item.meta.collectionId;\n if (typeof metadata === \"string\" && metadata.trim()) {\n const normalized = metadata.trim();\n return { id: normalized, name: getCollectionName(item.meta.collection, normalized) };\n }\n if (typeof item.meta.collection === \"string\" && item.meta.collection.trim()) {\n const normalized = item.meta.collection.trim();\n return { id: normalized, name: normalized };\n }\n if (isRecord(item.meta.collection) && typeof item.meta.collection.id === \"string\") {\n const normalized = item.meta.collection.id.trim();\n if (!normalized) return undefined;\n return { id: normalized, name: getCollectionName(item.meta.collection, normalized) };\n }\n return undefined;\n}\n\nfunction getCollectionName(value: unknown, fallback: string): string {\n if (isRecord(value) && typeof value.name === \"string\" && value.name.trim()) return value.name.trim();\n return fallback;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n","import { useCallback, useMemo } from \"react\";\nimport { type KeepListQuery, type QueryKeepItemsResult, queryKeepItems } from \"../../features/items/query\";\nimport type {\n KeepItemRevalidationSummary,\n KeepItemRevalidator,\n RevalidateKeepItemsOptions,\n} from \"../../features/items/revalidation\";\nimport type { KeepItem } from \"../../features/items/types\";\nimport { useKeepStore } from \"../components/KeepProvider\";\nimport { useKeepStoreSelector } from \"./useKeepStoreSelector\";\n\nexport type { KeepListQuery } from \"../../features/items/query\";\n\nexport type UseKeepListResult<TMeta = Record<string, unknown>> = {\n items: KeepItem<TMeta>[];\n totalCount: number;\n tags: string[];\n tagCounts: Record<string, number>;\n page: number;\n pageCount: number;\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n isLoading: boolean;\n isHydrated: boolean;\n isMutating: boolean;\n error: unknown | null;\n remove: (id: string) => Promise<void>;\n removeBatch: (ids: string[]) => Promise<void>;\n removeWithUndo: (id: string) => Promise<void>;\n removeBatchWithUndo: (ids: string[]) => Promise<void>;\n updateTagsBatch: (ids: string[], tags?: string[]) => Promise<void>;\n toggleArchive: (id: string) => Promise<void>;\n archiveItem: (id: string) => Promise<void>;\n unarchiveItem: (id: string) => Promise<void>;\n archive: (id: string) => Promise<void>;\n unarchive: (id: string) => Promise<void>;\n togglePin: (id: string) => Promise<void>;\n moveToCollection: (id: string, collectionId?: string) => Promise<void>;\n addTagsBatch: (ids: string[], tags: string[]) => Promise<void>;\n removeTagsBatch: (ids: string[], tags: string[]) => Promise<void>;\n reorder: (orderedIds: string[]) => Promise<void>;\n move: (id: string, targetIndex: number) => Promise<void>;\n clear: () => Promise<void>;\n refresh: () => Promise<void>;\n revalidate: (\n revalidator: KeepItemRevalidator<TMeta>,\n options?: RevalidateKeepItemsOptions<TMeta>,\n ) => Promise<KeepItemRevalidationSummary<TMeta>>;\n};\n\nexport function useKeepList<TMeta = Record<string, unknown>>(\n query: KeepListQuery<TMeta> = {},\n): UseKeepListResult<TMeta> {\n const { store, actions } = useKeepStore<TMeta>();\n const {\n archiveScope,\n archived,\n collectionId,\n filter,\n pagination,\n pinnedFirst,\n savedBetween,\n search,\n sort,\n tags,\n targetType,\n } = query;\n const queryOptions = useMemo<KeepListQuery<TMeta>>(\n () => ({\n archiveScope,\n archived,\n collectionId,\n filter,\n pagination,\n pinnedFirst,\n savedBetween,\n search,\n sort,\n tags,\n targetType,\n }),\n [\n archiveScope,\n archived,\n collectionId,\n filter,\n pagination,\n pinnedFirst,\n savedBetween,\n search,\n sort,\n tags,\n targetType,\n ],\n );\n const selector = useMemo(() => {\n let previousResult: QueryKeepItemsResult<TMeta> | undefined;\n return (state: { items: KeepItem<TMeta>[] }) => {\n const next = queryKeepItems(state.items, queryOptions);\n if (previousResult && sameQueryResult(previousResult, next)) return previousResult;\n previousResult = next;\n return previousResult;\n };\n }, [queryOptions]);\n const result = useKeepStoreSelector(store, selector);\n const tagsSelector = useMemo(() => {\n let previous: string[] | undefined;\n return (state: { items: KeepItem<TMeta>[] }) => {\n const next = [...new Set(state.items.flatMap((item) => item.tags ?? []))].sort();\n if (previous?.length === next.length && previous.every((tag, index) => tag === next[index])) return previous;\n previous = next;\n return next;\n };\n }, []);\n const isLoading = useKeepStoreSelector(\n store,\n useCallback((state) => state.isLoading, []),\n );\n const isHydrated = useKeepStoreSelector(\n store,\n useCallback((state) => state.isHydrated, []),\n );\n const isMutating = useKeepStoreSelector(\n store,\n useCallback((state) => state.isMutating, []),\n );\n const error = useKeepStoreSelector(\n store,\n useCallback((state) => state.error, []),\n );\n const allTags = useKeepStoreSelector(store, tagsSelector);\n const remove = useCallback((id: string) => actions.removeItem(id), [actions]);\n const removeBatch = useCallback((ids: string[]) => actions.removeItems(ids), [actions]);\n const removeWithUndo = useCallback((id: string) => actions.removeItemWithUndo(id), [actions]);\n const removeBatchWithUndo = useCallback((ids: string[]) => actions.removeItemsWithUndo(ids), [actions]);\n const updateTagsBatch = useCallback(\n (ids: string[], nextTags?: string[]) => actions.updateTagsBatch(ids, nextTags),\n [actions],\n );\n const addTagsBatch = useCallback(\n (ids: string[], nextTags: string[]) => actions.addTagsBatch(ids, nextTags),\n [actions],\n );\n const removeTagsBatch = useCallback(\n (ids: string[], nextTags: string[]) => actions.removeTagsBatch(ids, nextTags),\n [actions],\n );\n const toggleArchive = useCallback((id: string) => actions.toggleArchive(id), [actions]);\n const archive = useCallback((id: string) => actions.archiveItem(id), [actions]);\n const unarchive = useCallback((id: string) => actions.unarchiveItem(id), [actions]);\n const togglePin = useCallback((id: string) => actions.togglePin(id), [actions]);\n const moveToCollection = useCallback(\n (id: string, collectionId?: string) => actions.moveToCollection(id, collectionId),\n [actions],\n );\n\n return {\n items: result.items,\n totalCount: result.totalCount,\n tags: allTags,\n tagCounts: result.tagCounts,\n page: result.page,\n pageCount: result.pageCount,\n hasNextPage: result.hasNextPage,\n hasPreviousPage: result.hasPreviousPage,\n isLoading,\n isHydrated,\n isMutating,\n error,\n remove,\n removeBatch,\n removeWithUndo,\n removeBatchWithUndo,\n updateTagsBatch,\n addTagsBatch,\n removeTagsBatch,\n toggleArchive,\n archiveItem: archive,\n unarchiveItem: unarchive,\n archive,\n unarchive,\n togglePin,\n moveToCollection,\n reorder: actions.reorderItems,\n move: actions.moveItem,\n clear: actions.clear,\n refresh: actions.refresh,\n revalidate: actions.revalidateItems,\n };\n}\n\nfunction sameQueryResult<TMeta>(left: QueryKeepItemsResult<TMeta>, right: QueryKeepItemsResult<TMeta>): boolean {\n return (\n left.totalCount === right.totalCount &&\n left.page === right.page &&\n left.pageCount === right.pageCount &&\n left.hasNextPage === right.hasNextPage &&\n left.hasPreviousPage === right.hasPreviousPage &&\n left.items.length === right.items.length &&\n left.items.every((item, index) => item === right.items[index]) &&\n sameCounts(left.tagCounts, right.tagCounts)\n );\n}\n\nfunction sameCounts(left: Record<string, number>, right: Record<string, number>): boolean {\n const leftEntries = Object.entries(left);\n const rightEntries = Object.entries(right);\n return (\n leftEntries.length === rightEntries.length &&\n leftEntries.every(([key, value], index) => {\n const [rightKey, rightValue] = rightEntries[index] ?? [];\n return key === rightKey && value === rightValue;\n })\n );\n}\n","import { useCallback, useMemo, useState } from \"react\";\nimport { getKeepNavigationState, type KeepNavigationState } from \"../../features/items/navigation\";\nimport { type KeepListQuery, queryKeepItems } from \"../../features/items/query\";\nimport type { KeepItem } from \"../../features/items/types\";\nimport { useKeepStore } from \"../components/KeepProvider\";\nimport { useKeepStoreSelector } from \"./useKeepStoreSelector\";\n\nexport type UseKeepNavigatorOptions<TMeta = Record<string, unknown>> = {\n currentId?: string;\n initialIndex?: number;\n query?: Omit<KeepListQuery<TMeta>, \"pagination\">;\n};\n\nexport type UseKeepNavigatorResult<TMeta = Record<string, unknown>> = KeepNavigationState<TMeta> & {\n goToNext: () => KeepItem<TMeta> | null;\n goToPrev: () => KeepItem<TMeta> | null;\n goToIndex: (index: number) => KeepItem<TMeta> | null;\n goToItem: (id: string) => KeepItem<TMeta> | null;\n};\n\n/** Derive a stable previous/current/next view and pointer actions from the provider store. */\nexport function useKeepNavigator<TMeta = Record<string, unknown>>(\n options: UseKeepNavigatorOptions<TMeta> = {},\n): UseKeepNavigatorResult<TMeta> {\n const { store } = useKeepStore<TMeta>();\n const { currentId, initialIndex = 0, query } = options;\n const [activeIndex, setActiveIndex] = useState(() => Math.max(0, Math.floor(initialIndex)));\n const queryOptions = useMemo(() => ({ ...query, pagination: undefined }), [query]);\n const selector = useMemo(() => {\n let previousSource: KeepItem<TMeta>[] | undefined;\n let previousItems: KeepItem<TMeta>[] | undefined;\n let previousPointer: string | number | undefined;\n let previousResult: KeepNavigationState<TMeta> | undefined;\n return (state: { items: KeepItem<TMeta>[] }) => {\n if (previousSource !== state.items) {\n previousSource = state.items;\n previousItems = queryKeepItems(state.items, queryOptions).items;\n previousResult = undefined;\n }\n const items = previousItems ?? [];\n const pointer = currentId ?? activeIndex;\n if (previousResult && previousPointer === pointer) return previousResult;\n previousPointer = pointer;\n previousResult = getKeepNavigationState(items, pointer);\n return previousResult;\n };\n }, [activeIndex, currentId, queryOptions]);\n const navigation = useKeepStoreSelector(store, selector);\n\n const goToIndex = useCallback(\n (index: number) => {\n const item = navigation.items[index];\n if (!item) return null;\n setActiveIndex(index);\n return item;\n },\n [navigation.items],\n );\n const goToNext = useCallback(() => {\n if (!navigation.nextItem) return null;\n setActiveIndex(navigation.currentIndex + 1);\n return navigation.nextItem;\n }, [navigation.currentIndex, navigation.nextItem]);\n const goToPrev = useCallback(() => {\n if (!navigation.prevItem) return null;\n setActiveIndex(navigation.currentIndex - 1);\n return navigation.prevItem;\n }, [navigation.currentIndex, navigation.prevItem]);\n const goToItem = useCallback(\n (id: string) => {\n const index = navigation.items.findIndex((item) => item.id === id);\n return index < 0 ? null : goToIndex(index);\n },\n [goToIndex, navigation.items],\n );\n\n return { ...navigation, goToNext, goToPrev, goToIndex, goToItem };\n}\n","import { useEffect } from \"react\";\nimport type { KeepItemInput } from \"../../features/items/types\";\nimport { useKeepItem } from \"./useKeepItem\";\n\nexport type KeepShortcutModifier = \"meta\" | \"ctrl\" | \"alt\" | \"shift\";\n\nexport type KeepShortcutOptions<TMeta = Record<string, unknown>> = {\n key: string;\n modifier?: KeepShortcutModifier;\n item?: KeepItemInput<TMeta>;\n action?: \"toggle\" | \"save\" | \"remove\";\n enabled?: boolean;\n preventDefault?: boolean;\n allowInEditable?: boolean;\n onTrigger?: (event: KeyboardEvent) => void | Promise<void>;\n onError?: (error: unknown) => void;\n};\n\n/** Bind a keyboard shortcut to a Keep action or an arbitrary command. */\nexport function useKeepShortcut<TMeta = Record<string, unknown>>(options: KeepShortcutOptions<TMeta>): void {\n const item = useKeepItem(options.item);\n const {\n action = \"toggle\",\n allowInEditable = false,\n enabled = true,\n key,\n modifier,\n onError,\n onTrigger,\n preventDefault = true,\n } = options;\n\n useEffect(() => {\n if (!enabled) return;\n const handleKeyDown = (event: KeyboardEvent) => {\n if (!allowInEditable && isEditableTarget(event.target)) return;\n if (!matchesShortcut(event, key, modifier)) return;\n if (preventDefault) event.preventDefault();\n const run = onTrigger\n ? onTrigger(event)\n : options.item\n ? action === \"save\"\n ? item.save()\n : action === \"remove\"\n ? item.remove()\n : item.toggle()\n : undefined;\n if (run) void Promise.resolve(run).catch((error) => onError?.(error));\n };\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [\n action,\n allowInEditable,\n enabled,\n item.remove,\n item.save,\n item.toggle,\n key,\n modifier,\n onError,\n onTrigger,\n options.item,\n preventDefault,\n ]);\n}\n\nfunction matchesShortcut(event: KeyboardEvent, key: string, modifier?: KeepShortcutModifier): boolean {\n if (event.key.toLocaleLowerCase() !== key.toLocaleLowerCase()) return false;\n const modifiers = {\n meta: event.metaKey,\n ctrl: event.ctrlKey,\n alt: event.altKey,\n shift: event.shiftKey,\n };\n if (modifier ? !modifiers[modifier] : Object.values(modifiers).some(Boolean)) return false;\n return Object.entries(modifiers).every(([name, pressed]) => name === modifier || !pressed);\n}\n\nfunction isEditableTarget(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n return (\n target.isContentEditable ||\n target.tagName === \"INPUT\" ||\n target.tagName === \"TEXTAREA\" ||\n target.tagName === \"SELECT\"\n );\n}\n","import type { ComponentType } from \"react\";\nimport type { KeepListQuery } from \"../features/items/query\";\nimport type { KeepItemInput } from \"../features/items/types\";\nimport { KeepButton, type KeepButtonProps } from \"./components/KeepButton\";\nimport { KeepProvider, type KeepProviderProps, useKeepContext } from \"./components/KeepProvider\";\nimport { type UseKeepCollectionsResult, useKeepCollections } from \"./hooks/useKeepCollections\";\nimport { type UseKeepItemResult, useKeepItem } from \"./hooks/useKeepItem\";\nimport { type UseKeepListResult, useKeepList } from \"./hooks/useKeepList\";\nimport { type UseKeepNavigatorOptions, type UseKeepNavigatorResult, useKeepNavigator } from \"./hooks/useKeepNavigator\";\nimport { type KeepShortcutOptions, useKeepShortcut } from \"./hooks/useKeepShortcut\";\n\nexport type CreateKeepKitOptions<TMeta = Record<string, unknown>> = Omit<KeepProviderProps<TMeta>, \"children\">;\n\nexport type KeepKit<TMeta> = {\n Provider: ComponentType<KeepProviderProps<TMeta>>;\n Button: ComponentType<KeepButtonProps<TMeta>>;\n useContext: () => ReturnType<typeof useKeepContext<TMeta>>;\n useItem: (item?: KeepItemInput<TMeta>) => UseKeepItemResult<TMeta>;\n useCollections: (options?: { targetType?: string; orderBy?: \"name\" | \"count\" }) => UseKeepCollectionsResult;\n useList: (query?: KeepListQuery<TMeta>) => UseKeepListResult<TMeta>;\n useNavigator: (options?: UseKeepNavigatorOptions<TMeta>) => UseKeepNavigatorResult<TMeta>;\n useShortcut: (options: KeepShortcutOptions<TMeta>) => void;\n};\n\n/** Create an app-specific, fully typed set of KeepKit components and hooks. */\nexport function createKeepKit<TMeta = Record<string, unknown>>(\n options: CreateKeepKitOptions<TMeta> = {},\n): KeepKit<TMeta> {\n return {\n Provider: (props) => <KeepProvider<TMeta> {...options} {...props} />,\n Button: (props) => <KeepButton<TMeta> {...props} />,\n useContext: () => useKeepContext<TMeta>(),\n useItem: (item) => useKeepItem<TMeta>(item),\n useCollections: (collectionsOptions) => useKeepCollections<TMeta>(collectionsOptions),\n useList: (query) => useKeepList<TMeta>(query),\n useNavigator: (navigatorOptions) => useKeepNavigator<TMeta>(navigatorOptions),\n useShortcut: (shortcutOptions) => useKeepShortcut<TMeta>(shortcutOptions),\n };\n}\n"],"mappings":"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;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU;AAAA,IACd,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA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","names":["useCallback","item","refresh","useCallback","useRef","useSyncExternalStore","useCallback","jsx","useMemo","useMemo","useCallback","useMemo","useMemo","useCallback","collectionId","useCallback","useMemo","useMemo","useCallback","useEffect","useEffect","jsx"]}
1
+ {"version":3,"sources":["../src/react/components/KeepButton.tsx","../src/react/hooks/useKeepItem.ts","../src/react/components/KeepProvider.tsx","../src/react/components/KeepErrorBoundary.tsx","../src/react/hooks/useKeepStoreSelector.ts","../src/react/hooks/useKeepCollections.ts","../src/react/hooks/useKeepList.ts","../src/react/hooks/useKeepNavigator.ts","../src/react/hooks/useKeepShortcut.ts","../src/react/createKeepKit.tsx"],"sourcesContent":["import {\n type ButtonHTMLAttributes,\n Children,\n cloneElement,\n type HTMLAttributes,\n isValidElement,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n type RefCallback,\n} from \"react\";\nimport type { KeepItemInput } from \"../../features/items/types\";\nimport { useKeepItem } from \"../hooks/useKeepItem\";\n\nexport type KeepButtonItem<TMeta = Record<string, unknown>> = KeepItemInput<TMeta>;\n\ntype KeepButtonSharedProps<TMeta> = {\n item: KeepButtonItem<TMeta>;\n children?: ReactNode | ((state: KeepButtonState<TMeta>) => ReactNode);\n savedLabel?: ReactNode;\n unsavedLabel?: ReactNode;\n savedAriaLabel?: string;\n unsavedAriaLabel?: string;\n getAriaLabel?: (state: KeepButtonState<TMeta>) => string;\n disabled?: boolean;\n onToggleError?: (error: unknown) => void;\n ref?: Ref<HTMLElement> | { readonly current: unknown };\n};\n\nexport type KeepButtonProps<TMeta = Record<string, unknown>> = KeepButtonSharedProps<TMeta> &\n (\n | (Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"children\" | \"onClick\" | \"aria-pressed\"> & {\n asChild?: false;\n onClick?: (event: MouseEvent<HTMLButtonElement>) => void;\n })\n | (Omit<HTMLAttributes<HTMLElement>, \"children\" | \"onClick\" | \"aria-pressed\"> & {\n asChild: true;\n children: ReactElement | ((state: KeepButtonState<TMeta>) => ReactElement);\n onClick?: (event: MouseEvent<HTMLElement>) => void;\n })\n );\n\nexport type KeepButtonState<TMeta = Record<string, unknown>> = {\n item: ReturnType<typeof useKeepItem<TMeta>>[\"item\"];\n isSaved: boolean;\n isLoading: boolean;\n isMutating: boolean;\n error: unknown | null;\n save: () => Promise<void>;\n remove: () => Promise<void>;\n toggle: () => Promise<void>;\n updateNote: (note?: string) => Promise<void>;\n updateTags: (tags?: string[]) => Promise<void>;\n};\n\n/** A style-free accessible save toggle. Consumers provide all visual styling. */\nexport function KeepButton<TMeta = Record<string, unknown>>({\n item,\n children,\n savedLabel = \"Saved\",\n unsavedLabel = \"Save\",\n savedAriaLabel,\n unsavedAriaLabel,\n getAriaLabel,\n asChild = false,\n onToggleError,\n onClick,\n disabled,\n ref: providedRef,\n ...buttonProps\n}: KeepButtonProps<TMeta>) {\n const state = useKeepItem(item);\n const { isSaved, toggle } = state;\n const isDisabled = disabled ?? state.isMutating;\n\n async function handleClick(event: MouseEvent<HTMLElement>) {\n if (isDisabled) return;\n if (asChild) {\n (onClick as ((event: MouseEvent<HTMLElement>) => void) | undefined)?.(event);\n } else {\n (onClick as ((event: MouseEvent<HTMLButtonElement>) => void) | undefined)?.(\n event as MouseEvent<HTMLButtonElement>,\n );\n }\n if (event.defaultPrevented) return;\n try {\n await toggle();\n } catch (error) {\n onToggleError?.(error);\n }\n }\n\n const content =\n typeof children === \"function\" ? children(state) : (children ?? (isSaved ? savedLabel : unsavedLabel));\n function handleElementClick(event: MouseEvent<HTMLElement>) {\n if (isDisabled) return;\n if (asChild && isValidElement<{ onClick?: (event: MouseEvent<HTMLElement>) => void }>(content)) {\n content.props.onClick?.(event);\n }\n if (!event.defaultPrevented) void handleClick(event);\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLElement>) {\n if (asChild && isValidElement<{ onKeyDown?: (event: KeyboardEvent<HTMLElement>) => void }>(content)) {\n content.props.onKeyDown?.(event);\n }\n (buttonProps as { onKeyDown?: (event: KeyboardEvent<HTMLElement>) => void }).onKeyDown?.(event);\n if (!event.defaultPrevented && !isDisabled && asChild && (event.key === \"Enter\" || event.key === \" \")) {\n void handleClick(event as unknown as MouseEvent<HTMLElement>);\n event.preventDefault();\n }\n }\n\n const child = asChild ? Children.only(content) : undefined;\n if (asChild && !isValidElement(child)) {\n throw new Error(\"KeepButton with asChild requires a single React element child.\");\n }\n const childRef = asChild && isValidElement(child) ? (child.props as { ref?: Ref<HTMLElement> }).ref : undefined;\n\n const commonProps = {\n ...buttonProps,\n \"aria-pressed\": isSaved,\n \"data-state\": state.error ? \"error\" : isSaved ? \"saved\" : \"unsaved\",\n \"data-loading\": state.isLoading || state.isMutating ? \"true\" : undefined,\n \"data-disabled\": isDisabled ? \"true\" : undefined,\n \"aria-label\":\n (\"aria-label\" in buttonProps ? buttonProps[\"aria-label\"] : undefined) ??\n getAriaLabel?.(state) ??\n (isSaved ? savedAriaLabel : unsavedAriaLabel) ??\n getAccessibleLabel(isSaved, item, asChild),\n ...(asChild\n ? {\n \"aria-disabled\": isDisabled,\n role: buttonProps.role ?? \"button\",\n tabIndex: isDisabled ? -1 : (buttonProps.tabIndex ?? 0),\n }\n : { disabled: isDisabled }),\n onClick: handleElementClick,\n onKeyDown: handleKeyDown,\n ...(asChild ? { ref: composeRefs(childRef, providedRef) } : {}),\n };\n\n if (asChild) {\n return cloneElement(child as ReactElement, commonProps);\n }\n\n return (\n <button\n {...commonProps}\n ref={providedRef as Ref<HTMLButtonElement>}\n type={\"type\" in buttonProps ? (buttonProps.type ?? \"button\") : \"button\"}\n >\n {content}\n </button>\n );\n}\n\nfunction composeRefs<T>(...refs: Array<Ref<T> | { readonly current: unknown } | null | undefined>): RefCallback<T> {\n return (value) => {\n for (const ref of refs) {\n if (typeof ref === \"function\") ref(value);\n else if (ref) (ref as { current: T | null }).current = value;\n }\n };\n}\n\nfunction getAccessibleLabel<TMeta>(isSaved: boolean, item: KeepButtonItem<TMeta>, asChild: boolean): string {\n if (!asChild) return isSaved ? \"Remove saved item\" : \"Save item\";\n const title = getMetaTitle(item.meta);\n const subject = title ? `${item.targetType ?? \"item\"}: ${title}` : (item.targetType ?? \"item\");\n return `${isSaved ? \"Remove\" : \"Save\"} ${subject}`;\n}\n\nfunction getMetaTitle<TMeta>(meta: TMeta): string | undefined {\n if (typeof meta !== \"object\" || meta === null || !(\"title\" in meta)) return undefined;\n const title = (meta as { title?: unknown }).title;\n return typeof title === \"string\" && title.trim() ? title.trim() : undefined;\n}\n","import { useCallback } from \"react\";\nimport type { KeepItemMetadataRefresher } from \"../../features/items/revalidation\";\nimport type { KeepItem, KeepItemInput } from \"../../features/items/types\";\nimport { useKeepStore } from \"../components/KeepProvider\";\nimport { useKeepStoreSelector } from \"./useKeepStoreSelector\";\n\nexport type UseKeepItemResult<TMeta = Record<string, unknown>> = {\n item: KeepItem<TMeta> | undefined;\n isSaved: boolean;\n isLoading: boolean;\n isMutating: boolean;\n error: unknown | null;\n save: () => Promise<void>;\n remove: () => Promise<void>;\n removeWithUndo: () => Promise<void>;\n undo: () => Promise<void>;\n toggle: () => Promise<void>;\n updateNote: (note?: string) => Promise<void>;\n updateTags: (tags?: string[]) => Promise<void>;\n toggleArchive: () => Promise<void>;\n archiveItem: () => Promise<void>;\n unarchiveItem: () => Promise<void>;\n archive: () => Promise<void>;\n unarchive: () => Promise<void>;\n togglePin: () => Promise<void>;\n moveToCollection: (collectionId?: string) => Promise<void>;\n refreshMetadata: (refresh: KeepItemMetadataRefresher<TMeta>) => Promise<void>;\n};\n\n/** Read and mutate one saved item from its complete minimal input description. */\nexport function useKeepItem<TMeta = Record<string, unknown>>(input?: KeepItemInput<TMeta>): UseKeepItemResult<TMeta> {\n const { store, actions } = useKeepStore<TMeta>();\n const id = input?.id ?? \"\";\n const item = useKeepStoreSelector(\n store,\n useCallback((state) => state.items.find((current) => current.id === id), [id]),\n );\n const isLoading = useKeepStoreSelector(\n store,\n useCallback((state) => state.isLoading, []),\n );\n const isMutating = useKeepStoreSelector(\n store,\n useCallback((state) => state.isMutating, []),\n );\n const error = useKeepStoreSelector(\n store,\n useCallback((state) => state.error, []),\n );\n const currentOrder = item?.order;\n\n const save = useCallback(async () => {\n if (!input) throw new Error(\"An item input is required to save an item.\");\n const now = Date.now();\n await actions.saveItem({\n ...input,\n ...(currentOrder === undefined ? {} : { order: currentOrder }),\n savedAt: item?.savedAt ?? now,\n updatedAt: now,\n });\n }, [actions, currentOrder, input, item?.savedAt]);\n\n const remove = useCallback(() => actions.removeItem(id), [actions, id]);\n const removeWithUndo = useCallback(() => actions.removeItemWithUndo(id), [actions, id]);\n const toggle = useCallback(() => (item ? remove() : save()), [item, remove, save]);\n const updateNote = useCallback((note?: string) => actions.updateNote(id, note), [actions, id]);\n const updateTags = useCallback((tags?: string[]) => actions.updateTags(id, tags), [actions, id]);\n const toggleArchive = useCallback(() => actions.toggleArchive(id), [actions, id]);\n const archive = useCallback(() => actions.archiveItem(id), [actions, id]);\n const unarchive = useCallback(() => actions.unarchiveItem(id), [actions, id]);\n const togglePin = useCallback(() => actions.togglePin(id), [actions, id]);\n const moveToCollection = useCallback(\n (collectionId?: string) => actions.moveToCollection(id, collectionId),\n [actions, id],\n );\n const refreshMetadata = useCallback(\n (refresh: KeepItemMetadataRefresher<TMeta>) => actions.refreshItemMetadata(id, refresh),\n [actions, id],\n );\n\n return {\n item,\n isSaved: Boolean(item),\n isLoading,\n isMutating,\n error,\n save,\n remove,\n removeWithUndo,\n undo: actions.undoLastRemoval,\n toggle,\n updateNote,\n updateTags,\n toggleArchive,\n archiveItem: archive,\n unarchiveItem: unarchive,\n archive,\n unarchive,\n togglePin,\n moveToCollection,\n refreshMetadata,\n };\n}\n","import {\n createContext,\n type PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useSyncExternalStore,\n} from \"react\";\nimport { moveKeepItem, orderKeepItems, reorderKeepItems } from \"../../features/items/navigation\";\nimport type { KeepAutoRevalidationOptions, KeepItemResolver } from \"../../features/items/revalidation\";\nimport {\n type KeepItemMetadataRefresher,\n type KeepItemRevalidationSummary,\n type KeepItemRevalidator,\n type RevalidateKeepItemsOptions,\n revalidateKeepItems,\n} from \"../../features/items/revalidation\";\nimport type {\n KeepAction,\n KeepChangeContext,\n KeepErrorContext,\n KeepErrorHandler,\n KeepEventHandlers,\n KeepInvalidItemPolicy,\n KeepItem,\n KeepPlugin,\n KeepSchema,\n KeepSyncState,\n KeepUndoState,\n StorageAdapter,\n SyncCapableStorageAdapter,\n} from \"../../features/items/types\";\nimport { normalizeKeepTags } from \"../../features/items/types\";\nimport {\n exportItems,\n type ImportItemsOptions,\n type ImportItemsResult,\n importItems,\n} from \"../../features/persistence/backup\";\nimport { parseKeepMeta } from \"../../features/persistence/schema\";\nimport { type KeepCollectionMeta, KeepStore, type KeepStoreActions } from \"../../features/store/store\";\nimport { createBrowserStorageAdapter } from \"../../storage\";\nimport { KeepErrorBoundary, type KeepErrorBoundaryProps } from \"./KeepErrorBoundary\";\n\nexport type KeepContextValue<TMeta = Record<string, unknown>> = {\n items: KeepItem<TMeta>[];\n collections: Record<string, KeepCollectionMeta>;\n isLoading: boolean;\n isHydrated: boolean;\n isMutating: boolean;\n error: unknown | null;\n lastChange?: KeepChangeContext<TMeta>;\n syncState: KeepSyncState<TMeta>;\n undo: KeepUndoState;\n saveItem: (item: KeepItem<TMeta>) => Promise<void>;\n updateNote: (id: string, note?: string) => Promise<void>;\n updateTags: (id: string, tags?: string[]) => Promise<void>;\n toggleArchive: (id: string) => Promise<void>;\n archiveItem: (id: string) => Promise<void>;\n unarchiveItem: (id: string) => Promise<void>;\n togglePin: (id: string) => Promise<void>;\n moveToCollection: (id: string, collectionId?: string) => Promise<void>;\n createCollection: (id: string, name: string) => Promise<void>;\n renameCollection: (id: string, name: string) => Promise<void>;\n removeCollection: (id: string) => Promise<void>;\n updateTagsBatch: (ids: string[], tags?: string[]) => Promise<void>;\n addTagsBatch: (ids: string[], tags: string[]) => Promise<void>;\n removeTagsBatch: (ids: string[], tags: string[]) => Promise<void>;\n removeItem: (id: string) => Promise<void>;\n removeItems: (ids: string[]) => Promise<void>;\n removeItemWithUndo: (id: string) => Promise<void>;\n removeItemsWithUndo: (ids: string[]) => Promise<void>;\n undoLastRemoval: () => Promise<void>;\n clear: () => Promise<void>;\n refresh: () => Promise<void>;\n flushSync: () => Promise<void>;\n resolveSyncConflict: (id: string, resolution: \"local\" | \"remote\" | \"manual\", item?: KeepItem<TMeta>) => Promise<void>;\n refreshItemMetadata: (id: string, refresh: KeepItemMetadataRefresher<TMeta>) => Promise<void>;\n revalidateItems: (\n revalidator?: KeepItemRevalidator<TMeta>,\n options?: RevalidateKeepItemsOptions<TMeta>,\n ) => Promise<KeepItemRevalidationSummary<TMeta>>;\n reorderItems: (orderedIds: string[]) => Promise<void>;\n moveItem: (id: string, targetIndex: number) => Promise<void>;\n exportBackup: () => Promise<string>;\n importBackup: (\n data: string,\n options?: Pick<ImportItemsOptions<TMeta>, \"mode\" | \"invalidItemPolicy\" | \"onInvalidItem\">,\n ) => Promise<ImportItemsResult<TMeta>>;\n};\n\nexport type KeepProviderProps<TMeta = Record<string, unknown>> = PropsWithChildren<\n KeepEventHandlers<TMeta> & {\n storage?: StorageAdapter<TMeta>;\n /**\n * Optional server-provided snapshot rendered before the client adapter\n * finishes hydrating. The adapter remains the source of truth after the\n * first refresh.\n */\n initialItems?: KeepItem<TMeta>[];\n plugins?: KeepPlugin<TMeta>[];\n schemaVersion?: number;\n schema?: KeepSchema<TMeta>;\n invalidItemPolicy?: KeepInvalidItemPolicy;\n onInvalidItem?: (error: unknown, item: KeepItem<unknown>) => void;\n migrateMeta?: (\n meta: unknown,\n fromVersion: number,\n toVersion: number,\n item: KeepItem<TMeta>,\n ) => TMeta | Promise<TMeta>;\n /** Render this content when a descendant or provider render unexpectedly throws. */\n fallback?: KeepErrorBoundaryProps[\"fallback\"];\n onBoundaryError?: KeepErrorBoundaryProps[\"onError\"];\n boundaryResetKey?: unknown;\n validateItem?: KeepItemRevalidator<TMeta>;\n resolveItem?: KeepItemResolver<TMeta>;\n autoRevalidation?: KeepAutoRevalidationOptions<TMeta>;\n undoTimeoutMs?: number;\n }\n>;\n\nconst defaultStorage = createBrowserStorageAdapter();\nconst KeepContext = createContext<KeepContextValue<unknown> | null>(null);\nconst KeepStoreContext = createContext<KeepStoreAccess<unknown> | null>(null);\n\ntype KeepStoreAccess<TMeta> = {\n store: KeepStore<TMeta>;\n actions: KeepStoreActions<TMeta>;\n};\n\ntype MutationPlan<TMeta> = {\n next: KeepItem<TMeta>[];\n persist: () => Promise<void>;\n onSuccess?: () => void;\n pluginContext?: {\n action: KeepAction;\n id?: string;\n item?: KeepItem<TMeta>;\n items?: KeepItem<TMeta>[];\n };\n};\n\nexport function KeepProvider<TMeta = Record<string, unknown>>({\n storage = defaultStorage as StorageAdapter<TMeta>,\n initialItems,\n onSave,\n onRemove,\n onNoteUpdate,\n onTagsUpdate,\n onChange,\n onUndo,\n onError,\n plugins = [],\n schemaVersion,\n schema,\n invalidItemPolicy = \"error\",\n onInvalidItem,\n migrateMeta,\n fallback,\n onBoundaryError,\n boundaryResetKey,\n validateItem,\n resolveItem,\n autoRevalidation,\n undoTimeoutMs,\n children,\n}: KeepProviderProps<TMeta>) {\n const content = (\n <KeepProviderContent<TMeta>\n storage={storage}\n initialItems={initialItems}\n onSave={onSave}\n onRemove={onRemove}\n onNoteUpdate={onNoteUpdate}\n onTagsUpdate={onTagsUpdate}\n onChange={onChange}\n onUndo={onUndo}\n onError={onError}\n plugins={plugins}\n schemaVersion={schemaVersion}\n schema={schema}\n invalidItemPolicy={invalidItemPolicy}\n onInvalidItem={onInvalidItem}\n migrateMeta={migrateMeta}\n validateItem={validateItem}\n resolveItem={resolveItem}\n autoRevalidation={autoRevalidation}\n undoTimeoutMs={undoTimeoutMs}\n >\n {children}\n </KeepProviderContent>\n );\n if (fallback === undefined && onBoundaryError === undefined) return content;\n return (\n <KeepErrorBoundary fallback={fallback} onError={onBoundaryError} resetKey={boundaryResetKey}>\n {content}\n </KeepErrorBoundary>\n );\n}\n\nfunction KeepProviderContent<TMeta = Record<string, unknown>>({\n storage = defaultStorage as StorageAdapter<TMeta>,\n initialItems,\n onSave,\n onRemove,\n onNoteUpdate,\n onTagsUpdate,\n onChange,\n onUndo,\n onError,\n plugins = [],\n schemaVersion,\n schema,\n invalidItemPolicy = \"error\",\n onInvalidItem,\n migrateMeta,\n validateItem,\n resolveItem,\n autoRevalidation,\n undoTimeoutMs = 5000,\n children,\n}: KeepProviderProps<TMeta>) {\n const storeRef = useRef<KeepStore<TMeta> | null>(null);\n if (!storeRef.current) {\n storeRef.current = new KeepStore<TMeta>({\n items: initialItems ? [...initialItems] : [],\n collections: {},\n isLoading: true,\n isHydrated: false,\n isMutating: false,\n error: null,\n lastChange: undefined,\n undo: { canUndo: false, ids: [] },\n });\n }\n const store = storeRef.current;\n const state = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n const { items, collections, isLoading, isHydrated, isMutating, error, lastChange, undo: storedUndo } = state;\n const undo = storedUndo ?? EMPTY_UNDO_STATE;\n const itemsRef = useRef(items);\n const pluginsRef = useRef(plugins);\n pluginsRef.current = plugins;\n const handlersRef = useRef({ onSave, onRemove, onNoteUpdate, onTagsUpdate, onChange, onUndo, onError });\n handlersRef.current = { onSave, onRemove, onNoteUpdate, onTagsUpdate, onChange, onUndo, onError };\n const migrationRef = useRef({\n schemaVersion,\n migrateMeta,\n schema,\n invalidItemPolicy,\n onInvalidItem,\n });\n migrationRef.current = { schemaVersion, migrateMeta, schema, invalidItemPolicy, onInvalidItem };\n const operationTailRef = useRef<Promise<unknown>>(Promise.resolve());\n const pendingRefreshesRef = useRef(0);\n const pendingMutationsRef = useRef(0);\n const undoRef = useRef<\n { items: KeepItem<TMeta>[]; expiresAt: number; timer?: ReturnType<typeof setTimeout> } | undefined\n >(undefined);\n const autoRevalidationRef = useRef<KeepAutoRevalidationOptions<TMeta> | undefined>(autoRevalidation);\n autoRevalidationRef.current = autoRevalidation;\n const didMountRevalidateRef = useRef(false);\n const syncStorage = isSyncCapableStorage(storage) ? storage : undefined;\n const getSyncState = useCallback(() => syncStorage?.getSyncState() ?? IDLE_SYNC_STATE, [syncStorage]);\n const subscribeSync = useCallback(\n (listener: () => void) => syncStorage?.subscribeSync(listener) ?? (() => undefined),\n [syncStorage],\n );\n const syncState = useSyncExternalStore(subscribeSync, getSyncState, getSyncState);\n\n const reportError = useCallback(\n (cause: unknown, context: KeepErrorContext) => {\n store.setState({ error: cause });\n handlersRef.current.onError?.(cause, context);\n for (const plugin of pluginsRef.current) plugin.onError?.(cause, context);\n },\n [store],\n );\n\n const setItems = useCallback(\n (next: KeepItem<TMeta>[]) => {\n itemsRef.current = next;\n store.setState({ items: next });\n },\n [store],\n );\n\n const runBeforePlugins = useCallback(async (context: NonNullable<MutationPlan<TMeta>[\"pluginContext\"]>) => {\n for (const plugin of pluginsRef.current) await plugin.before?.(context);\n return context;\n }, []);\n\n const runAfterPlugins = useCallback(async (context: NonNullable<MutationPlan<TMeta>[\"pluginContext\"]>) => {\n for (const plugin of pluginsRef.current) await plugin.after?.(context);\n }, []);\n\n const enqueueOperation = useCallback(<T,>(operation: () => Promise<T>): Promise<T> => {\n const run = operationTailRef.current.then(operation, operation);\n operationTailRef.current = run.then(\n () => undefined,\n () => undefined,\n );\n return run;\n }, []);\n\n const refresh = useCallback(async () => {\n pendingRefreshesRef.current += 1;\n store.setState({ isLoading: true });\n\n try {\n await enqueueOperation(async () => {\n try {\n let next = await storage.getAll();\n let needsMigrationPersist = false;\n if (migrationRef.current.schemaVersion !== undefined) {\n const migrated = await Promise.all(\n next.map(async (item) => {\n const currentSchemaVersion = migrationRef.current.schemaVersion as number;\n if (item.schemaVersion === currentSchemaVersion) return item;\n const meta = migrationRef.current.migrateMeta\n ? await migrationRef.current.migrateMeta(\n item.meta,\n item.schemaVersion ?? 0,\n currentSchemaVersion,\n item,\n )\n : item.meta;\n return { ...item, meta, schemaVersion: currentSchemaVersion };\n }),\n );\n if (migrated.some((item, index) => item !== next[index])) {\n next = migrated;\n needsMigrationPersist = true;\n }\n }\n if (migrationRef.current.schema) {\n const validated: KeepItem<TMeta>[] = [];\n for (const item of next) {\n try {\n validated.push(await parseKeepMetaItem(item, migrationRef.current.schema));\n } catch (cause) {\n migrationRef.current.onInvalidItem?.(cause, item);\n if (migrationRef.current.invalidItemPolicy === \"drop\") continue;\n throw cause;\n }\n }\n next = validated;\n }\n if (needsMigrationPersist) {\n if (storage.setMany) await storage.setMany(next);\n else for (const item of next) await storage.set(item);\n }\n setItems(next);\n store.setState({ error: null });\n } catch (cause) {\n reportError(cause, { action: \"refresh\" });\n }\n });\n } finally {\n pendingRefreshesRef.current -= 1;\n if (pendingRefreshesRef.current === 0) store.setState({ isLoading: false });\n store.setState({ isHydrated: true });\n }\n }, [enqueueOperation, reportError, setItems, storage, store]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n useEffect(() => {\n if (!storage.subscribe) return;\n return storage.subscribe(() => void refresh());\n }, [refresh, storage]);\n\n useEffect(() => {\n if (!isScopeAwareStorage(storage)) return;\n return storage.subscribeScope(() => {\n undoRef.current?.timer && clearTimeout(undoRef.current.timer);\n undoRef.current = undefined;\n itemsRef.current = [];\n store.setState({ items: [], isHydrated: false, isLoading: true, error: null, undo: EMPTY_UNDO_STATE });\n void refresh();\n });\n }, [refresh, storage, store]);\n\n const runMutation = useCallback(\n (\n action: Exclude<KeepAction, \"refresh\">,\n id: string | undefined,\n createPlan: (previous: KeepItem<TMeta>[]) => MutationPlan<TMeta> | undefined,\n ): Promise<void> => {\n pendingMutationsRef.current += 1;\n store.setState({ isMutating: true });\n\n const run = enqueueOperation(async () => {\n const previous = itemsRef.current;\n const plan = createPlan(previous);\n if (!plan) return;\n\n try {\n if (plan.pluginContext) await runBeforePlugins(plan.pluginContext);\n setItems(plan.next);\n store.setState({ error: null });\n await plan.persist();\n plan.onSuccess?.();\n if (plan.pluginContext) await runAfterPlugins(plan.pluginContext);\n if (plan.pluginContext) {\n const change: KeepChangeContext<TMeta> = { ...plan.pluginContext, phase: \"local\" };\n store.setState({ lastChange: change });\n void Promise.resolve(handlersRef.current.onChange?.(change)).catch((cause) =>\n reportError(cause, { action, id }),\n );\n }\n } catch (cause) {\n setItems(previous);\n reportError(cause, { action, id });\n throw cause;\n }\n });\n\n return run.finally(() => {\n pendingMutationsRef.current -= 1;\n if (pendingMutationsRef.current === 0) store.setState({ isMutating: false });\n });\n },\n [enqueueOperation, reportError, runAfterPlugins, runBeforePlugins, setItems, store],\n );\n\n const saveItem = useCallback(\n async (item: KeepItem<TMeta>) => {\n let normalizedItem: KeepItem<TMeta>;\n try {\n const meta = migrationRef.current.schema\n ? await parseKeepMeta(migrationRef.current.schema, item.meta)\n : item.meta;\n normalizedItem = {\n ...item,\n meta,\n tags: normalizeKeepTags(item.tags),\n ...(migrationRef.current.schemaVersion === undefined\n ? {}\n : { schemaVersion: migrationRef.current.schemaVersion }),\n };\n } catch (cause) {\n reportError(cause, { action: \"save\", id: item.id });\n throw cause;\n }\n await runMutation(\"save\", normalizedItem.id, (previous) => {\n const current = previous.find((item) => item.id === normalizedItem.id);\n const hasCustomOrder = previous.some((item) => item.order !== undefined);\n const nextItem = {\n ...normalizedItem,\n ...(normalizedItem.order === undefined && current?.order !== undefined ? { order: current.order } : {}),\n ...(normalizedItem.order === undefined && !current && hasCustomOrder\n ? { order: previous.reduce((max, item) => Math.max(max, item.order ?? -1), -1) + 1 }\n : {}),\n };\n const withoutCurrent = previous.filter((item) => item.id !== nextItem.id);\n const next = hasCustomOrder\n ? reorderKeepItems(\n [...withoutCurrent, nextItem],\n orderKeepItems(previous).map((item) => (item.id === nextItem.id ? nextItem.id : item.id)),\n )\n : [...withoutCurrent, nextItem].sort((a, b) => b.updatedAt - a.updatedAt);\n return {\n next,\n persist: () => storage.set(nextItem),\n onSuccess: () => handlersRef.current.onSave?.(nextItem),\n pluginContext: { action: \"save\", id: nextItem.id, item: nextItem },\n };\n });\n },\n [reportError, runMutation, storage],\n );\n\n const reorderItems = useCallback(\n async (orderedIds: string[]) => {\n await runMutation(\"reorder\", undefined, (previous) => {\n const next = reorderKeepItems(previous, orderedIds);\n const changedItems = next.filter(\n (item, index) => item.id !== previous[index]?.id || item.order !== previous[index]?.order,\n );\n return {\n next,\n persist: async () => {\n try {\n if (storage.setMany) await storage.setMany(changedItems);\n else for (const item of changedItems) await storage.set(item);\n } catch (cause) {\n await restoreItems(storage, previous);\n throw cause;\n }\n },\n pluginContext: { action: \"reorder\", items: changedItems },\n };\n });\n },\n [runMutation, storage],\n );\n\n const moveItem = useCallback(\n async (id: string, targetIndex: number) => {\n await runMutation(\"reorder\", id, (previous) => {\n const next = moveKeepItem(previous, id, targetIndex);\n const changedItems = next.filter(\n (item, index) => item.id !== previous[index]?.id || item.order !== previous[index]?.order,\n );\n return {\n next,\n persist: async () => {\n try {\n if (storage.setMany) await storage.setMany(changedItems);\n else for (const item of changedItems) await storage.set(item);\n } catch (cause) {\n await restoreItems(storage, previous);\n throw cause;\n }\n },\n pluginContext: { action: \"reorder\", id, items: changedItems },\n };\n });\n },\n [runMutation, storage],\n );\n\n const updateNote = useCallback(\n async (id: string, note?: string) => {\n const nextNote = note?.trim() || undefined;\n await runMutation(\"updateNote\", id, (previous) => {\n const current = previous.find((item) => item.id === id);\n if (!current) return undefined;\n const next = { ...current, note: nextNote, updatedAt: Date.now() };\n return {\n next: previous.map((item) => (item.id === id ? next : item)),\n persist: () => storage.set(next),\n onSuccess: () => handlersRef.current.onNoteUpdate?.(id, nextNote),\n pluginContext: { action: \"updateNote\", id, item: next },\n };\n });\n },\n [runMutation, storage],\n );\n\n const updateTags = useCallback(\n async (id: string, tags?: string[]) => {\n const nextTags = normalizeKeepTags(tags);\n await runMutation(\"updateTags\", id, (previous) => {\n const current = previous.find((item) => item.id === id);\n if (!current) return undefined;\n const next = { ...current, tags: nextTags, updatedAt: Date.now() };\n return {\n next: previous.map((item) => (item.id === id ? next : item)),\n persist: () => storage.set(next),\n onSuccess: () => handlersRef.current.onTagsUpdate?.(id, nextTags),\n pluginContext: { action: \"updateTags\", id, item: next },\n };\n });\n },\n [runMutation, storage],\n );\n\n const setArchive = useCallback(\n async (id: string, archived: boolean) => {\n await runMutation(\"archive\", id, (previous) => {\n const current = previous.find((item) => item.id === id);\n if (!current) return undefined;\n const next = { ...current, archived, updatedAt: Date.now() };\n return {\n next: previous.map((item) => (item.id === id ? next : item)),\n persist: () => storage.set(next),\n pluginContext: { action: \"archive\", id, item: next },\n };\n });\n },\n [runMutation, storage],\n );\n\n const toggleArchive = useCallback(\n (id: string) => {\n const item = itemsRef.current.find((current) => current.id === id);\n return setArchive(id, item?.archived !== true);\n },\n [setArchive],\n );\n const archiveItem = useCallback((id: string) => setArchive(id, true), [setArchive]);\n const unarchiveItem = useCallback((id: string) => setArchive(id, false), [setArchive]);\n\n const togglePin = useCallback(\n async (id: string) => {\n await runMutation(\"pin\", id, (previous) => {\n const current = previous.find((item) => item.id === id);\n if (!current) return undefined;\n const next = { ...current, pinned: current.pinned !== true, updatedAt: Date.now() };\n return {\n next: previous.map((item) => (item.id === id ? next : item)),\n persist: () => storage.set(next),\n pluginContext: { action: \"pin\", id, item: next },\n };\n });\n },\n [runMutation, storage],\n );\n\n const moveToCollection = useCallback(\n async (id: string, collectionId?: string) => {\n const nextCollectionId = collectionId?.trim() || undefined;\n await runMutation(\"collection\", id, (previous) => {\n const current = previous.find((item) => item.id === id);\n if (!current) return undefined;\n const { collectionId: _oldCollectionId, ...withoutCollection } = current;\n const next = {\n ...withoutCollection,\n ...(nextCollectionId ? { collectionId: nextCollectionId } : {}),\n updatedAt: Date.now(),\n };\n return {\n next: previous.map((item) => (item.id === id ? next : item)),\n persist: () => storage.set(next),\n pluginContext: { action: \"collection\", id, item: next },\n };\n });\n },\n [runMutation, storage],\n );\n\n const createCollection = useCallback(\n async (id: string, name: string) => {\n const trimmedId = id.trim();\n const trimmedName = name.trim();\n if (!trimmedId || !trimmedName) throw new Error(\"Collection id and name are required.\");\n const current = store.getSnapshot().collections;\n if (current[trimmedId]) throw new Error(`Collection \"${trimmedId}\" already exists.`);\n store.setState({ collections: { ...current, [trimmedId]: { name: trimmedName } } });\n },\n [store],\n );\n\n const renameCollection = useCallback(\n async (id: string, name: string) => {\n const trimmedName = name.trim();\n if (!trimmedName) throw new Error(\"Collection name is required.\");\n const current = store.getSnapshot().collections;\n if (!current[id]) throw new Error(`Collection \"${id}\" does not exist.`);\n store.setState({ collections: { ...current, [id]: { name: trimmedName } } });\n },\n [store],\n );\n\n const removeCollection = useCallback(\n async (id: string) => {\n const current = store.getSnapshot().collections;\n if (!current[id]) throw new Error(`Collection \"${id}\" does not exist.`);\n const { [id]: _removed, ...remaining } = current;\n store.setState({ collections: remaining });\n // Move all items in this collection to uncategorized.\n const affected = itemsRef.current.filter((item) => item.collectionId === id);\n if (affected.length > 0) {\n const nextItems = itemsRef.current.map((item) =>\n item.collectionId === id ? { ...item, collectionId: undefined, updatedAt: Date.now() } : item,\n );\n itemsRef.current = nextItems;\n store.setState({ items: nextItems });\n for (const item of affected) {\n const { collectionId: _, ...withoutCollection } = item;\n await storage.set({ ...withoutCollection, collectionId: undefined, updatedAt: Date.now() });\n }\n }\n },\n [storage, store],\n );\n\n const updateTagsBatch = useCallback(\n async (ids: string[], tags?: string[]) => {\n const idSet = new Set(ids);\n const nextTags = normalizeKeepTags(tags);\n await runMutation(\"updateTagsBatch\", undefined, (previous) => {\n const currentItems = previous.filter((item) => idSet.has(item.id));\n if (currentItems.length === 0) return undefined;\n const updatedItems = currentItems.map((item) => ({\n ...item,\n tags: nextTags,\n updatedAt: Date.now(),\n }));\n const updatedById = new Map(updatedItems.map((item) => [item.id, item]));\n return {\n next: previous.map((item) => updatedById.get(item.id) ?? item),\n persist: async () => {\n if (storage.setMany) {\n await storage.setMany(updatedItems);\n return;\n }\n const completed: KeepItem<TMeta>[] = [];\n try {\n for (const item of updatedItems) {\n await storage.set(item);\n completed.push(item);\n }\n } catch (cause) {\n const previousById = new Map(currentItems.map((item) => [item.id, item]));\n await Promise.allSettled(\n completed.map((item) => {\n const previousItem = previousById.get(item.id);\n return previousItem ? storage.set(previousItem) : Promise.resolve();\n }),\n );\n throw cause;\n }\n },\n onSuccess: () => {\n updatedItems.forEach((item) => {\n handlersRef.current.onTagsUpdate?.(item.id, nextTags);\n });\n },\n pluginContext: { action: \"updateTagsBatch\", items: updatedItems },\n };\n });\n },\n [runMutation, storage],\n );\n\n const addTagsBatch = useCallback(\n async (ids: string[], tags: string[]) => {\n const additions = normalizeKeepTags(tags) ?? [];\n const idSet = new Set(ids);\n const currentItems = itemsRef.current.filter((item) => idSet.has(item.id));\n await Promise.all(\n currentItems.map((item) => updateTags(item.id, normalizeKeepTags([...(item.tags ?? []), ...additions]))),\n );\n },\n [updateTags],\n );\n\n const removeTagsBatch = useCallback(\n async (ids: string[], tags: string[]) => {\n const removals = new Set(normalizeKeepTags(tags) ?? []);\n const idSet = new Set(ids);\n const currentItems = itemsRef.current.filter((item) => idSet.has(item.id));\n await Promise.all(\n currentItems.map((item) =>\n updateTags(item.id, normalizeKeepTags((item.tags ?? []).filter((tag) => !removals.has(tag)))),\n ),\n );\n },\n [updateTags],\n );\n\n const removeItem = useCallback(\n async (id: string) => {\n await runMutation(\"remove\", id, (previous) => {\n const current = previous.find((item) => item.id === id);\n if (!current) return undefined;\n return {\n next: previous.filter((item) => item.id !== id),\n persist: () => storage.remove(id),\n onSuccess: () => handlersRef.current.onRemove?.(current),\n pluginContext: { action: \"remove\", id, item: current },\n };\n });\n },\n [runMutation, storage],\n );\n\n const removeItems = useCallback(\n async (ids: string[]) => {\n const idSet = new Set(ids);\n await runMutation(\"removeBatch\", undefined, (previous) => {\n const removedItems = previous.filter((item) => idSet.has(item.id));\n if (removedItems.length === 0) return undefined;\n return {\n next: previous.filter((item) => !idSet.has(item.id)),\n persist: async () => {\n if (storage.removeMany) {\n await storage.removeMany(removedItems.map((item) => item.id));\n return;\n }\n const completed: KeepItem<TMeta>[] = [];\n try {\n for (const item of removedItems) {\n await storage.remove(item.id);\n completed.push(item);\n }\n } catch (cause) {\n await Promise.allSettled(completed.map((item) => storage.set(item)));\n throw cause;\n }\n },\n onSuccess: () => {\n removedItems.forEach((item) => {\n handlersRef.current.onRemove?.(item);\n });\n },\n pluginContext: { action: \"removeBatch\", items: removedItems },\n };\n });\n },\n [runMutation, storage],\n );\n\n const rememberUndo = useCallback(\n (removedItems: KeepItem<TMeta>[]) => {\n undoRef.current?.timer && clearTimeout(undoRef.current.timer);\n const startedAt = Date.now();\n const expiresAt = startedAt + Math.max(0, undoTimeoutMs);\n const timer = setTimeout(\n () => {\n undoRef.current = undefined;\n store.setState({ undo: { canUndo: false, ids: [] } });\n },\n Math.max(0, undoTimeoutMs),\n );\n undoRef.current = { items: removedItems, expiresAt, timer };\n store.setState({ undo: { canUndo: true, ids: removedItems.map((item) => item.id), startedAt, expiresAt } });\n },\n [store, undoTimeoutMs],\n );\n\n const removeItemWithUndo = useCallback(\n async (id: string) => {\n const item = itemsRef.current.find((current) => current.id === id);\n await removeItem(id);\n if (item) rememberUndo([item]);\n },\n [rememberUndo, removeItem],\n );\n\n const removeItemsWithUndo = useCallback(\n async (ids: string[]) => {\n const idSet = new Set(ids);\n const removedItems = itemsRef.current.filter((item) => idSet.has(item.id));\n await removeItems(ids);\n if (removedItems.length > 0) rememberUndo(removedItems);\n },\n [rememberUndo, removeItems],\n );\n\n const undoLastRemoval = useCallback(async () => {\n const pending = undoRef.current;\n if (!pending || pending.expiresAt < Date.now()) {\n undoRef.current = undefined;\n store.setState({ undo: { canUndo: false, ids: [] } });\n return;\n }\n if (pending.timer) clearTimeout(pending.timer);\n undoRef.current = undefined;\n store.setState({ undo: { canUndo: false, ids: [] } });\n await runMutation(\"undo\", undefined, (previous) => {\n const restored = new Map(pending.items.map((item) => [item.id, item]));\n const next = [...previous.filter((item) => !restored.has(item.id)), ...pending.items].sort(\n (a, b) => b.updatedAt - a.updatedAt,\n );\n return {\n next,\n persist: async () => {\n if (storage.setMany) await storage.setMany(pending.items);\n else for (const item of pending.items) await storage.set(item);\n },\n onSuccess: () => handlersRef.current.onUndo?.(pending.items),\n pluginContext: { action: \"undo\", items: pending.items },\n };\n });\n }, [runMutation, storage, store]);\n\n useEffect(() => {\n if (syncState.status !== \"error\" || !undoRef.current) return;\n void undoLastRemoval();\n }, [syncState.status, undoLastRemoval]);\n\n const clear = useCallback(\n () =>\n runMutation(\"clear\", undefined, (_previous) => ({\n next: [],\n persist: () => storage.clear(),\n pluginContext: { action: \"clear\", items: [] },\n })),\n [runMutation, storage],\n );\n\n const revalidateItems = useCallback(\n async (\n revalidator: KeepItemRevalidator<TMeta> | undefined,\n options: RevalidateKeepItemsOptions<TMeta> = {},\n ): Promise<KeepItemRevalidationSummary<TMeta>> => {\n pendingMutationsRef.current += 1;\n store.setState({ isMutating: true });\n const run = enqueueOperation(async () => {\n const previous = itemsRef.current;\n let persistenceStarted = false;\n try {\n const activeRevalidator = revalidator ?? validateItem;\n if (!activeRevalidator)\n throw new Error(\"KeepProvider.revalidateItems requires a revalidator or validateItem.\");\n const summary = await revalidateKeepItems(previous, activeRevalidator, {\n ...options,\n resolveItem: options.resolveItem ?? resolveItem,\n });\n const pluginContext = { action: \"revalidate\" as const, items: summary.updatedItems };\n await runBeforePlugins(pluginContext);\n if (summary.updatedItems.length > 0) {\n persistenceStarted = true;\n if (storage.setMany) await storage.setMany(summary.updatedItems);\n else for (const item of summary.updatedItems) await storage.set(item);\n }\n if (summary.removedIds.length > 0) {\n persistenceStarted = true;\n if (storage.removeMany) await storage.removeMany(summary.removedIds);\n else for (const id of summary.removedIds) await storage.remove(id);\n }\n setItems(summary.items);\n store.setState({ error: null });\n const removedIdSet = new Set(summary.removedIds);\n for (const result of summary.results) {\n if (removedIdSet.has(result.item.id)) handlersRef.current.onRemove?.(result.item);\n }\n await runAfterPlugins(pluginContext);\n void Promise.resolve(handlersRef.current.onChange?.({ ...pluginContext, phase: \"local\" })).catch((cause) =>\n reportError(cause, { action: \"revalidate\" }),\n );\n return summary;\n } catch (cause) {\n if (persistenceStarted) await restoreItems(storage, previous);\n setItems(previous);\n reportError(cause, { action: \"revalidate\" });\n throw cause;\n }\n });\n return run.finally(() => {\n pendingMutationsRef.current -= 1;\n if (pendingMutationsRef.current === 0) store.setState({ isMutating: false });\n });\n },\n [\n enqueueOperation,\n reportError,\n resolveItem,\n runAfterPlugins,\n runBeforePlugins,\n setItems,\n storage,\n store,\n validateItem,\n ],\n );\n\n useEffect(() => {\n const settings = autoRevalidationRef.current;\n const activeRevalidator = settings?.revalidator ?? validateItem;\n if (!settings || !activeRevalidator) return;\n const run = () =>\n void revalidateItems(activeRevalidator, { removeStatuses: settings.removeStatuses }).catch(() => undefined);\n if (isHydrated && settings.onMount !== false && !didMountRevalidateRef.current) {\n didMountRevalidateRef.current = true;\n run();\n }\n const interval = settings.intervalMs && settings.intervalMs > 0 ? setInterval(run, settings.intervalMs) : undefined;\n const onOnline = () => {\n if (settings.onReconnect !== false) run();\n };\n if (typeof window !== \"undefined\" && settings.onReconnect !== false) {\n window.addEventListener(\"online\", onOnline);\n }\n return () => {\n if (interval) clearInterval(interval);\n if (typeof window !== \"undefined\") window.removeEventListener(\"online\", onOnline);\n };\n }, [isHydrated, revalidateItems, validateItem]);\n\n const refreshItemMetadata = useCallback(\n async (id: string, refresh: KeepItemMetadataRefresher<TMeta>): Promise<void> => {\n if (!itemsRef.current.some((item) => item.id === id)) {\n throw new Error(`Cannot refresh metadata for missing item \"${id}\".`);\n }\n await revalidateItems(async (item) => {\n if (item.id !== id) return \"available\";\n return { status: \"available\", meta: await refresh(item) };\n });\n },\n [revalidateItems],\n );\n const flushSync = useCallback(() => (syncStorage ? syncStorage.flushSync() : Promise.resolve()), [syncStorage]);\n const resolveSyncConflict = useCallback(\n (id: string, resolution: \"local\" | \"remote\" | \"manual\", item?: KeepItem<TMeta>) => {\n if (!syncStorage?.resolveSyncConflict) {\n return Promise.reject(new Error(\"The configured storage does not support sync conflict resolution.\"));\n }\n return syncStorage.resolveSyncConflict(id, resolution, item);\n },\n [syncStorage],\n );\n const exportBackup = useCallback(() => exportItems(storage), [storage]);\n const importBackup = useCallback(\n async (\n data: string,\n options: Pick<ImportItemsOptions<TMeta>, \"mode\" | \"invalidItemPolicy\" | \"onInvalidItem\"> = {},\n ): Promise<ImportItemsResult<TMeta>> => {\n pendingMutationsRef.current += 1;\n store.setState({ isMutating: true });\n const run = enqueueOperation(async () => {\n try {\n const result = await importItems(storage, data, {\n ...options,\n schema: migrationRef.current.schema,\n invalidItemPolicy: options.invalidItemPolicy ?? migrationRef.current.invalidItemPolicy,\n onInvalidItem: options.onInvalidItem ?? migrationRef.current.onInvalidItem,\n });\n setItems(result.items);\n store.setState({ error: null });\n return result;\n } catch (cause) {\n reportError(cause, { action: \"import\" });\n throw cause;\n }\n });\n return run.finally(() => {\n pendingMutationsRef.current -= 1;\n if (pendingMutationsRef.current === 0) store.setState({ isMutating: false });\n });\n },\n [enqueueOperation, reportError, setItems, storage, store],\n );\n\n const value = useMemo<KeepContextValue<TMeta>>(\n () => ({\n items,\n collections,\n isLoading,\n isHydrated,\n isMutating,\n error,\n lastChange,\n syncState,\n undo,\n saveItem,\n updateNote,\n updateTags,\n toggleArchive,\n archiveItem,\n unarchiveItem,\n togglePin,\n moveToCollection,\n createCollection,\n renameCollection,\n removeCollection,\n updateTagsBatch,\n addTagsBatch,\n removeTagsBatch,\n removeItem,\n removeItems,\n removeItemWithUndo,\n removeItemsWithUndo,\n undoLastRemoval,\n clear,\n refresh,\n flushSync,\n resolveSyncConflict,\n refreshItemMetadata,\n revalidateItems,\n reorderItems,\n moveItem,\n exportBackup,\n importBackup,\n }),\n [\n clear,\n collections,\n error,\n lastChange,\n flushSync,\n resolveSyncConflict,\n isHydrated,\n isLoading,\n isMutating,\n items,\n syncState,\n undo,\n refresh,\n removeItem,\n saveItem,\n removeItemWithUndo,\n removeItemsWithUndo,\n undoLastRemoval,\n updateNote,\n updateTags,\n toggleArchive,\n archiveItem,\n unarchiveItem,\n togglePin,\n moveToCollection,\n createCollection,\n renameCollection,\n removeCollection,\n updateTagsBatch,\n addTagsBatch,\n removeTagsBatch,\n removeItems,\n refreshItemMetadata,\n revalidateItems,\n reorderItems,\n moveItem,\n exportBackup,\n importBackup,\n ],\n );\n\n const actions = useMemo<KeepStoreActions<TMeta>>(\n () => ({\n saveItem,\n updateNote,\n updateTags,\n toggleArchive,\n archiveItem,\n unarchiveItem,\n togglePin,\n moveToCollection,\n createCollection,\n renameCollection,\n removeCollection,\n updateTagsBatch,\n addTagsBatch,\n removeTagsBatch,\n removeItem,\n removeItems,\n removeItemWithUndo,\n removeItemsWithUndo,\n undoLastRemoval,\n clear,\n refresh,\n refreshItemMetadata,\n revalidateItems,\n reorderItems,\n moveItem,\n }),\n [\n addTagsBatch,\n clear,\n createCollection,\n refresh,\n removeCollection,\n removeItem,\n removeItems,\n removeTagsBatch,\n renameCollection,\n saveItem,\n updateNote,\n updateTags,\n toggleArchive,\n archiveItem,\n unarchiveItem,\n togglePin,\n moveToCollection,\n updateTagsBatch,\n refreshItemMetadata,\n revalidateItems,\n reorderItems,\n moveItem,\n removeItemWithUndo,\n removeItemsWithUndo,\n undoLastRemoval,\n ],\n );\n const storeAccess = useMemo<KeepStoreAccess<TMeta>>(() => ({ store, actions }), [actions, store]);\n\n return (\n <KeepStoreContext.Provider value={storeAccess as KeepStoreAccess<unknown>}>\n <KeepContext.Provider value={value as unknown as KeepContextValue<unknown>}>{children}</KeepContext.Provider>\n </KeepStoreContext.Provider>\n );\n}\n\nconst IDLE_SYNC_STATE: KeepSyncState<never> = Object.freeze({\n status: \"idle\",\n pendingCount: 0,\n conflictIds: [],\n conflicts: [],\n});\n\nconst EMPTY_UNDO_STATE: KeepUndoState = Object.freeze({ canUndo: false, ids: [] });\n\nfunction isSyncCapableStorage<TMeta>(storage: StorageAdapter<TMeta>): storage is SyncCapableStorageAdapter<TMeta> {\n return (\n \"getSyncState\" in storage &&\n typeof storage.getSyncState === \"function\" &&\n \"subscribeSync\" in storage &&\n typeof storage.subscribeSync === \"function\" &&\n \"flushSync\" in storage &&\n typeof storage.flushSync === \"function\"\n );\n}\n\nfunction isScopeAwareStorage<TMeta>(\n storage: StorageAdapter<TMeta>,\n): storage is StorageAdapter<TMeta> & { subscribeScope: (listener: () => void) => () => void } {\n return \"subscribeScope\" in storage && typeof storage.subscribeScope === \"function\";\n}\n\nasync function parseKeepMetaItem<TMeta>(item: KeepItem<unknown>, schema: KeepSchema<TMeta>): Promise<KeepItem<TMeta>> {\n return { ...item, meta: await parseKeepMeta(schema, item.meta) };\n}\n\nasync function restoreItems<TMeta>(storage: StorageAdapter<TMeta>, items: KeepItem<TMeta>[]): Promise<void> {\n try {\n if (storage.setMany) {\n await storage.setMany(items);\n return;\n }\n for (const item of items) await storage.set(item);\n } catch {\n // The original operation's error is more useful to the caller than a best-effort rollback error.\n }\n}\n\nexport function useKeepContext<TMeta = Record<string, unknown>>(): KeepContextValue<TMeta> {\n const context = useContext(KeepContext);\n if (!context) throw new Error(\"Keep hooks must be used inside a KeepProvider\");\n return context as unknown as KeepContextValue<TMeta>;\n}\n\nexport function useKeepStore<TMeta = Record<string, unknown>>(): KeepStoreAccess<TMeta> {\n const context = useContext(KeepStoreContext);\n if (!context) throw new Error(\"Keep hooks must be used inside a KeepProvider\");\n return context as unknown as KeepStoreAccess<TMeta>;\n}\n\nexport type { KeepErrorHandler };\n","import { Component, type ErrorInfo, type ReactNode } from \"react\";\n\nexport type KeepErrorBoundaryProps = {\n children?: ReactNode;\n fallback?: ReactNode | ((error: unknown) => ReactNode);\n onError?: (error: unknown, info: ErrorInfo) => void;\n /** Change this value to retry rendering after an error has been handled. */\n resetKey?: unknown;\n};\n\ntype KeepErrorBoundaryState = { error: unknown | null };\n\n/** Prevents an unexpected render error from taking down the host application. */\nexport class KeepErrorBoundary extends Component<KeepErrorBoundaryProps, KeepErrorBoundaryState> {\n state: KeepErrorBoundaryState = { error: null };\n\n static getDerivedStateFromError(error: unknown): KeepErrorBoundaryState {\n return { error };\n }\n\n componentDidCatch(error: unknown, info: ErrorInfo) {\n this.props.onError?.(error, info);\n }\n\n componentDidUpdate(previousProps: KeepErrorBoundaryProps) {\n if (this.state.error !== null && previousProps.resetKey !== this.props.resetKey) {\n this.setState({ error: null });\n }\n }\n\n render() {\n if (this.state.error !== null) {\n return typeof this.props.fallback === \"function\"\n ? this.props.fallback(this.state.error)\n : (this.props.fallback ?? null);\n }\n return this.props.children;\n }\n}\n","import { useCallback, useRef, useSyncExternalStore } from \"react\";\nimport type { KeepStore, KeepStoreState } from \"../../features/store/store\";\n\nexport function useKeepStoreSelector<TMeta, TSelected>(\n store: KeepStore<TMeta>,\n selector: (state: KeepStoreState<TMeta>) => TSelected,\n): TSelected {\n const cacheRef = useRef<{\n snapshot: KeepStoreState<TMeta>;\n selector: (state: KeepStoreState<TMeta>) => TSelected;\n selected: TSelected;\n } | null>(null);\n const getSelectedSnapshot = useCallback(() => {\n const snapshot = store.getSnapshot();\n const cached = cacheRef.current;\n if (cached?.snapshot === snapshot && cached.selector === selector) return cached.selected;\n const selected = selector(snapshot);\n cacheRef.current = { snapshot, selector, selected };\n return selected;\n }, [selector, store]);\n\n return useSyncExternalStore(store.subscribe, getSelectedSnapshot, getSelectedSnapshot);\n}\n","import { useMemo } from \"react\";\nimport type { KeepItem } from \"../../features/items/types\";\nimport { useKeepContext } from \"../components/KeepProvider\";\n\nexport type KeepCollectionSummary = {\n id: string;\n name: string;\n count: number;\n};\n\nexport type UseKeepCollectionsOptions = {\n targetType?: string;\n orderBy?: \"name\" | \"count\";\n};\n\nexport type UseKeepCollectionsResult = KeepCollectionSummary[];\n\n/** Derive de-duplicated collection choices from the provider's saved items and explicit collections. */\nexport function useKeepCollections<TMeta = Record<string, unknown>>(\n options: UseKeepCollectionsOptions = {},\n): UseKeepCollectionsResult {\n const { items, collections: explicitCollections } = useKeepContext<TMeta>();\n const { orderBy = \"name\", targetType } = options;\n return useMemo(() => {\n const collections = new Map<string, KeepCollectionSummary>();\n // Merge explicit collections (may have zero items).\n for (const [id, meta] of Object.entries(explicitCollections ?? {})) {\n collections.set(id, { id, name: meta.name, count: 0 });\n }\n for (const item of items) {\n if (targetType !== undefined && item.targetType !== targetType) continue;\n const collection = getCollection(item);\n if (!collection) continue;\n const current = collections.get(collection.id);\n collections.set(collection.id, {\n id: collection.id,\n name: current?.name ?? collection.name,\n count: (current?.count ?? 0) + 1,\n });\n }\n return [...collections.values()].sort((left, right) => {\n if (orderBy === \"count\" && left.count !== right.count) return right.count - left.count;\n return left.name.localeCompare(right.name) || left.id.localeCompare(right.id);\n });\n }, [items, explicitCollections, orderBy, targetType]);\n}\n\nfunction getCollection<TMeta>(item: KeepItem<TMeta>): { id: string; name: string } | undefined {\n const id = item.collectionId?.trim();\n if (id) return { id, name: id };\n if (!isRecord(item.meta)) return undefined;\n const metadata = item.meta.collectionId;\n if (typeof metadata === \"string\" && metadata.trim()) {\n const normalized = metadata.trim();\n return { id: normalized, name: getCollectionName(item.meta.collection, normalized) };\n }\n if (typeof item.meta.collection === \"string\" && item.meta.collection.trim()) {\n const normalized = item.meta.collection.trim();\n return { id: normalized, name: normalized };\n }\n if (isRecord(item.meta.collection) && typeof item.meta.collection.id === \"string\") {\n const normalized = item.meta.collection.id.trim();\n if (!normalized) return undefined;\n return { id: normalized, name: getCollectionName(item.meta.collection, normalized) };\n }\n return undefined;\n}\n\nfunction getCollectionName(value: unknown, fallback: string): string {\n if (isRecord(value) && typeof value.name === \"string\" && value.name.trim()) return value.name.trim();\n return fallback;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n","import { useCallback, useMemo } from \"react\";\nimport { type KeepListQuery, type QueryKeepItemsResult, queryKeepItems } from \"../../features/items/query\";\nimport type {\n KeepItemRevalidationSummary,\n KeepItemRevalidator,\n RevalidateKeepItemsOptions,\n} from \"../../features/items/revalidation\";\nimport type { KeepItem } from \"../../features/items/types\";\nimport { useKeepStore } from \"../components/KeepProvider\";\nimport { useKeepStoreSelector } from \"./useKeepStoreSelector\";\n\nexport type { KeepListQuery } from \"../../features/items/query\";\n\nexport type UseKeepListResult<TMeta = Record<string, unknown>> = {\n items: KeepItem<TMeta>[];\n totalCount: number;\n tags: string[];\n tagCounts: Record<string, number>;\n page: number;\n pageCount: number;\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n isLoading: boolean;\n isHydrated: boolean;\n isMutating: boolean;\n error: unknown | null;\n remove: (id: string) => Promise<void>;\n removeBatch: (ids: string[]) => Promise<void>;\n removeWithUndo: (id: string) => Promise<void>;\n removeBatchWithUndo: (ids: string[]) => Promise<void>;\n updateTagsBatch: (ids: string[], tags?: string[]) => Promise<void>;\n toggleArchive: (id: string) => Promise<void>;\n archiveItem: (id: string) => Promise<void>;\n unarchiveItem: (id: string) => Promise<void>;\n archive: (id: string) => Promise<void>;\n unarchive: (id: string) => Promise<void>;\n togglePin: (id: string) => Promise<void>;\n moveToCollection: (id: string, collectionId?: string) => Promise<void>;\n addTagsBatch: (ids: string[], tags: string[]) => Promise<void>;\n removeTagsBatch: (ids: string[], tags: string[]) => Promise<void>;\n reorder: (orderedIds: string[]) => Promise<void>;\n move: (id: string, targetIndex: number) => Promise<void>;\n clear: () => Promise<void>;\n refresh: () => Promise<void>;\n revalidate: (\n revalidator: KeepItemRevalidator<TMeta>,\n options?: RevalidateKeepItemsOptions<TMeta>,\n ) => Promise<KeepItemRevalidationSummary<TMeta>>;\n};\n\nexport function useKeepList<TMeta = Record<string, unknown>>(\n query: KeepListQuery<TMeta> = {},\n): UseKeepListResult<TMeta> {\n const { store, actions } = useKeepStore<TMeta>();\n const {\n archiveScope,\n archived,\n collectionId,\n filter,\n pagination,\n pinnedFirst,\n savedBetween,\n search,\n sort,\n tags,\n targetType,\n } = query;\n const queryOptions = useMemo<KeepListQuery<TMeta>>(\n () => ({\n archiveScope,\n archived,\n collectionId,\n filter,\n pagination,\n pinnedFirst,\n savedBetween,\n search,\n sort,\n tags,\n targetType,\n }),\n [\n archiveScope,\n archived,\n collectionId,\n filter,\n pagination,\n pinnedFirst,\n savedBetween,\n search,\n sort,\n tags,\n targetType,\n ],\n );\n const selector = useMemo(() => {\n let previousResult: QueryKeepItemsResult<TMeta> | undefined;\n return (state: { items: KeepItem<TMeta>[] }) => {\n const next = queryKeepItems(state.items, queryOptions);\n if (previousResult && sameQueryResult(previousResult, next)) return previousResult;\n previousResult = next;\n return previousResult;\n };\n }, [queryOptions]);\n const result = useKeepStoreSelector(store, selector);\n const tagsSelector = useMemo(() => {\n let previous: string[] | undefined;\n return (state: { items: KeepItem<TMeta>[] }) => {\n const next = [...new Set(state.items.flatMap((item) => item.tags ?? []))].sort();\n if (previous?.length === next.length && previous.every((tag, index) => tag === next[index])) return previous;\n previous = next;\n return next;\n };\n }, []);\n const isLoading = useKeepStoreSelector(\n store,\n useCallback((state) => state.isLoading, []),\n );\n const isHydrated = useKeepStoreSelector(\n store,\n useCallback((state) => state.isHydrated, []),\n );\n const isMutating = useKeepStoreSelector(\n store,\n useCallback((state) => state.isMutating, []),\n );\n const error = useKeepStoreSelector(\n store,\n useCallback((state) => state.error, []),\n );\n const allTags = useKeepStoreSelector(store, tagsSelector);\n const remove = useCallback((id: string) => actions.removeItem(id), [actions]);\n const removeBatch = useCallback((ids: string[]) => actions.removeItems(ids), [actions]);\n const removeWithUndo = useCallback((id: string) => actions.removeItemWithUndo(id), [actions]);\n const removeBatchWithUndo = useCallback((ids: string[]) => actions.removeItemsWithUndo(ids), [actions]);\n const updateTagsBatch = useCallback(\n (ids: string[], nextTags?: string[]) => actions.updateTagsBatch(ids, nextTags),\n [actions],\n );\n const addTagsBatch = useCallback(\n (ids: string[], nextTags: string[]) => actions.addTagsBatch(ids, nextTags),\n [actions],\n );\n const removeTagsBatch = useCallback(\n (ids: string[], nextTags: string[]) => actions.removeTagsBatch(ids, nextTags),\n [actions],\n );\n const toggleArchive = useCallback((id: string) => actions.toggleArchive(id), [actions]);\n const archive = useCallback((id: string) => actions.archiveItem(id), [actions]);\n const unarchive = useCallback((id: string) => actions.unarchiveItem(id), [actions]);\n const togglePin = useCallback((id: string) => actions.togglePin(id), [actions]);\n const moveToCollection = useCallback(\n (id: string, collectionId?: string) => actions.moveToCollection(id, collectionId),\n [actions],\n );\n\n return {\n items: result.items,\n totalCount: result.totalCount,\n tags: allTags,\n tagCounts: result.tagCounts,\n page: result.page,\n pageCount: result.pageCount,\n hasNextPage: result.hasNextPage,\n hasPreviousPage: result.hasPreviousPage,\n isLoading,\n isHydrated,\n isMutating,\n error,\n remove,\n removeBatch,\n removeWithUndo,\n removeBatchWithUndo,\n updateTagsBatch,\n addTagsBatch,\n removeTagsBatch,\n toggleArchive,\n archiveItem: archive,\n unarchiveItem: unarchive,\n archive,\n unarchive,\n togglePin,\n moveToCollection,\n reorder: actions.reorderItems,\n move: actions.moveItem,\n clear: actions.clear,\n refresh: actions.refresh,\n revalidate: actions.revalidateItems,\n };\n}\n\nfunction sameQueryResult<TMeta>(left: QueryKeepItemsResult<TMeta>, right: QueryKeepItemsResult<TMeta>): boolean {\n return (\n left.totalCount === right.totalCount &&\n left.page === right.page &&\n left.pageCount === right.pageCount &&\n left.hasNextPage === right.hasNextPage &&\n left.hasPreviousPage === right.hasPreviousPage &&\n left.items.length === right.items.length &&\n left.items.every((item, index) => item === right.items[index]) &&\n sameCounts(left.tagCounts, right.tagCounts)\n );\n}\n\nfunction sameCounts(left: Record<string, number>, right: Record<string, number>): boolean {\n const leftEntries = Object.entries(left);\n const rightEntries = Object.entries(right);\n return (\n leftEntries.length === rightEntries.length &&\n leftEntries.every(([key, value], index) => {\n const [rightKey, rightValue] = rightEntries[index] ?? [];\n return key === rightKey && value === rightValue;\n })\n );\n}\n","import { useCallback, useMemo, useState } from \"react\";\nimport { getKeepNavigationState, type KeepNavigationState } from \"../../features/items/navigation\";\nimport { type KeepListQuery, queryKeepItems } from \"../../features/items/query\";\nimport type { KeepItem } from \"../../features/items/types\";\nimport { useKeepStore } from \"../components/KeepProvider\";\nimport { useKeepStoreSelector } from \"./useKeepStoreSelector\";\n\nexport type UseKeepNavigatorOptions<TMeta = Record<string, unknown>> = {\n currentId?: string;\n initialIndex?: number;\n query?: Omit<KeepListQuery<TMeta>, \"pagination\">;\n};\n\nexport type UseKeepNavigatorResult<TMeta = Record<string, unknown>> = KeepNavigationState<TMeta> & {\n goToNext: () => KeepItem<TMeta> | null;\n goToPrev: () => KeepItem<TMeta> | null;\n goToIndex: (index: number) => KeepItem<TMeta> | null;\n goToItem: (id: string) => KeepItem<TMeta> | null;\n};\n\n/** Derive a stable previous/current/next view and pointer actions from the provider store. */\nexport function useKeepNavigator<TMeta = Record<string, unknown>>(\n options: UseKeepNavigatorOptions<TMeta> = {},\n): UseKeepNavigatorResult<TMeta> {\n const { store } = useKeepStore<TMeta>();\n const { currentId, initialIndex = 0, query } = options;\n const [activeIndex, setActiveIndex] = useState(() => Math.max(0, Math.floor(initialIndex)));\n const queryOptions = useMemo(() => ({ ...query, pagination: undefined }), [query]);\n const selector = useMemo(() => {\n let previousSource: KeepItem<TMeta>[] | undefined;\n let previousItems: KeepItem<TMeta>[] | undefined;\n let previousPointer: string | number | undefined;\n let previousResult: KeepNavigationState<TMeta> | undefined;\n return (state: { items: KeepItem<TMeta>[] }) => {\n if (previousSource !== state.items) {\n previousSource = state.items;\n previousItems = queryKeepItems(state.items, queryOptions).items;\n previousResult = undefined;\n }\n const items = previousItems ?? [];\n const pointer = currentId ?? activeIndex;\n if (previousResult && previousPointer === pointer) return previousResult;\n previousPointer = pointer;\n previousResult = getKeepNavigationState(items, pointer);\n return previousResult;\n };\n }, [activeIndex, currentId, queryOptions]);\n const navigation = useKeepStoreSelector(store, selector);\n\n const goToIndex = useCallback(\n (index: number) => {\n const item = navigation.items[index];\n if (!item) return null;\n setActiveIndex(index);\n return item;\n },\n [navigation.items],\n );\n const goToNext = useCallback(() => {\n if (!navigation.nextItem) return null;\n setActiveIndex(navigation.currentIndex + 1);\n return navigation.nextItem;\n }, [navigation.currentIndex, navigation.nextItem]);\n const goToPrev = useCallback(() => {\n if (!navigation.prevItem) return null;\n setActiveIndex(navigation.currentIndex - 1);\n return navigation.prevItem;\n }, [navigation.currentIndex, navigation.prevItem]);\n const goToItem = useCallback(\n (id: string) => {\n const index = navigation.items.findIndex((item) => item.id === id);\n return index < 0 ? null : goToIndex(index);\n },\n [goToIndex, navigation.items],\n );\n\n return { ...navigation, goToNext, goToPrev, goToIndex, goToItem };\n}\n","import { useEffect } from \"react\";\nimport type { KeepItemInput } from \"../../features/items/types\";\nimport { useKeepItem } from \"./useKeepItem\";\n\nexport type KeepShortcutModifier = \"meta\" | \"ctrl\" | \"alt\" | \"shift\";\n\nexport type KeepShortcutOptions<TMeta = Record<string, unknown>> = {\n key: string;\n modifier?: KeepShortcutModifier;\n item?: KeepItemInput<TMeta>;\n action?: \"toggle\" | \"save\" | \"remove\";\n enabled?: boolean;\n preventDefault?: boolean;\n allowInEditable?: boolean;\n onTrigger?: (event: KeyboardEvent) => void | Promise<void>;\n onError?: (error: unknown) => void;\n};\n\n/** Bind a keyboard shortcut to a Keep action or an arbitrary command. */\nexport function useKeepShortcut<TMeta = Record<string, unknown>>(options: KeepShortcutOptions<TMeta>): void {\n const item = useKeepItem(options.item);\n const {\n action = \"toggle\",\n allowInEditable = false,\n enabled = true,\n key,\n modifier,\n onError,\n onTrigger,\n preventDefault = true,\n } = options;\n\n useEffect(() => {\n if (!enabled) return;\n const handleKeyDown = (event: KeyboardEvent) => {\n if (!allowInEditable && isEditableTarget(event.target)) return;\n if (!matchesShortcut(event, key, modifier)) return;\n if (preventDefault) event.preventDefault();\n const run = onTrigger\n ? onTrigger(event)\n : options.item\n ? action === \"save\"\n ? item.save()\n : action === \"remove\"\n ? item.remove()\n : item.toggle()\n : undefined;\n if (run) void Promise.resolve(run).catch((error) => onError?.(error));\n };\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [\n action,\n allowInEditable,\n enabled,\n item.remove,\n item.save,\n item.toggle,\n key,\n modifier,\n onError,\n onTrigger,\n options.item,\n preventDefault,\n ]);\n}\n\nfunction matchesShortcut(event: KeyboardEvent, key: string, modifier?: KeepShortcutModifier): boolean {\n if (event.key.toLocaleLowerCase() !== key.toLocaleLowerCase()) return false;\n const modifiers = {\n meta: event.metaKey,\n ctrl: event.ctrlKey,\n alt: event.altKey,\n shift: event.shiftKey,\n };\n if (modifier ? !modifiers[modifier] : Object.values(modifiers).some(Boolean)) return false;\n return Object.entries(modifiers).every(([name, pressed]) => name === modifier || !pressed);\n}\n\nfunction isEditableTarget(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n return (\n target.isContentEditable ||\n target.tagName === \"INPUT\" ||\n target.tagName === \"TEXTAREA\" ||\n target.tagName === \"SELECT\"\n );\n}\n","import type { ComponentType } from \"react\";\nimport type { KeepListQuery } from \"../features/items/query\";\nimport type { KeepItemInput } from \"../features/items/types\";\nimport { KeepButton, type KeepButtonProps } from \"./components/KeepButton\";\nimport { KeepProvider, type KeepProviderProps, useKeepContext } from \"./components/KeepProvider\";\nimport { type UseKeepCollectionsResult, useKeepCollections } from \"./hooks/useKeepCollections\";\nimport { type UseKeepItemResult, useKeepItem } from \"./hooks/useKeepItem\";\nimport { type UseKeepListResult, useKeepList } from \"./hooks/useKeepList\";\nimport { type UseKeepNavigatorOptions, type UseKeepNavigatorResult, useKeepNavigator } from \"./hooks/useKeepNavigator\";\nimport { type KeepShortcutOptions, useKeepShortcut } from \"./hooks/useKeepShortcut\";\n\nexport type CreateKeepKitOptions<TMeta = Record<string, unknown>> = Omit<KeepProviderProps<TMeta>, \"children\">;\n\nexport type KeepKit<TMeta> = {\n Provider: ComponentType<KeepProviderProps<TMeta>>;\n Button: ComponentType<KeepButtonProps<TMeta>>;\n useContext: () => ReturnType<typeof useKeepContext<TMeta>>;\n useItem: (item?: KeepItemInput<TMeta>) => UseKeepItemResult<TMeta>;\n useCollections: (options?: { targetType?: string; orderBy?: \"name\" | \"count\" }) => UseKeepCollectionsResult;\n useList: (query?: KeepListQuery<TMeta>) => UseKeepListResult<TMeta>;\n useNavigator: (options?: UseKeepNavigatorOptions<TMeta>) => UseKeepNavigatorResult<TMeta>;\n useShortcut: (options: KeepShortcutOptions<TMeta>) => void;\n};\n\n/** Create an app-specific, fully typed set of KeepKit components and hooks. */\nexport function createKeepKit<TMeta = Record<string, unknown>>(\n options: CreateKeepKitOptions<TMeta> = {},\n): KeepKit<TMeta> {\n return {\n Provider: (props) => <KeepProvider<TMeta> {...options} {...props} />,\n Button: (props) => <KeepButton<TMeta> {...props} />,\n useContext: () => useKeepContext<TMeta>(),\n useItem: (item) => useKeepItem<TMeta>(item),\n useCollections: (collectionsOptions) => useKeepCollections<TMeta>(collectionsOptions),\n useList: (query) => useKeepList<TMeta>(query),\n useNavigator: (navigatorOptions) => useKeepNavigator<TMeta>(navigatorOptions),\n useShortcut: (shortcutOptions) => useKeepShortcut<TMeta>(shortcutOptions),\n };\n}\n"],"mappings":"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","names":["useCallback","item","refresh","useCallback","useRef","useSyncExternalStore","useCallback","jsx","useMemo","useMemo","useCallback","useMemo","useMemo","useCallback","collectionId","useCallback","useMemo","useMemo","useCallback","useEffect","useEffect","jsx"]}
@@ -177,8 +177,12 @@ declare function exportItems<TMeta>(adapter: StorageAdapter<TMeta>): Promise<str
177
177
  /** Validate and restore a backup, either replacing or merging existing data. */
178
178
  declare function importItems<TMeta>(adapter: StorageAdapter<TMeta>, data: string | KeepBackup<TMeta>, options?: ImportItemsOptions<TMeta>): Promise<ImportItemsResult<TMeta>>;
179
179
 
180
+ type KeepCollectionMeta = {
181
+ name: string;
182
+ };
180
183
  type KeepStoreState<TMeta = Record<string, unknown>> = {
181
184
  items: KeepItem<TMeta>[];
185
+ collections: Record<string, KeepCollectionMeta>;
182
186
  isLoading: boolean;
183
187
  isHydrated: boolean;
184
188
  isMutating: boolean;
@@ -195,6 +199,9 @@ type KeepStoreActions<TMeta = Record<string, unknown>> = {
195
199
  unarchiveItem: (id: string) => Promise<void>;
196
200
  togglePin: (id: string) => Promise<void>;
197
201
  moveToCollection: (id: string, collectionId?: string) => Promise<void>;
202
+ createCollection: (id: string, name: string) => Promise<void>;
203
+ renameCollection: (id: string, name: string) => Promise<void>;
204
+ removeCollection: (id: string) => Promise<void>;
198
205
  updateTagsBatch: (ids: string[], tags?: string[]) => Promise<void>;
199
206
  addTagsBatch: (ids: string[], tags: string[]) => Promise<void>;
200
207
  removeTagsBatch: (ids: string[], tags: string[]) => Promise<void>;
@@ -219,4 +226,4 @@ declare class KeepStore<TMeta = Record<string, unknown>> {
219
226
  setState(next: Partial<KeepStoreState<TMeta>>): void;
220
227
  }
221
228
 
222
- export { isKeepItemMetadataStale as A, mergeKeepListQueryFromUrl as B, moveKeepItem as C, DEFAULT_KEEP_URL_PARAMS as D, orderKeepItems as E, queryKeepItems as F, reconcileKeepItems as G, reorderKeepItems as H, type ImportItemsOptions as I, revalidateKeepItems as J, KEEP_BACKUP_FORMAT as K, serializeKeepListQuery as L, type QueryKeepItemsResult as Q, type RevalidateKeepItemsOptions as R, type ImportItemsResult as a, KEEP_BACKUP_VERSION as b, type KeepAutoRevalidationOptions as c, type KeepBackup as d, KeepBackupImportError as e, KeepBackupParseError as f, type KeepItemMetadataRefresher as g, type KeepItemResolver as h, type KeepItemRevalidationRecord as i, type KeepItemRevalidationResult as j, type KeepItemRevalidationSummary as k, type KeepItemRevalidator as l, type KeepListQuery as m, type KeepNavigationState as n, KeepStore as o, type KeepStoreActions as p, type KeepStoreState as q, type KeepUrlParamNames as r, type KeepUrlState as s, type KeepUrlSyncOptions as t, decodeKeepListQuery as u, encodeKeepListQuery as v, exportItems as w, getKeepNavigationState as x, getTagCounts as y, importItems as z };
229
+ export { importItems as A, isKeepItemMetadataStale as B, mergeKeepListQueryFromUrl as C, DEFAULT_KEEP_URL_PARAMS as D, moveKeepItem as E, orderKeepItems as F, queryKeepItems as G, reconcileKeepItems as H, type ImportItemsOptions as I, reorderKeepItems as J, KEEP_BACKUP_FORMAT as K, revalidateKeepItems as L, serializeKeepListQuery as M, type QueryKeepItemsResult as Q, type RevalidateKeepItemsOptions as R, type ImportItemsResult as a, KEEP_BACKUP_VERSION as b, type KeepAutoRevalidationOptions as c, type KeepBackup as d, KeepBackupImportError as e, KeepBackupParseError as f, type KeepCollectionMeta as g, type KeepItemMetadataRefresher as h, type KeepItemResolver as i, type KeepItemRevalidationRecord as j, type KeepItemRevalidationResult as k, type KeepItemRevalidationSummary as l, type KeepItemRevalidator as m, type KeepListQuery as n, type KeepNavigationState as o, KeepStore as p, type KeepStoreActions as q, type KeepStoreState as r, type KeepUrlParamNames as s, type KeepUrlState as t, type KeepUrlSyncOptions as u, decodeKeepListQuery as v, encodeKeepListQuery as w, exportItems as x, getKeepNavigationState as y, getTagCounts as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keepkit/core",
3
- "version": "0.26.2",
3
+ "version": "0.27.0",
4
4
  "description": "A flexible save-and-collect toolkit for React apps.",
5
5
  "type": "module",
6
6
  "license": "MIT",