unikvs 0.0.16 → 0.0.17
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/dist/index.d.ts.map +1 -1
- package/dist/index.js +630 -599
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
- package/src/_contexts.ts +37 -32
- package/src/_storage.ts +54 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unikvs",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.17",
|
|
4
4
|
"description": "A modular and portable KVS client implemented in TypeScript.",
|
|
5
5
|
"homepage": "https://tai-kun.github.io/unikvs/",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@tai-kun/valibot-extra-lab": "^0.0.5",
|
|
28
|
-
"@unikvs/core": "0.0.
|
|
28
|
+
"@unikvs/core": "0.0.17",
|
|
29
29
|
"abort-signal-utils": "^0.0.6",
|
|
30
30
|
"asyncmux": "^0.0.12",
|
|
31
31
|
"call-fn-once": "^0.0.12",
|
|
@@ -35,14 +35,14 @@
|
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@babel/plugin-proposal-decorators": "^8.0.2",
|
|
37
37
|
"@rolldown/plugin-babel": "^0.2.4",
|
|
38
|
-
"@unikvs/allow-repair": "0.0.
|
|
39
|
-
"@unikvs/checksum": "0.0.
|
|
40
|
-
"@unikvs/compression": "0.0.
|
|
41
|
-
"@unikvs/fs.node": "0.0.
|
|
42
|
-
"@unikvs/memory": "0.0.
|
|
43
|
-
"@unikvs/opfs": "0.0.
|
|
38
|
+
"@unikvs/allow-repair": "0.0.17",
|
|
39
|
+
"@unikvs/checksum": "0.0.17",
|
|
40
|
+
"@unikvs/compression": "0.0.17",
|
|
41
|
+
"@unikvs/fs.node": "0.0.17",
|
|
42
|
+
"@unikvs/memory": "0.0.17",
|
|
43
|
+
"@unikvs/opfs": "0.0.17",
|
|
44
44
|
"@unikvs/testing": "0.0.0",
|
|
45
|
-
"@unikvs/utils": "0.0.
|
|
45
|
+
"@unikvs/utils": "0.0.17",
|
|
46
46
|
"@vitest/browser-playwright": "5.0.5",
|
|
47
47
|
"@vitest/coverage-istanbul": "5.0.5",
|
|
48
48
|
"@vitest/coverage-v8": "5.0.5",
|
package/src/_contexts.ts
CHANGED
|
@@ -15,9 +15,9 @@ import {
|
|
|
15
15
|
type IStreamContext,
|
|
16
16
|
type IReadableStream,
|
|
17
17
|
type IPipelineContext,
|
|
18
|
+
type ITransferContext,
|
|
18
19
|
type ILifecycleContext,
|
|
19
20
|
type ITransformContext,
|
|
20
|
-
type VariablesSnapshot,
|
|
21
21
|
type IKeyedActionContext,
|
|
22
22
|
type IDecodeStreamContext,
|
|
23
23
|
type IEncodeStreamContext,
|
|
@@ -119,14 +119,9 @@ type PipelineContextInit = {
|
|
|
119
119
|
*/
|
|
120
120
|
class PipelineContext implements IPipelineContext {
|
|
121
121
|
/**
|
|
122
|
-
*
|
|
122
|
+
* 実行時変数のストアです。共有する場合は参照を共有します。
|
|
123
123
|
*/
|
|
124
|
-
readonly #
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* 読み取り専用の変数名の集合です。共有ストアの参照である場合があります。
|
|
128
|
-
*/
|
|
129
|
-
readonly #readonly: Set<string>;
|
|
124
|
+
readonly #store: VariablesStore;
|
|
130
125
|
|
|
131
126
|
/**
|
|
132
127
|
* コンテキストを作成します。
|
|
@@ -136,22 +131,25 @@ class PipelineContext implements IPipelineContext {
|
|
|
136
131
|
public constructor(init: PipelineContextInit) {
|
|
137
132
|
const { store } = init;
|
|
138
133
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
this.#data = store.data;
|
|
142
|
-
this.#readonly = store.readonly;
|
|
143
|
-
} else {
|
|
144
|
-
this.#data = new Map();
|
|
145
|
-
this.#readonly = new Set();
|
|
146
|
-
}
|
|
134
|
+
// 共有ストアを参照し、下流の変更が上流に見えるようにします。
|
|
135
|
+
this.#store = store ?? createVariablesStore();
|
|
147
136
|
|
|
148
137
|
const vars = normalizeVariablesInit(init.vars);
|
|
149
138
|
|
|
150
139
|
for (const [name, value] of vars) {
|
|
151
|
-
this.#data.set(name, value);
|
|
140
|
+
this.#store.data.set(name, value);
|
|
152
141
|
}
|
|
153
142
|
}
|
|
154
143
|
|
|
144
|
+
/**
|
|
145
|
+
* 共有する実行時変数のストアを取得します。
|
|
146
|
+
*
|
|
147
|
+
* @returns 実行時変数のストアを返します。
|
|
148
|
+
*/
|
|
149
|
+
public get store(): VariablesStore {
|
|
150
|
+
return this.#store;
|
|
151
|
+
}
|
|
152
|
+
|
|
155
153
|
/**
|
|
156
154
|
* 変数の値を読み取ります。
|
|
157
155
|
*
|
|
@@ -160,7 +158,7 @@ class PipelineContext implements IPipelineContext {
|
|
|
160
158
|
* @returns 変数の値を返します。
|
|
161
159
|
*/
|
|
162
160
|
public get(name: string): unknown {
|
|
163
|
-
return this.#data.get(name);
|
|
161
|
+
return this.#store.data.get(name);
|
|
164
162
|
}
|
|
165
163
|
|
|
166
164
|
/**
|
|
@@ -172,11 +170,11 @@ class PipelineContext implements IPipelineContext {
|
|
|
172
170
|
* @returns 自身を返します。
|
|
173
171
|
*/
|
|
174
172
|
public set(name: string, value: unknown): this {
|
|
175
|
-
if (this.#readonly.has(name)) {
|
|
173
|
+
if (this.#store.readonly.has(name)) {
|
|
176
174
|
throw new ReadonlyVariableError({ name });
|
|
177
175
|
}
|
|
178
176
|
|
|
179
|
-
this.#data.set(name, value);
|
|
177
|
+
this.#store.data.set(name, value);
|
|
180
178
|
|
|
181
179
|
return this;
|
|
182
180
|
}
|
|
@@ -190,24 +188,28 @@ class PipelineContext implements IPipelineContext {
|
|
|
190
188
|
* @returns 自身を返します。
|
|
191
189
|
*/
|
|
192
190
|
public setReadonly(name: string, value: unknown): this {
|
|
193
|
-
if (this.#readonly.has(name)) {
|
|
191
|
+
if (this.#store.readonly.has(name)) {
|
|
194
192
|
throw new ReadonlyVariableError({ name });
|
|
195
193
|
}
|
|
196
194
|
|
|
197
|
-
this.#data.set(name, value);
|
|
198
|
-
this.#readonly.add(name);
|
|
195
|
+
this.#store.data.set(name, value);
|
|
196
|
+
this.#store.readonly.add(name);
|
|
199
197
|
|
|
200
198
|
return this;
|
|
201
199
|
}
|
|
200
|
+
}
|
|
202
201
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
202
|
+
/**
|
|
203
|
+
* コンテキストが共有する実行時変数のストアを取得します。
|
|
204
|
+
*
|
|
205
|
+
* 外部実装のコンテキストは共有ストアを公開しないため、独立したストアを返します。
|
|
206
|
+
*
|
|
207
|
+
* @param context 対象のコンテキストです。
|
|
208
|
+
*
|
|
209
|
+
* @returns 実行時変数のストアを返します。
|
|
210
|
+
*/
|
|
211
|
+
export function getVariablesStore(context: IPipelineContext): VariablesStore {
|
|
212
|
+
return context instanceof PipelineContext ? context.store : createVariablesStore();
|
|
211
213
|
}
|
|
212
214
|
|
|
213
215
|
/**
|
|
@@ -748,7 +750,10 @@ type TransferContextInit<TAction extends "copy" | "move"> = KeyedActionContextIn
|
|
|
748
750
|
/**
|
|
749
751
|
* コピー・移動で共通のコンテキストです。
|
|
750
752
|
*/
|
|
751
|
-
class TransferContext<TAction extends "copy" | "move">
|
|
753
|
+
class TransferContext<TAction extends "copy" | "move">
|
|
754
|
+
extends KeyedActionContext<TAction>
|
|
755
|
+
implements ITransferContext
|
|
756
|
+
{
|
|
752
757
|
/**
|
|
753
758
|
* コピー先または移動先のキーです。
|
|
754
759
|
*/
|
package/src/_storage.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { IStorage, IReadableStream, IWritableStream } from "@unikvs/core";
|
|
|
2
2
|
import { asyncmux } from "asyncmux";
|
|
3
3
|
import { callFnOnce } from "call-fn-once";
|
|
4
4
|
|
|
5
|
+
import { CopyContext, MoveContext, getVariablesStore } from "./_contexts.js";
|
|
5
6
|
import { PluginLifecycle } from "./_plugin-lifecycle.js";
|
|
6
7
|
import { ReadableStreamSchema, WritableStreamSchema } from "./_streams.schemas.js";
|
|
7
8
|
import * as v from "./_valibot.js";
|
|
@@ -167,6 +168,27 @@ export default class UniKvsStorage {
|
|
|
167
168
|
throw new StorageIsNotOpenError({ name: this.name });
|
|
168
169
|
}
|
|
169
170
|
|
|
171
|
+
if (this.#io.copy === undefined) {
|
|
172
|
+
// copy 操作に伴う読み取りであることを伝えるために、必ず CopyContext を渡します。
|
|
173
|
+
const data = await this.#io.read(c);
|
|
174
|
+
|
|
175
|
+
if (c.key !== c.destinationKey) {
|
|
176
|
+
// copy 操作に伴う書き込みであることを伝えるために、必ず CopyContext を渡します。
|
|
177
|
+
// 書き込み先がコピー先になるように、キーを差し替えたコンテキストを作成します。
|
|
178
|
+
await this.#io.write(
|
|
179
|
+
new CopyContext({
|
|
180
|
+
key: c.destinationKey,
|
|
181
|
+
store: getVariablesStore(c),
|
|
182
|
+
signal: c.signal,
|
|
183
|
+
destinationKey: c.destinationKey,
|
|
184
|
+
}),
|
|
185
|
+
data,
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
|
|
170
192
|
await this.#io.copy(c);
|
|
171
193
|
}
|
|
172
194
|
|
|
@@ -180,6 +202,38 @@ export default class UniKvsStorage {
|
|
|
180
202
|
throw new StorageIsNotOpenError({ name: this.name });
|
|
181
203
|
}
|
|
182
204
|
|
|
205
|
+
if (this.#io.move === undefined) {
|
|
206
|
+
if (c.key === c.destinationKey) {
|
|
207
|
+
// move 操作に伴う読み取りであることを伝えるために、必ず MoveContext を渡します。
|
|
208
|
+
await this.#io.read(c);
|
|
209
|
+
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (this.#io.copy === undefined) {
|
|
214
|
+
const data = await this.#io.read(c);
|
|
215
|
+
// move 操作に伴う書き込みであることを伝えるために、必ず MoveContext を渡します。
|
|
216
|
+
// 書き込み先が移動先になるように、キーを差し替えたコンテキストを作成します。
|
|
217
|
+
await this.#io.write(
|
|
218
|
+
new MoveContext({
|
|
219
|
+
key: c.destinationKey,
|
|
220
|
+
store: getVariablesStore(c),
|
|
221
|
+
signal: c.signal,
|
|
222
|
+
destinationKey: c.destinationKey,
|
|
223
|
+
}),
|
|
224
|
+
data,
|
|
225
|
+
);
|
|
226
|
+
} else {
|
|
227
|
+
// move 操作に伴う複製であることを伝えるために、必ず MoveContext を渡します。
|
|
228
|
+
await this.#io.copy(c);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// move 操作に伴う削除であることを伝えるために、必ず MoveContext を渡します。
|
|
232
|
+
await this.#io.delete(c);
|
|
233
|
+
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
183
237
|
await this.#io.move(c);
|
|
184
238
|
}
|
|
185
239
|
|