@keepkit/core 0.9.0 → 0.10.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.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, ButtonHTMLAttributes, MouseEvent, HTMLAttributes, ReactElement, ErrorInfo, Component, PropsWithChildren, ComponentType } from 'react';
3
- import { K as KeepItemMetadataRefresher, d as KeepItemRevalidator, R as RevalidateKeepItemsOptions, c as KeepItemRevalidationSummary, f as KeepListQuery, g as KeepStore, h as KeepStoreActions } from './store-CqNh-2DS.js';
4
- export { b as KeepItemRevalidationResult, e as KeepItemStatus, k as isKeepItemMetadataStale } from './store-CqNh-2DS.js';
5
- import { m as KeepItemInput, a as KeepItem, l as KeepEventHandlers, S as StorageAdapter, d as KeepPlugin, K as KeepSchema, b as KeepInvalidItemPolicy, f as KeepChangeContext, t as KeepSyncState } from './types-BCziYE6E.js';
3
+ import { f as KeepItemMetadataRefresher, k as KeepItemRevalidator, R as RevalidateKeepItemsOptions, j as KeepItemRevalidationSummary, l as KeepListQuery, g as KeepItemResolver, I as ImportItemsOptions, a as ImportItemsResult, m as KeepStore, n as KeepStoreActions } from './store-Cgqx7_xd.js';
4
+ export { i as KeepItemRevalidationResult, s as isKeepItemMetadataStale } from './store-Cgqx7_xd.js';
5
+ import { m as KeepItemInput, a as KeepItem, k as KeepEventHandlers, S as StorageAdapter, c as KeepPlugin, K as KeepSchema, l as KeepInvalidItemPolicy, e as KeepChangeContext, u as KeepSyncState } from './types--YahIoEB.js';
6
+ export { n as KeepItemStatus } from './types--YahIoEB.js';
6
7
 
