@kubb/fabric-core 0.2.19 → 0.3.1

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 (51) hide show
  1. package/dist/{Fabric-CVe8cc8b.d.ts → Fabric-RmoYWGrr.d.cts} +4 -4
  2. package/dist/{Fabric-BezqNTQ9.d.cts → Fabric-cIhiQpgN.d.ts} +4 -4
  3. package/dist/defineProperty-DwFON4j7.cjs +367 -0
  4. package/dist/defineProperty-DwFON4j7.cjs.map +1 -0
  5. package/dist/defineProperty-fiNt9UhD.js +325 -0
  6. package/dist/defineProperty-fiNt9UhD.js.map +1 -0
  7. package/dist/{getRelativePath-C6lvNCs7.cjs → getRelativePath-eCdp2Z8M.cjs} +1 -2
  8. package/dist/{getRelativePath-C6lvNCs7.cjs.map → getRelativePath-eCdp2Z8M.cjs.map} +1 -1
  9. package/dist/index.cjs +20 -21
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +1 -1
  12. package/dist/index.d.ts +1 -1
  13. package/dist/index.js +20 -19
  14. package/dist/index.js.map +1 -1
  15. package/dist/parsers/typescript.cjs +2 -2
  16. package/dist/parsers/typescript.d.cts +2 -2
  17. package/dist/parsers/typescript.d.ts +2 -2
  18. package/dist/parsers/typescript.js +1 -1
  19. package/dist/parsers.cjs +2 -2
  20. package/dist/parsers.d.cts +2 -2
  21. package/dist/parsers.d.ts +2 -2
  22. package/dist/parsers.js +1 -1
  23. package/dist/plugins.cjs +79 -46
  24. package/dist/plugins.cjs.map +1 -1
  25. package/dist/plugins.d.cts +1 -1
  26. package/dist/plugins.d.ts +1 -1
  27. package/dist/plugins.js +78 -43
  28. package/dist/plugins.js.map +1 -1
  29. package/dist/types.d.cts +1 -1
  30. package/dist/types.d.ts +1 -1
  31. package/dist/{typescriptParser-B5SxjtvV.d.ts → typescriptParser-BjqVuRHF.d.cts} +3 -14
  32. package/dist/{typescriptParser-CWT7zCJy.js → typescriptParser-CvJg4PQJ.js} +27 -45
  33. package/dist/typescriptParser-CvJg4PQJ.js.map +1 -0
  34. package/dist/{typescriptParser-PfAO0SSm.d.cts → typescriptParser-Cy9_9o6I.d.ts} +3 -14
  35. package/dist/{typescriptParser-CNHO6H2_.cjs → typescriptParser-D6-3Z7Lj.cjs} +28 -46
  36. package/dist/typescriptParser-D6-3Z7Lj.cjs.map +1 -0
  37. package/package.json +1 -1
  38. package/src/Fabric.ts +1 -1
  39. package/src/FileManager.ts +2 -2
  40. package/src/FileProcessor.ts +8 -15
  41. package/src/createFile.ts +110 -57
  42. package/src/defineFabric.ts +15 -3
  43. package/src/parsers/typescriptParser.ts +55 -73
  44. package/src/plugins/barrelPlugin.ts +63 -36
  45. package/src/utils/TreeNode.ts +54 -27
  46. package/dist/defineProperty-DZi5DvrW.cjs +0 -390
  47. package/dist/defineProperty-DZi5DvrW.cjs.map +0 -1
  48. package/dist/defineProperty-DcP1vZ2K.js +0 -346
  49. package/dist/defineProperty-DcP1vZ2K.js.map +0 -1
  50. package/dist/typescriptParser-CNHO6H2_.cjs.map +0 -1
  51. package/dist/typescriptParser-CWT7zCJy.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as _classPrivateFieldInitSpec, i as _assertClassBrand, n as _classPrivateFieldSet2, o as _checkPrivateRedeclaration, r as _classPrivateFieldGet2, s as createFile, t as _defineProperty } from "./defineProperty-DcP1vZ2K.js";
1
+ import { a as _classPrivateFieldInitSpec, i as _assertClassBrand, n as _classPrivateFieldSet2, o as _checkPrivateRedeclaration, r as _classPrivateFieldGet2, s as createFile, t as _defineProperty } from "./defineProperty-fiNt9UhD.js";
2
2
  import { t as trimExtName } from "./trimExtName-CeOVQVbu.js";
3
3
  import "./createParser-17uGjfu3.js";
4
4
  import { t as defaultParser } from "./defaultParser--HzU9LPa.js";
@@ -79,23 +79,15 @@ var FileProcessor = class {
79
79
  return defaultParser.parse(file, { extname: parseExtName });
80
80
  }
81
81
  if (!file.extname) return defaultParser.parse(file, { extname: parseExtName });
82
- let parser;
83
- for (const item of parsers) {
84
- var _item$extNames;
85
- if ((_item$extNames = item.extNames) === null || _item$extNames === void 0 ? void 0 : _item$extNames.includes(file.extname)) {
86
- parser = item;
87
- break;
88
- }
89
- }
82
+ const parser = parsers.get(file.extname);
90
83
  if (!parser) return defaultParser.parse(file, { extname: parseExtName });
91
84
  return parser.parse(file, { extname: parseExtName });
92
85
  }
