unikvs 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/LICENSE +21 -0
  2. package/dist/src/core/_assign-context.d.ts +3 -0
  3. package/dist/src/core/_assign-context.d.ts.map +1 -0
  4. package/dist/src/core/_assign-context.js +3 -0
  5. package/dist/src/core/_combine-signals.d.ts +3 -0
  6. package/dist/src/core/_combine-signals.d.ts.map +1 -0
  7. package/dist/src/core/_combine-signals.js +34 -0
  8. package/dist/src/core/_is-iterable.d.ts +2 -0
  9. package/dist/src/core/_is-iterable.d.ts.map +1 -0
  10. package/dist/src/core/_is-iterable.js +3 -0
  11. package/dist/src/core/_is-plain-object.d.ts +2 -0
  12. package/dist/src/core/_is-plain-object.d.ts.map +1 -0
  13. package/dist/src/core/_is-plain-object.js +7 -0
  14. package/dist/src/core/_logger.d.ts +3 -0
  15. package/dist/src/core/_logger.d.ts.map +1 -0
  16. package/dist/src/core/_logger.js +3 -0
  17. package/dist/src/core/_merge-context.d.ts +3 -0
  18. package/dist/src/core/_merge-context.d.ts.map +1 -0
  19. package/dist/src/core/_merge-context.js +4 -0
  20. package/dist/src/core/_to-context.d.ts +7 -0
  21. package/dist/src/core/_to-context.d.ts.map +1 -0
  22. package/dist/src/core/_to-context.js +42 -0
  23. package/dist/src/core/_to-value-stream.d.ts +4 -0
  24. package/dist/src/core/_to-value-stream.d.ts.map +1 -0
  25. package/dist/src/core/_to-value-stream.js +38 -0
  26. package/dist/src/core/_with-readable-stream-from.d.ts +6 -0
  27. package/dist/src/core/_with-readable-stream-from.d.ts.map +1 -0
  28. package/dist/src/core/_with-readable-stream-from.js +58 -0
  29. package/dist/src/core/context.types.d.ts +5 -0
  30. package/dist/src/core/context.types.d.ts.map +1 -0
  31. package/dist/src/core/context.types.js +1 -0
  32. package/dist/src/core/errors.d.ts +13 -0
  33. package/dist/src/core/errors.d.ts.map +1 -0
  34. package/dist/src/core/errors.js +20 -0
  35. package/dist/src/core/index.d.ts +15 -0
  36. package/dist/src/core/index.d.ts.map +1 -0
  37. package/dist/src/core/index.js +4 -0
  38. package/dist/src/core/plugin.types.d.ts +8 -0
  39. package/dist/src/core/plugin.types.d.ts.map +1 -0
  40. package/dist/src/core/plugin.types.js +1 -0
  41. package/dist/src/core/storage.types.d.ts +22 -0
  42. package/dist/src/core/storage.types.d.ts.map +1 -0
  43. package/dist/src/core/storage.types.js +1 -0
  44. package/dist/src/core/to-readable-stream.d.ts +2 -0
  45. package/dist/src/core/to-readable-stream.d.ts.map +1 -0
  46. package/dist/src/core/to-readable-stream.js +4 -0
  47. package/dist/src/core/transformer.types.d.ts +18 -0
  48. package/dist/src/core/transformer.types.d.ts.map +1 -0
  49. package/dist/src/core/transformer.types.js +1 -0
  50. package/dist/src/core/unikvs-config.d.ts +82 -0
  51. package/dist/src/core/unikvs-config.d.ts.map +1 -0
  52. package/dist/src/core/unikvs-config.js +49 -0
  53. package/dist/src/core/unikvs.d.ts +73 -0
  54. package/dist/src/core/unikvs.d.ts.map +1 -0
  55. package/dist/src/core/unikvs.js +678 -0
  56. package/dist/src/core/utils.types.d.ts +3 -0
  57. package/dist/src/core/utils.types.d.ts.map +1 -0
  58. package/dist/src/core/utils.types.js +1 -0
  59. package/dist/src/core/value-stream.types.d.ts +4 -0
  60. package/dist/src/core/value-stream.types.d.ts.map +1 -0
  61. package/dist/src/core/value-stream.types.js +1 -0
  62. package/dist/src/destinations/memory-storage.d.ts +17 -0
  63. package/dist/src/destinations/memory-storage.d.ts.map +1 -0
  64. package/dist/src/destinations/memory-storage.js +113 -0
  65. package/dist/src/types/storage.d.ts +5 -0
  66. package/dist/src/types/storage.d.ts.map +1 -0
  67. package/dist/src/types/storage.js +1 -0
  68. package/dist/src/types/transformer.d.ts +5 -0
  69. package/dist/src/types/transformer.d.ts.map +1 -0
  70. package/dist/src/types/transformer.js +1 -0
  71. package/package.json +69 -6
  72. package/src/core/_assign-context.ts +5 -0
  73. package/src/core/_combine-signals.ts +40 -0
  74. package/src/core/_is-iterable.ts +3 -0
  75. package/src/core/_is-plain-object.ts +11 -0
  76. package/src/core/_logger.ts +5 -0
  77. package/src/core/_merge-context.ts +9 -0
  78. package/src/core/_to-context.ts +59 -0
  79. package/src/core/_to-value-stream.ts +41 -0
  80. package/src/core/_with-readable-stream-from.ts +70 -0
  81. package/src/core/context.types.ts +7 -0
  82. package/src/core/errors.ts +37 -0
  83. package/src/core/index.ts +23 -0
  84. package/src/core/plugin.types.ts +10 -0
  85. package/src/core/storage.types.ts +53 -0
  86. package/src/core/to-readable-stream.ts +7 -0
  87. package/src/core/transformer.types.ts +110 -0
  88. package/src/core/unikvs-config.ts +230 -0
  89. package/src/core/unikvs.ts +740 -0
  90. package/src/core/utils.types.ts +3 -0
  91. package/src/core/value-stream.types.ts +3 -0
  92. package/src/destinations/memory-storage.ts +160 -0
  93. package/src/types/storage.ts +5 -0
  94. package/src/types/transformer.ts +5 -0
  95. package/README.md +0 -45
