@keepkit/core 0.28.1 → 0.28.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -4
- package/dist/{chunk-JGGKIE3O.js → chunk-IIGN4U7N.js} +18 -4
- package/dist/chunk-IIGN4U7N.js.map +1 -0
- package/dist/{chunk-HDML3IDX.js → chunk-MZFZQIM5.js} +22 -6
- package/dist/chunk-MZFZQIM5.js.map +1 -0
- package/dist/core.d.ts +33 -2
- package/dist/core.js +169 -4
- package/dist/core.js.map +1 -1
- package/dist/react.d.ts +12 -2
- package/dist/react.js +93 -3
- package/dist/react.js.map +1 -1
- package/dist/storage.js +1 -1
- package/dist/{store-DbAAC4yU.d.ts → store-C7pEDMLm.d.ts} +21 -2
- package/package.json +1 -1
- package/dist/chunk-HDML3IDX.js.map +0 -1
- package/dist/chunk-JGGKIE3O.js.map +0 -1
package/dist/core.js
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
KeepBackupImportError,
|
|
5
5
|
KeepBackupParseError,
|
|
6
6
|
KeepStore,
|
|
7
|
+
createInboxQuery,
|
|
7
8
|
createRediscoveryQuery,
|
|
8
9
|
exportItems,
|
|
9
10
|
getKeepNavigationState,
|
|
@@ -18,7 +19,7 @@ import {
|
|
|
18
19
|
reconcileKeepItems,
|
|
19
20
|
reorderKeepItems,
|
|
20
21
|
revalidateKeepItems
|
|
21
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-IIGN4U7N.js";
|
|
22
23
|
import {
|
|
23
24
|
KeepSchemaValidationError,
|
|
24
25
|
parseKeepMeta,
|
|
@@ -52,7 +53,7 @@ import {
|
|
|
52
53
|
isKeepSyncAuthError,
|
|
53
54
|
isSameKeepScope,
|
|
54
55
|
normalizeKeepTags
|
|
55
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-MZFZQIM5.js";
|
|
56
57
|
|
|
57
58
|
// src/features/items/presets.ts
|
|
58
59
|
function createKeepKitPreset(options = {}) {
|
|
@@ -81,6 +82,124 @@ function createKeepKitPreset(options = {}) {
|
|
|
81
82
|
}
|
|
82
83
|
var createKeepKitSetup = createKeepKitPreset;
|
|
83
84
|
|
|
85
|
+
// src/features/items/saved-views.ts
|
|
86
|
+
var DEFAULT_SAVED_VIEWS_STORAGE_KEY = "keepkit:saved-views";
|
|
87
|
+
var LocalStorageKeepSavedViewStorage = class {
|
|
88
|
+
constructor(options = {}) {
|
|
89
|
+
this.key = options.key ?? DEFAULT_SAVED_VIEWS_STORAGE_KEY;
|
|
90
|
+
this.storage = options.storage;
|
|
91
|
+
}
|
|
92
|
+
async getAll() {
|
|
93
|
+
const raw = this.getStorage().getItem(this.key);
|
|
94
|
+
if (!raw) return [];
|
|
95
|
+
const data = JSON.parse(raw);
|
|
96
|
+
if (!Array.isArray(data) || !data.every(isSavedView)) throw new Error("KeepKit saved-view data is invalid.");
|
|
97
|
+
return data;
|
|
98
|
+
}
|
|
99
|
+
async set(view) {
|
|
100
|
+
const range = view.query.savedBetween;
|
|
101
|
+
const normalized = {
|
|
102
|
+
...view,
|
|
103
|
+
query: {
|
|
104
|
+
...view.query,
|
|
105
|
+
...range ? {
|
|
106
|
+
savedBetween: [
|
|
107
|
+
range[0] instanceof Date ? range[0].getTime() : range[0],
|
|
108
|
+
range[1] instanceof Date ? range[1].getTime() : range[1]
|
|
109
|
+
]
|
|
110
|
+
} : {}
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
if (!isSavedView(normalized)) throw new Error("KeepKit Saved View is invalid.");
|
|
114
|
+
const views = await this.getAll();
|
|
115
|
+
const next = [...views.filter((current) => current.id !== normalized.id), normalized];
|
|
116
|
+
this.getStorage().setItem(this.key, JSON.stringify(next));
|
|
117
|
+
}
|
|
118
|
+
async get(id) {
|
|
119
|
+
return (await this.getAll()).find((view) => view.id === id);
|
|
120
|
+
}
|
|
121
|
+
async remove(id) {
|
|
122
|
+
const views = await this.getAll();
|
|
123
|
+
this.getStorage().setItem(this.key, JSON.stringify(views.filter((view) => view.id !== id)));
|
|
124
|
+
}
|
|
125
|
+
getStorage() {
|
|
126
|
+
if (this.storage) return this.storage;
|
|
127
|
+
if (typeof localStorage === "undefined")
|
|
128
|
+
throw new Error("KeepKit Saved Views require browser storage or an injected adapter.");
|
|
129
|
+
return localStorage;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
function isSavedView(value) {
|
|
133
|
+
if (typeof value !== "object" || value === null) return false;
|
|
134
|
+
const view = value;
|
|
135
|
+
return typeof view.id === "string" && view.id.length > 0 && typeof view.name === "string" && view.name.trim().length > 0 && Number.isFinite(view.createdAt) && Number.isFinite(view.updatedAt) && isKeepListQuery(view.query) && (view.pinned === void 0 || typeof view.pinned === "boolean");
|
|
136
|
+
}
|
|
137
|
+
function isKeepListQuery(value) {
|
|
138
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
139
|
+
const query = value;
|
|
140
|
+
if (query.filter !== void 0) return false;
|
|
141
|
+
if (query.tags !== void 0 && (!Array.isArray(query.tags) || !query.tags.every((tag) => typeof tag === "string"))) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
if (query.collectionId !== void 0 && typeof query.collectionId !== "string") return false;
|
|
145
|
+
if (query.targetType !== void 0 && typeof query.targetType !== "string") return false;
|
|
146
|
+
if (query.archived !== void 0 && typeof query.archived !== "boolean") return false;
|
|
147
|
+
if (query.archiveScope !== void 0 && !["active", "archived", "all"].includes(String(query.archiveScope))) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
if (query.pinnedFirst !== void 0 && typeof query.pinnedFirst !== "boolean") return false;
|
|
151
|
+
if (query.sort !== void 0) {
|
|
152
|
+
if (!isRecord(query.sort) || !["savedAt", "updatedAt", "lastOpenedAt"].includes(String(query.sort.by)))
|
|
153
|
+
return false;
|
|
154
|
+
if (query.sort.direction !== void 0 && query.sort.direction !== "asc" && query.sort.direction !== "desc")
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
if (query.search !== void 0) {
|
|
158
|
+
if (!isRecord(query.search)) return false;
|
|
159
|
+
if (query.search.query !== void 0 && typeof query.search.query !== "string") return false;
|
|
160
|
+
if (query.search.mode !== void 0 && query.search.mode !== "and" && query.search.mode !== "or") return false;
|
|
161
|
+
if (query.search.tokenize !== void 0 && typeof query.search.tokenize !== "boolean") return false;
|
|
162
|
+
if (query.search.fields !== void 0 && (!Array.isArray(query.search.fields) || !query.search.fields.every((field) => field === "note" || field === "meta" || field === "tags"))) {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (query.activity !== void 0) {
|
|
167
|
+
if (!isRecord(query.activity)) return false;
|
|
168
|
+
if (query.activity.opened !== void 0 && query.activity.opened !== "ever" && query.activity.opened !== "never") {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
if ([query.activity.lastOpenedBefore, query.activity.lastOpenedAfter, query.activity.inactiveForMs].some(
|
|
172
|
+
isInvalidNumber
|
|
173
|
+
)) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (query.savedBetween !== void 0 && (!Array.isArray(query.savedBetween) || query.savedBetween.length !== 2 || query.savedBetween.some(isInvalidNumber))) {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
if (query.pagination !== void 0) {
|
|
181
|
+
if (!isRecord(query.pagination) || [query.pagination.page, query.pagination.pageSize].some(isInvalidNumber))
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
const organization = query.organization;
|
|
185
|
+
if (organization !== void 0) {
|
|
186
|
+
if (typeof organization !== "object" || organization === null || Array.isArray(organization)) return false;
|
|
187
|
+
const fields = organization;
|
|
188
|
+
if ([fields.collection, fields.tags, fields.note].some(
|
|
189
|
+
(field) => field !== void 0 && field !== "assigned" && field !== "unassigned"
|
|
190
|
+
)) {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
function isRecord(value) {
|
|
197
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
198
|
+
}
|
|
199
|
+
function isInvalidNumber(value) {
|
|
200
|
+
return value !== void 0 && (typeof value !== "number" || !Number.isFinite(value));
|
|
201
|
+
}
|
|
202
|
+
|
|
84
203
|
// src/features/items/url.ts
|
|
85
204
|
var DEFAULT_KEEP_URL_PARAMS = {
|
|
86
205
|
search: "q",
|
|
@@ -94,7 +213,12 @@ var DEFAULT_KEEP_URL_PARAMS = {
|
|
|
94
213
|
activityOpened: "opened",
|
|
95
214
|
lastOpenedBefore: "openedBefore",
|
|
96
215
|
lastOpenedAfter: "openedAfter",
|
|
97
|
-
inactiveForMs: "inactiveFor"
|
|
216
|
+
inactiveForMs: "inactiveFor",
|
|
217
|
+
organizationCollection: "collectionState",
|
|
218
|
+
organizationTags: "tagsState",
|
|
219
|
+
organizationNote: "noteState",
|
|
220
|
+
savedAfter: "savedAfter",
|
|
221
|
+
savedBefore: "savedBefore"
|
|
98
222
|
};
|
|
99
223
|
function encodeKeepListQuery(query = {}, options = {}) {
|
|
100
224
|
const params = { ...DEFAULT_KEEP_URL_PARAMS, ...options.params };
|
|
@@ -111,7 +235,21 @@ function encodeKeepListQuery(query = {}, options = {}) {
|
|
|
111
235
|
if (query.archiveScope !== void 0) result.set(params.archiveScope, query.archiveScope);
|
|
112
236
|
else if (query.archived !== void 0) result.set(params.archived, query.archived ? "true" : "false");
|
|
113
237
|
if (query.collectionId) result.set(params.collection, query.collectionId);
|
|
238
|
+
for (const [key, value] of [
|
|
239
|
+
[params.organizationCollection, query.organization?.collection],
|
|
240
|
+
[params.organizationTags, query.organization?.tags],
|
|
241
|
+
[params.organizationNote, query.organization?.note]
|
|
242
|
+
]) {
|
|
243
|
+
if (value !== void 0) result.set(key, value);
|
|
244
|
+
}
|
|
114
245
|
if (query.pinnedFirst) result.set(params.pinnedFirst, "true");
|
|
246
|
+
if (query.savedBetween) {
|
|
247
|
+
const [from, to] = query.savedBetween.map((value) => value instanceof Date ? value.getTime() : value);
|
|
248
|
+
if (Number.isFinite(from) && Number.isFinite(to)) {
|
|
249
|
+
result.set(params.savedAfter, String(from));
|
|
250
|
+
result.set(params.savedBefore, String(to));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
115
253
|
if (query.activity?.opened) result.set(params.activityOpened, query.activity.opened);
|
|
116
254
|
for (const [key, value] of [
|
|
117
255
|
[params.lastOpenedBefore, query.activity?.lastOpenedBefore],
|
|
@@ -143,7 +281,24 @@ function decodeKeepListQuery(input, options = {}) {
|
|
|
143
281
|
const archivedValue = searchParams.get(params.archived);
|
|
144
282
|
const archived = archiveScope === "archived" || archivedValue === "true" ? true : archiveScope === "active" || archivedValue === "false" ? false : void 0;
|
|
145
283
|
const collectionId = searchParams.get(params.collection)?.trim() || void 0;
|
|
284
|
+
const organizationCollection = parseOrganizationState(searchParams.get(params.organizationCollection));
|
|
285
|
+
const organizationTags = parseOrganizationState(searchParams.get(params.organizationTags));
|
|
286
|
+
const organizationNote = parseOrganizationState(searchParams.get(params.organizationNote));
|
|
287
|
+
const organization = organizationCollection || organizationTags || organizationNote ? {
|
|
288
|
+
...organizationCollection ? { collection: organizationCollection } : {},
|
|
289
|
+
...organizationTags ? { tags: organizationTags } : {},
|
|
290
|
+
...organizationNote ? { note: organizationNote } : {}
|
|
291
|
+
} : void 0;
|
|
146
292
|
const pinnedFirst = searchParams.get(params.pinnedFirst) === "true" ? true : void 0;
|
|
293
|
+
const parseSavedDate = (name) => {
|
|
294
|
+
const rawValue = searchParams.get(name);
|
|
295
|
+
if (rawValue === null || rawValue.trim() === "") return void 0;
|
|
296
|
+
const value = Number(rawValue);
|
|
297
|
+
return Number.isFinite(value) ? value : void 0;
|
|
298
|
+
};
|
|
299
|
+
const savedAfter = parseSavedDate(params.savedAfter);
|
|
300
|
+
const savedBefore = parseSavedDate(params.savedBefore);
|
|
301
|
+
const savedBetween = savedAfter === void 0 || savedBefore === void 0 ? void 0 : [savedAfter, savedBefore];
|
|
147
302
|
const activityOpenedValue = searchParams.get(params.activityOpened);
|
|
148
303
|
const activityOpened = activityOpenedValue === "ever" || activityOpenedValue === "never" ? activityOpenedValue : void 0;
|
|
149
304
|
const parseActivityNumber = (name) => {
|
|
@@ -169,7 +324,9 @@ function decodeKeepListQuery(input, options = {}) {
|
|
|
169
324
|
...archived === void 0 ? {} : { archived },
|
|
170
325
|
...archiveScope === void 0 ? {} : { archiveScope },
|
|
171
326
|
...collectionId ? { collectionId } : {},
|
|
327
|
+
...organization ? { organization } : {},
|
|
172
328
|
...pinnedFirst ? { pinnedFirst } : {},
|
|
329
|
+
...savedBetween ? { savedBetween } : {},
|
|
173
330
|
...activity === void 0 ? {} : { activity }
|
|
174
331
|
};
|
|
175
332
|
}
|
|
@@ -188,9 +345,14 @@ function mergeKeepListQueryFromUrl(query, input, options = {}) {
|
|
|
188
345
|
pagination: decoded.pagination ? { ...query.pagination, ...decoded.pagination } : query.pagination,
|
|
189
346
|
archived: decoded.archived ?? query.archived,
|
|
190
347
|
archiveScope: decoded.archiveScope ?? query.archiveScope,
|
|
191
|
-
activity: decoded.activity ?? query.activity
|
|
348
|
+
activity: decoded.activity ?? query.activity,
|
|
349
|
+
organization: decoded.organization ?? query.organization,
|
|
350
|
+
savedBetween: decoded.savedBetween ?? query.savedBetween
|
|
192
351
|
};
|
|
193
352
|
}
|
|
353
|
+
function parseOrganizationState(value) {
|
|
354
|
+
return value === "assigned" || value === "unassigned" ? value : void 0;
|
|
355
|
+
}
|
|
194
356
|
|
|
195
357
|
// src/features/sync/integrations.ts
|
|
196
358
|
function createKeepInvalidationPlugin(options) {
|
|
@@ -400,6 +562,7 @@ export {
|
|
|
400
562
|
DEFAULT_INDEXEDDB_DATABASE,
|
|
401
563
|
DEFAULT_INDEXEDDB_STORE,
|
|
402
564
|
DEFAULT_KEEP_URL_PARAMS,
|
|
565
|
+
DEFAULT_SAVED_VIEWS_STORAGE_KEY,
|
|
403
566
|
DEFAULT_STORAGE_KEY,
|
|
404
567
|
DEFAULT_SYNC_QUEUE_DATABASE,
|
|
405
568
|
DEFAULT_SYNC_QUEUE_KEY,
|
|
@@ -420,12 +583,14 @@ export {
|
|
|
420
583
|
KeepStore,
|
|
421
584
|
KeepSyncAuthError,
|
|
422
585
|
LocalStorageAdapter,
|
|
586
|
+
LocalStorageKeepSavedViewStorage,
|
|
423
587
|
LocalStorageSyncQueueAdapter,
|
|
424
588
|
ScopedStorageAdapter,
|
|
425
589
|
ScopedSyncQueueAdapter,
|
|
426
590
|
SyncStorageAdapter,
|
|
427
591
|
createAuthenticatedSyncKit,
|
|
428
592
|
createBrowserStorageAdapter,
|
|
593
|
+
createInboxQuery,
|
|
429
594
|
createKeepInvalidationPlugin,
|
|
430
595
|
createKeepKitPreset,
|
|
431
596
|
createKeepKitSetup,
|
package/dist/core.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/features/items/presets.ts","../src/features/items/url.ts","../src/features/sync/integrations.ts","../src/features/sync/templates/auth-sync.ts"],"sourcesContent":["import { createBrowserStorageAdapter } from \"../../storage/index\";\nimport { SyncStorageAdapter } from \"../../storage/sync\";\nimport { exportItems } from \"../persistence/backup\";\nimport { createScopedStorageAdapter, type KeepScope } from \"../persistence/scope\";\nimport type { RemoteSyncDriver, StorageAdapter } from \"./types\";\n\nexport type KeepKitPresetMode = \"local\" | \"sync\" | \"backup\";\n\nexport type KeepKitPresetOptions<TMeta = Record<string, unknown>> = {\n mode?: KeepKitPresetMode;\n key?: string;\n scope?: KeepScope;\n remote?: RemoteSyncDriver<TMeta>;\n storage?: StorageAdapter<TMeta>;\n};\n\nexport type KeepKitSetup<TMeta = Record<string, unknown>> = {\n mode: KeepKitPresetMode;\n scope?: KeepScope;\n storage: StorageAdapter<TMeta>;\n exportBackup: () => Promise<string>;\n};\n\n/**\n * Build the recommended local/sync/backup wiring without imposing an auth or\n * API client. Pass the current user and tenant scope whenever the account changes.\n */\nexport function createKeepKitPreset<TMeta = Record<string, unknown>>(\n options: KeepKitPresetOptions<TMeta> = {},\n): KeepKitSetup<TMeta> {\n const mode = options.mode ?? \"local\";\n const local = options.storage\n ? options.scope\n ? createScopedStorageAdapter(options.storage, options.scope)\n : options.storage\n : createBrowserStorageAdapter<TMeta>({ key: options.key, scope: options.scope });\n if (mode === \"sync\" && !options.remote) {\n throw new Error('createKeepKitPreset({ mode: \"sync\" }) requires a remote driver.');\n }\n let storage: StorageAdapter<TMeta> = local;\n if (mode === \"sync\") {\n const remote = options.remote;\n if (!remote) throw new Error('createKeepKitPreset({ mode: \"sync\" }) requires a remote driver.');\n storage = new SyncStorageAdapter<TMeta>({\n local,\n remote,\n userId: options.scope?.userId,\n tenantId: options.scope?.tenantId,\n });\n }\n return {\n mode,\n scope: options.scope,\n storage,\n exportBackup: () => exportItems(storage),\n };\n}\n\nexport const createKeepKitSetup = createKeepKitPreset;\n","import type { KeepListQuery } from \"./query\";\n\nexport type KeepUrlParamNames = {\n search: string;\n tags: string;\n sort: string;\n page: string;\n archived: string;\n archiveScope: string;\n collection: string;\n pinnedFirst: string;\n activityOpened?: string;\n lastOpenedBefore?: string;\n lastOpenedAfter?: string;\n inactiveForMs?: string;\n};\n\nexport type KeepUrlSyncOptions = {\n /** Parameters are intentionally short so shared collection URLs stay readable. */\n params?: Partial<KeepUrlParamNames>;\n /** Push is the default so browser back/forward restores collection states. */\n history?: \"replace\" | \"push\";\n /** URL to read/write. Defaults to the current browser URL. */\n url?: string;\n};\n\nexport const DEFAULT_KEEP_URL_PARAMS: Required<KeepUrlParamNames> = {\n search: \"q\",\n tags: \"tag\",\n sort: \"sort\",\n page: \"page\",\n archived: \"archived\",\n archiveScope: \"archiveScope\",\n collection: \"collection\",\n pinnedFirst: \"pinned\",\n activityOpened: \"opened\",\n lastOpenedBefore: \"openedBefore\",\n lastOpenedAfter: \"openedAfter\",\n inactiveForMs: \"inactiveFor\",\n};\n\nexport type KeepUrlState = Pick<\n KeepListQuery,\n \"search\" | \"tags\" | \"sort\" | \"pagination\" | \"archived\" | \"archiveScope\" | \"collectionId\" | \"pinnedFirst\" | \"activity\"\n>;\n\n/** Convert a list query to stable URLSearchParams without serializing functions or unsupported filters. */\nexport function encodeKeepListQuery<TMeta = Record<string, unknown>>(\n query: KeepListQuery<TMeta> = {},\n options: Pick<KeepUrlSyncOptions, \"params\"> = {},\n): URLSearchParams {\n const params: Required<KeepUrlParamNames> = { ...DEFAULT_KEEP_URL_PARAMS, ...options.params };\n const result = new URLSearchParams();\n const search = query.search?.query?.trim();\n if (search) result.set(params.search, search);\n for (const tag of query.tags ?? []) {\n const normalized = tag.trim();\n if (normalized) result.append(params.tags, normalized);\n }\n if (query.sort?.by) result.set(params.sort, `${query.sort.by}:${query.sort.direction ?? \"desc\"}`);\n const page = query.pagination?.page;\n if (page !== undefined && Number.isFinite(page) && page > 1) result.set(params.page, String(Math.floor(page)));\n if (query.archiveScope !== undefined) result.set(params.archiveScope, query.archiveScope);\n else if (query.archived !== undefined) result.set(params.archived, query.archived ? \"true\" : \"false\");\n if (query.collectionId) result.set(params.collection, query.collectionId);\n if (query.pinnedFirst) result.set(params.pinnedFirst, \"true\");\n if (query.activity?.opened) result.set(params.activityOpened, query.activity.opened);\n for (const [key, value] of [\n [params.lastOpenedBefore, query.activity?.lastOpenedBefore],\n [params.lastOpenedAfter, query.activity?.lastOpenedAfter],\n [params.inactiveForMs, query.activity?.inactiveForMs],\n ] as const) {\n if (value !== undefined && Number.isFinite(value)) result.set(key, String(value));\n }\n return result;\n}\n\n/** Parse a URL into the query fields supported by KeepCollection. Invalid values are ignored. */\nexport function decodeKeepListQuery(\n input: string | URL | URLSearchParams,\n options: Pick<KeepUrlSyncOptions, \"params\"> = {},\n): KeepUrlState {\n const params: Required<KeepUrlParamNames> = { ...DEFAULT_KEEP_URL_PARAMS, ...options.params };\n const searchParams = input instanceof URLSearchParams ? input : new URL(input, \"http://keepkit.invalid\").searchParams;\n const search = searchParams.get(params.search)?.trim();\n const tags = [\n ...new Set(\n searchParams\n .getAll(params.tags)\n .map((tag) => tag.trim())\n .filter(Boolean),\n ),\n ];\n const sortValue = searchParams.get(params.sort)?.split(\":\");\n const sort: KeepListQuery[\"sort\"] =\n sortValue?.[0] === \"savedAt\" || sortValue?.[0] === \"updatedAt\" || sortValue?.[0] === \"lastOpenedAt\"\n ? {\n by: sortValue[0],\n direction: sortValue[1] === \"asc\" ? (\"asc\" as const) : (\"desc\" as const),\n }\n : undefined;\n const rawPage = Number(searchParams.get(params.page));\n const page = Number.isInteger(rawPage) && rawPage > 0 ? rawPage : undefined;\n const archiveScopeValue = searchParams.get(params.archiveScope);\n const archiveScope =\n archiveScopeValue === \"active\" || archiveScopeValue === \"archived\" || archiveScopeValue === \"all\"\n ? archiveScopeValue\n : undefined;\n const archivedValue = searchParams.get(params.archived);\n const archived =\n archiveScope === \"archived\" || archivedValue === \"true\"\n ? true\n : archiveScope === \"active\" || archivedValue === \"false\"\n ? false\n : undefined;\n const collectionId = searchParams.get(params.collection)?.trim() || undefined;\n const pinnedFirst = searchParams.get(params.pinnedFirst) === \"true\" ? true : undefined;\n const activityOpenedValue = searchParams.get(params.activityOpened);\n const activityOpened: \"ever\" | \"never\" | undefined =\n activityOpenedValue === \"ever\" || activityOpenedValue === \"never\" ? activityOpenedValue : undefined;\n const parseActivityNumber = (name: string): number | undefined => {\n const rawValue = searchParams.get(name);\n if (rawValue === null || rawValue.trim() === \"\") return undefined;\n const value = Number(rawValue);\n return Number.isFinite(value) ? value : undefined;\n };\n const lastOpenedBefore = parseActivityNumber(params.lastOpenedBefore);\n const lastOpenedAfter = parseActivityNumber(params.lastOpenedAfter);\n const inactiveForMs = parseActivityNumber(params.inactiveForMs);\n const activity =\n activityOpened !== undefined ||\n lastOpenedBefore !== undefined ||\n lastOpenedAfter !== undefined ||\n inactiveForMs !== undefined\n ? {\n ...(activityOpened === undefined ? {} : { opened: activityOpened }),\n ...(lastOpenedBefore === undefined ? {} : { lastOpenedBefore }),\n ...(lastOpenedAfter === undefined ? {} : { lastOpenedAfter }),\n ...(inactiveForMs === undefined ? {} : { inactiveForMs }),\n }\n : undefined;\n return {\n ...(search ? { search: { query: search } } : {}),\n ...(tags.length > 0 ? { tags } : {}),\n ...(sort ? { sort } : {}),\n ...(page ? { pagination: { page } } : {}),\n ...(archived === undefined ? {} : { archived }),\n ...(archiveScope === undefined ? {} : { archiveScope }),\n ...(collectionId ? { collectionId } : {}),\n ...(pinnedFirst ? { pinnedFirst } : {}),\n ...(activity === undefined ? {} : { activity }),\n };\n}\n\nexport function serializeKeepListQuery<TMeta = Record<string, unknown>>(\n query: KeepListQuery<TMeta> = {},\n options: Pick<KeepUrlSyncOptions, \"params\"> = {},\n): string {\n const value = encodeKeepListQuery(query, options).toString();\n return value ? `?${value}` : \"\";\n}\n\nexport function mergeKeepListQueryFromUrl<TMeta = Record<string, unknown>>(\n query: KeepListQuery<TMeta>,\n input: string | URL | URLSearchParams,\n options: Pick<KeepUrlSyncOptions, \"params\"> = {},\n): KeepListQuery<TMeta> {\n const decoded = decodeKeepListQuery(input, options);\n return {\n ...query,\n ...decoded,\n search: decoded.search ?? query.search,\n tags: decoded.tags ?? query.tags,\n sort: decoded.sort ?? query.sort,\n pagination: decoded.pagination ? { ...query.pagination, ...decoded.pagination } : query.pagination,\n archived: decoded.archived ?? query.archived,\n archiveScope: decoded.archiveScope ?? query.archiveScope,\n activity: decoded.activity ?? query.activity,\n };\n}\n","import type { KeepPlugin, KeepPluginContext } from \"../items/types\";\n\nexport type KeepInvalidationPluginOptions<TMeta = Record<string, unknown>> = {\n /** Query keys to invalidate after a successful local KeepKit mutation. */\n queryKeys: readonly unknown[] | ((context: KeepPluginContext<TMeta>) => readonly (readonly unknown[])[]);\n /** Connect this callback to queryClient.invalidateQueries or SWR mutate. */\n invalidate: (queryKey: readonly unknown[], context: KeepPluginContext<TMeta>) => void | Promise<void>;\n name?: string;\n};\n\n/** Framework-neutral bridge for TanStack Query, SWR, and similar caches. */\nexport function createKeepInvalidationPlugin<TMeta = Record<string, unknown>>(\n options: KeepInvalidationPluginOptions<TMeta>,\n): KeepPlugin<TMeta> {\n return {\n name: options.name ?? \"keepkit-cache-invalidation\",\n after: async (context) => {\n const keys = typeof options.queryKeys === \"function\" ? options.queryKeys(context) : [options.queryKeys];\n await Promise.all(keys.map((queryKey) => options.invalidate(queryKey, context)));\n },\n };\n}\n","import { type BrowserStorageAdapterOptions, createBrowserStorageAdapter } from \"../../../storage\";\nimport { SyncStorageAdapter, type SyncStorageAdapterOptions } from \"../../../storage/sync\";\nimport type {\n KeepItem,\n KeepSyncAuthError,\n KeepSyncAuthStatus,\n KeepSyncState,\n RemoteSyncDriver,\n RemoteSyncResult,\n StorageAdapter,\n SyncCapableStorageAdapter,\n SyncOperation,\n SyncScope,\n} from \"../../items/types\";\nimport { KeepSyncAuthError as KeepSyncAuthErrorClass } from \"../../items/types\";\nimport { exportItems } from \"../../persistence/backup\";\nimport {\n createScopedStorageAdapter,\n getKeepScopeKey,\n isSameKeepScope,\n ScopedSyncQueueAdapter,\n} from \"../../persistence/scope\";\n\nexport type AuthenticatedSyncRequestContext<TMeta = Record<string, unknown>> = {\n token: string | null;\n scope?: SyncScope;\n operation?: SyncOperation<TMeta>;\n};\n\n/** Transport boundary for auth-aware requests; cookies and bearer tokens remain host concerns. */\nexport type AuthenticatedSyncTransport<TMeta = Record<string, unknown>> = {\n push: (\n operation: SyncOperation<TMeta>,\n context: AuthenticatedSyncRequestContext<TMeta>,\n ) => Promise<RemoteSyncResult<TMeta>>;\n pull?: (context: AuthenticatedSyncRequestContext<TMeta>) => Promise<KeepItem<TMeta>[]>;\n};\n\nexport type AuthenticatedSyncAuthContext<TMeta = Record<string, unknown>> = {\n operation?: SyncOperation<TMeta>;\n scope?: SyncScope;\n};\n\nexport type AuthenticatedSyncKitOptions<TMeta = Record<string, unknown>> = Omit<\n SyncStorageAdapterOptions<TMeta>,\n \"local\" | \"remote\" | \"scope\"\n> & {\n /** Optional custom local adapter. Browser storage is used when omitted. */\n local?: StorageAdapter<TMeta>;\n key?: BrowserStorageAdapterOptions[\"key\"];\n databaseName?: BrowserStorageAdapterOptions[\"databaseName\"];\n scope?: SyncScope;\n /** Resolve the active account or tenant before storage operations. */\n getScope?: () => SyncScope | undefined | Promise<SyncScope | undefined>;\n getAuthToken: () => Promise<string | null>;\n transport: AuthenticatedSyncTransport<TMeta>;\n onAuthError?: (error: KeepSyncAuthError<TMeta>, context: AuthenticatedSyncAuthContext<TMeta>) => void | Promise<void>;\n onReauthenticate?: (\n error: KeepSyncAuthError<TMeta>,\n context: AuthenticatedSyncAuthContext<TMeta>,\n ) => void | Promise<void>;\n onScopeChange?: (next: SyncScope | undefined, previous: SyncScope | undefined) => void | Promise<void>;\n};\n\nexport type AuthenticatedSyncKit<TMeta = Record<string, unknown>> = {\n readonly mode: \"sync\";\n readonly storage: SyncCapableStorageAdapter<TMeta>;\n readonly scope?: SyncScope;\n readonly scopeKey: string;\n getScope(): SyncScope | undefined;\n setScope(scope?: SyncScope): Promise<void>;\n subscribeScope(listener: () => void): () => void;\n exportBackup(): Promise<string>;\n dispose(): void;\n};\n\n/** Creates auth-independent sync wiring with per-request tokens and isolated account scopes. */\nexport function createAuthenticatedSyncKit<TMeta = Record<string, unknown>>(\n options: AuthenticatedSyncKitOptions<TMeta>,\n): AuthenticatedSyncKit<TMeta> {\n const controller = new AuthenticatedSyncStorageController(options);\n return {\n mode: \"sync\",\n storage: controller,\n get scope() {\n return controller.scope;\n },\n get scopeKey() {\n return controller.scopeKey;\n },\n getScope: () => controller.scope,\n setScope: (scope) => controller.setScope(scope),\n subscribeScope: (listener) => controller.subscribeScope(listener),\n exportBackup: () => controller.exportBackup(),\n dispose: () => controller.dispose(),\n };\n}\n\nclass AuthenticatedSyncStorageController<TMeta = Record<string, unknown>> implements SyncCapableStorageAdapter<TMeta> {\n private readonly options: AuthenticatedSyncKitOptions<TMeta>;\n private currentScope: SyncScope | undefined;\n private current: SyncStorageAdapter<TMeta>;\n private readonly scopeListeners = new Set<() => void>();\n private readonly dataListeners = new Set<() => void>();\n private readonly syncListeners = new Set<() => void>();\n private unsubscribeData: () => void = () => undefined;\n private unsubscribeSync: () => void = () => undefined;\n private transition = Promise.resolve();\n private disposed = false;\n\n constructor(options: AuthenticatedSyncKitOptions<TMeta>) {\n this.options = options;\n this.currentScope = options.scope;\n this.current = this.createAdapter(this.currentScope);\n this.attach(this.current);\n }\n\n get storageKey(): string | undefined {\n return this.current.storageKey;\n }\n\n get scope(): SyncScope | undefined {\n return this.currentScope;\n }\n\n get scopeKey(): string {\n return getKeepScopeKey(this.currentScope);\n }\n\n async getAll(): Promise<KeepItem<TMeta>[]> {\n await this.ensureScope();\n return this.current.getAll();\n }\n\n async set(item: KeepItem<TMeta>): Promise<void> {\n await this.ensureScope();\n return this.current.set(item);\n }\n\n async setMany(items: KeepItem<TMeta>[]): Promise<void> {\n await this.ensureScope();\n return this.current.setMany(items);\n }\n\n async remove(id: string): Promise<void> {\n await this.ensureScope();\n return this.current.remove(id);\n }\n\n async removeMany(ids: string[]): Promise<void> {\n await this.ensureScope();\n return this.current.removeMany(ids);\n }\n\n async clear(): Promise<void> {\n await this.ensureScope();\n return this.current.clear();\n }\n\n async merge(items: KeepItem<TMeta>[]): Promise<KeepItem<TMeta>[]> {\n await this.ensureScope();\n return this.current.merge(items);\n }\n\n subscribe(listener: () => void): () => void {\n this.dataListeners.add(listener);\n return () => this.dataListeners.delete(listener);\n }\n\n getSyncState(): KeepSyncState<TMeta> {\n return this.current.getSyncState();\n }\n\n subscribeSync(listener: () => void): () => void {\n this.syncListeners.add(listener);\n return () => this.syncListeners.delete(listener);\n }\n\n async flushSync(): Promise<void> {\n await this.ensureScope();\n return this.current.flushSync();\n }\n\n async retrySync(): Promise<void> {\n await this.ensureScope();\n return this.current.retrySync?.() ?? this.current.flushSync();\n }\n\n async resolveSyncConflict(\n id: string,\n resolution: \"local\" | \"remote\" | \"manual\",\n item?: KeepItem<TMeta>,\n ): Promise<void> {\n await this.ensureScope();\n if (!this.current.resolveSyncConflict) {\n throw new Error(\"The authenticated sync adapter does not support conflict resolution.\");\n }\n return this.current.resolveSyncConflict(id, resolution, item);\n }\n\n async setScope(nextScope?: SyncScope): Promise<void> {\n const run = this.transition.then(async () => {\n if (isSameKeepScope(this.currentScope, nextScope)) return;\n if (this.disposed) throw new Error(\"AuthenticatedSyncKit has been disposed.\");\n const previousScope = this.currentScope;\n this.unsubscribeData();\n this.unsubscribeSync();\n this.current.dispose?.();\n this.currentScope = nextScope;\n this.current = this.createAdapter(nextScope);\n this.attach(this.current);\n await this.options.onScopeChange?.(nextScope, previousScope);\n this.notify(this.scopeListeners);\n this.notify(this.dataListeners);\n this.notify(this.syncListeners);\n });\n this.transition = run.catch(() => undefined);\n return run;\n }\n\n subscribeScope(listener: () => void): () => void {\n this.scopeListeners.add(listener);\n return () => this.scopeListeners.delete(listener);\n }\n\n async exportBackup(): Promise<string> {\n await this.ensureScope();\n return exportItems(this.current);\n }\n\n dispose(): void {\n this.disposed = true;\n this.unsubscribeData();\n this.unsubscribeSync();\n this.current.dispose?.();\n this.scopeListeners.clear();\n this.dataListeners.clear();\n this.syncListeners.clear();\n }\n\n private createAdapter(scope: SyncScope | undefined): SyncStorageAdapter<TMeta> {\n const local = this.options.local\n ? scope\n ? createScopedStorageAdapter(this.options.local, scope)\n : this.options.local\n : createBrowserStorageAdapter<TMeta>({ key: this.options.key, databaseName: this.options.databaseName, scope });\n const queue =\n this.options.queue && scope ? new ScopedSyncQueueAdapter(this.options.queue, scope) : this.options.queue;\n const remote = createAuthenticatedRemote(this.options, scope);\n return new SyncStorageAdapter<TMeta>({\n ...this.options,\n local,\n remote,\n queue,\n scope,\n });\n }\n\n private attach(adapter: SyncStorageAdapter<TMeta>): void {\n this.unsubscribeData = adapter.subscribe?.(() => this.notify(this.dataListeners)) ?? (() => undefined);\n this.unsubscribeSync = adapter.subscribeSync(() => this.notify(this.syncListeners));\n }\n\n private async ensureScope(): Promise<void> {\n if (!this.options.getScope) return;\n await this.setScope(await this.options.getScope());\n }\n\n private notify(listeners: Set<() => void>): void {\n for (const listener of listeners) listener();\n }\n}\n\nfunction createAuthenticatedRemote<TMeta>(\n options: AuthenticatedSyncKitOptions<TMeta>,\n scope: SyncScope | undefined,\n): RemoteSyncDriver<TMeta> {\n const pull = options.transport.pull;\n return {\n push: async (operation) => {\n try {\n const token = await options.getAuthToken();\n return await options.transport.push(operation, { token, scope, operation });\n } catch (cause) {\n return handleAuthFailure(cause, options, { operation, scope });\n }\n },\n pull: pull\n ? async () => {\n try {\n const token = await options.getAuthToken();\n return await pull({ token, scope });\n } catch (cause) {\n return handleAuthFailure(cause, options, { scope });\n }\n }\n : undefined,\n };\n}\n\nasync function handleAuthFailure<TMeta>(\n cause: unknown,\n options: AuthenticatedSyncKitOptions<TMeta>,\n context: AuthenticatedSyncAuthContext<TMeta>,\n): Promise<never> {\n const status = getAuthStatus(cause);\n if (!status) throw cause;\n const error =\n cause instanceof KeepSyncAuthErrorClass\n ? cause\n : new KeepSyncAuthErrorClass(status, { operation: context.operation, scope: context.scope, cause });\n await options.onAuthError?.(error, context);\n await options.onReauthenticate?.(error, context);\n throw error;\n}\n\nfunction getAuthStatus(error: unknown): KeepSyncAuthStatus | undefined {\n if (error instanceof KeepSyncAuthErrorClass) return error.status;\n if (!error || typeof error !== \"object\") return undefined;\n const candidate = error as { status?: unknown; response?: { status?: unknown }; cause?: unknown };\n if (candidate.status === 401 || candidate.status === 403) return candidate.status;\n if (candidate.response?.status === 401 || candidate.response?.status === 403) return candidate.response.status;\n return candidate.cause ? getAuthStatus(candidate.cause) : undefined;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/features/items/presets.ts","../src/features/items/saved-views.ts","../src/features/items/url.ts","../src/features/sync/integrations.ts","../src/features/sync/templates/auth-sync.ts"],"sourcesContent":["import { createBrowserStorageAdapter } from \"../../storage/index\";\nimport { SyncStorageAdapter } from \"../../storage/sync\";\nimport { exportItems } from \"../persistence/backup\";\nimport { createScopedStorageAdapter, type KeepScope } from \"../persistence/scope\";\nimport type { RemoteSyncDriver, StorageAdapter } from \"./types\";\n\nexport type KeepKitPresetMode = \"local\" | \"sync\" | \"backup\";\n\nexport type KeepKitPresetOptions<TMeta = Record<string, unknown>> = {\n mode?: KeepKitPresetMode;\n key?: string;\n scope?: KeepScope;\n remote?: RemoteSyncDriver<TMeta>;\n storage?: StorageAdapter<TMeta>;\n};\n\nexport type KeepKitSetup<TMeta = Record<string, unknown>> = {\n mode: KeepKitPresetMode;\n scope?: KeepScope;\n storage: StorageAdapter<TMeta>;\n exportBackup: () => Promise<string>;\n};\n\n/**\n * Build the recommended local/sync/backup wiring without imposing an auth or\n * API client. Pass the current user and tenant scope whenever the account changes.\n */\nexport function createKeepKitPreset<TMeta = Record<string, unknown>>(\n options: KeepKitPresetOptions<TMeta> = {},\n): KeepKitSetup<TMeta> {\n const mode = options.mode ?? \"local\";\n const local = options.storage\n ? options.scope\n ? createScopedStorageAdapter(options.storage, options.scope)\n : options.storage\n : createBrowserStorageAdapter<TMeta>({ key: options.key, scope: options.scope });\n if (mode === \"sync\" && !options.remote) {\n throw new Error('createKeepKitPreset({ mode: \"sync\" }) requires a remote driver.');\n }\n let storage: StorageAdapter<TMeta> = local;\n if (mode === \"sync\") {\n const remote = options.remote;\n if (!remote) throw new Error('createKeepKitPreset({ mode: \"sync\" }) requires a remote driver.');\n storage = new SyncStorageAdapter<TMeta>({\n local,\n remote,\n userId: options.scope?.userId,\n tenantId: options.scope?.tenantId,\n });\n }\n return {\n mode,\n scope: options.scope,\n storage,\n exportBackup: () => exportItems(storage),\n };\n}\n\nexport const createKeepKitSetup = createKeepKitPreset;\n","import type { KeepListQuery } from \"./query\";\n\nexport type KeepSavedView<TMeta = Record<string, unknown>> = {\n id: string;\n name: string;\n query: KeepListQuery<TMeta>;\n pinned?: boolean;\n createdAt: number;\n updatedAt: number;\n};\n\nexport interface KeepSavedViewStorage<TMeta = Record<string, unknown>> {\n getAll(): Promise<KeepSavedView<TMeta>[]>;\n get(id: string): Promise<KeepSavedView<TMeta> | undefined>;\n set(view: KeepSavedView<TMeta>): Promise<void>;\n remove(id: string): Promise<void>;\n}\n\nexport const DEFAULT_SAVED_VIEWS_STORAGE_KEY = \"keepkit:saved-views\";\n\n/** Local-first Saved View storage kept separate from item storage. */\nexport class LocalStorageKeepSavedViewStorage<TMeta = Record<string, unknown>> implements KeepSavedViewStorage<TMeta> {\n private readonly key: string;\n private readonly storage?: Storage;\n\n constructor(options: { key?: string; storage?: Storage } = {}) {\n this.key = options.key ?? DEFAULT_SAVED_VIEWS_STORAGE_KEY;\n this.storage = options.storage;\n }\n\n async getAll(): Promise<KeepSavedView<TMeta>[]> {\n const raw = this.getStorage().getItem(this.key);\n if (!raw) return [];\n const data: unknown = JSON.parse(raw);\n if (!Array.isArray(data) || !data.every(isSavedView)) throw new Error(\"KeepKit saved-view data is invalid.\");\n return data as KeepSavedView<TMeta>[];\n }\n\n async set(view: KeepSavedView<TMeta>): Promise<void> {\n const range = view.query.savedBetween;\n const normalized = {\n ...view,\n query: {\n ...view.query,\n ...(range\n ? {\n savedBetween: [\n range[0] instanceof Date ? range[0].getTime() : range[0],\n range[1] instanceof Date ? range[1].getTime() : range[1],\n ] as const,\n }\n : {}),\n },\n };\n if (!isSavedView(normalized)) throw new Error(\"KeepKit Saved View is invalid.\");\n const views = await this.getAll();\n const next = [...views.filter((current) => current.id !== normalized.id), normalized];\n this.getStorage().setItem(this.key, JSON.stringify(next));\n }\n\n async get(id: string): Promise<KeepSavedView<TMeta> | undefined> {\n return (await this.getAll()).find((view) => view.id === id);\n }\n\n async remove(id: string): Promise<void> {\n const views = await this.getAll();\n this.getStorage().setItem(this.key, JSON.stringify(views.filter((view) => view.id !== id)));\n }\n\n private getStorage(): Storage {\n if (this.storage) return this.storage;\n if (typeof localStorage === \"undefined\")\n throw new Error(\"KeepKit Saved Views require browser storage or an injected adapter.\");\n return localStorage;\n }\n}\n\nfunction isSavedView(value: unknown): value is KeepSavedView {\n if (typeof value !== \"object\" || value === null) return false;\n const view = value as Record<string, unknown>;\n return (\n typeof view.id === \"string\" &&\n view.id.length > 0 &&\n typeof view.name === \"string\" &&\n view.name.trim().length > 0 &&\n Number.isFinite(view.createdAt) &&\n Number.isFinite(view.updatedAt) &&\n isKeepListQuery(view.query) &&\n (view.pinned === undefined || typeof view.pinned === \"boolean\")\n );\n}\n\nfunction isKeepListQuery(value: unknown): boolean {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) return false;\n const query = value as Record<string, unknown>;\n if (query.filter !== undefined) return false;\n if (query.tags !== undefined && (!Array.isArray(query.tags) || !query.tags.every((tag) => typeof tag === \"string\"))) {\n return false;\n }\n if (query.collectionId !== undefined && typeof query.collectionId !== \"string\") return false;\n if (query.targetType !== undefined && typeof query.targetType !== \"string\") return false;\n if (query.archived !== undefined && typeof query.archived !== \"boolean\") return false;\n if (query.archiveScope !== undefined && ![\"active\", \"archived\", \"all\"].includes(String(query.archiveScope))) {\n return false;\n }\n if (query.pinnedFirst !== undefined && typeof query.pinnedFirst !== \"boolean\") return false;\n if (query.sort !== undefined) {\n if (!isRecord(query.sort) || ![\"savedAt\", \"updatedAt\", \"lastOpenedAt\"].includes(String(query.sort.by)))\n return false;\n if (query.sort.direction !== undefined && query.sort.direction !== \"asc\" && query.sort.direction !== \"desc\")\n return false;\n }\n if (query.search !== undefined) {\n if (!isRecord(query.search)) return false;\n if (query.search.query !== undefined && typeof query.search.query !== \"string\") return false;\n if (query.search.mode !== undefined && query.search.mode !== \"and\" && query.search.mode !== \"or\") return false;\n if (query.search.tokenize !== undefined && typeof query.search.tokenize !== \"boolean\") return false;\n if (\n query.search.fields !== undefined &&\n (!Array.isArray(query.search.fields) ||\n !query.search.fields.every((field) => field === \"note\" || field === \"meta\" || field === \"tags\"))\n ) {\n return false;\n }\n }\n if (query.activity !== undefined) {\n if (!isRecord(query.activity)) return false;\n if (query.activity.opened !== undefined && query.activity.opened !== \"ever\" && query.activity.opened !== \"never\") {\n return false;\n }\n if (\n [query.activity.lastOpenedBefore, query.activity.lastOpenedAfter, query.activity.inactiveForMs].some(\n isInvalidNumber,\n )\n ) {\n return false;\n }\n }\n if (\n query.savedBetween !== undefined &&\n (!Array.isArray(query.savedBetween) || query.savedBetween.length !== 2 || query.savedBetween.some(isInvalidNumber))\n ) {\n return false;\n }\n if (query.pagination !== undefined) {\n if (!isRecord(query.pagination) || [query.pagination.page, query.pagination.pageSize].some(isInvalidNumber))\n return false;\n }\n const organization = query.organization;\n if (organization !== undefined) {\n if (typeof organization !== \"object\" || organization === null || Array.isArray(organization)) return false;\n const fields = organization as Record<string, unknown>;\n if (\n [fields.collection, fields.tags, fields.note].some(\n (field) => field !== undefined && field !== \"assigned\" && field !== \"unassigned\",\n )\n ) {\n return false;\n }\n }\n return true;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isInvalidNumber(value: unknown): boolean {\n return value !== undefined && (typeof value !== \"number\" || !Number.isFinite(value));\n}\n","import type { KeepListQuery } from \"./query\";\n\nexport type KeepUrlParamNames = {\n search: string;\n tags: string;\n sort: string;\n page: string;\n archived: string;\n archiveScope: string;\n collection: string;\n pinnedFirst: string;\n activityOpened?: string;\n lastOpenedBefore?: string;\n lastOpenedAfter?: string;\n inactiveForMs?: string;\n organizationCollection?: string;\n organizationTags?: string;\n organizationNote?: string;\n savedAfter?: string;\n savedBefore?: string;\n};\n\nexport type KeepUrlSyncOptions = {\n /** Parameters are intentionally short so shared collection URLs stay readable. */\n params?: Partial<KeepUrlParamNames>;\n /** Push is the default so browser back/forward restores collection states. */\n history?: \"replace\" | \"push\";\n /** URL to read/write. Defaults to the current browser URL. */\n url?: string;\n};\n\nexport const DEFAULT_KEEP_URL_PARAMS: Required<KeepUrlParamNames> = {\n search: \"q\",\n tags: \"tag\",\n sort: \"sort\",\n page: \"page\",\n archived: \"archived\",\n archiveScope: \"archiveScope\",\n collection: \"collection\",\n pinnedFirst: \"pinned\",\n activityOpened: \"opened\",\n lastOpenedBefore: \"openedBefore\",\n lastOpenedAfter: \"openedAfter\",\n inactiveForMs: \"inactiveFor\",\n organizationCollection: \"collectionState\",\n organizationTags: \"tagsState\",\n organizationNote: \"noteState\",\n savedAfter: \"savedAfter\",\n savedBefore: \"savedBefore\",\n};\n\nexport type KeepUrlState = Pick<\n KeepListQuery,\n | \"search\"\n | \"tags\"\n | \"sort\"\n | \"pagination\"\n | \"archived\"\n | \"archiveScope\"\n | \"collectionId\"\n | \"pinnedFirst\"\n | \"activity\"\n | \"organization\"\n | \"savedBetween\"\n>;\n\n/** Convert a list query to stable URLSearchParams without serializing functions or unsupported filters. */\nexport function encodeKeepListQuery<TMeta = Record<string, unknown>>(\n query: KeepListQuery<TMeta> = {},\n options: Pick<KeepUrlSyncOptions, \"params\"> = {},\n): URLSearchParams {\n const params: Required<KeepUrlParamNames> = { ...DEFAULT_KEEP_URL_PARAMS, ...options.params };\n const result = new URLSearchParams();\n const search = query.search?.query?.trim();\n if (search) result.set(params.search, search);\n for (const tag of query.tags ?? []) {\n const normalized = tag.trim();\n if (normalized) result.append(params.tags, normalized);\n }\n if (query.sort?.by) result.set(params.sort, `${query.sort.by}:${query.sort.direction ?? \"desc\"}`);\n const page = query.pagination?.page;\n if (page !== undefined && Number.isFinite(page) && page > 1) result.set(params.page, String(Math.floor(page)));\n if (query.archiveScope !== undefined) result.set(params.archiveScope, query.archiveScope);\n else if (query.archived !== undefined) result.set(params.archived, query.archived ? \"true\" : \"false\");\n if (query.collectionId) result.set(params.collection, query.collectionId);\n for (const [key, value] of [\n [params.organizationCollection, query.organization?.collection],\n [params.organizationTags, query.organization?.tags],\n [params.organizationNote, query.organization?.note],\n ] as const) {\n if (value !== undefined) result.set(key, value);\n }\n if (query.pinnedFirst) result.set(params.pinnedFirst, \"true\");\n if (query.savedBetween) {\n const [from, to] = query.savedBetween.map((value) => (value instanceof Date ? value.getTime() : value));\n if (Number.isFinite(from) && Number.isFinite(to)) {\n result.set(params.savedAfter, String(from));\n result.set(params.savedBefore, String(to));\n }\n }\n if (query.activity?.opened) result.set(params.activityOpened, query.activity.opened);\n for (const [key, value] of [\n [params.lastOpenedBefore, query.activity?.lastOpenedBefore],\n [params.lastOpenedAfter, query.activity?.lastOpenedAfter],\n [params.inactiveForMs, query.activity?.inactiveForMs],\n ] as const) {\n if (value !== undefined && Number.isFinite(value)) result.set(key, String(value));\n }\n return result;\n}\n\n/** Parse a URL into the query fields supported by KeepCollection. Invalid values are ignored. */\nexport function decodeKeepListQuery(\n input: string | URL | URLSearchParams,\n options: Pick<KeepUrlSyncOptions, \"params\"> = {},\n): KeepUrlState {\n const params: Required<KeepUrlParamNames> = { ...DEFAULT_KEEP_URL_PARAMS, ...options.params };\n const searchParams = input instanceof URLSearchParams ? input : new URL(input, \"http://keepkit.invalid\").searchParams;\n const search = searchParams.get(params.search)?.trim();\n const tags = [\n ...new Set(\n searchParams\n .getAll(params.tags)\n .map((tag) => tag.trim())\n .filter(Boolean),\n ),\n ];\n const sortValue = searchParams.get(params.sort)?.split(\":\");\n const sort: KeepListQuery[\"sort\"] =\n sortValue?.[0] === \"savedAt\" || sortValue?.[0] === \"updatedAt\" || sortValue?.[0] === \"lastOpenedAt\"\n ? {\n by: sortValue[0],\n direction: sortValue[1] === \"asc\" ? (\"asc\" as const) : (\"desc\" as const),\n }\n : undefined;\n const rawPage = Number(searchParams.get(params.page));\n const page = Number.isInteger(rawPage) && rawPage > 0 ? rawPage : undefined;\n const archiveScopeValue = searchParams.get(params.archiveScope);\n const archiveScope =\n archiveScopeValue === \"active\" || archiveScopeValue === \"archived\" || archiveScopeValue === \"all\"\n ? archiveScopeValue\n : undefined;\n const archivedValue = searchParams.get(params.archived);\n const archived =\n archiveScope === \"archived\" || archivedValue === \"true\"\n ? true\n : archiveScope === \"active\" || archivedValue === \"false\"\n ? false\n : undefined;\n const collectionId = searchParams.get(params.collection)?.trim() || undefined;\n const organizationCollection = parseOrganizationState(searchParams.get(params.organizationCollection));\n const organizationTags = parseOrganizationState(searchParams.get(params.organizationTags));\n const organizationNote = parseOrganizationState(searchParams.get(params.organizationNote));\n const organization =\n organizationCollection || organizationTags || organizationNote\n ? {\n ...(organizationCollection ? { collection: organizationCollection } : {}),\n ...(organizationTags ? { tags: organizationTags } : {}),\n ...(organizationNote ? { note: organizationNote } : {}),\n }\n : undefined;\n const pinnedFirst = searchParams.get(params.pinnedFirst) === \"true\" ? true : undefined;\n const parseSavedDate = (name: string): number | undefined => {\n const rawValue = searchParams.get(name);\n if (rawValue === null || rawValue.trim() === \"\") return undefined;\n const value = Number(rawValue);\n return Number.isFinite(value) ? value : undefined;\n };\n const savedAfter = parseSavedDate(params.savedAfter);\n const savedBefore = parseSavedDate(params.savedBefore);\n const savedBetween =\n savedAfter === undefined || savedBefore === undefined ? undefined : ([savedAfter, savedBefore] as const);\n const activityOpenedValue = searchParams.get(params.activityOpened);\n const activityOpened: \"ever\" | \"never\" | undefined =\n activityOpenedValue === \"ever\" || activityOpenedValue === \"never\" ? activityOpenedValue : undefined;\n const parseActivityNumber = (name: string): number | undefined => {\n const rawValue = searchParams.get(name);\n if (rawValue === null || rawValue.trim() === \"\") return undefined;\n const value = Number(rawValue);\n return Number.isFinite(value) ? value : undefined;\n };\n const lastOpenedBefore = parseActivityNumber(params.lastOpenedBefore);\n const lastOpenedAfter = parseActivityNumber(params.lastOpenedAfter);\n const inactiveForMs = parseActivityNumber(params.inactiveForMs);\n const activity =\n activityOpened !== undefined ||\n lastOpenedBefore !== undefined ||\n lastOpenedAfter !== undefined ||\n inactiveForMs !== undefined\n ? {\n ...(activityOpened === undefined ? {} : { opened: activityOpened }),\n ...(lastOpenedBefore === undefined ? {} : { lastOpenedBefore }),\n ...(lastOpenedAfter === undefined ? {} : { lastOpenedAfter }),\n ...(inactiveForMs === undefined ? {} : { inactiveForMs }),\n }\n : undefined;\n return {\n ...(search ? { search: { query: search } } : {}),\n ...(tags.length > 0 ? { tags } : {}),\n ...(sort ? { sort } : {}),\n ...(page ? { pagination: { page } } : {}),\n ...(archived === undefined ? {} : { archived }),\n ...(archiveScope === undefined ? {} : { archiveScope }),\n ...(collectionId ? { collectionId } : {}),\n ...(organization ? { organization } : {}),\n ...(pinnedFirst ? { pinnedFirst } : {}),\n ...(savedBetween ? { savedBetween } : {}),\n ...(activity === undefined ? {} : { activity }),\n };\n}\n\nexport function serializeKeepListQuery<TMeta = Record<string, unknown>>(\n query: KeepListQuery<TMeta> = {},\n options: Pick<KeepUrlSyncOptions, \"params\"> = {},\n): string {\n const value = encodeKeepListQuery(query, options).toString();\n return value ? `?${value}` : \"\";\n}\n\nexport function mergeKeepListQueryFromUrl<TMeta = Record<string, unknown>>(\n query: KeepListQuery<TMeta>,\n input: string | URL | URLSearchParams,\n options: Pick<KeepUrlSyncOptions, \"params\"> = {},\n): KeepListQuery<TMeta> {\n const decoded = decodeKeepListQuery(input, options);\n return {\n ...query,\n ...decoded,\n search: decoded.search ?? query.search,\n tags: decoded.tags ?? query.tags,\n sort: decoded.sort ?? query.sort,\n pagination: decoded.pagination ? { ...query.pagination, ...decoded.pagination } : query.pagination,\n archived: decoded.archived ?? query.archived,\n archiveScope: decoded.archiveScope ?? query.archiveScope,\n activity: decoded.activity ?? query.activity,\n organization: decoded.organization ?? query.organization,\n savedBetween: decoded.savedBetween ?? query.savedBetween,\n };\n}\n\nfunction parseOrganizationState(value: string | null): \"assigned\" | \"unassigned\" | undefined {\n return value === \"assigned\" || value === \"unassigned\" ? value : undefined;\n}\n","import type { KeepPlugin, KeepPluginContext } from \"../items/types\";\n\nexport type KeepInvalidationPluginOptions<TMeta = Record<string, unknown>> = {\n /** Query keys to invalidate after a successful local KeepKit mutation. */\n queryKeys: readonly unknown[] | ((context: KeepPluginContext<TMeta>) => readonly (readonly unknown[])[]);\n /** Connect this callback to queryClient.invalidateQueries or SWR mutate. */\n invalidate: (queryKey: readonly unknown[], context: KeepPluginContext<TMeta>) => void | Promise<void>;\n name?: string;\n};\n\n/** Framework-neutral bridge for TanStack Query, SWR, and similar caches. */\nexport function createKeepInvalidationPlugin<TMeta = Record<string, unknown>>(\n options: KeepInvalidationPluginOptions<TMeta>,\n): KeepPlugin<TMeta> {\n return {\n name: options.name ?? \"keepkit-cache-invalidation\",\n after: async (context) => {\n const keys = typeof options.queryKeys === \"function\" ? options.queryKeys(context) : [options.queryKeys];\n await Promise.all(keys.map((queryKey) => options.invalidate(queryKey, context)));\n },\n };\n}\n","import { type BrowserStorageAdapterOptions, createBrowserStorageAdapter } from \"../../../storage\";\nimport { SyncStorageAdapter, type SyncStorageAdapterOptions } from \"../../../storage/sync\";\nimport type {\n KeepItem,\n KeepSyncAuthError,\n KeepSyncAuthStatus,\n KeepSyncState,\n RemoteSyncDriver,\n RemoteSyncResult,\n StorageAdapter,\n SyncCapableStorageAdapter,\n SyncOperation,\n SyncScope,\n} from \"../../items/types\";\nimport { KeepSyncAuthError as KeepSyncAuthErrorClass } from \"../../items/types\";\nimport { exportItems } from \"../../persistence/backup\";\nimport {\n createScopedStorageAdapter,\n getKeepScopeKey,\n isSameKeepScope,\n ScopedSyncQueueAdapter,\n} from \"../../persistence/scope\";\n\nexport type AuthenticatedSyncRequestContext<TMeta = Record<string, unknown>> = {\n token: string | null;\n scope?: SyncScope;\n operation?: SyncOperation<TMeta>;\n};\n\n/** Transport boundary for auth-aware requests; cookies and bearer tokens remain host concerns. */\nexport type AuthenticatedSyncTransport<TMeta = Record<string, unknown>> = {\n push: (\n operation: SyncOperation<TMeta>,\n context: AuthenticatedSyncRequestContext<TMeta>,\n ) => Promise<RemoteSyncResult<TMeta>>;\n pull?: (context: AuthenticatedSyncRequestContext<TMeta>) => Promise<KeepItem<TMeta>[]>;\n};\n\nexport type AuthenticatedSyncAuthContext<TMeta = Record<string, unknown>> = {\n operation?: SyncOperation<TMeta>;\n scope?: SyncScope;\n};\n\nexport type AuthenticatedSyncKitOptions<TMeta = Record<string, unknown>> = Omit<\n SyncStorageAdapterOptions<TMeta>,\n \"local\" | \"remote\" | \"scope\"\n> & {\n /** Optional custom local adapter. Browser storage is used when omitted. */\n local?: StorageAdapter<TMeta>;\n key?: BrowserStorageAdapterOptions[\"key\"];\n databaseName?: BrowserStorageAdapterOptions[\"databaseName\"];\n scope?: SyncScope;\n /** Resolve the active account or tenant before storage operations. */\n getScope?: () => SyncScope | undefined | Promise<SyncScope | undefined>;\n getAuthToken: () => Promise<string | null>;\n transport: AuthenticatedSyncTransport<TMeta>;\n onAuthError?: (error: KeepSyncAuthError<TMeta>, context: AuthenticatedSyncAuthContext<TMeta>) => void | Promise<void>;\n onReauthenticate?: (\n error: KeepSyncAuthError<TMeta>,\n context: AuthenticatedSyncAuthContext<TMeta>,\n ) => void | Promise<void>;\n onScopeChange?: (next: SyncScope | undefined, previous: SyncScope | undefined) => void | Promise<void>;\n};\n\nexport type AuthenticatedSyncKit<TMeta = Record<string, unknown>> = {\n readonly mode: \"sync\";\n readonly storage: SyncCapableStorageAdapter<TMeta>;\n readonly scope?: SyncScope;\n readonly scopeKey: string;\n getScope(): SyncScope | undefined;\n setScope(scope?: SyncScope): Promise<void>;\n subscribeScope(listener: () => void): () => void;\n exportBackup(): Promise<string>;\n dispose(): void;\n};\n\n/** Creates auth-independent sync wiring with per-request tokens and isolated account scopes. */\nexport function createAuthenticatedSyncKit<TMeta = Record<string, unknown>>(\n options: AuthenticatedSyncKitOptions<TMeta>,\n): AuthenticatedSyncKit<TMeta> {\n const controller = new AuthenticatedSyncStorageController(options);\n return {\n mode: \"sync\",\n storage: controller,\n get scope() {\n return controller.scope;\n },\n get scopeKey() {\n return controller.scopeKey;\n },\n getScope: () => controller.scope,\n setScope: (scope) => controller.setScope(scope),\n subscribeScope: (listener) => controller.subscribeScope(listener),\n exportBackup: () => controller.exportBackup(),\n dispose: () => controller.dispose(),\n };\n}\n\nclass AuthenticatedSyncStorageController<TMeta = Record<string, unknown>> implements SyncCapableStorageAdapter<TMeta> {\n private readonly options: AuthenticatedSyncKitOptions<TMeta>;\n private currentScope: SyncScope | undefined;\n private current: SyncStorageAdapter<TMeta>;\n private readonly scopeListeners = new Set<() => void>();\n private readonly dataListeners = new Set<() => void>();\n private readonly syncListeners = new Set<() => void>();\n private unsubscribeData: () => void = () => undefined;\n private unsubscribeSync: () => void = () => undefined;\n private transition = Promise.resolve();\n private disposed = false;\n\n constructor(options: AuthenticatedSyncKitOptions<TMeta>) {\n this.options = options;\n this.currentScope = options.scope;\n this.current = this.createAdapter(this.currentScope);\n this.attach(this.current);\n }\n\n get storageKey(): string | undefined {\n return this.current.storageKey;\n }\n\n get scope(): SyncScope | undefined {\n return this.currentScope;\n }\n\n get scopeKey(): string {\n return getKeepScopeKey(this.currentScope);\n }\n\n async getAll(): Promise<KeepItem<TMeta>[]> {\n await this.ensureScope();\n return this.current.getAll();\n }\n\n async set(item: KeepItem<TMeta>): Promise<void> {\n await this.ensureScope();\n return this.current.set(item);\n }\n\n async setMany(items: KeepItem<TMeta>[]): Promise<void> {\n await this.ensureScope();\n return this.current.setMany(items);\n }\n\n async remove(id: string): Promise<void> {\n await this.ensureScope();\n return this.current.remove(id);\n }\n\n async removeMany(ids: string[]): Promise<void> {\n await this.ensureScope();\n return this.current.removeMany(ids);\n }\n\n async clear(): Promise<void> {\n await this.ensureScope();\n return this.current.clear();\n }\n\n async merge(items: KeepItem<TMeta>[]): Promise<KeepItem<TMeta>[]> {\n await this.ensureScope();\n return this.current.merge(items);\n }\n\n subscribe(listener: () => void): () => void {\n this.dataListeners.add(listener);\n return () => this.dataListeners.delete(listener);\n }\n\n getSyncState(): KeepSyncState<TMeta> {\n return this.current.getSyncState();\n }\n\n subscribeSync(listener: () => void): () => void {\n this.syncListeners.add(listener);\n return () => this.syncListeners.delete(listener);\n }\n\n async flushSync(): Promise<void> {\n await this.ensureScope();\n return this.current.flushSync();\n }\n\n async retrySync(): Promise<void> {\n await this.ensureScope();\n return this.current.retrySync?.() ?? this.current.flushSync();\n }\n\n async resolveSyncConflict(\n id: string,\n resolution: \"local\" | \"remote\" | \"manual\",\n item?: KeepItem<TMeta>,\n ): Promise<void> {\n await this.ensureScope();\n if (!this.current.resolveSyncConflict) {\n throw new Error(\"The authenticated sync adapter does not support conflict resolution.\");\n }\n return this.current.resolveSyncConflict(id, resolution, item);\n }\n\n async setScope(nextScope?: SyncScope): Promise<void> {\n const run = this.transition.then(async () => {\n if (isSameKeepScope(this.currentScope, nextScope)) return;\n if (this.disposed) throw new Error(\"AuthenticatedSyncKit has been disposed.\");\n const previousScope = this.currentScope;\n this.unsubscribeData();\n this.unsubscribeSync();\n this.current.dispose?.();\n this.currentScope = nextScope;\n this.current = this.createAdapter(nextScope);\n this.attach(this.current);\n await this.options.onScopeChange?.(nextScope, previousScope);\n this.notify(this.scopeListeners);\n this.notify(this.dataListeners);\n this.notify(this.syncListeners);\n });\n this.transition = run.catch(() => undefined);\n return run;\n }\n\n subscribeScope(listener: () => void): () => void {\n this.scopeListeners.add(listener);\n return () => this.scopeListeners.delete(listener);\n }\n\n async exportBackup(): Promise<string> {\n await this.ensureScope();\n return exportItems(this.current);\n }\n\n dispose(): void {\n this.disposed = true;\n this.unsubscribeData();\n this.unsubscribeSync();\n this.current.dispose?.();\n this.scopeListeners.clear();\n this.dataListeners.clear();\n this.syncListeners.clear();\n }\n\n private createAdapter(scope: SyncScope | undefined): SyncStorageAdapter<TMeta> {\n const local = this.options.local\n ? scope\n ? createScopedStorageAdapter(this.options.local, scope)\n : this.options.local\n : createBrowserStorageAdapter<TMeta>({ key: this.options.key, databaseName: this.options.databaseName, scope });\n const queue =\n this.options.queue && scope ? new ScopedSyncQueueAdapter(this.options.queue, scope) : this.options.queue;\n const remote = createAuthenticatedRemote(this.options, scope);\n return new SyncStorageAdapter<TMeta>({\n ...this.options,\n local,\n remote,\n queue,\n scope,\n });\n }\n\n private attach(adapter: SyncStorageAdapter<TMeta>): void {\n this.unsubscribeData = adapter.subscribe?.(() => this.notify(this.dataListeners)) ?? (() => undefined);\n this.unsubscribeSync = adapter.subscribeSync(() => this.notify(this.syncListeners));\n }\n\n private async ensureScope(): Promise<void> {\n if (!this.options.getScope) return;\n await this.setScope(await this.options.getScope());\n }\n\n private notify(listeners: Set<() => void>): void {\n for (const listener of listeners) listener();\n }\n}\n\nfunction createAuthenticatedRemote<TMeta>(\n options: AuthenticatedSyncKitOptions<TMeta>,\n scope: SyncScope | undefined,\n): RemoteSyncDriver<TMeta> {\n const pull = options.transport.pull;\n return {\n push: async (operation) => {\n try {\n const token = await options.getAuthToken();\n return await options.transport.push(operation, { token, scope, operation });\n } catch (cause) {\n return handleAuthFailure(cause, options, { operation, scope });\n }\n },\n pull: pull\n ? async () => {\n try {\n const token = await options.getAuthToken();\n return await pull({ token, scope });\n } catch (cause) {\n return handleAuthFailure(cause, options, { scope });\n }\n }\n : undefined,\n };\n}\n\nasync function handleAuthFailure<TMeta>(\n cause: unknown,\n options: AuthenticatedSyncKitOptions<TMeta>,\n context: AuthenticatedSyncAuthContext<TMeta>,\n): Promise<never> {\n const status = getAuthStatus(cause);\n if (!status) throw cause;\n const error =\n cause instanceof KeepSyncAuthErrorClass\n ? cause\n : new KeepSyncAuthErrorClass(status, { operation: context.operation, scope: context.scope, cause });\n await options.onAuthError?.(error, context);\n await options.onReauthenticate?.(error, context);\n throw error;\n}\n\nfunction getAuthStatus(error: unknown): KeepSyncAuthStatus | undefined {\n if (error instanceof KeepSyncAuthErrorClass) return error.status;\n if (!error || typeof error !== \"object\") return undefined;\n const candidate = error as { status?: unknown; response?: { status?: unknown }; cause?: unknown };\n if (candidate.status === 401 || candidate.status === 403) return candidate.status;\n if (candidate.response?.status === 401 || candidate.response?.status === 403) return candidate.response.status;\n return candidate.cause ? getAuthStatus(candidate.cause) : undefined;\n}\n"],"mappings":"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","names":[]}
|
package/dist/react.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { i as KeepItemMetadataRefresher, n as KeepItemRevalidator, j as KeepItemResolver, d as KeepAutoRevalidationOptions, h as KeepCollectionMeta, R as RevalidateKeepItemsOptions, m as KeepItemRevalidationSummary, I as ImportItemsOptions, a as ImportItemsResult, r as KeepStore, s as KeepStoreActions, K as KeepListQuery, o as KeepNavigationState, p as KeepRediscoveryOptions } from './store-C7pEDMLm.js';
|
|
2
|
+
export { l as KeepItemRevalidationResult, q as KeepRediscoveryStrategy, u as KeepUrlParamNames, v as KeepUrlState, w as KeepUrlSyncOptions, y as createRediscoveryQuery, G as isKeepItemMetadataStale } from './store-C7pEDMLm.js';
|
|
3
3
|
import { r as KeepItemInput, K as KeepItem, p as KeepEventHandlers, a as StorageAdapter, e as KeepPlugin, t as KeepSchema, q as KeepInvalidItemPolicy, j as KeepChangeContext, D as KeepSyncState, F as KeepUndoState } from './types-CJIbuqTO.js';
|
|
4
4
|
export { s as KeepItemStatus } from './types-CJIbuqTO.js';
|
|
5
5
|
export { K as KeepScope, S as ScopedStorageAdapter } from './scope-BsU6xvN9.js';
|
|
@@ -108,6 +108,11 @@ type KeepContextValue<TMeta = Record<string, unknown>> = {
|
|
|
108
108
|
unarchiveItem: (id: string) => Promise<void>;
|
|
109
109
|
togglePin: (id: string) => Promise<void>;
|
|
110
110
|
moveToCollection: (id: string, collectionId?: string) => Promise<void>;
|
|
111
|
+
archiveBatch: (ids: string[]) => Promise<void>;
|
|
112
|
+
unarchiveBatch: (ids: string[]) => Promise<void>;
|
|
113
|
+
pinBatch: (ids: string[]) => Promise<void>;
|
|
114
|
+
unpinBatch: (ids: string[]) => Promise<void>;
|
|
115
|
+
moveToCollectionBatch: (ids: string[], collectionId?: string) => Promise<void>;
|
|
111
116
|
createCollection: (id: string, name: string) => Promise<void>;
|
|
112
117
|
renameCollection: (id: string, name: string) => Promise<void>;
|
|
113
118
|
removeCollection: (id: string) => Promise<void>;
|
|
@@ -199,6 +204,11 @@ type UseKeepListResult<TMeta = Record<string, unknown>> = {
|
|
|
199
204
|
unarchive: (id: string) => Promise<void>;
|
|
200
205
|
togglePin: (id: string) => Promise<void>;
|
|
201
206
|
moveToCollection: (id: string, collectionId?: string) => Promise<void>;
|
|
207
|
+
archiveBatch: (ids: string[]) => Promise<void>;
|
|
208
|
+
unarchiveBatch: (ids: string[]) => Promise<void>;
|
|
209
|
+
pinBatch: (ids: string[]) => Promise<void>;
|
|
210
|
+
unpinBatch: (ids: string[]) => Promise<void>;
|
|
211
|
+
moveToCollectionBatch: (ids: string[], collectionId?: string) => Promise<void>;
|
|
202
212
|
addTagsBatch: (ids: string[], tags: string[]) => Promise<void>;
|
|
203
213
|
removeTagsBatch: (ids: string[], tags: string[]) => Promise<void>;
|
|
204
214
|
reorder: (orderedIds: string[]) => Promise<void>;
|