@kikiutils/shared 18.2.0 → 18.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -360,4 +360,5 @@ export declare class Path {
360
360
  writeFile(...args: DropFirstParameters<typeof fsp.writeFile>): Promise<void>;
361
361
  }
362
362
  //#endregion
363
+ export {};
363
364
  //# sourceMappingURL=path.d.ts.map
@@ -36,4 +36,5 @@ export declare class SshClient {
36
36
  setLoggerLevel(level: keyof typeof loggerLevelStringToConsolaLogLevelMap): void;
37
37
  }
38
38
  //#endregion
39
+ export {};
39
40
  //# sourceMappingURL=ssh-client.d.ts.map
@@ -62,4 +62,5 @@ export declare function copyBlobToClipboard(blob: Blob, options?: ClipboardItemO
62
62
  */
63
63
  export declare function copyTextToClipboard(text: string): Promise<CopyResult>;
64
64
  //#endregion
65
+ export {};
65
66
  //# sourceMappingURL=clipboard.d.ts.map
package/dist/file.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ import { BinaryInput } from "./types/index.js";
2
+ //#region src/file.d.ts
3
+ /**
4
+ * Detects a lowercase MIME type from binary content rather than its name or declared type.
5
+ *
6
+ * @remarks
7
+ * Requires the optional `file-type` peer dependency. Only formats supported by its binary detection
8
+ * are recognized; this is not a general text-file detector or a guarantee that a file is safe.
9
+ * Blob and File inputs are read through the detector's tokenizer instead of being fully buffered up front.
10
+ * The amount of content inspected depends on its format; this does not impose a fixed read limit.
11
+ * Detection and input-reading errors propagate to the caller.
12
+ *
13
+ * @param input - The binary content to inspect.
14
+ *
15
+ * @returns The detected lowercase MIME type, or `undefined` when the content is not recognized.
16
+ *
17
+ * @example
18
+ *
19
+ * ```ts
20
+ * import { getFileMimeType } from '@kikiutils/shared/file';
21
+ *
22
+ * const mimeType = await getFileMimeType(file);
23
+ * ```
24
+ */
25
+ export declare function getFileMimeType(input: BinaryInput): Promise<string | undefined>;
26
+ //#endregion
27
+ //# sourceMappingURL=file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.d.ts","names":[],"sources":["../src/file.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;wBA6BsB,gBAAgB,OAAO,cAAW"}
package/dist/file.js ADDED
@@ -0,0 +1,31 @@
1
+ import { fileTypeFromBlob, fileTypeFromBuffer } from "file-type";
2
+ //#region src/file.ts
3
+ /**
4
+ * Detects a lowercase MIME type from binary content rather than its name or declared type.
5
+ *
6
+ * @remarks
7
+ * Requires the optional `file-type` peer dependency. Only formats supported by its binary detection
8
+ * are recognized; this is not a general text-file detector or a guarantee that a file is safe.
9
+ * Blob and File inputs are read through the detector's tokenizer instead of being fully buffered up front.
10
+ * The amount of content inspected depends on its format; this does not impose a fixed read limit.
11
+ * Detection and input-reading errors propagate to the caller.
12
+ *
13
+ * @param input - The binary content to inspect.
14
+ *
15
+ * @returns The detected lowercase MIME type, or `undefined` when the content is not recognized.
16
+ *
17
+ * @example
18
+ *
19
+ * ```ts
20
+ * import { getFileMimeType } from '@kikiutils/shared/file';
21
+ *
22
+ * const mimeType = await getFileMimeType(file);
23
+ * ```
24
+ */
25
+ async function getFileMimeType(input) {
26
+ return (input instanceof ArrayBuffer || input instanceof Uint8Array ? await fileTypeFromBuffer(input) : await fileTypeFromBlob(input))?.mime.toLowerCase();
27
+ }
28
+ //#endregion
29
+ export { getFileMimeType };
30
+
31
+ //# sourceMappingURL=file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.js","names":[],"sources":["../src/file.ts"],"sourcesContent":["import {\n fileTypeFromBlob,\n fileTypeFromBuffer,\n} from 'file-type';\n\nimport type { BinaryInput } from './types';\n\n/**\n * Detects a lowercase MIME type from binary content rather than its name or declared type.\n *\n * @remarks\n * Requires the optional `file-type` peer dependency. Only formats supported by its binary detection\n * are recognized; this is not a general text-file detector or a guarantee that a file is safe.\n * Blob and File inputs are read through the detector's tokenizer instead of being fully buffered up front.\n * The amount of content inspected depends on its format; this does not impose a fixed read limit.\n * Detection and input-reading errors propagate to the caller.\n *\n * @param input - The binary content to inspect.\n *\n * @returns The detected lowercase MIME type, or `undefined` when the content is not recognized.\n *\n * @example\n *\n * ```ts\n * import { getFileMimeType } from '@kikiutils/shared/file';\n *\n * const mimeType = await getFileMimeType(file);\n * ```\n */\nexport async function getFileMimeType(input: BinaryInput) {\n // The tokenizer only uses size, slice, and arrayBuffer; Node/DOM Blob stream typings differ.\n const result = input instanceof ArrayBuffer || input instanceof Uint8Array\n ? await fileTypeFromBuffer(input)\n : await fileTypeFromBlob(input as Blob);\n\n return result?.mime.toLowerCase();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA6BA,eAAsB,gBAAgB,OAAoB;CAMtD,QAJe,iBAAiB,eAAe,iBAAiB,aAC1D,MAAM,mBAAmB,KAAK,IAC9B,MAAM,iBAAiB,KAAa,EAAA,EAE3B,KAAK,YAAY;AACpC"}
package/dist/math.d.ts CHANGED
@@ -46,4 +46,5 @@ export interface ToPercentageStringOptions {
46
46
  */
47
47
  export declare function toPercentageString(molecular: CalculableValue, denominator: CalculableValue, options?: ToPercentageStringOptions): string;
48
48
  //#endregion
49
+ export {};
49
50
  //# sourceMappingURL=math.d.ts.map
@@ -7,6 +7,7 @@ import { LRUCache } from "lru-cache";
7
7
  * The key resolver is called synchronously once per operation, and its exceptions propagate.
8
8
  * Reads return the cached value without copying it, or `null` for missing or nullish values.
9
9
  * `getItemTtl` exposes the underlying remaining TTL in milliseconds; `setItem` returns the underlying cache.
10
+ * `setItemWithTtl` accepts its TTL in milliseconds before the value and key arguments and returns the cache.
10
11
  * The facade does not dispose the supplied cache, and LRU defaults remain those of the supplied instance.
11
12
  *
12
13
  * @typeParam D - The stored value type used by reads and writes.
@@ -42,6 +43,7 @@ export declare function createLruKeyedStore<D = unknown>(lruInstance: LRUCache<a
42
43
  */
43
44
  resolveKey: (...args: P) => string;
44
45
  setItem: (value: D, ...args: P) => LRUCache<any, any, any>;
46
+ setItemWithTtl(ttlMilliseconds: number, value: D, ...args: P): LRUCache<any, any, any>;
45
47
  }>;
46
48
  //#endregion
47
49
  //# sourceMappingURL=keyed-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"keyed-store.d.ts","names":[],"sources":["../../../src/storages/lru/keyed-store.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA6BgB,oBAAoB,aAAa,aAAa,2BAClD,iBAAiB,WAAW,MAAM,iBAAY;;;;;;EAMjC,WAAA,MAAA,IAAC,YAAA;EAII,gBAAA,MAAA;EACH,aAAA,MAAA;EACG,gBAAA,MAAA;;;;EAIA,gBAAA,MAAA;EACL,UAAA,OAAA,MAAC,MAAW,MAAC"}
1
+ {"version":3,"file":"keyed-store.d.ts","names":[],"sources":["../../../src/storages/lru/keyed-store.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA8BgB,oBAAoB,aAAa,aAAa,2BAClD,iBAAiB,WAAW,MAAM,iBAAY;;;;;;EAMjC,WAAA,MAAA,IAAC,YAAA;EAII,gBAAA,MAAA;EACH,aAAA,MAAA;EACG,gBAAA,MAAA;;;;EAIA,gBAAA,MAAA;EACL,UAAA,OAAA,MAAC,MAAW,MAAC;EACE,eAAA,yBAAM,OAAS,MAAC,MAAW,IAAC"}
@@ -6,6 +6,7 @@
6
6
  * The key resolver is called synchronously once per operation, and its exceptions propagate.
7
7
  * Reads return the cached value without copying it, or `null` for missing or nullish values.
8
8
  * `getItemTtl` exposes the underlying remaining TTL in milliseconds; `setItem` returns the underlying cache.
9
+ * `setItemWithTtl` accepts its TTL in milliseconds before the value and key arguments and returns the cache.
9
10
  * The facade does not dispose the supplied cache, and LRU defaults remain those of the supplied instance.
10
11
  *
11
12
  * @typeParam D - The stored value type used by reads and writes.
@@ -43,7 +44,10 @@ function createLruKeyedStore(lruInstance) {
43
44
  * Resolves the full cache key from the given arguments.
44
45
  */
45
46
  resolveKey: (...args) => keyFn(...args),
46
- setItem: (value, ...args) => lruInstance.set(keyFn(...args), value)
47
+ setItem: (value, ...args) => lruInstance.set(keyFn(...args), value),
48
+ setItemWithTtl(ttlMilliseconds, value, ...args) {
49
+ return lruInstance.set(keyFn(...args), value, { ttl: ttlMilliseconds });
50
+ }
47
51
  });
48
52
  }
49
53
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"keyed-store.js","names":[],"sources":["../../../src/storages/lru/keyed-store.ts"],"sourcesContent":["import type { LRUCache } from 'lru-cache';\n\n/**\n * Creates a keyed cache factory sharing a caller-owned LRU cache.\n *\n * @remarks\n * The key resolver is called synchronously once per operation, and its exceptions propagate.\n * Reads return the cached value without copying it, or `null` for missing or nullish values.\n * `getItemTtl` exposes the underlying remaining TTL in milliseconds; `setItem` returns the underlying cache.\n * The facade does not dispose the supplied cache, and LRU defaults remain those of the supplied instance.\n *\n * @typeParam D - The stored value type used by reads and writes.\n *\n * @param lruInstance - The shared LRU cache instance.\n *\n * @returns A factory accepting a key resolver and returning a new frozen keyed facade sharing the cache.\n *\n * @example\n *\n * ```ts\n * import { createLruKeyedStore } from '@kikiutils/shared/storages/lru/keyed-store';\n * import { LRUCache } from 'lru-cache';\n *\n * const cache = new LRUCache<string, { name: string }>({ max: 100 });\n * const keyedStore = createLruKeyedStore<{ name: string }>(cache)((userId: string) => `user:${userId}`);\n * keyedStore.setItem({ name: 'Alice' }, 'user-123');\n * console.log(keyedStore.getItem('user-123')); // => { name: 'Alice' }\n * ```\n */\nexport function createLruKeyedStore<D = unknown>(lruInstance: LRUCache<any, any, any>) {\n return <P extends any[]>(keyFn: (...args: P) => string) => Object.freeze({\n /**\n * Returns the cached value and applies the underlying cache's read-recency policy.\n *\n * @returns The cached value without copying it, or `null` when absent or nullish.\n */\n getItem(...args: P) {\n const rawValue = lruInstance.get(keyFn(...args));\n return rawValue as D ?? null;\n },\n getItemTtl: (...args: P) => lruInstance.getRemainingTTL(keyFn(...args)),\n hasItem: (...args: P) => lruInstance.has(keyFn(...args)),\n removeItem: (...args: P) => lruInstance.delete(keyFn(...args)),\n /**\n * Resolves the full cache key from the given arguments.\n */\n resolveKey: (...args: P) => keyFn(...args),\n setItem: (value: D, ...args: P) => lruInstance.set(keyFn(...args), value),\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,SAAgB,oBAAiC,aAAsC;CACnF,QAAyB,UAAkC,OAAO,OAAO;;;;;;EAMrE,QAAQ,GAAG,MAAS;GAEhB,OADiB,YAAY,IAAI,MAAM,GAAG,IAAI,CAChC,KAAU;EAC5B;EACA,aAAa,GAAG,SAAY,YAAY,gBAAgB,MAAM,GAAG,IAAI,CAAC;EACtE,UAAU,GAAG,SAAY,YAAY,IAAI,MAAM,GAAG,IAAI,CAAC;EACvD,aAAa,GAAG,SAAY,YAAY,OAAO,MAAM,GAAG,IAAI,CAAC;;;;EAI7D,aAAa,GAAG,SAAY,MAAM,GAAG,IAAI;EACzC,UAAU,OAAU,GAAG,SAAY,YAAY,IAAI,MAAM,GAAG,IAAI,GAAG,KAAK;CAC5E,CAAC;AACL"}
1
+ {"version":3,"file":"keyed-store.js","names":[],"sources":["../../../src/storages/lru/keyed-store.ts"],"sourcesContent":["import type { LRUCache } from 'lru-cache';\n\n/**\n * Creates a keyed cache factory sharing a caller-owned LRU cache.\n *\n * @remarks\n * The key resolver is called synchronously once per operation, and its exceptions propagate.\n * Reads return the cached value without copying it, or `null` for missing or nullish values.\n * `getItemTtl` exposes the underlying remaining TTL in milliseconds; `setItem` returns the underlying cache.\n * `setItemWithTtl` accepts its TTL in milliseconds before the value and key arguments and returns the cache.\n * The facade does not dispose the supplied cache, and LRU defaults remain those of the supplied instance.\n *\n * @typeParam D - The stored value type used by reads and writes.\n *\n * @param lruInstance - The shared LRU cache instance.\n *\n * @returns A factory accepting a key resolver and returning a new frozen keyed facade sharing the cache.\n *\n * @example\n *\n * ```ts\n * import { createLruKeyedStore } from '@kikiutils/shared/storages/lru/keyed-store';\n * import { LRUCache } from 'lru-cache';\n *\n * const cache = new LRUCache<string, { name: string }>({ max: 100 });\n * const keyedStore = createLruKeyedStore<{ name: string }>(cache)((userId: string) => `user:${userId}`);\n * keyedStore.setItem({ name: 'Alice' }, 'user-123');\n * console.log(keyedStore.getItem('user-123')); // => { name: 'Alice' }\n * ```\n */\nexport function createLruKeyedStore<D = unknown>(lruInstance: LRUCache<any, any, any>) {\n return <P extends any[]>(keyFn: (...args: P) => string) => Object.freeze({\n /**\n * Returns the cached value and applies the underlying cache's read-recency policy.\n *\n * @returns The cached value without copying it, or `null` when absent or nullish.\n */\n getItem(...args: P) {\n const rawValue = lruInstance.get(keyFn(...args));\n return rawValue as D ?? null;\n },\n getItemTtl: (...args: P) => lruInstance.getRemainingTTL(keyFn(...args)),\n hasItem: (...args: P) => lruInstance.has(keyFn(...args)),\n removeItem: (...args: P) => lruInstance.delete(keyFn(...args)),\n /**\n * Resolves the full cache key from the given arguments.\n */\n resolveKey: (...args: P) => keyFn(...args),\n setItem: (value: D, ...args: P) => lruInstance.set(keyFn(...args), value),\n setItemWithTtl(ttlMilliseconds: number, value: D, ...args: P) {\n return lruInstance.set(keyFn(...args), value, { ttl: ttlMilliseconds });\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,SAAgB,oBAAiC,aAAsC;CACnF,QAAyB,UAAkC,OAAO,OAAO;;;;;;EAMrE,QAAQ,GAAG,MAAS;GAEhB,OADiB,YAAY,IAAI,MAAM,GAAG,IAAI,CAChC,KAAU;EAC5B;EACA,aAAa,GAAG,SAAY,YAAY,gBAAgB,MAAM,GAAG,IAAI,CAAC;EACtE,UAAU,GAAG,SAAY,YAAY,IAAI,MAAM,GAAG,IAAI,CAAC;EACvD,aAAa,GAAG,SAAY,YAAY,OAAO,MAAM,GAAG,IAAI,CAAC;;;;EAI7D,aAAa,GAAG,SAAY,MAAM,GAAG,IAAI;EACzC,UAAU,OAAU,GAAG,SAAY,YAAY,IAAI,MAAM,GAAG,IAAI,GAAG,KAAK;EACxE,eAAe,iBAAyB,OAAU,GAAG,MAAS;GAC1D,OAAO,YAAY,IAAI,MAAM,GAAG,IAAI,GAAG,OAAO,EAAE,KAAK,gBAAgB,CAAC;EAC1E;CACJ,CAAC;AACL"}
@@ -14,4 +14,5 @@ type PathImpl<K extends number | string, V, U> = [U] extends [never] ? DefaultPa
14
14
  type TerminalType = bigint | Blob | boolean | Date | File | null | number | ObjectId | RegExp | string | symbol | undefined;
15
15
  type TupleKey<T extends ReadonlyArray<any>> = Exclude<keyof T, keyof any[]>;
16
16
  //#endregion
17
+ export {};
17
18
  //# sourceMappingURL=filtered-key-path.d.ts.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kikiutils/shared",
3
3
  "type": "module",
4
- "version": "18.2.0",
4
+ "version": "18.3.0",
5
5
  "description": "A lightweight and modular utility library for modern JavaScript and TypeScript — includes secure hashing, flexible logging, datetime tools, Vue/web helpers, storage abstraction, and more.",
6
6
  "author": "kiki-kanri",
7
7
  "license": "MIT",
@@ -75,6 +75,7 @@
75
75
  "date-fns": "^4.4.0",
76
76
  "decimal.js": "^10.6.0",
77
77
  "element-plus": "^2.14.4",
78
+ "file-type": "^22.1.1",
78
79
  "lru-cache": "^11.5.2",
79
80
  "millify": "^6.1.0",
80
81
  "msgpackr": "^2.0.5",
@@ -109,6 +110,9 @@
109
110
  "element-plus": {
110
111
  "optional": true
111
112
  },
113
+ "file-type": {
114
+ "optional": true
115
+ },
112
116
  "lru-cache": {
113
117
  "optional": true
114
118
  },
@@ -136,12 +140,12 @@
136
140
  },
137
141
  "devDependencies": {
138
142
  "@antfu/eslint-config": "^9.5.1",
139
- "@kikiutils/eslint-config": "^9.2.1",
143
+ "@kikiutils/eslint-config": "^9.3.0",
140
144
  "@kikiutils/tsconfigs": "^7.0.0",
141
145
  "@noble/hashes": "^2.4.0",
142
- "@types/node": "^26.6.4",
146
+ "@types/node": "^26.6.5",
143
147
  "@types/ssh2": "^1.15.6",
144
- "@vitest/coverage-v8": "^5.0.3",
148
+ "@vitest/coverage-v8": "^5.0.4",
145
149
  "async-validator": "^4.2.5",
146
150
  "bson": "^7.3.3",
147
151
  "changelogen": "^0.6.2",
@@ -151,20 +155,21 @@
151
155
  "decimal.js": "^10.6.0",
152
156
  "element-plus": "^2.14.7",
153
157
  "eslint": "^10.12.0",
154
- "jsdom": "^30.1.1",
155
- "knip": "^6.39.0",
158
+ "file-type": "^22.1.1",
159
+ "jsdom": "^30.1.2",
160
+ "knip": "^6.41.0",
156
161
  "lru-cache": "^11.5.3",
157
162
  "millify": "^6.1.0",
158
163
  "msgpackr": "^2.1.0",
159
164
  "node-ssh": "^13.2.1",
160
165
  "pino": "^10.4.0",
161
- "pino-pretty": "^13.1.3",
166
+ "pino-pretty": "^13.2.0",
162
167
  "publint": "^0.3.25",
163
- "tsdown": "^0.23.0",
168
+ "tsdown": "^0.23.1",
164
169
  "typescript": "^6.0.3",
165
170
  "unplugin-unused": "^0.6.0",
166
- "vitest": "^5.0.3",
171
+ "vitest": "^5.0.4",
167
172
  "vue": "^3.5.43",
168
- "vue-router": "^5.3.1"
173
+ "vue-router": "^5.4.0"
169
174
  }
170
175
  }
