@keepkit/core 0.16.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -4
- package/dist/{chunk-THZ3ACR2.js → chunk-5W4QSJHV.js} +2 -2
- package/dist/chunk-5W4QSJHV.js.map +1 -0
- package/dist/{chunk-MDTL5L64.js → chunk-62I2YZYI.js} +72 -9
- package/dist/chunk-62I2YZYI.js.map +1 -0
- package/dist/{chunk-VJDO3GFH.js → chunk-PNP7OALR.js} +55 -55
- package/dist/chunk-PNP7OALR.js.map +1 -0
- package/dist/core.d.ts +20 -20
- package/dist/core.js +84 -76
- package/dist/core.js.map +1 -1
- package/dist/react.d.ts +66 -47
- package/dist/react.js +255 -118
- package/dist/react.js.map +1 -1
- package/dist/schema.d.ts +1 -1
- package/dist/schema.js +1 -1
- package/dist/{scope-y_aBm363.d.ts → scope-Dk5FTVz8.d.ts} +1 -1
- package/dist/storage.d.ts +3 -3
- package/dist/storage.js +1 -1
- package/dist/{url-VhisKZCR.d.ts → store-Cm35R_ho.d.ts} +87 -66
- package/dist/{types-iMK12pmy.d.ts → types-Aoc0Eyvk.d.ts} +6 -2
- package/package.json +1 -1
- package/dist/chunk-MDTL5L64.js.map +0 -1
- package/dist/chunk-THZ3ACR2.js.map +0 -1
- package/dist/chunk-VJDO3GFH.js.map +0 -1
package/README.md
CHANGED
|
@@ -26,17 +26,19 @@ const list = useKeepList({
|
|
|
26
26
|
});
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
`KeepItemInput`は`id`、`meta`、`targetType`、`note`、`tags
|
|
29
|
+
`KeepItemInput`は`id`、`meta`、`targetType`、`note`、`tags`、`order`を持つ入力です。保存時刻・更新時刻・タグ正規化は内部で処理されます。
|
|
30
30
|
|
|
31
31
|
`KeepListQuery`は`targetType`、`tags`、`search`、`sort`、`pagination`、`filter`、`savedBetween`で構成されます。`queryKeepItems`はReactなしで同じ条件を適用できます。
|
|
32
32
|
|
|
33
|
+
保存順を巡回ルートとして管理する場合は、`reorderKeepItems` / `moveKeepItem`、Reactでは`useKeepNavigator`と`useKeepList().reorder()` / `.move()`を利用できます。`getKeepNavigationState`は現在・前・次のアイテムと進行度を返します。
|
|
34
|
+
|
|
33
35
|
`@keepkit/core/core`はフレームワーク中立、`@keepkit/core/react`はReact、`@keepkit/core/storage`はlocalStorage、IndexedDB、fallback、同期adapter、`@keepkit/core/schema`はschema処理を公開します。パッケージルートにはexportがありません。
|
|
34
36
|
|
|
35
37
|
`KeepProvider`には描画エラーを局所化する`fallback`、`onBoundaryError`、`boundaryResetKey`を指定できます。より細かい境界が必要な場合は`KeepErrorBoundary`を`@keepkit/core/react`から利用できます。
|
|
36
38
|
|
|
37
39
|
保存対象の公開状態は`KeepItem.status`(`expired`、`removed`、`private`など)と`statusReason`で保持できます。`KeepProvider`の`validateItem` / `resolveItem`を指定すると、引数なしの`revalidateItems()`で検証できます。`revalidateItems`に`removeStatuses`を渡すと検出したアイテムを保存一覧から削除します。`SyncStorageAdapter`は`userId`、`tenantId`、`maxRetries`、`retryDelayMs`、`retryBackoff`に対応し、`retrySync()`で失敗後の同期を再開できます。
|
|
38
40
|
|
|
39
|
-
v0.
|
|
41
|
+
v0.18.0では、保存順プレイリストと`useKeepNavigator`による連続閲覧、`reorderKeepItems` / `moveKeepItem`による順序管理を追加しました。`encodeKeepListQuery` / `decodeKeepListQuery`によるURL状態codec、`createScopedStorageAdapter`によるユーザー/テナント分離、`createKeepKitPreset({ mode: "local" | "sync" | "backup" })`も利用できます。`createAuthenticatedSyncKit`で認証付き同期とscope切り替えを構成できます。
|
|
40
42
|
|
|
41
43
|
`createAuthenticatedSyncKit`は、リクエストごとの`getAuthToken`、注入可能なpush/pull transport、401/403時の再認証callback、永続オフラインキュー、`setScope`による安全なユーザー/テナント切替を提供します。詳細は[`examples/authenticated-sync`](../../examples/authenticated-sync/README.md)を参照してください。
|
|
42
44
|
|
|
@@ -71,7 +73,9 @@ const list = useKeepList({
|
|
|
71
73
|
});
|
|
72
74
|
```
|
|
73
75
|
|
|
74
|
-
`KeepItemInput`
|
|
76
|
+
`KeepItemInput` contains `id`, `meta`, `targetType`, `note`, `tags`, and the optional persisted `order`. KeepKit owns persistence timestamps and tag normalization. `KeepListQuery` uses the canonical `targetType`, `tags`, `search`, `sort`, `pagination`, `filter`, and `savedBetween` fields.
|
|
77
|
+
|
|
78
|
+
Use `reorderKeepItems` / `moveKeepItem` for framework-neutral route ordering, or `useKeepNavigator` with `useKeepList().reorder()` / `.move()` in React. `getKeepNavigationState` returns the current, previous, next, and progress state.
|
|
75
79
|
|
|
76
80
|
Use `@keepkit/core/core` for framework-neutral code, `@keepkit/core/react` for React bindings, `@keepkit/core/storage` for browser/fallback/sync adapters, and `@keepkit/core/schema` for schema validation. The package root has no export.
|
|
77
81
|
|
|
@@ -79,7 +83,7 @@ Use `@keepkit/core/core` for framework-neutral code, `@keepkit/core/react` for R
|
|
|
79
83
|
|
|
80
84
|
`KeepItem.status` and `statusReason` preserve source availability such as `expired`, `removed`, and `private`. Configure `KeepProvider` with `validateItem` / `resolveItem` to make `revalidateItems()` use those hooks by default. Pass `removeStatuses` to remove detected items from storage. `SyncStorageAdapter` supports scoped queues with `userId` and `tenantId`, configurable retries/backoff, and explicit `retrySync()` recovery.
|
|
81
85
|
|
|
82
|
-
In v0.
|
|
86
|
+
In v0.18.0, use persisted playlist ordering with `useKeepNavigator`, `reorderKeepItems`, and `moveKeepItem` for continuous saved-item tours. `encodeKeepListQuery` / `decodeKeepListQuery` provide URL state, `createScopedStorageAdapter` provides user/tenant isolation, and `createKeepKitPreset({ mode: "local" | "sync" | "backup" })` provides the standard setup. `createAuthenticatedSyncKit` composes token-aware sync and scope switching.
|
|
83
87
|
|
|
84
88
|
`createAuthenticatedSyncKit` provides a per-request `getAuthToken`, injectable push/pull transport, 401/403 reauthentication callbacks, persistent offline queues, and `setScope` for safe user or tenant changes. See [`examples/authenticated-sync`](../../examples/authenticated-sync/README.md) for a recipe.
|
|
85
89
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/schema.ts
|
|
1
|
+
// src/features/persistence/schema.ts
|
|
2
2
|
var KeepSchemaValidationError = class extends Error {
|
|
3
3
|
constructor(message, options = {}) {
|
|
4
4
|
super(message);
|
|
@@ -38,4 +38,4 @@ export {
|
|
|
38
38
|
parseKeepMeta,
|
|
39
39
|
validateKeepItem
|
|
40
40
|
};
|
|
41
|
-
//# sourceMappingURL=chunk-
|
|
41
|
+
//# sourceMappingURL=chunk-5W4QSJHV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/features/persistence/schema.ts"],"sourcesContent":["import type { KeepItem, KeepSchema } from \"../items/types\";\n\nexport class KeepSchemaValidationError extends Error {\n readonly cause?: unknown;\n readonly itemId?: string;\n\n constructor(message: string, options: { cause?: unknown; itemId?: string } = {}) {\n super(message);\n this.name = \"KeepSchemaValidationError\";\n this.cause = options.cause;\n this.itemId = options.itemId;\n }\n}\n\n/** Parse metadata with a Zod-like, safeParse-like, or Standard Schema parser. */\nexport async function parseKeepMeta<T>(schema: KeepSchema<T>, value: unknown): Promise<T> {\n try {\n if (\"parse\" in schema) return await schema.parse(value);\n\n if (\"safeParse\" in schema) {\n const result = await schema.safeParse(value);\n if (result.success) return result.data;\n throw new KeepSchemaValidationError(\"KeepKit metadata did not match the configured schema.\", {\n cause: result.error,\n });\n }\n\n const result = await schema[\"~standard\"].validate(value);\n if (!result.issues && \"value\" in result) return result.value as T;\n throw new KeepSchemaValidationError(\"KeepKit metadata did not match the configured schema.\", {\n cause: result.issues,\n });\n } catch (cause) {\n if (cause instanceof KeepSchemaValidationError) throw cause;\n throw new KeepSchemaValidationError(\"KeepKit metadata did not match the configured schema.\", {\n cause,\n });\n }\n}\n\nexport async function validateKeepItem<TMeta>(\n item: KeepItem<unknown>,\n schema: KeepSchema<TMeta>,\n): Promise<KeepItem<TMeta>> {\n return { ...item, meta: await parseKeepMeta(schema, item.meta) };\n}\n"],"mappings":";AAEO,IAAM,4BAAN,cAAwC,MAAM;AAAA,EAInD,YAAY,SAAiB,UAAgD,CAAC,GAAG;AAC/E,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,QAAQ,QAAQ;AACrB,SAAK,SAAS,QAAQ;AAAA,EACxB;AACF;AAGA,eAAsB,cAAiB,QAAuB,OAA4B;AACxF,MAAI;AACF,QAAI,WAAW,OAAQ,QAAO,MAAM,OAAO,MAAM,KAAK;AAEtD,QAAI,eAAe,QAAQ;AACzB,YAAMA,UAAS,MAAM,OAAO,UAAU,KAAK;AAC3C,UAAIA,QAAO,QAAS,QAAOA,QAAO;AAClC,YAAM,IAAI,0BAA0B,yDAAyD;AAAA,QAC3F,OAAOA,QAAO;AAAA,MAChB,CAAC;AAAA,IACH;AAEA,UAAM,SAAS,MAAM,OAAO,WAAW,EAAE,SAAS,KAAK;AACvD,QAAI,CAAC,OAAO,UAAU,WAAW,OAAQ,QAAO,OAAO;AACvD,UAAM,IAAI,0BAA0B,yDAAyD;AAAA,MAC3F,OAAO,OAAO;AAAA,IAChB,CAAC;AAAA,EACH,SAAS,OAAO;AACd,QAAI,iBAAiB,0BAA2B,OAAM;AACtD,UAAM,IAAI,0BAA0B,yDAAyD;AAAA,MAC3F;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,eAAsB,iBACpB,MACA,QAC0B;AAC1B,SAAO,EAAE,GAAG,MAAM,MAAM,MAAM,cAAc,QAAQ,KAAK,IAAI,EAAE;AACjE;","names":["result"]}
|
|
@@ -1,8 +1,67 @@
|
|
|
1
1
|
import {
|
|
2
2
|
validateKeepItem
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5W4QSJHV.js";
|
|
4
4
|
|
|
5
|
-
// src/
|
|
5
|
+
// src/features/items/navigation.ts
|
|
6
|
+
function orderKeepItems(items) {
|
|
7
|
+
if (!items.some((item) => item.order !== void 0)) return [...items];
|
|
8
|
+
return items.map((item, index) => ({ item, index })).sort((left, right) => {
|
|
9
|
+
const leftOrder = left.item.order;
|
|
10
|
+
const rightOrder = right.item.order;
|
|
11
|
+
if (leftOrder === void 0 && rightOrder !== void 0) return 1;
|
|
12
|
+
if (leftOrder !== void 0 && rightOrder === void 0) return -1;
|
|
13
|
+
if (leftOrder !== void 0 && rightOrder !== void 0 && leftOrder !== rightOrder) {
|
|
14
|
+
return leftOrder - rightOrder;
|
|
15
|
+
}
|
|
16
|
+
return left.index - right.index;
|
|
17
|
+
}).map(({ item }) => item);
|
|
18
|
+
}
|
|
19
|
+
function getKeepNavigationState(source, current) {
|
|
20
|
+
const items = orderKeepItems(source);
|
|
21
|
+
const currentIndex = typeof current === "number" ? Number.isInteger(current) && current >= 0 && current < items.length ? current : -1 : current === void 0 ? -1 : items.findIndex((item) => item.id === current);
|
|
22
|
+
const currentItem = currentIndex >= 0 ? items[currentIndex] ?? null : null;
|
|
23
|
+
return {
|
|
24
|
+
items,
|
|
25
|
+
currentIndex,
|
|
26
|
+
currentPosition: currentIndex >= 0 ? currentIndex + 1 : null,
|
|
27
|
+
currentItem,
|
|
28
|
+
hasNext: currentIndex >= 0 && currentIndex < items.length - 1,
|
|
29
|
+
hasPrev: currentIndex > 0,
|
|
30
|
+
nextItem: currentIndex >= 0 ? items[currentIndex + 1] ?? null : null,
|
|
31
|
+
prevItem: currentIndex > 0 ? items[currentIndex - 1] ?? null : null
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function reorderKeepItems(source, orderedIds) {
|
|
35
|
+
const byId = new Map(source.map((item) => [item.id, item]));
|
|
36
|
+
const seen = /* @__PURE__ */ new Set();
|
|
37
|
+
for (const id of orderedIds) {
|
|
38
|
+
if (!byId.has(id)) throw new Error(`Cannot reorder unknown Keep item "${id}".`);
|
|
39
|
+
if (seen.has(id)) throw new Error(`Cannot reorder Keep items with duplicate id "${id}".`);
|
|
40
|
+
seen.add(id);
|
|
41
|
+
}
|
|
42
|
+
const current = orderKeepItems(source);
|
|
43
|
+
const sequence = [...orderedIds, ...current.map((item) => item.id).filter((id) => !seen.has(id))];
|
|
44
|
+
return sequence.map((id, order) => {
|
|
45
|
+
const item = byId.get(id);
|
|
46
|
+
if (!item) throw new Error(`Cannot reorder unknown Keep item "${id}".`);
|
|
47
|
+
return { ...item, order };
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
function moveKeepItem(source, id, targetIndex) {
|
|
51
|
+
const items = orderKeepItems(source);
|
|
52
|
+
const currentIndex = items.findIndex((item2) => item2.id === id);
|
|
53
|
+
if (currentIndex < 0) throw new Error(`Cannot move unknown Keep item "${id}".`);
|
|
54
|
+
if (!Number.isInteger(targetIndex)) throw new Error("Keep item targetIndex must be an integer.");
|
|
55
|
+
const nextIndex = Math.min(Math.max(0, targetIndex), items.length - 1);
|
|
56
|
+
const [item] = items.splice(currentIndex, 1);
|
|
57
|
+
items.splice(nextIndex, 0, item);
|
|
58
|
+
return reorderKeepItems(
|
|
59
|
+
items,
|
|
60
|
+
items.map((entry) => entry.id)
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// src/features/persistence/migration.ts
|
|
6
65
|
async function mergeKeepItems(localItems, target) {
|
|
7
66
|
if (target.merge) return target.merge(localItems);
|
|
8
67
|
const remoteItems = await target.getAll();
|
|
@@ -24,7 +83,7 @@ async function migrateKeepItems(source, target) {
|
|
|
24
83
|
return merged;
|
|
25
84
|
}
|
|
26
85
|
|
|
27
|
-
// src/backup.ts
|
|
86
|
+
// src/features/persistence/backup.ts
|
|
28
87
|
var KEEP_BACKUP_FORMAT = "keepkit";
|
|
29
88
|
var KEEP_BACKUP_VERSION = 1;
|
|
30
89
|
var KeepBackupParseError = class extends Error {
|
|
@@ -129,7 +188,7 @@ function parseBackup(data) {
|
|
|
129
188
|
}
|
|
130
189
|
function isKeepItem(value) {
|
|
131
190
|
if (!isRecord(value)) return false;
|
|
132
|
-
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.metaUpdatedAt === void 0 || typeof value.metaUpdatedAt === "number" && Number.isFinite(value.metaUpdatedAt)) && (value.status === void 0 || value.status === "available" || value.status === "expired" || value.status === "removed" || value.status === "deleted" || value.status === "private" || value.status === "unknown") && (value.statusReason === void 0 || typeof value.statusReason === "string") && (value.scope === void 0 || isSyncScope(value.scope)) && (value.tags === void 0 || Array.isArray(value.tags) && value.tags.every((tag) => typeof tag === "string"));
|
|
191
|
+
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.order === void 0 || typeof value.order === "number" && Number.isFinite(value.order)) && (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.metaUpdatedAt === void 0 || typeof value.metaUpdatedAt === "number" && Number.isFinite(value.metaUpdatedAt)) && (value.status === void 0 || value.status === "available" || value.status === "expired" || value.status === "removed" || value.status === "deleted" || value.status === "private" || value.status === "unknown") && (value.statusReason === void 0 || typeof value.statusReason === "string") && (value.scope === void 0 || isSyncScope(value.scope)) && (value.tags === void 0 || Array.isArray(value.tags) && value.tags.every((tag) => typeof tag === "string"));
|
|
133
192
|
}
|
|
134
193
|
function isRecord(value) {
|
|
135
194
|
return typeof value === "object" && value !== null;
|
|
@@ -138,7 +197,7 @@ function isSyncScope(value) {
|
|
|
138
197
|
return isRecord(value) && (value.userId === void 0 || typeof value.userId === "string") && (value.tenantId === void 0 || typeof value.tenantId === "string");
|
|
139
198
|
}
|
|
140
199
|
|
|
141
|
-
// src/query.ts
|
|
200
|
+
// src/features/items/query.ts
|
|
142
201
|
function queryKeepItems(source, query = {}) {
|
|
143
202
|
const filtered = source.filter((item) => {
|
|
144
203
|
const [from, to] = query.savedBetween ?? [];
|
|
@@ -150,7 +209,7 @@ function queryKeepItems(source, query = {}) {
|
|
|
150
209
|
const tagCounts = getTagCounts(filtered);
|
|
151
210
|
const sortBy = query.sort?.by;
|
|
152
211
|
const direction = query.sort?.direction === "asc" ? 1 : -1;
|
|
153
|
-
const sorted = sortBy ? [...filtered].sort((a, b) => (a[sortBy] - b[sortBy]) * direction) : filtered;
|
|
212
|
+
const sorted = sortBy ? [...filtered].sort((a, b) => (a[sortBy] - b[sortBy]) * direction) : orderKeepItems(filtered);
|
|
154
213
|
const pageSize = Math.max(1, query.pagination?.pageSize ?? (sorted.length || 1));
|
|
155
214
|
const pageCount = Math.max(1, Math.ceil(sorted.length / pageSize));
|
|
156
215
|
const page = Math.min(Math.max(1, query.pagination?.page ?? 1), pageCount);
|
|
@@ -195,7 +254,7 @@ function toTimestamp(value) {
|
|
|
195
254
|
return value instanceof Date ? value.getTime() : value;
|
|
196
255
|
}
|
|
197
256
|
|
|
198
|
-
// src/revalidation.ts
|
|
257
|
+
// src/features/items/revalidation.ts
|
|
199
258
|
function isKeepItemMetadataStale(item, maxAgeMs, now = Date.now) {
|
|
200
259
|
return item.metaUpdatedAt === void 0 || now() - item.metaUpdatedAt >= maxAgeMs;
|
|
201
260
|
}
|
|
@@ -276,7 +335,7 @@ function clearItemStatus(item) {
|
|
|
276
335
|
return next;
|
|
277
336
|
}
|
|
278
337
|
|
|
279
|
-
// src/store.ts
|
|
338
|
+
// src/features/store/store.ts
|
|
280
339
|
var KeepStore = class {
|
|
281
340
|
constructor(initialState) {
|
|
282
341
|
this.listeners = /* @__PURE__ */ new Set();
|
|
@@ -302,6 +361,10 @@ var KeepStore = class {
|
|
|
302
361
|
};
|
|
303
362
|
|
|
304
363
|
export {
|
|
364
|
+
orderKeepItems,
|
|
365
|
+
getKeepNavigationState,
|
|
366
|
+
reorderKeepItems,
|
|
367
|
+
moveKeepItem,
|
|
305
368
|
mergeKeepItems,
|
|
306
369
|
migrateKeepItems,
|
|
307
370
|
KEEP_BACKUP_FORMAT,
|
|
@@ -317,4 +380,4 @@ export {
|
|
|
317
380
|
reconcileKeepItems,
|
|
318
381
|
KeepStore
|
|
319
382
|
};
|
|
320
|
-
//# sourceMappingURL=chunk-
|
|
383
|
+
//# sourceMappingURL=chunk-62I2YZYI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/features/items/navigation.ts","../src/features/persistence/migration.ts","../src/features/persistence/backup.ts","../src/features/items/query.ts","../src/features/items/revalidation.ts","../src/features/store/store.ts"],"sourcesContent":["import type { KeepItem } from \"./types\";\n\nexport type KeepNavigationState<TMeta = Record<string, unknown>> = {\n items: KeepItem<TMeta>[];\n currentIndex: number;\n currentPosition: number | null;\n currentItem: KeepItem<TMeta> | null;\n hasNext: boolean;\n hasPrev: boolean;\n nextItem: KeepItem<TMeta> | null;\n prevItem: KeepItem<TMeta> | null;\n};\n\n/** Return items in their persisted custom order, leaving legacy items stable. */\nexport function orderKeepItems<TMeta>(items: readonly KeepItem<TMeta>[]): KeepItem<TMeta>[] {\n if (!items.some((item) => item.order !== undefined)) return [...items];\n return items\n .map((item, index) => ({ item, index }))\n .sort((left, right) => {\n const leftOrder = left.item.order;\n const rightOrder = right.item.order;\n if (leftOrder === undefined && rightOrder !== undefined) return 1;\n if (leftOrder !== undefined && rightOrder === undefined) return -1;\n if (leftOrder !== undefined && rightOrder !== undefined && leftOrder !== rightOrder) {\n return leftOrder - rightOrder;\n }\n return left.index - right.index;\n })\n .map(({ item }) => item);\n}\n\n/** Derive the previous/current/next view for a list and an item id or index. */\nexport function getKeepNavigationState<TMeta = Record<string, unknown>>(\n source: readonly KeepItem<TMeta>[],\n current?: string | number,\n): KeepNavigationState<TMeta> {\n const items = orderKeepItems(source);\n const currentIndex =\n typeof current === \"number\"\n ? Number.isInteger(current) && current >= 0 && current < items.length\n ? current\n : -1\n : current === undefined\n ? -1\n : items.findIndex((item) => item.id === current);\n const currentItem = currentIndex >= 0 ? (items[currentIndex] ?? null) : null;\n return {\n items,\n currentIndex,\n currentPosition: currentIndex >= 0 ? currentIndex + 1 : null,\n currentItem,\n hasNext: currentIndex >= 0 && currentIndex < items.length - 1,\n hasPrev: currentIndex > 0,\n nextItem: currentIndex >= 0 ? (items[currentIndex + 1] ?? null) : null,\n prevItem: currentIndex > 0 ? (items[currentIndex - 1] ?? null) : null,\n };\n}\n\n/** Apply a partial or complete id order and assign stable zero-based positions. */\nexport function reorderKeepItems<TMeta = Record<string, unknown>>(\n source: readonly KeepItem<TMeta>[],\n orderedIds: readonly string[],\n): KeepItem<TMeta>[] {\n const byId = new Map(source.map((item) => [item.id, item]));\n const seen = new Set<string>();\n for (const id of orderedIds) {\n if (!byId.has(id)) throw new Error(`Cannot reorder unknown Keep item \"${id}\".`);\n if (seen.has(id)) throw new Error(`Cannot reorder Keep items with duplicate id \"${id}\".`);\n seen.add(id);\n }\n const current = orderKeepItems(source);\n const sequence = [...orderedIds, ...current.map((item) => item.id).filter((id) => !seen.has(id))];\n return sequence.map((id, order) => {\n const item = byId.get(id);\n if (!item) throw new Error(`Cannot reorder unknown Keep item \"${id}\".`);\n return { ...item, order };\n });\n}\n\n/** Move one item within the current custom/legacy order. */\nexport function moveKeepItem<TMeta = Record<string, unknown>>(\n source: readonly KeepItem<TMeta>[],\n id: string,\n targetIndex: number,\n): KeepItem<TMeta>[] {\n const items = orderKeepItems(source);\n const currentIndex = items.findIndex((item) => item.id === id);\n if (currentIndex < 0) throw new Error(`Cannot move unknown Keep item \"${id}\".`);\n if (!Number.isInteger(targetIndex)) throw new Error(\"Keep item targetIndex must be an integer.\");\n const nextIndex = Math.min(Math.max(0, targetIndex), items.length - 1);\n const [item] = items.splice(currentIndex, 1);\n items.splice(nextIndex, 0, item);\n return reorderKeepItems(\n items,\n items.map((entry) => entry.id),\n );\n}\n","import type { KeepItem, StorageAdapter } from \"../items/types\";\n\n/** Merge anonymous local items into a signed-in or remote adapter. */\nexport async function mergeKeepItems<TMeta>(\n localItems: KeepItem<TMeta>[],\n target: StorageAdapter<TMeta>,\n): Promise<KeepItem<TMeta>[]> {\n if (target.merge) return target.merge(localItems);\n\n const remoteItems = await target.getAll();\n const byId = new Map(remoteItems.map((item) => [item.id, item]));\n for (const localItem of localItems) {\n const remoteItem = byId.get(localItem.id);\n if (!remoteItem || localItem.updatedAt > remoteItem.updatedAt) {\n byId.set(localItem.id, localItem);\n }\n }\n\n const merged = [...byId.values()].sort((a, b) => b.updatedAt - a.updatedAt);\n await Promise.all(merged.map((item) => target.set(item)));\n return merged;\n}\n\n/** Read anonymous items, merge them into the target, then clear the source. */\nexport async function migrateKeepItems<TMeta>(\n source: StorageAdapter<TMeta>,\n target: StorageAdapter<TMeta>,\n): Promise<KeepItem<TMeta>[]> {\n const localItems = await source.getAll();\n const merged = await mergeKeepItems(localItems, target);\n await source.clear();\n return merged;\n}\n","import type { KeepInvalidItemPolicy, KeepItem, KeepSchema, StorageAdapter } from \"../items/types\";\nimport { mergeKeepItems } from \"./migration\";\nimport { validateKeepItem } from \"./schema\";\n\nexport const KEEP_BACKUP_FORMAT = \"keepkit\";\nexport const KEEP_BACKUP_VERSION = 1;\n\nexport type KeepBackup<TMeta = Record<string, unknown>> = {\n format: typeof KEEP_BACKUP_FORMAT;\n version: typeof KEEP_BACKUP_VERSION;\n exportedAt: number;\n items: KeepItem<TMeta>[];\n};\n\nexport type ImportItemsOptions<TMeta = unknown> = {\n mode?: \"replace\" | \"merge\";\n schema?: KeepSchema<TMeta>;\n invalidItemPolicy?: KeepInvalidItemPolicy;\n onInvalidItem?: (error: unknown, item: KeepItem<unknown>) => void;\n};\n\nexport type ImportItemsResult<TMeta = Record<string, unknown>> = {\n mode: \"replace\" | \"merge\";\n imported: number;\n failed: number;\n total: number;\n items: KeepItem<TMeta>[];\n};\n\nexport class KeepBackupParseError extends Error {\n readonly cause?: unknown;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message);\n this.name = \"KeepBackupParseError\";\n if (options?.cause !== undefined) this.cause = options.cause;\n }\n}\n\nexport class KeepBackupImportError extends Error {\n readonly mode: \"replace\" | \"merge\";\n readonly imported: number;\n readonly failed: number;\n readonly cause?: unknown;\n\n constructor(\n message: string,\n options: {\n mode: \"replace\" | \"merge\";\n imported: number;\n failed: number;\n cause?: unknown;\n },\n ) {\n super(message);\n this.name = \"KeepBackupImportError\";\n this.mode = options.mode;\n this.imported = options.imported;\n this.failed = options.failed;\n if (options.cause !== undefined) this.cause = options.cause;\n }\n}\n\n/** Serialize all adapter data into a versioned JSON backup. */\nexport async function exportItems<TMeta>(adapter: StorageAdapter<TMeta>): Promise<string> {\n const backup: KeepBackup<TMeta> = {\n format: KEEP_BACKUP_FORMAT,\n version: KEEP_BACKUP_VERSION,\n exportedAt: Date.now(),\n items: await adapter.getAll(),\n };\n return JSON.stringify(backup, null, 2);\n}\n\n/** Validate and restore a backup, either replacing or merging existing data. */\nexport async function importItems<TMeta>(\n adapter: StorageAdapter<TMeta>,\n data: string | KeepBackup<TMeta>,\n options: ImportItemsOptions<TMeta> = {},\n): Promise<ImportItemsResult<TMeta>> {\n const backup = parseBackup<TMeta>(data);\n const mode = options.mode ?? \"merge\";\n const validItems: KeepItem<TMeta>[] = [];\n let failed = 0;\n for (const item of backup.items) {\n if (!options.schema) {\n validItems.push(item);\n continue;\n }\n try {\n validItems.push(await validateKeepItem(item, options.schema));\n } catch (cause) {\n options.onInvalidItem?.(cause, item);\n if ((options.invalidItemPolicy ?? \"error\") === \"drop\") {\n failed += 1;\n continue;\n }\n throw cause;\n }\n }\n let items: KeepItem<TMeta>[];\n\n if (mode === \"merge\") {\n try {\n items = await mergeKeepItems(validItems, adapter);\n } catch (cause) {\n throw new KeepBackupImportError(\"KeepKit could not merge the backup.\", {\n mode,\n imported: 0,\n failed: validItems.length + failed,\n cause,\n });\n }\n } else {\n let imported = 0;\n try {\n await adapter.clear();\n for (const item of validItems) {\n await adapter.set(item);\n imported += 1;\n }\n items = await adapter.getAll();\n } catch (cause) {\n throw new KeepBackupImportError(\"KeepKit could not replace the stored items.\", {\n mode,\n imported,\n failed: validItems.length + failed - imported,\n cause,\n });\n }\n }\n\n return { mode, imported: validItems.length, failed, total: items.length, items };\n}\n\nfunction parseBackup<TMeta>(data: string | KeepBackup<TMeta>): KeepBackup<TMeta> {\n let value: unknown = data;\n if (typeof data === \"string\") {\n try {\n value = JSON.parse(data);\n } catch (cause) {\n throw new KeepBackupParseError(\"KeepKit backup is not valid JSON.\", { cause });\n }\n }\n\n if (!isRecord(value)) throw new KeepBackupParseError(\"KeepKit backup must be an object.\");\n if (value.format !== KEEP_BACKUP_FORMAT || value.version !== KEEP_BACKUP_VERSION) {\n throw new KeepBackupParseError(\"KeepKit backup format or version is unsupported.\");\n }\n if (typeof value.exportedAt !== \"number\" || !Number.isFinite(value.exportedAt)) {\n throw new KeepBackupParseError(\"KeepKit backup has an invalid export timestamp.\");\n }\n if (!Array.isArray(value.items) || !value.items.every(isKeepItem)) {\n throw new KeepBackupParseError(\"KeepKit backup contains invalid items.\");\n }\n return value as KeepBackup<TMeta>;\n}\n\nfunction isKeepItem(value: unknown): value is KeepItem {\n if (!isRecord(value)) return false;\n return (\n typeof value.id === \"string\" &&\n typeof value.savedAt === \"number\" &&\n Number.isFinite(value.savedAt) &&\n typeof value.updatedAt === \"number\" &&\n Number.isFinite(value.updatedAt) &&\n \"meta\" in value &&\n (value.order === undefined || (typeof value.order === \"number\" && Number.isFinite(value.order))) &&\n (value.targetType === undefined || typeof value.targetType === \"string\") &&\n (value.note === undefined || typeof value.note === \"string\") &&\n (value.schemaVersion === undefined ||\n (typeof value.schemaVersion === \"number\" && Number.isFinite(value.schemaVersion))) &&\n (value.revision === undefined || typeof value.revision === \"string\") &&\n (value.metaUpdatedAt === undefined ||\n (typeof value.metaUpdatedAt === \"number\" && Number.isFinite(value.metaUpdatedAt))) &&\n (value.status === undefined ||\n value.status === \"available\" ||\n value.status === \"expired\" ||\n value.status === \"removed\" ||\n value.status === \"deleted\" ||\n value.status === \"private\" ||\n value.status === \"unknown\") &&\n (value.statusReason === undefined || typeof value.statusReason === \"string\") &&\n (value.scope === undefined || isSyncScope(value.scope)) &&\n (value.tags === undefined || (Array.isArray(value.tags) && value.tags.every((tag) => typeof tag === \"string\")))\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isSyncScope(value: unknown): boolean {\n return (\n isRecord(value) &&\n (value.userId === undefined || typeof value.userId === \"string\") &&\n (value.tenantId === undefined || typeof value.tenantId === \"string\")\n );\n}\n","import { orderKeepItems } from \"./navigation\";\nimport type { KeepItem } from \"./types\";\n\nexport type KeepListQuery<TMeta = Record<string, unknown>> = {\n targetType?: string;\n tags?: string[];\n sort?: {\n by: \"savedAt\" | \"updatedAt\";\n direction?: \"asc\" | \"desc\";\n };\n search?: {\n query?: string;\n mode?: \"and\" | \"or\";\n tokenize?: boolean;\n fields?: Array<\"note\" | \"meta\" | \"tags\">;\n };\n pagination?: {\n page?: number;\n pageSize?: number;\n };\n filter?: (item: KeepItem<TMeta>) => boolean;\n savedBetween?: readonly [Date | number, Date | number];\n};\n\nexport type QueryKeepItemsResult<TMeta = Record<string, unknown>> = {\n items: KeepItem<TMeta>[];\n totalCount: number;\n tagCounts: Record<string, number>;\n page: number;\n pageCount: number;\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n};\n\n/** Apply the collection query and one-based pagination without React. */\nexport function queryKeepItems<TMeta = Record<string, unknown>>(\n source: KeepItem<TMeta>[],\n query: KeepListQuery<TMeta> = {},\n): QueryKeepItemsResult<TMeta> {\n const filtered = source.filter((item) => {\n const [from, to] = query.savedBetween ?? [];\n const savedAt = item.savedAt;\n const lowerBound = from === undefined ? undefined : toTimestamp(from);\n const upperBound = to === undefined ? undefined : toTimestamp(to);\n return (\n (query.targetType === undefined || item.targetType === query.targetType) &&\n (query.tags === undefined || query.tags.every((tag) => item.tags?.includes(tag))) &&\n (lowerBound === undefined || savedAt >= lowerBound) &&\n (upperBound === undefined || savedAt <= upperBound) &&\n matchesSearch(item, query.search) &&\n (query.filter?.(item) ?? true)\n );\n });\n const tagCounts = getTagCounts(filtered);\n const sortBy = query.sort?.by;\n const direction = query.sort?.direction === \"asc\" ? 1 : -1;\n const sorted = sortBy ? [...filtered].sort((a, b) => (a[sortBy] - b[sortBy]) * direction) : orderKeepItems(filtered);\n const pageSize = Math.max(1, query.pagination?.pageSize ?? (sorted.length || 1));\n const pageCount = Math.max(1, Math.ceil(sorted.length / pageSize));\n const page = Math.min(Math.max(1, query.pagination?.page ?? 1), pageCount);\n const offset = (page - 1) * pageSize;\n\n return {\n items: sorted.slice(offset, offset + pageSize),\n totalCount: sorted.length,\n tagCounts,\n page,\n pageCount,\n hasNextPage: page < pageCount,\n hasPreviousPage: page > 1,\n };\n}\n\nexport function getTagCounts<TMeta = Record<string, unknown>>(items: KeepItem<TMeta>[]): Record<string, number> {\n const counts: Record<string, number> = {};\n for (const item of items) {\n for (const tag of item.tags ?? []) counts[tag] = (counts[tag] ?? 0) + 1;\n }\n return Object.fromEntries(Object.entries(counts).sort(([a], [b]) => a.localeCompare(b)));\n}\n\nfunction matchesSearch<TMeta>(item: KeepItem<TMeta>, search?: KeepListQuery<TMeta>[\"search\"]): boolean {\n const query = search?.query;\n if (!query?.trim()) return true;\n const fields = search?.fields ?? [\"note\", \"meta\", \"tags\"];\n const values = fields.map((field) => {\n if (field === \"note\") return item.note ?? \"\";\n if (field === \"tags\") return (item.tags ?? []).join(\" \");\n try {\n return JSON.stringify(item.meta) ?? \"\";\n } catch {\n return String(item.meta);\n }\n });\n const text = values.join(\" \").toLocaleLowerCase();\n const normalized = query.trim().toLocaleLowerCase();\n const needles = search?.tokenize === false ? [normalized] : normalized.split(/\\s+/).filter(Boolean);\n const matches = needles.map((needle) => text.includes(needle));\n return search?.mode === \"or\" ? matches.some(Boolean) : matches.every(Boolean);\n}\n\nfunction toTimestamp(value: Date | number): number {\n return value instanceof Date ? value.getTime() : value;\n}\n","import type { KeepItem, KeepItemStatus, StorageAdapter } from \"./types\";\n\nexport type { KeepItemStatus } from \"./types\";\n\nexport type KeepItemRevalidationResult<TMeta = Record<string, unknown>> =\n | { status: \"available\"; meta?: TMeta }\n | { status: Exclude<KeepItemStatus, \"available\">; reason?: string };\n\nexport type KeepItemRevalidator<TMeta = Record<string, unknown>> = (\n item: KeepItem<TMeta>,\n) =>\n | KeepItemRevalidationResult<TMeta>\n | KeepItemRevalidationResult<TMeta>[\"status\"]\n | Promise<KeepItemRevalidationResult<TMeta> | KeepItemRevalidationResult<TMeta>[\"status\"]>;\n\nexport type KeepItemResolver<TMeta = Record<string, unknown>> = (\n item: KeepItem<TMeta>,\n result: KeepItemRevalidationResult<TMeta>,\n) => KeepItem<TMeta> | undefined | Promise<KeepItem<TMeta> | undefined>;\n\nexport type KeepItemMetadataRefresher<TMeta = Record<string, unknown>> = (\n item: KeepItem<TMeta>,\n) => TMeta | Promise<TMeta>;\n\n/** Return whether source metadata should be fetched again based on its age. */\nexport function isKeepItemMetadataStale<TMeta>(\n item: KeepItem<TMeta>,\n maxAgeMs: number,\n now: () => number = Date.now,\n): boolean {\n return item.metaUpdatedAt === undefined || now() - item.metaUpdatedAt >= maxAgeMs;\n}\n\nexport type KeepItemRevalidationRecord<TMeta = Record<string, unknown>> = {\n item: KeepItem<TMeta>;\n status: KeepItemStatus;\n reason?: string;\n updated: boolean;\n};\n\nexport type RevalidateKeepItemsOptions<TMeta = Record<string, unknown>> = {\n /** Statuses that should be removed after they are detected. Detection is the default. */\n removeStatuses?: Array<Exclude<KeepItemStatus, \"available\">>;\n now?: () => number;\n resolveItem?: KeepItemResolver<TMeta>;\n};\n\nexport type KeepAutoRevalidationOptions<TMeta = Record<string, unknown>> = {\n /** Revalidate after the provider hydrates. Defaults to true when validateItem is supplied. */\n onMount?: boolean;\n /** Revalidate when the browser returns online. Defaults to true. */\n onReconnect?: boolean;\n /** Revalidate repeatedly while mounted. Disabled by default. */\n intervalMs?: number;\n removeStatuses?: Array<Exclude<KeepItemStatus, \"available\">>;\n revalidator?: KeepItemRevalidator<TMeta>;\n};\n\nexport type KeepItemRevalidationSummary<TMeta = Record<string, unknown>> = {\n items: KeepItem<TMeta>[];\n checked: number;\n updated: number;\n removed: number;\n updatedItems: KeepItem<TMeta>[];\n removedIds: string[];\n results: KeepItemRevalidationRecord<TMeta>[];\n};\n\n/** Revalidate saved items without coupling the checker to a network client. */\nexport async function revalidateKeepItems<TMeta = Record<string, unknown>>(\n source: KeepItem<TMeta>[],\n revalidator: KeepItemRevalidator<TMeta>,\n options: RevalidateKeepItemsOptions<TMeta> = {},\n): Promise<KeepItemRevalidationSummary<TMeta>> {\n const removeStatuses = new Set(options.removeStatuses ?? []);\n const now = options.now ?? Date.now;\n const items: KeepItem<TMeta>[] = [];\n const updatedItems: KeepItem<TMeta>[] = [];\n const removedIds: string[] = [];\n const results: KeepItemRevalidationRecord<TMeta>[] = [];\n\n for (const item of source) {\n const rawResult = await revalidator(item);\n const result: KeepItemRevalidationResult<TMeta> = typeof rawResult === \"string\" ? { status: rawResult } : rawResult;\n const reason = result.status === \"available\" ? undefined : result.reason;\n const defaultResolved = {\n ...item,\n status: result.status,\n ...(result.status === \"available\" ? { statusReason: undefined } : { statusReason: reason }),\n };\n const resolved = options.resolveItem\n ? await (options.resolveItem as KeepItemResolver<TMeta>)(item, result)\n : defaultResolved;\n if (resolved === undefined) {\n removedIds.push(item.id);\n results.push({ item, status: result.status, reason, updated: false });\n continue;\n }\n if (result.status === \"available\") {\n const timestamp = now();\n const availableItem = clearItemStatus(resolved);\n const updated =\n result.meta === undefined\n ? availableItem\n : { ...availableItem, meta: result.meta, metaUpdatedAt: timestamp, updatedAt: timestamp };\n const didUpdate = updated !== item;\n items.push(updated);\n if (didUpdate) updatedItems.push(updated);\n results.push({ item: updated, status: \"available\", updated: didUpdate });\n continue;\n }\n\n const withStatus = { ...resolved, status: result.status, ...(reason ? { statusReason: reason } : {}) };\n const shouldRemove = removeStatuses.has(result.status);\n if (shouldRemove) removedIds.push(item.id);\n else items.push(withStatus);\n if (!shouldRemove && withStatus !== item) updatedItems.push(withStatus);\n results.push({ item: withStatus, status: result.status, reason, updated: !shouldRemove && withStatus !== item });\n }\n\n return {\n items,\n checked: source.length,\n updated: updatedItems.length,\n removed: removedIds.length,\n updatedItems,\n removedIds,\n results,\n };\n}\n\n/** Revalidate and persist saved items for framework-neutral applications. */\nexport async function reconcileKeepItems<TMeta = Record<string, unknown>>(\n storage: StorageAdapter<TMeta>,\n revalidator: KeepItemRevalidator<TMeta>,\n options: RevalidateKeepItemsOptions<TMeta> = {},\n): Promise<KeepItemRevalidationSummary<TMeta>> {\n const source = await storage.getAll();\n const summary = await revalidateKeepItems(source, revalidator, options);\n if (summary.updatedItems.length > 0) await persistItems(storage, summary.updatedItems);\n if (summary.removedIds.length > 0) await removeItems(storage, summary.removedIds);\n return summary;\n}\n\nasync function persistItems<TMeta>(storage: StorageAdapter<TMeta>, items: KeepItem<TMeta>[]): Promise<void> {\n if (storage.setMany) {\n await storage.setMany(items);\n return;\n }\n for (const item of items) await storage.set(item);\n}\n\nasync function removeItems<TMeta>(storage: StorageAdapter<TMeta>, ids: string[]): Promise<void> {\n if (storage.removeMany) {\n await storage.removeMany(ids);\n return;\n }\n for (const id of ids) await storage.remove(id);\n}\n\nfunction clearItemStatus<TMeta>(item: KeepItem<TMeta>): KeepItem<TMeta> {\n const next = { ...item };\n delete next.status;\n delete next.statusReason;\n return next;\n}\n","import type {\n KeepItemMetadataRefresher,\n KeepItemRevalidationSummary,\n KeepItemRevalidator,\n RevalidateKeepItemsOptions,\n} from \"../items/revalidation\";\nimport type { KeepChangeContext, KeepItem, KeepUndoState } from \"../items/types\";\n\nexport type KeepStoreState<TMeta = Record<string, unknown>> = {\n items: KeepItem<TMeta>[];\n isLoading: boolean;\n isHydrated: boolean;\n isMutating: boolean;\n error: unknown | null;\n lastChange?: KeepChangeContext<TMeta>;\n undo?: KeepUndoState;\n};\n\nexport type KeepStoreActions<TMeta = Record<string, unknown>> = {\n saveItem: (item: KeepItem<TMeta>) => Promise<void>;\n updateNote: (id: string, note?: string) => Promise<void>;\n updateTags: (id: string, tags?: string[]) => Promise<void>;\n updateTagsBatch: (ids: string[], tags?: string[]) => Promise<void>;\n addTagsBatch: (ids: string[], tags: string[]) => Promise<void>;\n removeTagsBatch: (ids: string[], tags: string[]) => Promise<void>;\n removeItem: (id: string) => Promise<void>;\n removeItems: (ids: string[]) => Promise<void>;\n removeItemWithUndo: (id: string) => Promise<void>;\n removeItemsWithUndo: (ids: string[]) => Promise<void>;\n undoLastRemoval: () => Promise<void>;\n clear: () => Promise<void>;\n refresh: () => Promise<void>;\n refreshItemMetadata: (id: string, refresh: KeepItemMetadataRefresher<TMeta>) => Promise<void>;\n revalidateItems: (\n revalidator: KeepItemRevalidator<TMeta>,\n options?: RevalidateKeepItemsOptions<TMeta>,\n ) => Promise<KeepItemRevalidationSummary<TMeta>>;\n reorderItems: (orderedIds: string[]) => Promise<void>;\n moveItem: (id: string, targetIndex: number) => Promise<void>;\n};\n\nexport class KeepStore<TMeta = Record<string, unknown>> {\n private state: KeepStoreState<TMeta>;\n private readonly listeners = new Set<() => void>();\n\n constructor(initialState: KeepStoreState<TMeta>) {\n this.state = initialState;\n }\n\n getSnapshot = (): KeepStoreState<TMeta> => this.state;\n\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n };\n\n setState(next: Partial<KeepStoreState<TMeta>>): void {\n let changed = false;\n for (const key of Object.keys(next) as Array<keyof KeepStoreState<TMeta>>) {\n if (!Object.is(this.state[key], next[key])) {\n changed = true;\n break;\n }\n }\n if (!changed) return;\n this.state = { ...this.state, ...next };\n for (const listener of this.listeners) listener();\n }\n}\n"],"mappings":";;;;;AAcO,SAAS,eAAsB,OAAsD;AAC1F,MAAI,CAAC,MAAM,KAAK,CAAC,SAAS,KAAK,UAAU,MAAS,EAAG,QAAO,CAAC,GAAG,KAAK;AACrE,SAAO,MACJ,IAAI,CAAC,MAAM,WAAW,EAAE,MAAM,MAAM,EAAE,EACtC,KAAK,CAAC,MAAM,UAAU;AACrB,UAAM,YAAY,KAAK,KAAK;AAC5B,UAAM,aAAa,MAAM,KAAK;AAC9B,QAAI,cAAc,UAAa,eAAe,OAAW,QAAO;AAChE,QAAI,cAAc,UAAa,eAAe,OAAW,QAAO;AAChE,QAAI,cAAc,UAAa,eAAe,UAAa,cAAc,YAAY;AACnF,aAAO,YAAY;AAAA,IACrB;AACA,WAAO,KAAK,QAAQ,MAAM;AAAA,EAC5B,CAAC,EACA,IAAI,CAAC,EAAE,KAAK,MAAM,IAAI;AAC3B;AAGO,SAAS,uBACd,QACA,SAC4B;AAC5B,QAAM,QAAQ,eAAe,MAAM;AACnC,QAAM,eACJ,OAAO,YAAY,WACf,OAAO,UAAU,OAAO,KAAK,WAAW,KAAK,UAAU,MAAM,SAC3D,UACA,KACF,YAAY,SACV,KACA,MAAM,UAAU,CAAC,SAAS,KAAK,OAAO,OAAO;AACrD,QAAM,cAAc,gBAAgB,IAAK,MAAM,YAAY,KAAK,OAAQ;AACxE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,iBAAiB,gBAAgB,IAAI,eAAe,IAAI;AAAA,IACxD;AAAA,IACA,SAAS,gBAAgB,KAAK,eAAe,MAAM,SAAS;AAAA,IAC5D,SAAS,eAAe;AAAA,IACxB,UAAU,gBAAgB,IAAK,MAAM,eAAe,CAAC,KAAK,OAAQ;AAAA,IAClE,UAAU,eAAe,IAAK,MAAM,eAAe,CAAC,KAAK,OAAQ;AAAA,EACnE;AACF;AAGO,SAAS,iBACd,QACA,YACmB;AACnB,QAAM,OAAO,IAAI,IAAI,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;AAC1D,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,MAAM,YAAY;AAC3B,QAAI,CAAC,KAAK,IAAI,EAAE,EAAG,OAAM,IAAI,MAAM,qCAAqC,EAAE,IAAI;AAC9E,QAAI,KAAK,IAAI,EAAE,EAAG,OAAM,IAAI,MAAM,gDAAgD,EAAE,IAAI;AACxF,SAAK,IAAI,EAAE;AAAA,EACb;AACA,QAAM,UAAU,eAAe,MAAM;AACrC,QAAM,WAAW,CAAC,GAAG,YAAY,GAAG,QAAQ,IAAI,CAAC,SAAS,KAAK,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;AAChG,SAAO,SAAS,IAAI,CAAC,IAAI,UAAU;AACjC,UAAM,OAAO,KAAK,IAAI,EAAE;AACxB,QAAI,CAAC,KAAM,OAAM,IAAI,MAAM,qCAAqC,EAAE,IAAI;AACtE,WAAO,EAAE,GAAG,MAAM,MAAM;AAAA,EAC1B,CAAC;AACH;AAGO,SAAS,aACd,QACA,IACA,aACmB;AACnB,QAAM,QAAQ,eAAe,MAAM;AACnC,QAAM,eAAe,MAAM,UAAU,CAACA,UAASA,MAAK,OAAO,EAAE;AAC7D,MAAI,eAAe,EAAG,OAAM,IAAI,MAAM,kCAAkC,EAAE,IAAI;AAC9E,MAAI,CAAC,OAAO,UAAU,WAAW,EAAG,OAAM,IAAI,MAAM,2CAA2C;AAC/F,QAAM,YAAY,KAAK,IAAI,KAAK,IAAI,GAAG,WAAW,GAAG,MAAM,SAAS,CAAC;AACrE,QAAM,CAAC,IAAI,IAAI,MAAM,OAAO,cAAc,CAAC;AAC3C,QAAM,OAAO,WAAW,GAAG,IAAI;AAC/B,SAAO;AAAA,IACL;AAAA,IACA,MAAM,IAAI,CAAC,UAAU,MAAM,EAAE;AAAA,EAC/B;AACF;;;AC7FA,eAAsB,eACpB,YACA,QAC4B;AAC5B,MAAI,OAAO,MAAO,QAAO,OAAO,MAAM,UAAU;AAEhD,QAAM,cAAc,MAAM,OAAO,OAAO;AACxC,QAAM,OAAO,IAAI,IAAI,YAAY,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;AAC/D,aAAW,aAAa,YAAY;AAClC,UAAM,aAAa,KAAK,IAAI,UAAU,EAAE;AACxC,QAAI,CAAC,cAAc,UAAU,YAAY,WAAW,WAAW;AAC7D,WAAK,IAAI,UAAU,IAAI,SAAS;AAAA,IAClC;AAAA,EACF;AAEA,QAAM,SAAS,CAAC,GAAG,KAAK,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,YAAY,EAAE,SAAS;AAC1E,QAAM,QAAQ,IAAI,OAAO,IAAI,CAAC,SAAS,OAAO,IAAI,IAAI,CAAC,CAAC;AACxD,SAAO;AACT;AAGA,eAAsB,iBACpB,QACA,QAC4B;AAC5B,QAAM,aAAa,MAAM,OAAO,OAAO;AACvC,QAAM,SAAS,MAAM,eAAe,YAAY,MAAM;AACtD,QAAM,OAAO,MAAM;AACnB,SAAO;AACT;;;AC5BO,IAAM,qBAAqB;AAC3B,IAAM,sBAAsB;AAwB5B,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAG9C,YAAY,SAAiB,SAA+B;AAC1D,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,QAAI,SAAS,UAAU,OAAW,MAAK,QAAQ,QAAQ;AAAA,EACzD;AACF;AAEO,IAAM,wBAAN,cAAoC,MAAM;AAAA,EAM/C,YACE,SACA,SAMA;AACA,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO,QAAQ;AACpB,SAAK,WAAW,QAAQ;AACxB,SAAK,SAAS,QAAQ;AACtB,QAAI,QAAQ,UAAU,OAAW,MAAK,QAAQ,QAAQ;AAAA,EACxD;AACF;AAGA,eAAsB,YAAmB,SAAiD;AACxF,QAAM,SAA4B;AAAA,IAChC,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,YAAY,KAAK,IAAI;AAAA,IACrB,OAAO,MAAM,QAAQ,OAAO;AAAA,EAC9B;AACA,SAAO,KAAK,UAAU,QAAQ,MAAM,CAAC;AACvC;AAGA,eAAsB,YACpB,SACA,MACA,UAAqC,CAAC,GACH;AACnC,QAAM,SAAS,YAAmB,IAAI;AACtC,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,aAAgC,CAAC;AACvC,MAAI,SAAS;AACb,aAAW,QAAQ,OAAO,OAAO;AAC/B,QAAI,CAAC,QAAQ,QAAQ;AACnB,iBAAW,KAAK,IAAI;AACpB;AAAA,IACF;AACA,QAAI;AACF,iBAAW,KAAK,MAAM,iBAAiB,MAAM,QAAQ,MAAM,CAAC;AAAA,IAC9D,SAAS,OAAO;AACd,cAAQ,gBAAgB,OAAO,IAAI;AACnC,WAAK,QAAQ,qBAAqB,aAAa,QAAQ;AACrD,kBAAU;AACV;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AACA,MAAI;AAEJ,MAAI,SAAS,SAAS;AACpB,QAAI;AACF,cAAQ,MAAM,eAAe,YAAY,OAAO;AAAA,IAClD,SAAS,OAAO;AACd,YAAM,IAAI,sBAAsB,uCAAuC;AAAA,QACrE;AAAA,QACA,UAAU;AAAA,QACV,QAAQ,WAAW,SAAS;AAAA,QAC5B;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,OAAO;AACL,QAAI,WAAW;AACf,QAAI;AACF,YAAM,QAAQ,MAAM;AACpB,iBAAW,QAAQ,YAAY;AAC7B,cAAM,QAAQ,IAAI,IAAI;AACtB,oBAAY;AAAA,MACd;AACA,cAAQ,MAAM,QAAQ,OAAO;AAAA,IAC/B,SAAS,OAAO;AACd,YAAM,IAAI,sBAAsB,+CAA+C;AAAA,QAC7E;AAAA,QACA;AAAA,QACA,QAAQ,WAAW,SAAS,SAAS;AAAA,QACrC;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,UAAU,WAAW,QAAQ,QAAQ,OAAO,MAAM,QAAQ,MAAM;AACjF;AAEA,SAAS,YAAmB,MAAqD;AAC/E,MAAI,QAAiB;AACrB,MAAI,OAAO,SAAS,UAAU;AAC5B,QAAI;AACF,cAAQ,KAAK,MAAM,IAAI;AAAA,IACzB,SAAS,OAAO;AACd,YAAM,IAAI,qBAAqB,qCAAqC,EAAE,MAAM,CAAC;AAAA,IAC/E;AAAA,EACF;AAEA,MAAI,CAAC,SAAS,KAAK,EAAG,OAAM,IAAI,qBAAqB,mCAAmC;AACxF,MAAI,MAAM,WAAW,sBAAsB,MAAM,YAAY,qBAAqB;AAChF,UAAM,IAAI,qBAAqB,kDAAkD;AAAA,EACnF;AACA,MAAI,OAAO,MAAM,eAAe,YAAY,CAAC,OAAO,SAAS,MAAM,UAAU,GAAG;AAC9E,UAAM,IAAI,qBAAqB,iDAAiD;AAAA,EAClF;AACA,MAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,KAAK,CAAC,MAAM,MAAM,MAAM,UAAU,GAAG;AACjE,UAAM,IAAI,qBAAqB,wCAAwC;AAAA,EACzE;AACA,SAAO;AACT;AAEA,SAAS,WAAW,OAAmC;AACrD,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,SACE,OAAO,MAAM,OAAO,YACpB,OAAO,MAAM,YAAY,YACzB,OAAO,SAAS,MAAM,OAAO,KAC7B,OAAO,MAAM,cAAc,YAC3B,OAAO,SAAS,MAAM,SAAS,KAC/B,UAAU,UACT,MAAM,UAAU,UAAc,OAAO,MAAM,UAAU,YAAY,OAAO,SAAS,MAAM,KAAK,OAC5F,MAAM,eAAe,UAAa,OAAO,MAAM,eAAe,cAC9D,MAAM,SAAS,UAAa,OAAO,MAAM,SAAS,cAClD,MAAM,kBAAkB,UACtB,OAAO,MAAM,kBAAkB,YAAY,OAAO,SAAS,MAAM,aAAa,OAChF,MAAM,aAAa,UAAa,OAAO,MAAM,aAAa,cAC1D,MAAM,kBAAkB,UACtB,OAAO,MAAM,kBAAkB,YAAY,OAAO,SAAS,MAAM,aAAa,OAChF,MAAM,WAAW,UAChB,MAAM,WAAW,eACjB,MAAM,WAAW,aACjB,MAAM,WAAW,aACjB,MAAM,WAAW,aACjB,MAAM,WAAW,aACjB,MAAM,WAAW,eAClB,MAAM,iBAAiB,UAAa,OAAO,MAAM,iBAAiB,cAClE,MAAM,UAAU,UAAa,YAAY,MAAM,KAAK,OACpD,MAAM,SAAS,UAAc,MAAM,QAAQ,MAAM,IAAI,KAAK,MAAM,KAAK,MAAM,CAAC,QAAQ,OAAO,QAAQ,QAAQ;AAEhH;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,YAAY,OAAyB;AAC5C,SACE,SAAS,KAAK,MACb,MAAM,WAAW,UAAa,OAAO,MAAM,WAAW,cACtD,MAAM,aAAa,UAAa,OAAO,MAAM,aAAa;AAE/D;;;ACnKO,SAAS,eACd,QACA,QAA8B,CAAC,GACF;AAC7B,QAAM,WAAW,OAAO,OAAO,CAAC,SAAS;AACvC,UAAM,CAAC,MAAM,EAAE,IAAI,MAAM,gBAAgB,CAAC;AAC1C,UAAM,UAAU,KAAK;AACrB,UAAM,aAAa,SAAS,SAAY,SAAY,YAAY,IAAI;AACpE,UAAM,aAAa,OAAO,SAAY,SAAY,YAAY,EAAE;AAChE,YACG,MAAM,eAAe,UAAa,KAAK,eAAe,MAAM,gBAC5D,MAAM,SAAS,UAAa,MAAM,KAAK,MAAM,CAAC,QAAQ,KAAK,MAAM,SAAS,GAAG,CAAC,OAC9E,eAAe,UAAa,WAAW,gBACvC,eAAe,UAAa,WAAW,eACxC,cAAc,MAAM,MAAM,MAAM,MAC/B,MAAM,SAAS,IAAI,KAAK;AAAA,EAE7B,CAAC;AACD,QAAM,YAAY,aAAa,QAAQ;AACvC,QAAM,SAAS,MAAM,MAAM;AAC3B,QAAM,YAAY,MAAM,MAAM,cAAc,QAAQ,IAAI;AACxD,QAAM,SAAS,SAAS,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,OAAO,EAAE,MAAM,IAAI,EAAE,MAAM,KAAK,SAAS,IAAI,eAAe,QAAQ;AACnH,QAAM,WAAW,KAAK,IAAI,GAAG,MAAM,YAAY,aAAa,OAAO,UAAU,EAAE;AAC/E,QAAM,YAAY,KAAK,IAAI,GAAG,KAAK,KAAK,OAAO,SAAS,QAAQ,CAAC;AACjE,QAAM,OAAO,KAAK,IAAI,KAAK,IAAI,GAAG,MAAM,YAAY,QAAQ,CAAC,GAAG,SAAS;AACzE,QAAM,UAAU,OAAO,KAAK;AAE5B,SAAO;AAAA,IACL,OAAO,OAAO,MAAM,QAAQ,SAAS,QAAQ;AAAA,IAC7C,YAAY,OAAO;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,OAAO;AAAA,IACpB,iBAAiB,OAAO;AAAA,EAC1B;AACF;AAEO,SAAS,aAA8C,OAAkD;AAC9G,QAAM,SAAiC,CAAC;AACxC,aAAW,QAAQ,OAAO;AACxB,eAAW,OAAO,KAAK,QAAQ,CAAC,EAAG,QAAO,GAAG,KAAK,OAAO,GAAG,KAAK,KAAK;AAAA,EACxE;AACA,SAAO,OAAO,YAAY,OAAO,QAAQ,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;AACzF;AAEA,SAAS,cAAqB,MAAuB,QAAkD;AACrG,QAAM,QAAQ,QAAQ;AACtB,MAAI,CAAC,OAAO,KAAK,EAAG,QAAO;AAC3B,QAAM,SAAS,QAAQ,UAAU,CAAC,QAAQ,QAAQ,MAAM;AACxD,QAAM,SAAS,OAAO,IAAI,CAAC,UAAU;AACnC,QAAI,UAAU,OAAQ,QAAO,KAAK,QAAQ;AAC1C,QAAI,UAAU,OAAQ,SAAQ,KAAK,QAAQ,CAAC,GAAG,KAAK,GAAG;AACvD,QAAI;AACF,aAAO,KAAK,UAAU,KAAK,IAAI,KAAK;AAAA,IACtC,QAAQ;AACN,aAAO,OAAO,KAAK,IAAI;AAAA,IACzB;AAAA,EACF,CAAC;AACD,QAAM,OAAO,OAAO,KAAK,GAAG,EAAE,kBAAkB;AAChD,QAAM,aAAa,MAAM,KAAK,EAAE,kBAAkB;AAClD,QAAM,UAAU,QAAQ,aAAa,QAAQ,CAAC,UAAU,IAAI,WAAW,MAAM,KAAK,EAAE,OAAO,OAAO;AAClG,QAAM,UAAU,QAAQ,IAAI,CAAC,WAAW,KAAK,SAAS,MAAM,CAAC;AAC7D,SAAO,QAAQ,SAAS,OAAO,QAAQ,KAAK,OAAO,IAAI,QAAQ,MAAM,OAAO;AAC9E;AAEA,SAAS,YAAY,OAA8B;AACjD,SAAO,iBAAiB,OAAO,MAAM,QAAQ,IAAI;AACnD;;;AC9EO,SAAS,wBACd,MACA,UACA,MAAoB,KAAK,KAChB;AACT,SAAO,KAAK,kBAAkB,UAAa,IAAI,IAAI,KAAK,iBAAiB;AAC3E;AAsCA,eAAsB,oBACpB,QACA,aACA,UAA6C,CAAC,GACD;AAC7C,QAAM,iBAAiB,IAAI,IAAI,QAAQ,kBAAkB,CAAC,CAAC;AAC3D,QAAM,MAAM,QAAQ,OAAO,KAAK;AAChC,QAAM,QAA2B,CAAC;AAClC,QAAM,eAAkC,CAAC;AACzC,QAAM,aAAuB,CAAC;AAC9B,QAAM,UAA+C,CAAC;AAEtD,aAAW,QAAQ,QAAQ;AACzB,UAAM,YAAY,MAAM,YAAY,IAAI;AACxC,UAAM,SAA4C,OAAO,cAAc,WAAW,EAAE,QAAQ,UAAU,IAAI;AAC1G,UAAM,SAAS,OAAO,WAAW,cAAc,SAAY,OAAO;AAClE,UAAM,kBAAkB;AAAA,MACtB,GAAG;AAAA,MACH,QAAQ,OAAO;AAAA,MACf,GAAI,OAAO,WAAW,cAAc,EAAE,cAAc,OAAU,IAAI,EAAE,cAAc,OAAO;AAAA,IAC3F;AACA,UAAM,WAAW,QAAQ,cACrB,MAAO,QAAQ,YAAwC,MAAM,MAAM,IACnE;AACJ,QAAI,aAAa,QAAW;AAC1B,iBAAW,KAAK,KAAK,EAAE;AACvB,cAAQ,KAAK,EAAE,MAAM,QAAQ,OAAO,QAAQ,QAAQ,SAAS,MAAM,CAAC;AACpE;AAAA,IACF;AACA,QAAI,OAAO,WAAW,aAAa;AACjC,YAAM,YAAY,IAAI;AACtB,YAAM,gBAAgB,gBAAgB,QAAQ;AAC9C,YAAM,UACJ,OAAO,SAAS,SACZ,gBACA,EAAE,GAAG,eAAe,MAAM,OAAO,MAAM,eAAe,WAAW,WAAW,UAAU;AAC5F,YAAM,YAAY,YAAY;AAC9B,YAAM,KAAK,OAAO;AAClB,UAAI,UAAW,cAAa,KAAK,OAAO;AACxC,cAAQ,KAAK,EAAE,MAAM,SAAS,QAAQ,aAAa,SAAS,UAAU,CAAC;AACvE;AAAA,IACF;AAEA,UAAM,aAAa,EAAE,GAAG,UAAU,QAAQ,OAAO,QAAQ,GAAI,SAAS,EAAE,cAAc,OAAO,IAAI,CAAC,EAAG;AACrG,UAAM,eAAe,eAAe,IAAI,OAAO,MAAM;AACrD,QAAI,aAAc,YAAW,KAAK,KAAK,EAAE;AAAA,QACpC,OAAM,KAAK,UAAU;AAC1B,QAAI,CAAC,gBAAgB,eAAe,KAAM,cAAa,KAAK,UAAU;AACtE,YAAQ,KAAK,EAAE,MAAM,YAAY,QAAQ,OAAO,QAAQ,QAAQ,SAAS,CAAC,gBAAgB,eAAe,KAAK,CAAC;AAAA,EACjH;AAEA,SAAO;AAAA,IACL;AAAA,IACA,SAAS,OAAO;AAAA,IAChB,SAAS,aAAa;AAAA,IACtB,SAAS,WAAW;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAGA,eAAsB,mBACpB,SACA,aACA,UAA6C,CAAC,GACD;AAC7C,QAAM,SAAS,MAAM,QAAQ,OAAO;AACpC,QAAM,UAAU,MAAM,oBAAoB,QAAQ,aAAa,OAAO;AACtE,MAAI,QAAQ,aAAa,SAAS,EAAG,OAAM,aAAa,SAAS,QAAQ,YAAY;AACrF,MAAI,QAAQ,WAAW,SAAS,EAAG,OAAM,YAAY,SAAS,QAAQ,UAAU;AAChF,SAAO;AACT;AAEA,eAAe,aAAoB,SAAgC,OAAyC;AAC1G,MAAI,QAAQ,SAAS;AACnB,UAAM,QAAQ,QAAQ,KAAK;AAC3B;AAAA,EACF;AACA,aAAW,QAAQ,MAAO,OAAM,QAAQ,IAAI,IAAI;AAClD;AAEA,eAAe,YAAmB,SAAgC,KAA8B;AAC9F,MAAI,QAAQ,YAAY;AACtB,UAAM,QAAQ,WAAW,GAAG;AAC5B;AAAA,EACF;AACA,aAAW,MAAM,IAAK,OAAM,QAAQ,OAAO,EAAE;AAC/C;AAEA,SAAS,gBAAuB,MAAwC;AACtE,QAAM,OAAO,EAAE,GAAG,KAAK;AACvB,SAAO,KAAK;AACZ,SAAO,KAAK;AACZ,SAAO;AACT;;;AC5HO,IAAM,YAAN,MAAiD;AAAA,EAItD,YAAY,cAAqC;AAFjD,SAAiB,YAAY,oBAAI,IAAgB;AAMjD,uBAAc,MAA6B,KAAK;AAEhD,qBAAY,CAAC,aAAuC;AAClD,WAAK,UAAU,IAAI,QAAQ;AAC3B,aAAO,MAAM,KAAK,UAAU,OAAO,QAAQ;AAAA,IAC7C;AARE,SAAK,QAAQ;AAAA,EACf;AAAA,EASA,SAAS,MAA4C;AACnD,QAAI,UAAU;AACd,eAAW,OAAO,OAAO,KAAK,IAAI,GAAyC;AACzE,UAAI,CAAC,OAAO,GAAG,KAAK,MAAM,GAAG,GAAG,KAAK,GAAG,CAAC,GAAG;AAC1C,kBAAU;AACV;AAAA,MACF;AAAA,IACF;AACA,QAAI,CAAC,QAAS;AACd,SAAK,QAAQ,EAAE,GAAG,KAAK,OAAO,GAAG,KAAK;AACtC,eAAW,YAAY,KAAK,UAAW,UAAS;AAAA,EAClD;AACF;","names":["item"]}
|
|
@@ -1,4 +1,51 @@
|
|
|
1
|
-
// src/
|
|
1
|
+
// src/features/items/types.ts
|
|
2
|
+
var KeepSyncAuthError = class extends Error {
|
|
3
|
+
constructor(status, options) {
|
|
4
|
+
super(`KeepKit sync authorization failed with status ${status}.`);
|
|
5
|
+
this.name = "KeepSyncAuthError";
|
|
6
|
+
this.status = status;
|
|
7
|
+
this.operation = options.operation;
|
|
8
|
+
this.scope = options.scope;
|
|
9
|
+
if (options.cause !== void 0) this.cause = options.cause;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
function isKeepSyncAuthError(error) {
|
|
13
|
+
return error instanceof KeepSyncAuthError;
|
|
14
|
+
}
|
|
15
|
+
var KeepStorageError = class extends Error {
|
|
16
|
+
constructor(message, options) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.name = "KeepStorageError";
|
|
19
|
+
this.operation = options.operation;
|
|
20
|
+
this.storageKey = options.storageKey;
|
|
21
|
+
if (options.cause !== void 0) this.cause = options.cause;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
var KeepStorageQuotaError = class extends KeepStorageError {
|
|
25
|
+
constructor(options) {
|
|
26
|
+
super("KeepKit storage quota was exceeded.", options);
|
|
27
|
+
this.name = "KeepStorageQuotaError";
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
var KeepStorageAccessError = class extends KeepStorageError {
|
|
31
|
+
constructor(options) {
|
|
32
|
+
super("KeepKit could not access the configured storage.", options);
|
|
33
|
+
this.name = "KeepStorageAccessError";
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
var KeepStorageParseError = class extends KeepStorageError {
|
|
37
|
+
constructor(options) {
|
|
38
|
+
super("KeepKit found invalid data in the configured storage.", options);
|
|
39
|
+
this.name = "KeepStorageParseError";
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
function normalizeKeepTags(tags) {
|
|
43
|
+
if (!tags) return void 0;
|
|
44
|
+
const normalized = [...new Set(tags.map((tag) => tag.trim()).filter(Boolean))];
|
|
45
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/features/persistence/scope.ts
|
|
2
49
|
function getKeepScopeKey(scope) {
|
|
3
50
|
if (!scope?.userId && !scope?.tenantId) return "";
|
|
4
51
|
return `:${encodeURIComponent(scope.tenantId ?? "_")}:${encodeURIComponent(scope.userId ?? "_")}`;
|
|
@@ -102,53 +149,6 @@ async function writeAll(base, items) {
|
|
|
102
149
|
for (const item of items) await base.set(item);
|
|
103
150
|
}
|
|
104
151
|
|
|
105
|
-
// src/types.ts
|
|
106
|
-
var KeepSyncAuthError = class extends Error {
|
|
107
|
-
constructor(status, options) {
|
|
108
|
-
super(`KeepKit sync authorization failed with status ${status}.`);
|
|
109
|
-
this.name = "KeepSyncAuthError";
|
|
110
|
-
this.status = status;
|
|
111
|
-
this.operation = options.operation;
|
|
112
|
-
this.scope = options.scope;
|
|
113
|
-
if (options.cause !== void 0) this.cause = options.cause;
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
function isKeepSyncAuthError(error) {
|
|
117
|
-
return error instanceof KeepSyncAuthError;
|
|
118
|
-
}
|
|
119
|
-
var KeepStorageError = class extends Error {
|
|
120
|
-
constructor(message, options) {
|
|
121
|
-
super(message);
|
|
122
|
-
this.name = "KeepStorageError";
|
|
123
|
-
this.operation = options.operation;
|
|
124
|
-
this.storageKey = options.storageKey;
|
|
125
|
-
if (options.cause !== void 0) this.cause = options.cause;
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
var KeepStorageQuotaError = class extends KeepStorageError {
|
|
129
|
-
constructor(options) {
|
|
130
|
-
super("KeepKit storage quota was exceeded.", options);
|
|
131
|
-
this.name = "KeepStorageQuotaError";
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
var KeepStorageAccessError = class extends KeepStorageError {
|
|
135
|
-
constructor(options) {
|
|
136
|
-
super("KeepKit could not access the configured storage.", options);
|
|
137
|
-
this.name = "KeepStorageAccessError";
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
var KeepStorageParseError = class extends KeepStorageError {
|
|
141
|
-
constructor(options) {
|
|
142
|
-
super("KeepKit found invalid data in the configured storage.", options);
|
|
143
|
-
this.name = "KeepStorageParseError";
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
function normalizeKeepTags(tags) {
|
|
147
|
-
if (!tags) return void 0;
|
|
148
|
-
const normalized = [...new Set(tags.map((tag) => tag.trim()).filter(Boolean))];
|
|
149
|
-
return normalized.length > 0 ? normalized : void 0;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
152
|
// src/storage/sync.ts
|
|
153
153
|
var DEFAULT_SYNC_QUEUE_KEY = "keepkit:sync-queue";
|
|
154
154
|
var DEFAULT_SYNC_QUEUE_DATABASE = "keepkit-sync";
|
|
@@ -1124,7 +1124,7 @@ var IndexedDBAdapter = class {
|
|
|
1124
1124
|
};
|
|
1125
1125
|
function isKeepItemArray(value) {
|
|
1126
1126
|
return Array.isArray(value) && value.every(
|
|
1127
|
-
(item) => isRecord2(item) && typeof item.id === "string" && typeof item.savedAt === "number" && Number.isFinite(item.savedAt) && typeof item.updatedAt === "number" && Number.isFinite(item.updatedAt) && "meta" in item && (item.targetType === void 0 || typeof item.targetType === "string") && (item.note === void 0 || typeof item.note === "string") && (item.schemaVersion === void 0 || typeof item.schemaVersion === "number" && Number.isFinite(item.schemaVersion)) && (item.revision === void 0 || typeof item.revision === "string") && (item.metaUpdatedAt === void 0 || typeof item.metaUpdatedAt === "number" && Number.isFinite(item.metaUpdatedAt)) && (item.status === void 0 || item.status === "available" || item.status === "expired" || item.status === "removed" || item.status === "deleted" || item.status === "private" || item.status === "unknown") && (item.statusReason === void 0 || typeof item.statusReason === "string") && (item.scope === void 0 || isSyncScope(item.scope)) && (item.tags === void 0 || Array.isArray(item.tags) && item.tags.every((tag) => typeof tag === "string"))
|
|
1127
|
+
(item) => isRecord2(item) && typeof item.id === "string" && typeof item.savedAt === "number" && Number.isFinite(item.savedAt) && typeof item.updatedAt === "number" && Number.isFinite(item.updatedAt) && "meta" in item && (item.order === void 0 || typeof item.order === "number" && Number.isFinite(item.order)) && (item.targetType === void 0 || typeof item.targetType === "string") && (item.note === void 0 || typeof item.note === "string") && (item.schemaVersion === void 0 || typeof item.schemaVersion === "number" && Number.isFinite(item.schemaVersion)) && (item.revision === void 0 || typeof item.revision === "string") && (item.metaUpdatedAt === void 0 || typeof item.metaUpdatedAt === "number" && Number.isFinite(item.metaUpdatedAt)) && (item.status === void 0 || item.status === "available" || item.status === "expired" || item.status === "removed" || item.status === "deleted" || item.status === "private" || item.status === "unknown") && (item.statusReason === void 0 || typeof item.statusReason === "string") && (item.scope === void 0 || isSyncScope(item.scope)) && (item.tags === void 0 || Array.isArray(item.tags) && item.tags.every((tag) => typeof tag === "string"))
|
|
1128
1128
|
);
|
|
1129
1129
|
}
|
|
1130
1130
|
function isRecord2(value) {
|
|
@@ -1167,11 +1167,6 @@ function isQuotaExceededError(cause) {
|
|
|
1167
1167
|
}
|
|
1168
1168
|
|
|
1169
1169
|
export {
|
|
1170
|
-
getKeepScopeKey,
|
|
1171
|
-
isSameKeepScope,
|
|
1172
|
-
ScopedStorageAdapter,
|
|
1173
|
-
createScopedStorageAdapter,
|
|
1174
|
-
ScopedSyncQueueAdapter,
|
|
1175
1170
|
KeepSyncAuthError,
|
|
1176
1171
|
isKeepSyncAuthError,
|
|
1177
1172
|
KeepStorageError,
|
|
@@ -1179,6 +1174,11 @@ export {
|
|
|
1179
1174
|
KeepStorageAccessError,
|
|
1180
1175
|
KeepStorageParseError,
|
|
1181
1176
|
normalizeKeepTags,
|
|
1177
|
+
getKeepScopeKey,
|
|
1178
|
+
isSameKeepScope,
|
|
1179
|
+
ScopedStorageAdapter,
|
|
1180
|
+
createScopedStorageAdapter,
|
|
1181
|
+
ScopedSyncQueueAdapter,
|
|
1182
1182
|
DEFAULT_SYNC_QUEUE_KEY,
|
|
1183
1183
|
DEFAULT_SYNC_QUEUE_DATABASE,
|
|
1184
1184
|
DEFAULT_SYNC_QUEUE_STORE,
|
|
@@ -1195,4 +1195,4 @@ export {
|
|
|
1195
1195
|
LocalStorageAdapter,
|
|
1196
1196
|
IndexedDBAdapter
|
|
1197
1197
|
};
|
|
1198
|
-
//# sourceMappingURL=chunk-
|
|
1198
|
+
//# sourceMappingURL=chunk-PNP7OALR.js.map
|