rspress-plugin-api-extractor 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +1 -1
  2. package/api-extracted-package.js +20 -8
  3. package/build-program.js +1 -2
  4. package/build-stages.js +6 -7
  5. package/config-helpers.js +5 -8
  6. package/config-utils.js +4 -4
  7. package/index.d.ts +492 -742
  8. package/layers/ConfigServiceLive.js +6 -6
  9. package/layers/ObservabilityLive.js +7 -8
  10. package/layers/SnapshotServiceLive.js +3 -5
  11. package/layers/TypeRegistryServiceLive.js +119 -116
  12. package/layers/build-metrics.js +7 -7
  13. package/llms-program.js +3 -4
  14. package/migrations/001_create_snapshots.js +1 -1
  15. package/observability/EventBus.js +1 -1
  16. package/observability/sinks/metrics-sink.js +13 -13
  17. package/package.json +16 -15
  18. package/runtime/components/EnumMembersTable/index.css +18 -18
  19. package/runtime/components/EnumMembersTable/index.module.js +3 -3
  20. package/runtime/components/ExampleBlock/index.css +2 -2
  21. package/runtime/components/ExampleBlock/index.module.js +2 -2
  22. package/runtime/components/MemberSignature/index.css +5 -5
  23. package/runtime/components/MemberSignature/index.module.js +3 -3
  24. package/runtime/components/ParametersTable/index.css +19 -19
  25. package/runtime/components/ParametersTable/index.module.js +3 -3
  26. package/runtime/components/SignatureBlock/index.css +5 -5
  27. package/runtime/components/SignatureBlock/index.module.js +3 -3
  28. package/runtime/components/SignatureCode/index.css +9 -9
  29. package/runtime/components/SignatureCode/index.module.js +3 -3
  30. package/runtime/components/SignatureToolbar/index.css +18 -18
  31. package/runtime/components/SignatureToolbar/index.module.js +7 -7
  32. package/runtime/components/buttons/index.css +5 -5
  33. package/runtime/components/buttons/index.module.js +2 -2
  34. package/schemas/config.js +63 -57
  35. package/schemas/observability.js +12 -4
  36. package/schemas/opengraph.js +5 -5
  37. package/schemas/performance.js +13 -13
  38. package/services/ConfigService.js +1 -1
  39. package/services/PathDerivationService.js +1 -1
  40. package/services/SnapshotService.js +1 -1
  41. package/services/TypeRegistryService.js +1 -1
  42. package/tsdoc-metadata.json +1 -1