@@ -0,0 +1 @@
1
+ {"version":3,"file":"value-stream.types.d.ts","sourceRoot":"","sources":["../../../src/core/value-stream.types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW,CAAC,CAAC,CAAE,SAAQ,cAAc,CAAC,CAAC,CAAC;IACvD,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,mBAAmB,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;CACtE"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ import type { IStorage, Key } from "../core/storage.types.js";
2
+ type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;
3
+ type Chunk = ArrayBuffer | TypedArray;
4
+ export default class MemoryStorage implements IStorage {
5
+ readonly isOpen: boolean;
6
+ private store;
7
+ constructor();
8
+ write(key: Key, data: any): void;
9
+ getWritable(key: Key): WritableStream<Chunk>;
10
+ read(key: Key): any;
11
+ getReadable(key: Key): ReadableStream;
12
+ exists(key: Key): boolean;
13
+ delete(key: Key): void;
14
+ clear(): void;
15
+ }
16
+ export {};
17
+ //# sourceMappingURL=memory-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-storage.d.ts","sourceRoot":"","sources":["../../../src/destinations/memory-storage.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAG9D,KAAK,UAAU,GACX,SAAS,GACT,UAAU,GACV,iBAAiB,GACjB,UAAU,GACV,WAAW,GACX,UAAU,GACV,WAAW,GACX,YAAY,GACZ,YAAY,GACZ,aAAa,GACb,cAAc,CAAC;AAEnB,KAAK,KAAK,GAAG,WAAW,GAAG,UAAU,CAAC;AAYtC,MAAM,CAAC,OAAO,OAAO,aAAc,YAAW,QAAQ;IACpD,SAAgB,MAAM,EAAE,OAAO,CAAQ;IAEvC,OAAO,CAAC,KAAK,CAAgB;;IAMtB,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAIhC,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,cAAc,CAAC,KAAK,CAAC;IA8B5C,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG;IAkDnB,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,cAAc;IAoBrC,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO;IAQzB,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAItB,KAAK,IAAI,IAAI;CAGrB"}
@@ -0,0 +1,113 @@
1
+ import getType from "type-name";
2
+ import { TypeError } from "../core/errors.js";
3
+ class Chunks extends Array {
4
+ }
5
+ function isTypedArray(x) {
6
+ return ArrayBuffer.isView(x) && !(x instanceof DataView);
7
+ }
8
+ function isArrayBuffer(x) {
9
+ return x instanceof ArrayBuffer;
10
+ }
11
+ export default class MemoryStorage {
12
+ constructor() {
13
+ this.isOpen = true;
14
+ this.store = new Map();
15
+ }
16
+ write(key, data) {
17
+ this.store.set(key, data);
18
+ }
19
+ getWritable(key) {
20
+ const chunks = new Chunks();
21
+ let firstChunk = null;
22
+ return new WritableStream({
23
+ write: (chunk) => {
24
+ if (!isTypedArray(chunk) && !isArrayBuffer(chunk)) {
25
+ throw new TypeError({
26
+ actualValue: chunk,
27
+ expectedType: "ArrayBuffer | TypedArray",
28
+ });
29
+ }
30
+ if (firstChunk === null) {
31
+ firstChunk = chunk;
32
+ }
33
+ else if (!(chunk instanceof firstChunk.constructor)) {
34
+ throw new TypeError({
35
+ actualValue: chunk,
36
+ expectedType: getType(firstChunk),
37
+ });
38
+ }
39
+ chunks.push(chunk);
40
+ },
41
+ close: () => {
42
+ this.store.set(key, chunks);
43
+ },
44
+ });
45
+ }
46
+ read(key) {
47
+ const data = this.store.get(key);
48
+ if (data instanceof Chunks) {
49
+ if (data.length === 0) {
50
+ return null;
51
+ }
52
+ const firstChunk = data[0];
53
+ if (isTypedArray(firstChunk)) {
54
+ const chunks = data;
55
+ const Constructor = firstChunk.constructor;
56
+ const totalLength = chunks.reduce((len, chunk) => len + chunk.length, 0);
57
+ const mergedArray = new Constructor(totalLength);
58
+ let offset = 0;
59
+ for (const chunk of chunks) {
60
+ mergedArray.set(chunk, offset);
61
+ offset += chunk.length;
62
+ }
63
+ return mergedArray;
64
+ }
65
+ if (isArrayBuffer(firstChunk)) {
66
+ const chunks = data;
67
+ const totalLength = data.reduce((len, chunk) => len + chunk.byteLength, 0);
68
+ const mergedArray = new Uint8Array(totalLength);
69
+ let offset = 0;
70
+ for (const chunk of chunks) {
71
+ mergedArray.set(new Uint8Array(chunk), offset);
72
+ offset += chunk.byteLength;
73
+ }
74
+ return mergedArray.buffer;
75
+ }
76
+ throw new TypeError({
77
+ actualValue: firstChunk,
78
+ expectedType: "ArrayBuffer | TypedArray",
79
+ });
80
+ }
81
+ return data;
82
+ }
83
+ getReadable(key) {
84
+ const data = this.store.get(key);
85
+ return new ReadableStream({
86
+ start(controller) {
87
+ if (data !== undefined) {
88
+ if (data instanceof Chunks) {
89
+ for (const chunk of data) {
90
+ controller.enqueue(chunk);
91
+ }
92
+ }
93
+ else {
94
+ controller.enqueue(data);
95
+ }
96
+ }
97
+ controller.close();
98
+ },
99
+ });
100
+ }
101
+ exists(key) {
102
+ return this.store.has(key);
103
+ }
104
+ // public keys(): Iterable<Key> {
105
+ // return this.store.keys();
106
+ // }
107
+ delete(key) {
108
+ this.store.delete(key);
109
+ }
110
+ clear() {
111
+ this.store.clear();
112
+ }
113
+ }
@@ -0,0 +1,5 @@
1
+ export type { Context } from "../core/context.types.js";
2
+ export type { IPlugin } from "../core/plugin.types.js";
3
+ export type { MaybePromise } from "../core/utils.types.js";
4
+ export type * from "../core/storage.types.js";
5
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/types/storage.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACxD,YAAY,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,mBAAmB,0BAA0B,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ export type { Context } from "../core/context.types.js";
2
+ export type { IPlugin } from "../core/plugin.types.js";
3
+ export type { MaybePromise } from "../core/utils.types.js";
4
+ export type * from "../core/transformer.types.js";
5
+ //# sourceMappingURL=transformer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transformer.d.ts","sourceRoot":"","sources":["../../../src/types/transformer.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACxD,YAAY,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACvD,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,mBAAmB,8BAA8B,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,10 +1,73 @@
1
1
  {
2
2
  "name": "unikvs",
3
- "version": "0.0.2",
4
- "description": "OIDC trusted publishing setup package for unikvs",
3
+ "version": "0.0.3",
4
+ "description": "",
5
5
  "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
9
- ]
6
+ "kv",
7
+ "kvs"
8
+ ],
9
+ "homepage": "https://github.com/tai-kun/unikvs",
10
+ "license": "MIT",
11
+ "author": "tai-kun",
12
+ "repository": {
13
+ "url": "https://github.com/tai-kun/unikvs"
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "src",
18
+ "package.json",
19
+ "LICENSE"
20
+ ],
21
+ "type": "module",
22
+ "sideEffects": false,
23
+ "main": "./dist/src/core/index.js",
24
+ "module": "./dist/src/core/index.js",
25
+ "types": "./dist/src/core/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/src/core/index.d.ts",
29
+ "import": "./dist/src/core/index.js",
30
+ "require": "./dist/src/core/index.js"
31
+ },
32
+ "./storage/memory": {
33
+ "types": "./dist/src/destinations/memory-storage.d.ts",
34
+ "import": "./dist/src/destinations/memory-storage.js",
35
+ "require": "./dist/src/destinations/memory-storage.js"
36
+ },
37
+ "./types/storage": {
38
+ "types": "./dist/src/types/storage.d.ts",
39
+ "import": "./dist/src/types/storage.js",
40
+ "require": "./dist/src/types/storage.js"
41
+ },
42
+ "./types/transformer": {
43
+ "types": "./dist/src/types/transformer.d.ts",
44
+ "import": "./dist/src/types/transformer.js",
45
+ "require": "./dist/src/types/transformer.js"
46
+ }
47
+ },
48
+ "scripts": {
49
+ "build": "tsc --project ./.config/tsconfig.build.json"
50
+ },
51
+ "dependencies": {
52
+ "@logtape/logtape": "^2.0.5",
53
+ "asyncmux": "^0.0.5",
54
+ "i18n-error-base": "^0.0.3",
55
+ "type-name": "^2.0.2"
56
+ },
57
+ "devDependencies": {
58
+ "@tsconfig/node22": "^22.0.5",
59
+ "@tsconfig/strictest": "^2.0.8",
60
+ "@types/filename-reserved-regex": "^3.0.0",
61
+ "@types/node": "^22.19.17",
62
+ "@types/type-name": "^1.0.32",
63
+ "@vitest/browser": "^4.1.2",
64
+ "@vitest/browser-playwright": "^4.1.2",
65
+ "npm-check-updates": "^20.0.0",
66
+ "oxfmt": "^0.44.0",
67
+ "oxlint": "^1.59.0",
68
+ "oxlint-tsgolint": "^0.20.0",
69
+ "playwright": "^1.59.1",
70
+ "typescript": "^6.0.2",
71
+ "vitest": "^4.1.2"
72
+ }
10
73
  }
