@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.
Files changed (262) hide show
  1. package/commonjs/src/caching/cache-manager.js +98 -0
  2. package/commonjs/src/caching/cache.decorator.js +69 -0
  3. package/commonjs/src/caching/cache.js +6 -0
  4. package/commonjs/src/caching/index.js +23 -0
  5. package/commonjs/src/caching/invalidate-cache.decorator.js +92 -0
  6. package/commonjs/src/caching/memoize.decorator.js +36 -0
  7. package/commonjs/src/caching/node-cache-memoize.adapter.js +49 -0
  8. package/commonjs/src/cli/action.js +65 -0
  9. package/commonjs/src/cli/command.js +127 -0
  10. package/commonjs/src/cli/index.js +61 -0
  11. package/commonjs/src/cli/module.type.js +18 -0
  12. package/commonjs/src/cli/options.js +115 -0
  13. package/commonjs/src/collections/collections.js +21 -0
  14. package/commonjs/src/collections/find-duplicates.js +35 -0
  15. package/commonjs/src/collections/index.js +52 -0
  16. package/commonjs/src/collections/merge-arrays.js +34 -0
  17. package/commonjs/src/collections/sum.js +63 -0
  18. package/commonjs/src/collections/unique-objects.js +39 -0
  19. package/commonjs/src/composition/index.js +4 -0
  20. package/commonjs/src/configuration/configuration.types.js +11 -0
  21. package/commonjs/src/configuration/index.js +18 -0
  22. package/commonjs/src/diagnostics/index.js +22 -0
  23. package/commonjs/src/diagnostics/trace.js +86 -0
  24. package/commonjs/src/extensibility/decorator-factory-base.js +22 -0
  25. package/commonjs/src/extensibility/decorator-factory.js +31 -0
  26. package/commonjs/src/extensibility/extension.js +37 -0
  27. package/commonjs/src/extensibility/index.js +23 -0
  28. package/commonjs/src/extensibility/mixwith.js +36 -0
  29. package/commonjs/src/extensibility/pipeline.js +56 -0
  30. package/commonjs/src/extensibility/step.js +18 -0
  31. package/commonjs/src/interop/docker/docker.js +54 -0
  32. package/commonjs/src/interop/errors/interop.error.js +12 -0
  33. package/commonjs/src/interop/git/git.js +134 -0
  34. package/commonjs/src/interop/git/git.types.js +4 -0
  35. package/commonjs/src/interop/index.js +97 -0
  36. package/commonjs/src/interop/node/index.js +18 -0
  37. package/commonjs/src/interop/node/node.js +45 -0
  38. package/commonjs/src/interop/npm/npm.js +231 -0
  39. package/commonjs/src/interop/npm/npm.types.js +16 -0
  40. package/commonjs/src/interop/pnpm/pnpm.js +34 -0
  41. package/commonjs/src/interop/pnpm/pnpm.types.js +4 -0
  42. package/commonjs/src/interop/shell/shell.argv.js +45 -0
  43. package/commonjs/src/interop/shell/shell.js +105 -0
  44. package/commonjs/src/interop/shell/shell.types.js +4 -0
  45. package/commonjs/src/interop/types/detect-package-manager.js +71 -0
  46. package/commonjs/src/interop/types/package-manager.js +4 -0
  47. package/commonjs/src/interop/yarn/yarn.js +34 -0
  48. package/commonjs/src/interop/yarn/yarn.types.js +4 -0
  49. package/commonjs/src/io/copy-file.js +25 -0
  50. package/commonjs/src/io/delete-file.js +21 -0
  51. package/commonjs/src/io/directory-exists.js +24 -0
  52. package/commonjs/src/io/file-exists.js +19 -0
  53. package/commonjs/src/io/find-directories.js +21 -0
  54. package/commonjs/src/io/find-file.js +45 -0
  55. package/commonjs/src/io/index.js +66 -0
  56. package/commonjs/src/io/io.js +28 -0
  57. package/commonjs/src/io/read-file.js +39 -0
  58. package/commonjs/src/io/remove-dir.js +22 -0
  59. package/commonjs/src/io/types/directory.type.js +4 -0
  60. package/commonjs/src/io/types/file.js +28 -0
  61. package/commonjs/src/io/types/index.js +19 -0
  62. package/commonjs/src/io/url-to-path.js +33 -0
  63. package/commonjs/src/io/watch.js +261 -0
  64. package/commonjs/src/io/write-file.js +30 -0
  65. package/commonjs/src/objects/deep-merge.js +67 -0
  66. package/commonjs/src/objects/index.js +11 -0
  67. package/commonjs/src/reflection/index.js +20 -0
  68. package/commonjs/src/reflection/types/index.js +18 -0
  69. package/commonjs/src/reflection/types/reflection.types.js +26 -0
  70. package/commonjs/src/reflection/utilities.js +118 -0
  71. package/commonjs/src/semver/index.js +18 -0
  72. package/commonjs/src/semver/semver.js +92 -0
  73. package/commonjs/src/system/camel-case.js +13 -0
  74. package/commonjs/src/system/debounce.js +19 -0
  75. package/commonjs/src/system/decorator.js +46 -0
  76. package/commonjs/src/system/environment.js +23 -0
  77. package/commonjs/src/system/function.types.js +18 -0
  78. package/commonjs/src/system/index.js +24 -0
  79. package/commonjs/src/system/retry.decorator.js +40 -0
  80. package/commonjs/src/system/sleep.js +13 -0
  81. package/commonjs/src/system/type.utils.js +4 -0
  82. package/commonjs/src/testing/flush-promises.js +16 -0
  83. package/commonjs/src/testing/glob-with-memfs.js +22 -0
  84. package/commonjs/src/testing/index.js +22 -0
  85. package/commonjs/src/testing/memfs.js +52 -0
  86. package/commonjs/src/testing/mock-logger.js +36 -0
  87. package/commonjs/src/testing/spy-on-constructor.js +27 -0
  88. package/es6/src/caching/cache-manager.js +82 -0
  89. package/es6/src/caching/cache.decorator.js +51 -0
  90. package/es6/src/caching/cache.js +3 -0
  91. package/es6/src/caching/index.js +6 -0
  92. package/es6/src/caching/invalidate-cache.decorator.js +71 -0
  93. package/es6/src/caching/memoize.decorator.js +27 -0
  94. package/es6/src/caching/node-cache-memoize.adapter.js +37 -0
  95. package/es6/src/cli/action.js +47 -0
  96. package/es6/src/cli/command.js +106 -0
  97. package/es6/src/cli/index.js +4 -0
  98. package/es6/src/cli/module.type.js +11 -0
  99. package/es6/src/cli/options.js +76 -0
  100. package/es6/src/collections/collections.js +4 -0
  101. package/es6/src/collections/find-duplicates.js +17 -0
  102. package/es6/src/collections/index.js +1 -0
  103. package/es6/src/collections/merge-arrays.js +16 -0
  104. package/es6/src/collections/sum.js +45 -0
  105. package/es6/src/collections/unique-objects.js +21 -0
  106. package/es6/src/composition/index.js +1 -0
  107. package/es6/src/configuration/configuration.types.js +1 -0
  108. package/es6/src/configuration/index.js +1 -0
  109. package/es6/src/diagnostics/index.js +1 -0
  110. package/es6/src/diagnostics/trace.js +68 -0
  111. package/es6/src/extensibility/decorator-factory-base.js +39 -0
  112. package/es6/src/extensibility/decorator-factory.js +21 -0
  113. package/es6/src/extensibility/extension.js +27 -0
  114. package/es6/src/extensibility/index.js +6 -0
  115. package/es6/src/extensibility/mixwith.js +26 -0
  116. package/es6/src/extensibility/pipeline.js +46 -0
  117. package/es6/src/extensibility/step.js +16 -0
  118. package/es6/src/interop/docker/docker.js +44 -0
  119. package/es6/src/interop/errors/interop.error.js +2 -0
  120. package/es6/src/interop/git/git.js +124 -0
  121. package/es6/src/interop/git/git.types.js +1 -0
  122. package/es6/src/interop/index.js +21 -0
  123. package/es6/src/interop/node/index.js +1 -0
  124. package/es6/src/interop/node/node.js +35 -0
  125. package/es6/src/interop/npm/npm.js +180 -0
  126. package/es6/src/interop/npm/npm.types.js +6 -0
  127. package/es6/src/interop/pnpm/pnpm.js +24 -0
  128. package/es6/src/interop/pnpm/pnpm.types.js +1 -0
  129. package/es6/src/interop/shell/shell.argv.js +35 -0
  130. package/es6/src/interop/shell/shell.js +95 -0
  131. package/es6/src/interop/shell/shell.types.js +1 -0
  132. package/es6/src/interop/types/detect-package-manager.js +50 -0
  133. package/es6/src/interop/types/package-manager.js +1 -0
  134. package/es6/src/interop/yarn/yarn.js +24 -0
  135. package/es6/src/interop/yarn/yarn.types.js +1 -0
  136. package/es6/src/io/copy-file.js +10 -0
  137. package/es6/src/io/delete-file.js +6 -0
  138. package/es6/src/io/directory-exists.js +9 -0
  139. package/es6/src/io/file-exists.js +9 -0
  140. package/es6/src/io/find-directories.js +11 -0
  141. package/es6/src/io/find-file.js +27 -0
  142. package/es6/src/io/index.js +2 -0
  143. package/es6/src/io/io.js +11 -0
  144. package/es6/src/io/read-file.js +13 -0
  145. package/es6/src/io/remove-dir.js +7 -0
  146. package/es6/src/io/types/directory.type.js +1 -0
  147. package/es6/src/io/types/file.js +18 -0
  148. package/es6/src/io/types/index.js +2 -0
  149. package/es6/src/io/url-to-path.js +15 -0
  150. package/es6/src/io/watch.js +238 -0
  151. package/es6/src/io/write-file.js +15 -0
  152. package/es6/src/objects/deep-merge.js +57 -0
  153. package/es6/src/objects/index.js +1 -0
  154. package/es6/src/reflection/index.js +3 -0
  155. package/es6/src/reflection/types/index.js +1 -0
  156. package/es6/src/reflection/types/reflection.types.js +8 -0
  157. package/es6/src/reflection/utilities.js +74 -0
  158. package/es6/src/semver/index.js +1 -0
  159. package/es6/src/semver/semver.js +71 -0
  160. package/es6/src/system/camel-case.js +3 -0
  161. package/es6/src/system/debounce.js +9 -0
  162. package/es6/src/system/decorator.js +30 -0
  163. package/es6/src/system/environment.js +5 -0
  164. package/es6/src/system/function.types.js +26 -0
  165. package/es6/src/system/index.js +7 -0
  166. package/es6/src/system/retry.decorator.js +30 -0
  167. package/es6/src/system/sleep.js +3 -0
  168. package/es6/src/system/type.utils.js +1 -0
  169. package/es6/src/testing/flush-promises.js +6 -0
  170. package/es6/src/testing/glob-with-memfs.js +20 -0
  171. package/es6/src/testing/index.js +5 -0
  172. package/es6/src/testing/memfs.js +25 -0
  173. package/es6/src/testing/mock-logger.js +26 -0
  174. package/es6/src/testing/spy-on-constructor.js +31 -0
  175. package/package.json +106 -0
  176. package/types/src/caching/cache-manager.d.ts +59 -0
  177. package/types/src/caching/cache.d.ts +11 -0
  178. package/types/src/caching/cache.decorator.d.ts +18 -0
  179. package/types/src/caching/index.d.ts +6 -0
  180. package/types/src/caching/invalidate-cache.decorator.d.ts +17 -0
  181. package/types/src/caching/memoize.decorator.d.ts +16 -0
  182. package/types/src/caching/node-cache-memoize.adapter.d.ts +22 -0
  183. package/types/src/cli/action.d.ts +36 -0
  184. package/types/src/cli/command.d.ts +34 -0
  185. package/types/src/cli/index.d.ts +7 -0
  186. package/types/src/cli/module.type.d.ts +36 -0
  187. package/types/src/cli/options.d.ts +28 -0
  188. package/types/src/collections/collections.d.ts +4 -0
  189. package/types/src/collections/find-duplicates.d.ts +2 -0
  190. package/types/src/collections/index.d.ts +1 -0
  191. package/types/src/collections/merge-arrays.d.ts +2 -0
  192. package/types/src/collections/sum.d.ts +4 -0
  193. package/types/src/collections/unique-objects.d.ts +2 -0
  194. package/types/src/composition/index.d.ts +37 -0
  195. package/types/src/configuration/configuration.types.d.ts +10 -0
  196. package/types/src/configuration/index.d.ts +1 -0
  197. package/types/src/diagnostics/index.d.ts +1 -0
  198. package/types/src/diagnostics/trace.d.ts +10 -0
  199. package/types/src/extensibility/decorator-factory-base.d.ts +39 -0
  200. package/types/src/extensibility/decorator-factory.d.ts +19 -0
  201. package/types/src/extensibility/extension.d.ts +9 -0
  202. package/types/src/extensibility/index.d.ts +6 -0
  203. package/types/src/extensibility/mixwith.d.ts +6 -0
  204. package/types/src/extensibility/pipeline.d.ts +12 -0
  205. package/types/src/extensibility/step.d.ts +16 -0
  206. package/types/src/interop/docker/docker.d.ts +19 -0
  207. package/types/src/interop/errors/interop.error.d.ts +2 -0
  208. package/types/src/interop/git/git.d.ts +16 -0
  209. package/types/src/interop/git/git.types.d.ts +14 -0
  210. package/types/src/interop/index.d.ts +14 -0
  211. package/types/src/interop/node/index.d.ts +1 -0
  212. package/types/src/interop/node/node.d.ts +5 -0
  213. package/types/src/interop/npm/npm.d.ts +29 -0
  214. package/types/src/interop/npm/npm.types.d.ts +24 -0
  215. package/types/src/interop/pnpm/pnpm.d.ts +9 -0
  216. package/types/src/interop/pnpm/pnpm.types.d.ts +3 -0
  217. package/types/src/interop/shell/shell.argv.d.ts +5 -0
  218. package/types/src/interop/shell/shell.d.ts +6 -0
  219. package/types/src/interop/shell/shell.types.d.ts +9 -0
  220. package/types/src/interop/types/detect-package-manager.d.ts +4 -0
  221. package/types/src/interop/types/package-manager.d.ts +10 -0
  222. package/types/src/interop/yarn/yarn.d.ts +9 -0
  223. package/types/src/interop/yarn/yarn.types.d.ts +3 -0
  224. package/types/src/io/copy-file.d.ts +4 -0
  225. package/types/src/io/delete-file.d.ts +1 -0
  226. package/types/src/io/directory-exists.d.ts +1 -0
  227. package/types/src/io/file-exists.d.ts +1 -0
  228. package/types/src/io/find-directories.d.ts +2 -0
  229. package/types/src/io/find-file.d.ts +9 -0
  230. package/types/src/io/index.d.ts +2 -0
  231. package/types/src/io/io.d.ts +11 -0
  232. package/types/src/io/read-file.d.ts +4 -0
  233. package/types/src/io/remove-dir.d.ts +5 -0
  234. package/types/src/io/types/directory.type.d.ts +4 -0
  235. package/types/src/io/types/file.d.ts +20 -0
  236. package/types/src/io/types/index.d.ts +2 -0
  237. package/types/src/io/url-to-path.d.ts +2 -0
  238. package/types/src/io/watch.d.ts +16 -0
  239. package/types/src/io/write-file.d.ts +5 -0
  240. package/types/src/objects/deep-merge.d.ts +41 -0
  241. package/types/src/objects/index.d.ts +1 -0
  242. package/types/src/reflection/index.d.ts +3 -0
  243. package/types/src/reflection/types/index.d.ts +1 -0
  244. package/types/src/reflection/types/reflection.types.d.ts +21 -0
  245. package/types/src/reflection/utilities.d.ts +27 -0
  246. package/types/src/semver/index.d.ts +1 -0
  247. package/types/src/semver/semver.d.ts +18 -0
  248. package/types/src/system/camel-case.d.ts +1 -0
  249. package/types/src/system/debounce.d.ts +1 -0
  250. package/types/src/system/decorator.d.ts +15 -0
  251. package/types/src/system/environment.d.ts +6 -0
  252. package/types/src/system/function.types.d.ts +55 -0
  253. package/types/src/system/index.d.ts +7 -0
  254. package/types/src/system/retry.decorator.d.ts +6 -0
  255. package/types/src/system/sleep.d.ts +1 -0
  256. package/types/src/system/type.utils.d.ts +1 -0
  257. package/types/src/testing/flush-promises.d.ts +1 -0
  258. package/types/src/testing/glob-with-memfs.d.ts +3 -0
  259. package/types/src/testing/index.d.ts +5 -0
  260. package/types/src/testing/memfs.d.ts +5 -0
  261. package/types/src/testing/mock-logger.d.ts +13 -0
  262. 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,3 @@