7
8
  type UseKeepItemResult<TMeta = Record<string, unknown>> = {
8
9
  item: KeepItem<TMeta> | undefined;
@@ -40,7 +41,7 @@ type UseKeepListResult<TMeta = Record<string, unknown>> = {
40
41
  removeTagsBatch: (ids: string[], tags: string[]) => Promise<void>;
41
42
  clear: () => Promise<void>;
42
43
  refresh: () => Promise<void>;
43
- revalidate: (revalidator: KeepItemRevalidator<TMeta>, options?: RevalidateKeepItemsOptions) => Promise<KeepItemRevalidationSummary<TMeta>>;
44
+ revalidate: (revalidator: KeepItemRevalidator<TMeta>, options?: RevalidateKeepItemsOptions<TMeta>) => Promise<KeepItemRevalidationSummary<TMeta>>;
44
45
  };
45
46
  declare function useKeepList<TMeta = Record<string, unknown>>(query?: KeepListQuery<TMeta>): UseKeepListResult<TMeta>;
46
47
 
@@ -133,7 +134,9 @@ type KeepContextValue<TMeta = Record<string, unknown>> = {
133
134
  refresh: () => Promise<void>;
134
135
  flushSync: () => Promise<void>;
135
136
  refreshItemMetadata: (id: string, refresh: KeepItemMetadataRefresher<TMeta>) => Promise<void>;
136
- revalidateItems: (revalidator: KeepItemRevalidator<TMeta>, options?: RevalidateKeepItemsOptions) => Promise<KeepItemRevalidationSummary<TMeta>>;
137
+ revalidateItems: (revalidator?: KeepItemRevalidator<TMeta>, options?: RevalidateKeepItemsOptions<TMeta>) => Promise<KeepItemRevalidationSummary<TMeta>>;
138
+ exportBackup: () => Promise<string>;
139
+ importBackup: (data: string, options?: Pick<ImportItemsOptions<TMeta>, "mode" | "invalidItemPolicy" | "onInvalidItem">) => Promise<ImportItemsResult<TMeta>>;
137
140
  };
138
141
  type KeepProviderProps<TMeta = Record<string, unknown>> = PropsWithChildren<KeepEventHandlers<TMeta> & {
139
142
  storage?: StorageAdapter<TMeta>;
@@ -153,12 +156,14 @@ type KeepProviderProps<TMeta = Record<string, unknown>> = PropsWithChildren<Keep
153
156
  fallback?: KeepErrorBoundaryProps["fallback"];
154
157
  onBoundaryError?: KeepErrorBoundaryProps["onError"];
155
158
  boundaryResetKey?: unknown;
159
+ validateItem?: KeepItemRevalidator<TMeta>;
160
+ resolveItem?: KeepItemResolver<TMeta>;
156
161
  }>;
157
162
  type KeepStoreAccess<TMeta> = {
158
163
  store: KeepStore<TMeta>;
159
164
  actions: KeepStoreActions<TMeta>;
160
165
  };
161
- declare function KeepProvider<TMeta = Record<string, unknown>>({ storage, initialItems, onSave, onRemove, onNoteUpdate, onTagsUpdate, onChange, onError, plugins, schemaVersion, schema, invalidItemPolicy, onInvalidItem, migrateMeta, fallback, onBoundaryError, boundaryResetKey, children, }: KeepProviderProps<TMeta>): react.JSX.Element;
166
+ declare function KeepProvider<TMeta = Record<string, unknown>>({ storage, initialItems, onSave, onRemove, onNoteUpdate, onTagsUpdate, onChange, onError, plugins, schemaVersion, schema, invalidItemPolicy, onInvalidItem, migrateMeta, fallback, onBoundaryError, boundaryResetKey, validateItem, resolveItem, children, }: KeepProviderProps<TMeta>): react.JSX.Element;
162
167
  declare function useKeepContext<TMeta = Record<string, unknown>>(): KeepContextValue<TMeta>;
163
168
  declare function useKeepStore<TMeta = Record<string, unknown>>(): KeepStoreAccess<TMeta>;
164
169
 
@@ -174,4 +179,4 @@ type KeepKit<TMeta> = {
174
179
  /** Create an app-specific, fully typed set of KeepKit components and hooks. */
175
180
  declare function createKeepKit<TMeta = Record<string, unknown>>(options?: CreateKeepKitOptions<TMeta>): KeepKit<TMeta>;
176
181
 
177
- export { type CreateKeepKitOptions, KeepButton, type KeepButtonItem, type KeepButtonProps, type KeepButtonState, type KeepContextValue, KeepErrorBoundary, type KeepErrorBoundaryProps, KeepItemMetadataRefresher, KeepItemRevalidationSummary, KeepItemRevalidator, type KeepKit, KeepListQuery, KeepProvider, type KeepProviderProps, type KeepShortcutModifier, type KeepShortcutOptions, RevalidateKeepItemsOptions, type UseKeepItemResult, type UseKeepListResult, createKeepKit, useKeepContext, useKeepItem, useKeepList, useKeepShortcut, useKeepStore };
182
+ export { type CreateKeepKitOptions, KeepButton, type KeepButtonItem, type KeepButtonProps, type KeepButtonState, type KeepContextValue, KeepErrorBoundary, type KeepErrorBoundaryProps, KeepItemMetadataRefresher, KeepItemResolver, KeepItemRevalidationSummary, KeepItemRevalidator, type KeepKit, KeepListQuery, KeepProvider, type KeepProviderProps, type KeepShortcutModifier, type KeepShortcutOptions, RevalidateKeepItemsOptions, type UseKeepItemResult, type UseKeepListResult, createKeepKit, useKeepContext, useKeepItem, useKeepList, useKeepShortcut, useKeepStore };
package/dist/react.js CHANGED
@@ -1,10 +1,12 @@
1
1
  "use client";
2
2
  import {
3
3
  KeepStore,
4
+ exportItems,
5
+ importItems,
4
6
  isKeepItemMetadataStale,
5
7
  queryKeepItems,
6
8
  revalidateKeepItems
7
- } from "./chunk-AWQWKK4V.js";
9
+ } from "./chunk-XF5VI6O5.js";
8
10
  import {
9
11
  parseKeepMeta
10
12
  } from "./chunk-THZ3ACR2.js";
@@ -12,7 +14,7 @@ import "./chunk-5QSZP6MT.js";
12
14
  import {
13
15
  createBrowserStorageAdapter,
14
16
  normalizeKeepTags
15
- } from "./chunk-DBRHZ6XU.js";
17
+ } from "./chunk-EXE4E3GA.js";
16
18
 
17
19
  // src/hooks/useKeepItem.ts
18
20
  import { useCallback as useCallback3 } from "react";
