@keepkit/core 0.1.0 → 0.2.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.
@@ -1,190 +1,16 @@
1
+ "use client";
1
2
  import {
2
- DEFAULT_INDEXEDDB_DATABASE,
3
- DEFAULT_INDEXEDDB_STORE,
4
- DEFAULT_STORAGE_KEY,
5
- DEFAULT_SYNC_QUEUE_DATABASE,
6
- DEFAULT_SYNC_QUEUE_KEY,
7
- DEFAULT_SYNC_QUEUE_STORE,
8
- IndexedDBAdapter,
9
- IndexedDBSyncQueueAdapter,
10
- KeepStorageAccessError,
11
- KeepStorageError,
12
- KeepStorageParseError,
13
- KeepStorageQuotaError,
14
- LocalStorageAdapter,
15
- LocalStorageSyncQueueAdapter,
16
- SyncStorageAdapter,
17
- createStorageAdapter,
3
+ KeepStore,
4
+ queryKeepItems
5
+ } from "./chunk-PLT2WJVM.js";
6
+ import {
7
+ parseKeepMeta
8
+ } from "./chunk-THZ3ACR2.js";
9
+ import "./chunk-5QSZP6MT.js";
10
+ import {
11
+ createBrowserStorageAdapter,
18
12
  normalizeKeepTags
19
- } from "./chunk-H4A322SZ.js";
20
-
21
- // src/migration.ts
22
- async function mergeKeepItems(localItems, target) {
23
- if (target.merge) return target.merge(localItems);
24
- const remoteItems = await target.getAll();
25
- const byId = new Map(remoteItems.map((item) => [item.id, item]));
26
- for (const localItem of localItems) {
27
- const remoteItem = byId.get(localItem.id);
28
- if (!remoteItem || localItem.updatedAt > remoteItem.updatedAt) {
29
- byId.set(localItem.id, localItem);
30
- }
31
- }
32
- const merged = [...byId.values()].sort((a, b) => b.updatedAt - a.updatedAt);
33
- await Promise.all(merged.map((item) => target.set(item)));
34
- return merged;
35
- }
36
- async function migrateKeepItems(source, target) {
37
- const localItems = await source.getAll();
38
- const merged = await mergeKeepItems(localItems, target);
39
- await source.clear();
40
- return merged;
41
- }
42
-
43
- // src/schema.ts
44
- var KeepSchemaValidationError = class extends Error {
45
- constructor(message, options = {}) {
46
- super(message);
47
- this.name = "KeepSchemaValidationError";
48
- this.cause = options.cause;
49
- this.itemId = options.itemId;
50
- }
51
- };
52
- async function parseKeepMeta(schema, value) {
53
- try {
54
- if ("parse" in schema) return await schema.parse(value);
55
- if ("safeParse" in schema) {
56
- const result2 = await schema.safeParse(value);
57
- if (result2.success) return result2.data;
58
- throw new KeepSchemaValidationError("KeepKit metadata did not match the configured schema.", {
59
- cause: result2.error
60
- });
61
- }
62
- const result = await schema["~standard"].validate(value);
63
- if (!result.issues && "value" in result) return result.value;
64
- throw new KeepSchemaValidationError("KeepKit metadata did not match the configured schema.", {
65
- cause: result.issues
66
- });
67
- } catch (cause) {
68
- if (cause instanceof KeepSchemaValidationError) throw cause;
69
- throw new KeepSchemaValidationError("KeepKit metadata did not match the configured schema.", {
70
- cause
71
- });
72
- }
73
- }
74
- async function validateKeepItem(item, schema) {
75
- return { ...item, meta: await parseKeepMeta(schema, item.meta) };
76
- }
77
-
78
- // src/backup.ts
79
- var KEEP_BACKUP_FORMAT = "keepkit";
80
- var KEEP_BACKUP_VERSION = 1;
81
- var KeepBackupParseError = class extends Error {
82
- constructor(message, options) {
83
- super(message);
84
- this.name = "KeepBackupParseError";
85
- if (options?.cause !== void 0) this.cause = options.cause;
86
- }
87
- };
88
- var KeepBackupImportError = class extends Error {
89
- constructor(message, options) {
90
- super(message);
91
- this.name = "KeepBackupImportError";
92
- this.mode = options.mode;
93
- this.imported = options.imported;
94
- this.failed = options.failed;
95
- if (options.cause !== void 0) this.cause = options.cause;
96
- }
97
- };
98
- async function exportItems(adapter) {
99
- const backup = {
100
- format: KEEP_BACKUP_FORMAT,
101
- version: KEEP_BACKUP_VERSION,
102
- exportedAt: Date.now(),
103
- items: await adapter.getAll()
104
- };
105
- return JSON.stringify(backup, null, 2);
106
- }
107
- async function importItems(adapter, data, options = {}) {
108
- const backup = parseBackup(data);
109
- const mode = options.mode ?? "merge";
110
- const validItems = [];
111
- let failed = 0;
112
- for (const item of backup.items) {
113
- if (!options.schema) {
114
- validItems.push(item);
115
- continue;
116
- }
117
- try {
118
- validItems.push(await validateKeepItem(item, options.schema));
119
- } catch (cause) {
120
- options.onInvalidItem?.(cause, item);
121
- if ((options.invalidItemPolicy ?? "error") === "drop") {
122
- failed += 1;
123
- continue;
124
- }
125
- throw cause;
126
- }
127
- }
128
- let items;
129
- if (mode === "merge") {
130
- try {
131
- items = await mergeKeepItems(validItems, adapter);
132
- } catch (cause) {
133
- throw new KeepBackupImportError("KeepKit could not merge the backup.", {
134
- mode,
135
- imported: 0,
136
- failed: validItems.length + failed,
137
- cause
138
- });
139
- }
140
- } else {
141
- let imported = 0;
142
- try {
143
- await adapter.clear();
144
- for (const item of validItems) {
145
- await adapter.set(item);
146
- imported += 1;
147
- }
148
- items = await adapter.getAll();
149
- } catch (cause) {
150
- throw new KeepBackupImportError("KeepKit could not replace the stored items.", {
151
- mode,
152
- imported,
153
- failed: validItems.length + failed - imported,
154
- cause
155
- });
156
- }
157
- }
158
- return { mode, imported: validItems.length, failed, total: items.length, items };
159
- }
160
- function parseBackup(data) {
161
- let value = data;
162
- if (typeof data === "string") {
163
- try {
164
- value = JSON.parse(data);
165
- } catch (cause) {
166
- throw new KeepBackupParseError("KeepKit backup is not valid JSON.", { cause });
167
- }
168
- }
169
- if (!isRecord(value)) throw new KeepBackupParseError("KeepKit backup must be an object.");
170
- if (value.format !== KEEP_BACKUP_FORMAT || value.version !== KEEP_BACKUP_VERSION) {
171
- throw new KeepBackupParseError("KeepKit backup format or version is unsupported.");
172
- }
173
- if (typeof value.exportedAt !== "number" || !Number.isFinite(value.exportedAt)) {
174
- throw new KeepBackupParseError("KeepKit backup has an invalid export timestamp.");
175
- }
176
- if (!Array.isArray(value.items) || !value.items.every(isKeepItem)) {
177
- throw new KeepBackupParseError("KeepKit backup contains invalid items.");
178
- }
179
- return value;
180
- }
181
- function isKeepItem(value) {
182
- if (!isRecord(value)) return false;
183
- return typeof value.id === "string" && typeof value.savedAt === "number" && Number.isFinite(value.savedAt) && typeof value.updatedAt === "number" && Number.isFinite(value.updatedAt) && "meta" in value && (value.targetType === void 0 || typeof value.targetType === "string") && (value.note === void 0 || typeof value.note === "string") && (value.schemaVersion === void 0 || typeof value.schemaVersion === "number" && Number.isFinite(value.schemaVersion)) && (value.revision === void 0 || typeof value.revision === "string") && (value.tags === void 0 || Array.isArray(value.tags) && value.tags.every((tag) => typeof tag === "string"));
184
- }
185
- function isRecord(value) {
186
- return typeof value === "object" && value !== null;
187
- }
13
+ } from "./chunk-C3SOQCVW.js";
188
14
 
