barely-effect 0.1.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.
- package/README.md +1 -0
- package/dist/ansi-colors/ansiColors.d.ts +11 -0
- package/dist/ansi-colors/ansiColors.d.ts.map +1 -0
- package/dist/ansi-colors/ansiColors.js +15 -0
- package/dist/ansi-colors/index.d.ts +2 -0
- package/dist/ansi-colors/index.d.ts.map +1 -0
- package/dist/ansi-colors/index.js +1 -0
- package/dist/assert.d.ts +10 -0
- package/dist/assert.d.ts.map +1 -0
- package/dist/assert.js +30 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/logger/LogFormatterJson.d.ts +5 -0
- package/dist/logger/LogFormatterJson.d.ts.map +1 -0
- package/dist/logger/LogFormatterJson.js +19 -0
- package/dist/logger/LogFormatterPretty.d.ts +17 -0
- package/dist/logger/LogFormatterPretty.d.ts.map +1 -0
- package/dist/logger/LogFormatterPretty.js +88 -0
- package/dist/logger/LogLevel.d.ts +4 -0
- package/dist/logger/LogLevel.d.ts.map +1 -0
- package/dist/logger/LogLevel.js +5 -0
- package/dist/logger/Logger.d.ts +36 -0
- package/dist/logger/Logger.d.ts.map +1 -0
- package/dist/logger/Logger.js +115 -0
- package/dist/logger/index.d.ts +7 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +5 -0
- package/dist/logger/parseLogArguments.d.ts +7 -0
- package/dist/logger/parseLogArguments.d.ts.map +1 -0
- package/dist/logger/parseLogArguments.js +51 -0
- package/dist/logger/resolveError.d.ts +7 -0
- package/dist/logger/resolveError.d.ts.map +1 -0
- package/dist/logger/resolveError.js +13 -0
- package/dist/logger/types.d.ts +38 -0
- package/dist/logger/types.d.ts.map +1 -0
- package/dist/logger/types.js +3 -0
- package/dist/networking/HttpClient.d.ts +78 -0
- package/dist/networking/HttpClient.d.ts.map +1 -0
- package/dist/networking/HttpClient.js +77 -0
- package/dist/networking/index.d.ts +2 -0
- package/dist/networking/index.d.ts.map +1 -0
- package/dist/networking/index.js +1 -0
- package/dist/platform/filesystem/AbsolutePath.d.ts +18 -0
- package/dist/platform/filesystem/AbsolutePath.d.ts.map +1 -0
- package/dist/platform/filesystem/AbsolutePath.js +41 -0
- package/dist/platform/filesystem/FileSystem.d.ts +30 -0
- package/dist/platform/filesystem/FileSystem.d.ts.map +1 -0
- package/dist/platform/filesystem/FileSystem.js +129 -0
- package/dist/platform/filesystem/IFileSystem.d.ts +98 -0
- package/dist/platform/filesystem/IFileSystem.d.ts.map +1 -0
- package/dist/platform/filesystem/IFileSystem.js +19 -0
- package/dist/platform/filesystem/KeyedMap.d.ts +23 -0
- package/dist/platform/filesystem/KeyedMap.d.ts.map +1 -0
- package/dist/platform/filesystem/KeyedMap.js +59 -0
- package/dist/platform/filesystem/MemoryFileSystem.d.ts +42 -0
- package/dist/platform/filesystem/MemoryFileSystem.d.ts.map +1 -0
- package/dist/platform/filesystem/MemoryFileSystem.js +200 -0
- package/dist/platform/filesystem/glob/cachedFs.d.ts +9 -0
- package/dist/platform/filesystem/glob/cachedFs.d.ts.map +1 -0
- package/dist/platform/filesystem/glob/cachedFs.js +25 -0
- package/dist/platform/filesystem/glob/glob.d.ts +15 -0
- package/dist/platform/filesystem/glob/glob.d.ts.map +1 -0
- package/dist/platform/filesystem/glob/glob.js +62 -0
- package/dist/platform/filesystem/glob/parseGlob.d.ts +11 -0
- package/dist/platform/filesystem/glob/parseGlob.d.ts.map +1 -0
- package/dist/platform/filesystem/glob/parseGlob.js +61 -0
- package/dist/platform/filesystem/index.d.ts +6 -0
- package/dist/platform/filesystem/index.d.ts.map +1 -0
- package/dist/platform/filesystem/index.js +5 -0
- package/dist/platform/process/EnvReader.d.ts +13 -0
- package/dist/platform/process/EnvReader.d.ts.map +1 -0
- package/dist/platform/process/EnvReader.js +92 -0
- package/dist/platform/process/ProcessContext.d.ts +34 -0
- package/dist/platform/process/ProcessContext.d.ts.map +1 -0
- package/dist/platform/process/ProcessContext.js +47 -0
- package/dist/time/Clock.d.ts +21 -0
- package/dist/time/Clock.d.ts.map +1 -0
- package/dist/time/Clock.js +27 -0
- package/dist/time/temporal.d.ts +5 -0
- package/dist/time/temporal.d.ts.map +1 -0
- package/dist/time/temporal.js +39 -0
- package/dist/utils/jsonStringify.d.ts +7 -0
- package/dist/utils/jsonStringify.d.ts.map +1 -0
- package/dist/utils/jsonStringify.js +23 -0
- package/dist/utils/runMain.d.ts +3 -0
- package/dist/utils/runMain.d.ts.map +1 -0
- package/dist/utils/runMain.js +75 -0
- package/package.json +71 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { type Cause, Effect } from "effect";
|
|
2
|
+
declare const HttpNetworkError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").MatchRecord<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }, void, { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
3
|
+
readonly _tag: "HttpNetworkError";
|
|
4
|
+
} & Readonly<A>;
|
|
5
|
+
export declare class HttpNetworkError extends HttpNetworkError_base<{
|
|
6
|
+
readonly cause: unknown;
|
|
7
|
+
}> {
|
|
8
|
+
}
|
|
9
|
+
declare const HttpStatusError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").MatchRecord<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }, void, { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
10
|
+
readonly _tag: "HttpStatusError";
|
|
11
|
+
} & Readonly<A>;
|
|
12
|
+
export declare class HttpStatusError extends HttpStatusError_base<{
|
|
13
|
+
readonly status: number;
|
|
14
|
+
}> {
|
|
15
|
+
}
|
|
16
|
+
declare const HttpParseError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").MatchRecord<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }, void, { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
17
|
+
readonly _tag: "HttpParseError";
|
|
18
|
+
} & Readonly<A>;
|
|
19
|
+
export declare class HttpParseError extends HttpParseError_base<{
|
|
20
|
+
readonly cause: unknown;
|
|
21
|
+
}> {
|
|
22
|
+
}
|
|
23
|
+
export type HttpClientError = HttpNetworkError | HttpStatusError | HttpParseError | Cause.TimeoutError;
|
|
24
|
+
export interface RetryOptions {
|
|
25
|
+
times: number;
|
|
26
|
+
delay?: number;
|
|
27
|
+
until?: (error: HttpClientError) => boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface HttpClientOptions {
|
|
30
|
+
retry?: RetryOptions;
|
|
31
|
+
retryUntilStatus?: (status: number) => boolean;
|
|
32
|
+
timeout?: number;
|
|
33
|
+
}
|
|
34
|
+
export interface HttpClientRequestOptions {
|
|
35
|
+
url: string;
|
|
36
|
+
headers?: Record<string, string>;
|
|
37
|
+
output?: "json" | "text";
|
|
38
|
+
}
|
|
39
|
+
export interface HttpClientRequestOptionsWithBody extends HttpClientRequestOptions {
|
|
40
|
+
readonly body?: RequestInit["body"];
|
|
41
|
+
}
|
|
42
|
+
export declare class HttpClient {
|
|
43
|
+
private readonly options;
|
|
44
|
+
constructor(options?: HttpClientOptions);
|
|
45
|
+
get(options: HttpClientRequestOptions & {
|
|
46
|
+
output: "text";
|
|
47
|
+
}, overrides?: HttpClientOptions): Effect.Effect<string, HttpClientError>;
|
|
48
|
+
get(options: HttpClientRequestOptions & {
|
|
49
|
+
output?: "json";
|
|
50
|
+
}, overrides?: HttpClientOptions): Effect.Effect<unknown, HttpClientError>;
|
|
51
|
+
post(options: HttpClientRequestOptionsWithBody & {
|
|
52
|
+
output: "text";
|
|
53
|
+
}, overrides?: HttpClientOptions): Effect.Effect<string, HttpClientError>;
|
|
54
|
+
post(options: HttpClientRequestOptionsWithBody & {
|
|
55
|
+
output?: "json";
|
|
56
|
+
}, overrides?: HttpClientOptions): Effect.Effect<unknown, HttpClientError>;
|
|
57
|
+
put(options: HttpClientRequestOptionsWithBody & {
|
|
58
|
+
output: "text";
|
|
59
|
+
}, overrides?: HttpClientOptions): Effect.Effect<string, HttpClientError>;
|
|
60
|
+
put(options: HttpClientRequestOptionsWithBody & {
|
|
61
|
+
output?: "json";
|
|
62
|
+
}, overrides?: HttpClientOptions): Effect.Effect<unknown, HttpClientError>;
|
|
63
|
+
patch(options: HttpClientRequestOptionsWithBody & {
|
|
64
|
+
output: "text";
|
|
65
|
+
}, overrides?: HttpClientOptions): Effect.Effect<string, HttpClientError>;
|
|
66
|
+
patch(options: HttpClientRequestOptionsWithBody & {
|
|
67
|
+
output?: "json";
|
|
68
|
+
}, overrides?: HttpClientOptions): Effect.Effect<unknown, HttpClientError>;
|
|
69
|
+
delete(options: HttpClientRequestOptions & {
|
|
70
|
+
output: "text";
|
|
71
|
+
}, overrides?: HttpClientOptions): Effect.Effect<string, HttpClientError>;
|
|
72
|
+
delete(options: HttpClientRequestOptions & {
|
|
73
|
+
output?: "json";
|
|
74
|
+
}, overrides?: HttpClientOptions): Effect.Effect<unknown, HttpClientError>;
|
|
75
|
+
private request;
|
|
76
|
+
}
|
|
77
|
+
export {};
|
|
78
|
+
//# sourceMappingURL=HttpClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HttpClient.d.ts","sourceRoot":"","sources":["../../src/networking/HttpClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Data, Duration, Effect, Schedule } from "effect";
|
|
2
|
+
export class HttpNetworkError extends Data.TaggedError("HttpNetworkError") {
|
|
3
|
+
}
|
|
4
|
+
export class HttpStatusError extends Data.TaggedError("HttpStatusError") {
|
|
5
|
+
}
|
|
6
|
+
export class HttpParseError extends Data.TaggedError("HttpParseError") {
|
|
7
|
+
}
|
|
8
|
+
const defaultOptions = {
|
|
9
|
+
timeout: 5000,
|
|
10
|
+
retry: {
|
|
11
|
+
times: 3,
|
|
12
|
+
delay: 200,
|
|
13
|
+
until: () => true,
|
|
14
|
+
},
|
|
15
|
+
retryUntilStatus: (status) => status >= 200 && status < 300,
|
|
16
|
+
};
|
|
17
|
+
export class HttpClient {
|
|
18
|
+
options;
|
|
19
|
+
constructor(options = {}) {
|
|
20
|
+
this.options = {
|
|
21
|
+
timeout: options.timeout ?? defaultOptions.timeout,
|
|
22
|
+
retryUntilStatus: options.retryUntilStatus ?? defaultOptions.retryUntilStatus,
|
|
23
|
+
retry: "retry" in options ? options.retry : defaultOptions.retry,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
get(options, overrides) {
|
|
27
|
+
return this.request(options, "GET", overrides);
|
|
28
|
+
}
|
|
29
|
+
post(options, overrides) {
|
|
30
|
+
return this.request(options, "POST", overrides);
|
|
31
|
+
}
|
|
32
|
+
put(options, overrides) {
|
|
33
|
+
return this.request(options, "PUT", overrides);
|
|
34
|
+
}
|
|
35
|
+
patch(options, overrides) {
|
|
36
|
+
return this.request(options, "PATCH", overrides);
|
|
37
|
+
}
|
|
38
|
+
delete(options, overrides) {
|
|
39
|
+
return this.request(options, "DELETE", overrides);
|
|
40
|
+
}
|
|
41
|
+
request(requestOptions, method, overrides) {
|
|
42
|
+
const options = { ...this.options, ...overrides };
|
|
43
|
+
const output = requestOptions.output ?? "json";
|
|
44
|
+
const fetchEffect = Effect.gen({ self: this }, function* () {
|
|
45
|
+
const response = yield* Effect.tryPromise({
|
|
46
|
+
try: () => fetch(requestOptions.url, {
|
|
47
|
+
method,
|
|
48
|
+
headers: requestOptions.headers,
|
|
49
|
+
body: requestOptions.body,
|
|
50
|
+
}),
|
|
51
|
+
catch: (cause) => new HttpNetworkError({ cause }),
|
|
52
|
+
});
|
|
53
|
+
if (options.retryUntilStatus && !options.retryUntilStatus(response.status)) {
|
|
54
|
+
return yield* Effect.fail(new HttpStatusError({ status: response.status }));
|
|
55
|
+
}
|
|
56
|
+
return yield* Effect.tryPromise({
|
|
57
|
+
try: () => (output === "text" ? response.text() : response.json()),
|
|
58
|
+
catch: (cause) => new HttpParseError({ cause }),
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
let result = fetchEffect;
|
|
62
|
+
if (options.timeout) {
|
|
63
|
+
result = Effect.timeout(result, Duration.millis(options.timeout));
|
|
64
|
+
}
|
|
65
|
+
if (options.retry) {
|
|
66
|
+
const retryOpts = options.retry;
|
|
67
|
+
result = Effect.retry(result, {
|
|
68
|
+
times: retryOpts.times,
|
|
69
|
+
...(retryOpts.delay != null
|
|
70
|
+
? { schedule: Schedule.spaced(Duration.millis(retryOpts.delay)) }
|
|
71
|
+
: {}),
|
|
72
|
+
...(retryOpts.until ? { while: retryOpts.until } : {}),
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/networking/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./HttpClient.js";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
declare class AbsolutePathClazz {
|
|
2
|
+
readonly path: string;
|
|
3
|
+
constructor(absolutePath: string);
|
|
4
|
+
getName(): string;
|
|
5
|
+
getDirPath(): AbsolutePath;
|
|
6
|
+
join(...paths: Array<string>): AbsolutePath;
|
|
7
|
+
relativeFrom(root: AbsolutePath): string;
|
|
8
|
+
contains(other: AbsolutePath): boolean;
|
|
9
|
+
eq(other: AbsolutePath): boolean;
|
|
10
|
+
toString(): string;
|
|
11
|
+
}
|
|
12
|
+
export declare const AbsolutePath: {
|
|
13
|
+
new (absolutePath: string): AbsolutePathClazz;
|
|
14
|
+
(absolutePath: string): AbsolutePathClazz;
|
|
15
|
+
};
|
|
16
|
+
export type AbsolutePath = AbsolutePathClazz;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=AbsolutePath.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AbsolutePath.d.ts","sourceRoot":"","sources":["../../../src/platform/filesystem/AbsolutePath.ts"],"names":[],"mappings":"AAEA,cAAM,iBAAiB;IACrB,SAAgB,IAAI,EAAE,MAAM,CAAA;gBAEhB,YAAY,EAAE,MAAM;IAOhC,OAAO,IAAI,MAAM;IAIjB,UAAU,IAAI,YAAY;IAI1B,IAAI,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,YAAY;IAI3C,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM;IAIxC,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO;IAStC,EAAE,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO;IAIhC,QAAQ,IAAI,MAAM;CAGnB;AAQD,eAAO,MAAM,YAAY,EAAqE;IAC5F,KAAK,YAAY,EAAE,MAAM,GAAG,iBAAiB,CAAA;IAC7C,CAAC,YAAY,EAAE,MAAM,GAAG,iBAAiB,CAAA;CAC1C,CAAA;AACD,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as pathModule from "node:path";
|
|
2
|
+
class AbsolutePathClazz {
|
|
3
|
+
path;
|
|
4
|
+
constructor(absolutePath) {
|
|
5
|
+
if (!pathModule.isAbsolute(absolutePath)) {
|
|
6
|
+
throw new Error(`Path is not absolute, was: ${absolutePath}`);
|
|
7
|
+
}
|
|
8
|
+
this.path = pathModule.resolve(absolutePath);
|
|
9
|
+
}
|
|
10
|
+
getName() {
|
|
11
|
+
return pathModule.basename(this.path);
|
|
12
|
+
}
|
|
13
|
+
getDirPath() {
|
|
14
|
+
return AbsolutePath(pathModule.dirname(this.path));
|
|
15
|
+
}
|
|
16
|
+
join(...paths) {
|
|
17
|
+
return AbsolutePath(pathModule.join(this.path, ...paths));
|
|
18
|
+
}
|
|
19
|
+
relativeFrom(root) {
|
|
20
|
+
return pathModule.relative(root.path, this.path);
|
|
21
|
+
}
|
|
22
|
+
contains(other) {
|
|
23
|
+
const relative = pathModule.relative(this.path, other.path);
|
|
24
|
+
if (relative === "") {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
return !relative.startsWith("../") && relative !== ".." && !pathModule.isAbsolute(relative);
|
|
28
|
+
}
|
|
29
|
+
eq(other) {
|
|
30
|
+
return this.path === other.path;
|
|
31
|
+
}
|
|
32
|
+
toString() {
|
|
33
|
+
return this.path;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function AbsolutePathClass(absolutePath) {
|
|
37
|
+
return new AbsolutePathClazz(absolutePath);
|
|
38
|
+
}
|
|
39
|
+
Object.setPrototypeOf(AbsolutePathClass, AbsolutePathClazz);
|
|
40
|
+
AbsolutePathClass.prototype = AbsolutePathClazz.prototype;
|
|
41
|
+
export const AbsolutePath = Object.assign(AbsolutePathClass, AbsolutePathClazz);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { type AbsolutePath } from "./AbsolutePath";
|
|
3
|
+
import { FsDirNotEmptyError, FsNotADirError, type FsDirAccessError, type FsDirCreateError, type FsDirRemoveError, type FsFileAccessError, type FsFileWriteError, type FileSystemEntry, type IFileSystem } from "./IFileSystem";
|
|
4
|
+
export declare class FileSystem implements IFileSystem {
|
|
5
|
+
readFile(path: AbsolutePath): Effect.Effect<string, FsFileAccessError>;
|
|
6
|
+
writeFile(path: AbsolutePath, contents: string): Effect.Effect<void, FsFileWriteError>;
|
|
7
|
+
exists(path: AbsolutePath): Effect.Effect<boolean>;
|
|
8
|
+
get(path: AbsolutePath): Effect.Effect<FileSystemEntry | undefined>;
|
|
9
|
+
listDir(path: AbsolutePath): Effect.Effect<FileSystemEntry[], FsDirAccessError>;
|
|
10
|
+
createDir(path: AbsolutePath, options?: {
|
|
11
|
+
recursive: boolean;
|
|
12
|
+
}): Effect.Effect<void, FsDirCreateError>;
|
|
13
|
+
removeDir(path: AbsolutePath, options: {
|
|
14
|
+
recursive: true;
|
|
15
|
+
force: true;
|
|
16
|
+
}): Effect.Effect<void, never>;
|
|
17
|
+
removeDir(path: AbsolutePath, options: {
|
|
18
|
+
recursive: true;
|
|
19
|
+
force: false;
|
|
20
|
+
}): Effect.Effect<void, FsDirAccessError>;
|
|
21
|
+
removeDir(path: AbsolutePath, options: {
|
|
22
|
+
recursive: false;
|
|
23
|
+
force: true;
|
|
24
|
+
}): Effect.Effect<void, FsDirNotEmptyError | FsNotADirError>;
|
|
25
|
+
removeDir(path: AbsolutePath, options: {
|
|
26
|
+
recursive: false;
|
|
27
|
+
force: false;
|
|
28
|
+
}): Effect.Effect<void, FsDirRemoveError>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=FileSystem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileSystem.d.ts","sourceRoot":"","sources":["../../../src/platform/filesystem/FileSystem.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAG/B,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EAEL,kBAAkB,EAIlB,cAAc,EAGd,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,WAAW,EACjB,MAAM,eAAe,CAAA;AAEtB,qBAAa,UAAW,YAAW,WAAW;IAC5C,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC;IAkBtE,SAAS,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAkBtF,MAAM,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;IAYlD,GAAG,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,GAAG,SAAS,CAAC;IAmBnE,OAAO,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,EAAE,gBAAgB,CAAC;IAwB/E,SAAS,CACP,IAAI,EAAE,YAAY,EAClB,OAAO,GAAE;QAAE,SAAS,EAAE,OAAO,CAAA;KAAwB,GACpD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAkBxC,SAAS,CACP,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE;QAAE,SAAS,EAAE,IAAI,CAAC;QAAC,KAAK,EAAE,IAAI,CAAA;KAAE,GACxC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC;IAC7B,SAAS,CACP,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE;QAAE,SAAS,EAAE,IAAI,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,GACzC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,gBAAgB,CAAC;IACxC,SAAS,CACP,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE;QAAE,SAAS,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,IAAI,CAAA;KAAE,GACzC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,kBAAkB,GAAG,cAAc,CAAC;IAC3D,SAAS,CACP,IAAI,EAAE,YAAY,EAClB,OAAO,EAAE;QAAE,SAAS,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,GAC1C,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,gBAAgB,CAAC;CAiCzC"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { access, mkdir, readdir, readFile, rm, rmdir, stat, writeFile } from "node:fs/promises";
|
|
3
|
+
import {} from "./AbsolutePath.js";
|
|
4
|
+
import { FsAlreadyExistsError, FsDirNotEmptyError, FsDirNotFoundError, FsFileIsADirError, FsFileNotFoundError, FsNotADirError, FsOtherError, FsParentNotFoundError, } from "./IFileSystem.js";
|
|
5
|
+
export class FileSystem {
|
|
6
|
+
readFile(path) {
|
|
7
|
+
return Effect.tryPromise({
|
|
8
|
+
try: () => readFile(path.path, "utf8"),
|
|
9
|
+
catch: (error) => {
|
|
10
|
+
if (error instanceof Error && "code" in error) {
|
|
11
|
+
switch (error.code) {
|
|
12
|
+
case "ENOENT":
|
|
13
|
+
return new FsFileNotFoundError({ path });
|
|
14
|
+
case "EISDIR":
|
|
15
|
+
return new FsFileIsADirError({ path });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return new FsOtherError({ cause: error });
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
writeFile(path, contents) {
|
|
23
|
+
return Effect.tryPromise({
|
|
24
|
+
try: () => writeFile(path.path, contents, "utf8"),
|
|
25
|
+
catch: (error) => {
|
|
26
|
+
if (error instanceof Error && "code" in error) {
|
|
27
|
+
switch (error.code) {
|
|
28
|
+
case "EISDIR":
|
|
29
|
+
return new FsFileIsADirError({ path });
|
|
30
|
+
case "ENOENT":
|
|
31
|
+
return new FsParentNotFoundError({ path });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return new FsOtherError({ cause: error });
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
exists(path) {
|
|
39
|
+
return Effect.promise(async () => {
|
|
40
|
+
try {
|
|
41
|
+
await access(path.path);
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
get(path) {
|
|
50
|
+
return Effect.promise(async () => {
|
|
51
|
+
try {
|
|
52
|
+
const stats = await stat(path.path);
|
|
53
|
+
if (stats.isFile()) {
|
|
54
|
+
return { type: "file", path };
|
|
55
|
+
}
|
|
56
|
+
if (stats.isDirectory()) {
|
|
57
|
+
return { type: "dir", path };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
listDir(path) {
|
|
69
|
+
return Effect.gen({ self: this }, function* () {
|
|
70
|
+
const entry = yield* this.get(path);
|
|
71
|
+
if (entry === undefined) {
|
|
72
|
+
return yield* Effect.fail(new FsDirNotFoundError({ path }));
|
|
73
|
+
}
|
|
74
|
+
if (entry.type === "file") {
|
|
75
|
+
return yield* Effect.fail(new FsNotADirError({ path }));
|
|
76
|
+
}
|
|
77
|
+
const entries = yield* Effect.promise(() => readdir(path.path, { withFileTypes: true }));
|
|
78
|
+
return entries.map((dirent) => {
|
|
79
|
+
const entryPath = path.join(dirent.name);
|
|
80
|
+
if (dirent.isDirectory()) {
|
|
81
|
+
return { type: "dir", path: entryPath };
|
|
82
|
+
}
|
|
83
|
+
return { type: "file", path: entryPath };
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
createDir(path, options = { recursive: true }) {
|
|
88
|
+
return Effect.tryPromise({
|
|
89
|
+
try: () => mkdir(path.path, { recursive: options.recursive }),
|
|
90
|
+
catch: (error) => {
|
|
91
|
+
if (error instanceof Error && "code" in error) {
|
|
92
|
+
switch (error.code) {
|
|
93
|
+
case "EEXIST":
|
|
94
|
+
return new FsAlreadyExistsError({ path });
|
|
95
|
+
case "ENOENT":
|
|
96
|
+
return new FsParentNotFoundError({ path });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return new FsOtherError({ cause: error });
|
|
100
|
+
},
|
|
101
|
+
}).pipe(Effect.asVoid);
|
|
102
|
+
}
|
|
103
|
+
removeDir(path, options) {
|
|
104
|
+
return Effect.tryPromise({
|
|
105
|
+
try: async () => {
|
|
106
|
+
if (options.recursive) {
|
|
107
|
+
await rm(path.path, { recursive: true, force: options.force });
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
await rmdir(path.path);
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
catch: (error) => {
|
|
114
|
+
if (error instanceof Error && "code" in error) {
|
|
115
|
+
switch (error.code) {
|
|
116
|
+
case "EEXIST":
|
|
117
|
+
case "ENOTEMPTY":
|
|
118
|
+
return new FsDirNotEmptyError({ path });
|
|
119
|
+
case "ENOENT":
|
|
120
|
+
return new FsDirNotFoundError({ path });
|
|
121
|
+
case "ENOTDIR":
|
|
122
|
+
return new FsNotADirError({ path });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
throw error;
|
|
126
|
+
},
|
|
127
|
+
}).pipe(Effect.catchTag("FsDirNotFoundError", (err) => options.force ? Effect.void : Effect.fail(err)));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { type Effect } from "effect";
|
|
2
|
+
import { type AbsolutePath } from "./AbsolutePath";
|
|
3
|
+
declare const FsFileNotFoundError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").MatchRecord<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }, void, { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
4
|
+
readonly _tag: "FsFileNotFoundError";
|
|
5
|
+
} & Readonly<A>;
|
|
6
|
+
export declare class FsFileNotFoundError extends FsFileNotFoundError_base<{
|
|
7
|
+
readonly path: AbsolutePath;
|
|
8
|
+
}> {
|
|
9
|
+
}
|
|
10
|
+
declare const FsFileIsADirError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").MatchRecord<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }, void, { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
11
|
+
readonly _tag: "FsFileIsADirError";
|
|
12
|
+
} & Readonly<A>;
|
|
13
|
+
export declare class FsFileIsADirError extends FsFileIsADirError_base<{
|
|
14
|
+
readonly path: AbsolutePath;
|
|
15
|
+
}> {
|
|
16
|
+
}
|
|
17
|
+
declare const FsOtherError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").MatchRecord<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }, void, { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
18
|
+
readonly _tag: "FsOtherError";
|
|
19
|
+
} & Readonly<A>;
|
|
20
|
+
export declare class FsOtherError extends FsOtherError_base<{
|
|
21
|
+
readonly cause: unknown;
|
|
22
|
+
}> {
|
|
23
|
+
}
|
|
24
|
+
declare const FsParentNotFoundError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").MatchRecord<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }, void, { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
25
|
+
readonly _tag: "FsParentNotFoundError";
|
|
26
|
+
} & Readonly<A>;
|
|
27
|
+
export declare class FsParentNotFoundError extends FsParentNotFoundError_base<{
|
|
28
|
+
readonly path: AbsolutePath;
|
|
29
|
+
}> {
|
|
30
|
+
}
|
|
31
|
+
declare const FsDirNotFoundError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").MatchRecord<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }, void, { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
32
|
+
readonly _tag: "FsDirNotFoundError";
|
|
33
|
+
} & Readonly<A>;
|
|
34
|
+
export declare class FsDirNotFoundError extends FsDirNotFoundError_base<{
|
|
35
|
+
readonly path: AbsolutePath;
|
|
36
|
+
}> {
|
|
37
|
+
}
|
|
38
|
+
declare const FsNotADirError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").MatchRecord<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }, void, { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
39
|
+
readonly _tag: "FsNotADirError";
|
|
40
|
+
} & Readonly<A>;
|
|
41
|
+
export declare class FsNotADirError extends FsNotADirError_base<{
|
|
42
|
+
readonly path: AbsolutePath;
|
|
43
|
+
}> {
|
|
44
|
+
}
|
|
45
|
+
declare const FsDirNotEmptyError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").MatchRecord<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }, void, { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
46
|
+
readonly _tag: "FsDirNotEmptyError";
|
|
47
|
+
} & Readonly<A>;
|
|
48
|
+
export declare class FsDirNotEmptyError extends FsDirNotEmptyError_base<{
|
|
49
|
+
readonly path: AbsolutePath;
|
|
50
|
+
}> {
|
|
51
|
+
}
|
|
52
|
+
declare const FsAlreadyExistsError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").MatchRecord<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }, void, { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
53
|
+
readonly _tag: "FsAlreadyExistsError";
|
|
54
|
+
} & Readonly<A>;
|
|
55
|
+
export declare class FsAlreadyExistsError extends FsAlreadyExistsError_base<{
|
|
56
|
+
readonly path: AbsolutePath;
|
|
57
|
+
}> {
|
|
58
|
+
}
|
|
59
|
+
export type FsFileAccessError = FsFileNotFoundError | FsFileIsADirError | FsOtherError;
|
|
60
|
+
export type FsFileWriteError = FsFileIsADirError | FsParentNotFoundError | FsOtherError;
|
|
61
|
+
export type FsDirAccessError = FsDirNotFoundError | FsNotADirError;
|
|
62
|
+
export type FsDirRemoveError = FsDirAccessError | FsDirNotEmptyError;
|
|
63
|
+
export type FsDirCreateError = FsParentNotFoundError | FsAlreadyExistsError | FsOtherError;
|
|
64
|
+
export type FileSystemEntry = {
|
|
65
|
+
type: "file";
|
|
66
|
+
path: AbsolutePath;
|
|
67
|
+
} | {
|
|
68
|
+
type: "dir";
|
|
69
|
+
path: AbsolutePath;
|
|
70
|
+
};
|
|
71
|
+
export interface IFileSystem {
|
|
72
|
+
readFile(path: AbsolutePath): Effect.Effect<string, FsFileAccessError>;
|
|
73
|
+
writeFile(path: AbsolutePath, contents: string): Effect.Effect<void, FsFileWriteError>;
|
|
74
|
+
createDir(path: AbsolutePath, options?: {
|
|
75
|
+
recursive: boolean;
|
|
76
|
+
}): Effect.Effect<void, FsDirCreateError>;
|
|
77
|
+
removeDir(path: AbsolutePath, options: {
|
|
78
|
+
recursive: true;
|
|
79
|
+
force: true;
|
|
80
|
+
}): Effect.Effect<void, never>;
|
|
81
|
+
removeDir(path: AbsolutePath, options: {
|
|
82
|
+
recursive: true;
|
|
83
|
+
force: false;
|
|
84
|
+
}): Effect.Effect<void, FsDirAccessError>;
|
|
85
|
+
removeDir(path: AbsolutePath, options: {
|
|
86
|
+
recursive: false;
|
|
87
|
+
force: true;
|
|
88
|
+
}): Effect.Effect<void, FsDirNotEmptyError | FsNotADirError>;
|
|
89
|
+
removeDir(path: AbsolutePath, options: {
|
|
90
|
+
recursive: false;
|
|
91
|
+
force: false;
|
|
92
|
+
}): Effect.Effect<void, FsDirRemoveError>;
|
|
93
|
+
listDir(path: AbsolutePath): Effect.Effect<FileSystemEntry[], FsDirAccessError>;
|
|
94
|
+
get(path: AbsolutePath): Effect.Effect<FileSystemEntry | undefined>;
|
|
95
|
+
exists(path: AbsolutePath): Effect.Effect<boolean>;
|
|
96
|
+
}
|
|
97
|
+
export {};
|
|
98
|
+
//# sourceMappingURL=IFileSystem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IFileSystem.d.ts","sourceRoot":"","sources":["../../../src/platform/filesystem/IFileSystem.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Data } from "effect";
|
|
2
|
+
import {} from "./AbsolutePath.js";
|
|
3
|
+
// --- Error types ---
|
|
4
|
+
export class FsFileNotFoundError extends Data.TaggedError("FsFileNotFoundError") {
|
|
5
|
+
}
|
|
6
|
+
export class FsFileIsADirError extends Data.TaggedError("FsFileIsADirError") {
|
|
7
|
+
}
|
|
8
|
+
export class FsOtherError extends Data.TaggedError("FsOtherError") {
|
|
9
|
+
}
|
|
10
|
+
export class FsParentNotFoundError extends Data.TaggedError("FsParentNotFoundError") {
|
|
11
|
+
}
|
|
12
|
+
export class FsDirNotFoundError extends Data.TaggedError("FsDirNotFoundError") {
|
|
13
|
+
}
|
|
14
|
+
export class FsNotADirError extends Data.TaggedError("FsNotADirError") {
|
|
15
|
+
}
|
|
16
|
+
export class FsDirNotEmptyError extends Data.TaggedError("FsDirNotEmptyError") {
|
|
17
|
+
}
|
|
18
|
+
export class FsAlreadyExistsError extends Data.TaggedError("FsAlreadyExistsError") {
|
|
19
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A Map-like data structure that supports arbitrary keys via a serialization function.
|
|
3
|
+
* This is useful when you want to use objects (like AbsolutePath) as map keys
|
|
4
|
+
* while maintaining proper equality semantics.
|
|
5
|
+
*/
|
|
6
|
+
export declare class KeyedMap<K, V> {
|
|
7
|
+
private readonly serialize;
|
|
8
|
+
private readonly map;
|
|
9
|
+
private readonly keyMap;
|
|
10
|
+
constructor(serialize: (key: K) => string);
|
|
11
|
+
get(key: K): V | undefined;
|
|
12
|
+
set(key: K, value: V): this;
|
|
13
|
+
has(key: K): boolean;
|
|
14
|
+
delete(key: K): boolean;
|
|
15
|
+
clear(): void;
|
|
16
|
+
get size(): number;
|
|
17
|
+
keys(): IterableIterator<K>;
|
|
18
|
+
values(): IterableIterator<V>;
|
|
19
|
+
entries(): IterableIterator<[K, V]>;
|
|
20
|
+
[Symbol.iterator](): IterableIterator<[K, V]>;
|
|
21
|
+
forEach(callbackfn: (value: V, key: K, map: KeyedMap<K, V>) => void): void;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=KeyedMap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KeyedMap.d.ts","sourceRoot":"","sources":["../../../src/platform/filesystem/KeyedMap.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,qBAAa,QAAQ,CAAC,CAAC,EAAE,CAAC;IAIZ,OAAO,CAAC,QAAQ,CAAC,SAAS;IAHtC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAuB;IAC3C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;gBAEjB,SAAS,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,MAAM;IAE1D,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS;IAI1B,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAO3B,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO;IAIpB,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO;IAMvB,KAAK,IAAI,IAAI;IAKb,IAAI,IAAI,IAAI,MAAM,CAEjB;IAEA,IAAI,IAAI,gBAAgB,CAAC,CAAC,CAAC;IAM3B,MAAM,IAAI,gBAAgB,CAAC,CAAC,CAAC;IAI7B,OAAO,IAAI,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAOpC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAI7C,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI;CAK3E"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A Map-like data structure that supports arbitrary keys via a serialization function.
|
|
3
|
+
* This is useful when you want to use objects (like AbsolutePath) as map keys
|
|
4
|
+
* while maintaining proper equality semantics.
|
|
5
|
+
*/
|
|
6
|
+
export class KeyedMap {
|
|
7
|
+
serialize;
|
|
8
|
+
map = new Map();
|
|
9
|
+
keyMap = new Map();
|
|
10
|
+
constructor(serialize) {
|
|
11
|
+
this.serialize = serialize;
|
|
12
|
+
}
|
|
13
|
+
get(key) {
|
|
14
|
+
return this.map.get(this.serialize(key));
|
|
15
|
+
}
|
|
16
|
+
set(key, value) {
|
|
17
|
+
const serialized = this.serialize(key);
|
|
18
|
+
this.map.set(serialized, value);
|
|
19
|
+
this.keyMap.set(serialized, key);
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
has(key) {
|
|
23
|
+
return this.map.has(this.serialize(key));
|
|
24
|
+
}
|
|
25
|
+
delete(key) {
|
|
26
|
+
const serialized = this.serialize(key);
|
|
27
|
+
this.keyMap.delete(serialized);
|
|
28
|
+
return this.map.delete(serialized);
|
|
29
|
+
}
|
|
30
|
+
clear() {
|
|
31
|
+
this.map.clear();
|
|
32
|
+
this.keyMap.clear();
|
|
33
|
+
}
|
|
34
|
+
get size() {
|
|
35
|
+
return this.map.size;
|
|
36
|
+
}
|
|
37
|
+
*keys() {
|
|
38
|
+
for (const key of this.keyMap.values()) {
|
|
39
|
+
yield key;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
*values() {
|
|
43
|
+
yield* this.map.values();
|
|
44
|
+
}
|
|
45
|
+
*entries() {
|
|
46
|
+
for (const [serialized, value] of this.map.entries()) {
|
|
47
|
+
const key = this.keyMap.get(serialized);
|
|
48
|
+
yield [key, value];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
[Symbol.iterator]() {
|
|
52
|
+
return this.entries();
|
|
53
|
+
}
|
|
54
|
+
forEach(callbackfn) {
|
|
55
|
+
for (const [key, value] of this.entries()) {
|
|
56
|
+
callbackfn(value, key, this);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|