@@ -180,7 +180,7 @@ function ConfigServiceLive(options, shikiCrossLinker, buildId = "", resolvedThre
180
180
  const packageJson = api.packageJson ? await ApiModelLoader.loadPackageJson(api.packageJson) : void 0;
181
181
  validateExternalPackages(api.externalPackages, packageJson);
182
182
  const externalPackages = api.externalPackages || extractAutoDetectedPackages(packageJson, api.autoDetectDependencies);
183
- if (externalPackages && externalPackages.length > 0) Effect.runSync(Metric.incrementBy(BuildMetrics.externalPackagesTotal, externalPackages.length));
183
+ if (externalPackages && externalPackages.length > 0) Effect.runSync(Metric.update(BuildMetrics.externalPackagesTotal, externalPackages.length));
184
184
  const vfs = ApiExtractedPackage.fromPackage(apiPackage, api.packageName).generateVfs();
185
185
  const vfsPayloads = prependImportsToVfs(vfs, apiPackage, api.packageName, wantTrace);
186
186
  const resolvedOgImage = api.ogImage ?? options.ogImage;
@@ -234,7 +234,7 @@ function ConfigServiceLive(options, shikiCrossLinker, buildId = "", resolvedThre
234
234
  return yield* Effect.promise(async () => {
235
235
  const versionConfig = isVersionConfig(versionValue) ? versionValue : { model: versionValue };
236
236
  const { apiPackage, packageJson: versionPackageJson, categories: versionCategories, source: versionSource, externalPackages: versionExternalPackages, autoDetectDependencies: versionAutoDetectDependencies, llmsPlugin: versionLlms, ogImage: versionOgImage } = await ApiModelLoader.loadVersionModel(versionConfig);
237
- Effect.runSync(Metric.increment(BuildMetrics.apiVersionsLoaded));
237
+ Effect.runSync(Metric.update(BuildMetrics.apiVersionsLoaded, 1));
238
238
  const resolvedCategories = categoryResolver.resolveCategoryConfig(pluginDefaults, api.categories, versionCategories);
239
239
  const resolvedSource = categoryResolver.resolveSourceConfig(api.source, versionSource);
240
240
  const resolvedLlms = mergeLlmsPluginConfig(options.llmsPlugin, api.llmsPlugin, versionLlms);
@@ -242,7 +242,7 @@ function ConfigServiceLive(options, shikiCrossLinker, buildId = "", resolvedThre
242
242
  validateExternalPackages(versionExternalPackages || api.externalPackages, packageJson);
243
243
  const autoDetectOptions = versionAutoDetectDependencies || api.autoDetectDependencies;
244
244
  const externalPackages = versionExternalPackages || api.externalPackages || extractAutoDetectedPackages(packageJson, autoDetectOptions);
245
- if (externalPackages && externalPackages.length > 0) Effect.runSync(Metric.incrementBy(BuildMetrics.externalPackagesTotal, externalPackages.length));
245
+ if (externalPackages && externalPackages.length > 0) Effect.runSync(Metric.update(BuildMetrics.externalPackagesTotal, externalPackages.length));
246
246
  const vfs = ApiExtractedPackage.fromPackage(apiPackage, api.packageName).generateVfs();
247
247
  const vfsPayloads = prependImportsToVfs(vfs, apiPackage, api.packageName, wantTrace);
248
248
  const resolvedOgImage = versionOgImage ?? api.ogImage ?? options.ogImage;
@@ -433,7 +433,7 @@ function ConfigServiceLive(options, shikiCrossLinker, buildId = "", resolvedThre
433
433
  }));
434
434
  const documentedPackageNames = new Set(apiConfigs.map((config) => config.packageName));
435
435
  const externalPackagesToLoad = allExternalPackages.filter((pkg) => !documentedPackageNames.has(pkg.name));
436
- const typeLoadResult = yield* Effect.either(Effect.gen(function* () {
436
+ const typeLoadResult = yield* Effect.result(Effect.gen(function* () {
437
437
  if (externalPackagesToLoad.length > 0) {
438
438
  const resolvedPackages = yield* typeRegistry.resolveVersions(externalPackagesToLoad);
439
439
  const droppedCount = externalPackagesToLoad.length - resolvedPackages.length;
@@ -454,12 +454,12 @@ function ConfigServiceLive(options, shikiCrossLinker, buildId = "", resolvedThre
454
454
  }
455
455
  }
456
456
  }));
457
- if (typeLoadResult._tag === "Left") yield* emit(PluginEvent.ConfigCascadeWarning({
457
+ if (typeLoadResult._tag === "Failure") yield* emit(PluginEvent.ConfigCascadeWarning({
458
458
  ctx: { buildId: "" },
459
459
  level: "warn",
460
460
  field: "externalTypes",
461
461
  chosen: "empty VFS",
462
- ignored: [typeLoadResult.left.message ?? String(typeLoadResult.left)]
462
+ ignored: [typeLoadResult.failure.message ?? String(typeLoadResult.failure)]
463
463
  }));
464
464
  const twoslashStartMs = performance.now();
465
465
  TwoslashManager.getInstance().initialize(combinedVfs, void 0, void 0, void 0, resolvedCompilerOptions);
@@ -3,7 +3,7 @@ import { makeConsoleSink } from "../observability/sinks/console-sink.js";
3
3
  import { BuildMetrics } from "./build-metrics.js";
4
4
  import { makeMetricsSink } from "../observability/sinks/metrics-sink.js";
5
5
  import { makeTraceSink } from "../observability/sinks/trace-sink.js";
6
- import { Effect, Layer, LogLevel, Logger, Metric } from "effect";
6
+ import { Effect, Layer, Logger, Metric, References } from "effect";
7
7
 
8
8
  //#region src/layers/ObservabilityLive.ts
9
9
  function formatTime(date) {
@@ -13,20 +13,19 @@ function formatTime(date) {
13
13
  * A slim Effect Logger layer that gates the residual `Effect.log*` calls in
14
14
  * `build-program.ts` and `logBuildSummary` at the configured level.
15
15
  *
16
- * Level mapping: none→None, error→Error, warn→Warning, info→Info,
16
+ * Level mapping: none→None, error→Error, warn→Warn, info→Info,
17
17
  * debug/trace→Debug. Format: `[HH:MM:SS] <prefix><message>` with
18
- * `⚠️ ` / `🔴 ` prefixes for Warning / Error to match the EventBus
18
+ * `⚠️ ` / `🔴 ` prefixes for Warn / Error to match the EventBus
19
19
  * console-sink style.
20
20
  */
21
21
  function makeSummaryLoggerLayer(logLevel) {
22
- const effectLevel = logLevel === "none" ? LogLevel.None : logLevel === "error" ? LogLevel.Error : logLevel === "warn" ? LogLevel.Warning : logLevel === "info" ? LogLevel.Info : LogLevel.Debug;
22
+ const effectLevel = logLevel === "none" ? "None" : logLevel === "error" ? "Error" : logLevel === "warn" ? "Warn" : logLevel === "info" ? "Info" : "Debug";
23
23
  const pluginLogger = Logger.make(({ logLevel: lvl, message, date }) => {
24
24
  const time = formatTime(date);
25
- const msg = typeof message === "string" ? message : String(message);
26
- const prefix = lvl._tag === "Warning" ? "⚠️ " : lvl._tag === "Error" ? "🔴 " : "";
27
- console.log(`[${time}] ${prefix}${msg}`);
25
+ const msg = Array.isArray(message) ? message.map(String).join(" ") : String(message);
26
+ console.log(`[${time}] ${lvl === "Warn" ? "⚠️ " : lvl === "Error" ? "🔴 " : ""}${msg}`);
28
27
  });
29
- return Layer.mergeAll(Logger.replace(Logger.defaultLogger, pluginLogger), Logger.minimumLogLevel(effectLevel));
28
+ return Layer.mergeAll(Logger.layer([pluginLogger]), Layer.succeed(References.MinimumLogLevel, effectLevel));
30
29
  }
31
30
  /**
32
31
  * Compose the console + metrics (+ optional trace) sinks into an EventBus layer.
@@ -2,11 +2,9 @@ import { hashContent } from "../content-hash.js";
2
2
  import { SnapshotService } from "../services/SnapshotService.js";
3
3
  import { SnapshotDbError } from "../errors.js";
4
4
  import migration from "../migrations/001_create_snapshots.js";
5
- import { NodeContext } from "@effect/platform-node";
6
5
  import { Effect, Layer, Option } from "effect";
7
- import { Migrator } from "@effect/sql";
8
- import * as SqlClient from "@effect/sql/SqlClient";
9
6
  import { SqliteClient, SqliteMigrator } from "@effect/sql-sqlite-node";
7
+ import { Migrator, SqlClient } from "effect/unstable/sql";
10
8
 
11
9
  //#region src/layers/SnapshotServiceLive.ts
12
10
  function toFileSnapshot(row) {
@@ -29,8 +27,8 @@ function toSnapshotDbError(error) {
29
27
  }
30
28
  const SnapshotServiceLive = (dbPath) => {
31
29
  const SqlLive = SqliteClient.layer({ filename: dbPath });
32
- const MigratorLive = SqliteMigrator.layer({ loader: Migrator.fromRecord({ "001_create_snapshots": migration }) }).pipe(Layer.provide(Layer.merge(SqlLive, NodeContext.layer)));
33
- const ServiceImpl = Layer.scoped(SnapshotService, Effect.gen(function* () {
30
+ const MigratorLive = SqliteMigrator.layer({ loader: Migrator.fromRecord({ "001_create_snapshots": migration }) }).pipe(Layer.provide(SqlLive));
31
+ const ServiceImpl = Layer.effect(SnapshotService, Effect.gen(function* () {
34
32
  const sql = yield* SqlClient.SqlClient;
35
33
  yield* Effect.addFinalizer(() => sql`PRAGMA wal_checkpoint(TRUNCATE)`.pipe(Effect.ignore));
36
34
  return {
@@ -3,9 +3,11 @@ import { emit } from "../observability/EventBus.js";
3
3
  import { resolveExternalPackageVersions } from "../config-utils.js";
4
4
  import { TypeRegistryError } from "../errors.js";
5
5
  import { TypeRegistryService } from "../services/TypeRegistryService.js";
6
- import { Effect, Layer } from "effect";
7
- import { PackageSpec, RegistryEvent, TypeRegistry, TypeRegistryObserver } from "type-registry-effect";
8
- import { NodeLayer } from "type-registry-effect/node";
6
+ import { NodeFileSystem, NodeHttpClient } from "@effect/platform-node";
7
+ import { Duration, Effect, Layer, Path } from "effect";
8
+ import { PackageFetcher, PackageSpec, RegistryObserver, TypeCache, TypeRegistry } from "type-registry-effect";
9
+ import { Cache } from "@effected/store";
10
+ import { AppDirs, Xdg } from "@effected/xdg";
9
11
 
10
12
  //#region src/layers/TypeRegistryServiceLive.ts
11
13
  /**
@@ -17,130 +19,131 @@ import { NodeLayer } from "type-registry-effect/node";
17
19
  * The summary (`BatchComplete`) and failures are surfaced at info/warning;
18
20
  * per-package detail stays at debug so a normal build is quiet.
19
21
  */
20
- const RegistryObserverLayer = Layer.succeed(TypeRegistryObserver, { emit: (event) => RegistryEvent.$match(event, {
21
- VersionResolved: ({ package: pkg, requested, resolved }) => emit(PluginEvent.TypeRegistryEvent({
22
- ctx: {
23
- buildId: "",
24
- packageName: pkg
25
- },
26
- level: "debug",
27
- kind: "VersionResolved",
28
- detail: `${requested} -> ${resolved}`
29
- })),
30
- VersionResolveFailed: ({ package: pkg, requested, reason }) => emit(PluginEvent.TypeRegistryEvent({
31
- ctx: {
32
- buildId: "",
33
- packageName: pkg
34
- },
35
- level: "debug",
36
- kind: "VersionResolveFailed",
37
- detail: `${requested}: ${reason}`
38
- })),
39
- CacheHit: ({ package: pkg, version }) => emit(PluginEvent.TypeRegistryEvent({
40
- ctx: {
41
- buildId: "",
42
- packageName: pkg,
43
- version
44
- },
45
- level: "debug",
46
- kind: "CacheHit",
47
- detail: ""
48
- })),
49
- CacheStale: ({ package: pkg, version }) => emit(PluginEvent.TypeRegistryEvent({
50
- ctx: {
51
- buildId: "",
52
- packageName: pkg,
53
- version
54
- },
55
- level: "debug",
56
- kind: "CacheStale",
57
- detail: ""
58
- })),
59
- CacheMiss: ({ package: pkg, version }) => emit(PluginEvent.TypeRegistryEvent({
60
- ctx: {
61
- buildId: "",
62
- packageName: pkg,
63
- version
64
- },
65
- level: "debug",
66
- kind: "CacheMiss",
67
- detail: ""
68
- })),
69
- FetchStart: ({ package: pkg, version }) => emit(PluginEvent.TypeRegistryEvent({
70
- ctx: {
71
- buildId: "",
72
- packageName: pkg,
73
- version
74
- },
75
- level: "debug",
76
- kind: "FetchStart",
77
- detail: ""
78
- })),
79
- FetchFailed: ({ url, status, bodySnippet }) => emit(PluginEvent.TypeRegistryEvent({
80
- ctx: { buildId: "" },
81
- level: "debug",
82
- kind: "FetchFailed",
83
- detail: `HTTP ${status}: ${url}${bodySnippet ? ` — ${bodySnippet}` : ""}`
84
- })),
85
- PackageLoaded: ({ package: pkg, version, files, source }) => emit(PluginEvent.TypeRegistryEvent({
86
- ctx: {
87
- buildId: "",
88
- packageName: pkg,
89
- version
90
- },
91
- level: "debug",
92
- kind: "PackageLoaded",
93
- detail: `${files} files, ${source}`
94
- })),
95
- PackageLoadFailed: ({ package: pkg, version, kind, message }) => emit(PluginEvent.TypeRegistryEvent({
96
- ctx: {
97
- buildId: "",
98
- packageName: pkg,
99
- version
100
- },
101
- level: "warn",
102
- kind: "PackageLoadFailed",
103
- detail: `[${kind}] ${message}`
104
- })),
105
- BatchStart: ({ total }) => emit(PluginEvent.TypeRegistryEvent({
106
- ctx: { buildId: "" },
107
- level: "debug",
108
- kind: "BatchStart",
109
- detail: `${total} package(s)`
110
- })),
111
- BatchComplete: ({ loaded, total, totalFiles, durationMs }) => emit(PluginEvent.TypeRegistryEvent({
112
- ctx: { buildId: "" },
113
- level: "info",
114
- kind: "BatchComplete",
115
- detail: `${loaded}/${total} packages, ${totalFiles} files, ${durationMs}ms`
116
- }))
117
- }) });
22
+ const RegistryObserverLayer = Layer.succeed(RegistryObserver, { emit: (event) => {
23
+ switch (event._tag) {
24
+ case "VersionResolved": return emit(PluginEvent.TypeRegistryEvent({
25
+ ctx: {
26
+ buildId: "",
27
+ packageName: event.package
28
+ },
29
+ level: "debug",
30
+ kind: "VersionResolved",
31
+ detail: `${event.requested} -> ${event.resolved}`
32
+ }));
33
+ case "VersionResolveFailed": return emit(PluginEvent.TypeRegistryEvent({
34
+ ctx: {
35
+ buildId: "",
36
+ packageName: event.package
37
+ },
38
+ level: "debug",
39
+ kind: "VersionResolveFailed",
40
+ detail: `${event.requested}: ${event.kind}`
41
+ }));
42
+ case "CacheHit":
43
+ case "CacheMiss":
44
+ case "FetchStart": return emit(PluginEvent.TypeRegistryEvent({
45
+ ctx: {
46
+ buildId: "",
47
+ packageName: event.package,
48
+ version: event.version
49
+ },
50
+ level: "debug",
51
+ kind: event._tag,
52
+ detail: ""
53
+ }));
54
+ case "CacheStale": return emit(PluginEvent.TypeRegistryEvent({
55
+ ctx: {
56
+ buildId: "",
57
+ packageName: event.package,
58
+ version: event.version
59
+ },
60
+ level: "debug",
61
+ kind: "CacheStale",
62
+ detail: ""
63
+ }));
64
+ case "FetchFailed": return emit(PluginEvent.TypeRegistryEvent({
65
+ ctx: { buildId: "" },
66
+ level: "debug",
67
+ kind: "FetchFailed",
68
+ detail: `HTTP ${event.status}: ${event.url}${event.bodySnippet ? ` — ${event.bodySnippet}` : ""}`
69
+ }));
70
+ case "PackageLoaded": return emit(PluginEvent.TypeRegistryEvent({
71
+ ctx: {
72
+ buildId: "",
73
+ packageName: event.package,
74
+ version: event.version
75
+ },
76
+ level: "debug",
77
+ kind: "PackageLoaded",
78
+ detail: `${event.files} files, ${event.source}`
79
+ }));
80
+ case "PackageLoadFailed": return emit(PluginEvent.TypeRegistryEvent({
81
+ ctx: {
82
+ buildId: "",
83
+ packageName: event.package,
84
+ version: event.version
85
+ },
86
+ level: "warn",
87
+ kind: "PackageLoadFailed",
88
+ detail: `[${event.kind}] ${event.error instanceof Error ? event.error.message : String(event.error)}`
89
+ }));
90
+ case "BatchStart": return emit(PluginEvent.TypeRegistryEvent({
91
+ ctx: { buildId: "" },
92
+ level: "debug",
93
+ kind: "BatchStart",
94
+ detail: `${event.total} package(s)`
95
+ }));
96
+ case "BatchComplete": return emit(PluginEvent.TypeRegistryEvent({
97
+ ctx: { buildId: "" },
98
+ level: "info",
99
+ kind: "BatchComplete",
100
+ detail: `${event.loaded}/${event.total} packages, ${event.totalFiles} files, ${Math.round(Duration.toMillis(event.duration))}ms`
101
+ }));
102
+ }
103
+ } });
118
104
  /**
119
- * type-registry-effect runtime: the Node platform layer plus the observer that
120
- * forwards registry events to the plugin logger.
105
+ * type-registry-effect v2 composes at the edge: the library ships no platform
106
+ * layer of its own, so the plugin wires FileSystem/Path, the XDG directories,
107
+ * the sqlite metadata Cache and the HTTP client here.
121
108
  *
122
- * `NodeLayer` provides CacheService, PackageFetcher, and TypeResolver with
123
- * Node.js platform implementations (FileSystem, HttpClient). Built-in metrics
124
- * (packagesLoaded, packagesFailed, cacheHits, etc.) are tracked by the library.
109
+ * All layers are bound to module-level consts (never rebuilt per call) per the
110
+ * v4 layer memoization discipline.
111
+ */
112
+ const PlatformLive = Layer.mergeAll(NodeFileSystem.layer, Path.layer);
113
+ /** XDG app directories under the library's shared namespace (cache is shared across consumers). */
114
+ const AppDirsLive = AppDirs.layer({ namespace: "type-registry-effect" }).pipe(Layer.provide(Layer.mergeAll(Xdg.layer, PlatformLive)));
115
+ /** Metadata plane: a sqlite-backed `@effected/store` Cache rooted in the XDG cache dir. */
116
+ const MetadataCacheLive = Layer.unwrap(Effect.gen(function* () {
117
+ const appDirs = yield* AppDirs;
118
+ const path = yield* Path.Path;
119
+ const cacheDir = yield* appDirs.ensureCache;
120
+ return Cache.layerSqlite({ filename: path.join(cacheDir, "metadata.sqlite") });
121
+ })).pipe(Layer.provide(Layer.mergeAll(AppDirsLive, PlatformLive)));
122
+ /**
123
+ * The full registry runtime: TypeRegistry over an XDG-rooted TypeCache and the
124
+ * jsDelivr PackageFetcher, with the observer that forwards registry events to
125
+ * the plugin's EventBus (found ambiently via serviceOption at emit time).
125
126
  */
126
- const RegistryLayer = Layer.merge(NodeLayer, RegistryObserverLayer);
127
+ const RegistryLayer = TypeRegistry.layer.pipe(Layer.provideMerge(Layer.mergeAll(TypeCache.layerXdg(), PackageFetcher.layer)), Layer.provideMerge(RegistryObserverLayer), Layer.provide(Layer.mergeAll(MetadataCacheLive, AppDirsLive, PlatformLive, NodeHttpClient.layerUndici)));
127
128
  /**
128
129
  * TypeRegistryServiceLive: uses type-registry-effect Effect programs directly.
129
130
  */
130
131
  const TypeRegistryServiceLive = Layer.succeed(TypeRegistryService, {
131
- resolveVersions: (packages) => resolveExternalPackageVersions(packages, (pkg) => TypeRegistry.resolveVersion(pkg.name, pkg.version)).pipe(Effect.provide(RegistryLayer)),
132
- loadPackages: (packages) => Effect.gen(function* () {
133
- if (packages.length === 0) return { vfs: /* @__PURE__ */ new Map() };
132
+ resolveVersions: (packages) => Effect.gen(function* () {
133
+ const registry = yield* TypeRegistry;
134
+ return yield* resolveExternalPackageVersions(packages, (pkg) => registry.resolveVersion(pkg.name, pkg.version));
135
+ }).pipe(Effect.provide(RegistryLayer), Effect.catch(() => Effect.succeed([...packages]))),
136
+ loadPackages: (packages) => packages.length === 0 ? Effect.succeed({ vfs: /* @__PURE__ */ new Map() }) : Effect.gen(function* () {
134
137
  const specs = packages.map((pkg) => new PackageSpec({
135
138
  name: pkg.name,
136
139
  version: pkg.version
137
140
  }));
138
- return { vfs: yield* TypeRegistry.getVFS(specs, { autoFetch: true }).pipe(Effect.catchAll((error) => Effect.fail(new TypeRegistryError({
139
- packageName: packages.map((p) => p.name).join(", "),
140
- version: packages.map((p) => p.version).join(", "),
141
- reason: error.message ?? String(error)
142
- })))) };
143
- }).pipe(Effect.provide(RegistryLayer))
141
+ return { vfs: yield* (yield* TypeRegistry).getVfs(specs, { autoFetch: true }) };
142
+ }).pipe(Effect.provide(RegistryLayer), Effect.catch((error) => Effect.fail(new TypeRegistryError({
143
+ packageName: packages.map((p) => p.name).join(", "),
144
+ version: packages.map((p) => p.version).join(", "),
145
+ reason: error instanceof Error ? error.message ?? String(error) : String(error)
146
+ }))))
144
147
  });
145
148
 
146
149
  //#endregion
@@ -1,4 +1,4 @@
1
- import { Metric, MetricBoundaries } from "effect";
1
+ import { Metric } from "effect";
2
2
 
3
3
  //#region src/layers/build-metrics.ts
4
4
  /**
@@ -17,7 +17,7 @@ const BuildMetrics = {
17
17
  filesNew: Metric.counter("files.new"),
18
18
  filesModified: Metric.counter("files.modified"),
19
19
  filesUnchanged: Metric.counter("files.unchanged"),
20
- codeblockDuration: Metric.histogram("codeblock.duration", MetricBoundaries.fromIterable([
20
+ codeblockDuration: Metric.histogram("codeblock.duration", { boundaries: [
21
21
  10,
22
22
  25,
23
23
  50,
@@ -25,15 +25,15 @@ const BuildMetrics = {
25
25
  200,
26
26
  500,
27
27
  1e3
28
- ])),
29
- codeblockShikiDuration: Metric.histogram("codeblock.shiki.duration", MetricBoundaries.fromIterable([
28
+ ] }),
29
+ codeblockShikiDuration: Metric.histogram("codeblock.shiki.duration", { boundaries: [
30
30
  5,
31
31
  10,
32
32
  25,
33
33
  50,
34
34
  100,
35
35
  250
36
- ])),
36
+ ] }),
37
37
  codeblockTotal: Metric.counter("codeblock.total"),
38
38
  codeblockSlow: Metric.counter("codeblock.slow"),
39
39
  twoslashErrors: Metric.counter("twoslash.errors"),
@@ -41,7 +41,7 @@ const BuildMetrics = {
41
41
  pagesGenerated: Metric.counter("pages.generated"),
42
42
  apiVersionsLoaded: Metric.counter("api.versions.loaded"),
43
43
  externalPackagesTotal: Metric.counter("external.packages.total"),
44
- phaseDuration: Metric.histogram("phase.duration", MetricBoundaries.fromIterable([
44
+ phaseDuration: Metric.histogram("phase.duration", { boundaries: [
45
45
  50,
46
46
  100,
47
47
  250,
@@ -50,7 +50,7 @@ const BuildMetrics = {
50
50
  2500,
51
51
  5e3,
52
52
  1e4
53
- ])),
53
+ ] }),
54
54
  vfsFiles: Metric.counter("vfs.files"),
55
55
  importsPrepended: Metric.counter("imports.prepended"),
56
56
  twoslashDiagnostics: Metric.counter("twoslash.diagnostics"),
package/llms-program.js CHANGED
@@ -2,15 +2,14 @@ import { PluginEvent } from "./observability/events.js";
2
2
  import { emit } from "./observability/EventBus.js";
3
3
  import { filterLlmsFullTxt, filterLlmsTxt, generatePackageLlmsFullTxt, generatePackageLlmsTxt, generateStructuredLlmsTxt, parseLlmsTxtLine } from "./llms-processing.js";
4
4
  import path from "node:path";
5
- import { Effect } from "effect";
6
- import { FileSystem } from "@effect/platform";
5
+ import { Effect, FileSystem } from "effect";
7
6
 
8
7
  //#region src/llms-program.ts
9
8
  /**
10
9
  * Effect program for post-processing LLMs text files in afterBuild.
11
10
  *
12
11
  * Wires the pure processing functions from llms-processing.ts into the
13
- * plugin lifecycle, handling file I/O via \@effect/platform FileSystem.
12
+ * plugin lifecycle, handling file I/O via the core `effect` FileSystem service.
14
13
  *
15
14
  * Responsibilities:
16
15
  * 1. Collect all API routes from build results
@@ -170,7 +169,7 @@ function collectApiPageContent(globalLlmsFullContent, result) {
170
169
  * 3. For each prefix, post-processes global llms.txt and llms-full.txt
171
170
  * 4. When scopes is enabled, generates per-package LLMs files
172
171
  *
173
- * Requires FileSystem from \@effect/platform.
172
+ * Requires the core `effect` FileSystem service.
174
173
  */
175
174
  function processLlmsFiles(input) {
176
175
  return Effect.gen(function* () {
@@ -1,5 +1,5 @@
1
1
  import { Effect } from "effect";
2
- import * as SqlClient from "@effect/sql/SqlClient";
2
+ import { SqlClient } from "effect/unstable/sql";
3
3
 
4
4
  //#region src/migrations/001_create_snapshots.ts
5
5
  const migration = Effect.gen(function* () {
@@ -2,7 +2,7 @@ import { LEVEL_RANK, levelOf } from "./events.js";
2
2
  import { Context, Effect, Layer, Option } from "effect";
3
3
 
4
4
  //#region src/observability/EventBus.ts
5
- var EventBus = class extends Context.Tag("rspress-plugin-api-extractor/EventBus")() {};
5
+ var EventBus = class extends Context.Service()("rspress-plugin-api-extractor/EventBus") {};
6
6
  function makeShape(sinks) {
7
7
  const maxAdmitted = sinks.filter((s) => s.capturesPayload === true).reduce((max, s) => Math.max(max, LEVEL_RANK[s.minLevel]), -1);
8
8
  return {
@@ -25,38 +25,38 @@ function makeMetricsSink() {
25
25
  handle(event) {
26
26
  switch (event._tag) {
27
27
  case "FileDecision":
28
- Effect.runSync(Metric.increment(BuildMetrics.filesTotal));
29
- if (event.status === "new") Effect.runSync(Metric.increment(BuildMetrics.filesNew));
30
- else if (event.status === "modified") Effect.runSync(Metric.increment(BuildMetrics.filesModified));
31
- else Effect.runSync(Metric.increment(BuildMetrics.filesUnchanged));
28
+ Effect.runSync(Metric.update(BuildMetrics.filesTotal, 1));
29
+ if (event.status === "new") Effect.runSync(Metric.update(BuildMetrics.filesNew, 1));
30
+ else if (event.status === "modified") Effect.runSync(Metric.update(BuildMetrics.filesModified, 1));
31
+ else Effect.runSync(Metric.update(BuildMetrics.filesUnchanged, 1));
32
32
  break;
33
33
  case "PageGenerated":
34
- Effect.runSync(Metric.increment(BuildMetrics.pagesGenerated));
34
+ Effect.runSync(Metric.update(BuildMetrics.pagesGenerated, 1));
35
35
  break;
36
36
  case "TwoslashDiagnostic":
37
- Effect.runSync(Metric.increment(BuildMetrics.twoslashDiagnostics));
38
- Effect.runSync(Metric.increment(BuildMetrics.twoslashErrors));
37
+ Effect.runSync(Metric.update(BuildMetrics.twoslashDiagnostics, 1));
38
+ Effect.runSync(Metric.update(BuildMetrics.twoslashErrors, 1));
39
39
  break;
40
40
  case "PrettierError":
41
- Effect.runSync(Metric.increment(BuildMetrics.prettierErrors));
41
+ Effect.runSync(Metric.update(BuildMetrics.prettierErrors, 1));
42
42
  break;
43
43
  case "CodeBlockProcessed":
44
- Effect.runSync(Metric.increment(BuildMetrics.codeblockTotal));
44
+ Effect.runSync(Metric.update(BuildMetrics.codeblockTotal, 1));
45
45
  Effect.runSync(Metric.update(BuildMetrics.codeblockDuration, event.totalMs));
46
46
  if (event.shikiMs > 0) Effect.runSync(Metric.update(BuildMetrics.codeblockShikiDuration, event.shikiMs));
47
- if (event.slow) Effect.runSync(Metric.increment(BuildMetrics.codeblockSlow));
47
+ if (event.slow) Effect.runSync(Metric.update(BuildMetrics.codeblockSlow, 1));
48
48
  break;
49
49
  case "VfsGenerated":
50
- Effect.runSync(Metric.increment(BuildMetrics.vfsFiles));
50
+ Effect.runSync(Metric.update(BuildMetrics.vfsFiles, 1));
51
51
  break;
52
52
  case "ImportsPrepended":
53
- Effect.runSync(Metric.increment(BuildMetrics.importsPrepended));
53
+ Effect.runSync(Metric.update(BuildMetrics.importsPrepended, 1));
54
54
  break;
55
55
  case "PhaseCompleted":
56
56
  Effect.runSync(Metric.update(BuildMetrics.phaseDuration, event.durationMs));
57
57
  break;
58
58
  case "DefaultApplied":
59
- Effect.runSync(Metric.increment(BuildMetrics.configDefaultsApplied));
59
+ Effect.runSync(Metric.update(BuildMetrics.configDefaultsApplied, 1));
60
60
  break;
61
61
  default: break;
62
62
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rspress-plugin-api-extractor",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "private": false,
5
5
  "description": "RSPress plugin for generating API documentation from TypeScript API Extractor models",
6
6
  "keywords": [
@@ -14,7 +14,7 @@
14
14
  "repository": {
15
15
  "type": "git",
16
16
  "url": "git+https://github.com/spencerbeggs/rspress-plugin-api-extractor.git",
17
- "directory": "plugin"
17
+ "directory": "package"
18
18
  },
19
19
  "license": "MIT",
20
20
  "author": "Spencer Beggs",
@@ -22,40 +22,41 @@
22
22
  "exports": {
23
23
  ".": {
24
24
  "types": "./index.d.ts",
25
- "import": "./index.js"
25
+ "import": "./index.js",
26
+ "default": "./index.js"
26
27
  },
27
28
  "./runtime": {
28
29
  "types": "./runtime/index.d.ts",
29
- "import": "./runtime/index.js"
30
+ "import": "./runtime/index.js",
31
+ "default": "./runtime/index.js"
30
32
  },
31
33
  "./tsconfig/rspress.json": "./tsconfig/rspress.json",
32
34
  "./package.json": "./package.json"
33
35
  },
34
36
  "dependencies": {
35
- "@effect/cluster": "^0.59.0",
36
- "@effect/experimental": "^0.60.0",
37
- "@effect/platform": "^0.96.2",
38
- "@effect/platform-node": "^0.107.0",
39
- "@effect/rpc": "^0.75.1",
40
- "@effect/sql": "^0.51.1",
41
- "@effect/sql-sqlite-node": "^0.52.0",
42
- "@effect/workflow": "^0.18.2",
37
+ "@effect/platform-node": "4.0.0-beta.98",
38
+ "@effect/sql-sqlite-node": "4.0.0-beta.98",
39
+ "@effected/semver": "^0.1.0",
40
+ "@effected/store": "^0.1.0",
41
+ "@effected/tsconfig-json": "^0.2.3",
42
+ "@effected/xdg": "^0.1.3",
43
43
  "@microsoft/api-extractor-model": "^7.33.8",
44
44
  "@shikijs/twoslash": "^4.3.1",
45
+ "@typescript/vfs": "^1.6.4",
45
46
  "api-extractor-llms": "^0.2.0",
46
47
  "clsx": "^2.1.1",
47
- "effect": "^3.21.4",
48
+ "effect": "4.0.0-beta.98",
48
49
  "gray-matter": "^4.0.3",
49
50
  "hast-util-to-jsx-runtime": "^2.3.6",
50
51
  "image-size": "^2.0.2",
52
+ "ioredis": "^5.7.0",
51
53
  "mdast-util-from-markdown": "^2.0.3",
52
54
  "mdast-util-to-hast": "^13.2.1",
53
55
  "open": "^11.0.0",
54
56
  "prettier": "^3.9.5",
55
57
  "react-markdown": "^10.1.0",
56
- "semver-effect": "^0.3.1",
57
58
  "shiki": "^4.3.1",
58
- "type-registry-effect": "^1.1.0",
59
+ "type-registry-effect": "^2.0.0",
59
60
  "typescript": "^6.0.3",
60
61
  "unist-util-visit": "^5.1.0"
61
62
  },