unikvs 0.0.4 → 0.0.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unikvs",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "",
5
5
  "homepage": "https://github.com/tai-kun/unikvs",
6
6
  "license": "MIT",
@@ -24,33 +24,35 @@
24
24
  "default": "./dist/src/index.js"
25
25
  }
26
26
  },
27
- "scripts": {
28
- "build": "tsc --project ./.config/tsconfig.build.json"
29
- },
30
27
  "dependencies": {
31
- "@unikvs/core": "0.0.4",
32
- "asyncmux": "^0.0.5",
28
+ "@tai-kun/valibot-extra-lab": "^0.0.4",
29
+ "@unikvs/core": "0.0.6",
30
+ "asyncmux": "^0.0.8",
33
31
  "call-fn-once": "^0.0.4",
34
32
  "try-capture-stack-trace": "^0.0.3"
35
33
  },
36
34
  "devDependencies": {
37
- "@tsconfig/node22": "^22.0.5",
35
+ "@tsconfig/node24": "^24.0.4",
38
36
  "@tsconfig/strictest": "^2.0.8",
39
- "@types/node": "^22.19.17",
40
- "@unikvs/checksum": "0.0.4",
41
- "@unikvs/compression": "0.0.4",
42
- "@unikvs/fs.node": "0.0.4",
43
- "@unikvs/memory": "0.0.4",
44
- "@unikvs/opfs": "0.0.4",
45
- "@unikvs/utils": "0.0.4",
46
- "@vitest/browser": "^4.1.4",
47
- "@vitest/browser-playwright": "^4.1.4",
37
+ "@types/node": "^24.12.2",
38
+ "@unikvs/checksum": "0.0.6",
39
+ "@unikvs/compression": "0.0.6",
40
+ "@unikvs/fs.node": "0.0.6",
41
+ "@unikvs/memory": "0.0.6",
42
+ "@unikvs/opfs": "0.0.6",
43
+ "@unikvs/utils": "0.0.6",
44
+ "@vitest/browser": "^4.1.5",
45
+ "@vitest/browser-playwright": "^4.1.5",
48
46
  "npm-check-updates": "^20.0.2",
49
47
  "playwright": "^1.59.1",
50
- "vitest": "^4.1.4"
48
+ "vite": "^8.0.10",
49
+ "vitest": "^4.1.5"
51
50
  },
52
51
  "peerDependencies": {
53
52
  "@logtape/logtape": "^2.0.0",
54
53
  "valibot": "^1.0.0"
54
+ },
55
+ "scripts": {
56
+ "build": "tsc --project ./.config/tsconfig.build.json"
55
57
  }
56
- }
58
+ }
package/src/_storage.ts CHANGED
@@ -1,5 +1,6 @@
1
- import type { Context, IReadableStream, IStorage, IWritableStream, Key } from "@unikvs/core";
1
+ import type { Context, IReadableStream, IStorage, IWritableStream } from "@unikvs/core";
2
2
 
