@decohere/core 0.0.1-dev.116
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/commonjs/src/caching/cache-manager.js +98 -0
- package/commonjs/src/caching/cache.decorator.js +69 -0
- package/commonjs/src/caching/cache.js +6 -0
- package/commonjs/src/caching/index.js +23 -0
- package/commonjs/src/caching/invalidate-cache.decorator.js +92 -0
- package/commonjs/src/caching/memoize.decorator.js +36 -0
- package/commonjs/src/caching/node-cache-memoize.adapter.js +49 -0
- package/commonjs/src/cli/action.js +65 -0
- package/commonjs/src/cli/command.js +127 -0
- package/commonjs/src/cli/index.js +61 -0
- package/commonjs/src/cli/module.type.js +18 -0
- package/commonjs/src/cli/options.js +115 -0
- package/commonjs/src/collections/collections.js +21 -0
- package/commonjs/src/collections/find-duplicates.js +35 -0
- package/commonjs/src/collections/index.js +52 -0
- package/commonjs/src/collections/merge-arrays.js +34 -0
- package/commonjs/src/collections/sum.js +63 -0
- package/commonjs/src/collections/unique-objects.js +39 -0
- package/commonjs/src/composition/index.js +4 -0
- package/commonjs/src/configuration/configuration.types.js +11 -0
- package/commonjs/src/configuration/index.js +18 -0
- package/commonjs/src/diagnostics/index.js +22 -0
- package/commonjs/src/diagnostics/trace.js +86 -0
- package/commonjs/src/extensibility/decorator-factory-base.js +22 -0
- package/commonjs/src/extensibility/decorator-factory.js +31 -0
- package/commonjs/src/extensibility/extension.js +37 -0
- package/commonjs/src/extensibility/index.js +23 -0
- package/commonjs/src/extensibility/mixwith.js +36 -0
- package/commonjs/src/extensibility/pipeline.js +56 -0
- package/commonjs/src/extensibility/step.js +18 -0
- package/commonjs/src/interop/docker/docker.js +54 -0
- package/commonjs/src/interop/errors/interop.error.js +12 -0
- package/commonjs/src/interop/git/git.js +134 -0
- package/commonjs/src/interop/git/git.types.js +4 -0
- package/commonjs/src/interop/index.js +97 -0
- package/commonjs/src/interop/node/index.js +18 -0
- package/commonjs/src/interop/node/node.js +45 -0
- package/commonjs/src/interop/npm/npm.js +231 -0
- package/commonjs/src/interop/npm/npm.types.js +16 -0
- package/commonjs/src/interop/pnpm/pnpm.js +34 -0
- package/commonjs/src/interop/pnpm/pnpm.types.js +4 -0
- package/commonjs/src/interop/shell/shell.argv.js +45 -0
- package/commonjs/src/interop/shell/shell.js +105 -0
- package/commonjs/src/interop/shell/shell.types.js +4 -0
- package/commonjs/src/interop/types/detect-package-manager.js +71 -0
- package/commonjs/src/interop/types/package-manager.js +4 -0
- package/commonjs/src/interop/yarn/yarn.js +34 -0
- package/commonjs/src/interop/yarn/yarn.types.js +4 -0
- package/commonjs/src/io/copy-file.js +25 -0
- package/commonjs/src/io/delete-file.js +21 -0
- package/commonjs/src/io/directory-exists.js +24 -0
- package/commonjs/src/io/file-exists.js +19 -0
- package/commonjs/src/io/find-directories.js +21 -0
- package/commonjs/src/io/find-file.js +45 -0
- package/commonjs/src/io/index.js +66 -0
- package/commonjs/src/io/io.js +28 -0
- package/commonjs/src/io/read-file.js +39 -0
- package/commonjs/src/io/remove-dir.js +22 -0
- package/commonjs/src/io/types/directory.type.js +4 -0
- package/commonjs/src/io/types/file.js +28 -0
- package/commonjs/src/io/types/index.js +19 -0
- package/commonjs/src/io/url-to-path.js +33 -0
- package/commonjs/src/io/watch.js +261 -0
- package/commonjs/src/io/write-file.js +30 -0
- package/commonjs/src/objects/deep-merge.js +67 -0
- package/commonjs/src/objects/index.js +11 -0
- package/commonjs/src/reflection/index.js +20 -0
- package/commonjs/src/reflection/types/index.js +18 -0
- package/commonjs/src/reflection/types/reflection.types.js +26 -0
- package/commonjs/src/reflection/utilities.js +118 -0
- package/commonjs/src/semver/index.js +18 -0
- package/commonjs/src/semver/semver.js +92 -0
- package/commonjs/src/system/camel-case.js +13 -0
- package/commonjs/src/system/debounce.js +19 -0
- package/commonjs/src/system/decorator.js +46 -0
- package/commonjs/src/system/environment.js +23 -0
- package/commonjs/src/system/function.types.js +18 -0
- package/commonjs/src/system/index.js +24 -0
- package/commonjs/src/system/retry.decorator.js +40 -0
- package/commonjs/src/system/sleep.js +13 -0
- package/commonjs/src/system/type.utils.js +4 -0
- package/commonjs/src/testing/flush-promises.js +16 -0
- package/commonjs/src/testing/glob-with-memfs.js +22 -0
- package/commonjs/src/testing/index.js +22 -0
- package/commonjs/src/testing/memfs.js +52 -0
- package/commonjs/src/testing/mock-logger.js +36 -0
- package/commonjs/src/testing/spy-on-constructor.js +27 -0
- package/es6/src/caching/cache-manager.js +82 -0
- package/es6/src/caching/cache.decorator.js +51 -0
- package/es6/src/caching/cache.js +3 -0
- package/es6/src/caching/index.js +6 -0
- package/es6/src/caching/invalidate-cache.decorator.js +71 -0
- package/es6/src/caching/memoize.decorator.js +27 -0
- package/es6/src/caching/node-cache-memoize.adapter.js +37 -0
- package/es6/src/cli/action.js +47 -0
- package/es6/src/cli/command.js +106 -0
- package/es6/src/cli/index.js +4 -0
- package/es6/src/cli/module.type.js +11 -0
- package/es6/src/cli/options.js +76 -0
- package/es6/src/collections/collections.js +4 -0
- package/es6/src/collections/find-duplicates.js +17 -0
- package/es6/src/collections/index.js +1 -0
- package/es6/src/collections/merge-arrays.js +16 -0
- package/es6/src/collections/sum.js +45 -0
- package/es6/src/collections/unique-objects.js +21 -0
- package/es6/src/composition/index.js +1 -0
- package/es6/src/configuration/configuration.types.js +1 -0
- package/es6/src/configuration/index.js +1 -0
- package/es6/src/diagnostics/index.js +1 -0
- package/es6/src/diagnostics/trace.js +68 -0
- package/es6/src/extensibility/decorator-factory-base.js +39 -0
- package/es6/src/extensibility/decorator-factory.js +21 -0
- package/es6/src/extensibility/extension.js +27 -0
- package/es6/src/extensibility/index.js +6 -0
- package/es6/src/extensibility/mixwith.js +26 -0
- package/es6/src/extensibility/pipeline.js +46 -0
- package/es6/src/extensibility/step.js +16 -0
- package/es6/src/interop/docker/docker.js +44 -0
- package/es6/src/interop/errors/interop.error.js +2 -0
- package/es6/src/interop/git/git.js +124 -0
- package/es6/src/interop/git/git.types.js +1 -0
- package/es6/src/interop/index.js +21 -0
- package/es6/src/interop/node/index.js +1 -0
- package/es6/src/interop/node/node.js +35 -0
- package/es6/src/interop/npm/npm.js +180 -0
- package/es6/src/interop/npm/npm.types.js +6 -0
- package/es6/src/interop/pnpm/pnpm.js +24 -0
- package/es6/src/interop/pnpm/pnpm.types.js +1 -0
- package/es6/src/interop/shell/shell.argv.js +35 -0
- package/es6/src/interop/shell/shell.js +95 -0
- package/es6/src/interop/shell/shell.types.js +1 -0
- package/es6/src/interop/types/detect-package-manager.js +50 -0
- package/es6/src/interop/types/package-manager.js +1 -0
- package/es6/src/interop/yarn/yarn.js +24 -0
- package/es6/src/interop/yarn/yarn.types.js +1 -0
- package/es6/src/io/copy-file.js +10 -0
- package/es6/src/io/delete-file.js +6 -0
- package/es6/src/io/directory-exists.js +9 -0
- package/es6/src/io/file-exists.js +9 -0
- package/es6/src/io/find-directories.js +11 -0
- package/es6/src/io/find-file.js +27 -0
- package/es6/src/io/index.js +2 -0
- package/es6/src/io/io.js +11 -0
- package/es6/src/io/read-file.js +13 -0
- package/es6/src/io/remove-dir.js +7 -0
- package/es6/src/io/types/directory.type.js +1 -0
- package/es6/src/io/types/file.js +18 -0
- package/es6/src/io/types/index.js +2 -0
- package/es6/src/io/url-to-path.js +15 -0
- package/es6/src/io/watch.js +238 -0
- package/es6/src/io/write-file.js +15 -0
- package/es6/src/objects/deep-merge.js +57 -0
- package/es6/src/objects/index.js +1 -0
- package/es6/src/reflection/index.js +3 -0
- package/es6/src/reflection/types/index.js +1 -0
- package/es6/src/reflection/types/reflection.types.js +8 -0
- package/es6/src/reflection/utilities.js +74 -0
- package/es6/src/semver/index.js +1 -0
- package/es6/src/semver/semver.js +71 -0
- package/es6/src/system/camel-case.js +3 -0
- package/es6/src/system/debounce.js +9 -0
- package/es6/src/system/decorator.js +30 -0
- package/es6/src/system/environment.js +5 -0
- package/es6/src/system/function.types.js +26 -0
- package/es6/src/system/index.js +7 -0
- package/es6/src/system/retry.decorator.js +30 -0
- package/es6/src/system/sleep.js +3 -0
- package/es6/src/system/type.utils.js +1 -0
- package/es6/src/testing/flush-promises.js +6 -0
- package/es6/src/testing/glob-with-memfs.js +20 -0
- package/es6/src/testing/index.js +5 -0
- package/es6/src/testing/memfs.js +25 -0
- package/es6/src/testing/mock-logger.js +26 -0
- package/es6/src/testing/spy-on-constructor.js +31 -0
- package/package.json +106 -0
- package/types/src/caching/cache-manager.d.ts +59 -0
- package/types/src/caching/cache.d.ts +11 -0
- package/types/src/caching/cache.decorator.d.ts +18 -0
- package/types/src/caching/index.d.ts +6 -0
- package/types/src/caching/invalidate-cache.decorator.d.ts +17 -0
- package/types/src/caching/memoize.decorator.d.ts +16 -0
- package/types/src/caching/node-cache-memoize.adapter.d.ts +22 -0
- package/types/src/cli/action.d.ts +36 -0
- package/types/src/cli/command.d.ts +34 -0
- package/types/src/cli/index.d.ts +7 -0
- package/types/src/cli/module.type.d.ts +36 -0
- package/types/src/cli/options.d.ts +28 -0
- package/types/src/collections/collections.d.ts +4 -0
- package/types/src/collections/find-duplicates.d.ts +2 -0
- package/types/src/collections/index.d.ts +1 -0
- package/types/src/collections/merge-arrays.d.ts +2 -0
- package/types/src/collections/sum.d.ts +4 -0
- package/types/src/collections/unique-objects.d.ts +2 -0
- package/types/src/composition/index.d.ts +37 -0
- package/types/src/configuration/configuration.types.d.ts +10 -0
- package/types/src/configuration/index.d.ts +1 -0
- package/types/src/diagnostics/index.d.ts +1 -0
- package/types/src/diagnostics/trace.d.ts +10 -0
- package/types/src/extensibility/decorator-factory-base.d.ts +39 -0
- package/types/src/extensibility/decorator-factory.d.ts +19 -0
- package/types/src/extensibility/extension.d.ts +9 -0
- package/types/src/extensibility/index.d.ts +6 -0
- package/types/src/extensibility/mixwith.d.ts +6 -0
- package/types/src/extensibility/pipeline.d.ts +12 -0
- package/types/src/extensibility/step.d.ts +16 -0
- package/types/src/interop/docker/docker.d.ts +19 -0
- package/types/src/interop/errors/interop.error.d.ts +2 -0
- package/types/src/interop/git/git.d.ts +16 -0
- package/types/src/interop/git/git.types.d.ts +14 -0
- package/types/src/interop/index.d.ts +14 -0
- package/types/src/interop/node/index.d.ts +1 -0
- package/types/src/interop/node/node.d.ts +5 -0
- package/types/src/interop/npm/npm.d.ts +29 -0
- package/types/src/interop/npm/npm.types.d.ts +24 -0
- package/types/src/interop/pnpm/pnpm.d.ts +9 -0
- package/types/src/interop/pnpm/pnpm.types.d.ts +3 -0
- package/types/src/interop/shell/shell.argv.d.ts +5 -0
- package/types/src/interop/shell/shell.d.ts +6 -0
- package/types/src/interop/shell/shell.types.d.ts +9 -0
- package/types/src/interop/types/detect-package-manager.d.ts +4 -0
- package/types/src/interop/types/package-manager.d.ts +10 -0
- package/types/src/interop/yarn/yarn.d.ts +9 -0
- package/types/src/interop/yarn/yarn.types.d.ts +3 -0
- package/types/src/io/copy-file.d.ts +4 -0
- package/types/src/io/delete-file.d.ts +1 -0
- package/types/src/io/directory-exists.d.ts +1 -0
- package/types/src/io/file-exists.d.ts +1 -0
- package/types/src/io/find-directories.d.ts +2 -0
- package/types/src/io/find-file.d.ts +9 -0
- package/types/src/io/index.d.ts +2 -0
- package/types/src/io/io.d.ts +11 -0
- package/types/src/io/read-file.d.ts +4 -0
- package/types/src/io/remove-dir.d.ts +5 -0
- package/types/src/io/types/directory.type.d.ts +4 -0
- package/types/src/io/types/file.d.ts +20 -0
- package/types/src/io/types/index.d.ts +2 -0
- package/types/src/io/url-to-path.d.ts +2 -0
- package/types/src/io/watch.d.ts +16 -0
- package/types/src/io/write-file.d.ts +5 -0
- package/types/src/objects/deep-merge.d.ts +41 -0
- package/types/src/objects/index.d.ts +1 -0
- package/types/src/reflection/index.d.ts +3 -0
- package/types/src/reflection/types/index.d.ts +1 -0
- package/types/src/reflection/types/reflection.types.d.ts +21 -0
- package/types/src/reflection/utilities.d.ts +27 -0
- package/types/src/semver/index.d.ts +1 -0
- package/types/src/semver/semver.d.ts +18 -0
- package/types/src/system/camel-case.d.ts +1 -0
- package/types/src/system/debounce.d.ts +1 -0
- package/types/src/system/decorator.d.ts +15 -0
- package/types/src/system/environment.d.ts +6 -0
- package/types/src/system/function.types.d.ts +55 -0
- package/types/src/system/index.d.ts +7 -0
- package/types/src/system/retry.decorator.d.ts +6 -0
- package/types/src/system/sleep.d.ts +1 -0
- package/types/src/system/type.utils.d.ts +1 -0
- package/types/src/testing/flush-promises.d.ts +1 -0
- package/types/src/testing/glob-with-memfs.d.ts +3 -0
- package/types/src/testing/index.d.ts +5 -0
- package/types/src/testing/memfs.d.ts +5 -0
- package/types/src/testing/mock-logger.d.ts +13 -0
- package/types/src/testing/spy-on-constructor.d.ts +21 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export const VersionTypes = {
|
|
2
|
+
major: "major",
|
|
3
|
+
minor: "minor",
|
|
4
|
+
patch: "patch",
|
|
5
|
+
prerelease: "prerelease"
|
|
6
|
+
};
|
|
7
|
+
export class SemverError extends Error {
|
|
8
|
+
constructor(message){
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = SemverError.name;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const SEMVER_REGEX = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/;
|
|
14
|
+
export class Semver {
|
|
15
|
+
version;
|
|
16
|
+
constructor(version){
|
|
17
|
+
this.ensureValid(version);
|
|
18
|
+
this.version = version;
|
|
19
|
+
}
|
|
20
|
+
increment(versionType, preid = "pre") {
|
|
21
|
+
const { major, minor, patch, prerelease } = this.parse(this.version);
|
|
22
|
+
if (versionType === "major") {
|
|
23
|
+
this.version = `${major + 1}.0.0`;
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
if (versionType === "minor") {
|
|
27
|
+
this.version = `${major}.${minor + 1}.0`;
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
if (versionType === "patch") {
|
|
31
|
+
this.version = `${major}.${minor}.${patch + 1}`;
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
if (prerelease == null) {
|
|
35
|
+
this.version = `${major}.${minor}.${patch + 1}-${preid}.0`;
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
const [identifier, ...rest] = prerelease.split(".");
|
|
39
|
+
const maybeCounter = rest.at(-1);
|
|
40
|
+
const counter = maybeCounter != null ? Number.parseInt(maybeCounter, 10) : Number.NaN;
|
|
41
|
+
if (identifier === preid && Number.isFinite(counter)) {
|
|
42
|
+
const nextCounter = counter + 1;
|
|
43
|
+
const prefix = rest.length > 1 ? `${rest.slice(0, -1).join(".")}.` : "";
|
|
44
|
+
this.version = `${major}.${minor}.${patch}-${preid}.${prefix}${nextCounter}`;
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
this.version = `${major}.${minor}.${patch}-${preid}.0`;
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
toString() {
|
|
51
|
+
return this.version;
|
|
52
|
+
}
|
|
53
|
+
ensureValid(version) {
|
|
54
|
+
if (SEMVER_REGEX.test(version)) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
throw new SemverError(`Invalid semantic version: ${version}`);
|
|
58
|
+
}
|
|
59
|
+
parse(version) {
|
|
60
|
+
const match = version.match(SEMVER_REGEX);
|
|
61
|
+
if (match == null) {
|
|
62
|
+
throw new SemverError(`Invalid semantic version: ${version}`);
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
major: Number.parseInt(match[1], 10),
|
|
66
|
+
minor: Number.parseInt(match[2], 10),
|
|
67
|
+
patch: Number.parseInt(match[3], 10),
|
|
68
|
+
prerelease: match[4]
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export class FunctionDecorator {
|
|
2
|
+
options;
|
|
3
|
+
constructor(){
|
|
4
|
+
this.decoratorFactory = this.decoratorFactory.bind(this);
|
|
5
|
+
}
|
|
6
|
+
decoratorFactory(options) {
|
|
7
|
+
this.options = options;
|
|
8
|
+
return this.decorator.bind(this);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Skips the decorated method decorator if any of the named environment variables equal "true".
|
|
13
|
+
* Useful for disabling decorators like @cache() during unit tests or via feature flags.
|
|
14
|
+
*
|
|
15
|
+
* @example @ignoreIf("TEST", "DISABLE_CACHE")
|
|
16
|
+
*/ export function ignoreIf(...envVars) {
|
|
17
|
+
return (_, __, descriptor)=>{
|
|
18
|
+
const originalFunction = descriptor.value;
|
|
19
|
+
descriptor.value = function(target, key, descriptor) {
|
|
20
|
+
if (envVars.some((v)=>process.env[v] === "true")) {
|
|
21
|
+
return descriptor;
|
|
22
|
+
}
|
|
23
|
+
return originalFunction.bind(this)(target, key, descriptor);
|
|
24
|
+
};
|
|
25
|
+
return descriptor;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/** @deprecated Use ignoreIf("TEST") instead */ export function ignoreDuringUnitTest() {
|
|
29
|
+
return ignoreIf("TEST");
|
|
30
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic function type that can replace arrow function signatures.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```typescript
|
|
6
|
+
* // Instead of: (arg1: string, arg2: number) => boolean
|
|
7
|
+
* type MyCallback = Func<[string, number], boolean>;
|
|
8
|
+
*
|
|
9
|
+
* // Instead of: (data: any) => void
|
|
10
|
+
* type MyHandler = Func<[any], void>;
|
|
11
|
+
*
|
|
12
|
+
* // Instead of: () => Promise<string>
|
|
13
|
+
* type MyAsyncFunc = Func<[], Promise<string>>;
|
|
14
|
+
* ```
|
|
15
|
+
*/ /**
|
|
16
|
+
* Action function type that returns void.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* // Instead of: (event: Event) => void
|
|
21
|
+
* type EventHandler = Action<[Event]>;
|
|
22
|
+
*
|
|
23
|
+
* // Instead of: () => void
|
|
24
|
+
* type Callback = Action<[]>;
|
|
25
|
+
* ```
|
|
26
|
+
*/ export { };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { FunctionDecorator } from "./decorator.js";
|
|
2
|
+
import { sleep } from "./sleep.js";
|
|
3
|
+
class RetryDecorator extends FunctionDecorator {
|
|
4
|
+
decorator(_target, _propertyKey, descriptor) {
|
|
5
|
+
const originalMethod = descriptor.value;
|
|
6
|
+
const attempts = Math.max(1, this.options?.attempts ?? 3);
|
|
7
|
+
const delayMs = Math.max(0, this.options?.delayMs ?? 0);
|
|
8
|
+
const shouldRetry = this.options?.shouldRetry ?? (()=>true);
|
|
9
|
+
descriptor.value = async function(...args) {
|
|
10
|
+
let lastError;
|
|
11
|
+
for(let attempt = 1; attempt <= attempts; attempt++){
|
|
12
|
+
try {
|
|
13
|
+
return await Promise.resolve(originalMethod.apply(this, args));
|
|
14
|
+
} catch (error) {
|
|
15
|
+
lastError = error;
|
|
16
|
+
const shouldAttemptAgain = attempt < attempts && shouldRetry(error);
|
|
17
|
+
if (!shouldAttemptAgain) {
|
|
18
|
+
throw error;
|
|
19
|
+
}
|
|
20
|
+
if (delayMs > 0) {
|
|
21
|
+
await sleep(delayMs);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
throw lastError;
|
|
26
|
+
};
|
|
27
|
+
return descriptor;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export const retry = new RetryDecorator().decoratorFactory;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { fs } from "memfs";
|
|
2
|
+
// Wraps a real `glob` module so all file-system access is routed through memfs.
|
|
3
|
+
//
|
|
4
|
+
// Why this exists:
|
|
5
|
+
// - Integration tests often need real glob matching semantics.
|
|
6
|
+
// - Vitest `vi.mock` factories are hoisted, so directly importing and patching
|
|
7
|
+
// `glob` inside helper modules can trigger initialization-order issues.
|
|
8
|
+
// - Passing the already-loaded `actual` module keeps the helper pure and
|
|
9
|
+
// hoist-safe while still allowing us to inject memfs.
|
|
10
|
+
export function withMemfsFsForGlob(actual) {
|
|
11
|
+
// Preserve all module exports, overriding only `glob` to force `{ fs: memfs }`.
|
|
12
|
+
const glob = (pattern, options)=>actual.glob(pattern, {
|
|
13
|
+
...options,
|
|
14
|
+
fs
|
|
15
|
+
});
|
|
16
|
+
return {
|
|
17
|
+
...actual,
|
|
18
|
+
glob
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { fs, vol } from "memfs";
|
|
2
|
+
export function resetMemfs() {
|
|
3
|
+
vol.reset();
|
|
4
|
+
}
|
|
5
|
+
export function seedMemfs(files) {
|
|
6
|
+
vol.fromJSON(files);
|
|
7
|
+
}
|
|
8
|
+
export function createTestFile(filePath, content) {
|
|
9
|
+
fs.mkdirSync(filePath.substring(0, filePath.lastIndexOf("/")), {
|
|
10
|
+
recursive: true
|
|
11
|
+
});
|
|
12
|
+
fs.writeFileSync(filePath, content);
|
|
13
|
+
}
|
|
14
|
+
export async function readFile(filePath) {
|
|
15
|
+
const response = await fs.promises.readFile(filePath, "utf8");
|
|
16
|
+
return response;
|
|
17
|
+
}
|
|
18
|
+
export function fileExists(filePath) {
|
|
19
|
+
try {
|
|
20
|
+
vol.statSync(filePath);
|
|
21
|
+
return true;
|
|
22
|
+
} catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { vi } from "vitest";
|
|
2
|
+
const DefaultLogLevels = {
|
|
3
|
+
fatal: 60,
|
|
4
|
+
error: 50,
|
|
5
|
+
warn: 40,
|
|
6
|
+
info: 30,
|
|
7
|
+
debug: 20,
|
|
8
|
+
trace: 10
|
|
9
|
+
};
|
|
10
|
+
export function createMockLogger() {
|
|
11
|
+
return {
|
|
12
|
+
error: vi.fn(),
|
|
13
|
+
info: vi.fn(),
|
|
14
|
+
warn: vi.fn(),
|
|
15
|
+
debug: vi.fn(),
|
|
16
|
+
trace: vi.fn(),
|
|
17
|
+
fatal: vi.fn(),
|
|
18
|
+
isLevelEnabled: vi.fn().mockReturnValue(true),
|
|
19
|
+
get currentLevel () {
|
|
20
|
+
return "info";
|
|
21
|
+
},
|
|
22
|
+
get logLevels () {
|
|
23
|
+
return DefaultLogLevels;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { vi } from "vitest";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a Proxy around a class constructor that intercepts `new` calls,
|
|
4
|
+
* records arguments via a spy, and delegates to the real constructor.
|
|
5
|
+
*
|
|
6
|
+
* Use this to assert what was injected into a class by a DI container
|
|
7
|
+
* (e.g. Container) without changing actual behavior.
|
|
8
|
+
*
|
|
9
|
+
* The proxy copies all `reflect-metadata` entries from the original class
|
|
10
|
+
* so that DI metadata (`design:paramtypes`) remains intact.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* const { spy, Proxy: SpiedService } = spyOnConstructor(MyService);
|
|
14
|
+
* // use SpiedService in place of MyService when wiring the container
|
|
15
|
+
* expect(spy).toHaveBeenCalledWith(expect.any(ExpectedDependency));
|
|
16
|
+
*/ export function spyOnConstructor(Target) {
|
|
17
|
+
const spy = vi.fn();
|
|
18
|
+
const ProxiedTarget = new Proxy(Target, {
|
|
19
|
+
construct (Ctor, args) {
|
|
20
|
+
spy(...args);
|
|
21
|
+
return Reflect.construct(Ctor, args);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
for (const key of Reflect.getMetadataKeys(Target)){
|
|
25
|
+
Reflect.defineMetadata(key, Reflect.getMetadata(key, Target), ProxiedTarget);
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
spy,
|
|
29
|
+
Proxy: ProxiedTarget
|
|
30
|
+
};
|
|
31
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@decohere/core",
|
|
3
|
+
"version": "0.0.1-dev.116",
|
|
4
|
+
"description": "Core utility library — collections, caching, IO, CLI primitives, reflection, and composition",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"typescript",
|
|
7
|
+
"utilities",
|
|
8
|
+
"collections",
|
|
9
|
+
"caching",
|
|
10
|
+
"io",
|
|
11
|
+
"cli",
|
|
12
|
+
"reflection",
|
|
13
|
+
"decohere"
|
|
14
|
+
],
|
|
15
|
+
"license": "ISC",
|
|
16
|
+
"author": "Typesmiths",
|
|
17
|
+
"type": "module",
|
|
18
|
+
"main": "index.js",
|
|
19
|
+
"exports": {
|
|
20
|
+
"./collections": {
|
|
21
|
+
"types": "./types/src/collections/index.d.ts",
|
|
22
|
+
"import": "./es6/src/collections/index.js",
|
|
23
|
+
"require": "./commonjs/src/collections/index.js"
|
|
24
|
+
},
|
|
25
|
+
"./caching": {
|
|
26
|
+
"types": "./types/src/caching/index.d.ts",
|
|
27
|
+
"import": "./es6/src/caching/index.js",
|
|
28
|
+
"require": "./commonjs/src/caching/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./configuration": {
|
|
31
|
+
"types": "./types/src/configuration/index.d.ts",
|
|
32
|
+
"import": "./es6/src/configuration/index.js",
|
|
33
|
+
"require": "./commonjs/src/configuration/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./extensibility": {
|
|
36
|
+
"types": "./types/src/extensibility/index.d.ts",
|
|
37
|
+
"import": "./es6/src/extensibility/index.js",
|
|
38
|
+
"require": "./commonjs/src/extensibility/index.js"
|
|
39
|
+
},
|
|
40
|
+
"./interop": {
|
|
41
|
+
"types": "./types/src/interop/index.d.ts",
|
|
42
|
+
"import": "./es6/src/interop/index.js",
|
|
43
|
+
"require": "./commonjs/src/interop/index.js"
|
|
44
|
+
},
|
|
45
|
+
"./io": {
|
|
46
|
+
"types": "./types/src/io/index.d.ts",
|
|
47
|
+
"import": "./es6/src/io/index.js",
|
|
48
|
+
"require": "./commonjs/src/io/index.js"
|
|
49
|
+
},
|
|
50
|
+
"./objects": {
|
|
51
|
+
"types": "./types/src/objects/index.d.ts",
|
|
52
|
+
"import": "./es6/src/objects/index.js",
|
|
53
|
+
"require": "./commonjs/src/objects/index.js"
|
|
54
|
+
},
|
|
55
|
+
"./reflection": {
|
|
56
|
+
"types": "./types/src/reflection/index.d.ts",
|
|
57
|
+
"import": "./es6/src/reflection/index.js",
|
|
58
|
+
"require": "./commonjs/src/reflection/index.js"
|
|
59
|
+
},
|
|
60
|
+
"./system": {
|
|
61
|
+
"types": "./types/src/system/index.d.ts",
|
|
62
|
+
"import": "./es6/src/system/index.js",
|
|
63
|
+
"require": "./commonjs/src/system/index.js"
|
|
64
|
+
},
|
|
65
|
+
"./semver": {
|
|
66
|
+
"types": "./types/src/semver/index.d.ts",
|
|
67
|
+
"import": "./es6/src/semver/index.js",
|
|
68
|
+
"require": "./commonjs/src/semver/index.js"
|
|
69
|
+
},
|
|
70
|
+
"./testing": {
|
|
71
|
+
"types": "./types/src/testing/index.d.ts",
|
|
72
|
+
"import": "./es6/src/testing/index.js",
|
|
73
|
+
"require": "./commonjs/src/testing/index.js"
|
|
74
|
+
},
|
|
75
|
+
"./composition": {
|
|
76
|
+
"types": "./types/src/composition/index.d.ts",
|
|
77
|
+
"import": "./es6/src/composition/index.js",
|
|
78
|
+
"require": "./commonjs/src/composition/index.js"
|
|
79
|
+
},
|
|
80
|
+
"./cli": {
|
|
81
|
+
"types": "./types/src/cli/index.d.ts",
|
|
82
|
+
"import": "./es6/src/cli/index.js",
|
|
83
|
+
"require": "./commonjs/src/cli/index.js"
|
|
84
|
+
},
|
|
85
|
+
"./diagnostics": {
|
|
86
|
+
"types": "./types/src/diagnostics/index.d.ts",
|
|
87
|
+
"import": "./es6/src/diagnostics/index.js",
|
|
88
|
+
"require": "./commonjs/src/diagnostics/index.js"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"scripts": {
|
|
92
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
93
|
+
},
|
|
94
|
+
"dependencies": {
|
|
95
|
+
"@cacheable/node-cache": "^2.0.1",
|
|
96
|
+
"@decohere/scribe": "0.0.1-dev.116",
|
|
97
|
+
"commander": "^13.1.0",
|
|
98
|
+
"glob": "^13.0.1",
|
|
99
|
+
"picomatch": "^4.0.4",
|
|
100
|
+
"reflect-metadata": "^0.2.2"
|
|
101
|
+
},
|
|
102
|
+
"devDependencies": {
|
|
103
|
+
"memfs": "^4.17.0",
|
|
104
|
+
"vitest": "^3.2.6"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ICache } from "./cache.js";
|
|
2
|
+
export declare const Caches: {
|
|
3
|
+
readonly default: "DEFAULT";
|
|
4
|
+
readonly memoize: "MEMOIZE_CACHE";
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Central cache manager for managing named cache instances
|
|
8
|
+
*/
|
|
9
|
+
declare class CacheManager {
|
|
10
|
+
private caches;
|
|
11
|
+
private readonly defaultCacheName;
|
|
12
|
+
/**
|
|
13
|
+
* Set a cache instance with the given name
|
|
14
|
+
* @param name - The name of the cache
|
|
15
|
+
* @param cache - The cache instance
|
|
16
|
+
*/
|
|
17
|
+
setCache(name: string, cache: ICache): void;
|
|
18
|
+
/**
|
|
19
|
+
* Get a cache instance by name
|
|
20
|
+
* @param name - The name of the cache, defaults to "DEFAULT"
|
|
21
|
+
* @returns The cache instance
|
|
22
|
+
*/
|
|
23
|
+
getCache(name?: string, memoize?: boolean): ICache;
|
|
24
|
+
/**
|
|
25
|
+
* Clear a cache by name. If no name is provided, clears the default cache.
|
|
26
|
+
* Note: This only works if the cache implements a clear() method.
|
|
27
|
+
* @param name - The name of the cache to clear
|
|
28
|
+
*/
|
|
29
|
+
flush(name?: string): void;
|
|
30
|
+
flushAllCaches(): void;
|
|
31
|
+
/**
|
|
32
|
+
* Remove a cache instance by name
|
|
33
|
+
* @param name - The name of the cache to remove
|
|
34
|
+
*/
|
|
35
|
+
removeCache(name: string): void;
|
|
36
|
+
/**
|
|
37
|
+
* Check if a cache with the given name exists
|
|
38
|
+
* @param name - The name of the cache
|
|
39
|
+
* @returns True if the cache exists, false otherwise
|
|
40
|
+
*/
|
|
41
|
+
hasCache(name: string): boolean;
|
|
42
|
+
private readonly instanceIds;
|
|
43
|
+
private instanceIdCounter;
|
|
44
|
+
/**
|
|
45
|
+
* Generate a cache key for a given instance, function name, and arguments.
|
|
46
|
+
* Each instance receives a stable numeric ID so cache entries are never
|
|
47
|
+
* shared across instances of the same class.
|
|
48
|
+
* @param instance - The class instance (`this` at call time)
|
|
49
|
+
* @param functionName - The name of the decorated method
|
|
50
|
+
* @param args - The method arguments
|
|
51
|
+
* @returns A unique cache key string
|
|
52
|
+
*/
|
|
53
|
+
generateCacheKey(instance: object, functionName: string, args: unknown[]): string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Singleton instance of the cache manager
|
|
57
|
+
*/
|
|
58
|
+
export declare const Caching: CacheManager;
|
|
59
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for cache implementations used by the @cache() decorator
|
|
3
|
+
*/
|
|
4
|
+
export interface ICache {
|
|
5
|
+
get(key: string): unknown;
|
|
6
|
+
set(key: string, value: unknown): void;
|
|
7
|
+
has(key: string): boolean;
|
|
8
|
+
del(key: string): void;
|
|
9
|
+
flushAll(): any;
|
|
10
|
+
get isMemoize(): boolean;
|
|
11
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FunctionDecorator } from "../system/decorator.js";
|
|
2
|
+
import type { ICache } from "./cache.js";
|
|
3
|
+
/**
|
|
4
|
+
* Options for configuring the @cache() decorator
|
|
5
|
+
*/
|
|
6
|
+
export interface CacheOptions {
|
|
7
|
+
cache?: ICache;
|
|
8
|
+
name?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Custom key function. When provided, replaces the default instance-scoped key
|
|
11
|
+
* with a caller-defined key, enabling cross-instance cache sharing.
|
|
12
|
+
*/
|
|
13
|
+
keyFn?: (...args: unknown[]) => string;
|
|
14
|
+
}
|
|
15
|
+
export declare class CacheDecorator extends FunctionDecorator<CacheOptions> {
|
|
16
|
+
decorator(_target: object, propertyKey: string, descriptor: PropertyDescriptor): void;
|
|
17
|
+
}
|
|
18
|
+
export declare const cache: (options?: CacheOptions) => any;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { FunctionDecorator } from "../system/decorator.js";
|
|
2
|
+
import type { CacheOptions } from "./cache.decorator.js";
|
|
3
|
+
type InvalidateCacheOptions = CacheOptions & {
|
|
4
|
+
getKey: (instance: object, args: unknown[]) => string;
|
|
5
|
+
};
|
|
6
|
+
export declare class InvalidateCacheDecorator extends FunctionDecorator<InvalidateCacheOptions> {
|
|
7
|
+
decorator(_target: object, _propertyKey: string, descriptor: PropertyDescriptor): void;
|
|
8
|
+
}
|
|
9
|
+
export declare const invalidateCache: {
|
|
10
|
+
(method: string | ((...args: never[]) => unknown), options?: CacheOptions): any;
|
|
11
|
+
evict(instance: object, method: (...args: never[]) => unknown, args?: unknown[]): void;
|
|
12
|
+
};
|
|
13
|
+
export declare const invalidateMemoize: {
|
|
14
|
+
(method: string | ((...args: never[]) => unknown), options?: CacheOptions): any;
|
|
15
|
+
evict(instance: object, method: (...args: never[]) => unknown, args?: unknown[]): void;
|
|
16
|
+
};
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CacheDecorator } from "./cache.decorator.js";
|
|
2
|
+
/**
|
|
3
|
+
* Memoize decorator class that extends CacheDecorator with memoization support
|
|
4
|
+
* Automatically uses a memoization-capable cache (NodeCache with useClones: false)
|
|
5
|
+
*/
|
|
6
|
+
export declare class MemoizeDecorator extends CacheDecorator {
|
|
7
|
+
decorator(target: object, propertyKey: string, descriptor: PropertyDescriptor): void;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Memoize decorator factory
|
|
11
|
+
* Provides true memoization by storing object references instead of clones
|
|
12
|
+
*
|
|
13
|
+
* @param options - Optional configuration for the memoize decorator
|
|
14
|
+
* @returns Decorator function
|
|
15
|
+
*/
|
|
16
|
+
export declare const memoize: (options?: import("./cache.decorator.js").CacheOptions) => any;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import NodeCache from "@cacheable/node-cache";
|
|
2
|
+
import type { ICache } from "./cache.js";
|
|
3
|
+
type NodeCacheMemoizeOptions = {
|
|
4
|
+
enableMemoization: boolean;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* NodeCache adapter configured for memoization (useClones: false)
|
|
8
|
+
* This allows storing object references instead of clones for true memoization
|
|
9
|
+
*/
|
|
10
|
+
export declare class NodeCacheAdapter implements ICache {
|
|
11
|
+
static create(options?: NodeCacheMemoizeOptions): NodeCacheAdapter;
|
|
12
|
+
readonly supportsMemoization: true;
|
|
13
|
+
private cache;
|
|
14
|
+
constructor(inst?: NodeCache<unknown>);
|
|
15
|
+
get isMemoize(): boolean;
|
|
16
|
+
get(key: string): unknown;
|
|
17
|
+
set(key: string, value: unknown): void;
|
|
18
|
+
has(key: string): boolean;
|
|
19
|
+
del(key: string): void;
|
|
20
|
+
flushAll(): void;
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Constructable } from "../reflection/index.js";
|
|
2
|
+
import type { UnionToIntersection } from "../system/type.utils.js";
|
|
3
|
+
export declare const ActionMap: unique symbol;
|
|
4
|
+
export type ActionClassMap = Record<string, Constructable<Action>>;
|
|
5
|
+
export interface ResultStatus {
|
|
6
|
+
succeeded: boolean;
|
|
7
|
+
error?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface Result {
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly succeeded: boolean;
|
|
12
|
+
readonly skipped: boolean;
|
|
13
|
+
readonly message: string;
|
|
14
|
+
}
|
|
15
|
+
export declare class ActionResponse<TData = unknown> implements Result {
|
|
16
|
+
static Success<TData>(name: string, data?: TData[]): ActionResponse<TData>;
|
|
17
|
+
static Skipped(name: string): ActionResponse<unknown>;
|
|
18
|
+
static Blocking(name: string): ActionResponse<unknown>;
|
|
19
|
+
static Error<TData = unknown>(name: string, message: string): ActionResponse<TData>;
|
|
20
|
+
static Error<TData extends ResultStatus>(name: string, data: TData[]): ActionResponse<TData>;
|
|
21
|
+
constructor(data: Partial<ActionResponse<TData>>);
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly succeeded: boolean;
|
|
24
|
+
readonly skipped: boolean;
|
|
25
|
+
readonly blocking: boolean;
|
|
26
|
+
readonly message: string;
|
|
27
|
+
readonly data: TData[];
|
|
28
|
+
}
|
|
29
|
+
export interface Action<T extends object = object> {
|
|
30
|
+
run(options: T): Promise<ActionResponse>;
|
|
31
|
+
}
|
|
32
|
+
export type Actions = Record<string, Action>;
|
|
33
|
+
export type ActionOptions<A extends Action> = A extends Action<infer T> ? T : never;
|
|
34
|
+
export type MergeOptions<TActions extends Record<string, Action>> = UnionToIntersection<{
|
|
35
|
+
[K in keyof TActions]: ActionOptions<TActions[K]>;
|
|
36
|
+
}[keyof TActions]>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Command as CommanderType, type OptionValues } from "commander";
|
|
2
|
+
import type { Constructable } from "../reflection/index.js";
|
|
3
|
+
import type { ActionResponse, Actions } from "./action.js";
|
|
4
|
+
export type CommandType = Constructable<DecohereCommand>;
|
|
5
|
+
export type CommandHandler = (opts: OptionValues, cmd: DecohereCommand) => Promise<void>;
|
|
6
|
+
export type CommandResponse<TActions extends Actions = Actions> = {
|
|
7
|
+
[ActionName in keyof TActions]?: ActionResponse;
|
|
8
|
+
};
|
|
9
|
+
export declare const CommandResponse: {
|
|
10
|
+
success<T extends Actions>(_ctx: unknown, responses: CommandResponse<T>): CommandResponse<T>;
|
|
11
|
+
help<T extends Actions = Actions>(): CommandResponse<T>;
|
|
12
|
+
fromAction(name: string, response: ActionResponse): CommandResponse;
|
|
13
|
+
};
|
|
14
|
+
/** Thrown when a command execution fails due to action errors. */
|
|
15
|
+
export declare class CommandError extends Error {
|
|
16
|
+
}
|
|
17
|
+
export declare class DecohereCommand<TActions extends Actions = Actions> extends CommanderType {
|
|
18
|
+
get actions(): readonly Constructable<import("./action.js").Action>[];
|
|
19
|
+
constructor(name?: string | Constructable | Record<string, CommandType>, handler?: CommandHandler);
|
|
20
|
+
/**
|
|
21
|
+
* Whether the command, with these options, runs until it is stopped (`flux serve`,
|
|
22
|
+
* `forge build --watch`). The CLI then listens for SIGINT and SIGTERM from the moment it
|
|
23
|
+
* starts, so a stop during start-up still shuts down cleanly; other commands keep Node's
|
|
24
|
+
* default, where Ctrl+C ends them at once.
|
|
25
|
+
*/
|
|
26
|
+
runsUntilStopped(_options: OptionValues): boolean;
|
|
27
|
+
run(actions: TActions, options: OptionValues): Promise<CommandResponse<TActions>>;
|
|
28
|
+
registerSubcommand(command: CommandType, onAction?: CommandHandler): void;
|
|
29
|
+
registerSubcommand(commands: Record<string, DecohereCommand | CommandType>, onAction?: CommandHandler): void;
|
|
30
|
+
protected runActions(actions: TActions, options: OptionValues): Promise<CommandResponse<TActions>>;
|
|
31
|
+
protected getSelectedActions(actions: TActions): Array<[keyof TActions, TActions[keyof TActions]]>;
|
|
32
|
+
protected throwOnErrors(responses: CommandResponse<TActions>): void;
|
|
33
|
+
private parseCommandName;
|
|
34
|
+
}
|