@@ -77,6 +79,8 @@ function KeepProvider({
77
79
  fallback,
78
80
  onBoundaryError,
79
81
  boundaryResetKey,
82
+ validateItem,
83
+ resolveItem,
80
84
  children
81
85
  }) {
82
86
  const content = /* @__PURE__ */ jsx(
@@ -96,6 +100,8 @@ function KeepProvider({
96
100
  invalidItemPolicy,
97
101
  onInvalidItem,
98
102
  migrateMeta,
103
+ validateItem,
104
+ resolveItem,
99
105
  children
100
106
  }
101
107
  );
@@ -117,6 +123,8 @@ function KeepProviderContent({
117
123
  invalidItemPolicy = "error",
118
124
  onInvalidItem,
119
125
  migrateMeta,
126
+ validateItem,
127
+ resolveItem,
120
128
  children
121
129
  }) {
122
130
  const storeRef = useRef(null);
@@ -482,7 +490,13 @@ function KeepProviderContent({
482
490
  const previous = itemsRef.current;
483
491
  let persistenceStarted = false;
484
492
  try {
485
- const summary = await revalidateKeepItems(previous, revalidator, options);
493
+ const activeRevalidator = revalidator ?? validateItem;
494
+ if (!activeRevalidator)
495
+ throw new Error("KeepProvider.revalidateItems requires a revalidator or validateItem.");
496
+ const summary = await revalidateKeepItems(previous, activeRevalidator, {
497
+ ...options,
498
+ resolveItem: options.resolveItem ?? resolveItem
499
+ });
486
500
  const pluginContext = { action: "revalidate", items: summary.updatedItems };
487
501
  await runBeforePlugins(pluginContext);
488
502
  if (summary.updatedItems.length > 0) {
@@ -518,7 +532,17 @@ function KeepProviderContent({
518
532
  if (pendingMutationsRef.current === 0) store.setState({ isMutating: false });
519
533
  });
520
534
  },
521
- [enqueueOperation, reportError, runAfterPlugins, runBeforePlugins, setItems, storage, store]
535
+ [
536
+ enqueueOperation,
537
+ reportError,
538
+ resolveItem,
539
+ runAfterPlugins,
540
+ runBeforePlugins,
541
+ setItems,
542
+ storage,
543
+ store,
544
+ validateItem
545
+ ]
522
546
  );
523
547
  const refreshItemMetadata = useCallback(
524
548
  async (id, refresh2) => {
@@ -533,6 +557,34 @@ function KeepProviderContent({
533
557
  [revalidateItems]
534
558
  );
535
559
  const flushSync = useCallback(() => syncStorage ? syncStorage.flushSync() : Promise.resolve(), [syncStorage]);
560
+ const exportBackup = useCallback(() => exportItems(storage), [storage]);
561
+ const importBackup = useCallback(
562
+ async (data, options = {}) => {
563
+ pendingMutationsRef.current += 1;
564
+ store.setState({ isMutating: true });
565
+ const run = enqueueOperation(async () => {
566
+ try {
567
+ const result = await importItems(storage, data, {
568
+ ...options,
569
+ schema: migrationRef.current.schema,
570
+ invalidItemPolicy: options.invalidItemPolicy ?? migrationRef.current.invalidItemPolicy,
571
+ onInvalidItem: options.onInvalidItem ?? migrationRef.current.onInvalidItem
572
+ });
573
+ setItems(result.items);
574
+ store.setState({ error: null });
575
+ return result;
576
+ } catch (cause) {
577
+ reportError(cause, { action: "import" });
578
+ throw cause;
579
+ }
580
+ });
581
+ return run.finally(() => {
582
+ pendingMutationsRef.current -= 1;
583
+ if (pendingMutationsRef.current === 0) store.setState({ isMutating: false });
584
+ });
585
+ },
586
+ [enqueueOperation, reportError, setItems, storage, store]
587
+ );
536
588
  const value = useMemo(
537
589
  () => ({
538
590
  items,
@@ -554,7 +606,9 @@ function KeepProviderContent({
554
606
  refresh,
555
607
  flushSync,
556
608
  refreshItemMetadata,
557
- revalidateItems
609
+ revalidateItems,
610
+ exportBackup,
611
+ importBackup
558
612
  }),
559
613
  [
560
614
  clear,
@@ -576,7 +630,9 @@ function KeepProviderContent({
576
630
  removeTagsBatch,
577
631
  removeItems,
578
632
  refreshItemMetadata,
579
- revalidateItems
633
+ revalidateItems,
634
+ exportBackup,
635
+ importBackup
580
636
  ]
581
637
  );
582
638
  const actions = useMemo(
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/useKeepItem.ts","../src/KeepProvider.tsx","../src/KeepErrorBoundary.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\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\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 savedAt: item?.savedAt ?? now,\n updatedAt: now,\n });\n }, [actions, input, item?.savedAt]);\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 { KeepErrorBoundary, type KeepErrorBoundaryProps } from \"./KeepErrorBoundary\";\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 lastChange?: KeepChangeContext<TMeta>;\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 /** Render this content when a descendant or provider render unexpectedly throws. */\n fallback?: KeepErrorBoundaryProps[\"fallback\"];\n onBoundaryError?: KeepErrorBoundaryProps[\"onError\"];\n boundaryResetKey?: unknown;\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 fallback,\n onBoundaryError,\n boundaryResetKey,\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 onError={onError}\n plugins={plugins}\n schemaVersion={schemaVersion}\n schema={schema}\n invalidItemPolicy={invalidItemPolicy}\n onInvalidItem={onInvalidItem}\n migrateMeta={migrateMeta}\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 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 lastChange: undefined,\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 } = 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 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 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 lastChange,\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 lastChange,\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 { 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 \"../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 KeepListQuery, type QueryKeepItemsResult, queryKeepItems } from \"../query\";\nimport type { KeepItemRevalidationSummary, KeepItemRevalidator, RevalidateKeepItemsOptions } from \"../revalidation\";\nimport type { KeepItem } from \"../types\";\nimport { useKeepStoreSelector } from \"./useKeepStoreSelector\";\n\nexport type { KeepListQuery } 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 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 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 query: KeepListQuery<TMeta> = {},\n): UseKeepListResult<TMeta> {\n const { store, actions } = useKeepStore<TMeta>();\n const { filter, pagination, savedBetween, search, sort, tags, targetType } = query;\n const queryOptions = useMemo<KeepListQuery<TMeta>>(\n () => ({ filter, pagination, savedBetween, search, sort, tags, targetType }),\n [filter, pagination, savedBetween, search, sort, tags, targetType],\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 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\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 updateTagsBatch,\n addTagsBatch,\n removeTagsBatch,\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 { 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 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 {\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\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);\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 \"data-state\": 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 };\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 { KeepListQuery } from \"./query\";\nimport type { KeepItemInput } from \"./types\";\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 useList: (query?: KeepListQuery<TMeta>) => UseKeepListResult<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 useList: (query) => useKeepList<TMeta>(query),\n useShortcut: (shortcutOptions) => useKeepShortcut<TMeta>(shortcutOptions),\n };\n}\n"],"mappings":"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","names":["useCallback","refresh","useCallback","useRef","useSyncExternalStore","useCallback","useCallback","useMemo","useMemo","useCallback","useEffect","useEffect","jsx","jsx"]}
1
+ {"version":3,"sources":["../src/hooks/useKeepItem.ts","../src/KeepProvider.tsx","../src/KeepErrorBoundary.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\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\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 savedAt: item?.savedAt ?? now,\n updatedAt: now,\n });\n }, [actions, input, item?.savedAt]);\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 { exportItems, type ImportItemsOptions, type ImportItemsResult, importItems } from \"./backup\";\nimport { KeepErrorBoundary, type KeepErrorBoundaryProps } from \"./KeepErrorBoundary\";\nimport type { KeepItemResolver } from \"./revalidation\";\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 lastChange?: KeepChangeContext<TMeta>;\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<TMeta>,\n ) => Promise<KeepItemRevalidationSummary<TMeta>>;\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 }\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 fallback,\n onBoundaryError,\n boundaryResetKey,\n validateItem,\n resolveItem,\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 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 >\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 onError,\n plugins = [],\n schemaVersion,\n schema,\n invalidItemPolicy = \"error\",\n onInvalidItem,\n migrateMeta,\n validateItem,\n resolveItem,\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 });\n }\n const store = storeRef.current;\n const state = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n const { items, isLoading, isHydrated, isMutating, error, lastChange } = 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 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 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> | 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 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 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 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 exportBackup,\n importBackup,\n }),\n [\n clear,\n error,\n lastChange,\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 exportBackup,\n importBackup,\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 { 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 \"../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 KeepListQuery, type QueryKeepItemsResult, queryKeepItems } from \"../query\";\nimport type { KeepItemRevalidationSummary, KeepItemRevalidator, RevalidateKeepItemsOptions } from \"../revalidation\";\nimport type { KeepItem } from \"../types\";\nimport { useKeepStoreSelector } from \"./useKeepStoreSelector\";\n\nexport type { KeepListQuery } 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 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 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<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 { filter, pagination, savedBetween, search, sort, tags, targetType } = query;\n const queryOptions = useMemo<KeepListQuery<TMeta>>(\n () => ({ filter, pagination, savedBetween, search, sort, tags, targetType }),\n [filter, pagination, savedBetween, search, sort, tags, targetType],\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 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\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 updateTagsBatch,\n addTagsBatch,\n removeTagsBatch,\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 { 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 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 {\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\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);\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 \"data-state\": 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 };\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 { KeepListQuery } from \"./query\";\nimport type { KeepItemInput } from \"./types\";\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 useList: (query?: KeepListQuery<TMeta>) => UseKeepListResult<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 useList: (query) => useKeepList<TMeta>(query),\n useShortcut: (shortcutOptions) => useKeepShortcut<TMeta>(shortcutOptions),\n };\n}\n"],"mappings":"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","names":["useCallback","refresh","useCallback","useRef","useSyncExternalStore","useCallback","useCallback","useMemo","useMemo","useCallback","useEffect","useEffect","jsx","jsx"]}
package/dist/schema.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { K as KeepSchema, a as KeepItem } from './types-BCziYE6E.js';
1
+ import { K as KeepSchema, a as KeepItem } from './types--YahIoEB.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-BCziYE6E.js';
1
+ import { z as SyncQueueAdapter, y as SyncOperation, x as SyncCapableStorageAdapter, S as StorageAdapter, R as RemoteSyncDriver, h as KeepConflictResolver, u as KeepSyncState, a as KeepItem } from './types--YahIoEB.js';
2
2
 
3
3
  type LocalStorageSyncQueueOptions = {
4
4
  key?: string;
@@ -24,6 +24,11 @@ type SyncStorageAdapterOptions<TMeta = Record<string, unknown>> = {
24
24
  clientId?: string;
25
25
  now?: () => number;
26
26
  resolveConflict?: KeepConflictResolver<TMeta>;
27
+ userId?: string;
28
+ tenantId?: string;
29
+ maxRetries?: number;
30
+ retryDelayMs?: number;
31
+ retryBackoff?: number;
27
32
  };
28
33
  declare const DEFAULT_SYNC_QUEUE_KEY = "keepkit:sync-queue";
29
34
  declare const DEFAULT_SYNC_QUEUE_DATABASE = "keepkit-sync";
@@ -73,6 +78,10 @@ declare class SyncStorageAdapter<TMeta = Record<string, unknown>> implements Syn
73
78
  private readonly clientId;
74
79
  private readonly now;
75
80
  private readonly resolveConflict?;
81
+ private readonly scope?;
82
+ private readonly maxRetries;
83
+ private readonly retryDelayMs;
84
+ private readonly retryBackoff;
76
85
  private readonly listeners;
77
86
  private readonly dataListeners;
78
87
  private queueItems;
@@ -93,9 +102,12 @@ declare class SyncStorageAdapter<TMeta = Record<string, unknown>> implements Syn
93
102
  clear(): Promise<void>;
94
103
  merge(localItems: KeepItem<TMeta>[]): Promise<KeepItem<TMeta>[]>;
95
104
  flushSync(): Promise<void>;
105
+ retrySync(): Promise<void>;
96
106
  dispose(): void;
97
107
  private runFlush;
98
108
  private createOperation;
109
+ private applyScope;
110
+ private pushWithRetry;
99
111
  private enqueueBeforeLocalWrite;
100
112
  private enqueueManyBeforeLocalWrite;
101
113
  private loadQueue;
package/dist/storage.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  SyncStorageAdapter,
16
16
  createBrowserStorageAdapter,
17
17
  createStorageAdapter
18
- } from "./chunk-DBRHZ6XU.js";
18
+ } from "./chunk-EXE4E3GA.js";
19
19
  export {
20
20
  DEFAULT_INDEXEDDB_DATABASE,
21
21
  DEFAULT_INDEXEDDB_STORE,