@keepkit/core 0.2.0 → 0.3.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/dist/react.js CHANGED
@@ -1,8 +1,10 @@
1
1
  "use client";
2
2
  import {
3
3
  KeepStore,
4
- queryKeepItems
5
- } from "./chunk-PLT2WJVM.js";
4
+ isKeepItemMetadataStale,
5
+ queryKeepItems,
6
+ revalidateKeepItems
7
+ } from "./chunk-J7NKIOXV.js";
6
8
  import {
7
9
  parseKeepMeta
8
10
  } from "./chunk-THZ3ACR2.js";
@@ -10,7 +12,7 @@ import "./chunk-5QSZP6MT.js";
10
12
  import {
11
13
  createBrowserStorageAdapter,
12
14
  normalizeKeepTags
13
- } from "./chunk-C3SOQCVW.js";
15
+ } from "./chunk-X4UVKTBK.js";
14
16
 
15
17
  // src/hooks/useKeepItem.ts
16
18
  import { useCallback as useCallback3 } from "react";
@@ -399,6 +401,64 @@ function KeepProvider({
399
401
  })),
400
402
  [runMutation, storage]
401
403
  );
404
+ const revalidateItems = useCallback(
405
+ async (revalidator, options = {}) => {
406
+ pendingMutationsRef.current += 1;
407
+ store.setState({ isMutating: true });
408
+ const run = enqueueOperation(async () => {
409
+ const previous = itemsRef.current;
410
+ let persistenceStarted = false;
411
+ try {
412
+ const summary = await revalidateKeepItems(previous, revalidator, options);
413
+ const pluginContext = { action: "revalidate", items: summary.updatedItems };
414
+ await runBeforePlugins(pluginContext);
415
+ if (summary.updatedItems.length > 0) {
416
+ persistenceStarted = true;
417
+ if (storage.setMany) await storage.setMany(summary.updatedItems);
418
+ else for (const item of summary.updatedItems) await storage.set(item);
419
+ }
420
+ if (summary.removedIds.length > 0) {
421
+ persistenceStarted = true;
422
+ if (storage.removeMany) await storage.removeMany(summary.removedIds);
423
+ else for (const id of summary.removedIds) await storage.remove(id);
424
+ }
425
+ setItems(summary.items);
426
+ store.setState({ error: null });
427
+ const removedIdSet = new Set(summary.removedIds);
428
+ for (const result of summary.results) {
429
+ if (removedIdSet.has(result.item.id)) handlersRef.current.onRemove?.(result.item);
430
+ }
431
+ await runAfterPlugins(pluginContext);
432
+ void Promise.resolve(handlersRef.current.onChange?.({ ...pluginContext, phase: "local" })).catch(
433
+ (cause) => reportError(cause, { action: "revalidate" })
434
+ );
435
+ return summary;
436
+ } catch (cause) {
437
+ if (persistenceStarted) await restoreItems(storage, previous);
438
+ setItems(previous);
439
+ reportError(cause, { action: "revalidate" });
440
+ throw cause;
441
+ }
442
+ });
443
+ return run.finally(() => {
444
+ pendingMutationsRef.current -= 1;
445
+ if (pendingMutationsRef.current === 0) store.setState({ isMutating: false });
446
+ });
447
+ },
448
+ [enqueueOperation, reportError, runAfterPlugins, runBeforePlugins, setItems, storage, store]
449
+ );
450
+ const refreshItemMetadata = useCallback(
451
+ async (id, refresh2) => {
452
+ if (!itemsRef.current.some((item) => item.id === id)) {
453
+ throw new Error(`Cannot refresh metadata for missing item "${id}".`);
454
+ }
455
+ await revalidateItems(async (item) => {
456
+ if (item.id !== id) return "available";
457
+ return { status: "available", meta: await refresh2(item) };
458
+ });
459
+ },
460
+ [revalidateItems]
461
+ );
402
462
  const flushSync = useCallback(() => syncStorage ? syncStorage.flushSync() : Promise.resolve(), [syncStorage]);