3
+ import * as v from "./_valibot.js";
3
4
  import {
4
5
  type PluginOperationAggregateError,
5
6
  ReadableStreamNotSupportedError,
@@ -7,7 +8,7 @@ import {
7
8
  WritableStreamNotSupportedError,
8
9
  } from "./errors.js";
9
10
 
10
- export class UniKvsStorage {
11
+ export default class UniKvsStorage {
11
12
  private readonly io: IStorage;
12
13
 
13
14
  public constructor(io: IStorage) {
@@ -37,7 +38,7 @@ export class UniKvsStorage {
37
38
  public async onOtherWriteError(
38
39
  context: Context,
39
40
  signal: AbortSignal,
40
- key: Key,
41
+ key: IStorage.Key,
41
42
  error: PluginOperationAggregateError,
42
43
  ): Promise<void> {
43
44
  if (!this.io.isOpen) {
@@ -56,7 +57,12 @@ export class UniKvsStorage {
56
57
  });
57
58
  }
58
59
 
59
- public async write(context: Context, signal: AbortSignal, key: Key, data: any): Promise<void> {
60
+ public async write(
61
+ context: Context,
62
+ signal: AbortSignal,
63
+ key: IStorage.Key,
64
+ data: unknown,
65
+ ): Promise<void> {
60
66
  if (!this.io.isOpen) {
61
67
  throw new StorageIsNotOpenError({ name: this.io.name });
62
68
  }
@@ -64,23 +70,28 @@ export class UniKvsStorage {
64
70
  await this.io.write({ key, data, signal, context });
65
71
  }
66
72
 
67
- public async read(context: Context, signal: AbortSignal, key: Key): Promise<any> {
73
+ public async read(context: Context, signal: AbortSignal, key: IStorage.Key): Promise<unknown> {
68
74
  if (!this.io.isOpen) {
69
75
  throw new StorageIsNotOpenError({ name: this.io.name });
70
76
  }
71
77
 
72
- return await this.io.read({ key, signal, context });
78
+ const output = await this.io.read({ key, signal, context });
79
+
80
+ return output;
73
81
  }
74
82
 
75
- public async exists(context: Context, signal: AbortSignal, key: Key): Promise<boolean> {
83
+ public async exists(context: Context, signal: AbortSignal, key: IStorage.Key): Promise<boolean> {
76
84
  if (!this.io.isOpen) {
77
85
  throw new StorageIsNotOpenError({ name: this.io.name });
78
86
  }
79
87
 
80
- return await this.io.exists({ key, signal, context });
88
+ const output = await this.io.exists({ key, signal, context });
89
+ const parsed = Boolean(output);
90
+
91
+ return parsed;
81
92
  }
82
93
 
83
- public async delete(context: Context, signal: AbortSignal, key: Key): Promise<void> {
94
+ public async delete(context: Context, signal: AbortSignal, key: IStorage.Key): Promise<void> {
84
95
  if (!this.io.isOpen) {
85
96
  throw new StorageIsNotOpenError({ name: this.io.name });
86
97
  }
@@ -99,7 +110,7 @@ export class UniKvsStorage {
99
110
  public async getWritable(
100
111
  context: Context,
101
112
  signal: AbortSignal,
102
- key: Key,
113
+ key: IStorage.Key,
103
114
  ): Promise<IWritableStream> {
104
115
  if (!this.io.isOpen) {
105
116
  throw new StorageIsNotOpenError({ name: this.io.name });
@@ -109,13 +120,16 @@ export class UniKvsStorage {
109
120
  throw new WritableStreamNotSupportedError({ name: this.io.name });
110
121
  }
111
122
 
112
- return await this.io.getWritable({ key, signal, context });
123
+ const output = await this.io.getWritable({ key, signal, context });
124
+ const parsed = v.parseOutput(v.instance(WritableStream), output);
125
+
126
+ return parsed;
113
127
  }
114
128
 
115
129
  public async getReadable(
116
130
  context: Context,
117
131
  signal: AbortSignal,
118
- key: Key,
132
+ key: IStorage.Key,
119
133
  ): Promise<IReadableStream> {
120
134
  if (!this.io.isOpen) {
121
135
  throw new StorageIsNotOpenError({ name: this.io.name });
@@ -125,6 +139,9 @@ export class UniKvsStorage {
125
139
  throw new ReadableStreamNotSupportedError({ name: this.io.name });
126
140
  }
127
141
 
128
- return await this.io.getReadable({ key, signal, context });
142
+ const output = await this.io.getReadable({ key, signal, context });
143
+ const parsed = v.parseOutput(v.instance(ReadableStream), output);
144
+
145
+ return parsed;
129
146
  }
130
147
  }
@@ -33,20 +33,24 @@ export default class UniKvsTransformer {
33
33
  }
34
34
  }
35
35
 
36
- public async encode(context: Context, signal: AbortSignal, data: any): Promise<void> {
36
+ public async encode(context: Context, signal: AbortSignal, data: any): Promise<unknown> {
37
37
  if (!this.tf.isOpen) {
38
38
  throw new TransformerIsNotOpenError({ name: this.tf.name });
39
39
  }
40
40
 
41
- return await this.tf.encode({ data, signal, context });
41
+ const output = await this.tf.encode({ data, signal, context });
42
+
43
+ return output;
42
44
  }
43
45
 
44
- public async decode(context: Context, signal: AbortSignal, data: any): Promise<any> {
46
+ public async decode(context: Context, signal: AbortSignal, data: any): Promise<unknown> {
45
47
  if (!this.tf.isOpen) {
46
48
  throw new TransformerIsNotOpenError({ name: this.tf.name });
47
49
  }
48
50
 
49
- return await this.tf.decode({ data, signal, context });
51
+ const output = await this.tf.decode({ data, signal, context });
52
+
53
+ return output;
50
54
  }
51
55
 
52
56
  public async getEncodable(context: Context, signal: AbortSignal): Promise<IEncodable> {
@@ -58,7 +62,10 @@ export default class UniKvsTransformer {
58
62
  throw new EncodableStreamNotSupportedError({ name: this.tf.name });
59
63
  }
60
64
 
61
- return await this.tf.getEncodable({ signal, context });
65
+ const output = await this.tf.getEncodable({ signal, context });
66
+ const parsed = output; // TODO(tai-kun): 要検証
67
+
68
+ return parsed;
62
69
  }
63
70
 
64
71
  public async getDecodable(context: Context, signal: AbortSignal): Promise<IDecodable> {
@@ -70,6 +77,9 @@ export default class UniKvsTransformer {
70
77
  throw new DecodableStreamNotSupportedError({ name: this.tf.name });
71
78
  }
72
79
 
73
- return await this.tf.getDecodable({ signal, context });
80
+ const output = await this.tf.getDecodable({ signal, context });
81
+ const parsed = output; // TODO(tai-kun): 要検証
82
+
83
+ return parsed;
74
84
  }
75
85
  }
package/src/_valibot.ts CHANGED
@@ -1,23 +1,61 @@
1
+ import type { ErrorOptions } from "@unikvs/core";
1
2
  import { tryCaptureStackTrace } from "try-capture-stack-trace";
2
3
  import { type InferOutput, safeParse } from "valibot";
3
4
 
4
- import { InvalidInputError, type Issue } from "./errors.js";
5
+ import {
6
+ InvalidInputError,
7
+ InvalidOutputError,
8
+ type InvalidInputErrorArgs,
9
+ type InvalidOutputErrorArgs,
10
+ } from "./errors.js";
11
+
12
+ export type { InferInput, InferOutput } from "valibot";
13
+ export {
14
+ any,
15
+ omit,
16
+ pipe,
17
+ union,
18
+ number,
19
+ string,
20
+ symbol,
21
+ unknown,
22
+ instance,
23
+ minValue,
24
+ optional,
25
+ safeInteger,
26
+ } from "valibot";
27
+
28
+ export { array, tuple, object, record, transform } from "@tai-kun/valibot-extra-lab";
5
29
 
6
30
  type BaseSchema = typeof safeParse extends (schema: infer S, ...args: any) => any ? S : never;
7
31
 
8
- export type ParseErrorConstructorArgs = {
9
- readonly value: unknown;
10
- readonly issues: readonly [Issue, ...Issue[]];
11
- };
32
+ export interface ParseInputErrorConstructor {
33
+ new (args: InvalidInputErrorArgs, options?: ErrorOptions): Error;
34
+ }
35
+
36
+ export function parseInput<const TSchema extends BaseSchema>(
37
+ schema: TSchema,
38
+ value: unknown,
39
+ Error: ParseInputErrorConstructor = InvalidInputError,
40
+ ): InferOutput<TSchema> {
41
+ const result = safeParse(schema, value);
42
+ if (result.success) {
43
+ return result.output;
44
+ }
45
+
46
+ const error = new Error({ value, issues: result.issues });
47
+ tryCaptureStackTrace(error, parseInput);
48
+ throw error;
49
+ }
12
50
 
13
- export interface ParseErrorConstructor {
14
- new (args: ParseErrorConstructorArgs): Error;
51
+ export interface ParseOutputErrorConstructor {
52
+ new (args: InvalidOutputErrorArgs, options?: ErrorOptions): Error;
15
53
  }
16
54
 
17
- export function parse<const TSchema extends BaseSchema>(
55
+ export function parseOutput<const TSchema extends BaseSchema>(
18
56
  schema: TSchema,
19
57
  value: unknown,
20
- Error: ParseErrorConstructor = InvalidInputError,
58
+ Error: ParseOutputErrorConstructor = InvalidOutputError,
21
59
  ): InferOutput<TSchema> {
22
60
  const result = safeParse(schema, value);
23
61
  if (result.success) {
@@ -25,6 +63,6 @@ export function parse<const TSchema extends BaseSchema>(
25
63
  }
26
64
 
27
65
  const error = new Error({ value, issues: result.issues });
28
- tryCaptureStackTrace(error, parse);
66
+ tryCaptureStackTrace(error, parseOutput);
29
67
  throw error;
30
68
  }
package/src/errors.ts CHANGED
@@ -1,4 +1,10 @@
1
- import { setErrorMessage, ErrorBase, type ErrorOptions, type ErrorMeta, Key } from "@unikvs/core";
1
+ import {
2
+ setErrorMessage,
3
+ ErrorBase,
4
+ type ErrorOptions,
5
+ type ErrorMeta,
6
+ type IStorage,
7
+ } from "@unikvs/core";
2
8
  import type { BaseIssue } from "valibot";
3
9
 
4
10
  // -------------------------------------------------------------------------------------------------
@@ -90,7 +96,7 @@ export class UniKvsIsNotOpenError extends ErrorBase<undefined> {
90
96
  setErrorMessage(UniKvsIsNotOpenError, "UniKvs は開いていません", "ja");
91
97
 
92
98
  export type KeyNotFoundErrorMeta = {
93
- readonly key: Key;
99
+ readonly key: IStorage.Key;
94
100
  };
95
101
 
96
102
  export type KeyNotFoundErrorArgs = KeyNotFoundErrorMeta;
@@ -101,7 +107,7 @@ export class KeyNotFoundError extends ErrorBase<KeyNotFoundErrorMeta> {
101
107
  }
102
108
 
103
109
  public constructor(args: KeyNotFoundErrorArgs, options?: ErrorOptions) {
104
- super(args, ({ key }) => `Key ${JSON.stringify(key)} not found`, options);
110
+ super(args, ({ key }) => `IStorage.Key ${JSON.stringify(key)} not found`, options);
105
111
  }
106
112
  }
107
113
 
@@ -197,6 +203,28 @@ setErrorMessage(
197
203
  "ja",
198
204
  );
199
205
 
206
+ export type MultipartWriteNotSupportedErrorMeta = {
207
+ readonly name: string;
208
+ };
209
+
210
+ export type MultipartWriteNotSupportedErrorArgs = MultipartWriteNotSupportedErrorMeta;
211
+
212
+ export class MultipartWriteNotSupportedError extends ErrorBase<MultipartWriteNotSupportedErrorMeta> {
213
+ static {
214
+ this.prototype.name = "UniKvsMultipartWriteNotSupportedError";
215
+ }
216
+
217
+ public constructor(args: MultipartWriteNotSupportedErrorArgs, options?: ErrorOptions) {
218
+ super(args, ({ name }) => `Storage "${name}" does not support multipart-write`, options);
219
+ }
220
+ }
221
+
222
+ setErrorMessage(
223
+ StorageIsNotOpenError,
224
+ ({ name }) => `ストレージ "${name}" はマルチパート書き込みをサポートしていません`,
225
+ "ja",
226
+ );
227
+
200
228
  // -------------------------------------------------------------------------------------------------
201
229
  //
202
230
  // トランスフォーマー
@@ -3,13 +3,12 @@ import type {
3
3
  IReadableStreamStorage,
4
4
  IStorage,
5
5
  IWritableStreamStorage,
6
- Key,
7
6
  IDecodableStreamTransformer,
8
7
  IEncodableStreamTransformer,
9
8
  ITransformer,
10
9
  } from "@unikvs/core";
11
10
 
12
- import { UniKvsStorage } from "./_storage.js";
11
+ import UniKvsStorage from "./_storage.js";
13
12
  import UniKvsTransformer from "./_transformer.js";
14
13
  import type { ContextSource } from "./context.types.js";
15
14
  import { MissingStorageError } from "./errors.js";
@@ -95,18 +94,16 @@ export type StreamValue<TChunkData = any> = [Type: typeof STREAM_VALUE, ChunkDat
95
94
  /**
96
95
  * UniKvs で扱う値の抽象型です。プレーンな値かストリーム値のいずれかになります。
97
96
  *
98
- * @template TDataAndChunkData データまたはチャンクデータの型です。
97
+ * @template TData データまたはチャンクデータの型です。
99
98
  */
100
- export type Value<TDataAndChunkData = any> =
101
- | PlainValue<TDataAndChunkData>
102
- | StreamValue<TDataAndChunkData>;
99
+ export type Value<TData = any> = PlainValue<TData> | StreamValue<TData>;
103
100
 
104
101
  /**
105
102
  * キーと値のマッピングを定義するオブジェクトの型です。
106
103
  *
107
104
  * @template T マッピングされる値の型です。
108
105
  */
109
- export type KeyValueMapping<T = any> = { readonly [key: Key]: Value<T> };
106
+ export type KeyValueMapping<T = any> = { readonly [key: IStorage.Key]: Value<T> };
110
107
 
111
108
  /**
112
109
  * PlainValue 型から内部のデータ型を抽出します。
@@ -130,7 +127,7 @@ export type $InferStreamValueChunkData<TStremValue> =
130
127
  * @template TKeyValueMapping 対象となるマッピング型です。
131
128
  */
132
129
  export type KeyofKeyValueMapping<TKeyValueMapping extends KeyValueMapping = KeyValueMapping> =
133
- Extract<keyof TKeyValueMapping, Key>;
130
+ Extract<keyof TKeyValueMapping, IStorage.Key>;
134
131
 
135
132
  /**
136
133
  * UniKvs の設定を構築するためのビルダーインターフェースです。