1
+ export function lowerCamelCase(val) {
2
+ return String(val).charAt(0).toLowerCase() + String(val).slice(1);
3
+ }
@@ -0,0 +1,9 @@
1
+ export function debounce(callback, delay) {
2
+ let timeoutTimer;
3
+ return (...args)=>{
4
+ clearTimeout(timeoutTimer);
5
+ timeoutTimer = setTimeout(async ()=>{
6
+ await callback(...args);
7
+ }, delay);
8
+ };
9
+ }
@@ -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,5 @@
1
+ export const Environments = {
2
+ production: "production",
3
+ development: "development"
4
+ };
5
+ export const DefaultEnvironment = Environments.development;
@@ -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,7 @@
1
+ export * from "./camel-case.js";
2
+ export * from "./debounce.js";
3
+ export * from "./decorator.js";
4
+ export * from "./environment.js";
5
+ export * from "./function.types.js";
6
+ export * from "./retry.decorator.js";
7
+ export * from "./type.utils.js";
@@ -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,3 @@
1
+ export const sleep = (ms)=>new Promise((resolve)=>setTimeout(()=>{
2
+ resolve(null);
3
+ }, ms));
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,6 @@
1
+ var scheduler = typeof setImmediate === "function" ? setImmediate : setTimeout;
2
+ export function flushPromises() {
3
+ return new Promise((resolve)=>{
4
+ scheduler(resolve);
5
+ });
6
+ }
@@ -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,5 @@
1
+ export * from "./flush-promises.js";
2
+ export * from "./glob-with-memfs.js";
3
+ export * from "./memfs.js";
4
+ export * from "./mock-logger.js";
5
+ export * from "./spy-on-constructor.js";
@@ -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,6 @@
1
+ export * from "./cache.decorator.js";
2
+ export * from "./cache.js";
3
+ export * from "./cache-manager.js";
4
+ export * from "./invalidate-cache.decorator.js";
5
+ export * from "./memoize.decorator.js";
6
+ export * from "./node-cache-memoize.adapter.js";
@@ -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
+ }