189
15
  // src/hooks/useKeepItem.ts
190
16
  import { useCallback as useCallback3 } from "react";
@@ -199,39 +25,13 @@ import {
199
25
  useRef,
200
26
  useSyncExternalStore
201
27
  } from "react";
202
-
203
- // src/store.ts
204
- var KeepStore = class {
205
- constructor(initialState) {
206
- this.listeners = /* @__PURE__ */ new Set();
207
- this.getSnapshot = () => this.state;
208
- this.subscribe = (listener) => {
209
- this.listeners.add(listener);
210
- return () => this.listeners.delete(listener);
211
- };
212
- this.state = initialState;
213
- }
214
- setState(next) {
215
- let changed = false;
216
- for (const key of Object.keys(next)) {
217
- if (!Object.is(this.state[key], next[key])) {
218
- changed = true;
219
- break;
220
- }
221
- }
222
- if (!changed) return;
223
- this.state = { ...this.state, ...next };
224
- for (const listener of this.listeners) listener();
225
- }
226
- };
227
-
228
- // src/KeepProvider.tsx
229
28
  import { jsx } from "react/jsx-runtime";
230
- var defaultStorage = new LocalStorageAdapter();
29
+ var defaultStorage = createBrowserStorageAdapter();
231
30
  var KeepContext = createContext(null);