package/src/file.ts ADDED
@@ -0,0 +1,37 @@
1
+ import {
2
+ fileTypeFromBlob,
3
+ fileTypeFromBuffer,
4
+ } from 'file-type';
5
+
6
+ import type { BinaryInput } from './types';
7
+
8
+ /**
9
+ * Detects a lowercase MIME type from binary content rather than its name or declared type.
10
+ *
11
+ * @remarks
12
+ * Requires the optional `file-type` peer dependency. Only formats supported by its binary detection
13
+ * are recognized; this is not a general text-file detector or a guarantee that a file is safe.
14
+ * Blob and File inputs are read through the detector's tokenizer instead of being fully buffered up front.
15
+ * The amount of content inspected depends on its format; this does not impose a fixed read limit.
16
+ * Detection and input-reading errors propagate to the caller.
17
+ *
18
+ * @param input - The binary content to inspect.
19
+ *
20
+ * @returns The detected lowercase MIME type, or `undefined` when the content is not recognized.
21
+ *
22
+ * @example
23
+ *
24
+ * ```ts
25
+ * import { getFileMimeType } from '@kikiutils/shared/file';
26
+ *
27
+ * const mimeType = await getFileMimeType(file);
28
+ * ```
29
+ */
30
+ export async function getFileMimeType(input: BinaryInput) {
31
+ // The tokenizer only uses size, slice, and arrayBuffer; Node/DOM Blob stream typings differ.
32
+ const result = input instanceof ArrayBuffer || input instanceof Uint8Array
33
+ ? await fileTypeFromBuffer(input)
34
+ : await fileTypeFromBlob(input as Blob);
35
+
36
+ return result?.mime.toLowerCase();
37
+ }
@@ -7,6 +7,7 @@ import type { LRUCache } from 'lru-cache';
7
7
  * The key resolver is called synchronously once per operation, and its exceptions propagate.
8
8
  * Reads return the cached value without copying it, or `null` for missing or nullish values.
9
9
  * `getItemTtl` exposes the underlying remaining TTL in milliseconds; `setItem` returns the underlying cache.
10
+ * `setItemWithTtl` accepts its TTL in milliseconds before the value and key arguments and returns the cache.
10
11
  * The facade does not dispose the supplied cache, and LRU defaults remain those of the supplied instance.
11
12
  *
12
13
  * @typeParam D - The stored value type used by reads and writes.
@@ -46,5 +47,8 @@ export function createLruKeyedStore<D = unknown>(lruInstance: LRUCache<any, any,
46
47
  */
47
48
  resolveKey: (...args: P) => keyFn(...args),
48
49
  setItem: (value: D, ...args: P) => lruInstance.set(keyFn(...args), value),
50
+ setItemWithTtl(ttlMilliseconds: number, value: D, ...args: P) {
51
+ return lruInstance.set(keyFn(...args), value, { ttl: ttlMilliseconds });
52
+ },
49
53
  });
50
54
  }