@raubjo/architect-core 0.1.0 → 0.1.2

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 (67) hide show
  1. package/README.md +216 -0
  2. package/bun.lock +82 -1
  3. package/package.json +55 -6
  4. package/src/cache/cache.ts +2 -2
  5. package/src/cache/manager.ts +93 -83
  6. package/src/config/adapters/esm.ts +26 -0
  7. package/src/config/clone.ts +5 -5
  8. package/src/config/env.global.d.ts +2 -1
  9. package/src/config/env.ts +53 -55
  10. package/src/config/env_test.helpers.ts +58 -0
  11. package/src/config/repository.ts +180 -142
  12. package/src/container/adapters/builtin.ts +347 -0
  13. package/src/container/adapters/inversify.ts +123 -0
  14. package/src/container/contract.ts +58 -0
  15. package/src/container/runtime.ts +149 -0
  16. package/src/filesystem/adapters/local.ts +92 -83
  17. package/src/filesystem/adapters/local_test.helpers.ts +50 -0
  18. package/src/filesystem/filesystem.ts +11 -11
  19. package/src/foundation/application.ts +205 -175
  20. package/src/foundation/application_test.helpers.ts +31 -0
  21. package/src/index.ts +15 -6
  22. package/src/react.ts +2 -0
  23. package/src/renderers/adapters/react.tsx +35 -0
  24. package/src/renderers/adapters/solid.tsx +32 -0
  25. package/src/renderers/adapters/svelte.ts +70 -0
  26. package/src/renderers/adapters/vue.ts +28 -0
  27. package/src/renderers/contract.ts +15 -0
  28. package/src/runtimes/react.tsx +24 -12
  29. package/src/runtimes/solid.tsx +30 -0
  30. package/src/runtimes/svelte.ts +23 -0
  31. package/src/runtimes/vue.ts +20 -0
  32. package/src/solid.ts +2 -0
  33. package/src/storage/adapters/contract.ts +10 -0
  34. package/src/storage/adapters/indexed-db.ts +170 -156
  35. package/src/storage/adapters/local-storage.ts +34 -34
  36. package/src/storage/adapters/memory.ts +25 -25
  37. package/src/storage/manager.ts +65 -61
  38. package/src/storage/storage.ts +1 -8
  39. package/src/support/facades/cache.ts +40 -40
  40. package/src/support/facades/config.ts +78 -48
  41. package/src/support/facades/facade.ts +43 -28
  42. package/src/support/facades/storage.ts +41 -41
  43. package/src/support/service-provider.ts +11 -11
  44. package/src/support/str.ts +94 -90
  45. package/src/support/str_test.helpers.ts +26 -0
  46. package/src/svelte.ts +2 -0
  47. package/src/vue.ts +2 -0
  48. package/tsconfig.json +16 -0
  49. package/coverage/lcov.info +0 -1078
  50. package/src/config/app.ts +0 -5
  51. package/src/rendering/adapters/react.tsx +0 -27
  52. package/src/rendering/renderer.ts +0 -13
  53. package/src/support/providers/config-service-provider.ts +0 -19
  54. package/tests/application.test.ts +0 -236
  55. package/tests/cache-facade.test.ts +0 -45
  56. package/tests/cache.test.ts +0 -68
  57. package/tests/config-clone.test.ts +0 -31
  58. package/tests/config-env.test.ts +0 -88
  59. package/tests/config-facade.test.ts +0 -96
  60. package/tests/config-repository.test.ts +0 -124
  61. package/tests/facade-base.test.ts +0 -80
  62. package/tests/filesystem.test.ts +0 -81
  63. package/tests/runtime-react.test.tsx +0 -37
  64. package/tests/service-provider.test.ts +0 -23
  65. package/tests/storage-facade.test.ts +0 -46
  66. package/tests/storage.test.ts +0 -264
  67. package/tests/str.test.ts +0 -73
@@ -1,22 +1,34 @@
1
1
  import { createContext, useContext, type ReactNode } from "react";
2
- import type { Container } from "inversify";
2
+ import type {
3
+ ContainerContract,
4
+ ContainerIdentifier,
5
+ } from "@/container/contract";
3
6
 
4
- const ContainerContext = createContext<Container | null>(null);
7
+ const ContainerContext = createContext<ContainerContract | null>(null);
5
8
 
6
9
  type ApplicationProviderProps = {
7
- container: Container;
8
- children?: ReactNode;
10
+ container: ContainerContract;
11
+ children?: ReactNode;
9
12
  };