232
31
  var KeepStoreContext = createContext(null);
233
32
  function KeepProvider({
234
33
  storage = defaultStorage,
34
+ initialItems,
235
35
  onSave,
236
36
  onRemove,
237
37
  onNoteUpdate,
@@ -249,7 +49,7 @@ function KeepProvider({
249
49
  const storeRef = useRef(null);
250
50
  if (!storeRef.current) {
251
51
  storeRef.current = new KeepStore({
252
- items: [],
52
+ items: initialItems ? [...initialItems] : [],
253
53
  isLoading: true,
254
54
  isHydrated: false,
255
55
  isMutating: false,
@@ -276,10 +76,7 @@ function KeepProvider({
276
76
  const pendingRefreshesRef = useRef(0);
277
77
  const pendingMutationsRef = useRef(0);
278
78
  const syncStorage = isSyncCapableStorage(storage) ? storage : void 0;
279
- const getSyncState = useCallback(
280
- () => syncStorage?.getSyncState() ?? IDLE_SYNC_STATE,
281
- [syncStorage]
282
- );
79
+ const getSyncState = useCallback(() => syncStorage?.getSyncState() ?? IDLE_SYNC_STATE, [syncStorage]);
283
80
  const subscribeSync = useCallback(
284
81
  (listener) => syncStorage?.subscribeSync(listener) ?? (() => void 0),
285
82
  [syncStorage]
@@ -300,19 +97,13 @@ function KeepProvider({
300
97
  },
301
98
  [store]
302
99
  );
303
- const runBeforePlugins = useCallback(
304
- async (context) => {
305
- for (const plugin of pluginsRef.current) await plugin.before?.(context);
306
- return context;
307
- },
308
- []
309
- );
310
- const runAfterPlugins = useCallback(
311
- async (context) => {
312
- for (const plugin of pluginsRef.current) await plugin.after?.(context);
313
- },
314
- []
315
- );
100
+ const runBeforePlugins = useCallback(async (context) => {
101
+ for (const plugin of pluginsRef.current) await plugin.before?.(context);
102
+ return context;
103
+ }, []);
104
+ const runAfterPlugins = useCallback(async (context) => {
105
+ for (const plugin of pluginsRef.current) await plugin.after?.(context);
106
+ }, []);
316
107
  const enqueueOperation = useCallback((operation) => {
317
108
  const run = operationTailRef.current.then(operation, operation);
318
109
  operationTailRef.current = run.then(
@@ -434,10 +225,9 @@ function KeepProvider({
434
225
  throw cause;
435
226
  }
436
227
  await runMutation("save", normalizedItem.id, (previous) => ({
437
- next: [
438
- ...previous.filter((current) => current.id !== normalizedItem.id),
439
- normalizedItem
440
- ].sort((a, b) => b.updatedAt - a.updatedAt),
228
+ next: [...previous.filter((current) => current.id !== normalizedItem.id), normalizedItem].sort(
229
+ (a, b) => b.updatedAt - a.updatedAt
230
+ ),
441
231
  persist: () => storage.set(normalizedItem),
442
232
  onSuccess: () => handlersRef.current.onSave?.(normalizedItem),
443
233
  pluginContext: { action: "save", id: normalizedItem.id, item: normalizedItem }
@@ -533,9 +323,7 @@ function KeepProvider({
533
323
  const idSet = new Set(ids);
534
324
  const currentItems = itemsRef.current.filter((item) => idSet.has(item.id));
535
325
  await Promise.all(
536
- currentItems.map(
537
- (item) => updateTags(item.id, normalizeKeepTags([...item.tags ?? [], ...additions]))
538
- )
326
+ currentItems.map((item) => updateTags(item.id, normalizeKeepTags([...item.tags ?? [], ...additions])))
539
327
  );
540
328
  },
541
329
  [updateTags]
@@ -547,10 +335,7 @@ function KeepProvider({
547
335
  const currentItems = itemsRef.current.filter((item) => idSet.has(item.id));
548
336
  await Promise.all(
549
337
  currentItems.map(
550
- (item) => updateTags(
551
- item.id,
552
- normalizeKeepTags((item.tags ?? []).filter((tag) => !removals.has(tag)))
553
- )
338
+ (item) => updateTags(item.id, normalizeKeepTags((item.tags ?? []).filter((tag) => !removals.has(tag))))
554
339
  )
555
340
  );
556
341
  },
@@ -614,10 +399,7 @@ function KeepProvider({
614
399
  })),
615
400
  [runMutation, storage]
616
401
  );
617
- const flushSync = useCallback(
618
- () => syncStorage ? syncStorage.flushSync() : Promise.resolve(),
619
- [syncStorage]
620
- );
402
+ const flushSync = useCallback(() => syncStorage ? syncStorage.flushSync() : Promise.resolve(), [syncStorage]);
621
403
  const value = useMemo(
622
404
  () => ({
623
405
  items,
@@ -873,14 +655,8 @@ function useKeepList(options = {}) {
873
655
  (ids, tags2) => actions.updateTagsBatch(ids, tags2),
874
656
  [actions]
875
657
  );
876
- const addTagsBatch = useCallback4(
877
- (ids, tags2) => actions.addTagsBatch(ids, tags2),
878
- [actions]
879
- );
880
- const removeTagsBatch = useCallback4(
881
- (ids, tags2) => actions.removeTagsBatch(ids, tags2),
882
- [actions]
883
- );
658
+ const addTagsBatch = useCallback4((ids, tags2) => actions.addTagsBatch(ids, tags2), [actions]);
659
+ const removeTagsBatch = useCallback4((ids, tags2) => actions.removeTagsBatch(ids, tags2), [actions]);
884
660
  return {
885
661
  items,
886
662
  totalCount,
@@ -899,52 +675,6 @@ function useKeepList(options = {}) {
899
675
  refresh: actions.refresh
900
676
  };
901
677
  }
902
- function queryKeepItems(source, options = {}) {
903
- const filtered = source.filter((item) => {
904
- const [from, to] = options.savedBetween ?? [];
905
- const savedAt = item.savedAt;
906
- const lowerBound = from === void 0 ? void 0 : toTimestamp(from);
907
- const upperBound = to === void 0 ? void 0 : toTimestamp(to);
908
- return (options.targetType === void 0 || item.targetType === options.targetType) && (options.tag === void 0 || item.tags?.includes(options.tag) === true) && (options.tags === void 0 || options.tags.every((tag) => item.tags?.includes(tag))) && (lowerBound === void 0 || savedAt >= lowerBound) && (upperBound === void 0 || savedAt <= upperBound) && matchesSearch(item, options.searchQuery, options.search) && (options.filter?.(item) ?? true) && (options.filterFn?.(item) ?? true);
909
- });
910
- const tagCounts = getTagCounts(filtered);
911
- const sortBy = options.sortBy ?? options.sort?.by;
912
- const direction = (options.order ?? options.sort?.direction) === "asc" ? 1 : -1;
913
- const sorted = sortBy ? [...filtered].sort((a, b) => (a[sortBy] - b[sortBy]) * direction) : filtered;
914
- const offset = Math.max(0, options.offset ?? 0);
915
- const items = options.limit === void 0 ? sorted.slice(offset) : sorted.slice(offset, offset + Math.max(0, options.limit));
916
- return { items, totalCount: sorted.length, tagCounts };
917
- }
918
- function getTagCounts(items) {
919
- const counts = {};
920
- for (const item of items) {
921
- for (const tag of item.tags ?? []) counts[tag] = (counts[tag] ?? 0) + 1;
922
- }
923
- return Object.fromEntries(Object.entries(counts).sort(([a], [b]) => a.localeCompare(b)));
924
- }
925
- function matchesSearch(item, searchQuery, search) {
926
- const query = search?.query ?? searchQuery;
927
- if (!query?.trim()) return true;
928
- const fields = search?.fields ?? ["note", "meta", "tags"];
929
- const values = fields.map((field) => {
930
- if (field === "note") return item.note ?? "";
931
- if (field === "tags") return (item.tags ?? []).join(" ");
932
- try {
933
- return JSON.stringify(item.meta) ?? "";
934
- } catch {
935
- return String(item.meta);
936
- }
937
- });
938
- const text = values.join(" ").toLocaleLowerCase();
939
- if (!search) return text.includes(query.trim().toLocaleLowerCase());
940
- const normalized = query.trim().toLocaleLowerCase();
941
- const needles = search.tokenize === false ? [normalized] : normalized.split(/\s+/).filter(Boolean);
942
- const matches = needles.map((needle) => text.includes(needle));
943
- return search.mode === "or" ? matches.some(Boolean) : matches.every(Boolean);
944
- }
945
- function toTimestamp(value) {
946
- return value instanceof Date ? value.getTime() : value;
947
- }
948
678
  function sameItems(left, right) {
949
679
  return left.length === right.length && left.every((item, index) => item === right[index]);
950
680
  }
@@ -957,6 +687,62 @@ function sameCounts(left, right) {
957
687
  });
958
688
  }
959
689
 
690
+ // src/hooks/useKeepShortcut.ts
691
+ import { useEffect as useEffect2 } from "react";
692
+ function useKeepShortcut(options) {
693
+ const item = useKeepItem(options.id ?? "", options.itemPayload);
694
+ const {
695
+ action = "toggle",
696
+ allowInEditable = false,
697
+ enabled = true,
698
+ key,
699
+ modifier,
700
+ onError,
701
+ onTrigger,
702
+ preventDefault = true
703
+ } = options;
704
+ useEffect2(() => {
705
+ if (!enabled) return;
706
+ const handleKeyDown = (event) => {
707
+ if (!allowInEditable && isEditableTarget(event.target)) return;
708
+ if (!matchesShortcut(event, key, modifier)) return;
709
+ if (preventDefault) event.preventDefault();
710
+ const run = onTrigger ? onTrigger(event) : options.id ? action === "save" ? item.save() : action === "remove" ? item.remove() : item.toggle() : void 0;
711
+ if (run) void Promise.resolve(run).catch((error) => onError?.(error));
712
+ };
713
+ window.addEventListener("keydown", handleKeyDown);
714
+ return () => window.removeEventListener("keydown", handleKeyDown);
715
+ }, [
716
+ action,
717
+ allowInEditable,
718
+ enabled,
719
+ item.remove,
720
+ item.save,
721
+ item.toggle,
722
+ key,
723
+ modifier,
724
+ onError,
725
+ onTrigger,
726
+ options.id,
727
+ preventDefault
728
+ ]);
729
+ }
730
+ function matchesShortcut(event, key, modifier) {
731
+ if (event.key.toLocaleLowerCase() !== key.toLocaleLowerCase()) return false;
732
+ const modifiers = {
733
+ meta: event.metaKey,
734
+ ctrl: event.ctrlKey,
735
+ alt: event.altKey,
736
+ shift: event.shiftKey
737
+ };
738
+ if (modifier ? !modifiers[modifier] : Object.values(modifiers).some(Boolean)) return false;
739
+ return Object.entries(modifiers).every(([name, pressed]) => name === modifier || !pressed);
740
+ }
741
+ function isEditableTarget(target) {
742
+ if (!(target instanceof HTMLElement)) return false;
743
+ return target.isContentEditable || target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.tagName === "SELECT";
744
+ }
745
+
960
746
  // src/KeepButton.tsx
961
747
  import {
962
748
  Children,
@@ -984,6 +770,7 @@ function KeepButton({
984
770
  const { isSaved, toggle } = state;
985
771
  const isDisabled = disabled ?? state.isMutating;
986
772
  async function handleClick(event) {
773
+ if (isDisabled) return;
987
774
  if (asChild) {
988
775
  onClick?.(event);
989
776
  } else {
@@ -1000,33 +787,53 @@ function KeepButton({
1000
787
  }
1001
788
  const content = typeof children === "function" ? children(state) : children ?? (isSaved ? savedLabel : unsavedLabel);
1002
789
  function handleElementClick(event) {
790
+ if (isDisabled) return;
1003
791
  if (asChild && isValidElement(content)) {
1004
792
  content.props.onClick?.(event);
1005
793
  }
1006
794
  if (!event.defaultPrevented) void handleClick(event);
1007
795
  }
796
+ function handleKeyDown(event) {
797
+ if (asChild && isValidElement(content)) {
798
+ content.props.onKeyDown?.(event);
799
+ }
800
+ buttonProps.onKeyDown?.(event);
801
+ if (!event.defaultPrevented && !isDisabled && asChild && (event.key === "Enter" || event.key === " ")) {
802
+ void handleClick(event);
803
+ event.preventDefault();
804
+ }
805
+ }
806
+ const child = asChild ? Children.only(content) : void 0;
807
+ if (asChild && !isValidElement(child)) {
808
+ throw new Error("KeepButton with asChild requires a single React element child.");
809
+ }
1008
810
  const commonProps = {
1009
811
  ...buttonProps,
1010
812
  "aria-pressed": isSaved,
1011
- "aria-label": ("aria-label" in buttonProps ? buttonProps["aria-label"] : void 0) ?? (isSaved ? "Remove saved item" : "Save item"),
1012
- disabled: isDisabled,
1013
- onClick: handleElementClick
813
+ "aria-label": ("aria-label" in buttonProps ? buttonProps["aria-label"] : void 0) ?? getAccessibleLabel(isSaved, item, asChild),
814
+ ...asChild ? {
815
+ "aria-disabled": isDisabled,
816
+ role: buttonProps.role ?? "button",
817
+ tabIndex: isDisabled ? -1 : buttonProps.tabIndex ?? 0
818
+ } : { disabled: isDisabled },
819
+ onClick: handleElementClick,
820
+ onKeyDown: handleKeyDown
1014
821
  };
1015
822
  if (asChild) {
1016
- const child = Children.only(content);
1017
- if (!isValidElement(child)) {
1018
- throw new Error("KeepButton with asChild requires a single React element child.");
1019
- }
1020
823
  return cloneElement(child, commonProps);
1021
824
  }
1022
- return /* @__PURE__ */ jsx2(
1023
- "button",
1024
- {
1025
- ...commonProps,
1026
- type: "type" in buttonProps ? buttonProps.type ?? "button" : "button",
1027
- children: content
1028
- }
1029
- );
825
+ return /* @__PURE__ */ jsx2("button", { ...commonProps, type: "type" in buttonProps ? buttonProps.type ?? "button" : "button", children: content });
826
+ }
827
+ function getAccessibleLabel(isSaved, item, asChild) {
828
+ if (!asChild) return isSaved ? "Remove saved item" : "Save item";
829
+ const title = getMetaTitle(item.meta);
830
+ const subject = title ? `${item.targetType ?? "item"}: ${title}` : item.targetType ?? "item";
831
+ return `${isSaved ? "Remove" : "Save"} ${subject}`;
832
+ }
833
+ function getMetaTitle(meta) {
834
+ if (typeof meta !== "object" || meta === null || !("title" in meta)) return void 0;
835
+ const title = meta.title;
836
+ return typeof title === "string" && title.trim() ? title.trim() : void 0;
1030
837
  }
1031
838
 
1032
839
  // src/createKeepKit.tsx
@@ -1037,57 +844,18 @@ function createKeepKit(options = {}) {
1037
844
  KeepButton: (props) => /* @__PURE__ */ jsx3(KeepButton, { ...props }),
1038
845
  useKeepContext: () => useKeepContext(),
1039
846
  useKeepItem: (id, itemPayload) => useKeepItem(id, itemPayload),
1040
- useKeepList: (options2) => useKeepList(options2)
1041
- };
1042
- }
1043
-
1044
- // src/integrations.ts
1045
- function createKeepInvalidationPlugin(options) {
1046
- return {
1047
- name: options.name ?? "keepkit-cache-invalidation",
1048
- after: async (context) => {
1049
- const keys = typeof options.queryKeys === "function" ? options.queryKeys(context) : [options.queryKeys];
1050
- await Promise.all(keys.map((queryKey) => options.invalidate(queryKey, context)));
1051
- }
847
+ useKeepList: (options2) => useKeepList(options2),
848
+ useKeepShortcut: (shortcutOptions) => useKeepShortcut(shortcutOptions)
1052
849
  };
1053
850
  }
1054
851
  export {
1055
- DEFAULT_INDEXEDDB_DATABASE,
1056
- DEFAULT_INDEXEDDB_STORE,
1057
- DEFAULT_STORAGE_KEY,
1058
- DEFAULT_SYNC_QUEUE_DATABASE,
1059
- DEFAULT_SYNC_QUEUE_KEY,
1060
- DEFAULT_SYNC_QUEUE_STORE,
1061
- IndexedDBAdapter,
1062
- IndexedDBSyncQueueAdapter,
1063
- KEEP_BACKUP_FORMAT,
1064
- KEEP_BACKUP_VERSION,
1065
- KeepBackupImportError,
1066
- KeepBackupParseError,
1067
852
  KeepButton,
1068
853
  KeepProvider,
1069
- KeepSchemaValidationError,
1070
- KeepStorageAccessError,
1071
- KeepStorageError,
1072
- KeepStorageParseError,
1073
- KeepStorageQuotaError,
1074
- LocalStorageAdapter,
1075
- LocalStorageSyncQueueAdapter,
1076
- SyncStorageAdapter,
1077
- createKeepInvalidationPlugin,
1078
854
  createKeepKit,
1079
- createStorageAdapter,
1080
- exportItems,
1081
- getTagCounts,
1082
- importItems,
1083
- mergeKeepItems,
1084
- migrateKeepItems,
1085
- normalizeKeepTags,
1086
- parseKeepMeta,
1087
- queryKeepItems,
1088
855
  useKeepContext,
1089
856
  useKeepItem,
1090
857
  useKeepList,
1091
- validateKeepItem
858
+ useKeepShortcut,
859
+ useKeepStore
1092
860
  };
1093
- //# sourceMappingURL=index.js.map
861
+ //# sourceMappingURL=react.js.map