diff options
| author | Dax <[email protected]> | 2026-04-16 02:03:03 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-04-16 02:03:03 -0400 |
| commit | 675a46e23e679c294355435584ae662a7c0903c7 (patch) | |
| tree | fb5162a7e3565f153db26055a0857d4ac3d6448f /packages/shared/src | |
| parent | 150ab07a833f0b10f4af17b3dd713cfedb16a6ff (diff) | |
| download | opencode-675a46e23e679c294355435584ae662a7c0903c7.tar.gz opencode-675a46e23e679c294355435584ae662a7c0903c7.zip | |
CLI perf: reduce deps (#22652)
Diffstat (limited to 'packages/shared/src')
| -rw-r--r-- | packages/shared/src/npm.ts | 25 | ||||
| -rw-r--r-- | packages/shared/src/util/error.ts | 6 | ||||
| -rw-r--r-- | packages/shared/src/util/flock.ts | 10 |
3 files changed, 33 insertions, 8 deletions
diff --git a/packages/shared/src/npm.ts b/packages/shared/src/npm.ts index 8bd0cc468..955cafa19 100644 --- a/packages/shared/src/npm.ts +++ b/packages/shared/src/npm.ts @@ -1,6 +1,5 @@ import path from "path" import semver from "semver" -import { Arborist } from "@npmcli/arborist" import { Effect, Schema, Context, Layer, Option, FileSystem } from "effect" import { NodeFileSystem } from "@effect/platform-node" import { AppFileSystem } from "./filesystem" @@ -19,8 +18,8 @@ export namespace Npm { } export interface Interface { - readonly add: (pkg: string) => Effect.Effect<EntryPoint, InstallFailedError> - readonly install: (dir: string) => Effect.Effect<void> + readonly add: (pkg: string) => Effect.Effect<EntryPoint, InstallFailedError | EffectFlock.LockError> + readonly install: (dir: string, input?: { add: string[] }) => Effect.Effect<void, EffectFlock.LockError> readonly outdated: (pkg: string, cachedVersion: string) => Effect.Effect<boolean> readonly which: (pkg: string) => Effect.Effect<Option.Option<string>> } @@ -92,6 +91,7 @@ export namespace Npm { }) const add = Effect.fn("Npm.add")(function* (pkg: string) { + const { Arborist } = yield* Effect.promise(() => import("@npmcli/arborist")) const dir = directory(pkg) yield* flock.acquire(`npm-install:${dir}`) @@ -133,10 +133,17 @@ export namespace Npm { return resolveEntryPoint(first.name, first.path) }, Effect.scoped) - const install = Effect.fn("Npm.install")(function* (dir: string) { + const install = Effect.fn("Npm.install")(function* (dir: string, input?: { add: string[] }) { + const canWrite = yield* afs.access(dir, { writable: true }).pipe( + Effect.as(true), + Effect.orElseSucceed(() => false), + ) + if (!canWrite) return + yield* flock.acquire(`npm-install:${dir}`) const reify = Effect.fnUntraced(function* () { + const { Arborist } = yield* Effect.promise(() => import("@npmcli/arborist")) const arb = new Arborist({ path: dir, binLinks: true, @@ -145,7 +152,14 @@ export namespace Npm { ignoreScripts: true, }) yield* Effect.tryPromise({ - try: () => arb.reify().catch(() => {}), + try: () => + arb + .reify({ + add: input?.add || [], + save: true, + saveType: "prod", + }) + .catch(() => {}), catch: () => {}, }).pipe(Effect.orElseSucceed(() => {})) }) @@ -167,6 +181,7 @@ export namespace Npm { ...Object.keys(pkgAny?.devDependencies || {}), ...Object.keys(pkgAny?.peerDependencies || {}), ...Object.keys(pkgAny?.optionalDependencies || {}), + ...(input?.add || []), ]) const root = lockAny?.packages?.[""] || {} diff --git a/packages/shared/src/util/error.ts b/packages/shared/src/util/error.ts index 12c27a0a7..9d3b7c661 100644 --- a/packages/shared/src/util/error.ts +++ b/packages/shared/src/util/error.ts @@ -4,6 +4,12 @@ export abstract class NamedError extends Error { abstract schema(): z.core.$ZodType abstract toObject(): { name: string; data: any } + static hasName(error: unknown, name: string): boolean { + return ( + typeof error === "object" && error !== null && "name" in error && (error as Record<string, unknown>).name === name + ) + } + static create<Name extends string, Data extends z.core.$ZodType>(name: Name, data: Data) { const schema = z .object({ diff --git a/packages/shared/src/util/flock.ts b/packages/shared/src/util/flock.ts index 4a1df1dee..958bd9fd1 100644 --- a/packages/shared/src/util/flock.ts +++ b/packages/shared/src/util/flock.ts @@ -345,10 +345,14 @@ export namespace Flock { return await fn() } - export const effect = Effect.fn("Flock.effect")(function* (key: string) { + export const effect = Effect.fn("Flock.effect")(function* (key: string, input: Options = {}) { return yield* Effect.acquireRelease( - Effect.promise((signal) => Flock.acquire(key, { signal })), - (foo) => Effect.promise(() => foo.release()), + Effect.promise((signal) => Flock.acquire(key, { ...input, signal })).pipe( + Effect.withSpan("Flock.acquire", { + attributes: { key }, + }), + ), + (lock) => Effect.promise(() => lock.release()).pipe(Effect.withSpan("Flock.release")), ).pipe(Effect.asVoid) }) } |