403
463
  const value = useMemo(
404
464
  () => ({
@@ -418,7 +478,9 @@ function KeepProvider({
418
478
  removeItems,
419
479
  clear,
420
480
  refresh,
421
- flushSync
481
+ flushSync,
482
+ refreshItemMetadata,
483
+ revalidateItems
422
484
  }),
423
485
  [
424
486
  clear,
@@ -437,7 +499,9 @@ function KeepProvider({
437
499
  updateTagsBatch,
438
500
  addTagsBatch,
439
501
  removeTagsBatch,
440
- removeItems
502
+ removeItems,
503
+ refreshItemMetadata,
504
+ revalidateItems
441
505
  ]
442
506
  );
443
507
  const actions = useMemo(
@@ -451,7 +515,9 @@ function KeepProvider({
451
515
  removeItem,
452
516
  removeItems,
453
517
  clear,
454
- refresh
518
+ refresh,
519
+ refreshItemMetadata,
520
+ revalidateItems
455
521
  }),
456
522
  [
457
523
  addTagsBatch,
@@ -463,7 +529,9 @@ function KeepProvider({
463
529
  saveItem,
464
530
  updateNote,
465
531
  updateTags,
466
- updateTagsBatch
532
+ updateTagsBatch,
533
+ refreshItemMetadata,
534
+ revalidateItems
467
535
  ]
468
536
  );
469
537
  const storeAccess = useMemo(() => ({ store, actions }), [actions, store]);
@@ -480,6 +548,16 @@ function isSyncCapableStorage(storage) {
480
548
  async function parseKeepMetaItem(item, schema) {
481
549
  return { ...item, meta: await parseKeepMeta(schema, item.meta) };
482
550
  }
551
+ async function restoreItems(storage, items) {
552
+ try {
553
+ if (storage.setMany) {
554
+ await storage.setMany(items);
555
+ return;
556
+ }
557
+ for (const item of items) await storage.set(item);
558
+ } catch {
559
+ }
560
+ }
483
561
  function useKeepContext() {
484
562
  const context = useContext(KeepContext);
485
563
  if (!context) throw new Error("Keep hooks must be used inside a KeepProvider");
@@ -541,6 +619,10 @@ function useKeepItem(id, itemPayload) {
541
619
  const toggle = useCallback3(() => item ? remove() : save(), [item, remove, save]);
542
620
  const updateNote = useCallback3((note) => actions.updateNote(id, note), [actions, id]);
543
621
  const updateTags = useCallback3((tags) => actions.updateTags(id, tags), [actions, id]);
622
+ const refreshMetadata = useCallback3(
623
+ (refresh) => actions.refreshItemMetadata(id, refresh),
624
+ [actions, id]
625
+ );
544
626
  return {
545
627
  item,
546
628
  isSaved: Boolean(item),
@@ -551,7 +633,8 @@ function useKeepItem(id, itemPayload) {
551
633
  remove,
552
634
  toggle,
553
635
  updateNote,
554
- updateTags
636
+ updateTags,
637
+ refreshMetadata
555
638
  };
556
639
  }
557
640
 
@@ -672,7 +755,8 @@ function useKeepList(options = {}) {
672
755
  addTagsBatch,
673
756
  removeTagsBatch,
674
757
  clear: actions.clear,
675
- refresh: actions.refresh
758
+ refresh: actions.refresh,
759
+ revalidate: actions.revalidateItems
676
760
  };
677
761
  }
678
762
  function sameItems(left, right) {
@@ -755,6 +839,9 @@ function KeepButton({
755
839
  children,
756
840
  savedLabel = "Saved",
757
841
  unsavedLabel = "Save",
842
+ savedAriaLabel,
843
+ unsavedAriaLabel,
844
+ getAriaLabel,
758
845
  asChild = false,
759
846
  onToggleError,
760
847
  onClick,
@@ -810,7 +897,7 @@ function KeepButton({
810
897
  const commonProps = {
811
898
  ...buttonProps,
812
899
  "aria-pressed": isSaved,
813
- "aria-label": ("aria-label" in buttonProps ? buttonProps["aria-label"] : void 0) ?? getAccessibleLabel(isSaved, item, asChild),
900
+ "aria-label": ("aria-label" in buttonProps ? buttonProps["aria-label"] : void 0) ?? getAriaLabel?.(state) ?? (isSaved ? savedAriaLabel : unsavedAriaLabel) ?? getAccessibleLabel(isSaved, item, asChild),
814
901
  ...asChild ? {
815
902
  "aria-disabled": isDisabled,
816
903
  role: buttonProps.role ?? "button",
@@ -852,6 +939,7 @@ export {
852
939
  KeepButton,
853
940
  KeepProvider,
854
941
  createKeepKit,
942
+ isKeepItemMetadataStale,
855
943
  useKeepContext,
856
944
  useKeepItem,
857
945
  useKeepList,
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/useKeepItem.ts","../src/KeepProvider.tsx","../src/hooks/useKeepStoreSelector.ts","../src/hooks/useKeepList.ts","../src/hooks/useKeepShortcut.ts","../src/KeepButton.tsx","../src/createKeepKit.tsx"],"sourcesContent":["import { useCallback } from \"react\";\nimport { useKeepStore } from \"../KeepProvider\";\nimport type { KeepItem, KeepItemInput } from \"../types\";\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 toggle: () => Promise<void>;\n updateNote: (note?: string) => Promise<void>;\n updateTags: (tags?: string[]) => Promise<void>;\n};\n\nexport function useKeepItem<TMeta = Record<string, unknown>>(\n id: string,\n itemPayload?: KeepItemInput<TMeta>,\n): UseKeepItemResult<TMeta> {\n const { store, actions } = useKeepStore<TMeta>();\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\n const save = useCallback(async () => {\n if (!itemPayload) {\n throw new Error(`An itemPayload is required to save item \"${id}\".`);\n }\n const now = Date.now();\n await actions.saveItem({\n id,\n ...itemPayload,\n savedAt: item?.savedAt ?? now,\n updatedAt: now,\n });\n }, [actions, id, item?.savedAt, itemPayload]);\n\n const remove = useCallback(() => actions.removeItem(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\n return {\n item,\n isSaved: Boolean(item),\n isLoading,\n isMutating,\n error,\n save,\n remove,\n toggle,\n updateNote,\n updateTags,\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 { parseKeepMeta } from \"./schema\";\nimport { createBrowserStorageAdapter } from \"./storage\";\nimport { KeepStore, type KeepStoreActions } from \"./store\";\nimport type {\n KeepAction,\n KeepChangeContext,\n KeepErrorContext,\n KeepErrorHandler,\n KeepEventHandlers,\n KeepInvalidItemPolicy,\n KeepItem,\n KeepPlugin,\n KeepSchema,\n KeepSyncState,\n StorageAdapter,\n SyncCapableStorageAdapter,\n} from \"./types\";\nimport { normalizeKeepTags } from \"./types\";\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 syncState: KeepSyncState;\n saveItem: (item: KeepItem<TMeta>) => Promise<void>;\n updateNote: (id: string, note?: string) => Promise<void>;\n updateTags: (id: string, tags?: 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 clear: () => Promise<void>;\n refresh: () => Promise<void>;\n flushSync: () => Promise<void>;\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 }\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 onError,\n plugins = [],\n schemaVersion,\n schema,\n invalidItemPolicy = \"error\",\n onInvalidItem,\n migrateMeta,\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 });\n }\n const store = storeRef.current;\n const state = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n const { items, isLoading, isHydrated, isMutating, error } = state;\n const itemsRef = useRef(items);\n const pluginsRef = useRef(plugins);\n pluginsRef.current = plugins;\n const handlersRef = useRef({ onSave, onRemove, onNoteUpdate, onTagsUpdate, onChange, onError });\n handlersRef.current = { onSave, onRemove, onNoteUpdate, onTagsUpdate, onChange, 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 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 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 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 next: [...previous.filter((current) => current.id !== normalizedItem.id), normalizedItem].sort(\n (a, b) => b.updatedAt - a.updatedAt,\n ),\n persist: () => storage.set(normalizedItem),\n onSuccess: () => handlersRef.current.onSave?.(normalizedItem),\n pluginContext: { action: \"save\", id: normalizedItem.id, item: normalizedItem },\n }));\n },\n [reportError, 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 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 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 const flushSync = useCallback(() => (syncStorage ? syncStorage.flushSync() : Promise.resolve()), [syncStorage]);\n\n const value = useMemo<KeepContextValue<TMeta>>(\n () => ({\n items,\n isLoading,\n isHydrated,\n isMutating,\n error,\n syncState,\n saveItem,\n updateNote,\n updateTags,\n updateTagsBatch,\n addTagsBatch,\n removeTagsBatch,\n removeItem,\n removeItems,\n clear,\n refresh,\n flushSync,\n }),\n [\n clear,\n error,\n flushSync,\n isHydrated,\n isLoading,\n isMutating,\n items,\n syncState,\n refresh,\n removeItem,\n saveItem,\n updateNote,\n updateTags,\n updateTagsBatch,\n addTagsBatch,\n removeTagsBatch,\n removeItems,\n ],\n );\n\n const actions = useMemo<KeepStoreActions<TMeta>>(\n () => ({\n saveItem,\n updateNote,\n updateTags,\n updateTagsBatch,\n addTagsBatch,\n removeTagsBatch,\n removeItem,\n removeItems,\n clear,\n refresh,\n }),\n [\n addTagsBatch,\n clear,\n refresh,\n removeItem,\n removeItems,\n removeTagsBatch,\n saveItem,\n updateNote,\n updateTags,\n updateTagsBatch,\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 = Object.freeze({\n status: \"idle\",\n pendingCount: 0,\n conflictIds: [],\n});\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\nasync function parseKeepMetaItem<TMeta>(item: KeepItem<unknown>, schema: KeepSchema<TMeta>): Promise<KeepItem<TMeta>> {\n return { ...item, meta: await parseKeepMeta(schema, item.meta) };\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 { useCallback, useRef, useSyncExternalStore } from \"react\";\nimport type { KeepStore, KeepStoreState } from \"../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 { useCallback, useMemo } from \"react\";\nimport { useKeepStore } from \"../KeepProvider\";\nimport { type KeepListOptions, type QueryKeepItemsResult, queryKeepItems } from \"../query\";\nimport type { KeepItem } from \"../types\";\nimport { useKeepStoreSelector } from \"./useKeepStoreSelector\";\n\nexport type { KeepListOptions } from \"../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 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 updateTagsBatch: (ids: string[], tags?: string[]) => Promise<void>;\n addTagsBatch: (ids: string[], tags: string[]) => Promise<void>;\n removeTagsBatch: (ids: string[], tags: string[]) => Promise<void>;\n clear: () => Promise<void>;\n refresh: () => Promise<void>;\n};\n\nexport function useKeepList<TMeta = Record<string, unknown>>(\n options: KeepListOptions<TMeta> = {},\n): UseKeepListResult<TMeta> {\n const { store, actions } = useKeepStore<TMeta>();\n const {\n filter,\n filterFn,\n limit,\n offset,\n order,\n savedBetween,\n search,\n searchQuery,\n sort,\n sortBy,\n tag,\n tags: queryTags,\n targetType,\n } = options;\n const queryOptions = useMemo<KeepListOptions<TMeta>>(\n () => ({\n filter,\n filterFn,\n limit,\n offset,\n order,\n savedBetween,\n search,\n searchQuery,\n sort,\n sortBy,\n tag,\n tags: queryTags,\n targetType,\n }),\n [\n filter,\n filterFn,\n limit,\n offset,\n order,\n savedBetween,\n search,\n searchQuery,\n sort,\n sortBy,\n tag,\n queryTags,\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 (\n previousResult &&\n previousResult.totalCount === next.totalCount &&\n sameItems(previousResult.items, next.items) &&\n sameCounts(previousResult.tagCounts, next.tagCounts)\n ) {\n return previousResult;\n }\n previousResult = next;\n return previousResult;\n };\n }, [queryOptions]);\n const query = 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])) {\n return previous;\n }\n previous = next;\n return next;\n };\n }, []);\n const items = query.items;\n const totalCount = query.totalCount;\n const tagCounts = query.tagCounts;\n const tags = useKeepStoreSelector(store, tagsSelector);\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 remove = useCallback((id: string) => actions.removeItem(id), [actions]);\n const removeBatch = useCallback((ids: string[]) => actions.removeItems(ids), [actions]);\n const updateTagsBatch = useCallback(\n (ids: string[], tags?: string[]) => actions.updateTagsBatch(ids, tags),\n [actions],\n );\n const addTagsBatch = useCallback((ids: string[], tags: string[]) => actions.addTagsBatch(ids, tags), [actions]);\n const removeTagsBatch = useCallback((ids: string[], tags: string[]) => actions.removeTagsBatch(ids, tags), [actions]);\n\n return {\n items,\n totalCount,\n tags,\n tagCounts,\n isLoading,\n isHydrated,\n isMutating,\n error,\n remove,\n removeBatch,\n updateTagsBatch,\n addTagsBatch,\n removeTagsBatch,\n clear: actions.clear,\n refresh: actions.refresh,\n };\n}\n\nfunction sameItems<TMeta>(left: KeepItem<TMeta>[], right: KeepItem<TMeta>[]): boolean {\n return left.length === right.length && left.every((item, index) => item === right[index]);\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 { useEffect } from \"react\";\nimport type { KeepItemInput } from \"../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 id?: string;\n itemPayload?: 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.id ?? \"\", options.itemPayload);\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.id\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.id,\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 {\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} from \"react\";\nimport { useKeepItem } from \"./hooks/useKeepItem\";\nimport type { KeepItemInput } from \"./types\";\n\nexport type KeepButtonItem<TMeta = Record<string, unknown>> = KeepItemInput<TMeta> & {\n id: string;\n};\n\ntype KeepButtonSharedProps<TMeta> = {\n item: KeepButtonItem<TMeta>;\n children?: ReactNode | ((state: KeepButtonState<TMeta>) => ReactNode);\n savedLabel?: ReactNode;\n unsavedLabel?: ReactNode;\n disabled?: boolean;\n onToggleError?: (error: unknown) => void;\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 asChild = false,\n onToggleError,\n onClick,\n disabled,\n ...buttonProps\n}: KeepButtonProps<TMeta>) {\n const state = useKeepItem(item.id, {\n meta: item.meta,\n targetType: item.targetType,\n note: item.note,\n tags: item.tags,\n });\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\n const commonProps = {\n ...buttonProps,\n \"aria-pressed\": isSaved,\n \"aria-label\":\n (\"aria-label\" in buttonProps ? buttonProps[\"aria-label\"] : undefined) ??\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 };\n\n if (asChild) {\n return cloneElement(child as ReactElement, commonProps);\n }\n\n return (\n <button {...commonProps} type={\"type\" in buttonProps ? (buttonProps.type ?? \"button\") : \"button\"}>\n {content}\n </button>\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 type { ComponentType } from \"react\";\nimport { type UseKeepItemResult, useKeepItem } from \"./hooks/useKeepItem\";\nimport { type UseKeepListResult, useKeepList } from \"./hooks/useKeepList\";\nimport { type KeepShortcutOptions, useKeepShortcut } from \"./hooks/useKeepShortcut\";\nimport { KeepButton, type KeepButtonProps } from \"./KeepButton\";\nimport { KeepProvider, type KeepProviderProps, useKeepContext } from \"./KeepProvider\";\nimport type { KeepListOptions } from \"./query\";\nimport type { KeepInvalidItemPolicy, KeepItemInput, KeepPlugin, KeepSchema } from \"./types\";\n\nexport type CreateKeepKitOptions<TMeta = Record<string, unknown>> = {\n initialItems?: KeepProviderProps<TMeta>[\"initialItems\"];\n plugins?: KeepPlugin<TMeta>[];\n schemaVersion?: number;\n schema?: KeepSchema<TMeta>;\n invalidItemPolicy?: KeepInvalidItemPolicy;\n onInvalidItem?: KeepProviderProps<TMeta>[\"onInvalidItem\"];\n migrateMeta?: KeepProviderProps<TMeta>[\"migrateMeta\"];\n};\n\nexport type KeepKit<TMeta> = {\n KeepProvider: ComponentType<KeepProviderProps<TMeta>>;\n KeepButton: ComponentType<KeepButtonProps<TMeta>>;\n useKeepContext: () => ReturnType<typeof useKeepContext<TMeta>>;\n useKeepItem: (id: string, itemPayload?: KeepItemInput<TMeta>) => UseKeepItemResult<TMeta>;\n useKeepList: (options?: KeepListOptions<TMeta>) => UseKeepListResult<TMeta>;\n useKeepShortcut: (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 KeepProvider: (props) => <KeepProvider<TMeta> {...options} {...props} />,\n KeepButton: (props) => <KeepButton<TMeta> {...props} />,\n useKeepContext: () => useKeepContext<TMeta>(),\n useKeepItem: (id, itemPayload) => useKeepItem<TMeta>(id, itemPayload),\n useKeepList: (options) => useKeepList<TMeta>(options),\n useKeepShortcut: (shortcutOptions) => useKeepShortcut<TMeta>(shortcutOptions),\n };\n}\n"],"mappings":"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","names":["useCallback","useCallback","useRef","useSyncExternalStore","useCallback","useCallback","useMemo","useMemo","tag","useCallback","tags","useEffect","useEffect","jsx","jsx","options"]}
1
+ {"version":3,"sources":["../src/hooks/useKeepItem.ts","../src/KeepProvider.tsx","../src/hooks/useKeepStoreSelector.ts","../src/hooks/useKeepList.ts","../src/hooks/useKeepShortcut.ts","../src/KeepButton.tsx","../src/createKeepKit.tsx"],"sourcesContent":["import { useCallback } from \"react\";\nimport { useKeepStore } from \"../KeepProvider\";\nimport type { KeepItemMetadataRefresher } from \"../revalidation\";\nimport type { KeepItem, KeepItemInput } from \"../types\";\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 toggle: () => Promise<void>;\n updateNote: (note?: string) => Promise<void>;\n updateTags: (tags?: string[]) => Promise<void>;\n refreshMetadata: (refresh: KeepItemMetadataRefresher<TMeta>) => Promise<void>;\n};\n\nexport function useKeepItem<TMeta = Record<string, unknown>>(\n id: string,\n itemPayload?: KeepItemInput<TMeta>,\n): UseKeepItemResult<TMeta> {\n const { store, actions } = useKeepStore<TMeta>();\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\n const save = useCallback(async () => {\n if (!itemPayload) {\n throw new Error(`An itemPayload is required to save item \"${id}\".`);\n }\n const now = Date.now();\n await actions.saveItem({\n id,\n ...itemPayload,\n savedAt: item?.savedAt ?? now,\n updatedAt: now,\n });\n }, [actions, id, item?.savedAt, itemPayload]);\n\n const remove = useCallback(() => actions.removeItem(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 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 toggle,\n updateNote,\n updateTags,\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 {\n type KeepItemMetadataRefresher,\n type KeepItemRevalidationSummary,\n type KeepItemRevalidator,\n type RevalidateKeepItemsOptions,\n revalidateKeepItems,\n} from \"./revalidation\";\nimport { parseKeepMeta } from \"./schema\";\nimport { createBrowserStorageAdapter } from \"./storage\";\nimport { KeepStore, type KeepStoreActions } from \"./store\";\nimport type {\n KeepAction,\n KeepChangeContext,\n KeepErrorContext,\n KeepErrorHandler,\n KeepEventHandlers,\n KeepInvalidItemPolicy,\n KeepItem,\n KeepPlugin,\n KeepSchema,\n KeepSyncState,\n StorageAdapter,\n SyncCapableStorageAdapter,\n} from \"./types\";\nimport { normalizeKeepTags } from \"./types\";\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 syncState: KeepSyncState;\n saveItem: (item: KeepItem<TMeta>) => Promise<void>;\n updateNote: (id: string, note?: string) => Promise<void>;\n updateTags: (id: string, tags?: 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 clear: () => Promise<void>;\n refresh: () => Promise<void>;\n flushSync: () => Promise<void>;\n refreshItemMetadata: (id: string, refresh: KeepItemMetadataRefresher<TMeta>) => Promise<void>;\n revalidateItems: (\n revalidator: KeepItemRevalidator<TMeta>,\n options?: RevalidateKeepItemsOptions,\n ) => Promise<KeepItemRevalidationSummary<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 }\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 onError,\n plugins = [],\n schemaVersion,\n schema,\n invalidItemPolicy = \"error\",\n onInvalidItem,\n migrateMeta,\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 });\n }\n const store = storeRef.current;\n const state = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n const { items, isLoading, isHydrated, isMutating, error } = state;\n const itemsRef = useRef(items);\n const pluginsRef = useRef(plugins);\n pluginsRef.current = plugins;\n const handlersRef = useRef({ onSave, onRemove, onNoteUpdate, onTagsUpdate, onChange, onError });\n handlersRef.current = { onSave, onRemove, onNoteUpdate, onTagsUpdate, onChange, 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 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 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 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 next: [...previous.filter((current) => current.id !== normalizedItem.id), normalizedItem].sort(\n (a, b) => b.updatedAt - a.updatedAt,\n ),\n persist: () => storage.set(normalizedItem),\n onSuccess: () => handlersRef.current.onSave?.(normalizedItem),\n pluginContext: { action: \"save\", id: normalizedItem.id, item: normalizedItem },\n }));\n },\n [reportError, 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 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 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>,\n options: RevalidateKeepItemsOptions = {},\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 summary = await revalidateKeepItems(previous, revalidator, options);\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 [enqueueOperation, reportError, runAfterPlugins, runBeforePlugins, setItems, storage, store],\n );\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\n const value = useMemo<KeepContextValue<TMeta>>(\n () => ({\n items,\n isLoading,\n isHydrated,\n isMutating,\n error,\n syncState,\n saveItem,\n updateNote,\n updateTags,\n updateTagsBatch,\n addTagsBatch,\n removeTagsBatch,\n removeItem,\n removeItems,\n clear,\n refresh,\n flushSync,\n refreshItemMetadata,\n revalidateItems,\n }),\n [\n clear,\n error,\n flushSync,\n isHydrated,\n isLoading,\n isMutating,\n items,\n syncState,\n refresh,\n removeItem,\n saveItem,\n updateNote,\n updateTags,\n updateTagsBatch,\n addTagsBatch,\n removeTagsBatch,\n removeItems,\n refreshItemMetadata,\n revalidateItems,\n ],\n );\n\n const actions = useMemo<KeepStoreActions<TMeta>>(\n () => ({\n saveItem,\n updateNote,\n updateTags,\n updateTagsBatch,\n addTagsBatch,\n removeTagsBatch,\n removeItem,\n removeItems,\n clear,\n refresh,\n refreshItemMetadata,\n revalidateItems,\n }),\n [\n addTagsBatch,\n clear,\n refresh,\n removeItem,\n removeItems,\n removeTagsBatch,\n saveItem,\n updateNote,\n updateTags,\n updateTagsBatch,\n refreshItemMetadata,\n revalidateItems,\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 = Object.freeze({\n status: \"idle\",\n pendingCount: 0,\n conflictIds: [],\n});\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\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 { useCallback, useRef, useSyncExternalStore } from \"react\";\nimport type { KeepStore, KeepStoreState } from \"../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 { useCallback, useMemo } from \"react\";\nimport { useKeepStore } from \"../KeepProvider\";\nimport { type KeepListOptions, type QueryKeepItemsResult, queryKeepItems } from \"../query\";\nimport type { KeepItemRevalidationSummary, KeepItemRevalidator, RevalidateKeepItemsOptions } from \"../revalidation\";\nimport type { KeepItem } from \"../types\";\nimport { useKeepStoreSelector } from \"./useKeepStoreSelector\";\n\nexport type { KeepListOptions } from \"../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 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 updateTagsBatch: (ids: string[], tags?: string[]) => Promise<void>;\n addTagsBatch: (ids: string[], tags: string[]) => Promise<void>;\n removeTagsBatch: (ids: string[], tags: string[]) => Promise<void>;\n clear: () => Promise<void>;\n refresh: () => Promise<void>;\n revalidate: (\n revalidator: KeepItemRevalidator<TMeta>,\n options?: RevalidateKeepItemsOptions,\n ) => Promise<KeepItemRevalidationSummary<TMeta>>;\n};\n\nexport function useKeepList<TMeta = Record<string, unknown>>(\n options: KeepListOptions<TMeta> = {},\n): UseKeepListResult<TMeta> {\n const { store, actions } = useKeepStore<TMeta>();\n const {\n filter,\n filterFn,\n limit,\n offset,\n order,\n savedBetween,\n search,\n searchQuery,\n sort,\n sortBy,\n tag,\n tags: queryTags,\n targetType,\n } = options;\n const queryOptions = useMemo<KeepListOptions<TMeta>>(\n () => ({\n filter,\n filterFn,\n limit,\n offset,\n order,\n savedBetween,\n search,\n searchQuery,\n sort,\n sortBy,\n tag,\n tags: queryTags,\n targetType,\n }),\n [\n filter,\n filterFn,\n limit,\n offset,\n order,\n savedBetween,\n search,\n searchQuery,\n sort,\n sortBy,\n tag,\n queryTags,\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 (\n previousResult &&\n previousResult.totalCount === next.totalCount &&\n sameItems(previousResult.items, next.items) &&\n sameCounts(previousResult.tagCounts, next.tagCounts)\n ) {\n return previousResult;\n }\n previousResult = next;\n return previousResult;\n };\n }, [queryOptions]);\n const query = 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])) {\n return previous;\n }\n previous = next;\n return next;\n };\n }, []);\n const items = query.items;\n const totalCount = query.totalCount;\n const tagCounts = query.tagCounts;\n const tags = useKeepStoreSelector(store, tagsSelector);\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 remove = useCallback((id: string) => actions.removeItem(id), [actions]);\n const removeBatch = useCallback((ids: string[]) => actions.removeItems(ids), [actions]);\n const updateTagsBatch = useCallback(\n (ids: string[], tags?: string[]) => actions.updateTagsBatch(ids, tags),\n [actions],\n );\n const addTagsBatch = useCallback((ids: string[], tags: string[]) => actions.addTagsBatch(ids, tags), [actions]);\n const removeTagsBatch = useCallback((ids: string[], tags: string[]) => actions.removeTagsBatch(ids, tags), [actions]);\n\n return {\n items,\n totalCount,\n tags,\n tagCounts,\n isLoading,\n isHydrated,\n isMutating,\n error,\n remove,\n removeBatch,\n updateTagsBatch,\n addTagsBatch,\n removeTagsBatch,\n clear: actions.clear,\n refresh: actions.refresh,\n revalidate: actions.revalidateItems,\n };\n}\n\nfunction sameItems<TMeta>(left: KeepItem<TMeta>[], right: KeepItem<TMeta>[]): boolean {\n return left.length === right.length && left.every((item, index) => item === right[index]);\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 { useEffect } from \"react\";\nimport type { KeepItemInput } from \"../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 id?: string;\n itemPayload?: 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.id ?? \"\", options.itemPayload);\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.id\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.id,\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 {\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} from \"react\";\nimport { useKeepItem } from \"./hooks/useKeepItem\";\nimport type { KeepItemInput } from \"./types\";\n\nexport type KeepButtonItem<TMeta = Record<string, unknown>> = KeepItemInput<TMeta> & {\n id: string;\n};\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};\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 ...buttonProps\n}: KeepButtonProps<TMeta>) {\n const state = useKeepItem(item.id, {\n meta: item.meta,\n targetType: item.targetType,\n note: item.note,\n tags: item.tags,\n });\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\n const commonProps = {\n ...buttonProps,\n \"aria-pressed\": isSaved,\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 };\n\n if (asChild) {\n return cloneElement(child as ReactElement, commonProps);\n }\n\n return (\n <button {...commonProps} type={\"type\" in buttonProps ? (buttonProps.type ?? \"button\") : \"button\"}>\n {content}\n </button>\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 type { ComponentType } from \"react\";\nimport { type UseKeepItemResult, useKeepItem } from \"./hooks/useKeepItem\";\nimport { type UseKeepListResult, useKeepList } from \"./hooks/useKeepList\";\nimport { type KeepShortcutOptions, useKeepShortcut } from \"./hooks/useKeepShortcut\";\nimport { KeepButton, type KeepButtonProps } from \"./KeepButton\";\nimport { KeepProvider, type KeepProviderProps, useKeepContext } from \"./KeepProvider\";\nimport type { KeepListOptions } from \"./query\";\nimport type { KeepInvalidItemPolicy, KeepItemInput, KeepPlugin, KeepSchema } from \"./types\";\n\nexport type CreateKeepKitOptions<TMeta = Record<string, unknown>> = {\n initialItems?: KeepProviderProps<TMeta>[\"initialItems\"];\n plugins?: KeepPlugin<TMeta>[];\n schemaVersion?: number;\n schema?: KeepSchema<TMeta>;\n invalidItemPolicy?: KeepInvalidItemPolicy;\n onInvalidItem?: KeepProviderProps<TMeta>[\"onInvalidItem\"];\n migrateMeta?: KeepProviderProps<TMeta>[\"migrateMeta\"];\n};\n\nexport type KeepKit<TMeta> = {\n KeepProvider: ComponentType<KeepProviderProps<TMeta>>;\n KeepButton: ComponentType<KeepButtonProps<TMeta>>;\n useKeepContext: () => ReturnType<typeof useKeepContext<TMeta>>;\n useKeepItem: (id: string, itemPayload?: KeepItemInput<TMeta>) => UseKeepItemResult<TMeta>;\n useKeepList: (options?: KeepListOptions<TMeta>) => UseKeepListResult<TMeta>;\n useKeepShortcut: (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 KeepProvider: (props) => <KeepProvider<TMeta> {...options} {...props} />,\n KeepButton: (props) => <KeepButton<TMeta> {...props} />,\n useKeepContext: () => useKeepContext<TMeta>(),\n useKeepItem: (id, itemPayload) => useKeepItem<TMeta>(id, itemPayload),\n useKeepList: (options) => useKeepList<TMeta>(options),\n useKeepShortcut: (shortcutOptions) => useKeepShortcut<TMeta>(shortcutOptions),\n };\n}\n"],"mappings":"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","names":["useCallback","refresh","useCallback","useRef","useSyncExternalStore","useCallback","useCallback","useMemo","useMemo","tag","useCallback","tags","useEffect","useEffect","jsx","jsx","options"]}
package/dist/schema.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { K as KeepSchema, a as KeepItem } from './types-DtILwEQ0.js';
1
+ import { K as KeepSchema, a as KeepItem } from './types-BRfvVnCA.js';
2
2
 
3
3
  declare class KeepSchemaValidationError extends Error {
4
4
  readonly cause?: unknown;
package/dist/storage.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { y as SyncQueueAdapter, x as SyncOperation, w as SyncCapableStorageAdapter, S as StorageAdapter, R as RemoteSyncDriver, i as KeepConflictResolver, t as KeepSyncState, a as KeepItem } from './types-DtILwEQ0.js';
1
+ import { y as SyncQueueAdapter, x as SyncOperation, w as SyncCapableStorageAdapter, S as StorageAdapter, R as RemoteSyncDriver, i as KeepConflictResolver, t as KeepSyncState, a as KeepItem } from './types-BRfvVnCA.js';
2
2
 
3
3
  type LocalStorageSyncQueueOptions = {
4
4
  key?: string;
package/dist/storage.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  SyncStorageAdapter,
16
16
  createBrowserStorageAdapter,
17
17
  createStorageAdapter
18
- } from "./chunk-C3SOQCVW.js";
18
+ } from "./chunk-X4UVKTBK.js";
19
19
  export {
20
20
  DEFAULT_INDEXEDDB_DATABASE,
21
21
  DEFAULT_INDEXEDDB_STORE,
@@ -0,0 +1,102 @@
1
+ import { a as KeepItem, S as StorageAdapter } from './types-BRfvVnCA.js';
2
+
3
+ type KeepListOptions<TMeta = Record<string, unknown>> = {
4
+ targetType?: string;
5
+ tag?: string;
6
+ tags?: string[];
7
+ sort?: {
8
+ by: "savedAt" | "updatedAt";
9
+ direction?: "asc" | "desc";
10
+ };
11
+ searchQuery?: string;
12
+ search?: {
13
+ query: string;
14
+ mode?: "and" | "or";
15
+ tokenize?: boolean;
16
+ fields?: Array<"note" | "meta" | "tags">;
17
+ };
18
+ sortBy?: "savedAt" | "updatedAt";
19
+ order?: "asc" | "desc";
20
+ limit?: number;
21
+ offset?: number;
22
+ filter?: (item: KeepItem<TMeta>) => boolean;
23
+ filterFn?: (item: KeepItem<TMeta>) => boolean;
24
+ savedBetween?: readonly [Date | number, Date | number];
25
+ };
26
+ type QueryKeepItemsResult<TMeta = Record<string, unknown>> = {
27
+ items: KeepItem<TMeta>[];
28
+ totalCount: number;
29
+ tagCounts: Record<string, number>;
30
+ };
31
+ /** Apply the same filtering and pagination rules as useKeepList without React. */
32
+ declare function queryKeepItems<TMeta = Record<string, unknown>>(source: KeepItem<TMeta>[], options?: KeepListOptions<TMeta>): QueryKeepItemsResult<TMeta>;
33
+ declare function getTagCounts<TMeta = Record<string, unknown>>(items: KeepItem<TMeta>[]): Record<string, number>;
34
+
35
+ type KeepItemStatus = "available" | "deleted" | "private" | "expired" | "unknown";
36
+ type KeepItemRevalidationResult<TMeta = Record<string, unknown>> = {
37
+ status: "available";
38
+ meta?: TMeta;
39
+ } | {
40
+ status: Exclude<KeepItemStatus, "available">;
41
+ reason?: string;
42
+ };
43
+ type KeepItemRevalidator<TMeta = Record<string, unknown>> = (item: KeepItem<TMeta>) => KeepItemRevalidationResult<TMeta> | KeepItemRevalidationResult<TMeta>["status"] | Promise<KeepItemRevalidationResult<TMeta> | KeepItemRevalidationResult<TMeta>["status"]>;
44
+ type KeepItemMetadataRefresher<TMeta = Record<string, unknown>> = (item: KeepItem<TMeta>) => TMeta | Promise<TMeta>;
45
+ /** Return whether source metadata should be fetched again based on its age. */
46
+ declare function isKeepItemMetadataStale<TMeta>(item: KeepItem<TMeta>, maxAgeMs: number, now?: () => number): boolean;
47
+ type KeepItemRevalidationRecord<TMeta = Record<string, unknown>> = {
48
+ item: KeepItem<TMeta>;
49
+ status: KeepItemStatus;
50
+ reason?: string;
51
+ updated: boolean;
52
+ };
53
+ type RevalidateKeepItemsOptions = {
54
+ /** Statuses that should be removed after they are detected. Detection is the default. */
55
+ removeStatuses?: Array<Exclude<KeepItemStatus, "available">>;
56
+ now?: () => number;
57
+ };
58
+ type KeepItemRevalidationSummary<TMeta = Record<string, unknown>> = {
59
+ items: KeepItem<TMeta>[];
60
+ checked: number;
61
+ updated: number;
62
+ removed: number;
63
+ updatedItems: KeepItem<TMeta>[];
64
+ removedIds: string[];
65
+ results: KeepItemRevalidationRecord<TMeta>[];
66
+ };
67
+ /** Revalidate saved items without coupling the checker to a network client. */
68
+ declare function revalidateKeepItems<TMeta = Record<string, unknown>>(source: KeepItem<TMeta>[], revalidator: KeepItemRevalidator<TMeta>, options?: RevalidateKeepItemsOptions): Promise<KeepItemRevalidationSummary<TMeta>>;
69
+ /** Revalidate and persist saved items for framework-neutral applications. */
70
+ declare function reconcileKeepItems<TMeta = Record<string, unknown>>(storage: StorageAdapter<TMeta>, revalidator: KeepItemRevalidator<TMeta>, options?: RevalidateKeepItemsOptions): Promise<KeepItemRevalidationSummary<TMeta>>;
71
+
72
+ type KeepStoreState<TMeta = Record<string, unknown>> = {
73
+ items: KeepItem<TMeta>[];
74
+ isLoading: boolean;
75
+ isHydrated: boolean;
76
+ isMutating: boolean;
77
+ error: unknown | null;
78
+ };
79
+ type KeepStoreActions<TMeta = Record<string, unknown>> = {
80
+ saveItem: (item: KeepItem<TMeta>) => Promise<void>;
81
+ updateNote: (id: string, note?: string) => Promise<void>;
82
+ updateTags: (id: string, tags?: string[]) => Promise<void>;
83
+ updateTagsBatch: (ids: string[], tags?: string[]) => Promise<void>;
84
+ addTagsBatch: (ids: string[], tags: string[]) => Promise<void>;
85
+ removeTagsBatch: (ids: string[], tags: string[]) => Promise<void>;
86
+ removeItem: (id: string) => Promise<void>;
87
+ removeItems: (ids: string[]) => Promise<void>;
88
+ clear: () => Promise<void>;
89
+ refresh: () => Promise<void>;
90
+ refreshItemMetadata: (id: string, refresh: KeepItemMetadataRefresher<TMeta>) => Promise<void>;
91
+ revalidateItems: (revalidator: KeepItemRevalidator<TMeta>, options?: RevalidateKeepItemsOptions) => Promise<KeepItemRevalidationSummary<TMeta>>;
92
+ };
93
+ declare class KeepStore<TMeta = Record<string, unknown>> {
94
+ private state;
95
+ private readonly listeners;
96
+ constructor(initialState: KeepStoreState<TMeta>);
97
+ getSnapshot: () => KeepStoreState<TMeta>;
98
+ subscribe: (listener: () => void) => (() => void);
99
+ setState(next: Partial<KeepStoreState<TMeta>>): void;
100
+ }
101
+
102
+ export { type KeepItemMetadataRefresher as K, type QueryKeepItemsResult as Q, type RevalidateKeepItemsOptions as R, type KeepItemRevalidationRecord as a, type KeepItemRevalidationResult as b, type KeepItemRevalidationSummary as c, type KeepItemRevalidator as d, type KeepItemStatus as e, type KeepListOptions as f, KeepStore as g, type KeepStoreActions as h, type KeepStoreState as i, getTagCounts as j, isKeepItemMetadataStale as k, revalidateKeepItems as l, queryKeepItems as q, reconcileKeepItems as r };