Просмотр исходного кода

test(opencode): simplify config effect tests (#29019)

Kit Langton 2 месяцев назад
Родитель
Сommit
0b3a1c2fdf

+ 6 - 1
packages/opencode/src/effect/service-use.ts → packages/core/src/effect/service-use.ts

@@ -15,6 +15,7 @@ type ServiceUse<Identifier, Shape> = {
 }
 
 export const serviceUse = <Identifier, Shape>(tag: Context.Service<Identifier, Shape>) => {
+  const cache = new Map<string, (...args: unknown[]) => Effect.Effect<unknown, unknown, unknown>>()
   // This is the only dynamic boundary: TypeScript knows the accessor shape,
   // but Proxy property names are runtime values.
   const access = new Proxy(
@@ -22,7 +23,9 @@ export const serviceUse = <Identifier, Shape>(tag: Context.Service<Identifier, S
     {
       get: (_, key) => {
         if (typeof key !== "string") return undefined
-        return (...args: unknown[]) =>
+        const cached = cache.get(key)
+        if (cached) return cached
+        const accessor = (...args: unknown[]) =>
           tag.use((service) => {
             // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- Proxy keys are checked at runtime.
             const method = service[key as keyof Shape]
@@ -30,6 +33,8 @@ export const serviceUse = <Identifier, Shape>(tag: Context.Service<Identifier, S
             // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- ServiceUse exposes only Effect-returning methods.
             return (method as (...args: unknown[]) => Effect.Effect<unknown, unknown, unknown>)(...args)
           })
+        cache.set(key, accessor)
+        return accessor
       },
     },
   )

+ 4 - 1
packages/core/src/filesystem.ts

@@ -3,9 +3,10 @@ import { dirname, join, relative, resolve as pathResolve } from "path"
 import { realpathSync } from "fs"
 import * as NFS from "fs/promises"
 import { lookup } from "mime-types"
-import { Effect, FileSystem, Layer, Schema, Context } from "effect"
+import { Context, Effect, FileSystem, Layer, Schema } from "effect"
 import type { PlatformError } from "effect/PlatformError"
 import { Glob } from "./util/glob"
+import { serviceUse } from "./effect/service-use"
 
 export namespace AppFileSystem {
   export class FileSystemError extends Schema.TaggedErrorClass<FileSystemError>()("FileSystemError", {
@@ -39,6 +40,8 @@ export namespace AppFileSystem {
 
   export class Service extends Context.Service<Service, Interface>()("@opencode/FileSystem") {}
 
+  export const use = serviceUse(Service)
+
   export const layer = Layer.effect(
     Service,
     Effect.gen(function* () {

+ 1 - 1
packages/opencode/src/account/account.ts

@@ -1,5 +1,5 @@
 import { Cache, Clock, Duration, Effect, Layer, Option, Schema, SchemaGetter, Context } from "effect"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import {
   FetchHttpClient,
   HttpClient,

+ 1 - 1
packages/opencode/src/account/repo.ts

@@ -1,5 +1,5 @@
 import { eq } from "drizzle-orm"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import { Effect, Layer, Option, Schema, Context } from "effect"
 
 import { Database } from "@/storage/db"

+ 1 - 1
packages/opencode/src/agent/agent.ts

@@ -1,5 +1,5 @@
 import { Config } from "@/config/config"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import { Provider } from "@/provider/provider"
 import { ModelID, ProviderID } from "../provider/schema"
 import { generateObject, streamObject, type ModelMessage } from "ai"

+ 1 - 1
packages/opencode/src/bus/index.ts

@@ -5,7 +5,7 @@ import { BusEvent } from "./bus-event"
 import { GlobalBus } from "./global"
 import { InstanceState } from "@/effect/instance-state"
 import { makeRuntime } from "@/effect/run-service"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import { Identifier } from "@/id/id"
 import type { InstanceContext } from "@/project/instance-context"
 import { InstanceRef } from "@/effect/instance-ref"

+ 1 - 1
packages/opencode/src/config/config.ts

@@ -1,5 +1,5 @@
 import * as Log from "@opencode-ai/core/util/log"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import path from "path"
 import { pathToFileURL } from "url"
 import os from "os"

+ 1 - 1
packages/opencode/src/control-plane/workspace.ts

@@ -1,5 +1,5 @@
 import { Context, Effect, FiberMap, Iterable, Layer, Schema, Stream } from "effect"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import { FetchHttpClient, HttpBody, HttpClient, HttpClientError, HttpClientRequest } from "effect/unstable/http"
 import { Database } from "@/storage/db"
 import { asc } from "drizzle-orm"

+ 1 - 1
packages/opencode/src/env/index.ts

@@ -1,5 +1,5 @@
 import { Context, Effect, Layer } from "effect"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import { InstanceState } from "@/effect/instance-state"
 
 type State = Record<string, string | undefined>

+ 1 - 1
packages/opencode/src/file/index.ts

@@ -1,5 +1,5 @@
 import { BusEvent } from "@/bus/bus-event"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import { InstanceState } from "@/effect/instance-state"
 
 import { AppFileSystem } from "@opencode-ai/core/filesystem"

+ 1 - 1
packages/opencode/src/file/ripgrep.ts

@@ -1,5 +1,5 @@
 import path from "path"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import { AppFileSystem } from "@opencode-ai/core/filesystem"
 import { Cause, Context, Effect, Fiber, Layer, Queue, Schema, Stream } from "effect"
 import type { PlatformError } from "effect/PlatformError"

+ 1 - 1
packages/opencode/src/format/index.ts

@@ -1,5 +1,5 @@
 import { Effect, Layer, Context, Schema } from "effect"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import { ChildProcess } from "effect/unstable/process"
 import { AppProcess } from "@opencode-ai/core/process"
 import { InstanceState } from "@/effect/instance-state"

+ 1 - 1
packages/opencode/src/installation/index.ts

@@ -1,5 +1,5 @@
 import { Effect, Layer, Schema, Context, Stream } from "effect"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import { FetchHttpClient, HttpClient, HttpClientRequest, HttpClientResponse } from "effect/unstable/http"
 import { withTransientReadRetry } from "@/util/effect-http-client"
 import { errorMessage } from "@/util/error"

+ 1 - 1
packages/opencode/src/mcp/auth.ts

@@ -1,5 +1,5 @@
 import path from "path"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import { Global } from "@opencode-ai/core/global"
 import { Effect, Layer, Context, Option, Schema } from "effect"
 import { AppFileSystem } from "@opencode-ai/core/filesystem"

+ 1 - 1
packages/opencode/src/mcp/index.ts

@@ -1,5 +1,5 @@
 import { dynamicTool, type Tool, jsonSchema, type JSONSchema7 } from "ai"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import { Client } from "@modelcontextprotocol/sdk/client/index.js"
 import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"
 import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js"

+ 1 - 1
packages/opencode/src/project/instance-store.ts

@@ -1,5 +1,5 @@
 import { GlobalBus } from "@/bus/global"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import { WorkspaceContext } from "@/control-plane/workspace-context"
 import { InstanceRef } from "@/effect/instance-ref"
 import { disposeInstance as runDisposers } from "@/effect/instance-registry"

+ 1 - 1
packages/opencode/src/project/project.ts

@@ -20,7 +20,7 @@ import { AppProcess } from "@opencode-ai/core/process"
 import { Project as ProjectV2 } from "@opencode-ai/core/project"
 import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
 import { AbsolutePath, NonNegativeInt, optionalOmitUndefined } from "@opencode-ai/core/schema"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import { RuntimeFlags } from "@/effect/runtime-flags"
 
 const log = Log.create({ service: "project" })

+ 1 - 1
packages/opencode/src/provider/auth.ts

@@ -1,5 +1,5 @@
 import type { AuthOAuthResult, Hooks } from "@opencode-ai/plugin"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import { Auth } from "@/auth"
 import { InstanceState } from "@/effect/instance-state"
 import { optionalOmitUndefined } from "@opencode-ai/core/schema"

+ 1 - 1
packages/opencode/src/provider/provider.ts

@@ -7,7 +7,7 @@ import * as Log from "@opencode-ai/core/util/log"
 import { Npm } from "@opencode-ai/core/npm"
 import { Hash } from "@opencode-ai/core/util/hash"
 import { Plugin } from "../plugin"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import { type LanguageModelV3 } from "@ai-sdk/provider"
 import * as ModelsDev from "@opencode-ai/core/models-dev"
 import { Auth } from "../auth"

+ 1 - 1
packages/opencode/src/session/compaction.ts

@@ -16,7 +16,7 @@ import { Effect, Layer, Context, Schema } from "effect"
 import * as DateTime from "effect/DateTime"
 import { InstanceState } from "@/effect/instance-state"
 import { isOverflow as overflow, usable } from "./overflow"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import { RuntimeFlags } from "@/effect/runtime-flags"
 import { EventV2Bridge } from "@/event-v2-bridge"
 import { SessionEvent } from "@opencode-ai/core/session-event"

+ 1 - 1
packages/opencode/src/session/llm.ts

@@ -1,5 +1,5 @@
 import { Provider } from "@/provider/provider"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import * as Log from "@opencode-ai/core/util/log"
 import { Context, Effect, Layer } from "effect"
 import * as Stream from "effect/Stream"

+ 1 - 1
packages/opencode/src/session/session.ts

@@ -1,5 +1,5 @@
 import { Slug } from "@opencode-ai/core/util/slug"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import path from "path"
 import { BackgroundJob } from "@/background/job"
 import { BusEvent } from "@/bus/bus-event"

+ 1 - 1
packages/opencode/src/share/share-next.ts

@@ -1,5 +1,5 @@
 import type * as SDK from "@opencode-ai/sdk/v2"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import { Effect, Exit, Layer, Option, Schema, Scope, Context, Stream } from "effect"
 import { FetchHttpClient, HttpClient, HttpClientRequest, HttpClientResponse } from "effect/unstable/http"
 import { Account } from "@/account/account"

+ 1 - 1
packages/opencode/src/sync/index.ts

@@ -12,7 +12,7 @@ import { EventID } from "./schema"
 import { Context, Effect, Layer, Schema as EffectSchema } from "effect"
 import type { DeepMutable } from "@opencode-ai/core/schema"
 import { EventV2 } from "@opencode-ai/core/event"
-import { serviceUse } from "@/effect/service-use"
+import { serviceUse } from "@opencode-ai/core/effect/service-use"
 import { InstanceState } from "@/effect/instance-state"
 import { RuntimeFlags } from "@/effect/runtime-flags"
 import { EffectBridge } from "@/effect/bridge"

Разница между файлами не показана из-за своего большого размера
+ 295 - 468
packages/opencode/test/config/config.test.ts


Некоторые файлы не были показаны из-за большого количества измененных файлов