93
86
  async run(files, { parsers, mode = "sequential", dryRun, extension } = {}) {
94
87
  await this.events.emit("process:start", { files });
95
- let processed = 0;
96
88
  const total = files.length;
89
+ let processed = 0;
97
90
  const processOne = async (resolvedFile, index) => {
98
- const percentage = processed / total * 100;
99
91
  await this.events.emit("file:start", {
100
92
  file: resolvedFile,
101
93
  index,
@@ -105,14 +97,15 @@ var FileProcessor = class {
105
97
  extension,
106
98
  parsers
107
99
  });
100
+ const currentProcessed = ++processed;
101
+ const percentage = currentProcessed / total * 100;
108
102
  await this.events.emit("process:progress", {
109
103
  file: resolvedFile,
110
104
  source,
111
- processed,
105
+ processed: currentProcessed,
112
106
  percentage,
113
107
  total
114
108
  });
115
- processed++;
116
109
  await this.events.emit("file:end", {
117
110
  file: resolvedFile,
118
111
  index,
@@ -163,7 +156,7 @@ var Cache = class {
163
156
  };
164
157
 
165
158
  //#endregion
166
- //#region \0@oxc-project+runtime@0.95.0/helpers/classPrivateMethodInitSpec.js
159
+ //#region \0@oxc-project+runtime@0.96.0/helpers/classPrivateMethodInitSpec.js
167
160
  function _classPrivateMethodInitSpec(e$1, a) {
168
161
  _checkPrivateRedeclaration(e$1, a), a.add(e$1);
169
162
  }
@@ -228,7 +221,7 @@ var FileManager = class {
228
221
  _classPrivateFieldSet2(_filesCache, this, null);
229
222
  }
230
223
  get files() {
231
- if (_classPrivateFieldGet2(_filesCache, this)) return [..._classPrivateFieldGet2(_filesCache, this)];
224
+ if (_classPrivateFieldGet2(_filesCache, this)) return _classPrivateFieldGet2(_filesCache, this);
232
225
  const keys = orderBy(_classPrivateFieldGet2(_cache, this).keys(), [(v) => v.length, (v) => trimExtName(v).endsWith("index")]);
233
226
  const files = [];
234
227
  for (const key of keys) {
@@ -236,7 +229,7 @@ var FileManager = class {
236
229
  if (file) files.push(file);
237
230
  }
238
231
  _classPrivateFieldSet2(_filesCache, this, files);
239
- return [...files];
232
+ return files;
240
233
  }
241
234
  async write(options) {
242
235
  await this.events.emit("write:start", { files: this.files });
@@ -269,7 +262,8 @@ function defineFabric(init) {
269
262
  function create(config = { mode: "sequential" }) {
270
263
  const events = new AsyncEventEmitter();
271
264
  const installedPlugins = /* @__PURE__ */ new Set();
272
- const installedParsers = /* @__PURE__ */ new Set();
265
+ const installedParsers = /* @__PURE__ */ new Map();
266
+ const installedParserNames = /* @__PURE__ */ new Set();
273
267
  const fileManager = new FileManager({ events });
274
268
  const context = {
275
269
  get files() {
@@ -306,8 +300,15 @@ function defineFabric(init) {
306
300
  Object.assign(fabric, injected);
307
301
  }
308
302
  }
309
- if (pluginOrParser.type === "parser") if (installedParsers.has(pluginOrParser)) console.warn(`Parser "${pluginOrParser.name}" already applied.`);
310
- else installedParsers.add(pluginOrParser);
303
+ if (pluginOrParser.type === "parser") {
304
+ if (installedParserNames.has(pluginOrParser.name)) console.warn(`Parser "${pluginOrParser.name}" already applied.`);
305
+ else installedParserNames.add(pluginOrParser.name);
306
+ if (pluginOrParser.extNames) for (const extName of pluginOrParser.extNames) {
307
+ const existing = installedParsers.get(extName);
308
+ if (existing && existing.name !== pluginOrParser.name) console.warn(`Parser "${pluginOrParser.name}" is overriding parser "${existing.name}" for extension "${extName}".`);
309
+ installedParsers.set(extName, pluginOrParser);
310
+ }
311
+ }
311
312
  if (e(pluginOrParser.install)) {
312
313
  const installer = pluginOrParser.install;
313
314
  await installer(context, ...options);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["e","NodeEventEmitter","errors: Error[]","parser: Parser | undefined","resolvedFiles: Array<KubbFile.ResolvedFile>","files: Array<KubbFile.ResolvedFile>","context: FabricContext<T>","fabric: Fabric<T>","isFunction"],"sources":["../../../node_modules/.pnpm/remeda@2.32.0/node_modules/remeda/dist/isFunction-BJjFuZR7.js","../src/utils/AsyncEventEmitter.ts","../src/FileProcessor.ts","../src/utils/Cache.ts","../src/FileManager.ts","../src/defineFabric.ts","../src/createFabric.ts"],"sourcesContent":["const e=e=>typeof e==`function`;export{e as isFunction};\n//# sourceMappingURL=isFunction-BJjFuZR7.js.map","import { EventEmitter as NodeEventEmitter } from 'node:events'\nimport type { FabricMode } from '../Fabric.ts'\n\ntype Options = {\n mode?: FabricMode\n maxListener?: number\n}\n\nexport class AsyncEventEmitter<TEvents extends Record<string, any>> {\n constructor({ maxListener = 100, mode = 'sequential' }: Options = {}) {\n this.#emitter.setMaxListeners(maxListener)\n this.#mode = mode\n }\n\n #emitter = new NodeEventEmitter()\n #mode: FabricMode\n\n async emit<TEventName extends keyof TEvents & string>(eventName: TEventName, ...eventArgs: TEvents[TEventName]): Promise<void> {\n const listeners = this.#emitter.listeners(eventName) as Array<(...args: TEvents[TEventName]) => any>\n\n if (listeners.length === 0) {\n return\n }\n\n const errors: Error[] = []\n\n if (this.#mode === 'sequential') {\n // Run listeners one by one, in order\n for (const listener of listeners) {\n try {\n await listener(...eventArgs)\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n errors.push(error)\n }\n }\n } else {\n // Run all listeners concurrently\n const promises = listeners.map(async (listener) => {\n try {\n await listener(...eventArgs)\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n errors.push(error)\n }\n })\n await Promise.all(promises)\n }\n\n if (errors.length === 1) {\n throw errors[0]\n }\n\n if (errors.length > 1) {\n throw new AggregateError(errors, `Errors in async listeners for \"${eventName}\"`)\n }\n }\n\n on<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: (...eventArg: TEvents[TEventName]) => void): void {\n this.#emitter.on(eventName, handler as any)\n }\n\n onOnce<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: (...eventArgs: TEvents[TEventName]) => void): void {\n const wrapper = (...args: TEvents[TEventName]) => {\n this.off(eventName, wrapper)\n handler(...args)\n }\n this.on(eventName, wrapper)\n }\n\n off<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: (...eventArg: TEvents[TEventName]) => void): void {\n this.#emitter.off(eventName, handler as any)\n }\n\n removeAll(): void {\n this.#emitter.removeAllListeners()\n }\n}\n","import pLimit from 'p-limit'\nimport type { FabricEvents, FabricMode } from './Fabric.ts'\nimport type * as KubbFile from './KubbFile.ts'\nimport { defaultParser } from './parsers/defaultParser.ts'\nimport type { Parser } from './parsers/types.ts'\nimport { AsyncEventEmitter } from './utils/AsyncEventEmitter.ts'\n\nexport type ProcessFilesProps = {\n parsers?: Set<Parser>\n extension?: Record<KubbFile.Extname, KubbFile.Extname | ''>\n dryRun?: boolean\n /**\n * @default 'sequential'\n */\n mode?: FabricMode\n}\n\ntype GetParseOptions = {\n parsers?: Set<Parser>\n extension?: Record<KubbFile.Extname, KubbFile.Extname | ''>\n}\n\ntype Options = {\n events?: AsyncEventEmitter<FabricEvents>\n}\n\nexport class FileProcessor {\n #limit = pLimit(100)\n events: AsyncEventEmitter<FabricEvents>\n\n constructor({ events = new AsyncEventEmitter<FabricEvents>() }: Options = {}) {\n this.events = events\n\n return this\n }\n\n async parse(file: KubbFile.ResolvedFile, { parsers, extension }: GetParseOptions = {}): Promise<string> {\n const parseExtName = extension?.[file.extname] || undefined\n\n if (!parsers) {\n console.warn('No parsers provided, using default parser. If you want to use a specific parser, please provide it in the options.')\n\n return defaultParser.parse(file, { extname: parseExtName })\n }\n\n if (!file.extname) {\n return defaultParser.parse(file, { extname: parseExtName })\n }\n\n let parser: Parser | undefined\n for (const item of parsers) {\n if (item.extNames?.includes(file.extname)) {\n parser = item\n break\n }\n }\n\n if (!parser) {\n return defaultParser.parse(file, { extname: parseExtName })\n }\n\n return parser.parse(file, { extname: parseExtName })\n }\n\n async run(\n files: Array<KubbFile.ResolvedFile>,\n { parsers, mode = 'sequential', dryRun, extension }: ProcessFilesProps = {},\n ): Promise<KubbFile.ResolvedFile[]> {\n await this.events.emit('process:start', { files })\n\n let processed = 0\n const total = files.length\n\n const processOne = async (resolvedFile: KubbFile.ResolvedFile, index: number) => {\n const percentage = (processed / total) * 100\n\n await this.events.emit('file:start', { file: resolvedFile, index, total })\n\n const source = dryRun ? undefined : await this.parse(resolvedFile, { extension, parsers })\n\n await this.events.emit('process:progress', {\n file: resolvedFile,\n source,\n processed,\n percentage,\n total,\n })\n\n processed++\n\n await this.events.emit('file:end', { file: resolvedFile, index, total })\n }\n\n if (mode === 'sequential') {\n async function* asyncFiles() {\n for (let index = 0; index < files.length; index++) {\n yield [files[index], index] as const\n }\n }\n\n for await (const [file, index] of asyncFiles()) {\n if (file) {\n await processOne(file, index)\n }\n }\n } else {\n const promises = files.map((resolvedFile, index) => this.#limit(() => processOne(resolvedFile, index)))\n await Promise.all(promises)\n }\n\n await this.events.emit('process:end', { files })\n\n return files\n }\n}\n","export class Cache<T> {\n #buffer = new Map<string, T>()\n\n get(key: string): T | null {\n return this.#buffer.get(key) ?? null\n }\n\n set(key: string, value: T): void {\n this.#buffer.set(key, value)\n }\n\n delete(key: string): void {\n this.#buffer.delete(key)\n }\n\n clear(): void {\n this.#buffer.clear()\n }\n\n keys(): string[] {\n return [...this.#buffer.keys()]\n }\n\n values(): Array<T> {\n return [...this.#buffer.values()]\n }\n\n flush(): void {\n // No-op for base cache\n }\n}\n","import { orderBy } from 'natural-orderby'\nimport { createFile } from './createFile.ts'\nimport type { FabricEvents } from './Fabric.ts'\nimport { FileProcessor, type ProcessFilesProps } from './FileProcessor.ts'\nimport type * as KubbFile from './KubbFile.ts'\nimport { AsyncEventEmitter } from './utils/AsyncEventEmitter.ts'\nimport { Cache } from './utils/Cache.ts'\nimport { trimExtName } from './utils/trimExtName.ts'\n\nfunction mergeFile<TMeta extends object = object>(a: KubbFile.File<TMeta>, b: KubbFile.File<TMeta>): KubbFile.File<TMeta> {\n return {\n ...a,\n sources: [...(a.sources || []), ...(b.sources || [])],\n imports: [...(a.imports || []), ...(b.imports || [])],\n exports: [...(a.exports || []), ...(b.exports || [])],\n }\n}\n\ntype Options = {\n events?: AsyncEventEmitter<FabricEvents>\n}\n\nexport class FileManager {\n #cache = new Cache<KubbFile.ResolvedFile>()\n #filesCache: Array<KubbFile.ResolvedFile> | null = null\n events: AsyncEventEmitter<FabricEvents>\n processor: FileProcessor\n\n constructor({ events = new AsyncEventEmitter<FabricEvents>() }: Options = {}) {\n this.processor = new FileProcessor({ events })\n\n this.events = events\n return this\n }\n\n #resolvePath(file: KubbFile.File): KubbFile.File {\n this.events.emit('file:resolve:path', { file })\n\n return file\n }\n\n #resolveName(file: KubbFile.File): KubbFile.File {\n this.events.emit('file:resolve:name', { file })\n\n return file\n }\n\n async add(...files: Array<KubbFile.File>) {\n const resolvedFiles: Array<KubbFile.ResolvedFile> = []\n\n const mergedFiles = new Map<string, KubbFile.File>()\n\n files.forEach((file) => {\n const existing = mergedFiles.get(file.path)\n if (existing) {\n mergedFiles.set(file.path, mergeFile(existing, file))\n } else {\n mergedFiles.set(file.path, file)\n }\n })\n\n for (let file of mergedFiles.values()) {\n const existing = this.#cache.get(file.path)\n\n file = this.#resolveName(file)\n file = this.#resolvePath(file)\n\n const merged = existing ? mergeFile(existing, file) : file\n const resolvedFile = createFile(merged)\n\n this.#cache.set(resolvedFile.path, resolvedFile)\n this.flush()\n\n resolvedFiles.push(resolvedFile)\n }\n\n await this.events.emit('file:add', { files: resolvedFiles })\n\n return resolvedFiles\n }\n\n flush() {\n this.#filesCache = null\n this.#cache.flush()\n }\n\n getByPath(path: KubbFile.Path): KubbFile.ResolvedFile | null {\n return this.#cache.get(path)\n }\n\n deleteByPath(path: KubbFile.Path): void {\n this.#cache.delete(path)\n this.#filesCache = null\n }\n\n clear(): void {\n this.#cache.clear()\n this.#filesCache = null\n }\n\n get files(): Array<KubbFile.ResolvedFile> {\n if (this.#filesCache) {\n return [...this.#filesCache]\n }\n\n const cachedKeys = this.#cache.keys()\n\n // order by path length and if file is a barrel file\n const keys = orderBy(cachedKeys, [(v) => v.length, (v) => trimExtName(v).endsWith('index')])\n\n const files: Array<KubbFile.ResolvedFile> = []\n\n for (const key of keys) {\n const file = this.#cache.get(key)\n if (file) {\n files.push(file)\n }\n }\n\n this.#filesCache = files\n\n return [...files]\n }\n\n //TODO add test and check if write of FileManager contains the newly added file\n async write(options: ProcessFilesProps): Promise<KubbFile.ResolvedFile[]> {\n await this.events.emit('write:start', { files: this.files })\n\n const resolvedFiles = await this.processor.run(this.files, options)\n\n this.clear()\n\n await this.events.emit('write:end', { files: resolvedFiles })\n\n return resolvedFiles\n }\n}\n","import { isFunction } from 'remeda'\nimport type { Fabric, FabricConfig, FabricContext, FabricEvents, FabricOptions } from './Fabric.ts'\nimport { FileManager } from './FileManager.ts'\nimport type { Parser } from './parsers/types.ts'\nimport type { Plugin } from './plugins/types.ts'\nimport { AsyncEventEmitter } from './utils/AsyncEventEmitter.ts'\n\n/**\n * Function that initializes the root Fabric instance.\n *\n * Used for setting up plugins, parsers, or performing side effects\n * once the Fabric context is ready.\n */\ntype FabricInitializer<T extends FabricOptions> = (fabric: Fabric<T>) => void | Promise<void>\n\n/**\n * A function returned by {@link defineFabric} that creates a Fabric instance.\n */\nexport type CreateFabric<T extends FabricOptions> = (config?: FabricConfig<T>) => Fabric<T>\n\n/**\n * Defines a new Fabric factory function.\n *\n * @example\n * export const createFabric = defineFabric((fabric) => {\n * fabric.use(myPlugin())\n * })\n */\nexport function defineFabric<T extends FabricOptions>(init?: FabricInitializer<T>): CreateFabric<T> {\n function create(config: FabricConfig<T> = { mode: 'sequential' } as FabricConfig<T>): Fabric<T> {\n const events = new AsyncEventEmitter<FabricEvents>()\n const installedPlugins = new Set<Plugin<any>>()\n const installedParsers = new Set<Parser<any>>()\n const fileManager = new FileManager({ events })\n\n const context: FabricContext<T> = {\n get files() {\n return fileManager.files\n },\n async addFile(...files) {\n await fileManager.add(...files)\n },\n config,\n fileManager,\n installedPlugins,\n installedParsers,\n on: events.on.bind(events),\n off: events.off.bind(events),\n onOnce: events.onOnce.bind(events),\n removeAll: events.removeAll.bind(events),\n emit: events.emit.bind(events),\n } as FabricContext<T>\n\n const fabric: Fabric<T> = {\n context,\n get files() {\n return fileManager.files\n },\n async addFile(...files) {\n await fileManager.add(...files)\n },\n async use(pluginOrParser, ...options) {\n if (pluginOrParser.type === 'plugin') {\n if (installedPlugins.has(pluginOrParser)) {\n console.warn(`Plugin \"${pluginOrParser.name}\" already applied.`)\n } else {\n installedPlugins.add(pluginOrParser)\n }\n\n if (isFunction(pluginOrParser.inject)) {\n const injecter = pluginOrParser.inject\n\n const injected = (injecter as any)(context, ...options)\n Object.assign(fabric, injected)\n }\n }\n\n if (pluginOrParser.type === 'parser') {\n if (installedParsers.has(pluginOrParser)) {\n console.warn(`Parser \"${pluginOrParser.name}\" already applied.`)\n } else {\n installedParsers.add(pluginOrParser)\n }\n }\n\n if (isFunction(pluginOrParser.install)) {\n const installer = pluginOrParser.install\n\n await (installer as any)(context, ...options)\n }\n\n return fabric\n },\n } as Fabric<T>\n\n if (init) {\n init(fabric)\n }\n\n return fabric\n }\n\n return create\n}\n","import { defineFabric } from './defineFabric.ts'\n\nexport const createFabric = defineFabric()\n"],"x_google_ignoreList":[0],"mappings":";;;;;;;;;AAAA,MAAM,KAAE,QAAG,OAAOA,OAAG;;;;;;ACQrB,IAAa,oBAAb,MAAoE;CAClE,YAAY,EAAE,cAAc,KAAK,OAAO,iBAA0B,EAAE,EAAE;6CAK3D,IAAIC,cAAkB;;AAJ/B,wCAAa,CAAC,gBAAgB,YAAY;AAC1C,sCAAa,KAAI;;CAMnB,MAAM,KAAgD,WAAuB,GAAG,WAA+C;EAC7H,MAAM,6CAAY,KAAa,CAAC,UAAU,UAAU;AAEpD,MAAI,UAAU,WAAW,EACvB;EAGF,MAAMC,SAAkB,EAAE;AAE1B,oCAAI,KAAU,KAAK,aAEjB,MAAK,MAAM,YAAY,UACrB,KAAI;AACF,SAAM,SAAS,GAAG,UAAU;WACrB,KAAK;GACZ,MAAM,QAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC;AACjE,UAAO,KAAK,MAAM;;OAGjB;GAEL,MAAM,WAAW,UAAU,IAAI,OAAO,aAAa;AACjD,QAAI;AACF,WAAM,SAAS,GAAG,UAAU;aACrB,KAAK;KACZ,MAAM,QAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC;AACjE,YAAO,KAAK,MAAM;;KAEpB;AACF,SAAM,QAAQ,IAAI,SAAS;;AAG7B,MAAI,OAAO,WAAW,EACpB,OAAM,OAAO;AAGf,MAAI,OAAO,SAAS,EAClB,OAAM,IAAI,eAAe,QAAQ,kCAAkC,UAAU,GAAG;;CAIpF,GAA8C,WAAuB,SAA2D;AAC9H,wCAAa,CAAC,GAAG,WAAW,QAAe;;CAG7C,OAAkD,WAAuB,SAA4D;EACnI,MAAM,WAAW,GAAG,SAA8B;AAChD,QAAK,IAAI,WAAW,QAAQ;AAC5B,WAAQ,GAAG,KAAK;;AAElB,OAAK,GAAG,WAAW,QAAQ;;CAG7B,IAA+C,WAAuB,SAA2D;AAC/H,wCAAa,CAAC,IAAI,WAAW,QAAe;;CAG9C,YAAkB;AAChB,wCAAa,CAAC,oBAAoB;;;;;;;ACjDtC,IAAa,gBAAb,MAA2B;CAIzB,YAAY,EAAE,SAAS,IAAI,mBAAiC,KAAc,EAAE,EAAE;2CAHrE,OAAO,IAAI;wBACpB;AAGE,OAAK,SAAS;AAEd,SAAO;;CAGT,MAAM,MAAM,MAA6B,EAAE,SAAS,cAA+B,EAAE,EAAmB;EACtG,MAAM,sEAAe,UAAY,KAAK,aAAY;AAElD,MAAI,CAAC,SAAS;AACZ,WAAQ,KAAK,qHAAqH;AAElI,UAAO,cAAc,MAAM,MAAM,EAAE,SAAS,cAAc,CAAC;;AAG7D,MAAI,CAAC,KAAK,QACR,QAAO,cAAc,MAAM,MAAM,EAAE,SAAS,cAAc,CAAC;EAG7D,IAAIC;AACJ,OAAK,MAAM,QAAQ,SAAS;;AAC1B,yBAAI,KAAK,0EAAU,SAAS,KAAK,QAAQ,EAAE;AACzC,aAAS;AACT;;;AAIJ,MAAI,CAAC,OACH,QAAO,cAAc,MAAM,MAAM,EAAE,SAAS,cAAc,CAAC;AAG7D,SAAO,OAAO,MAAM,MAAM,EAAE,SAAS,cAAc,CAAC;;CAGtD,MAAM,IACJ,OACA,EAAE,SAAS,OAAO,cAAc,QAAQ,cAAiC,EAAE,EACzC;AAClC,QAAM,KAAK,OAAO,KAAK,iBAAiB,EAAE,OAAO,CAAC;EAElD,IAAI,YAAY;EAChB,MAAM,QAAQ,MAAM;EAEpB,MAAM,aAAa,OAAO,cAAqC,UAAkB;GAC/E,MAAM,aAAc,YAAY,QAAS;AAEzC,SAAM,KAAK,OAAO,KAAK,cAAc;IAAE,MAAM;IAAc;IAAO;IAAO,CAAC;GAE1E,MAAM,SAAS,SAAS,SAAY,MAAM,KAAK,MAAM,cAAc;IAAE;IAAW;IAAS,CAAC;AAE1F,SAAM,KAAK,OAAO,KAAK,oBAAoB;IACzC,MAAM;IACN;IACA;IACA;IACA;IACD,CAAC;AAEF;AAEA,SAAM,KAAK,OAAO,KAAK,YAAY;IAAE,MAAM;IAAc;IAAO;IAAO,CAAC;;AAG1E,MAAI,SAAS,cAAc;GACzB,gBAAgB,aAAa;AAC3B,SAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,QACxC,OAAM,CAAC,MAAM,QAAQ,MAAM;;AAI/B,cAAW,MAAM,CAAC,MAAM,UAAU,YAAY,CAC5C,KAAI,KACF,OAAM,WAAW,MAAM,MAAM;SAG5B;GACL,MAAM,WAAW,MAAM,KAAK,cAAc,yCAAU,KAAW,kBAAO,WAAW,cAAc,MAAM,CAAC,CAAC;AACvG,SAAM,QAAQ,IAAI,SAAS;;AAG7B,QAAM,KAAK,OAAO,KAAK,eAAe,EAAE,OAAO,CAAC;AAEhD,SAAO;;;;;;;AChHX,IAAa,QAAb,MAAsB;;4DACV,IAAI,KAAgB;;CAE9B,IAAI,KAAuB;;AACzB,6DAAO,KAAY,CAAC,IAAI,IAAI,+DAAI;;CAGlC,IAAI,KAAa,OAAgB;AAC/B,uCAAY,CAAC,IAAI,KAAK,MAAM;;CAG9B,OAAO,KAAmB;AACxB,uCAAY,CAAC,OAAO,IAAI;;CAG1B,QAAc;AACZ,uCAAY,CAAC,OAAO;;CAGtB,OAAiB;AACf,SAAO,CAAC,mCAAG,KAAY,CAAC,MAAM,CAAC;;CAGjC,SAAmB;AACjB,SAAO,CAAC,mCAAG,KAAY,CAAC,QAAQ,CAAC;;CAGnC,QAAc;;;;;;;;;;;AClBhB,SAAS,UAAyC,GAAyB,GAA+C;AACxH,QAAO;EACL,GAAG;EACH,SAAS,CAAC,GAAI,EAAE,WAAW,EAAE,EAAG,GAAI,EAAE,WAAW,EAAE,CAAE;EACrD,SAAS,CAAC,GAAI,EAAE,WAAW,EAAE,EAAG,GAAI,EAAE,WAAW,EAAE,CAAE;EACrD,SAAS,CAAC,GAAI,EAAE,WAAW,EAAE,EAAG,GAAI,EAAE,WAAW,EAAE,CAAE;EACtD;;;;;AAOH,IAAa,cAAb,MAAyB;CAMvB,YAAY,EAAE,SAAS,IAAI,mBAAiC,KAAc,EAAE,EAAE;;2CALrE,IAAI,OAA8B;gDACQ;wBACnD;wBACA;AAGE,OAAK,YAAY,IAAI,cAAc,EAAE,QAAQ,CAAC;AAE9C,OAAK,SAAS;AACd,SAAO;;CAeT,MAAM,IAAI,GAAG,OAA6B;EACxC,MAAMC,gBAA8C,EAAE;EAEtD,MAAM,8BAAc,IAAI,KAA4B;AAEpD,QAAM,SAAS,SAAS;GACtB,MAAM,WAAW,YAAY,IAAI,KAAK,KAAK;AAC3C,OAAI,SACF,aAAY,IAAI,KAAK,MAAM,UAAU,UAAU,KAAK,CAAC;OAErD,aAAY,IAAI,KAAK,MAAM,KAAK;IAElC;AAEF,OAAK,IAAI,QAAQ,YAAY,QAAQ,EAAE;GACrC,MAAM,0CAAW,KAAW,CAAC,IAAI,KAAK,KAAK;AAE3C,gDAAO,mBAAiB,YAAC,KAAK;AAC9B,gDAAO,mBAAiB,YAAC,KAAK;GAG9B,MAAM,eAAe,WADN,WAAW,UAAU,UAAU,KAAK,GAAG,KACf;AAEvC,uCAAW,CAAC,IAAI,aAAa,MAAM,aAAa;AAChD,QAAK,OAAO;AAEZ,iBAAc,KAAK,aAAa;;AAGlC,QAAM,KAAK,OAAO,KAAK,YAAY,EAAE,OAAO,eAAe,CAAC;AAE5D,SAAO;;CAGT,QAAQ;AACN,4CAAmB,KAAI;AACvB,sCAAW,CAAC,OAAO;;CAGrB,UAAU,MAAmD;AAC3D,wCAAO,KAAW,CAAC,IAAI,KAAK;;CAG9B,aAAa,MAA2B;AACtC,sCAAW,CAAC,OAAO,KAAK;AACxB,4CAAmB,KAAI;;CAGzB,QAAc;AACZ,sCAAW,CAAC,OAAO;AACnB,4CAAmB,KAAI;;CAGzB,IAAI,QAAsC;AACxC,0CAAI,KAAgB,CAClB,QAAO,CAAC,uCAAG,KAAgB,CAAC;EAM9B,MAAM,OAAO,uCAHM,KAAW,CAAC,MAAM,EAGJ,EAAE,MAAM,EAAE,SAAS,MAAM,YAAY,EAAE,CAAC,SAAS,QAAQ,CAAC,CAAC;EAE5F,MAAMC,QAAsC,EAAE;AAE9C,OAAK,MAAM,OAAO,MAAM;GACtB,MAAM,sCAAO,KAAW,CAAC,IAAI,IAAI;AACjC,OAAI,KACF,OAAM,KAAK,KAAK;;AAIpB,4CAAmB,MAAK;AAExB,SAAO,CAAC,GAAG,MAAM;;CAInB,MAAM,MAAM,SAA8D;AACxE,QAAM,KAAK,OAAO,KAAK,eAAe,EAAE,OAAO,KAAK,OAAO,CAAC;EAE5D,MAAM,gBAAgB,MAAM,KAAK,UAAU,IAAI,KAAK,OAAO,QAAQ;AAEnE,OAAK,OAAO;AAEZ,QAAM,KAAK,OAAO,KAAK,aAAa,EAAE,OAAO,eAAe,CAAC;AAE7D,SAAO;;;AAnGT,sBAAa,MAAoC;AAC/C,MAAK,OAAO,KAAK,qBAAqB,EAAE,MAAM,CAAC;AAE/C,QAAO;;AAGT,sBAAa,MAAoC;AAC/C,MAAK,OAAO,KAAK,qBAAqB,EAAE,MAAM,CAAC;AAE/C,QAAO;;;;;;;;;;;;;AChBX,SAAgB,aAAsC,MAA8C;CAClG,SAAS,OAAO,SAA0B,EAAE,MAAM,cAAc,EAAgC;EAC9F,MAAM,SAAS,IAAI,mBAAiC;EACpD,MAAM,mCAAmB,IAAI,KAAkB;EAC/C,MAAM,mCAAmB,IAAI,KAAkB;EAC/C,MAAM,cAAc,IAAI,YAAY,EAAE,QAAQ,CAAC;EAE/C,MAAMC,UAA4B;GAChC,IAAI,QAAQ;AACV,WAAO,YAAY;;GAErB,MAAM,QAAQ,GAAG,OAAO;AACtB,UAAM,YAAY,IAAI,GAAG,MAAM;;GAEjC;GACA;GACA;GACA;GACA,IAAI,OAAO,GAAG,KAAK,OAAO;GAC1B,KAAK,OAAO,IAAI,KAAK,OAAO;GAC5B,QAAQ,OAAO,OAAO,KAAK,OAAO;GAClC,WAAW,OAAO,UAAU,KAAK,OAAO;GACxC,MAAM,OAAO,KAAK,KAAK,OAAO;GAC/B;EAED,MAAMC,SAAoB;GACxB;GACA,IAAI,QAAQ;AACV,WAAO,YAAY;;GAErB,MAAM,QAAQ,GAAG,OAAO;AACtB,UAAM,YAAY,IAAI,GAAG,MAAM;;GAEjC,MAAM,IAAI,gBAAgB,GAAG,SAAS;AACpC,QAAI,eAAe,SAAS,UAAU;AACpC,SAAI,iBAAiB,IAAI,eAAe,CACtC,SAAQ,KAAK,WAAW,eAAe,KAAK,oBAAoB;SAEhE,kBAAiB,IAAI,eAAe;AAGtC,SAAIC,EAAW,eAAe,OAAO,EAAE;MACrC,MAAM,WAAW,eAAe;MAEhC,MAAM,WAAY,SAAiB,SAAS,GAAG,QAAQ;AACvD,aAAO,OAAO,QAAQ,SAAS;;;AAInC,QAAI,eAAe,SAAS,SAC1B,KAAI,iBAAiB,IAAI,eAAe,CACtC,SAAQ,KAAK,WAAW,eAAe,KAAK,oBAAoB;QAEhE,kBAAiB,IAAI,eAAe;AAIxC,QAAIA,EAAW,eAAe,QAAQ,EAAE;KACtC,MAAM,YAAY,eAAe;AAEjC,WAAO,UAAkB,SAAS,GAAG,QAAQ;;AAG/C,WAAO;;GAEV;AAED,MAAI,KACF,MAAK,OAAO;AAGd,SAAO;;AAGT,QAAO;;;;;ACpGT,MAAa,eAAe,cAAc"}
1
+ {"version":3,"file":"index.js","names":["e","NodeEventEmitter","errors: Error[]","resolvedFiles: Array<KubbFile.ResolvedFile>","files: Array<KubbFile.ResolvedFile>","context: FabricContext<T>","fabric: Fabric<T>","isFunction"],"sources":["../../../node_modules/.pnpm/remeda@2.32.0/node_modules/remeda/dist/isFunction-BJjFuZR7.js","../src/utils/AsyncEventEmitter.ts","../src/FileProcessor.ts","../src/utils/Cache.ts","../src/FileManager.ts","../src/defineFabric.ts","../src/createFabric.ts"],"sourcesContent":["const e=e=>typeof e==`function`;export{e as isFunction};\n//# sourceMappingURL=isFunction-BJjFuZR7.js.map","import { EventEmitter as NodeEventEmitter } from 'node:events'\nimport type { FabricMode } from '../Fabric.ts'\n\ntype Options = {\n mode?: FabricMode\n maxListener?: number\n}\n\nexport class AsyncEventEmitter<TEvents extends Record<string, any>> {\n constructor({ maxListener = 100, mode = 'sequential' }: Options = {}) {\n this.#emitter.setMaxListeners(maxListener)\n this.#mode = mode\n }\n\n #emitter = new NodeEventEmitter()\n #mode: FabricMode\n\n async emit<TEventName extends keyof TEvents & string>(eventName: TEventName, ...eventArgs: TEvents[TEventName]): Promise<void> {\n const listeners = this.#emitter.listeners(eventName) as Array<(...args: TEvents[TEventName]) => any>\n\n if (listeners.length === 0) {\n return\n }\n\n const errors: Error[] = []\n\n if (this.#mode === 'sequential') {\n // Run listeners one by one, in order\n for (const listener of listeners) {\n try {\n await listener(...eventArgs)\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n errors.push(error)\n }\n }\n } else {\n // Run all listeners concurrently\n const promises = listeners.map(async (listener) => {\n try {\n await listener(...eventArgs)\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n errors.push(error)\n }\n })\n await Promise.all(promises)\n }\n\n if (errors.length === 1) {\n throw errors[0]\n }\n\n if (errors.length > 1) {\n throw new AggregateError(errors, `Errors in async listeners for \"${eventName}\"`)\n }\n }\n\n on<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: (...eventArg: TEvents[TEventName]) => void): void {\n this.#emitter.on(eventName, handler as any)\n }\n\n onOnce<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: (...eventArgs: TEvents[TEventName]) => void): void {\n const wrapper = (...args: TEvents[TEventName]) => {\n this.off(eventName, wrapper)\n handler(...args)\n }\n this.on(eventName, wrapper)\n }\n\n off<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: (...eventArg: TEvents[TEventName]) => void): void {\n this.#emitter.off(eventName, handler as any)\n }\n\n removeAll(): void {\n this.#emitter.removeAllListeners()\n }\n}\n","import pLimit from 'p-limit'\nimport type { FabricEvents, FabricMode } from './Fabric.ts'\nimport type * as KubbFile from './KubbFile.ts'\nimport { defaultParser } from './parsers/defaultParser.ts'\nimport type { Parser } from './parsers/types.ts'\nimport { AsyncEventEmitter } from './utils/AsyncEventEmitter.ts'\n\nexport type ProcessFilesProps = {\n parsers?: Map<KubbFile.Extname, Parser>\n extension?: Record<KubbFile.Extname, KubbFile.Extname | ''>\n dryRun?: boolean\n /**\n * @default 'sequential'\n */\n mode?: FabricMode\n}\n\ntype GetParseOptions = {\n parsers?: Map<KubbFile.Extname, Parser>\n extension?: Record<KubbFile.Extname, KubbFile.Extname | ''>\n}\n\ntype Options = {\n events?: AsyncEventEmitter<FabricEvents>\n}\n\nexport class FileProcessor {\n #limit = pLimit(100)\n events: AsyncEventEmitter<FabricEvents>\n\n constructor({ events = new AsyncEventEmitter<FabricEvents>() }: Options = {}) {\n this.events = events\n\n return this\n }\n\n async parse(file: KubbFile.ResolvedFile, { parsers, extension }: GetParseOptions = {}): Promise<string> {\n const parseExtName = extension?.[file.extname] || undefined\n\n if (!parsers) {\n console.warn('No parsers provided, using default parser. If you want to use a specific parser, please provide it in the options.')\n\n return defaultParser.parse(file, { extname: parseExtName })\n }\n\n if (!file.extname) {\n return defaultParser.parse(file, { extname: parseExtName })\n }\n\n const parser = parsers.get(file.extname)\n\n if (!parser) {\n return defaultParser.parse(file, { extname: parseExtName })\n }\n\n return parser.parse(file, { extname: parseExtName })\n }\n\n async run(\n files: Array<KubbFile.ResolvedFile>,\n { parsers, mode = 'sequential', dryRun, extension }: ProcessFilesProps = {},\n ): Promise<KubbFile.ResolvedFile[]> {\n await this.events.emit('process:start', { files })\n\n const total = files.length\n let processed = 0\n\n const processOne = async (resolvedFile: KubbFile.ResolvedFile, index: number) => {\n await this.events.emit('file:start', { file: resolvedFile, index, total })\n\n const source = dryRun ? undefined : await this.parse(resolvedFile, { extension, parsers })\n\n const currentProcessed = ++processed\n const percentage = (currentProcessed / total) * 100\n\n await this.events.emit('process:progress', {\n file: resolvedFile,\n source,\n processed: currentProcessed,\n percentage,\n total,\n })\n\n await this.events.emit('file:end', { file: resolvedFile, index, total })\n }\n\n if (mode === 'sequential') {\n async function* asyncFiles() {\n for (let index = 0; index < files.length; index++) {\n yield [files[index], index] as const\n }\n }\n\n for await (const [file, index] of asyncFiles()) {\n if (file) {\n await processOne(file, index)\n }\n }\n } else {\n const promises = files.map((resolvedFile, index) => this.#limit(() => processOne(resolvedFile, index)))\n await Promise.all(promises)\n }\n\n await this.events.emit('process:end', { files })\n\n return files\n }\n}\n","export class Cache<T> {\n #buffer = new Map<string, T>()\n\n get(key: string): T | null {\n return this.#buffer.get(key) ?? null\n }\n\n set(key: string, value: T): void {\n this.#buffer.set(key, value)\n }\n\n delete(key: string): void {\n this.#buffer.delete(key)\n }\n\n clear(): void {\n this.#buffer.clear()\n }\n\n keys(): string[] {\n return [...this.#buffer.keys()]\n }\n\n values(): Array<T> {\n return [...this.#buffer.values()]\n }\n\n flush(): void {\n // No-op for base cache\n }\n}\n","import { orderBy } from 'natural-orderby'\nimport { createFile } from './createFile.ts'\nimport type { FabricEvents } from './Fabric.ts'\nimport { FileProcessor, type ProcessFilesProps } from './FileProcessor.ts'\nimport type * as KubbFile from './KubbFile.ts'\nimport { AsyncEventEmitter } from './utils/AsyncEventEmitter.ts'\nimport { Cache } from './utils/Cache.ts'\nimport { trimExtName } from './utils/trimExtName.ts'\n\nfunction mergeFile<TMeta extends object = object>(a: KubbFile.File<TMeta>, b: KubbFile.File<TMeta>): KubbFile.File<TMeta> {\n return {\n ...a,\n sources: [...(a.sources || []), ...(b.sources || [])],\n imports: [...(a.imports || []), ...(b.imports || [])],\n exports: [...(a.exports || []), ...(b.exports || [])],\n }\n}\n\ntype Options = {\n events?: AsyncEventEmitter<FabricEvents>\n}\n\nexport class FileManager {\n #cache = new Cache<KubbFile.ResolvedFile>()\n #filesCache: Array<KubbFile.ResolvedFile> | null = null\n events: AsyncEventEmitter<FabricEvents>\n processor: FileProcessor\n\n constructor({ events = new AsyncEventEmitter<FabricEvents>() }: Options = {}) {\n this.processor = new FileProcessor({ events })\n\n this.events = events\n return this\n }\n\n #resolvePath(file: KubbFile.File): KubbFile.File {\n this.events.emit('file:resolve:path', { file })\n\n return file\n }\n\n #resolveName(file: KubbFile.File): KubbFile.File {\n this.events.emit('file:resolve:name', { file })\n\n return file\n }\n\n async add(...files: Array<KubbFile.File>) {\n const resolvedFiles: Array<KubbFile.ResolvedFile> = []\n\n const mergedFiles = new Map<string, KubbFile.File>()\n\n files.forEach((file) => {\n const existing = mergedFiles.get(file.path)\n if (existing) {\n mergedFiles.set(file.path, mergeFile(existing, file))\n } else {\n mergedFiles.set(file.path, file)\n }\n })\n\n for (let file of mergedFiles.values()) {\n const existing = this.#cache.get(file.path)\n\n file = this.#resolveName(file)\n file = this.#resolvePath(file)\n\n const merged = existing ? mergeFile(existing, file) : file\n const resolvedFile = createFile(merged)\n\n this.#cache.set(resolvedFile.path, resolvedFile)\n this.flush()\n\n resolvedFiles.push(resolvedFile)\n }\n\n await this.events.emit('file:add', { files: resolvedFiles })\n\n return resolvedFiles\n }\n\n flush() {\n this.#filesCache = null\n this.#cache.flush()\n }\n\n getByPath(path: KubbFile.Path): KubbFile.ResolvedFile | null {\n return this.#cache.get(path)\n }\n\n deleteByPath(path: KubbFile.Path): void {\n this.#cache.delete(path)\n this.#filesCache = null\n }\n\n clear(): void {\n this.#cache.clear()\n this.#filesCache = null\n }\n\n get files(): Array<KubbFile.ResolvedFile> {\n if (this.#filesCache) {\n return this.#filesCache\n }\n\n const cachedKeys = this.#cache.keys()\n\n // order by path length and if file is a barrel file\n const keys = orderBy(cachedKeys, [(v) => v.length, (v) => trimExtName(v).endsWith('index')])\n\n const files: Array<KubbFile.ResolvedFile> = []\n\n for (const key of keys) {\n const file = this.#cache.get(key)\n if (file) {\n files.push(file)\n }\n }\n\n this.#filesCache = files\n\n return files\n }\n\n //TODO add test and check if write of FileManager contains the newly added file\n async write(options: ProcessFilesProps): Promise<KubbFile.ResolvedFile[]> {\n await this.events.emit('write:start', { files: this.files })\n\n const resolvedFiles = await this.processor.run(this.files, options)\n\n this.clear()\n\n await this.events.emit('write:end', { files: resolvedFiles })\n\n return resolvedFiles\n }\n}\n","import { isFunction } from 'remeda'\nimport type { Fabric, FabricConfig, FabricContext, FabricEvents, FabricOptions } from './Fabric.ts'\nimport { FileManager } from './FileManager.ts'\nimport type * as KubbFile from './KubbFile.ts'\nimport type { Parser } from './parsers/types.ts'\nimport type { Plugin } from './plugins/types.ts'\nimport { AsyncEventEmitter } from './utils/AsyncEventEmitter.ts'\n\n/**\n * Function that initializes the root Fabric instance.\n *\n * Used for setting up plugins, parsers, or performing side effects\n * once the Fabric context is ready.\n */\ntype FabricInitializer<T extends FabricOptions> = (fabric: Fabric<T>) => void | Promise<void>\n\n/**\n * A function returned by {@link defineFabric} that creates a Fabric instance.\n */\nexport type CreateFabric<T extends FabricOptions> = (config?: FabricConfig<T>) => Fabric<T>\n\n/**\n * Defines a new Fabric factory function.\n *\n * @example\n * export const createFabric = defineFabric((fabric) => {\n * fabric.use(myPlugin())\n * })\n */\nexport function defineFabric<T extends FabricOptions>(init?: FabricInitializer<T>): CreateFabric<T> {\n function create(config: FabricConfig<T> = { mode: 'sequential' } as FabricConfig<T>): Fabric<T> {\n const events = new AsyncEventEmitter<FabricEvents>()\n const installedPlugins = new Set<Plugin<any>>()\n const installedParsers = new Map<KubbFile.Extname, Parser<any>>()\n const installedParserNames = new Set<string>()\n const fileManager = new FileManager({ events })\n\n const context: FabricContext<T> = {\n get files() {\n return fileManager.files\n },\n async addFile(...files) {\n await fileManager.add(...files)\n },\n config,\n fileManager,\n installedPlugins,\n installedParsers,\n on: events.on.bind(events),\n off: events.off.bind(events),\n onOnce: events.onOnce.bind(events),\n removeAll: events.removeAll.bind(events),\n emit: events.emit.bind(events),\n } as FabricContext<T>\n\n const fabric: Fabric<T> = {\n context,\n get files() {\n return fileManager.files\n },\n async addFile(...files) {\n await fileManager.add(...files)\n },\n async use(pluginOrParser, ...options) {\n if (pluginOrParser.type === 'plugin') {\n if (installedPlugins.has(pluginOrParser)) {\n console.warn(`Plugin \"${pluginOrParser.name}\" already applied.`)\n } else {\n installedPlugins.add(pluginOrParser)\n }\n\n if (isFunction(pluginOrParser.inject)) {\n const injecter = pluginOrParser.inject\n\n const injected = (injecter as any)(context, ...options)\n Object.assign(fabric, injected)\n }\n }\n\n if (pluginOrParser.type === 'parser') {\n if (installedParserNames.has(pluginOrParser.name)) {\n console.warn(`Parser \"${pluginOrParser.name}\" already applied.`)\n } else {\n installedParserNames.add(pluginOrParser.name)\n }\n\n if (pluginOrParser.extNames) {\n for (const extName of pluginOrParser.extNames) {\n const existing = installedParsers.get(extName)\n if (existing && existing.name !== pluginOrParser.name) {\n console.warn(`Parser \"${pluginOrParser.name}\" is overriding parser \"${existing.name}\" for extension \"${extName}\".`)\n }\n installedParsers.set(extName, pluginOrParser)\n }\n }\n }\n\n if (isFunction(pluginOrParser.install)) {\n const installer = pluginOrParser.install\n\n await (installer as any)(context, ...options)\n }\n\n return fabric\n },\n } as Fabric<T>\n\n if (init) {\n init(fabric)\n }\n\n return fabric\n }\n\n return create\n}\n","import { defineFabric } from './defineFabric.ts'\n\nexport const createFabric = defineFabric()\n"],"x_google_ignoreList":[0],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  require('../trimExtName-Bb4zGVF1.cjs');
2
2
  require('../createParser-C4IkyTs5.cjs');
3
- require('../getRelativePath-C6lvNCs7.cjs');
4
- const require_typescriptParser = require('../typescriptParser-CNHO6H2_.cjs');
3
+ require('../getRelativePath-eCdp2Z8M.cjs');
4
+ const require_typescriptParser = require('../typescriptParser-D6-3Z7Lj.cjs');
5
5
 
6
6
  exports.createExport = require_typescriptParser.createExport;
7
7
  exports.createImport = require_typescriptParser.createImport;
@@ -1,3 +1,3 @@
1
- import "../Fabric-BezqNTQ9.cjs";
2
- import { i as typescriptParser, n as createImport, r as print, t as createExport } from "../typescriptParser-PfAO0SSm.cjs";
1
+ import "../Fabric-RmoYWGrr.cjs";
2
+ import { i as typescriptParser, n as createImport, r as print, t as createExport } from "../typescriptParser-BjqVuRHF.cjs";
3
3
  export { createExport, createImport, print, typescriptParser };
@@ -1,3 +1,3 @@
1
- import "../Fabric-CVe8cc8b.js";
2
- import { i as typescriptParser, n as createImport, r as print, t as createExport } from "../typescriptParser-B5SxjtvV.js";
1
+ import "../Fabric-cIhiQpgN.js";
2
+ import { i as typescriptParser, n as createImport, r as print, t as createExport } from "../typescriptParser-Cy9_9o6I.js";
3
3
  export { createExport, createImport, print, typescriptParser };
@@ -1,6 +1,6 @@
1
1
  import "../trimExtName-CeOVQVbu.js";
2
2
  import "../createParser-17uGjfu3.js";
3
3
  import "../getRelativePath-CERJmYkp.js";
4
- import { i as typescriptParser, n as createImport, r as print, t as createExport } from "../typescriptParser-CWT7zCJy.js";
4
+ import { i as typescriptParser, n as createImport, r as print, t as createExport } from "../typescriptParser-CvJg4PQJ.js";
5
5
 
6
6
  export { createExport, createImport, print, typescriptParser };
package/dist/parsers.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  require('./trimExtName-Bb4zGVF1.cjs');
2
2
  const require_createParser = require('./createParser-C4IkyTs5.cjs');
3
3
  const require_defaultParser = require('./defaultParser-n9VW2iVf.cjs');
4
- require('./getRelativePath-C6lvNCs7.cjs');
5
- const require_typescriptParser = require('./typescriptParser-CNHO6H2_.cjs');
4
+ require('./getRelativePath-eCdp2Z8M.cjs');
5
+ const require_typescriptParser = require('./typescriptParser-D6-3Z7Lj.cjs');
6
6
 
7
7
  //#region src/parsers/tsxParser.ts
8
8
  const tsxParser = require_createParser.createParser({
@@ -1,5 +1,5 @@
1
- import { d as UserParser, u as Parser } from "./Fabric-BezqNTQ9.cjs";
2
- import { i as typescriptParser } from "./typescriptParser-PfAO0SSm.cjs";
1
+ import { d as UserParser, u as Parser } from "./Fabric-RmoYWGrr.cjs";
2
+ import { i as typescriptParser } from "./typescriptParser-BjqVuRHF.cjs";
3
3
 
4
4
  //#region src/parsers/createParser.d.ts
5
5
  declare function createParser<TOptions = unknown, TMeta extends object = any>(parser: UserParser<TOptions, TMeta>): Parser<TOptions, TMeta>;
package/dist/parsers.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { d as UserParser, u as Parser } from "./Fabric-CVe8cc8b.js";
2
- import { i as typescriptParser } from "./typescriptParser-B5SxjtvV.js";
1
+ import { d as UserParser, u as Parser } from "./Fabric-cIhiQpgN.js";
2
+ import { i as typescriptParser } from "./typescriptParser-Cy9_9o6I.js";
3
3
 
4
4
  //#region src/parsers/createParser.d.ts
5
5
  declare function createParser<TOptions = unknown, TMeta extends object = any>(parser: UserParser<TOptions, TMeta>): Parser<TOptions, TMeta>;
package/dist/parsers.js CHANGED
@@ -2,7 +2,7 @@ import "./trimExtName-CeOVQVbu.js";
2
2
  import { t as createParser } from "./createParser-17uGjfu3.js";
3
3
  import { t as defaultParser } from "./defaultParser--HzU9LPa.js";
4
4
  import "./getRelativePath-CERJmYkp.js";
5
- import { i as typescriptParser } from "./typescriptParser-CWT7zCJy.js";
5
+ import { i as typescriptParser } from "./typescriptParser-CvJg4PQJ.js";
6
6
 
7
7
  //#region src/parsers/tsxParser.ts
8
8
  const tsxParser = createParser({
package/dist/plugins.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  const require_trimExtName = require('./trimExtName-Bb4zGVF1.cjs');
2
- const require_defineProperty = require('./defineProperty-DZi5DvrW.cjs');
3
- const require_getRelativePath = require('./getRelativePath-C6lvNCs7.cjs');
2
+ const require_defineProperty = require('./defineProperty-DwFON4j7.cjs');
3
+ const require_getRelativePath = require('./getRelativePath-eCdp2Z8M.cjs');
4
4
  let node_path = require("node:path");
5
5
  node_path = require_trimExtName.__toESM(node_path);
6
6
  let fs_extra = require("fs-extra");
@@ -10,19 +10,19 @@ node_http = require_trimExtName.__toESM(node_http);
10
10
  let serve_handler = require("serve-handler");
11
11
  serve_handler = require_trimExtName.__toESM(serve_handler);
12
12
  let node_child_process = require("node:child_process");
13
- node_child_process = require_trimExtName.__toESM(node_child_process);
14
13
  let node_process = require("node:process");
15
14
  node_process = require_trimExtName.__toESM(node_process);
16
15
  let cli_progress = require("cli-progress");
17
- cli_progress = require_trimExtName.__toESM(cli_progress);
18
16
 
19
17
  //#region src/utils/TreeNode.ts
18
+ var _childrenMap = /* @__PURE__ */ new WeakMap();
20
19
  var _cachedLeaves = /* @__PURE__ */ new WeakMap();
21
20
  var TreeNode = class TreeNode {
22
21
  constructor(data, parent) {
23
22
  require_defineProperty._defineProperty(this, "data", void 0);
24
23
  require_defineProperty._defineProperty(this, "parent", void 0);
25
24
  require_defineProperty._defineProperty(this, "children", []);
25
+ require_defineProperty._classPrivateFieldInitSpec(this, _childrenMap, /* @__PURE__ */ new Map());
26
26
  require_defineProperty._classPrivateFieldInitSpec(this, _cachedLeaves, void 0);
27
27
  this.data = data;
28
28
  this.parent = parent;
@@ -30,24 +30,35 @@ var TreeNode = class TreeNode {
30
30
  addChild(data) {
31
31
  const child = new TreeNode(data, this);
32
32
  this.children.push(child);
33
+ if (typeof data === "object" && data !== null && "name" in data) require_defineProperty._classPrivateFieldGet2(_childrenMap, this).set(data.name, child);
33
34
  require_defineProperty._classPrivateFieldSet2(_cachedLeaves, this, void 0);
34
35
  return child;
35
36
  }
37
+ getChildByName(name) {
38
+ return require_defineProperty._classPrivateFieldGet2(_childrenMap, this).get(name);
39
+ }
36
40
  get leaves() {
37
41
  if (require_defineProperty._classPrivateFieldGet2(_cachedLeaves, this)) return require_defineProperty._classPrivateFieldGet2(_cachedLeaves, this);
38
42
  if (this.children.length === 0) return [this];
39
- const stack = [...this.children];
40
43
  const result = [];
41
- for (const node of stack) if (node.children.length) for (const child of node.children) stack.push(child);
42
- else result.push(node);
44
+ const stack = [...this.children];
45
+ const visited = /* @__PURE__ */ new Set();
46
+ while (stack.length > 0) {
47
+ const node = stack.pop();
48
+ if (visited.has(node)) continue;
49
+ visited.add(node);
50
+ if (node.children.length > 0) stack.push(...node.children);
51
+ else result.push(node);
52
+ }
43
53
  require_defineProperty._classPrivateFieldSet2(_cachedLeaves, this, result);
44
54
  return result;
45
55
  }
46
56
  forEach(callback) {
47
57
  const stack = [this];
48
- for (const node of stack) {
58
+ for (let i = 0; i < stack.length; i++) {
59
+ const node = stack[i];
49
60
  callback(node);
50
- if (node.children.length) for (const child of node.children) stack.push(child);
61
+ if (node.children.length > 0) stack.push(...node.children);
51
62
  }
52
63
  return this;
53
64
  }
@@ -57,16 +68,23 @@ var TreeNode = class TreeNode {
57
68
  static toGraph(root) {
58
69
  const nodes = [];
59
70
  const edges = [];
60
- root.forEach((node) => {
71
+ const stack = [root];
72
+ for (let i = 0; i < stack.length; i++) {
73
+ const node = stack[i];
61
74
  nodes.push({
62
75
  id: node.data.path,
63
76
  label: node.data.name
64
77
  });
65
- for (const child of node.children) edges.push({
66
- from: node.data.path,
67
- to: child.data.path
68
- });
69
- });
78
+ const children = node.children;
79
+ if (children.length > 0) for (let j = 0, len = children.length; j < len; j++) {
80
+ const child = children[j];
81
+ edges.push({
82
+ from: node.data.path,
83
+ to: child.data.path
84
+ });
85
+ stack.push(child);
86
+ }
87
+ }
70
88
  return {
71
89
  nodes,
72
90
  edges
@@ -76,10 +94,14 @@ var TreeNode = class TreeNode {
76
94
  const normalizePath = (p) => p.replace(/\\/g, "/");
77
95
  const normalizedRoot = normalizePath(rootFolder);
78
96
  const rootPrefix = normalizedRoot.endsWith("/") ? normalizedRoot : `${normalizedRoot}/`;
79
- const filteredFiles = files.filter((file) => {
80
- const filePath = normalizePath(file.path);
81
- return !filePath.endsWith(".json") && (!rootFolder || filePath.startsWith(rootPrefix));
82
- });
97
+ const normalizedPaths = /* @__PURE__ */ new Map();
98
+ const filteredFiles = [];
99
+ for (const file of files) {
100
+ var _normalizedPaths$get;
101
+ const filePath = (_normalizedPaths$get = normalizedPaths.get(file)) !== null && _normalizedPaths$get !== void 0 ? _normalizedPaths$get : normalizePath(file.path);
102
+ normalizedPaths.set(file, filePath);
103
+ if (!filePath.endsWith(".json") && (!rootFolder || filePath.startsWith(rootPrefix))) filteredFiles.push(file);
104
+ }
83
105
  if (filteredFiles.length === 0) return null;
84
106
  const treeNode = new TreeNode({
85
107
  name: rootFolder || "",
@@ -87,17 +109,13 @@ var TreeNode = class TreeNode {
87
109
  file: void 0
88
110
  });
89
111
  for (const file of filteredFiles) {
90
- const parts = normalizePath(file.path).slice(rootPrefix.length).split("/");
112
+ const parts = normalizedPaths.get(file).slice(rootPrefix.length).split("/");
91
113
  let current = treeNode;
92
114
  let currentPath = rootFolder;
93
115
  for (const [index, part] of parts.entries()) {
94
116
  const isLast = index === parts.length - 1;
95
117
  currentPath += (currentPath.endsWith("/") ? "" : "/") + part;
96
- let next;
97
- for (const child of current.children) if (child.data.name === part) {
98
- next = child;
99
- break;
100
- }
118
+ let next = current.getChildByName(part);
101
119
  if (!next) next = current.addChild({
102
120
  name: part,
103
121
  path: currentPath,
@@ -121,8 +139,15 @@ function createPlugin(plugin) {
121
139
 
122
140
  //#endregion
123
141
  //#region src/plugins/barrelPlugin.ts
142
+ /** biome-ignore-all lint/suspicious/useIterableCallbackReturn: not needed */
124
143
  function getBarrelFiles({ files, root, mode }) {
125
144
  if (mode === "propagate" || mode === false) return [];
145
+ const indexableSourcesMap = /* @__PURE__ */ new Map();
146
+ for (const file of files) {
147
+ const indexableSources = [];
148
+ for (const source of file.sources || []) if (source.isIndexable && source.name) indexableSources.push(source);
149
+ if (indexableSources.length > 0) indexableSourcesMap.set(file, indexableSources);
150
+ }
126
151
  const cachedFiles = /* @__PURE__ */ new Map();
127
152
  const dedupe = /* @__PURE__ */ new Map();
128
153
  const treeNode = TreeNode.fromFiles(files, root);
@@ -144,13 +169,14 @@ function getBarrelFiles({ files, root, mode }) {
144
169
  dedupe.set(barrelPath, /* @__PURE__ */ new Set());
145
170
  }
146
171
  const seen = dedupe.get(barrelPath);
147
- node.leaves.forEach((leaf) => {
172
+ for (const leaf of node.leaves) {
148
173
  const file = leaf.data.file;
149
- if (!file) return;
150
- (file.sources || []).forEach((source) => {
151
- if (!file.path || !source.isIndexable || !source.name) return;
174
+ if (!file || !file.path) continue;
175
+ const indexableSources = indexableSourcesMap.get(file);
176
+ if (!indexableSources) continue;
177
+ for (const source of indexableSources) {
152
178
  const key = `${source.name}|${source.isTypeOnly ? "1" : "0"}`;
153
- if (seen.has(key)) return;
179
+ if (seen.has(key)) continue;
154
180
  seen.add(key);
155
181
  barrelFile.exports.push({
156
182
  name: [source.name],
@@ -164,8 +190,8 @@ function getBarrelFiles({ files, root, mode }) {
164
190
  isExportable: mode === "all" || mode === "named",
165
191
  isIndexable: mode === "all" || mode === "named"
166
192
  });
167
- });
168
- });
193
+ }
194
+ }
169
195
  });
170
196
  const result = [...cachedFiles.values()];
171
197
  if (mode === "all") return result.map((file) => {
@@ -200,23 +226,30 @@ const barrelPlugin = createPlugin({
200
226
  return { async writeEntry({ root, mode }) {
201
227
  if (!mode || mode === "propagate") return;
202
228
  const rootPath = node_path.default.resolve(root, "index.ts");
229
+ const barrelFiles = [];
230
+ for (const file of ctx.files) for (const source of file.sources) if (source.isIndexable) {
231
+ barrelFiles.push(file);
232
+ break;
233
+ }
234
+ const fileTypeCache = /* @__PURE__ */ new Map();
235
+ for (const file of barrelFiles) fileTypeCache.set(file, file.sources.every((source) => source.isTypeOnly));
236
+ const exports$1 = [];
237
+ for (const file of barrelFiles) {
238
+ var _fileTypeCache$get;
239
+ const containsOnlyTypes = (_fileTypeCache$get = fileTypeCache.get(file)) !== null && _fileTypeCache$get !== void 0 ? _fileTypeCache$get : false;
240
+ for (const source of file.sources) {
241
+ if (!file.path || !source.isIndexable) continue;
242
+ exports$1.push({
243
+ name: mode === "all" ? void 0 : [source.name],
244
+ path: require_getRelativePath.getRelativePath(rootPath, file.path),
245
+ isTypeOnly: mode === "all" ? containsOnlyTypes : source.isTypeOnly
246
+ });
247
+ }
248
+ }
203
249
  const entryFile = require_defineProperty.createFile({
204
250
  path: rootPath,
205
251
  baseName: "index.ts",
206
- exports: ctx.files.filter((file) => {
207
- return file.sources.some((source) => source.isIndexable);
208
- }).flatMap((file) => {
209
- var _file$sources;
210
- const containsOnlyTypes = file.sources.every((source) => source.isTypeOnly);
211
- return (_file$sources = file.sources) === null || _file$sources === void 0 ? void 0 : _file$sources.map((source) => {
212
- if (!file.path || !source.isIndexable) return;
213
- return {
214
- name: mode === "all" ? void 0 : [source.name],
215
- path: require_getRelativePath.getRelativePath(rootPath, file.path),
216
- isTypeOnly: mode === "all" ? containsOnlyTypes : source.isTypeOnly
217
- };
218
- }).filter(Boolean);
219
- }).filter(Boolean),
252
+ exports: exports$1,
220
253
  sources: []
221
254
  });
222
255
  await ctx.addFile(entryFile);