10
13
 
11
- export function ApplicationProvider({ container, children }: ApplicationProviderProps) {
12
- return <ContainerContext.Provider value={container}>{children}</ContainerContext.Provider>;
14
+ export function ApplicationProvider({
15
+ container,
16
+ children,
17
+ }: ApplicationProviderProps) {
18
+ return (
19
+ <ContainerContext.Provider value={container}>
20
+ {children}
21
+ </ContainerContext.Provider>
22
+ );
13
23
  }
14
24
 
15
- export function useService<T>(identifier: Parameters<Container["get"]>[0]): T {
16
- const container = useContext(ContainerContext);
17
- if (!container) {
18
- throw new Error("Application container is not available in React context.");
19
- }
25
+ export function useService<T>(identifier: ContainerIdentifier<T>): T {
26
+ const container = useContext(ContainerContext);
27
+ if (!container) {
28
+ throw new Error(
29
+ "Application container is not available in React context.",
30
+ );
31
+ }
20
32
 
21
- return container.get<T>(identifier);
33
+ return container.make<T>(identifier);
22
34
  }
@@ -0,0 +1,30 @@
1
+ import { createContext, createComponent, useContext, type JSX } from "solid-js";
2
+ import type {
3
+ ContainerContract,
4
+ ContainerIdentifier,
5
+ } from "@/container/contract";
6
+
7
+ const ContainerContext = createContext<ContainerContract | null>(null);
8
+
9
+ type ApplicationProviderProps = {
10
+ container: ContainerContract;
11
+ children?: JSX.Element | (() => JSX.Element);
12
+ };
13
+
14
+ export function ApplicationProvider(props: ApplicationProviderProps) {
15
+ return createComponent(ContainerContext.Provider, {
16
+ value: props.container,
17
+ children: props.children as never,
18
+ });
19
+ }
20
+
21
+ export function useService<T>(identifier: ContainerIdentifier<T>): T {
22
+ const container = useContext(ContainerContext);
23
+ if (!container) {
24
+ throw new Error(
25
+ "Application container is not available in Solid context.",
26
+ );
27
+ }
28
+
29
+ return container.make<T>(identifier);
30
+ }
@@ -0,0 +1,23 @@
1
+ import { getContext, setContext } from "svelte";
2
+ import type {
3
+ ContainerContract,
4
+ ContainerIdentifier,
5
+ } from "@/container/contract";
6
+
7
+ export const containerKey: unique symbol = Symbol("application.container");
8
+
9
+ export function provideContainer(container: ContainerContract): void {
10
+ setContext(containerKey, container);
11
+ }
12
+
13
+ export function useService<T>(identifier: ContainerIdentifier<T>): T {
14
+ const container =
15
+ getContext<ContainerContract | null>(containerKey) ?? null;
16
+ if (!container) {
17
+ throw new Error(
18
+ "Application container is not available in Svelte context.",
19
+ );
20
+ }
21
+
22
+ return container.make<T>(identifier);
23
+ }
@@ -0,0 +1,20 @@
1
+ import { inject, type InjectionKey } from "vue";
2
+ import type {
3
+ ContainerContract,
4
+ ContainerIdentifier,
5
+ } from "@/container/contract";
6
+
7
+ export const containerKey: InjectionKey<ContainerContract> = Symbol(
8
+ "application.container",
9
+ );
10
+
11
+ export function useService<T>(identifier: ContainerIdentifier<T>): T {
12
+ const container = inject(containerKey, null);
13
+ if (!container) {
14
+ throw new Error(
15
+ "Application container is not available in Vue context.",
16
+ );
17
+ }
18
+
19
+ return container.make<T>(identifier);
20
+ }
package/src/solid.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { ApplicationProvider, useService } from "./runtimes/solid";
2
+ export { default as Renderer } from "./renderers/adapters/solid";
@@ -0,0 +1,10 @@
1
+ export interface Adapter {
2
+ get<T = unknown>(key: string): Promise<T | null>;
3
+ set<T = unknown>(key: string, value: T): Promise<void>;
4
+ has(key: string): Promise<boolean>;
5
+ delete(key: string): Promise<void>;
6
+ clear(): Promise<void>;
7
+ keys(): Promise<string[]>;
8
+ }
9
+
10
+ export type Contract = Adapter;
@@ -1,180 +1,194 @@
1
- import MemoryStorageAdapter from "./memory";
2
- import type { StorageAdapter } from "../storage";
1
+ import MemoryStorageAdapter from "@/storage/adapters/memory";
2
+ import type { Adapter } from "@/storage/adapters/contract";
3
3
 
4
4
  type OpenFactory = Pick<IDBFactory, "open">;
5
5
 
6
- export default class IndexedDbAdapter implements StorageAdapter {
7
- protected fallback: StorageAdapter;
8
- protected name: string;
9
- protected factory: OpenFactory | null;
10
- protected dbPromise: Promise<IDBDatabase> | null;
11
-
12
- constructor(
13
- options: {
14
- factory?: OpenFactory | null;
15
- name?: string;
16
- fallback?: StorageAdapter;
17
- } = {},
18
- ) {
19
- this.factory = options.factory ?? (globalThis.indexedDB ?? null);
20
- this.name = options.name ?? "ioc-storage";
21
- this.fallback = options.fallback ?? new MemoryStorageAdapter();
22
- this.dbPromise = null;
23
- }
24
-
25
- protected req<T>(request: IDBRequest<T>): Promise<T> {
26
- return new Promise<T>((resolve, reject) => {
27
- request.onsuccess = () => resolve(request.result);
28
- request.onerror = () => reject(request.error ?? new Error("IndexedDB request failed."));
29
- });
30
- }
31
-
32
- protected openDb(): Promise<IDBDatabase> {
33
- if (this.dbPromise) {
34
- return this.dbPromise;
6
+ export default class IndexedDbAdapter implements Adapter {
7
+ protected fallback: Adapter;
8
+ protected name: string;
9
+ protected factory: OpenFactory | null;
10
+ protected dbPromise: Promise<IDBDatabase> | null;
11
+
12
+ constructor(
13
+ options: {
14
+ factory?: OpenFactory | null;
15
+ name?: string;
16
+ fallback?: Adapter;
17
+ } = {},
18
+ ) {
19
+ this.factory = options.factory ?? globalThis.indexedDB ?? null;
20
+ this.name = options.name ?? "ioc-storage";
21
+ this.fallback = options.fallback ?? new MemoryStorageAdapter();
22
+ this.dbPromise = null;
35
23
  }
36
24
 
37
- if (!this.factory) {
38
- return Promise.reject(new Error("IndexedDB is not available."));
25
+ protected req<T>(request: IDBRequest<T>): Promise<T> {
26
+ return new Promise<T>((resolve, reject) => {
27
+ request.onsuccess = () => resolve(request.result);
28
+ request.onerror = () =>
29
+ reject(request.error ?? new Error("IndexedDB request failed."));
30
+ });
39
31
  }
40
32
 
41
- this.dbPromise = new Promise<IDBDatabase>((resolve, reject) => {
42
- const request = this.factory?.open(this.name, 1);
43
- if (!request) {
44
- reject(new Error("IndexedDB open request could not be created."));
45
- return;
46
- }
47
-
48
- request.onupgradeneeded = () => {
49
- const db = request.result;
50
- if (!db.objectStoreNames.contains("kv")) {
51
- db.createObjectStore("kv");
33
+ protected openDb(): Promise<IDBDatabase> {
34
+ if (this.dbPromise) {
35
+ return this.dbPromise;
52
36
  }
53
- };
54
- request.onsuccess = () => resolve(request.result);
55
- request.onerror = () =>
56
- reject(request.error ?? new Error("IndexedDB database could not be opened."));
57
- });
58
37
 
59
- return this.dbPromise;
60
- }
38
+ if (!this.factory) {
39
+ return Promise.reject(new Error("IndexedDB is not available."));
40
+ }
61
41
 
62
- protected async withStore<T>(
63
- mode: IDBTransactionMode,
64
- action: (store: IDBObjectStore) => Promise<T>,
65
- ): Promise<T> {
66
- try {
67
- const db = await this.openDb();
68
- const tx = db.transaction("kv", mode);
69
- const store = tx.objectStore("kv");
70
- return await action(store);
71
- } catch (_error) {
72
- return actionFallback(this.fallback, mode, action);
42
+ this.dbPromise = new Promise<IDBDatabase>((resolve, reject) => {
43
+ const request = this.factory?.open(this.name, 1);
44
+ if (!request) {
45
+ reject(
46
+ new Error("IndexedDB open request could not be created."),
47
+ );
48
+ return;
49
+ }
50
+
51
+ request.onupgradeneeded = () => {
52
+ const db = request.result;
53
+ if (!db.objectStoreNames.contains("kv")) {
54
+ db.createObjectStore("kv");
55
+ }
56
+ };
57
+ request.onsuccess = () => resolve(request.result);
58
+ request.onerror = () =>
59
+ reject(
60
+ request.error ??
61
+ new Error("IndexedDB database could not be opened."),
62
+ );
63
+ });
64
+
65
+ return this.dbPromise;
66
+ }
67
+
68
+ protected async withStore<T>(
69
+ mode: IDBTransactionMode,
70
+ action: (store: IDBObjectStore) => Promise<T>,
71
+ ): Promise<T> {
72
+ try {
73
+ const db = await this.openDb();
74
+ const tx = db.transaction("kv", mode);
75
+ const store = tx.objectStore("kv");
76
+ return await action(store);
77
+ } catch (_error) {
78
+ return actionFallback(this.fallback, mode, action);
79
+ }
80
+ }
81
+
82
+ async get<T = unknown>(key: string): Promise<T | null> {
83
+ return this.withStore("readonly", async (store) => {
84
+ const value = await this.req<unknown>(store.get(key));
85
+ return value === undefined ? null : (value as T);
86
+ });
87
+ }
88
+
89
+ async set<T = unknown>(key: string, value: T): Promise<void> {
90
+ await this.withStore("readwrite", async (store) => {
91
+ await this.req(store.put(value, key));
92
+ return undefined;
93
+ });
94
+ }
95
+
96
+ async has(key: string): Promise<boolean> {
97
+ return this.withStore("readonly", async (store) => {
98
+ const count = await this.req<number>(store.count(key));
99
+ return count > 0;
100
+ });
101
+ }
102
+
103
+ async delete(key: string): Promise<void> {
104
+ await this.withStore("readwrite", async (store) => {
105
+ await this.req(store.delete(key));
106
+ return undefined;
107
+ });
108
+ }
109
+
110
+ async clear(): Promise<void> {
111
+ await this.withStore("readwrite", async (store) => {
112
+ await this.req(store.clear());
113
+ return undefined;
114
+ });
115
+ }
116
+
117
+ async keys(): Promise<string[]> {
118
+ return this.withStore("readonly", async (store) => {
119
+ const keys = await this.req<Array<IDBValidKey>>(store.getAllKeys());
120
+ const normalized: string[] = [];
121
+ for (const key of keys) {
122
+ normalized.push(String(key));
123
+ }
124
+
125
+ return normalized;
126
+ });
73
127
  }
74
- }
75
-
76
- async get<T = unknown>(key: string): Promise<T | null> {
77
- return this.withStore("readonly", async (store) => {
78
- const value = await this.req<unknown>(store.get(key));
79
- return value === undefined ? null : (value as T);
80
- });
81
- }
82
-
83
- async set<T = unknown>(key: string, value: T): Promise<void> {
84
- await this.withStore("readwrite", async (store) => {
85
- await this.req(store.put(value, key));
86
- return undefined;
87
- });
88
- }
89
-
90
- async has(key: string): Promise<boolean> {
91
- return this.withStore("readonly", async (store) => {
92
- const count = await this.req<number>(store.count(key));
93
- return count > 0;
94
- });
95
- }
96
-
97
- async delete(key: string): Promise<void> {
98
- await this.withStore("readwrite", async (store) => {
99
- await this.req(store.delete(key));
100
- return undefined;
101
- });
102
- }
103
-
104
- async clear(): Promise<void> {
105
- await this.withStore("readwrite", async (store) => {
106
- await this.req(store.clear());
107
- return undefined;
108
- });
109
- }
110
-
111
- async keys(): Promise<string[]> {
112
- return this.withStore("readonly", async (store) => {
113
- const keys = await this.req<Array<IDBValidKey>>(store.getAllKeys());
114
- const normalized: string[] = [];
115
- for (const key of keys) {
116
- normalized.push(String(key));
117
- }
118
-
119
- return normalized;
120
- });
121
- }
122
128
  }
123
129
 
124
130
  async function actionFallback<T>(
125
- fallback: StorageAdapter,
126
- mode: IDBTransactionMode,
127
- action: (store: IDBObjectStore) => Promise<T>,
131
+ fallback: Adapter,
132
+ mode: IDBTransactionMode,
133
+ action: (store: IDBObjectStore) => Promise<T>,
128
134
  ): Promise<T> {
129
- // Keep call sites small: map IDB actions to the same short storage contract.
130
- if (mode === "readonly") {
131
- const store = createReadonlyProxy(fallback);
132
- return action(store as unknown as IDBObjectStore);
133
- }
135
+ // Keep call sites small: map IDB actions to the same short storage contract.
136
+ if (mode === "readonly") {
137
+ const store = createReadonlyProxy(fallback);
138
+ return action(store as unknown as IDBObjectStore);
139
+ }
134
140
 
135
- const store = createReadWriteProxy(fallback);
136
- return action(store as unknown as IDBObjectStore);
141
+ const store = createReadWriteProxy(fallback);
142
+ return action(store as unknown as IDBObjectStore);
137
143
  }
138
144
 
139
- function createReadonlyProxy(fallback: StorageAdapter): Partial<IDBObjectStore> {
140
- return {
141
- get: (key: IDBValidKey) => wrapPromiseRequest(fallback.get(String(key))),
142
- count: (key?: IDBValidKey | IDBKeyRange) =>
143
- wrapPromiseRequest(
144
- fallback.has(String(key as IDBValidKey)).then((exists) => (exists ? 1 : 0)),
145
- ),
146
- getAllKeys: () =>
147
- wrapPromiseRequest(fallback.keys().then((keys) => keys as Array<IDBValidKey>)),
148
- };
145
+ function createReadonlyProxy(fallback: Adapter): Partial<IDBObjectStore> {
146
+ return {
147
+ get: (key: IDBValidKey) =>
148
+ wrapPromiseRequest(fallback.get(String(key))),
149
+ count: (key?: IDBValidKey | IDBKeyRange) =>
150
+ wrapPromiseRequest(
151
+ fallback
152
+ .has(String(key as IDBValidKey))
153
+ .then((exists) => (exists ? 1 : 0)),
154
+ ),
155
+ getAllKeys: () =>
156
+ wrapPromiseRequest(
157
+ fallback.keys().then((keys) => keys as Array<IDBValidKey>),
158
+ ),
159
+ };
149
160
  }
150
161
 
151
- function createReadWriteProxy(fallback: StorageAdapter): Partial<IDBObjectStore> {
152
- return {
153
- ...createReadonlyProxy(fallback),
154
- put: (value: unknown, key?: IDBValidKey) =>
155
- wrapPromiseRequest(fallback.set(String(key as IDBValidKey), value)),
156
- delete: (key: IDBValidKey | IDBKeyRange) =>
157
- wrapPromiseRequest(fallback.delete(String(key as IDBValidKey))),
158
- clear: () => wrapPromiseRequest(fallback.clear()),
159
- };
162
+ function createReadWriteProxy(fallback: Adapter): Partial<IDBObjectStore> {
163
+ return {
164
+ ...createReadonlyProxy(fallback),
165
+ put: (value: unknown, key?: IDBValidKey) =>
166
+ wrapPromiseRequest(fallback.set(String(key as IDBValidKey), value)),
167
+ delete: (key: IDBValidKey | IDBKeyRange) =>
168
+ wrapPromiseRequest(fallback.delete(String(key as IDBValidKey))),
169
+ clear: () => wrapPromiseRequest(fallback.clear()),
170
+ };
160
171
  }
161
172
 
162
173
  function wrapPromiseRequest<T>(promise: Promise<T>): IDBRequest<T> {
163
- const request: Partial<IDBRequest<T>> = {
164
- onsuccess: null,
165
- onerror: null,
166
- };
167
-
168
- promise.then(
169
- (result) => {
170
- request.result = result;
171
- request.onsuccess?.call(request as IDBRequest<T>, new Event("success"));
172
- },
173
- (error) => {
174
- request.error = error as DOMException;
175
- request.onerror?.call(request as IDBRequest<T>, new Event("error"));
176
- },
177
- );
178
-
179
- return request as IDBRequest<T>;
174
+ const request: Partial<IDBRequest<T>> = {
175
+ onsuccess: null,
176
+ onerror: null,
177
+ };
178
+
179
+ promise.then(
180
+ (result) => {
181
+ request.result = result;
182
+ request.onsuccess?.call(
183
+ request as IDBRequest<T>,
184
+ new Event("success"),
185
+ );
186
+ },
187
+ (error) => {
188
+ request.error = error as DOMException;
189
+ request.onerror?.call(request as IDBRequest<T>, new Event("error"));
190
+ },
191
+ );
192
+
193
+ return request as IDBRequest<T>;
180
194
  }
@@ -1,46 +1,46 @@
1
- import type { StorageAdapter } from "../storage";
1
+ import type { Adapter } from "@/storage/adapters/contract";
2
2
 
3
- export default class LocalStorageAdapter implements StorageAdapter {
4
- protected storage: Storage;
3
+ export default class LocalStorageAdapter implements Adapter {
4
+ protected storage: Storage;
5
5
 
6
- constructor(storage: Storage = window.localStorage) {
7
- this.storage = storage;
8
- }
9
-
10
- async get<T = unknown>(key: string): Promise<T | null> {
11
- const value = this.storage.getItem(key);
12
- if (value === null) {
13
- return null;
6
+ constructor(storage: Storage = window.localStorage) {
7
+ this.storage = storage;
14
8
  }
15
9
 
16
- return JSON.parse(value) as T;
17
- }
10
+ async get<T = unknown>(key: string): Promise<T | null> {
11
+ const value = this.storage.getItem(key);
12
+ if (value === null) {
13
+ return null;
14
+ }
18
15
 
19
- async set<T = unknown>(key: string, value: T): Promise<void> {
20
- this.storage.setItem(key, JSON.stringify(value));
21
- }
16
+ return JSON.parse(value) as T;
17
+ }
22
18
 
23
- async has(key: string): Promise<boolean> {
24
- return this.storage.getItem(key) !== null;
25
- }
19
+ async set<T = unknown>(key: string, value: T): Promise<void> {
20
+ this.storage.setItem(key, JSON.stringify(value));
21
+ }
26
22
 
27
- async delete(key: string): Promise<void> {
28
- this.storage.removeItem(key);
29
- }
23
+ async has(key: string): Promise<boolean> {
24
+ return this.storage.getItem(key) !== null;
25
+ }
30
26
 
31
- async clear(): Promise<void> {
32
- this.storage.clear();
33
- }
27
+ async delete(key: string): Promise<void> {
28
+ this.storage.removeItem(key);
29
+ }
34
30
 
35
- async keys(): Promise<string[]> {
36
- const keys: string[] = [];
37
- for (let i = 0; i < this.storage.length; i += 1) {
38
- const key = this.storage.key(i);
39
- if (key !== null) {
40
- keys.push(key);
41
- }
31
+ async clear(): Promise<void> {
32
+ this.storage.clear();
42
33
  }
43
34
 
44
- return keys;
45
- }
35
+ async keys(): Promise<string[]> {
36
+ const keys: string[] = [];
37
+ for (let i = 0; i < this.storage.length; i += 1) {
38
+ const key = this.storage.key(i);
39
+ if (key !== null) {
40
+ keys.push(key);
41
+ }
42
+ }
43
+
44
+ return keys;
45
+ }
46
46
  }
@@ -1,35 +1,35 @@
1
- import type { StorageAdapter } from "../storage";
1
+ import type { Adapter } from "@/storage/adapters/contract";
2
2
 
3
- export default class MemoryStorageAdapter implements StorageAdapter {
4
- protected items = new Map<string, unknown>();
3
+ export default class MemoryStorageAdapter implements Adapter {
4
+ protected items = new Map<string, unknown>();
5
5
 
6
- constructor() {}
6
+ constructor() {}
7
7
 
8
- async get<T = unknown>(key: string): Promise<T | null> {
9
- if (!this.items.has(key)) {
10
- return null;
11
- }
8
+ async get<T = unknown>(key: string): Promise<T | null> {
9
+ if (!this.items.has(key)) {
10
+ return null;
11
+ }
12
12
 
13
- return this.items.get(key) as T;
14
- }
13
+ return this.items.get(key) as T;
14
+ }
15
15
 
16
- async set<T = unknown>(key: string, value: T): Promise<void> {
17
- this.items.set(key, value);
18
- }
16
+ async set<T = unknown>(key: string, value: T): Promise<void> {
17
+ this.items.set(key, value);
18
+ }
19
19
 
20
- async has(key: string): Promise<boolean> {
21
- return this.items.has(key);
22
- }
20
+ async has(key: string): Promise<boolean> {
21
+ return this.items.has(key);
22
+ }
23
23
 
24
- async delete(key: string): Promise<void> {
25
- this.items.delete(key);
26
- }
24
+ async delete(key: string): Promise<void> {
25
+ this.items.delete(key);
26
+ }
27
27
 
28
- async clear(): Promise<void> {
29
- this.items.clear();
30
- }
28
+ async clear(): Promise<void> {
29
+ this.items.clear();
30
+ }
31
31
 
32
- async keys(): Promise<string[]> {
33
- return Array.from(this.items.keys());
34
- }
32
+ async keys(): Promise<string[]> {
33
+ return Array.from(this.items.keys());
34
+ }
35
35
  }