@@ -0,0 +1,5 @@
1
+ import type { Context } from "./context.types.js";
2
+
3
+ export default function assignContext(target: Context, source: Readonly<Context>): void {
4
+ Object.assign(target, source);
5
+ }
@@ -0,0 +1,40 @@
1
+ let combineSignals: (signals: readonly (AbortSignal | null | undefined)[]) => AbortSignal;
2
+
3
+ if ("any" in AbortSignal && typeof AbortSignal.any === "function") {
4
+ const AbortSignalAny = AbortSignal.any.bind(AbortSignal);
5
+ combineSignals = function combineSignals(inputSignals) {
6
+ const signals = inputSignals.filter((s) => s != null);
7
+ return AbortSignalAny(signals);
8
+ };
9
+ } else {
10
+ combineSignals = function combineSignals(inputSignals) {
11
+ const ac = new AbortController();
12
+ const signals: AbortSignal[] = [];
13
+
14
+ for (const signal of inputSignals) {
15
+ if (signal?.aborted) {
16
+ ac.abort(signal.reason);
17
+ return ac.signal;
18
+ }
19
+
20
+ if (signal) {
21
+ signals.push(signal);
22
+ }
23
+ }
24
+
25
+ function handleAbort(this: AbortSignal): void {
26
+ ac.abort(this.reason);
27
+ for (const signal of signals) {
28
+ signal.removeEventListener("abort", handleAbort);
29
+ }
30
+ }
31
+
32
+ for (const signal of signals) {
33
+ signal.addEventListener("abort", handleAbort, { once: true });
34
+ }
35
+
36
+ return ac.signal;
37
+ };
38
+ }
39
+
40
+ export default combineSignals;
@@ -0,0 +1,3 @@
1
+ export default function isIterable(o: object): o is Iterable<unknown> | AsyncIterable<unknown> {
2
+ return Symbol.iterator in o || Symbol.asyncIterator in o;
3
+ }
@@ -0,0 +1,11 @@
1
+ const ObjectConstructor = Object;
2
+
3
+ // oxlint-disable typescript-eslint/unbound-method
4
+ const ObjectToString = ObjectConstructor.prototype.toString;
5
+
6
+ export default function isPlainObject(value: any): value is Record<keyof any, unknown> {
7
+ return (
8
+ ObjectToString.call(value) === "[object Object]" &&
9
+ (value.constructor === ObjectConstructor || value.constructor === undefined)
10
+ );
11
+ }
@@ -0,0 +1,5 @@
1
+ import { getLogger } from "@logtape/logtape";
2
+
3
+ const log = /*#__PURE__*/ getLogger("unikvs");
4
+
5
+ export default log;
@@ -0,0 +1,9 @@
1
+ import toContext from "./_to-context.js";
2
+ import type { Context, ContextSource } from "./context.types.js";
3
+
4
+ export default function mergeContext(
5
+ a: Readonly<Context>,
6
+ b: Readonly<Context> | ContextSource | undefined,
7
+ ): Context {
8
+ return b ? { ...a, ...toContext(b) } : a;
9
+ }
@@ -0,0 +1,59 @@
1
+ import isIterable from "./_is-iterable.js";
2
+ import isPlainObject from "./_is-plain-object.js";
3
+ import type { Context, ContextKeyValuePair, ContextSource } from "./context.types.js";
4
+ import { TypeError } from "./errors.js";
5
+
6
+ function isValidKeyValuePair(x: unknown): x is ContextKeyValuePair {
7
+ return (
8
+ Array.isArray(x) &&
9
+ x.length === 2 &&
10
+ (typeof x[0] === "string" || typeof x[0] === "number" || typeof x[0] === "symbol") &&
11
+ 1 in x
12
+ );
13
+ }
14
+
15
+ function iterableToContext(iterable: Iterable<ContextKeyValuePair>): Context {
16
+ const ctx: Context = {};
17
+ for (const item of iterable) {
18
+ if (!isValidKeyValuePair(item)) {
19
+ throw new TypeError({
20
+ actualValue: item satisfies never,
21
+ expectedType: "ContextKeyValuePair",
22
+ });
23
+ }
24
+
25
+ const [key, value] = item;
26
+ ctx[key] = value;
27
+ }
28
+
29
+ return ctx;
30
+ }
31
+
32
+ function contextToContext(ctx: Readonly<Context>, copy: boolean): Readonly<Context> {
33
+ if (copy) {
34
+ ctx = { ...ctx };
35
+ }
36
+
37
+ return ctx;
38
+ }
39
+
40
+ function toContext(source: ContextSource, options: { copy: true }): Context;
41
+
42
+ function toContext(source: ContextSource): Readonly<Context>;
43
+
44
+ function toContext(source: ContextSource, options: { copy: boolean } = { copy: false }) {
45
+ if (isIterable(source)) {
46
+ return iterableToContext(source);
47
+ }
48
+
49
+ if (isPlainObject(source)) {
50
+ return contextToContext(source, options.copy);
51
+ }
52
+
53
+ throw new TypeError({
54
+ actualValue: source satisfies never,
55
+ expectedType: "ContextSource",
56
+ });
57
+ }
58
+
59
+ export default toContext;
@@ -0,0 +1,41 @@
1
+ import log from "./_logger.js";
2
+ import type { IReadableStream } from "./storage.types.js";
3
+ import type { ValueStream } from "./value-stream.types.js";
4
+
5
+ export default function toValueStream<T>(r: IReadableStream<T>): ValueStream<T> {
6
+ if (Symbol.asyncIterator in r) {
7
+ return r;
8
+ }
9
+
10
+ return Object.assign(r, {
11
+ async *[Symbol.asyncIterator](this: IReadableStream<T>) {
12
+ const r = this.getReader();
13
+ try {
14
+ while (true) {
15
+ const { done, value } = await r.read();
16
+ if (done) {
17
+ break;
18
+ }
19
+
20
+ yield value;
21
+ }
22
+ } catch (ex) {
23
+ try {
24
+ await r.cancel(ex);
25
+ } catch (ex) {
26
+ log.error`Failed to cancel reader: ${ex}`;
27
+ }
28
+
29
+ throw ex;
30
+ } finally {
31
+ try {
32
+ r.releaseLock();
33
+ } catch (ex) {
34
+ log.error`Failed to release reader's lock: ${ex}`;
35
+ }
36
+ }
37
+
38
+ return undefined;
39
+ },
40
+ });
41
+ }
@@ -0,0 +1,70 @@
1
+ import isIterable from "./_is-iterable.js";
2
+ import log from "./_logger.js";
3
+ import { TypeError } from "./errors.js";
4
+
5
+ interface ReadableStreamWithFrom extends ReadableStream {
6
+ from<T>(iterable: Iterable<T> | AsyncIterable<T>): ReadableStream<T>;
7
+ }
8
+
9
+ export default function withReadableStreamFrom<T>(
10
+ cb: (ReadableStream: ReadableStreamWithFrom) => T,
11
+ ): T {
12
+ if ("from" in ReadableStream) {
13
+ return cb(ReadableStream as any);
14
+ }
15
+
16
+ try {
17
+ (ReadableStream as any).from = function ReadableStreamFrom<T>(
18
+ iterable: Iterable<T> | AsyncIterable<T>,
19
+ ): ReadableStream<T> {
20
+ if (!isIterable(iterable)) {
21
+ throw new TypeError({
22
+ actualValue: iterable satisfies never,
23
+ expectedType: "(Iterable | AsyncIterable)",
24
+ });
25
+ }
26
+
27
+ const iter: AsyncIterator<T> =
28
+ Symbol.asyncIterator in iterable
29
+ ? iterable[Symbol.asyncIterator]()
30
+ : (async function* (iterable) {
31
+ yield* iterable;
32
+ })(iterable);
33
+
34
+ let done = false;
35
+
36
+ return new ReadableStream<T>({
37
+ async pull(controller) {
38
+ if (done) {
39
+ return;
40
+ }
41
+
42
+ try {
43
+ const result = await iter.next();
44
+ if (result.done) {
45
+ done = true;
46
+ controller.close();
47
+ } else {
48
+ controller.enqueue(result.value);
49
+ }
50
+ } catch (ex) {
51
+ done = true;
52
+ controller.error(ex);
53
+ }
54
+ },
55
+ async cancel(reason) {
56
+ done = true;
57
+ try {
58
+ await iter.return?.(reason);
59
+ } catch (ex) {
60
+ log.error`Failed to close iterator: ${ex}`;
61
+ }
62
+ },
63
+ });
64
+ };
65
+
66
+ return cb(ReadableStream as any);
67
+ } finally {
68
+ delete (ReadableStream as any).from;
69
+ }
70
+ }
@@ -0,0 +1,7 @@
1
+ import type { ValueOf } from "./utils.types.js";
2
+
3
+ export type Context = Record<keyof any, unknown>;
4
+
5
+ export type ContextKeyValuePair = readonly [key: keyof Context, value: ValueOf<Context>];
6
+
7
+ export type ContextSource = Readonly<Context> | Iterable<ContextKeyValuePair>;
@@ -0,0 +1,37 @@
1
+ import { type ErrorMeta, I18nErrorBase, setErrorMessage } from "i18n-error-base";
2
+ import getTypeName from "type-name";
3
+
4
+ export { setErrorMessage };
5
+
6
+ export class ErrorBase<
7
+ TMeta extends ErrorMeta | undefined = ErrorMeta | undefined,
8
+ > extends I18nErrorBase<TMeta> {}
9
+
10
+ export type TypeErrorMeta = {
11
+ expectedType: string;
12
+ actualValue: unknown;
13
+ actualType: string;
14
+ };
15
+
16
+ export class TypeError extends ErrorBase<TypeErrorMeta> {
17
+ static {
18
+ this.prototype.name = "UniKvsTypeError";
19
+ }
20
+
21
+ public constructor(meta: Readonly<Pick<TypeErrorMeta, "expectedType" | "actualValue">>) {
22
+ super(
23
+ {
24
+ actualType: getTypeName(meta.actualValue),
25
+ actualValue: meta.actualValue,
26
+ expectedType: meta.expectedType,
27
+ },
28
+ ({ expectedType, actualType }) => `Expected type ${expectedType}, but got ${actualType}`,
29
+ );
30
+ }
31
+ }
32
+
33
+ /*#__PURE__*/ setErrorMessage(
34
+ TypeError,
35
+ ({ expectedType, actualType }) => `型 ${expectedType} を期待しましたが、${actualType} を得ました`,
36
+ "ja",
37
+ );
@@ -0,0 +1,23 @@
1
+ export type * from "./context.types.js";
2
+
3
+ export type { TypeErrorMeta } from "./errors.js";
4
+ export { setErrorMessage, TypeError, ErrorBase } from "./errors.js";
5
+
6
+ export type * from "./plugin.types.js";
7
+
8
+ export type * from "./storage.types.js";
9
+
10
+ export type * from "./to-readable-stream.js";
11
+ export { default as toReadableStream } from "./to-readable-stream.js";
12
+
13
+ export type * from "./transformer.types.js";
14
+
15
+ export type * from "./unikvs-config.js";
16
+ export { default as UniKvsConfig } from "./unikvs-config.js";
17
+
18
+ export type * from "./unikvs.js";
19
+ export { default as UniKvs } from "./unikvs.js";
20
+
21
+ export type * from "./utils.types.js";
22
+
23
+ export type * from "./value-stream.types.js";
@@ -0,0 +1,10 @@
1
+ import type { Context } from "./context.types.js";
2
+ import type { MaybePromise } from "./utils.types.js";
3
+
4
+ export interface IPlugin {
5
+ readonly isOpen: boolean;
6
+
7
+ open?(signal: AbortSignal, context: Context): MaybePromise<void>;
8
+
9
+ close?(signal: AbortSignal, context: Context): MaybePromise<void>;
10
+ }
@@ -0,0 +1,53 @@
1
+ import type { Context } from "./context.types.js";
2
+ import type { IPlugin } from "./plugin.types.js";
3
+ import type { MaybePromise } from "./utils.types.js";
4
+
5
+ export type Key = string;
6
+
7
+ export interface IWritableStream<TData = any> extends WritableStream<TData> {}
8
+
9
+ export interface IWritableStreamStorage<TData = any> {
10
+ getWritable(
11
+ key: Key,
12
+ signal: AbortSignal,
13
+ context: Context,
14
+ ): MaybePromise<IWritableStream<TData>>;
15
+ }
16
+
17
+ export interface IReadableStream<TData = any> extends ReadableStream<TData> {}
18
+
19
+ export interface IReadableStreamStorage<TData = any> {
20
+ getReadable(
21
+ key: Key,
22
+ signal: AbortSignal,
23
+ context: Context,
24
+ ): MaybePromise<IReadableStream<TData>>;
25
+ }
26
+
27
+ export interface IStorage<
28
+ TWriteDataInput = any,
29
+ TReadDataOutput = TWriteDataInput,
30
+ TWriteChunkInput = TWriteDataInput extends ArrayBufferLike | ArrayBufferView
31
+ ? TWriteDataInput
32
+ : any,
33
+ TReadChunkOutput = TWriteChunkInput,
34
+ >
35
+ extends
36
+ IPlugin,
37
+ Partial<IWritableStreamStorage<TWriteChunkInput>>,
38
+ Partial<IReadableStreamStorage<TReadChunkOutput>> {
39
+ write(key: Key, data: TWriteDataInput, signal: AbortSignal, context: Context): MaybePromise<void>;
40
+
41
+ read(key: Key, signal: AbortSignal, context: Context): MaybePromise<TReadDataOutput>;
42
+
43
+ exists(key: Key, signal: AbortSignal, context: Context): MaybePromise<boolean>;
44
+
45
+ // keys(
46
+ // signal: AbortSignal,
47
+ // context: Context,
48
+ // ): MaybePromise<AsyncIterable<Key> | Iterable<MaybePromise<Key>> | ArrayLike<MaybePromise<Key>>>;
49
+
50
+ delete(key: Key, signal: AbortSignal, context: Context): MaybePromise<void>;
51
+
52
+ clear(signal: AbortSignal, context: Context): MaybePromise<void>;
53
+ }
@@ -0,0 +1,7 @@
1
+ import withReadableStreamFrom from "./_with-readable-stream-from.js";
2
+
3
+ export default function toReadableStream<T>(
4
+ iterable: Iterable<T> | AsyncIterable<T>,
5
+ ): ReadableStream<T> {
6
+ return withReadableStreamFrom((ReadableStream) => ReadableStream.from(iterable));
7
+ }