diff --git a/.yarn/patches/@effect-vitest-npm-0.29.0-1c8cf3c306.patch b/.yarn/patches/@effect-vitest-npm-0.29.0-1c8cf3c306.patch deleted file mode 100644 index 377271df330..00000000000 --- a/.yarn/patches/@effect-vitest-npm-0.29.0-1c8cf3c306.patch +++ /dev/null @@ -1,58 +0,0 @@ -diff --git a/dist/cjs/internal/internal.js b/dist/cjs/internal/internal.js -index dee6eec6cd0646708773eb9e89d4e835858b3f5c..b9ce97e9b481980ff5a9092bf09c8d3179fed495 100644 ---- a/dist/cjs/internal/internal.js -+++ b/dist/cjs/internal/internal.js -@@ -28,7 +28,9 @@ const defaultApi = /*#__PURE__*/Object.assign(V.it, { - }); - const runPromise = ctx => effect => Effect.gen(function* () { - const exitFiber = yield* Effect.fork(Effect.exit(effect)); -- ctx?.onTestFinished(() => Fiber.interrupt(exitFiber).pipe(Effect.asVoid, Effect.runPromise)); -+ // Vitest 4 moved onTestFinished off the test context. Keep Effect 3's -+ // stable @effect/vitest usable until https://github.com/Effect-TS/effect/pull/5980 is released. -+ V.onTestFinished(() => Fiber.interrupt(exitFiber).pipe(Effect.asVoid, Effect.runPromise)); - const exit = yield* Fiber.join(exitFiber); - if (Exit.isSuccess(exit)) { - return () => exit.value; -diff --git a/dist/esm/internal/internal.js b/dist/esm/internal/internal.js -index adb6b213294cbbc1559f7a283b4a84df41d8342e..a04cef4d46c499aac08518abf0a99759ce800039 100644 ---- a/dist/esm/internal/internal.js -+++ b/dist/esm/internal/internal.js -@@ -21,7 +21,9 @@ const defaultApi = /*#__PURE__*/Object.assign(V.it, { - }); - const runPromise = ctx => effect => Effect.gen(function* () { - const exitFiber = yield* Effect.fork(Effect.exit(effect)); -- ctx?.onTestFinished(() => Fiber.interrupt(exitFiber).pipe(Effect.asVoid, Effect.runPromise)); -+ // Vitest 4 moved onTestFinished off the test context. Keep Effect 3's -+ // stable @effect/vitest usable until https://github.com/Effect-TS/effect/pull/5980 is released. -+ V.onTestFinished(() => Fiber.interrupt(exitFiber).pipe(Effect.asVoid, Effect.runPromise)); - const exit = yield* Fiber.join(exitFiber); - if (Exit.isSuccess(exit)) { - return () => exit.value; -diff --git a/package.json b/package.json -index 1ceac68f8e5cfed5d014c4066414c4f8eec67a69..3c5cac8abdae6087e927fab2669b736c4a0be5c4 100644 ---- a/package.json -+++ b/package.json -@@ -11,7 +11,7 @@ - "sideEffects": [], - "homepage": "https://effect.website", - "peerDependencies": { -- "vitest": "^3.2.0", -+ "vitest": "^3.2.0 || ^4.0.0", - "effect": "^3.21.0" - }, - "publishConfig": { -diff --git a/src/internal/internal.ts b/src/internal/internal.ts -index bd11019b8ad51bd49cc3015f8c69aac04ad18822..1d8a04e1ae3d195d75553fb3944efdd9720f64ca 100644 ---- a/src/internal/internal.ts -+++ b/src/internal/internal.ts -@@ -29,7 +29,9 @@ const runPromise = (ctx?: Vitest.TestContext) => (effect: Effect.Effect -+ // Vitest 4 moved onTestFinished off the test context. Keep Effect 3's -+ // stable @effect/vitest usable until https://github.com/Effect-TS/effect/pull/5980 is released. -+ V.onTestFinished(() => - Fiber.interrupt(exitFiber).pipe( - Effect.asVoid, - Effect.runPromise diff --git a/.yarnrc.yml b/.yarnrc.yml index e949e6ea854..9b7395c34a9 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -39,8 +39,11 @@ catalog: tsx: "4.20.6" typescript: "7.0.2" "@typescript/typescript6": "6.0.2" - vite: "8.3.4" - vitest: "4.1.11" + rolldown: "1.2.15" + vite: "8.3.5" + vitest: "5.0.5" + "@vitest/coverage-istanbul": "5.0.5" + "@fast-check/vitest": "0.5.0" "@tsconfig/bases": "1.0.28" "@types/node": "22.18.13" diff --git a/apps/brunch-agent/src/agents/petrinaut/petrinaut-agent-mounting.test.ts b/apps/brunch-agent/src/agents/petrinaut/petrinaut-agent-mounting.test.ts index f4ce7e2d6e7..2c565f3bb59 100644 --- a/apps/brunch-agent/src/agents/petrinaut/petrinaut-agent-mounting.test.ts +++ b/apps/brunch-agent/src/agents/petrinaut/petrinaut-agent-mounting.test.ts @@ -76,7 +76,6 @@ const systemPrompt = async () => ).trim(); beforeEach(() => { vi.resetModules(); - vi.clearAllMocks(); vi.stubEnv("BRUNCH_CHAT_MODEL", "claude-sonnet-4-6"); vi.stubEnv("NODE_ENV", "test"); mounted.initialData = undefined; diff --git a/apps/brunch-agent/src/provider-registration.test.ts b/apps/brunch-agent/src/provider-registration.test.ts index dfeb276ef95..731c55f5551 100644 --- a/apps/brunch-agent/src/provider-registration.test.ts +++ b/apps/brunch-agent/src/provider-registration.test.ts @@ -10,6 +10,8 @@ import { instrument, setProvider } from "@flue/runtime"; import { Hono } from "hono"; import { beforeAll, expect, test, vi } from "vitest"; +vi.setConfig({ clearMocks: false }); + vi.mock("./server/telemetry-bootstrap.ts", () => ({})); vi.mock("./agents/petrinaut/agent.ts", () => ({ PetrinautAgent: { agentName: "brunch-chat-agent" }, diff --git a/apps/hash-ai-worker-ts/package.json b/apps/hash-ai-worker-ts/package.json index 0a982218caa..3d6e131a4e0 100644 --- a/apps/hash-ai-worker-ts/package.json +++ b/apps/hash-ai-worker-ts/package.json @@ -112,7 +112,7 @@ "@types/node": "catalog:", "@types/papaparse": "5.3.16", "@types/sanitize-html": "2.16.0", - "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-istanbul": "catalog:", "eslint": "9.39.4", "rimraf": "6.1.3", "ts-json-schema-generator": "1.5.1", diff --git a/apps/hash-api/package.json b/apps/hash-api/package.json index abe5af1e459..531c505b5c8 100644 --- a/apps/hash-api/package.json +++ b/apps/hash-api/package.json @@ -76,7 +76,7 @@ "axios": "1.20.0", "cors": "2.8.5", "dedent": "1.7.0", - "effect": "3.21.0", + "effect": "4.0.3", "exponential-backoff": "3.1.3", "express": "5.2.0", "express-handlebars": "8.0.4", @@ -125,10 +125,11 @@ "@types/mime-types": "2.1.4", "@types/node": "catalog:", "@types/sanitize-html": "2.16.0", - "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-istanbul": "catalog:", "eslint": "9.39.4", "rimraf": "6.1.3", "typescript": "catalog:", + "vite": "catalog:", "vitest": "catalog:", "wait-on": "9.0.1" } diff --git a/apps/hash-api/src/graph/knowledge/primitive/entity/after-create-entity-hooks/opportunity-status-update-after-create-entity-hook.test.ts b/apps/hash-api/src/graph/knowledge/primitive/entity/after-create-entity-hooks/opportunity-status-update-after-create-entity-hook.test.ts index b67dbafccd8..a0cdc75d000 100644 --- a/apps/hash-api/src/graph/knowledge/primitive/entity/after-create-entity-hooks/opportunity-status-update-after-create-entity-hook.test.ts +++ b/apps/hash-api/src/graph/knowledge/primitive/entity/after-create-entity-hooks/opportunity-status-update-after-create-entity-hook.test.ts @@ -51,7 +51,6 @@ const user = (accountId: string) => describe("opportunity status update after-create hook", () => { beforeEach(() => { - vi.clearAllMocks(); mocks.deliverMentionNotifications.mockResolvedValue(undefined); mocks.deliverStatusParticipationNotifications.mockResolvedValue(undefined); mocks.getMentionedUsersInTextualContent.mockResolvedValue([ diff --git a/apps/hash-api/src/graph/knowledge/primitive/entity/shared/mention-delivery.test.ts b/apps/hash-api/src/graph/knowledge/primitive/entity/shared/mention-delivery.test.ts index 9d67d3816e6..7369e8b6636 100644 --- a/apps/hash-api/src/graph/knowledge/primitive/entity/shared/mention-delivery.test.ts +++ b/apps/hash-api/src/graph/knowledge/primitive/entity/shared/mention-delivery.test.ts @@ -89,7 +89,6 @@ const textualContent: TextToken[] = [ describe("deliverMentionNotifications", () => { beforeEach(() => { - vi.clearAllMocks(); mocks.checkPermissionsOnEntity.mockResolvedValue({ view: true }); mocks.getMentionNotification.mockResolvedValue(null); mocks.getWebShortname.mockResolvedValue("workspace"); diff --git a/apps/hash-api/src/graph/knowledge/system-types/notification.test.ts b/apps/hash-api/src/graph/knowledge/system-types/notification.test.ts index 82cf3abbee6..27daa8f0c22 100644 --- a/apps/hash-api/src/graph/knowledge/system-types/notification.test.ts +++ b/apps/hash-api/src/graph/knowledge/system-types/notification.test.ts @@ -47,7 +47,6 @@ const notificationEntity = { describe("notification helpers", () => { beforeEach(() => { - vi.clearAllMocks(); mocks.getWebMachineId.mockResolvedValue( "00000000-0000-0000-0000-000000000005", ); diff --git a/apps/hash-api/src/graphql/resolvers/flows/flow-definition.test.ts b/apps/hash-api/src/graphql/resolvers/flows/flow-definition.test.ts index 98a05f66f11..c9b3213f97a 100644 --- a/apps/hash-api/src/graphql/resolvers/flows/flow-definition.test.ts +++ b/apps/hash-api/src/graphql/resolvers/flows/flow-definition.test.ts @@ -117,7 +117,6 @@ const update = (definition: unknown, expectedEditionId = "edition-1") => ); beforeEach(() => { - vi.clearAllMocks(); mocks.getFlowDefinitionEntityById.mockResolvedValue(savedEntity("edition-1")); mocks.getActiveFlowSchedulesOfFlowDefinition.mockResolvedValue([]); mocks.updateFlowDefinition.mockResolvedValue(savedEntity("edition-2")); diff --git a/apps/hash-api/src/graphql/resolvers/flows/flow-schedule.test.ts b/apps/hash-api/src/graphql/resolvers/flows/flow-schedule.test.ts index 01b416b9f26..245ff4ed65f 100644 --- a/apps/hash-api/src/graphql/resolvers/flows/flow-schedule.test.ts +++ b/apps/hash-api/src/graphql/resolvers/flows/flow-schedule.test.ts @@ -59,7 +59,6 @@ const graphQLContext = { }; beforeEach(() => { - vi.clearAllMocks(); mocks.getRunnableFlowDefinition.mockResolvedValue({ flowDefinition: { inputs }, flowType: "integration", diff --git a/apps/hash-api/src/graphql/resolvers/knowledge/notification/update-notifications.test.ts b/apps/hash-api/src/graphql/resolvers/knowledge/notification/update-notifications.test.ts index f3c4cea6341..bba224ce2c6 100644 --- a/apps/hash-api/src/graphql/resolvers/knowledge/notification/update-notifications.test.ts +++ b/apps/hash-api/src/graphql/resolvers/knowledge/notification/update-notifications.test.ts @@ -1,4 +1,4 @@ -import { beforeEach, describe, expect, it, vi } from "vitest"; +import { describe, expect, it, vi } from "vitest"; import { archiveNotificationsResolver, @@ -44,10 +44,6 @@ const graphQLContext = { const resolveInfo = {} as GraphQLResolveInfo; describe("notification update resolvers", () => { - beforeEach(() => { - vi.clearAllMocks(); - }); - it("marks an owned notification as read through the notification service", async () => { const entity = { metadata: { recordId: { entityId: notificationEntityId } }, diff --git a/apps/hash-api/src/index.ts b/apps/hash-api/src/index.ts index e6b72b800b9..67db68186e1 100644 --- a/apps/hash-api/src/index.ts +++ b/apps/hash-api/src/index.ts @@ -4,8 +4,15 @@ import { promisify } from "node:util"; import KeyvRedis from "@keyv/redis"; import * as Sentry from "@sentry/node"; import cors from "cors"; -import { Effect, Exit, Layer, Logger, LogLevel, ManagedRuntime } from "effect"; -import { RuntimeException } from "effect/Cause"; +import { + Cause, + Effect, + Exit, + Layer, + Logger, + ManagedRuntime, + References, +} from "effect"; import express, { raw } from "express"; import { create as handlebarsCreate } from "express-handlebars"; import { ipKeyGenerator, rateLimit } from "express-rate-limit"; @@ -815,7 +822,7 @@ const main = async () => { RequestIdProducer.layer, JsonDecoder.layer, JsonEncoder.layer, - Logger.pretty, + Logger.layer([Logger.consolePretty(), Logger.tracerLogger]), ), ); @@ -857,7 +864,7 @@ const main = async () => { const effect = Effect.gen(function* () { const textQueryParam = req.query.text; if (typeof textQueryParam !== "string") { - return yield* new RuntimeException( + return yield* new Cause.IllegalArgumentError( "text query parameter is required", ); } @@ -870,7 +877,7 @@ const main = async () => { Transport.multiaddr(`/dns/${rpcHost}/tcp/${rpcPort}`), ), ), - Logger.withMinimumLogLevel(LogLevel.Trace), + Effect.provideService(References.MinimumLogLevel, "Trace"), ); runtime.runCallback(effect, { diff --git a/apps/hash-frontend/package.json b/apps/hash-frontend/package.json index 8e3479af492..3707537f232 100644 --- a/apps/hash-frontend/package.json +++ b/apps/hash-frontend/package.json @@ -191,6 +191,7 @@ "rimraf": "6.1.3", "sass": "1.93.2", "typescript": "catalog:", + "vite": "catalog:", "vitest": "catalog:", "wait-on": "9.0.1", "webpack": "5.107.2" diff --git a/apps/hash-frontend/src/pages/supply-chain/supply-chain-data-shell/product/production-schedule.test.tsx b/apps/hash-frontend/src/pages/supply-chain/supply-chain-data-shell/product/production-schedule.test.tsx index d6d4cf535b0..d72e661162a 100644 --- a/apps/hash-frontend/src/pages/supply-chain/supply-chain-data-shell/product/production-schedule.test.tsx +++ b/apps/hash-frontend/src/pages/supply-chain/supply-chain-data-shell/product/production-schedule.test.tsx @@ -450,7 +450,6 @@ beforeAll(() => { afterEach(() => { cleanup(); - vi.clearAllMocks(); vi.useRealTimers(); }); diff --git a/apps/petrinaut-website/package.json b/apps/petrinaut-website/package.json index 7f276999dfa..4020b2ac781 100644 --- a/apps/petrinaut-website/package.json +++ b/apps/petrinaut-website/package.json @@ -40,7 +40,7 @@ "zod": "4.6.7" }, "devDependencies": { - "@fast-check/vitest": "0.4.1", + "@fast-check/vitest": "catalog:", "@local/tsconfig": "workspace:*", "@tanstack/router-generator": "1.167.32", "@tanstack/router-plugin": "1.168.34", diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/assistant-labs-settings.test.tsx b/apps/petrinaut-website/src/main/app/local-storage-demo/assistant-labs-settings.test.tsx index 0084180193c..245f89b64b6 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/assistant-labs-settings.test.tsx +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/assistant-labs-settings.test.tsx @@ -42,7 +42,6 @@ beforeEach(() => { afterEach(() => { cleanup(); - vi.clearAllMocks(); vi.unstubAllGlobals(); }); diff --git a/apps/petrinaut-website/src/main/app/local-storage-demo/documents/use-document-controller.test.ts b/apps/petrinaut-website/src/main/app/local-storage-demo/documents/use-document-controller.test.ts index 49e1dfa20ca..67c65df8418 100644 --- a/apps/petrinaut-website/src/main/app/local-storage-demo/documents/use-document-controller.test.ts +++ b/apps/petrinaut-website/src/main/app/local-storage-demo/documents/use-document-controller.test.ts @@ -29,7 +29,6 @@ vi.mock("./local-storage/use-local-document-repository", () => ({ })); beforeEach(() => { - vi.clearAllMocks(); useLocal.mockReturnValue({ repository: { records: [record], diff --git a/apps/petrinaut-website/src/main/app/plugins/petrinaut-ai/chat/assistant-chat/chat-view.test.tsx b/apps/petrinaut-website/src/main/app/plugins/petrinaut-ai/chat/assistant-chat/chat-view.test.tsx index 4d58235c85e..a6c31aedf37 100644 --- a/apps/petrinaut-website/src/main/app/plugins/petrinaut-ai/chat/assistant-chat/chat-view.test.tsx +++ b/apps/petrinaut-website/src/main/app/plugins/petrinaut-ai/chat/assistant-chat/chat-view.test.tsx @@ -42,7 +42,6 @@ const render = (ui: ReactElement) => afterEach(() => { cleanup(); - vi.clearAllMocks(); vi.useRealTimers(); }); diff --git a/apps/petrinaut-website/src/routes/-share.test.tsx b/apps/petrinaut-website/src/routes/-share.test.tsx index 89ad36e3dd7..de9854b67bd 100644 --- a/apps/petrinaut-website/src/routes/-share.test.tsx +++ b/apps/petrinaut-website/src/routes/-share.test.tsx @@ -107,7 +107,6 @@ beforeEach(() => { afterEach(() => { cleanup(); vi.unstubAllGlobals(); - vi.clearAllMocks(); }); const open = async (path: string) => { diff --git a/apps/petrinaut-website/src/sharing/share-snapshot-button.test.tsx b/apps/petrinaut-website/src/sharing/share-snapshot-button.test.tsx index d83d2a81e89..be95a150aa3 100644 --- a/apps/petrinaut-website/src/sharing/share-snapshot-button.test.tsx +++ b/apps/petrinaut-website/src/sharing/share-snapshot-button.test.tsx @@ -36,7 +36,6 @@ beforeEach(() => { }); afterEach(() => { cleanup(); - vi.clearAllMocks(); vi.restoreAllMocks(); vi.unstubAllGlobals(); }); diff --git a/libs/@blockprotocol/type-system/typescript/package.json b/libs/@blockprotocol/type-system/typescript/package.json index f9d9d3dcd2c..789dff2e9a9 100644 --- a/libs/@blockprotocol/type-system/typescript/package.json +++ b/libs/@blockprotocol/type-system/typescript/package.json @@ -63,14 +63,15 @@ "@types/node": "catalog:", "@types/react": "19.2.14", "@types/semver": "7.7.1", - "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-istanbul": "catalog:", "eslint": "9.39.4", "react": "19.2.6", "rimraf": "6.1.3", - "rolldown": "1.2.6", + "rolldown": "catalog:", "rolldown-plugin-dts": "0.28.3", "tslib": "2.8.1", "typescript": "catalog:", + "vite": "catalog:", "vitest": "catalog:" } } diff --git a/libs/@hashintel/brunch-agent/src/ui/chat/ai-assistant-panel/ai-assistant-contents.test.tsx b/libs/@hashintel/brunch-agent/src/ui/chat/ai-assistant-panel/ai-assistant-contents.test.tsx index 127f838345d..32b71ea7edf 100644 --- a/libs/@hashintel/brunch-agent/src/ui/chat/ai-assistant-panel/ai-assistant-contents.test.tsx +++ b/libs/@hashintel/brunch-agent/src/ui/chat/ai-assistant-panel/ai-assistant-contents.test.tsx @@ -106,7 +106,6 @@ beforeAll(() => { afterEach(() => { cleanup(); - vi.clearAllMocks(); vi.useRealTimers(); if (initialClipboardDescriptor === undefined) { Reflect.deleteProperty(navigator, "clipboard"); diff --git a/libs/@hashintel/brunch-agent/src/ui/voice/live/live-conversation-control.test.tsx b/libs/@hashintel/brunch-agent/src/ui/voice/live/live-conversation-control.test.tsx index 34165f7ece1..4aa8b8aa67b 100644 --- a/libs/@hashintel/brunch-agent/src/ui/voice/live/live-conversation-control.test.tsx +++ b/libs/@hashintel/brunch-agent/src/ui/voice/live/live-conversation-control.test.tsx @@ -67,7 +67,6 @@ beforeEach(() => { }); afterEach(() => { cleanup(); - vi.clearAllMocks(); vi.unstubAllGlobals(); window.localStorage.clear(); }); diff --git a/libs/@hashintel/ds-components/package.json b/libs/@hashintel/ds-components/package.json index aa9451a5f49..ee0b6d9e0fd 100644 --- a/libs/@hashintel/ds-components/package.json +++ b/libs/@hashintel/ds-components/package.json @@ -129,7 +129,6 @@ "@types/react-dom": "19.2.3", "@typescript/typescript6": "catalog:", "@vitejs/plugin-react": "6.1.1", - "@vitest/browser-playwright": "4.1.11", "case-anything": "3.1.0", "esbuild-plugin-svgr": "3.1.1", "eslint": "9.39.4", @@ -156,7 +155,6 @@ "vite": "catalog:", "vite-plugin-svgr": "5.2.0", "vitest": "catalog:", - "vitest-browser-react": "^2.0.2", "zod": "4.6.7" }, "peerDependencies": { diff --git a/libs/@hashintel/ds-icons/package.json b/libs/@hashintel/ds-icons/package.json index 012a80a67ca..b77d3564c39 100644 --- a/libs/@hashintel/ds-icons/package.json +++ b/libs/@hashintel/ds-icons/package.json @@ -63,7 +63,7 @@ "oxlint-tsgolint": "7.0.2003", "react": "19.2.6", "react-dom": "19.2.6", - "rolldown": "1.2.6", + "rolldown": "catalog:", "rolldown-plugin-dts": "0.28.3", "typescript": "catalog:", "vite": "catalog:", diff --git a/libs/@hashintel/petrinaut-core/package.json b/libs/@hashintel/petrinaut-core/package.json index cddc8b80baa..5a4b2c1fa12 100644 --- a/libs/@hashintel/petrinaut-core/package.json +++ b/libs/@hashintel/petrinaut-core/package.json @@ -122,7 +122,7 @@ "oxlint": "1.86.0", "oxlint-tsgolint": "7.0.2003", "pyodide": "314.0.6", - "rolldown": "1.2.6", + "rolldown": "catalog:", "rolldown-plugin-dts": "0.28.3", "typescript": "catalog:", "vite": "catalog:", diff --git a/libs/@hashintel/petrinaut/package.json b/libs/@hashintel/petrinaut/package.json index 5cbff5a9ab9..49aa75f2686 100644 --- a/libs/@hashintel/petrinaut/package.json +++ b/libs/@hashintel/petrinaut/package.json @@ -112,7 +112,7 @@ "oxlint-tsgolint": "7.0.2003", "react": "19.2.6", "react-dom": "19.2.6", - "rolldown": "1.2.6", + "rolldown": "catalog:", "rolldown-plugin-dts": "0.28.3", "storybook": "10.6.2", "typescript": "catalog:", diff --git a/libs/@hashintel/petrinaut/src/ui/components/sub-view/vertical/vertical-sub-views-container.test.tsx b/libs/@hashintel/petrinaut/src/ui/components/sub-view/vertical/vertical-sub-views-container.test.tsx index a06a65bc078..fa03ce58620 100644 --- a/libs/@hashintel/petrinaut/src/ui/components/sub-view/vertical/vertical-sub-views-container.test.tsx +++ b/libs/@hashintel/petrinaut/src/ui/components/sub-view/vertical/vertical-sub-views-container.test.tsx @@ -76,7 +76,6 @@ afterEach(() => { else Reflect.deleteProperty(HTMLElement.prototype, "animate"); vi.restoreAllMocks(); vi.unstubAllGlobals(); - vi.clearAllMocks(); }); const Properties = () => { diff --git a/libs/@hashintel/petrinaut/src/ui/monaco/code-editor-activity.test.tsx b/libs/@hashintel/petrinaut/src/ui/monaco/code-editor-activity.test.tsx index b1a2f147436..05155d343ff 100644 --- a/libs/@hashintel/petrinaut/src/ui/monaco/code-editor-activity.test.tsx +++ b/libs/@hashintel/petrinaut/src/ui/monaco/code-editor-activity.test.tsx @@ -141,7 +141,6 @@ afterEach(() => { cleanup(); models.clear(); instances.length = 0; - vi.clearAllMocks(); }); it("disposes the hidden editor and ignores stale hidden values while typing", async () => { diff --git a/libs/@hashintel/petrinaut/src/ui/monaco/code-navigation.test.tsx b/libs/@hashintel/petrinaut/src/ui/monaco/code-navigation.test.tsx index 8ce7dc756be..c0d8ffe0f6a 100644 --- a/libs/@hashintel/petrinaut/src/ui/monaco/code-navigation.test.tsx +++ b/libs/@hashintel/petrinaut/src/ui/monaco/code-navigation.test.tsx @@ -67,7 +67,6 @@ const Harness = ({ afterEach(() => { cleanup(); - vi.clearAllMocks(); }); it("opens the matching property section and preserves its saved size", () => { diff --git a/libs/@hashintel/petrinaut/src/ui/views/Editor/components/BottomBar/use-keyboard-shortcuts.test.tsx b/libs/@hashintel/petrinaut/src/ui/views/Editor/components/BottomBar/use-keyboard-shortcuts.test.tsx index 2d6a09a2c16..96d60817b54 100644 --- a/libs/@hashintel/petrinaut/src/ui/views/Editor/components/BottomBar/use-keyboard-shortcuts.test.tsx +++ b/libs/@hashintel/petrinaut/src/ui/views/Editor/components/BottomBar/use-keyboard-shortcuts.test.tsx @@ -38,7 +38,6 @@ afterEach(() => { actions.readOnly = true; actions.reason = "host-readonly"; cleanup(); - vi.clearAllMocks(); }); const Shortcuts = () => { diff --git a/libs/@hashintel/petrinaut/src/ui/views/Editor/editor-view.test.tsx b/libs/@hashintel/petrinaut/src/ui/views/Editor/editor-view.test.tsx index 93d0025ce6d..77e9b9ec5fd 100644 --- a/libs/@hashintel/petrinaut/src/ui/views/Editor/editor-view.test.tsx +++ b/libs/@hashintel/petrinaut/src/ui/views/Editor/editor-view.test.tsx @@ -156,7 +156,6 @@ beforeEach(() => { afterEach(() => { cleanup(); - vi.clearAllMocks(); vi.unstubAllGlobals(); }); diff --git a/libs/@hashintel/petrinaut/src/ui/views/Editor/editor-view/user-settings/user-settings-dialog/settings-heading.test.tsx b/libs/@hashintel/petrinaut/src/ui/views/Editor/editor-view/user-settings/user-settings-dialog/settings-heading.test.tsx index db7d79b544e..5515177a63e 100644 --- a/libs/@hashintel/petrinaut/src/ui/views/Editor/editor-view/user-settings/user-settings-dialog/settings-heading.test.tsx +++ b/libs/@hashintel/petrinaut/src/ui/views/Editor/editor-view/user-settings/user-settings-dialog/settings-heading.test.tsx @@ -34,7 +34,6 @@ beforeEach(() => { afterEach(() => { cleanup(); vi.unstubAllGlobals(); - vi.clearAllMocks(); Reflect.deleteProperty(HTMLElement.prototype, "animate"); }); diff --git a/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/SimulateView/experiments/create-experiment-drawer.test.tsx b/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/SimulateView/experiments/create-experiment-drawer.test.tsx index 8854e2b7382..7c169b8af0e 100644 --- a/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/SimulateView/experiments/create-experiment-drawer.test.tsx +++ b/libs/@hashintel/petrinaut/src/ui/views/Editor/panels/SimulateView/experiments/create-experiment-drawer.test.tsx @@ -433,7 +433,6 @@ beforeEach(() => { afterEach(() => { cleanup(); vi.unstubAllGlobals(); - vi.clearAllMocks(); }); /** The Backend field: the CPU/GPU labels with the toggle between them. */ diff --git a/libs/@hashintel/refractive/package.json b/libs/@hashintel/refractive/package.json index 6cda2811cc6..24188f7b1e8 100644 --- a/libs/@hashintel/refractive/package.json +++ b/libs/@hashintel/refractive/package.json @@ -45,7 +45,7 @@ "oxlint-tsgolint": "7.0.2003", "react": "19.2.6", "react-dom": "19.2.6", - "rolldown": "1.2.6", + "rolldown": "catalog:", "rolldown-plugin-dts": "0.28.3", "storybook": "10.6.2", "typescript": "catalog:", diff --git a/libs/@hashintel/refractive/src/hoc/refractive.test.tsx b/libs/@hashintel/refractive/src/hoc/refractive.test.tsx index 112e3455a5e..30f4162fd02 100644 --- a/libs/@hashintel/refractive/src/hoc/refractive.test.tsx +++ b/libs/@hashintel/refractive/src/hoc/refractive.test.tsx @@ -52,7 +52,6 @@ afterEach(() => { act(() => root.unmount()); vi.restoreAllMocks(); vi.unstubAllGlobals(); - vi.clearAllMocks(); supports.mockReturnValue(true); }); diff --git a/libs/@local/eslint/package.json b/libs/@local/eslint/package.json index 0ac90215ab3..46b91139c49 100644 --- a/libs/@local/eslint/package.json +++ b/libs/@local/eslint/package.json @@ -27,7 +27,7 @@ "@eslint/eslintrc": "3.3.3", "@typescript-eslint/eslint-plugin": "8.71.0", "@typescript-eslint/parser": "8.71.0", - "effect": "3.21.0", + "effect": "4.0.3", "eslint": "9.39.4", "eslint-config-airbnb": "19.0.4", "eslint-config-flat-gitignore": "2.2.1", diff --git a/libs/@local/eslint/src/builtIn.ts b/libs/@local/eslint/src/builtIn.ts index bb1a58c4f8d..d0bc1e22ba6 100644 --- a/libs/@local/eslint/src/builtIn.ts +++ b/libs/@local/eslint/src/builtIn.ts @@ -1,4 +1,4 @@ -import { Array as ReadonlyArray, Option, pipe, Predicate } from "effect"; +import { Array as ReadonlyArray, pipe, Predicate, Result } from "effect"; import { defineConfig, type ESConfig } from "./utils.js"; @@ -46,15 +46,15 @@ const noRestrictedImports = ( ReadonlyArray.filter(Predicate.isNotUndefined), ReadonlyArray.filterMap((entry) => Array.isArray(entry) && entry.length === 2 - ? Option.some(entry[1]) - : Option.none(), + ? Result.succeed(entry[1]) + : Result.failVoid, ), ); const current = candidates.at(-1); // the value should be a dictionary with `paths` and `patterns` keys - if (!Predicate.isRecord(current) || Predicate.hasProperty(current, "name")) { + if (!Predicate.isObject(current) || Predicate.hasProperty(current, "name")) { throw new Error( "expected no-restricted-imports to follow the `paths` and `patterns` structure", ); diff --git a/libs/@local/flow-petri-net/package.json b/libs/@local/flow-petri-net/package.json index 20a8a6147b8..0468104fbde 100644 --- a/libs/@local/flow-petri-net/package.json +++ b/libs/@local/flow-petri-net/package.json @@ -46,6 +46,7 @@ "eslint": "9.39.4", "rimraf": "6.1.3", "typescript": "catalog:", + "vite": "catalog:", "vitest": "catalog:" } } diff --git a/libs/@local/graph/sdk/typescript/package.json b/libs/@local/graph/sdk/typescript/package.json index 1433d036a6e..b2d8c48823e 100644 --- a/libs/@local/graph/sdk/typescript/package.json +++ b/libs/@local/graph/sdk/typescript/package.json @@ -31,17 +31,18 @@ "@local/hash-graph-client": "workspace:*", "@local/hash-graph-store": "workspace:*", "@temporalio/client": "1.20.2", - "effect": "3.21.0", + "effect": "4.0.3", "uuid": "14.0.0" }, "devDependencies": { "@local/eslint": "workspace:*", "@local/tsconfig": "workspace:*", "@tsconfig/bases": "catalog:", - "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-istanbul": "catalog:", "eslint": "9.39.4", "rimraf": "6.1.3", "typescript": "catalog:", + "vite": "catalog:", "vitest": "catalog:" } } diff --git a/libs/@local/graph/sdk/typescript/src/harpc.ts b/libs/@local/graph/sdk/typescript/src/harpc.ts index 6d37aefb9f3..cb715622e59 100644 --- a/libs/@local/graph/sdk/typescript/src/harpc.ts +++ b/libs/@local/graph/sdk/typescript/src/harpc.ts @@ -5,8 +5,9 @@ import { Function, Option, pipe, - Predicate, + Result, Schema, + SchemaTransformation, Stream, } from "effect"; @@ -29,40 +30,40 @@ import { // eslint-disable-next-line @typescript-eslint/no-unused-vars -- otherwise TypeScript will fail on inference, I don't know why import { RequestIdProducer } from "@local/harpc-client/wire-protocol"; -const ServerResult = (ok: Schema.Schema) => - Schema.transform( - Schema.Union( - Schema.Struct({ - Ok: ok, - }), - Schema.Struct({ - Err: Schema.Unknown, - }), - ), - Schema.Either({ - left: Schema.instanceOf(ClientError.ServerError), - right: Schema.typeSchema(ok), +const ServerResult = (ok: Schema.Codec) => + Schema.Union([ + Schema.Struct({ + Ok: ok, + }), + Schema.Struct({ + Err: Schema.Unknown, }), - { - strict: true, - decode: (value) => { - if (Predicate.hasProperty(value, "Ok")) { - return { _tag: "Right", right: value.Ok } as const; - } + ]).pipe( + Schema.decodeTo( + Schema.Result( + Schema.toType(ok), + Schema.instanceOf(ClientError.ServerError), + ), + SchemaTransformation.transform< + Result.Result, + { readonly Ok: A } | { readonly Err: unknown } + >({ + decode: (value) => { + if ("Ok" in value) { + return Result.succeed(value.Ok); + } - return { - _tag: "Left", - left: new ClientError.ServerError({ cause: value.Err }), - } as const; - }, - encode: (value) => { - if (value._tag === "Right") { - return { Ok: value.right }; - } + return Result.fail(new ClientError.ServerError({ cause: value.Err })); + }, + encode: (value) => { + if (Result.isSuccess(value)) { + return { Ok: value.success }; + } - return { Err: value.left.cause } as const; - }, - }, + return { Err: value.failure.cause }; + }, + }), + ), ); export class EchoSubsystem { @@ -84,7 +85,7 @@ export class EchoSubsystem { Stream.succeed, encoder.encode(Schema.String), Stream.runCollect, - Effect.map(Stream.fromChunk), + Effect.map(Stream.fromArray), ); const request = yield* Request.make( @@ -102,10 +103,10 @@ export class EchoSubsystem { const items = decoder.decode(response.body, ServerResult(Schema.String)); const item = yield* Stream.runHead(items); - const eitherItem = Option.getOrThrowWith(item, () => + const resultItem = Option.getOrThrowWith(item, () => ClientError.ExpectedItemCountMismatchError.exactly(1, 0), ); - return yield* eitherItem; + return yield* Effect.fromResult(resultItem); }, Effect.map(Function.identity)); } diff --git a/libs/@local/harpc/client/typescript/package.json b/libs/@local/harpc/client/typescript/package.json index c903656d5c5..1c1f0be57e3 100644 --- a/libs/@local/harpc/client/typescript/package.json +++ b/libs/@local/harpc/client/typescript/package.json @@ -16,6 +16,7 @@ } }, "scripts": { + "bench": "yarn build && vitest bench --run --reporter=verbose --experimental.viteModuleRunner=false", "build": "rimraf dist && tsc --build tsconfig.build.json", "fix:eslint": "eslint --fix .", "lint:eslint": "eslint --report-unused-disable-directives .", @@ -32,28 +33,24 @@ "@libp2p/tcp": "11.0.28", "@multiformats/dns": "1.0.10", "@multiformats/multiaddr": "13.0.3", - "effect": "3.21.0", + "effect": "4.0.3", "it-stream-types": "2.0.2", "libp2p": "3.3.11", "multiformats": "14.0.5", "uint8arraylist": "3.0.2" }, "devDependencies": { - "@effect/cluster": "0.50.6", - "@effect/experimental": "0.56.0", - "@effect/platform": "0.92.1", - "@effect/platform-node": "0.98.4", - "@effect/rpc": "0.71.1", - "@effect/sql": "0.46.0", - "@effect/vitest": "patch:@effect/vitest@npm%3A0.29.0#~/.yarn/patches/@effect-vitest-npm-0.29.0-1c8cf3c306.patch", + "@effect/platform-node": "4.0.3", + "@effect/vitest": "4.0.3", "@local/eslint": "workspace:*", "@local/tsconfig": "workspace:*", "@tsconfig/bases": "catalog:", "@types/node": "catalog:", - "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-istanbul": "catalog:", "eslint": "9.39.4", "rimraf": "6.1.3", "typescript": "catalog:", + "vite": "catalog:", "vitest": "catalog:" } } diff --git a/libs/@local/harpc/client/typescript/src/binary/MutableBuffer.ts b/libs/@local/harpc/client/typescript/src/binary/MutableBuffer.ts index 986ea45c2c7..65fc01d3175 100644 --- a/libs/@local/harpc/client/typescript/src/binary/MutableBuffer.ts +++ b/libs/@local/harpc/client/typescript/src/binary/MutableBuffer.ts @@ -1,4 +1,4 @@ -import { Data, Either, Function, pipe, Pipeable } from "effect"; +import { Data, Function, pipe, Pipeable, Result } from "effect"; import { createProto } from "../utils.js"; import * as MutableBytes from "./MutableBytes.js"; @@ -22,7 +22,7 @@ export type Read = typeof Read; export type ReadBuffer = MutableBuffer; -export type ReadResult = Either.Either; +export type ReadResult = Result.Result; const Write: unique symbol = Symbol( "@local/harpc-client/binary/MutableBuffer/Write", @@ -32,7 +32,7 @@ export type Write = typeof Write; export type WriteBuffer = MutableBuffer; -export type WriteResult = Either.Either< +export type WriteResult = Result.Result< WriteBuffer, E >; @@ -89,17 +89,17 @@ export const makeWrite = (buffer?: MutableBytes.MutableBytes): WriteBuffer => const validateBounds = ( self: MutableBuffer, width: number, -): Either.Either => { +): Result.Result => { const impl = self as MutableBufferImpl; return impl.index + width > MutableBytes.length(impl.bytes) - ? Either.left( + ? Result.fail( new UnexpectedEndOfBufferError({ index: impl.index, length: MutableBytes.length(impl.bytes), }), ) - : Either.right(undefined); + : Result.succeed(undefined); }; /** @@ -122,7 +122,7 @@ const putInt = (sign: "u" | "i", width: 1 | 2 | 4) => >(2, (self, value) => pipe( validateBounds(self, width), - Either.map(() => { + Result.map(() => { const impl = self as MutableBufferImpl; const view = MutableBytes.asDataView(impl.bytes); @@ -173,7 +173,7 @@ export const putI32 = putInt("i", 4); const getInt = (sign: "u" | "i", width: 1 | 2 | 4) => (self: ReadBuffer) => pipe( validateBounds(self, width), - Either.map(() => { + Result.map(() => { const impl = self as MutableBufferImpl; const view = MutableBytes.asDataView(impl.bytes); @@ -215,7 +215,7 @@ export const putSlice = Function.dual< >(2, (self, value) => pipe( validateBounds(self, value.length), - Either.map(() => { + Result.map(() => { const impl = self as MutableBufferImpl; const slice = MutableBytes.asArray(impl.bytes); @@ -232,7 +232,7 @@ export const putSlice = Function.dual< export const getSlice = (self: ReadBuffer, byteLength: number) => pipe( validateBounds(self, byteLength), - Either.map(() => { + Result.map(() => { const impl = self as MutableBufferImpl; const slice = MutableBytes.asArray(impl.bytes).slice( @@ -257,15 +257,15 @@ export const advance = Function.dual< length: number, ) => ( self: MutableBuffer, - ) => Either.Either, UnexpectedEndOfBufferError>, + ) => Result.Result, UnexpectedEndOfBufferError>, ( self: MutableBuffer, length: number, - ) => Either.Either, UnexpectedEndOfBufferError> + ) => Result.Result, UnexpectedEndOfBufferError> >(2, (self: MutableBuffer, byteLength: number) => pipe( validateBounds(self, byteLength), - Either.map(() => { + Result.map(() => { const impl = self as MutableBufferImpl; impl.index = impl.index + byteLength; diff --git a/libs/@local/harpc/client/typescript/src/codec/Decoder.ts b/libs/@local/harpc/client/typescript/src/codec/Decoder.ts index e40d217946e..c7697eb99e8 100644 --- a/libs/@local/harpc/client/typescript/src/codec/Decoder.ts +++ b/libs/@local/harpc/client/typescript/src/codec/Decoder.ts @@ -1,13 +1,12 @@ import { - type ParseResult, - type Schema, - type Stream, + Context, Data, Function, Inspectable, Pipeable, + type Schema, + type Stream, } from "effect"; -import { GenericTag } from "effect/Context"; import { createProto } from "../utils.js"; @@ -19,7 +18,7 @@ export class DecodingError extends Data.TaggedError("DecodingError")<{ cause: unknown; }> { get message() { - return "Failed to encode value"; + return "Failed to decode value"; } } @@ -29,21 +28,21 @@ export interface Decoder readonly decode: { ( - schema: Schema.Schema, + schema: Schema.Codec, ): ( input: Stream.Stream, ) => Stream.Stream< SchemaType, - E | StreamError | ParseResult.ParseError, + E | StreamError | Schema.SchemaError, R | StreamContext | SchemaContext >; ( input: Stream.Stream, - schema: Schema.Schema, + schema: Schema.Codec, ): Stream.Stream< SchemaType, - E | StreamError | ParseResult.ParseError, + E | StreamError | Schema.SchemaError, R | StreamContext | SchemaContext >; }; @@ -75,7 +74,7 @@ const DecoderProto: Omit = { }; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- description is defined -export const Decoder = GenericTag(TypeId.description!); +export const Decoder = Context.Service(TypeId.description!); export const make = ( decode: < @@ -86,10 +85,10 @@ export const make = ( StreamContext, >( input: Stream.Stream, - schema: Schema.Schema, + schema: Schema.Codec, ) => Stream.Stream< SchemaType, - E | StreamError | ParseResult.ParseError, + E | StreamError | Schema.SchemaError, R | StreamContext | SchemaContext >, ) => diff --git a/libs/@local/harpc/client/typescript/src/codec/Encoder.ts b/libs/@local/harpc/client/typescript/src/codec/Encoder.ts index 03e631e9232..222875e5fb3 100644 --- a/libs/@local/harpc/client/typescript/src/codec/Encoder.ts +++ b/libs/@local/harpc/client/typescript/src/codec/Encoder.ts @@ -1,13 +1,12 @@ import { - type ParseResult, - type Schema, - type Stream, + Context, Data, Function, Inspectable, Pipeable, + type Schema, + type Stream, } from "effect"; -import { GenericTag } from "effect/Context"; import { createProto } from "../utils.js"; @@ -29,21 +28,21 @@ export interface Encoder readonly encode: { ( - schema: Schema.Schema, + schema: Schema.Codec, ): ( input: Stream.Stream, ) => Stream.Stream< ArrayBuffer, - E | StreamError | ParseResult.ParseError, + E | StreamError | Schema.SchemaError, R | StreamContext | SchemaContext >; ( input: Stream.Stream, - schema: Schema.Schema, + schema: Schema.Codec, ): Stream.Stream< ArrayBuffer, - E | StreamError | ParseResult.ParseError, + E | StreamError | Schema.SchemaError, R | StreamContext | SchemaContext >; }; @@ -75,7 +74,7 @@ const EncoderProto: Omit = { }; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- description is defined -export const Encoder = GenericTag(TypeId.description!); +export const Encoder = Context.Service(TypeId.description!); export const make = ( encode: < @@ -86,10 +85,10 @@ export const make = ( StreamContext, >( input: Stream.Stream, - schema: Schema.Schema, + schema: Schema.Codec, ) => Stream.Stream< ArrayBuffer, - E | StreamError | ParseResult.ParseError, + E | StreamError | Schema.SchemaError, R | StreamContext | SchemaContext >, ) => diff --git a/libs/@local/harpc/client/typescript/src/codec/JsonDecoder.ts b/libs/@local/harpc/client/typescript/src/codec/JsonDecoder.ts index 376620f7a63..4c29f12daa5 100644 --- a/libs/@local/harpc/client/typescript/src/codec/JsonDecoder.ts +++ b/libs/@local/harpc/client/typescript/src/codec/JsonDecoder.ts @@ -94,14 +94,16 @@ const make = (options: Options) => ignoreBOM: true, }); - const schemaJson = Schema.parseJson(schema); - const decodeJson = Schema.decode(schemaJson); + // parsing before the schema keeps the parser's `SyntaxError` as the failure's cause + const decodeValue = Schema.decodeUnknownEffect(schema); + const decodeJson = (text: string) => + Effect.flatMap(parseJson(text), decodeValue); let fragment = ""; return pipe( input, - Stream.mapConcatEffect((buffer) => + Stream.mapEffect((buffer) => Effect.gen(function* () { const [nextFragment, items] = yield* processArrayBuffer( buffer, @@ -116,6 +118,7 @@ const make = (options: Options) => return items; }), ), + Stream.flattenIterable, ); }); diff --git a/libs/@local/harpc/client/typescript/src/codec/JsonEncoder.ts b/libs/@local/harpc/client/typescript/src/codec/JsonEncoder.ts index 5d54fa1fcf9..df909bfb704 100644 --- a/libs/@local/harpc/client/typescript/src/codec/JsonEncoder.ts +++ b/libs/@local/harpc/client/typescript/src/codec/JsonEncoder.ts @@ -12,8 +12,8 @@ const encoder = (options: Options) => const textEncoder = new TextEncoder(); - const schemaJson = Schema.parseJson(schema); - const encodeJson = Schema.encode(schemaJson); + const schemaJson = Schema.fromJsonString(schema); + const encodeJson = Schema.encodeEffect(schemaJson); return pipe( input, diff --git a/libs/@local/harpc/client/typescript/src/net/Client.ts b/libs/@local/harpc/client/typescript/src/net/Client.ts index 6dbc696e275..d924d72c535 100644 --- a/libs/@local/harpc/client/typescript/src/net/Client.ts +++ b/libs/@local/harpc/client/typescript/src/net/Client.ts @@ -1,5 +1,4 @@ -import { Effect, Function, Layer, type Scope } from "effect"; -import { GenericTag } from "effect/Context"; +import { Context, Effect, Function, Layer, type Scope } from "effect"; import { createProto } from "../utils.js"; import * as Connection from "./Connection.js"; @@ -30,7 +29,7 @@ const ClientProto: Omit = { }; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- TypeId is defined -export const Client = GenericTag(TypeId.description!); +export const Client = Context.Service(TypeId.description!); // TODO: add a metrics compatability layer // see: https://linear.app/hash/issue/H-3712/libp2p-metrics-compatibility-layer @@ -47,7 +46,7 @@ export const make = Effect.fn("make")(function* (config?: ClientConfig) { }); export const layer = (config?: ClientConfig) => - Layer.scoped(Client, make(config)); + Layer.effect(Client, make(config)); export const connect = Function.dual< ( @@ -79,7 +78,7 @@ export const connect = Function.dual< ); export const connectLayer = (address: Transport.Address) => - Layer.scoped( + Layer.effect( Connection.Connection, Effect.gen(function* () { const client = yield* Client; diff --git a/libs/@local/harpc/client/typescript/src/net/Connection.ts b/libs/@local/harpc/client/typescript/src/net/Connection.ts index 6842be2e411..0c61096f64e 100644 --- a/libs/@local/harpc/client/typescript/src/net/Connection.ts +++ b/libs/@local/harpc/client/typescript/src/net/Connection.ts @@ -1,18 +1,20 @@ import { - type Scope, - Chunk, + type Cause, + Context, Deferred, Duration, Effect, + Exit, Function, MutableHashMap, + MutableRef, Option, pipe, Queue, + type Scope, Sink, Stream, } from "effect"; -import { GenericTag } from "effect/Context"; import { isUint8ArrayList, Uint8ArrayList } from "uint8arraylist"; import { MutableBuffer } from "../binary/index.js"; @@ -32,6 +34,7 @@ import * as Transaction from "./Transaction.js"; import * as Transport from "./Transport.js"; import type { IncompleteResponseError } from "../wire-protocol/stream/ResponseFromBytesStream.js"; +import type { NonEmptyReadonlyArray } from "effect/Array"; const TypeId: unique symbol = Symbol("@local/harpc-client/net/Connection"); @@ -55,12 +58,13 @@ interface ConnectionDuplex { export interface ConnectionConfig { /** - * The maximum duration to wait for a response before considering the transaction lagged. - * If a response is not received within this timeout, the transaction will be dropped. + * The maximum duration to wait for space in a transaction's response buffer before considering the transaction lagged. + * + * The connection delivers the responses of all its transactions one at a time, so while it waits, every other transaction waits too. Once the timeout expires, the connection drops the transaction, and reading it fails with {@link Transaction.TransactionLaggedError}. * * @defaultValue 200ms */ - lagTimeout?: Duration.DurationInput; + lagTimeout?: Duration.Input; /** * The size of the number of buffered responses to keep in memory. @@ -96,8 +100,12 @@ export interface Connection { } interface TransactionContext { - queue: Queue.Enqueue; + queue: Queue.Enqueue< + WireResponse.Response, + Transaction.TransactionError | Cause.Done + >; drop: Effect.Effect; + fail: (error: Transaction.TransactionError) => Effect.Effect; } interface ConnectionImpl extends Connection { @@ -106,6 +114,11 @@ interface ConnectionImpl extends Connection { TransactionContext >; + /** How the read task ended, once it has. */ + readonly closed: MutableRef.MutableRef< + Option.Option> + >; + readonly duplex: ConnectionDuplex; readonly config: ConnectionConfig; @@ -113,13 +126,13 @@ interface ConnectionImpl extends Connection { const ConnectionProto: Omit< ConnectionImpl, - "transactions" | "duplex" | "config" + "transactions" | "closed" | "duplex" | "config" > = { [TypeId]: TypeId, }; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- always defined -export const Connection = GenericTag(TypeId.description!); +export const Connection = Context.Service(TypeId.description!); const makeSink = (connection: ConnectionImpl) => Sink.forEach((response: WireResponse.Response) => @@ -136,21 +149,23 @@ const makeSink = (connection: ConnectionImpl) => const lagTimeout = connection.config.lagTimeout ?? Duration.seconds(0.2); - const isOnline = yield* pipe( + const offered = yield* pipe( Queue.offer(transaction.value.queue, response), - Effect.timeout(lagTimeout), - Effect.catchTag("TimeoutException", (timeout) => - Effect.gen(function* () { - yield* Effect.logWarning( - "transaction has lagged behind too far, dropping it", - ).pipe(Effect.annotateLogs({ timeout })); - - yield* transaction.value.drop; - }), - ), + Effect.timeoutOption(lagTimeout), ); - if (isOnline === false) { + if (Option.isNone(offered)) { + yield* Effect.logWarning( + "transaction has lagged behind too far, dropping it", + ).pipe(Effect.annotateLogs({ lagTimeout })); + yield* transaction.value.fail( + new Transaction.TransactionLaggedError({ id }), + ); + + return; + } + + if (!offered.value) { yield* Effect.logWarning("transaction has been closed, dropping it"); yield* transaction.value.drop; @@ -169,6 +184,7 @@ const wrapDrop = Effect.fn("wrapDrop")(function* ( connection: ConnectionImpl, id: RequestId.RequestId, drop: Deferred.Deferred, + close: (queue: TransactionContext["queue"]) => Effect.Effect, ) { const transaction = MutableHashMap.get(connection.transactions, id); @@ -179,7 +195,7 @@ const wrapDrop = Effect.fn("wrapDrop")(function* ( } MutableHashMap.remove(connection.transactions, id); - yield* transaction.value.queue.shutdown; + yield* close(transaction.value.queue); // call user defined drop function const dropImpl = yield* Deferred.poll(drop); @@ -189,11 +205,56 @@ const wrapDrop = Effect.fn("wrapDrop")(function* ( } }); +const closeError = ( + exit: Exit.Exit, + id: RequestId.RequestId, +) => + Option.getOrElse( + Exit.findErrorOption(exit), + (): Transaction.TransactionError => + new Transaction.ConnectionClosedError({ id }), + ); + +const closeTransactions = Effect.fn("closeTransactions")(function* ( + connection: ConnectionImpl, + exit: Exit.Exit, +) { + MutableRef.set(connection.closed, Option.some(exit)); + + for (const [id, transaction] of connection.transactions) { + yield* transaction.fail(closeError(exit, id)); + } +}); + const task = Effect.fn("task")(function* (connection: ConnectionImpl) { const sink = makeSink(connection); - // We don't need to monitor if the connection itself closes as that simply means that our stream would end. - yield* Stream.run(connection.duplex.read, sink); + // Once the read stream ends no response can arrive, so a transaction still waiting for one would wait forever. + yield* pipe( + Stream.run(connection.duplex.read, sink), + Effect.onExit((exit) => closeTransactions(connection, exit)), + ); +}); + +/** @internal */ +export const makeFromDuplex = Effect.fn("makeFromDuplex")(function* ( + duplex: ConnectionDuplex, + config: ConnectionConfig, +) { + const self: ConnectionImpl = createProto(ConnectionProto, { + transactions: MutableHashMap.empty< + RequestId.RequestId, + TransactionContext + >(), + closed: MutableRef.make(Option.none()), + duplex, + config, + }); + + // TODO: we might want to observe the task, for that we would need to have a partial connection that we then patch + yield* Effect.forkChild(task(self)); + + return self; }); /** @internal */ @@ -223,7 +284,8 @@ export const makeUnchecked = Effect.fn("makeUnchecked")(function* ( stream, (cause) => new Transport.TransportError({ cause }), ), - Stream.mapConcat((list) => (isUint8ArrayList(list) ? list : [list])), + Stream.map((list) => (isUint8ArrayList(list) ? list : [list])), + Stream.flattenIterable, // cast needed as uint8arraylist doesn't support Uint8Array yet Stream.map((array) => // take the underlying buffer and slice it to the correct view @@ -236,11 +298,10 @@ export const makeUnchecked = Effect.fn("makeUnchecked")(function* ( ); const writeSink = pipe( - Sink.forEachChunk((chunk: Chunk.Chunk) => + Sink.forEachArray((chunk: NonEmptyReadonlyArray) => Effect.gen(function* () { const shouldContinue = yield* Effect.try({ - try: () => - stream.send(Uint8ArrayList.fromUint8Arrays(Chunk.toArray(chunk))), + try: () => stream.send(Uint8ArrayList.fromUint8Arrays([...chunk])), catch: (cause) => new Transport.TransportError({ cause }), }); @@ -254,7 +315,7 @@ export const makeUnchecked = Effect.fn("makeUnchecked")(function* ( // in the future we might be able to re-use the allocated buffer (we would likely still need to copy the contents tho) const buffer = MutableBuffer.makeWrite(); - yield* WireRequest.encode(buffer, request); + yield* Effect.fromResult(WireRequest.encode(buffer, request)); const array = MutableBuffer.take(buffer); @@ -265,19 +326,7 @@ export const makeUnchecked = Effect.fn("makeUnchecked")(function* ( const duplex = { read: readStream, write: writeSink } as ConnectionDuplex; - const self: ConnectionImpl = createProto(ConnectionProto, { - transactions: MutableHashMap.empty< - RequestId.RequestId, - TransactionContext - >(), - duplex, - config, - }); - - // TODO: we might want to observe the task, for that we would need to have a partial connection that we then patch - yield* Effect.fork(task(self)); - - return self; + return yield* makeFromDuplex(duplex, config); }); // these bounds are stricter than required, as we have no way to inform the remote about a failure in the underlying stream, @@ -299,24 +348,41 @@ export const send = Function.dual< // eslint-disable-next-line @typescript-eslint/no-invalid-void-type -- it's indeed correct here const deferredDrop = yield* Deferred.make(); - const drop = wrapDrop(impl, request.id, deferredDrop); + const drop = wrapDrop(impl, request.id, deferredDrop, Queue.end); + const fail = (error: Transaction.TransactionError) => + wrapDrop(impl, request.id, deferredDrop, (transactionQueue) => + Queue.fail(transactionQueue, error), + ); - const queue = yield* Queue.bounded( - impl.config.responseBufferSize ?? 16, - ); + const queue = yield* Queue.bounded< + WireResponse.Response, + Transaction.TransactionError | Cause.Done + >(impl.config.responseBufferSize ?? 16); + + const closed = MutableRef.get(impl.closed); + + if (Option.isSome(closed)) { + // the read task has ended, so no response can arrive + yield* Queue.fail(queue, closeError(closed.value, request.id)); + + return Transaction.makeUnchecked(request.id, queue, deferredDrop); + } const transactionContext: TransactionContext = { queue, drop, + fail, }; MutableHashMap.set(impl.transactions, request.id, transactionContext); - yield* Effect.fork( + yield* Effect.forkChild( pipe( request, // Request.encode(), Stream.run(impl.duplex.write), + Effect.scoped, + Effect.catch(fail), ), ); diff --git a/libs/@local/harpc/client/typescript/src/net/NetworkLogger.ts b/libs/@local/harpc/client/typescript/src/net/NetworkLogger.ts index 12da032cdcb..e0cd68b98c6 100644 --- a/libs/@local/harpc/client/typescript/src/net/NetworkLogger.ts +++ b/libs/@local/harpc/client/typescript/src/net/NetworkLogger.ts @@ -1,4 +1,4 @@ -import { Effect, LogLevel, Runtime } from "effect"; +import { type Context, Effect, type LogLevel } from "effect"; import { createProto } from "../utils.js"; import * as internal from "./internal/networkLogger.js"; @@ -20,19 +20,19 @@ interface NetworkLogger extends ComponentLogger { interface NetworkLoggerImpl extends NetworkLogger { readonly formatters: FormatterCollection; - readonly runtime: Runtime.Runtime; + readonly context: Context.Context; logger: ( name: string, - level: LogLevel.LogLevel, + level: LogLevel.Severity, ) => (formatter: unknown, ...args: readonly unknown[]) => void; } -const NetworkLoggerProto: Omit = { +const NetworkLoggerProto: Omit = { [TypeId]: TypeId, - logger(this: NetworkLoggerImpl, name: string, level: LogLevel.LogLevel) { - const fork = Runtime.runFork(this.runtime); + logger(this: NetworkLoggerImpl, name: string, level: LogLevel.Severity) { + const fork = Effect.runForkWith(this.context); return (formatter: unknown, ...args: readonly unknown[]) => { const effect = internal @@ -44,9 +44,9 @@ const NetworkLoggerProto: Omit = { }, forComponent(this: NetworkLoggerImpl, name: string): Logger { - return Object.assign(this.logger(name, LogLevel.Debug), { - error: this.logger(name, LogLevel.Error), - trace: this.logger(name, LogLevel.Trace), + return Object.assign(this.logger(name, "Debug"), { + error: this.logger(name, "Error"), + trace: this.logger(name, "Trace"), newScope: (child: string) => this.forComponent(`${name}:${child}`), enabled: true, }); @@ -58,10 +58,10 @@ export const DefaultFormatters = internal.defaultFormatters; export const make = Effect.fn("make")(function* ( formatters?: FormatterCollection, ) { - const runtime = yield* Effect.runtime(); + const context = yield* Effect.context(); return createProto(NetworkLoggerProto, { formatters: formatters ?? DefaultFormatters, - runtime, + context, }) satisfies NetworkLoggerImpl; }); diff --git a/libs/@local/harpc/client/typescript/src/net/Request.ts b/libs/@local/harpc/client/typescript/src/net/Request.ts index d072c891972..c3980c02a91 100644 --- a/libs/@local/harpc/client/typescript/src/net/Request.ts +++ b/libs/@local/harpc/client/typescript/src/net/Request.ts @@ -124,13 +124,14 @@ const pack = ( if (noDelay) { return pipe( stream, - Stream.mapConcat((buffer) => { + Stream.map((buffer) => { const [remaining, output] = splitBuffer(makeScratch(), buffer); output.push(remaining.buffer.slice(0, remaining.length)); return output; }), + Stream.flattenIterable, ); } @@ -138,7 +139,7 @@ const pack = ( return pipe( stream, - Stream.mapConcatEffect((buffer) => + Stream.mapEffect((buffer) => Effect.gen(function* () { const [newScratch, output] = splitBuffer( yield* Ref.get(scratch), @@ -150,6 +151,7 @@ const pack = ( return output; }), ), + Stream.flattenIterable, Stream.concat( Stream.fromIterableEffect( Effect.suspend(() => diff --git a/libs/@local/harpc/client/typescript/src/net/Response.ts b/libs/@local/harpc/client/typescript/src/net/Response.ts index 6e410ef772c..80ae3ee2746 100644 --- a/libs/@local/harpc/client/typescript/src/net/Response.ts +++ b/libs/@local/harpc/client/typescript/src/net/Response.ts @@ -76,7 +76,7 @@ const flattenResponseStream = ( Stream.takeUntil((response) => ResponseFlags.isEndOfResponse(response.header.flags), ), - Stream.mapConcat((response) => { + Stream.map((response) => { const output: ResponseSegment[] = []; const begin = ResponseBody.getBegin(response.body); @@ -97,6 +97,7 @@ const flattenResponseStream = ( return output; }), + Stream.flattenIterable, ); const processResponseStream = ( @@ -106,7 +107,7 @@ const processResponseStream = ( return pipe( stream, - Stream.mapConcatEffect((segment) => { + Stream.mapEffect((segment) => { return ResponseSegment.$match(segment, { // eslint-disable-next-line @typescript-eslint/naming-convention ControlFlow: ({ code }) => { @@ -135,6 +136,18 @@ const processResponseStream = ( }, }); }), + Stream.flattenIterable, + Stream.concat( + Stream.fromIterableEffect( + Effect.suspend(() => + // no later control segment follows the last error, so it is emitted once the stream ends + Option.match(partialError, { + onNone: () => Effect.succeed([]), + onSome: Effect.fail, + }), + ), + ), + ), ); }; diff --git a/libs/@local/harpc/client/typescript/src/net/Transaction.ts b/libs/@local/harpc/client/typescript/src/net/Transaction.ts index 485aa60f03f..14815296644 100644 --- a/libs/@local/harpc/client/typescript/src/net/Transaction.ts +++ b/libs/@local/harpc/client/typescript/src/net/Transaction.ts @@ -1,15 +1,56 @@ -import { type Effect, type Queue, Deferred, Function } from "effect"; +import { + type Cause, + Data, + Deferred, + type Effect, + Function, + type Queue, + Stream, +} from "effect"; import { createProto } from "../utils.js"; import * as Response from "./Response.js"; -import type { RequestId } from "../wire-protocol/models/request/index.js"; +import type { + RequestId, + Request as WireRequest, +} from "../wire-protocol/models/request/index.js"; import type { Response as WireResponse } from "../wire-protocol/models/response/index.js"; +import type { IncompleteResponseError } from "../wire-protocol/stream/ResponseFromBytesStream.js"; +import type * as Transport from "./Transport.js"; const TypeId: unique symbol = Symbol("@local/harpc-client/net/Transaction"); export type TypeId = typeof TypeId; +export class TransactionLaggedError extends Data.TaggedError( + "TransactionLaggedError", +)<{ + id: RequestId.RequestId; +}> { + get message() { + return `Transaction ${this.id.value} fell behind the connection and was dropped before its response was complete`; + } +} + +export class ConnectionClosedError extends Data.TaggedError( + "ConnectionClosedError", +)<{ + id: RequestId.RequestId; +}> { + get message() { + return `Transaction ${this.id.value} was dropped because its connection closed before its response was complete`; + } +} + +export type TransactionError = + | TransactionLaggedError + | ConnectionClosedError + | Transport.TransportError + | WireRequest.EncodeError + | WireResponse.DecodeError + | IncompleteResponseError; + export interface Transaction { readonly [TypeId]: TypeId; @@ -17,7 +58,10 @@ export interface Transaction { } interface TransactionImpl extends Transaction { - readonly read: Queue.Dequeue; + readonly read: Queue.Dequeue< + WireResponse.Response, + TransactionError | Cause.Done + >; readonly drop: Deferred.Deferred; } @@ -29,7 +73,10 @@ const TransactionProto: Omit = { /** @internal */ export const makeUnchecked = ( id: RequestId.RequestId, - readQueue: Queue.Dequeue, + readQueue: Queue.Dequeue< + WireResponse.Response, + TransactionError | Cause.Done + >, drop: Deferred.Deferred, ): Transaction => createProto(TransactionProto, { id, read: readQueue, drop }); @@ -43,5 +90,10 @@ export const registerDestructor: { Deferred.completeWith(self.drop, destructor), ); +/** + * Reads the transaction's response. + * + * The body fails with {@link Response.NetworkError} when the server answers with an error code. It fails with {@link TransactionLaggedError} when the connection dropped the transaction because its response buffer stayed full, and with {@link ConnectionClosedError} when the connection stopped reading before the response was complete. An error writing the request fails its transaction with that error, and an error reading the connection fails every open transaction with it. + */ export const read = (transaction: Transaction) => - Response.decode((transaction as TransactionImpl).read); + Response.decode(Stream.fromQueue((transaction as TransactionImpl).read)); diff --git a/libs/@local/harpc/client/typescript/src/net/internal/dns.ts b/libs/@local/harpc/client/typescript/src/net/internal/dns.ts index ca89afa27bf..f13bdd5a63b 100644 --- a/libs/@local/harpc/client/typescript/src/net/internal/dns.ts +++ b/libs/@local/harpc/client/typescript/src/net/internal/dns.ts @@ -1,7 +1,7 @@ import dns from "node:dns/promises"; import { isIPv4, isIPv6 } from "node:net"; -import { Array, Cause, Data, Duration, Effect, Function } from "effect"; +import { Array, Cause, Data, Duration, Effect, Function, Result } from "effect"; import type { NonEmptyReadonlyArray } from "effect/Array"; @@ -71,7 +71,7 @@ const logEnvironment = Effect.fn("logEnvironment")(function* ( ) { const servers = dns.getServers(); const records = yield* Effect.tryPromise(() => dns.resolveAny(hostname)).pipe( - Effect.merge, + Effect.catch((error) => Effect.succeed(error)), ); yield* Effect.logTrace("resolved DNS environment").pipe( @@ -126,14 +126,12 @@ export const resolve = Effect.fn("resolve")(function* ( }); } - yield* Effect.fork(logEnvironment(hostname)); + yield* Effect.forkChild(logEnvironment(hostname)); - const [excluded, satisfying] = yield* Effect.partition( + const [satisfying, excluded] = yield* Effect.partition( resolvers, Function.identity, - { - concurrency: "unbounded", - }, + { concurrency: "unbounded" }, ); if (satisfying.length === 0) { @@ -141,7 +139,7 @@ export const resolve = Effect.fn("resolve")(function* ( return yield* Effect.failCause( // reduce without default is save here, because we guarantee non empty satisfying array - excluded.map(Cause.fail).reduce(Cause.parallel), + excluded.map(Cause.fail).reduce(Cause.combine), ); } @@ -158,12 +156,11 @@ export const lookup = Effect.fn("lookup")(function* ( catch: (cause) => new DnsError({ cause }), }); - yield* Effect.fork(logEnvironment(hostname)); + yield* Effect.forkChild(logEnvironment(hostname)); // partition into A and AAAA records - const [excluded, satisfying] = Array.partition( - records, - (record) => record.family === 4, + const [satisfying, excluded] = Array.partition(records, (record) => + record.family === 4 ? Result.succeed(record) : Result.fail(record), ); // we cannot determine the TTL of lookup records, therefore we set it to infinity diff --git a/libs/@local/harpc/client/typescript/src/net/internal/multiaddr.ts b/libs/@local/harpc/client/typescript/src/net/internal/multiaddr.ts index 9e2dc9fb612..1413a23acb8 100644 --- a/libs/@local/harpc/client/typescript/src/net/internal/multiaddr.ts +++ b/libs/@local/harpc/client/typescript/src/net/internal/multiaddr.ts @@ -68,7 +68,6 @@ const HashableMultiaddrProto: Omit = { return pipe( Hash.hash(MultiaddrSymbol), Hash.combine(hashUint8Array(this.bytes)), - Hash.cached(this), ); }, }; diff --git a/libs/@local/harpc/client/typescript/src/net/internal/networkLogger.ts b/libs/@local/harpc/client/typescript/src/net/internal/networkLogger.ts index 0c0f2f30628..81a7609853a 100644 --- a/libs/@local/harpc/client/typescript/src/net/internal/networkLogger.ts +++ b/libs/@local/harpc/client/typescript/src/net/internal/networkLogger.ts @@ -105,7 +105,7 @@ const enrichContext = ( ) => { const name = pipe( value?.constructor.name, - Option.fromNullable, + Option.fromNullishOr, Option.map(String.uncapitalize), Option.filter((_) => !Record.has(context, _)), Option.getOrElse(() => `unknown${index}`), @@ -118,7 +118,7 @@ const enrichContext = ( /** @internal */ export const format = ( formatters: FormatterCollection, - level: LogLevel.LogLevel, + level: LogLevel.Severity, input: unknown, args: readonly unknown[], ) => { @@ -167,8 +167,7 @@ export const format = ( const formatOutput = pipe( formatters[token.type], Option.liftPredicate(Predicate.isNotUndefined), - Option.ap(Option.some(argument)), - Option.flatten, + Option.flatMap((formatter) => formatter(argument)), Option.getOrElse(() => "???"), ); @@ -180,12 +179,12 @@ export const format = ( enrichContext(context, i, inputArguments[i]); } - return Effect.logWithLevel(level, output).pipe(Effect.annotateLogs(context)); + return Effect.logWithLevel(level)(output).pipe(Effect.annotateLogs(context)); }; const nonEmptyString = (value?: string) => pipe( - Option.fromNullable(value), + Option.fromNullishOr(value), Option.map(String.trim), Option.filter(String.isNonEmpty), ); diff --git a/libs/@local/harpc/client/typescript/src/net/internal/peerConnection.ts b/libs/@local/harpc/client/typescript/src/net/internal/peerConnection.ts index 6ca84d9bd2a..395a1952f67 100644 --- a/libs/@local/harpc/client/typescript/src/net/internal/peerConnection.ts +++ b/libs/@local/harpc/client/typescript/src/net/internal/peerConnection.ts @@ -126,11 +126,7 @@ const PeerConnectionProto: Omit = { }, [Hash.symbol](this: PeerConnection): number { - return pipe( - Hash.hash(TypeId), - Hash.combine(Hash.string(this.id)), - Hash.cached(this), - ); + return pipe(Hash.hash(TypeId), Hash.combine(Hash.string(this.id))); }, toString(this: PeerConnection) { diff --git a/libs/@local/harpc/client/typescript/src/net/internal/transport.ts b/libs/@local/harpc/client/typescript/src/net/internal/transport.ts index 9fcd100f425..899f429bace 100644 --- a/libs/@local/harpc/client/typescript/src/net/internal/transport.ts +++ b/libs/@local/harpc/client/typescript/src/net/internal/transport.ts @@ -13,10 +13,8 @@ import { import { Array, Cache, - Chunk, Data, Effect, - Either, flow, Match, Option, @@ -122,7 +120,7 @@ const resolveDnsMultiaddrSegment = Effect.fn("resolveDnsMultiaddrSegment")( { type: "AAAA" }, ({ address }) => [IPV6_PROTOCOL.code, address] as const, ), - Match.option, + Match.result, ), ), ); @@ -142,7 +140,7 @@ const resolveDnsMultiaddr = Effect.fn("resolveDnsMultiaddr")( concurrency: "unbounded", }), Stream.runFold( - [] as (number | string | undefined)[][], + (): (number | string | undefined)[][] => [], (accumulator, segments) => { // we basically have a fan out approach here, meaning that if our output is: // ["ip4", "127.0.0.1"], [["ip4", "192.168.178.1"], ["ip6", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"]] [["tcp", "4002"]] @@ -187,11 +185,11 @@ const resolveDnsMultiaddr = Effect.fn("resolveDnsMultiaddr")( const resolveMultiaddr = Effect.fn("resolveMultiaddr")((address: Multiaddr) => pipe( Stream.make(address), - Stream.flatMap((multiaddr) => resolveDnsMultiaddr(multiaddr), { - concurrency: "unbounded", - }), + Stream.flatMap( + (multiaddr) => Stream.fromEffect(resolveDnsMultiaddr(multiaddr)), + { concurrency: "unbounded" }, + ), Stream.runCollect, - Effect.map(Chunk.toReadonlyArray), Effect.map(Array.flatten), ), ); @@ -221,7 +219,7 @@ const lookupPeer = Effect.fn("lookupPeer")(function* ( flow( Struct.get("addresses"), Array.intersectionWith((a, b) => a.equals(b))(resolved), - Array.isNonEmptyArray, + Array.isArrayNonEmpty, ), ), ); @@ -254,20 +252,19 @@ const resolvePeer = Effect.fn("resolvePeer")(function* ( } const key = HashableMultiaddr.make(address); - const peerIdEither = yield* cache.getEither(key); + const isCached = yield* Cache.has(cache, key); + const peerId = yield* Cache.get(cache, key); - if (Either.isLeft(peerIdEither)) { + if (isCached) { yield* Effect.logTrace("retrieved PeerID from cache"); } else { yield* Effect.logTrace("resolved and matched multiaddr to PeerID"); } - const peerId = Either.merge(peerIdEither); - if (Option.isNone(peerId)) { yield* Effect.logDebug("PeerID lookup failed, invalidating cache entry"); - yield* cache.invalidate(key); + yield* Cache.invalidate(cache, key); } return peerId; @@ -342,7 +339,8 @@ export const connect = Effect.fn("connect")(function* ( // We already try to lookup the peer ID before dialing, if it doesn't exist in libp2p, associate the resolved address with the peer ID we just dialed, // this means that the next time we dial the same peer, we can reuse the connection. if (!isPeerId(address)) { - yield* transport.services.state.cache.set( + yield* Cache.set( + transport.services.state.cache, HashableMultiaddr.make(address), Option.some(connection.remotePeer), ); @@ -350,7 +348,8 @@ export const connect = Effect.fn("connect")(function* ( if (!isPeerId(resolved)) { for (const resolvedAddress of resolved) { - yield* transport.services.state.cache.set( + yield* Cache.set( + transport.services.state.cache, HashableMultiaddr.make(resolvedAddress), Option.some(connection.remotePeer), ); diff --git a/libs/@local/harpc/client/typescript/src/types/ErrorCode.ts b/libs/@local/harpc/client/typescript/src/types/ErrorCode.ts index ae92cb974dc..50c6b000ff9 100644 --- a/libs/@local/harpc/client/typescript/src/types/ErrorCode.ts +++ b/libs/@local/harpc/client/typescript/src/types/ErrorCode.ts @@ -1,5 +1,5 @@ import { - type FastCheck, + Arbitrary, Data, Effect, Equal, @@ -8,6 +8,8 @@ import { pipe, Pipeable, Predicate, + type Result, + Schema, } from "effect"; import { MutableBuffer } from "../binary/index.js"; @@ -52,11 +54,7 @@ const ErrorCodeProto: Omit = { }, [Hash.symbol](this: ErrorCode) { - return pipe( - Hash.hash(this[TypeId]), - Hash.combine(Hash.number(this.value)), - Hash.cached(this), - ); + return pipe(Hash.hash(this[TypeId]), Hash.combine(Hash.number(this.value))); }, toString(this: ErrorCode) { @@ -100,7 +98,7 @@ export const make = ( return Effect.succeed(makeUnchecked(value)); }; -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, errorCode: ErrorCode) => MutableBuffer.putU16(buffer, errorCode.value), @@ -111,5 +109,6 @@ export const encode = implEncode((buffer, errorCode: ErrorCode) => export const isErrorCode = (value: unknown): value is ErrorCode => Predicate.hasProperty(value, TypeId); -export const arbitrary = (fc: typeof FastCheck) => - fc.integer({ min: 1, max: U16_MAX }).map(makeUnchecked); +export const arbitrary = Arbitrary.schema( + Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: U16_MAX })), +).pipe(Arbitrary.map(makeUnchecked)); diff --git a/libs/@local/harpc/client/typescript/src/types/ProcedureDescriptor.ts b/libs/@local/harpc/client/typescript/src/types/ProcedureDescriptor.ts index d80ec1d68a5..073fd331ad0 100644 --- a/libs/@local/harpc/client/typescript/src/types/ProcedureDescriptor.ts +++ b/libs/@local/harpc/client/typescript/src/types/ProcedureDescriptor.ts @@ -1,13 +1,12 @@ import { - type FastCheck, - type Effect, - Either, + Arbitrary, Equal, Hash, Inspectable, pipe, Pipeable, Predicate, + Result, } from "effect"; import { createProto, implDecode, implEncode } from "../utils.js"; @@ -37,11 +36,7 @@ const ProcedureDescriptorProto: Omit = { }, [Hash.symbol](this: ProcedureDescriptor) { - return pipe( - Hash.hash(this[TypeId]), - Hash.combine(Hash.hash(this.id)), - Hash.cached(this), - ); + return pipe(Hash.hash(this[TypeId]), Hash.combine(Hash.hash(this.id))); }, toString(this: ProcedureDescriptor) { @@ -68,21 +63,20 @@ const ProcedureDescriptorProto: Omit = { export const make = (id: ProcedureId.ProcedureId): ProcedureDescriptor => createProto(ProcedureDescriptorProto, { id }); -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, descriptor: ProcedureDescriptor) => ProcedureId.encode(buffer, descriptor.id), ); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - ProcedureId.decode(buffer).pipe(Either.map(make)), + ProcedureId.decode(buffer).pipe(Result.map(make)), ); export const isProcedureDescriptor = ( value: unknown, ): value is ProcedureDescriptor => Predicate.hasProperty(value, TypeId); -export const arbitrary = (fc: typeof FastCheck) => - ProcedureId.arbitrary(fc).map(make); +export const arbitrary = ProcedureId.arbitrary.pipe(Arbitrary.map(make)); diff --git a/libs/@local/harpc/client/typescript/src/types/ProcedureId.ts b/libs/@local/harpc/client/typescript/src/types/ProcedureId.ts index 6477ed70e70..38467ad6225 100644 --- a/libs/@local/harpc/client/typescript/src/types/ProcedureId.ts +++ b/libs/@local/harpc/client/typescript/src/types/ProcedureId.ts @@ -1,14 +1,15 @@ import { - type FastCheck, + Arbitrary, Data, Effect, - Either, Equal, Hash, Inspectable, pipe, Pipeable, Predicate, + Result, + Schema, } from "effect"; import { MutableBuffer } from "../binary/index.js"; @@ -55,11 +56,7 @@ const ProcedureIdProto: Omit = { }, [Hash.symbol](this: ProcedureId) { - return pipe( - Hash.hash(this[TypeId]), - Hash.combine(Hash.hash(this.value)), - Hash.cached(this), - ); + return pipe(Hash.hash(this[TypeId]), Hash.combine(Hash.hash(this.value))); }, toString(this: ProcedureId) { @@ -103,16 +100,16 @@ export const make = ( return Effect.succeed(makeUnchecked(id)); }; -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, procedureId: ProcedureId) => MutableBuffer.putU16(buffer, procedureId.value), ); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - MutableBuffer.getU16(buffer).pipe(Either.map(makeUnchecked)), + MutableBuffer.getU16(buffer).pipe(Result.map(makeUnchecked)), ); export const isProcedureId = (value: unknown): value is ProcedureId => @@ -121,5 +118,6 @@ export const isProcedureId = (value: unknown): value is ProcedureId => export const isReserved = (value: ProcedureId) => (value.value & 0xf0_00) === 0xf0_00; -export const arbitrary = (fc: typeof FastCheck) => - fc.integer({ min: U16_MIN, max: U16_MAX }).map(makeUnchecked); +export const arbitrary = Arbitrary.schema( + Schema.Int.check(Schema.isBetween({ minimum: U16_MIN, maximum: U16_MAX })), +).pipe(Arbitrary.map(makeUnchecked)); diff --git a/libs/@local/harpc/client/typescript/src/types/ResponseKind.ts b/libs/@local/harpc/client/typescript/src/types/ResponseKind.ts index dfbf9c1df4d..632a630fe4c 100644 --- a/libs/@local/harpc/client/typescript/src/types/ResponseKind.ts +++ b/libs/@local/harpc/client/typescript/src/types/ResponseKind.ts @@ -1,9 +1,7 @@ /* eslint-disable unicorn/prevent-abbreviations -- same name as Rust reference implementation */ import { - type Effect, - Either, + Arbitrary, Equal, - type FastCheck, Function, Hash, Inspectable, @@ -11,6 +9,8 @@ import { pipe, Pipeable, Predicate, + Result, + Schema, } from "effect"; import { MutableBuffer } from "../binary/index.js"; @@ -41,7 +41,6 @@ const OkProto: Ok = { [Hash.symbol](this: Ok) { return pipe( Hash.hash(this[TypeId]), // - Hash.cached(this), ); }, @@ -86,11 +85,7 @@ const ErrProto: Omit = { }, [Hash.symbol](this: Err) { - return pipe( - Hash.hash(this[TypeId]), - Hash.combine(Hash.hash(this.code)), - Hash.cached(this), - ); + return pipe(Hash.hash(this[TypeId]), Hash.combine(Hash.hash(this.code))); }, toString(this: Err) { @@ -120,7 +115,7 @@ export const err = (code: ErrorCode.ErrorCode): Err => export type ResponseKind = Ok | Err; -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, kind: ResponseKind) => // eslint-disable-next-line @typescript-eslint/no-use-before-define @@ -129,10 +124,10 @@ export const encode = implEncode((buffer, kind: ResponseKind) => : ErrorCode.encode(buffer, kind.code), ); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - Either.gen(function* () { + Result.gen(function* () { const value = yield* MutableBuffer.getU16(buffer); if (value === 0) { @@ -193,5 +188,9 @@ export const getErr = ( onErr: Option.some, }); -export const arbitrary = (fc: typeof FastCheck) => - fc.oneof(fc.constant(ok()), ErrorCode.arbitrary(fc).map(err)); +const arbitraryOk = Arbitrary.Constant(ok()); +const arbitraryErr = ErrorCode.arbitrary.pipe(Arbitrary.map(err)); + +export const arbitrary = Arbitrary.schema(Schema.Boolean).pipe( + Arbitrary.flatMap((pickOk) => (pickOk ? arbitraryOk : arbitraryErr)), +); diff --git a/libs/@local/harpc/client/typescript/src/types/SubsystemDescriptor.ts b/libs/@local/harpc/client/typescript/src/types/SubsystemDescriptor.ts index 1c7c34bea45..706501f81c5 100644 --- a/libs/@local/harpc/client/typescript/src/types/SubsystemDescriptor.ts +++ b/libs/@local/harpc/client/typescript/src/types/SubsystemDescriptor.ts @@ -1,7 +1,5 @@ import { - type FastCheck, - type Effect, - Either, + Arbitrary, Equal, Function, Hash, @@ -9,6 +7,7 @@ import { pipe, Pipeable, Predicate, + Result, } from "effect"; import { createProto, implDecode, implEncode } from "../utils.js"; @@ -46,7 +45,6 @@ const SubsystemDescriptorProto: Omit = { Hash.hash(this[TypeId]), Hash.combine(Hash.hash(this.id)), Hash.combine(Hash.hash(this.version)), - Hash.cached(this), ); }, @@ -78,20 +76,20 @@ export const make = ( ): SubsystemDescriptor => createProto(SubsystemDescriptorProto, { id, version }); -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, descriptor: SubsystemDescriptor) => pipe( buffer, SubsystemId.encode(descriptor.id), - Either.andThen(Version.encode(descriptor.version)), + Result.andThen(Version.encode(descriptor.version)), ), ); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - Either.gen(function* () { + Result.gen(function* () { const id = yield* SubsystemId.decode(buffer); const version = yield* Version.decode(buffer); @@ -103,7 +101,7 @@ export const isSubsystemDescriptor = ( value: unknown, ): value is SubsystemDescriptor => Predicate.hasProperty(value, TypeId); -export const arbitrary = (fc: typeof FastCheck) => - fc - .tuple(SubsystemId.arbitrary(fc), Version.arbitrary(fc)) - .map(Function.tupled(make)); +export const arbitrary = Arbitrary.all([ + SubsystemId.arbitrary, + Version.arbitrary, +]).pipe(Arbitrary.map(Function.tupled(make))); diff --git a/libs/@local/harpc/client/typescript/src/types/SubsystemId.ts b/libs/@local/harpc/client/typescript/src/types/SubsystemId.ts index 9d73d7ea450..c9fc16d8be5 100644 --- a/libs/@local/harpc/client/typescript/src/types/SubsystemId.ts +++ b/libs/@local/harpc/client/typescript/src/types/SubsystemId.ts @@ -1,14 +1,15 @@ import { - type FastCheck, + Arbitrary, Data, Effect, - Either, Equal, Hash, Inspectable, pipe, Pipeable, Predicate, + Result, + Schema, } from "effect"; import { MutableBuffer } from "../binary/index.js"; @@ -55,11 +56,7 @@ const SubsystemIdProto: Omit = { }, [Hash.symbol](this: SubsystemId) { - return pipe( - Hash.hash(this[TypeId]), - Hash.combine(Hash.hash(this.value)), - Hash.cached(this), - ); + return pipe(Hash.hash(this[TypeId]), Hash.combine(Hash.hash(this.value))); }, toString(this: SubsystemId) { @@ -104,16 +101,16 @@ export const make = ( return Effect.succeed(makeUnchecked(id)); }; -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, subsystemId: SubsystemId) => MutableBuffer.putU16(buffer, subsystemId.value), ); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - MutableBuffer.getU16(buffer).pipe(Either.map(makeUnchecked)), + MutableBuffer.getU16(buffer).pipe(Result.map(makeUnchecked)), ); export const isSubsystemId = (value: unknown): value is SubsystemId => @@ -122,5 +119,6 @@ export const isSubsystemId = (value: unknown): value is SubsystemId => export const isReserved = (value: SubsystemId) => (value.value & 0xf0_00) === 0xf0_00; -export const arbitrary = (fc: typeof FastCheck) => - fc.integer({ min: U16_MIN, max: U16_MAX }).map(makeUnchecked); +export const arbitrary = Arbitrary.schema( + Schema.Int.check(Schema.isBetween({ minimum: U16_MIN, maximum: U16_MAX })), +).pipe(Arbitrary.map(makeUnchecked)); diff --git a/libs/@local/harpc/client/typescript/src/types/Version.ts b/libs/@local/harpc/client/typescript/src/types/Version.ts index 2a95391ac88..0f1e2e610b1 100644 --- a/libs/@local/harpc/client/typescript/src/types/Version.ts +++ b/libs/@local/harpc/client/typescript/src/types/Version.ts @@ -1,7 +1,5 @@ import { - type FastCheck, - type Effect, - Either, + Arbitrary, Equal, Function, Hash, @@ -9,6 +7,8 @@ import { pipe, Pipeable, Predicate, + Result, + Schema, } from "effect"; import { MutableBuffer } from "../binary/index.js"; @@ -46,7 +46,6 @@ const VersionProto: Omit = { Hash.hash(this[TypeId]), Hash.combine(Hash.hash(this.major)), Hash.combine(Hash.hash(this.minor)), - Hash.cached(this), ); }, @@ -75,10 +74,10 @@ const VersionProto: Omit = { export const make = (major: number, minor: number): Version => createProto(VersionProto, { major, minor }); -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, version: Version) => - Either.gen(function* () { + Result.gen(function* () { yield* MutableBuffer.putU8(buffer, version.major); yield* MutableBuffer.putU8(buffer, version.minor); @@ -86,10 +85,10 @@ export const encode = implEncode((buffer, version: Version) => }), ); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - Either.gen(function* () { + Result.gen(function* () { const major = yield* MutableBuffer.getU8(buffer); const minor = yield* MutableBuffer.getU8(buffer); @@ -100,10 +99,10 @@ export const decode = implDecode((buffer) => export const isVersion = (value: unknown): value is Version => Predicate.hasProperty(value, TypeId); -export const arbitrary = (fc: typeof FastCheck) => - fc - .tuple( - fc.integer({ min: U8_MIN, max: U8_MAX }), - fc.integer({ min: U8_MIN, max: U8_MAX }), - ) - .map(Function.tupled(make)); +const arbitraryU8 = Arbitrary.schema( + Schema.Int.check(Schema.isBetween({ minimum: U8_MIN, maximum: U8_MAX })), +); + +export const arbitrary = Arbitrary.all([arbitraryU8, arbitraryU8]).pipe( + Arbitrary.map(Function.tupled(make)), +); diff --git a/libs/@local/harpc/client/typescript/src/utils.ts b/libs/@local/harpc/client/typescript/src/utils.ts index e947c37267a..0cd0510e59b 100644 --- a/libs/@local/harpc/client/typescript/src/utils.ts +++ b/libs/@local/harpc/client/typescript/src/utils.ts @@ -1,4 +1,4 @@ -import { Function, Hash, Record, Tuple } from "effect"; +import { Function, Hash, Record } from "effect"; import type { MutableBuffer } from "./binary/index.js"; @@ -36,7 +36,7 @@ export const createProto = < Record.union( readablePropertyDescriptors, writeablePropertyDescriptors, - Function.untupled(Tuple.getFirst), + Function.identity, ), ) as T & Readonly & WriteableProperties; }; diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/RequestIdProducer.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/RequestIdProducer.ts index 8a2ed6c4cad..c7a92150eea 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/RequestIdProducer.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/RequestIdProducer.ts @@ -1,5 +1,4 @@ -import { Effect, Layer, Ref } from "effect"; -import { GenericTag } from "effect/Context"; +import { Context, Effect, Layer, Ref } from "effect"; import { createProto } from "../utils.js"; import * as RequestId from "./models/request/RequestId.js"; @@ -22,7 +21,7 @@ const RequestIdProducerProto: Omit = { [TypeId]: TypeId, }; -export const RequestIdProducer = GenericTag( +export const RequestIdProducer = Context.Service( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- always defined TypeId.description!, ); diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/models/Payload.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/models/Payload.ts index d5d569a2721..30813ec6435 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/models/Payload.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/models/Payload.ts @@ -1,18 +1,19 @@ import { - type FastCheck, + Arbitrary, Data, Effect, - Either, Equal, Hash, Inspectable, pipe, Pipeable, Predicate, + Result, + Schema, } from "effect"; import { MutableBuffer } from "../../binary/index.js"; -import { U16_MAX, U16_MIN } from "../../constants.js"; +import { U16_MAX, U16_MIN, U8_MAX, U8_MIN } from "../../constants.js"; import { createProto, hashUint8Array, @@ -59,7 +60,6 @@ const PayloadProto: Omit = { return pipe( Hash.hash(this[TypeId]), Hash.combine(hashUint8Array(this.buffer)), - Hash.cached(this), ); }, @@ -110,14 +110,14 @@ export const makeAssert = (buffer: Uint8Array) => { return Effect.succeed(makeUnchecked(buffer)); }; -const makeEither = ( +const makeResult = ( buffer: Uint8Array, -): Either.Either => { +): Result.Result => { if (buffer.length > MAX_SIZE) { - return Either.left(new PayloadTooLargeError({ received: buffer.length })); + return Result.fail(new PayloadTooLargeError({ received: buffer.length })); } - return Either.right(makeUnchecked(buffer)); + return Result.succeed(makeUnchecked(buffer)); }; /** @@ -132,12 +132,13 @@ const makeEither = ( */ export const make = ( buffer: Uint8Array, -): Effect.Effect => makeEither(buffer); +): Effect.Effect => + Effect.fromResult(makeResult(buffer)); -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, payload: Payload) => - Either.gen(function* () { + Result.gen(function* () { yield* MutableBuffer.putU16(buffer, payload.buffer.length); yield* MutableBuffer.putSlice(buffer, payload.buffer); @@ -145,23 +146,26 @@ export const encode = implEncode((buffer, payload: Payload) => }), ); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - Either.gen(function* () { + Result.gen(function* () { const length = yield* MutableBuffer.getU16(buffer); const slice = yield* MutableBuffer.getSlice(buffer, length); - return yield* makeEither(slice); + return yield* makeResult(slice); }), ); export const isPayload = (value: unknown): value is Payload => Predicate.hasProperty(value, TypeId); -export const arbitrary = (fc: typeof FastCheck) => - fc - .uint8Array({ minLength: U16_MIN, maxLength: MAX_SIZE }) - // cast needed as fast-check doesn't support Uint8Array yet - .map((array) => array as Uint8Array) - .map(makeUnchecked); +export const arbitrary = Arbitrary.array( + Arbitrary.schema( + Schema.Int.check(Schema.isBetween({ minimum: U8_MIN, maximum: U8_MAX })), + ), + { + minLength: U16_MIN, + maxLength: MAX_SIZE, + }, +).pipe(Arbitrary.map((bytes) => makeUnchecked(Uint8Array.from(bytes)))); diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/models/Protocol.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/models/Protocol.ts index bb901240f55..76826cfe607 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/models/Protocol.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/models/Protocol.ts @@ -1,14 +1,13 @@ import { - type FastCheck, + Arbitrary, Data, - type Effect, - Either, Equal, Hash, Inspectable, pipe, Pipeable, Predicate, + Result, } from "effect"; import { MutableBuffer } from "../../binary/index.js"; @@ -46,11 +45,7 @@ const ProtocolProto: Omit = { }, [Hash.symbol](this: Protocol) { - return pipe( - Hash.hash(this[TypeId]), - Hash.combine(Hash.hash(this.version)), - Hash.cached(this), - ); + return pipe(Hash.hash(this[TypeId]), Hash.combine(Hash.hash(this.version))); }, toString(this: Protocol) { @@ -81,24 +76,24 @@ const MAGIC = new Uint8Array([ 0x68 /* h */, 0x61 /* a */, 0x72 /* r */, 0x70 /* p */, 0x63 /* c */, ]); -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, protocol: Protocol) => pipe( buffer, MutableBuffer.putSlice(MAGIC), - Either.andThen(ProtocolVersion.encode(protocol.version)), + Result.andThen(ProtocolVersion.encode(protocol.version)), ), ); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - Either.gen(function* () { + Result.gen(function* () { const magic = yield* MutableBuffer.getSlice(buffer, 5); if (magic.some((byte, index) => byte !== MAGIC[index])) { - yield* Either.left(new InvalidMagicError({ received: magic })); + yield* Result.fail(new InvalidMagicError({ received: magic })); } const version = yield* ProtocolVersion.decode(buffer); @@ -110,8 +105,4 @@ export const decode = implDecode((buffer) => export const isProtocol = (value: unknown): value is Protocol => Predicate.hasProperty(value, TypeId); -export const arbitrary = (fc: typeof FastCheck) => { - const version = ProtocolVersion.arbitrary(fc); - - return version.map(make); -}; +export const arbitrary = ProtocolVersion.arbitrary.pipe(Arbitrary.map(make)); diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/models/ProtocolVersion.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/models/ProtocolVersion.ts index 269f74dfbb4..e3e5f7be787 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/models/ProtocolVersion.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/models/ProtocolVersion.ts @@ -1,14 +1,13 @@ import { - type FastCheck, + Arbitrary, Data, - type Effect, - Either, Equal, Hash, Inspectable, pipe, Pipeable, Predicate, + Result, } from "effect"; import { MutableBuffer } from "../../binary/index.js"; @@ -45,11 +44,7 @@ const ProtocolVersionProto: Omit = { }, [Hash.symbol](this: ProtocolVersion) { - return pipe( - Hash.hash(this[TypeId]), - Hash.combine(Hash.number(this.value)), - Hash.cached(this), - ); + return pipe(Hash.hash(this[TypeId]), Hash.combine(Hash.number(this.value))); }, toString(this: ProtocolVersion) { @@ -80,14 +75,14 @@ export const encode = implEncode((buffer, version: ProtocolVersion) => MutableBuffer.putU8(buffer, version.value), ); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - Either.gen(function* () { + Result.gen(function* () { const version = yield* MutableBuffer.getU8(buffer); if (version !== 1) { - yield* Either.left( + yield* Result.fail( new InvalidProtocolVersionError({ received: version }), ); } @@ -101,4 +96,4 @@ export const V1: ProtocolVersion = make(1); export const isProtocolVersion = (value: unknown): value is ProtocolVersion => Predicate.hasProperty(value, TypeId); -export const arbitrary = (fc: typeof FastCheck) => fc.oneof(fc.constant(V1)); +export const arbitrary = Arbitrary.Constant(V1); diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/Request.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/Request.ts index 591cef99e6f..5677e8d8e30 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/Request.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/Request.ts @@ -1,7 +1,5 @@ import { - type FastCheck, - type Effect, - Either, + Arbitrary, Equal, Function, Hash, @@ -9,6 +7,7 @@ import { pipe, Pipeable, Predicate, + Result, } from "effect"; import { createProto, implDecode, implEncode } from "../../../utils.js"; @@ -47,7 +46,6 @@ const RequestProto: Omit = { Hash.hash(this[TypeId]), Hash.combine(Hash.hash(this.header)), Hash.combine(Hash.hash(this.body)), - Hash.cached(this), ); }, @@ -92,10 +90,10 @@ export const prepare = (self: Request) => { return make(header, self.body); }; -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, request: Request) => - Either.gen(function* () { + Result.gen(function* () { const variant = RequestBody.variant(request.body); const header = RequestHeader.applyBodyVariant(request.header, variant); @@ -106,10 +104,10 @@ export const encode = implEncode((buffer, request: Request) => }), ); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - Either.gen(function* () { + Result.gen(function* () { const header = yield* RequestHeader.decode(buffer); const isBegin = RequestFlags.isBeginOfRequest(header.flags); @@ -124,7 +122,7 @@ export const decode = implDecode((buffer) => export const isRequest = (value: unknown): value is Request => Predicate.hasProperty(value, TypeId); -export const arbitrary = (fc: typeof FastCheck) => - fc - .tuple(RequestHeader.arbitrary(fc), RequestBody.arbitrary(fc)) - .map(Function.tupled(make)); +export const arbitrary = Arbitrary.all([ + RequestHeader.arbitrary, + RequestBody.arbitrary, +]).pipe(Arbitrary.map(Function.tupled(make))); diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestBegin.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestBegin.ts index 182f484cb74..ed7c9685974 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestBegin.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestBegin.ts @@ -1,7 +1,5 @@ import { - type FastCheck, - type Effect, - Either, + Arbitrary, Equal, Function, Hash, @@ -9,6 +7,7 @@ import { pipe, Pipeable, Predicate, + Result, } from "effect"; import { MutableBuffer } from "../../../binary/index.js"; @@ -55,7 +54,6 @@ const RequestBeginProto: Omit< Hash.combine(Hash.hash(this.subsystem)), Hash.combine(Hash.hash(this.procedure)), Hash.combine(Hash.hash(this.payload)), - Hash.cached(this), ); }, @@ -89,22 +87,22 @@ export const make = ( ): RequestBegin => createProto(RequestBeginProto, { subsystem, procedure, payload }); -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, begin: RequestBegin) => pipe( buffer, SubsystemDescriptor.encode(begin.subsystem), - Either.andThen(ProcedureDescriptor.encode(begin.procedure)), - Either.andThen(MutableBuffer.advance(13)), - Either.andThen(Payload.encode(begin.payload)), + Result.andThen(ProcedureDescriptor.encode(begin.procedure)), + Result.andThen(MutableBuffer.advance(13)), + Result.andThen(Payload.encode(begin.payload)), ), ); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - Either.gen(function* () { + Result.gen(function* () { const subsystem = yield* SubsystemDescriptor.decode(buffer); const procedure = yield* ProcedureDescriptor.decode(buffer); @@ -118,11 +116,8 @@ export const decode = implDecode((buffer) => export const isRequestBegin = (value: unknown): value is RequestBegin => Predicate.hasProperty(value, TypeId); -export const arbitrary = (fc: typeof FastCheck) => - fc - .tuple( - SubsystemDescriptor.arbitrary(fc), - ProcedureDescriptor.arbitrary(fc), - Payload.arbitrary(fc), - ) - .map(Function.tupled(make)); +export const arbitrary = Arbitrary.all([ + SubsystemDescriptor.arbitrary, + ProcedureDescriptor.arbitrary, + Payload.arbitrary, +]).pipe(Arbitrary.map(Function.tupled(make))); diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestBody.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestBody.ts index 84fb47f3e82..cd0ab6f779e 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestBody.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestBody.ts @@ -1,15 +1,15 @@ import { - type FastCheck, - type Option, - type Effect, - Either, + Arbitrary, Equal, Function, Hash, Inspectable, + type Option, pipe, Pipeable, Predicate, + Result, + Schema, } from "effect"; import { createProto, implDecode, implEncode } from "../../../utils.js"; @@ -28,7 +28,7 @@ export interface RequestBody extends Equal.Equal, Inspectable.Inspectable, Pipeable.Pipeable { readonly [TypeId]: TypeId; - readonly body: Either.Either< + readonly body: Result.Result< RequestBegin.RequestBegin, RequestFrame.RequestFrame >; @@ -45,11 +45,7 @@ const RequestBodyProto: Omit = { }, [Hash.symbol](this: RequestBody) { - return pipe( - Hash.hash(this[TypeId]), - Hash.combine(Hash.hash(this.body)), - Hash.cached(this), - ); + return pipe(Hash.hash(this[TypeId]), Hash.combine(Hash.hash(this.body))); }, toString(this: RequestBody) { @@ -74,14 +70,14 @@ const RequestBodyProto: Omit = { }; export const make = ( - body: Either.Either, + body: Result.Result, ): RequestBody => createProto(RequestBodyProto, { body }); export const makeBegin = (begin: RequestBegin.RequestBegin): RequestBody => - make(Either.right(begin)); + make(Result.succeed(begin)); export const makeFrame = (frame: RequestFrame.RequestFrame): RequestBody => - make(Either.left(frame)); + make(Result.fail(frame)); // eslint-disable-next-line fsecond/no-inline-interfaces export const match: { @@ -106,9 +102,9 @@ export const match: { readonly onFrame: (frame: RequestFrame.RequestFrame) => B; }, ) => - Either.match(self.body, { - onLeft: options.onFrame, - onRight: options.onBegin, + Result.match(self.body, { + onFailure: options.onFrame, + onSuccess: options.onBegin, }), ); @@ -139,7 +135,7 @@ export const mapBoth: { }), ); -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, body: RequestBody) => match(body, { @@ -148,7 +144,7 @@ export const encode = implEncode((buffer, body: RequestBody) => }), ); -export type DecodeError = Effect.Effect.Error< +export type DecodeError = Result.Result.Failure< ReturnType> >; @@ -159,14 +155,14 @@ export const decode = (variantHint: RequestBodyVariant) => return pipe( buffer, RequestBegin.decode, - Either.andThen((begin) => make(Either.right(begin))), + Result.andThen((begin) => make(Result.succeed(begin))), ); } case "RequestFrame": { return pipe( buffer, RequestFrame.decode, - Either.andThen((frame) => make(Either.left(frame))), + Result.andThen((frame) => make(Result.fail(frame))), ); } } @@ -181,22 +177,27 @@ export const variant = (body: RequestBody): RequestBodyVariant => export const isRequestBody = (value: unknown): value is RequestBody => Predicate.hasProperty(value, TypeId); -export const isBegin = (value: RequestBody) => Either.isRight(value.body); +export const isBegin = (value: RequestBody) => Result.isSuccess(value.body); -export const isFrame = (value: RequestBody) => Either.isLeft(value.body); +export const isFrame = (value: RequestBody) => Result.isFailure(value.body); export const getBegin = ( body: RequestBody, -): Option.Option => Either.getRight(body.body); +): Option.Option => Result.getSuccess(body.body); export const getFrame = ( body: RequestBody, -): Option.Option => Either.getLeft(body.body); - -export const arbitrary = (fc: typeof FastCheck) => - fc - .oneof( - RequestBegin.arbitrary(fc).map(Either.right), - RequestFrame.arbitrary(fc).map(Either.left), - ) - .map(make); +): Option.Option => Result.getFailure(body.body); + +const arbitraryRequestBegin = RequestBegin.arbitrary.pipe( + Arbitrary.map(makeBegin), +); +const arbitraryRequestFrame = RequestFrame.arbitrary.pipe( + Arbitrary.map(makeFrame), +); + +export const arbitrary = Arbitrary.schema(Schema.Boolean).pipe( + Arbitrary.flatMap((pickBegin) => + pickBegin ? arbitraryRequestBegin : arbitraryRequestFrame, + ), +); diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestFlags.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestFlags.ts index afeabe75e10..1f52f8c2988 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestFlags.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestFlags.ts @@ -1,7 +1,5 @@ import { - type FastCheck, - type Effect, - Either, + Arbitrary, Equal, Hash, HashSet, @@ -9,6 +7,8 @@ import { pipe, Pipeable, Predicate, + Result, + Schema, } from "effect"; import { MutableBuffer } from "../../../binary/index.js"; @@ -44,11 +44,7 @@ const RequestFlagsProto: Omit = { }, [Hash.symbol](this: RequestFlags) { - return pipe( - Hash.hash(this[TypeId]), - Hash.combine(Hash.hash(this.flags)), - Hash.cached(this), - ); + return pipe(Hash.hash(this[TypeId]), Hash.combine(Hash.hash(this.flags))); }, toString(this: RequestFlags) { @@ -105,29 +101,29 @@ export const repr = (flags: RequestFlags) => { return value; }; -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, flags: RequestFlags) => MutableBuffer.putU8(buffer, repr(flags)), ); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - Either.gen(function* () { + Result.gen(function* () { const value = yield* MutableBuffer.getU8(buffer); - const flags = HashSet.empty().pipe(HashSet.beginMutation); + const flags: Flag[] = []; if ((value & 0b1000_0000) === 0b1000_0000) { - HashSet.add(flags, "beginOfRequest"); + flags.push("beginOfRequest"); } if ((value & 0b0000_0001) === 0b0000_0001) { - HashSet.add(flags, "endOfRequest"); + flags.push("endOfRequest"); } - return makeUnchecked(flags.pipe(HashSet.endMutation)); + return makeUnchecked(HashSet.fromIterable(flags)); }), ); @@ -143,9 +139,8 @@ export const isEndOfRequest = (flags: RequestFlags) => export const withEndOfRequest = (flags: RequestFlags) => HashSet.add(flags.flags, "endOfRequest").pipe(makeUnchecked); -export const arbitrary = (fc: typeof FastCheck) => { - return fc - .uniqueArray(fc.constantFrom("beginOfRequest", "endOfRequest")) - .map(HashSet.fromIterable) - .map(makeUnchecked); -}; +export const arbitrary = Arbitrary.schema( + Schema.Array(Schema.Literals(["beginOfRequest", "endOfRequest"])), +).pipe( + Arbitrary.map((flags) => makeUnchecked(HashSet.fromIterable(flags))), +); diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestFrame.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestFrame.ts index fd28d779db9..7aea674e103 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestFrame.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestFrame.ts @@ -1,13 +1,12 @@ import { - type FastCheck, - type Effect, - Either, + Arbitrary, Equal, Hash, Inspectable, pipe, Pipeable, Predicate, + Result, } from "effect"; import { MutableBuffer } from "../../../binary/index.js"; @@ -38,11 +37,7 @@ const RequestFrameProto: Omit = { }, [Hash.symbol](this: RequestFrame) { - return pipe( - Hash.hash(this[TypeId]), - Hash.combine(Hash.hash(this.payload)), - Hash.cached(this), - ); + return pipe(Hash.hash(this[TypeId]), Hash.combine(Hash.hash(this.payload))); }, toString(this: RequestFrame) { @@ -69,20 +64,20 @@ const RequestFrameProto: Omit = { export const make = (payload: Payload.Payload): RequestFrame => createProto(RequestFrameProto, { payload }); -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, frame: RequestFrame) => pipe( buffer, MutableBuffer.advance(19), - Either.andThen(Payload.encode(frame.payload)), + Result.andThen(Payload.encode(frame.payload)), ), ); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - Either.gen(function* () { + Result.gen(function* () { yield* MutableBuffer.advance(buffer, 19); const payload = yield* Payload.decode(buffer); @@ -93,5 +88,4 @@ export const decode = implDecode((buffer) => export const isRequestFrame = (value: unknown): value is RequestFrame => Predicate.hasProperty(value, TypeId); -export const arbitrary = (fc: typeof FastCheck) => - Payload.arbitrary(fc).map(make); +export const arbitrary = Payload.arbitrary.pipe(Arbitrary.map(make)); diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestHeader.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestHeader.ts index 2f2fc325bbb..0b5a3cab2bd 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestHeader.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestHeader.ts @@ -1,7 +1,5 @@ import { - type FastCheck, - type Effect, - Either, + Arbitrary, Equal, Function, Hash, @@ -9,6 +7,7 @@ import { pipe, Pipeable, Predicate, + Result, } from "effect"; import { createProto, implDecode, implEncode } from "../../../utils.js"; @@ -55,7 +54,6 @@ const RequestHeaderProto: Omit< Hash.combine(Hash.hash(this.protocol)), Hash.combine(Hash.hash(this.requestId)), Hash.combine(Hash.hash(this.flags)), - Hash.cached(this), ); }, @@ -99,21 +97,21 @@ export const applyBodyVariant = ( RequestFlags.applyBodyVariant(header.flags, variant), ); -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, header: RequestHeader) => { return pipe( buffer, Protocol.encode(header.protocol), - Either.andThen(RequestId.encode(header.requestId)), - Either.andThen(RequestFlags.encode(header.flags)), + Result.andThen(RequestId.encode(header.requestId)), + Result.andThen(RequestFlags.encode(header.flags)), ); }); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - Either.gen(function* () { + Result.gen(function* () { const protocol = yield* Protocol.decode(buffer); const requestId = yield* RequestId.decode(buffer); const flags = yield* RequestFlags.decode(buffer); @@ -125,11 +123,8 @@ export const decode = implDecode((buffer) => export const isRequestHeader = (value: unknown): value is RequestHeader => Predicate.hasProperty(value, TypeId); -export const arbitrary = (fc: typeof FastCheck) => - fc - .tuple( - Protocol.arbitrary(fc), - RequestId.arbitrary(fc), - RequestFlags.arbitrary(fc), - ) - .map(Function.tupled(make)); +export const arbitrary = Arbitrary.all([ + Protocol.arbitrary, + RequestId.arbitrary, + RequestFlags.arbitrary, +]).pipe(Arbitrary.map(Function.tupled(make))); diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestId.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestId.ts index a3ea9eed763..5436622fe09 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestId.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestId.ts @@ -1,13 +1,13 @@ import { - type FastCheck, - type Effect, + Arbitrary, Equal, Hash, Inspectable, pipe, Pipeable, Predicate, - Either, + Result, + Schema, } from "effect"; import { MutableBuffer } from "../../../binary/index.js"; @@ -38,11 +38,7 @@ const RequestIdProto: Omit = { }, [Hash.symbol](this: RequestId) { - return pipe( - Hash.hash(this[TypeId]), - Hash.combine(Hash.number(this.value)), - Hash.cached(this), - ); + return pipe(Hash.hash(this[TypeId]), Hash.combine(Hash.number(this.value))); }, toString(this: RequestId) { @@ -70,23 +66,26 @@ const RequestIdProto: Omit = { export const makeUnchecked = (value: number): RequestId => createProto(RequestIdProto, { value }); -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, requestId: RequestId) => MutableBuffer.putU32(buffer, requestId.value), ); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => pipe( MutableBuffer.getU32(buffer), // - Either.map(makeUnchecked), + Result.map(makeUnchecked), ), ); export const isRequestId = (value: unknown): value is RequestId => Predicate.hasProperty(value, TypeId); -export const arbitrary = (fc: typeof FastCheck) => - fc.integer({ min: MIN_VALUE, max: MAX_VALUE }).map(makeUnchecked); +export const arbitrary = Arbitrary.schema( + Schema.Int.check( + Schema.isBetween({ minimum: MIN_VALUE, maximum: MAX_VALUE }), + ), +).pipe(Arbitrary.map(makeUnchecked)); diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/Response.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/Response.ts index 49bce956f2c..fb78c9e2e82 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/Response.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/Response.ts @@ -1,7 +1,5 @@ import { - type FastCheck, - type Effect, - Either, + Arbitrary, Equal, Function, Hash, @@ -9,6 +7,7 @@ import { pipe, Pipeable, Predicate, + Result, } from "effect"; import { createProto, implDecode, implEncode } from "../../../utils.js"; @@ -47,7 +46,6 @@ const ResponseProto: Omit = { Hash.hash(this[TypeId]), Hash.combine(Hash.hash(this.header)), Hash.combine(Hash.hash(this.body)), - Hash.cached(this), ); }, @@ -92,10 +90,10 @@ export const prepare = (self: Response) => { return make(header, self.body); }; -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, request: Response) => - Either.gen(function* () { + Result.gen(function* () { const variant = ResponseBody.variant(request.body); const header = ResponseHeader.applyBodyVariant(request.header, variant); @@ -106,10 +104,10 @@ export const encode = implEncode((buffer, request: Response) => }), ); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - Either.gen(function* () { + Result.gen(function* () { const header = yield* ResponseHeader.decode(buffer); const isBegin = ResponseFlags.isBeginOfResponse(header.flags); @@ -124,7 +122,7 @@ export const decode = implDecode((buffer) => export const isResponse = (value: unknown): value is Response => Predicate.hasProperty(value, TypeId); -export const arbitrary = (fc: typeof FastCheck) => - fc - .tuple(ResponseHeader.arbitrary(fc), ResponseBody.arbitrary(fc)) - .map(Function.tupled(make)); +export const arbitrary = Arbitrary.all([ + ResponseHeader.arbitrary, + ResponseBody.arbitrary, +]).pipe(Arbitrary.map(Function.tupled(make))); diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseBegin.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseBegin.ts index 42ca9918930..d6a27e5847d 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseBegin.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseBegin.ts @@ -1,7 +1,5 @@ import { - type FastCheck, - type Effect, - Either, + Arbitrary, Equal, Function, Hash, @@ -9,6 +7,7 @@ import { pipe, Pipeable, Predicate, + Result, } from "effect"; import { MutableBuffer } from "../../../binary/index.js"; @@ -48,7 +47,6 @@ const ResponseBeginProto: Omit = { Hash.hash(this[TypeId]), Hash.combine(Hash.hash(this.kind)), Hash.combine(Hash.hash(this.payload)), - Hash.cached(this), ); }, @@ -79,21 +77,21 @@ export const make = ( payload: Payload.Payload, ): ResponseBegin => createProto(ResponseBeginProto, { kind, payload }); -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, begin: ResponseBegin) => pipe( buffer, MutableBuffer.advance(17), - Either.andThen(ResponseKind.encode(buffer, begin.kind)), - Either.andThen(Payload.encode(begin.payload)), + Result.andThen(ResponseKind.encode(begin.kind)), + Result.andThen(Payload.encode(begin.payload)), ), ); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - Either.gen(function* () { + Result.gen(function* () { yield* MutableBuffer.advance(buffer, 17); const kind = yield* ResponseKind.decode(buffer); const payload = yield* Payload.decode(buffer); @@ -105,10 +103,7 @@ export const decode = implDecode((buffer) => export const isResponseBegin = (value: unknown): value is ResponseBegin => Predicate.hasProperty(value, TypeId); -export const arbitrary = (fc: typeof FastCheck) => - fc - .tuple( - ResponseKind.arbitrary(fc), // - Payload.arbitrary(fc), - ) - .map(Function.tupled(make)); +export const arbitrary = Arbitrary.all([ + ResponseKind.arbitrary, + Payload.arbitrary, +]).pipe(Arbitrary.map(Function.tupled(make))); diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseBody.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseBody.ts index 7a946da1a85..abe798780b2 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseBody.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseBody.ts @@ -1,15 +1,15 @@ import { - type FastCheck, - type Option, - type Effect, - Either, + Arbitrary, Equal, Function, Hash, Inspectable, + type Option, pipe, Pipeable, Predicate, + Result, + Schema, } from "effect"; import { createProto, implDecode, implEncode } from "../../../utils.js"; @@ -28,7 +28,7 @@ export interface ResponseBody extends Equal.Equal, Inspectable.Inspectable, Pipeable.Pipeable { readonly [TypeId]: TypeId; - readonly body: Either.Either< + readonly body: Result.Result< ResponseBegin.ResponseBegin, ResponseFrame.ResponseFrame >; @@ -45,11 +45,7 @@ const ResponseBodyProto: Omit = { }, [Hash.symbol](this: ResponseBody) { - return pipe( - Hash.hash(this[TypeId]), - Hash.combine(Hash.hash(this.body)), - Hash.cached(this), - ); + return pipe(Hash.hash(this[TypeId]), Hash.combine(Hash.hash(this.body))); }, toString(this: ResponseBody) { @@ -74,7 +70,7 @@ const ResponseBodyProto: Omit = { }; export const make = ( - body: Either.Either, + body: Result.Result, ): ResponseBody => createProto(ResponseBodyProto, { body }); // eslint-disable-next-line fsecond/no-inline-interfaces @@ -100,9 +96,9 @@ export const match: { readonly onFrame: (frame: ResponseFrame.ResponseFrame) => B; }, ) => - Either.match(self.body, { - onLeft: options.onFrame, - onRight: options.onBegin, + Result.match(self.body, { + onFailure: options.onFrame, + onSuccess: options.onBegin, }), ); @@ -133,7 +129,7 @@ export const mapBoth: { }), ); -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, body: ResponseBody) => match(body, { @@ -142,7 +138,7 @@ export const encode = implEncode((buffer, body: ResponseBody) => }), ); -export type DecodeError = Effect.Effect.Error< +export type DecodeError = Result.Result.Failure< ReturnType> >; @@ -153,14 +149,14 @@ export const decode = (variantHint: ResponseBodyVariant) => return pipe( buffer, ResponseBegin.decode, - Either.andThen((begin) => make(Either.right(begin))), + Result.andThen((begin) => make(Result.succeed(begin))), ); } case "ResponseFrame": { return pipe( buffer, ResponseFrame.decode, - Either.andThen((frame) => make(Either.left(frame))), + Result.andThen((frame) => make(Result.fail(frame))), ); } } @@ -177,16 +173,21 @@ export const isResponseBody = (value: unknown): value is ResponseBody => export const getBegin = ( body: ResponseBody, -): Option.Option => Either.getRight(body.body); +): Option.Option => Result.getSuccess(body.body); export const getFrame = ( body: ResponseBody, -): Option.Option => Either.getLeft(body.body); - -export const arbitrary = (fc: typeof FastCheck) => - fc - .oneof( - ResponseBegin.arbitrary(fc).map(Either.right), - ResponseFrame.arbitrary(fc).map(Either.left), - ) - .map(make); +): Option.Option => Result.getFailure(body.body); + +const arbitraryBegin = ResponseBegin.arbitrary.pipe( + Arbitrary.map((value) => make(Result.succeed(value))), +); +const arbitraryFrame = ResponseFrame.arbitrary.pipe( + Arbitrary.map((value) => make(Result.fail(value))), +); + +export const arbitrary = Arbitrary.schema(Schema.Boolean).pipe( + Arbitrary.flatMap((pickBegin) => + pickBegin ? arbitraryBegin : arbitraryFrame, + ), +); diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseFlags.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseFlags.ts index 7dd6fe3636c..d09394a992d 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseFlags.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseFlags.ts @@ -1,7 +1,5 @@ import { - type FastCheck, - type Effect, - Either, + Arbitrary, Equal, Hash, HashSet, @@ -9,6 +7,8 @@ import { pipe, Pipeable, Predicate, + Result, + Schema, } from "effect"; import { MutableBuffer } from "../../../binary/index.js"; @@ -43,11 +43,7 @@ const ResponseFlagsProto: Omit = { }, [Hash.symbol](this: ResponseFlags) { - return pipe( - Hash.hash(this[TypeId]), - Hash.combine(Hash.hash(this.flags)), - Hash.cached(this), - ); + return pipe(Hash.hash(this[TypeId]), Hash.combine(Hash.hash(this.flags))); }, toString(this: ResponseFlags) { @@ -102,29 +98,29 @@ export const repr = (flags: ResponseFlags) => { return value; }; -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, flags: ResponseFlags) => MutableBuffer.putU8(buffer, repr(flags)), ); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - Either.gen(function* () { + Result.gen(function* () { const value = yield* MutableBuffer.getU8(buffer); - const flags = HashSet.empty().pipe(HashSet.beginMutation); + const flags: Flag[] = []; if ((value & 0b1000_0000) === 0b1000_0000) { - HashSet.add(flags, "beginOfResponse"); + flags.push("beginOfResponse"); } if ((value & 0b0000_0001) === 0b0000_0001) { - HashSet.add(flags, "endOfResponse"); + flags.push("endOfResponse"); } - return make(flags.pipe(HashSet.endMutation)); + return make(HashSet.fromIterable(flags)); }), ); @@ -137,9 +133,6 @@ export const isBeginOfResponse = (flags: ResponseFlags) => export const isEndOfResponse = (flags: ResponseFlags) => HashSet.has(flags.flags, "endOfResponse"); -export const arbitrary = (fc: typeof FastCheck) => { - return fc - .uniqueArray(fc.constantFrom("beginOfResponse", "endOfResponse")) - .map(HashSet.fromIterable) - .map(make); -}; +export const arbitrary = Arbitrary.schema( + Schema.Array(Schema.Literals(["beginOfResponse", "endOfResponse"])), +).pipe(Arbitrary.map((flags) => make(HashSet.fromIterable(flags)))); diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseFrame.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseFrame.ts index fa943715974..eded59c2248 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseFrame.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseFrame.ts @@ -1,13 +1,12 @@ import { - type FastCheck, - type Effect, - Either, + Arbitrary, Equal, Hash, Inspectable, pipe, Pipeable, Predicate, + Result, } from "effect"; import { MutableBuffer } from "../../../binary/index.js"; @@ -38,11 +37,7 @@ const ResponseFrameProto: Omit = { }, [Hash.symbol](this: ResponseFrame) { - return pipe( - Hash.hash(this[TypeId]), - Hash.combine(Hash.hash(this.payload)), - Hash.cached(this), - ); + return pipe(Hash.hash(this[TypeId]), Hash.combine(Hash.hash(this.payload))); }, toString(this: ResponseFrame) { @@ -69,20 +64,20 @@ const ResponseFrameProto: Omit = { export const make = (payload: Payload.Payload): ResponseFrame => createProto(ResponseFrameProto, { payload }); -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, frame: ResponseFrame) => pipe( buffer, MutableBuffer.advance(19), - Either.andThen(Payload.encode(frame.payload)), + Result.andThen(Payload.encode(frame.payload)), ), ); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - Either.gen(function* () { + Result.gen(function* () { yield* MutableBuffer.advance(buffer, 19); const payload = yield* Payload.decode(buffer); @@ -93,5 +88,4 @@ export const decode = implDecode((buffer) => export const isResponseFrame = (value: unknown): value is ResponseFrame => Predicate.hasProperty(value, TypeId); -export const arbitrary = (fc: typeof FastCheck) => - Payload.arbitrary(fc).map(make); +export const arbitrary = Payload.arbitrary.pipe(Arbitrary.map(make)); diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseHeader.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseHeader.ts index ed949de9f3e..17570a1179b 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseHeader.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseHeader.ts @@ -1,7 +1,5 @@ import { - type FastCheck, - type Effect, - Either, + Arbitrary, Equal, Function, Hash, @@ -9,6 +7,7 @@ import { pipe, Pipeable, Predicate, + Result, } from "effect"; import { createProto, implDecode, implEncode } from "../../../utils.js"; @@ -56,7 +55,6 @@ const ResponseHeaderProto: Omit< Hash.combine(Hash.hash(this.protocol)), Hash.combine(Hash.hash(this.requestId)), Hash.combine(Hash.hash(this.flags)), - Hash.cached(this), ); }, @@ -100,21 +98,21 @@ export const applyBodyVariant = ( ResponseFlags.applyBodyVariant(header.flags, variant), ); -export type EncodeError = Effect.Effect.Error>; +export type EncodeError = Result.Result.Failure>; export const encode = implEncode((buffer, header: ResponseHeader) => { return pipe( buffer, Protocol.encode(header.protocol), - Either.andThen(RequestId.encode(header.requestId)), - Either.andThen(ResponseFlags.encode(header.flags)), + Result.andThen(RequestId.encode(header.requestId)), + Result.andThen(ResponseFlags.encode(header.flags)), ); }); -export type DecodeError = Effect.Effect.Error>; +export type DecodeError = Result.Result.Failure>; export const decode = implDecode((buffer) => - Either.gen(function* () { + Result.gen(function* () { const protocol = yield* Protocol.decode(buffer); const requestId = yield* RequestId.decode(buffer); const flags = yield* ResponseFlags.decode(buffer); @@ -126,11 +124,8 @@ export const decode = implDecode((buffer) => export const isResponseHeader = (value: unknown): value is ResponseHeader => Predicate.hasProperty(value, TypeId); -export const arbitrary = (fc: typeof FastCheck) => - fc - .tuple( - Protocol.arbitrary(fc), - RequestId.arbitrary(fc), - ResponseFlags.arbitrary(fc), - ) - .map(Function.tupled(make)); +export const arbitrary = Arbitrary.all([ + Protocol.arbitrary, + RequestId.arbitrary, + ResponseFlags.arbitrary, +]).pipe(Arbitrary.map(Function.tupled(make))); diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/stream/RequestToBytesStream.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/stream/RequestToBytesStream.ts index e8c891ee854..4eb059faa77 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/stream/RequestToBytesStream.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/stream/RequestToBytesStream.ts @@ -12,7 +12,7 @@ export const make = ( Effect.gen(function* () { const buffer = MutableBuffer.makeWrite(); - yield* Request.encode(buffer, request); + yield* Effect.fromResult(Request.encode(buffer, request)); return MutableBuffer.take(buffer); }), diff --git a/libs/@local/harpc/client/typescript/src/wire-protocol/stream/ResponseFromBytesStream.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/stream/ResponseFromBytesStream.ts index 61c72a93cf1..6aed49ba802 100644 --- a/libs/@local/harpc/client/typescript/src/wire-protocol/stream/ResponseFromBytesStream.ts +++ b/libs/@local/harpc/client/typescript/src/wire-protocol/stream/ResponseFromBytesStream.ts @@ -45,7 +45,7 @@ const tryDecodePacket = Effect.fn("tryDecodePacket")(function* ( // decode the message const reader = MutableBuffer.makeRead(packet); - const response = yield* Response.decode(reader); + const response = yield* Effect.fromResult(Response.decode(reader)); return Option.some(response); }); @@ -97,13 +97,14 @@ export const make = ( return Effect.logTrace(`Received chunk: ${hexView}`); }), - Stream.mapConcatEffect((chunk) => + Stream.mapEffect((chunk) => Effect.gen(function* () { MutableBytes.appendBuffer(scratch, chunk); return yield* tryDecode(scratch); }), ), + Stream.flattenIterable, Stream.concat( Stream.fromIterableEffect( Effect.suspend(() => diff --git a/libs/@local/harpc/client/typescript/tests/binary/MutableBuffer.test.ts b/libs/@local/harpc/client/typescript/tests/binary/MutableBuffer.test.ts index 64166c2572e..cb539990930 100644 --- a/libs/@local/harpc/client/typescript/tests/binary/MutableBuffer.test.ts +++ b/libs/@local/harpc/client/typescript/tests/binary/MutableBuffer.test.ts @@ -1,4 +1,4 @@ -import { Either } from "effect"; +import { Result } from "effect"; import { describe, test, expect } from "vitest"; import { MutableBuffer, MutableBytes } from "../../src/binary/index.js"; @@ -7,7 +7,7 @@ describe("put", () => { test("u8", () => { const buffer = MutableBuffer.makeWrite(); - MutableBuffer.putU8(buffer, 0x04).pipe(Either.getOrThrow); + MutableBuffer.putU8(buffer, 0x04).pipe(Result.getOrThrow); const array = MutableBuffer.take(buffer); @@ -17,7 +17,7 @@ describe("put", () => { test("u16", () => { const buffer = MutableBuffer.makeWrite(); - MutableBuffer.putU16(buffer, 0x04_03).pipe(Either.getOrThrow); + MutableBuffer.putU16(buffer, 0x04_03).pipe(Result.getOrThrow); const array = MutableBuffer.take(buffer); @@ -27,7 +27,7 @@ describe("put", () => { test("u32", () => { const buffer = MutableBuffer.makeWrite(); - MutableBuffer.putU32(buffer, 0x04_03_02_01).pipe(Either.getOrThrow); + MutableBuffer.putU32(buffer, 0x04_03_02_01).pipe(Result.getOrThrow); const array = MutableBuffer.take(buffer); @@ -39,7 +39,7 @@ describe("put", () => { test("i8", () => { const buffer = MutableBuffer.makeWrite(); - MutableBuffer.putI8(buffer, -0x04).pipe(Either.getOrThrow); + MutableBuffer.putI8(buffer, -0x04).pipe(Result.getOrThrow); const array = MutableBuffer.take(buffer); @@ -49,7 +49,7 @@ describe("put", () => { test("i16", () => { const buffer = MutableBuffer.makeWrite(); - MutableBuffer.putI16(buffer, -0x04_03).pipe(Either.getOrThrow); + MutableBuffer.putI16(buffer, -0x04_03).pipe(Result.getOrThrow); const array = MutableBuffer.take(buffer); @@ -59,7 +59,7 @@ describe("put", () => { test("i32", () => { const buffer = MutableBuffer.makeWrite(); - MutableBuffer.putI32(buffer, -0x04_03_02_01).pipe(Either.getOrThrow); + MutableBuffer.putI32(buffer, -0x04_03_02_01).pipe(Result.getOrThrow); const array = MutableBuffer.take(buffer); @@ -72,7 +72,7 @@ describe("put", () => { const buffer = MutableBuffer.makeWrite(); MutableBuffer.putSlice(buffer, new Uint8Array([0x04, 0x03])).pipe( - Either.getOrThrow, + Result.getOrThrow, ); const array = MutableBuffer.take(buffer); @@ -83,11 +83,11 @@ describe("put", () => { test("length", () => { const buffer = MutableBuffer.makeWrite(); - MutableBuffer.putU8(buffer, 0x04).pipe(Either.getOrThrow); + MutableBuffer.putU8(buffer, 0x04).pipe(Result.getOrThrow); expect(MutableBuffer.length(buffer)).toBe(1); - MutableBuffer.putU16(buffer, 0x04_03).pipe(Either.getOrThrow); + MutableBuffer.putU16(buffer, 0x04_03).pipe(Result.getOrThrow); expect(MutableBuffer.length(buffer)).toBe(3); }); @@ -105,55 +105,55 @@ describe("get", () => { MutableBuffer.makeRead(MutableBytes.from(new Uint8Array(elements).buffer)); test("u8", () => { - expect(MutableBuffer.getU8(makeBuffer()).pipe(Either.getOrThrow)).toBe( + expect(MutableBuffer.getU8(makeBuffer()).pipe(Result.getOrThrow)).toBe( 0xff, ); }); test("u16", () => { - expect(MutableBuffer.getU16(makeBuffer()).pipe(Either.getOrThrow)).toBe( + expect(MutableBuffer.getU16(makeBuffer()).pipe(Result.getOrThrow)).toBe( 0xff_fe, ); }); test("u32", () => { - expect(MutableBuffer.getU32(makeBuffer()).pipe(Either.getOrThrow)).toBe( + expect(MutableBuffer.getU32(makeBuffer()).pipe(Result.getOrThrow)).toBe( 0xff_fe_fd_fc, ); }); test("i8", () => { - expect(MutableBuffer.getI8(makeBuffer()).pipe(Either.getOrThrow)).toBe(-1); + expect(MutableBuffer.getI8(makeBuffer()).pipe(Result.getOrThrow)).toBe(-1); }); test("i16", () => { - expect(MutableBuffer.getI16(makeBuffer()).pipe(Either.getOrThrow)).toBe(-2); + expect(MutableBuffer.getI16(makeBuffer()).pipe(Result.getOrThrow)).toBe(-2); }); test("i32", () => { - expect(MutableBuffer.getI32(makeBuffer()).pipe(Either.getOrThrow)).toBe( + expect(MutableBuffer.getI32(makeBuffer()).pipe(Result.getOrThrow)).toBe( -66052, ); }); test("slice", () => { expect( - MutableBuffer.getSlice(makeBuffer(), 2).pipe(Either.getOrThrow), + MutableBuffer.getSlice(makeBuffer(), 2).pipe(Result.getOrThrow), ).toStrictEqual(new Uint8Array([0xff, 0xfe])); }); test("advance", () => { const buffer = makeBuffer(); - MutableBuffer.advance(buffer, 2).pipe(Either.getOrThrow); + MutableBuffer.advance(buffer, 2).pipe(Result.getOrThrow); - expect(MutableBuffer.getU8(buffer).pipe(Either.getOrThrow)).toBe(0xfd); + expect(MutableBuffer.getU8(buffer).pipe(Result.getOrThrow)).toBe(0xfd); }); test("remaining", () => { const buffer = makeBuffer(); - MutableBuffer.advance(buffer, 2).pipe(Either.getOrThrow); + MutableBuffer.advance(buffer, 2).pipe(Result.getOrThrow); expect(MutableBuffer.remaining(buffer)).toBe(254); }); diff --git a/libs/@local/harpc/client/typescript/tests/codec/JsonDecoder.test.ts b/libs/@local/harpc/client/typescript/tests/codec/JsonDecoder.test.ts index 9aefae62415..a9ec5342782 100644 --- a/libs/@local/harpc/client/typescript/tests/codec/JsonDecoder.test.ts +++ b/libs/@local/harpc/client/typescript/tests/codec/JsonDecoder.test.ts @@ -1,13 +1,12 @@ // mirror of the Rust test suite import { describe, it } from "@effect/vitest"; -import { Chunk, Effect, pipe, Schema, Stream } from "effect"; +import { Effect, pipe, Schema, Stream } from "effect"; import { Decoder, JsonDecoder } from "../../src/codec/index.js"; import { expectArrayBuffer } from "../wire-protocol/utils.js"; import type { DecodingError } from "../../src/codec/Decoder.js"; -import type { ParseError } from "effect/ParseResult"; import type * as vitest from "vitest"; const decode = Effect.fn("decode")(function* ( @@ -17,15 +16,14 @@ const decode = Effect.fn("decode")(function* ( const decoder = yield* Decoder.Decoder; const textEncoder = new TextEncoder(); - const schema = Schema.Record({ key: Schema.String, value: Schema.String }); + const schema = Schema.Record(Schema.String, Schema.String); - const effect = Stream.fromChunk(Chunk.fromIterable(text)).pipe( + const effect = Stream.fromArray(text).pipe( Stream.map((input) => expectArrayBuffer(cx, textEncoder.encode(input).buffer), ), decoder.decode(schema), Stream.runCollect, - Effect.map(Chunk.toReadonlyArray), ); // explicit type annotation needed for eslint @@ -90,14 +88,22 @@ describe.concurrent("JsonDecoder", () => { const textPayload = '{"key": "valu\x1E'; // explicit type annotation needed for eslint - const error: DecodingError | ParseError = yield* pipe( + const error: DecodingError | Schema.SchemaError = yield* pipe( decode(cx, [textPayload]), Effect.flip, ); - cx.expect(error.toString()).toMatch( - /Unterminated string in JSON at position 13/, - ); + cx.expect(error).toMatchObject({ + _tag: "DecodingError", + cause: { + _tag: "InvalidJsonError", + cause: { + message: cx.expect.stringMatching( + /Unterminated string in JSON at position 13/, + ), + }, + }, + }); }).pipe(Effect.provide(JsonDecoder.layer)), ); }); diff --git a/libs/@local/harpc/client/typescript/tests/codec/JsonEncoder.test.ts b/libs/@local/harpc/client/typescript/tests/codec/JsonEncoder.test.ts index c6515920aa4..6e1db5bd0ab 100644 --- a/libs/@local/harpc/client/typescript/tests/codec/JsonEncoder.test.ts +++ b/libs/@local/harpc/client/typescript/tests/codec/JsonEncoder.test.ts @@ -1,5 +1,5 @@ import { describe, it } from "@effect/vitest"; -import { Chunk, Effect, pipe, Schema, Stream } from "effect"; +import { Effect, pipe, Schema, Stream } from "effect"; import { Encoder, JsonEncoder } from "../../src/codec/index.js"; @@ -11,14 +11,13 @@ const encode = Effect.fn("encode")(function* ( const encoder = yield* Encoder.Encoder; const textDecoder = new TextDecoder(); - const schema = Schema.Record({ key: Schema.String, value: Schema.String }); + const schema = Schema.Record(Schema.String, Schema.String); return yield* pipe( Stream.fromIterable(items), encoder.encode(schema), Stream.map((buffer) => textDecoder.decode(buffer)), Stream.runCollect, - Effect.map(Chunk.toReadonlyArray), ); }); diff --git a/libs/@local/harpc/client/typescript/tests/net/Connection.test.ts b/libs/@local/harpc/client/typescript/tests/net/Connection.test.ts new file mode 100644 index 00000000000..dbb2ef8bf6d --- /dev/null +++ b/libs/@local/harpc/client/typescript/tests/net/Connection.test.ts @@ -0,0 +1,190 @@ +import { describe, it } from "@effect/vitest"; +import { + Cause, + Effect, + Exit, + HashSet, + pipe, + Queue, + Result, + Sink, + Stream, +} from "effect"; +import { TestClock } from "effect/testing"; + +import { + Connection, + Request, + Transaction, + Transport, +} from "../../src/net/index.js"; +import { + ProcedureDescriptor, + ProcedureId, + ResponseKind, + SubsystemDescriptor, + SubsystemId, + Version, +} from "../../src/types/index.js"; +import { RequestIdProducer } from "../../src/wire-protocol/index.js"; +import { + Payload, + Protocol, + ProtocolVersion, +} from "../../src/wire-protocol/models/index.js"; +import { + Response, + ResponseBegin, + ResponseBody, + ResponseFlags, + ResponseHeader, +} from "../../src/wire-protocol/models/response/index.js"; + +import type { RequestId } from "../../src/wire-protocol/models/request/index.js"; + +const makeConnection = Effect.fn("makeConnection")(function* ( + write: Sink.Sink, + config: Connection.ConnectionConfig = {}, +) { + const responses = yield* Queue.unbounded< + Response.Response, + Transport.TransportError | Cause.Done + >(); + + const connection = yield* Connection.makeFromDuplex( + { read: Stream.fromQueue(responses), write }, + config, + ); + + return { connection, responses }; +}); + +const makeRequest = Effect.fn("makeRequest")(function* () { + return yield* Request.make( + SubsystemDescriptor.make( + yield* SubsystemId.make(0x00), + Version.make(0x00, 0x00), + ), + ProcedureDescriptor.make(yield* ProcedureId.make(0x00)), + Stream.make(new TextEncoder().encode("ping").buffer), + ); +}); + +const makePartialResponse = Effect.fn("makePartialResponse")(function* ( + id: RequestId.RequestId, +) { + const payload = yield* Payload.make(new TextEncoder().encode("partial")); + + return Response.make( + ResponseHeader.make( + Protocol.make(ProtocolVersion.V1), + id, + ResponseFlags.make(HashSet.empty()), + ), + ResponseBody.make( + Result.succeed(ResponseBegin.make(ResponseKind.ok(), payload)), + ), + ); +}); + +const readError = (transaction: Transaction.Transaction) => + pipe( + Transaction.read(transaction).body, + Stream.runDrain, + Effect.exit, + Effect.map((exit) => Exit.isFailure(exit) && Cause.squash(exit.cause)), + ); + +describe.concurrent("Connection", () => { + it.effect("read end", (cx) => + Effect.gen(function* () { + const { connection, responses } = yield* makeConnection(Sink.drain); + const firstRequest = yield* makeRequest(); + const secondRequest = yield* makeRequest(); + const partial = yield* makePartialResponse(firstRequest.id); + + const first = yield* Connection.send(connection, firstRequest); + const second = yield* Connection.send(connection, secondRequest); + + yield* Queue.offer(responses, partial); + yield* Queue.end(responses); + + cx.expect(yield* readError(first)).toBeInstanceOf( + Transaction.ConnectionClosedError, + ); + cx.expect(yield* readError(second)).toBeInstanceOf( + Transaction.ConnectionClosedError, + ); + }).pipe(Effect.provide(RequestIdProducer.layer)), + ); + + it.effect("read failure", (cx) => + Effect.gen(function* () { + const { connection, responses } = yield* makeConnection(Sink.drain); + const request = yield* makeRequest(); + const partial = yield* makePartialResponse(request.id); + const error = new Transport.TransportError({ cause: "reset" }); + + const transaction = yield* Connection.send(connection, request); + + yield* Queue.offer(responses, partial); + yield* Queue.fail(responses, error); + + cx.expect(yield* readError(transaction)).toBe(error); + }).pipe(Effect.provide(RequestIdProducer.layer)), + ); + + it.effect("write failure", (cx) => + Effect.gen(function* () { + const error = new Transport.TransportError({ cause: "closed" }); + const { connection } = yield* makeConnection(Sink.fail(error)); + const request = yield* makeRequest(); + + const transaction = yield* Connection.send(connection, request); + + cx.expect(yield* readError(transaction)).toBe(error); + }).pipe(Effect.provide(RequestIdProducer.layer)), + ); + + it.effect("send after read end", (cx) => + Effect.gen(function* () { + const { connection, responses } = yield* makeConnection(Sink.drain); + const firstRequest = yield* makeRequest(); + const secondRequest = yield* makeRequest(); + + const first = yield* Connection.send(connection, firstRequest); + + yield* Queue.end(responses); + yield* readError(first); + // the read task is still failing open transactions, let it finish + yield* Effect.yieldNow; + + const second = yield* Connection.send(connection, secondRequest); + + cx.expect(yield* readError(second)).toBeInstanceOf( + Transaction.ConnectionClosedError, + ); + }).pipe(Effect.provide(RequestIdProducer.layer)), + ); + + it.effect("lagged", (cx) => + Effect.gen(function* () { + const { connection, responses } = yield* makeConnection(Sink.drain, { + responseBufferSize: 1, + }); + const request = yield* makeRequest(); + const first = yield* makePartialResponse(request.id); + const second = yield* makePartialResponse(request.id); + + const transaction = yield* Connection.send(connection, request); + + // the first response fills the buffer, so the connection waits to deliver the second + yield* Queue.offerAll(responses, [first, second]); + yield* TestClock.adjust("200 millis"); + + cx.expect(yield* readError(transaction)).toBeInstanceOf( + Transaction.TransactionLaggedError, + ); + }).pipe(Effect.provide(RequestIdProducer.layer)), + ); +}); diff --git a/libs/@local/harpc/client/typescript/tests/net/Request.test.ts b/libs/@local/harpc/client/typescript/tests/net/Request.test.ts index a6d7a44d2ff..8d863d6a30f 100644 --- a/libs/@local/harpc/client/typescript/tests/net/Request.test.ts +++ b/libs/@local/harpc/client/typescript/tests/net/Request.test.ts @@ -1,5 +1,5 @@ import { describe, it } from "@effect/vitest"; -import { Chunk, Effect, pipe, Predicate, Stream } from "effect"; +import { Effect, pipe, Predicate, Stream } from "effect"; import { Request } from "../../src/net/index.js"; import { @@ -66,11 +66,7 @@ describe.concurrent("Request", () => { Effect.gen(function* () { const request = yield* makeRequest(Stream.empty); - const items = yield* pipe( - Request.encode(request), - Stream.runCollect, - Effect.map(Chunk.toReadonlyArray), - ); + const items = yield* pipe(Request.encode(request), Stream.runCollect); cx.expect(items.length).toBe(1); assertBody(cx, items[0]!, RequestBody.isBegin, 0); @@ -87,11 +83,7 @@ describe.concurrent("Request", () => { ]), ); - const items = yield* pipe( - Request.encode(request), - Stream.runCollect, - Effect.map(Chunk.toReadonlyArray), - ); + const items = yield* pipe(Request.encode(request), Stream.runCollect); cx.expect(items.length).toBe(1); assertBody(cx, items[0]!, RequestBody.isBegin, "hello").assertEnd(); @@ -104,11 +96,7 @@ describe.concurrent("Request", () => { const request = yield* makeRequest(Stream.fromIterable([array.buffer])); - const items = yield* pipe( - Request.encode(request), - Stream.runCollect, - Effect.map(Chunk.toReadonlyArray), - ); + const items = yield* pipe(Request.encode(request), Stream.runCollect); cx.expect(items.length).toBe(2); assertBody(cx, items[0]!, RequestBody.isBegin, Payload.MAX_SIZE); @@ -127,11 +115,7 @@ describe.concurrent("Request", () => { ]), ); - const items = yield* pipe( - Request.encode(request), - Stream.runCollect, - Effect.map(Chunk.toReadonlyArray), - ); + const items = yield* pipe(Request.encode(request), Stream.runCollect); cx.expect(items.length).toBe(2); assertBody(cx, items[0]!, RequestBody.isBegin, Payload.MAX_SIZE); @@ -145,11 +129,7 @@ describe.concurrent("Request", () => { const request = yield* makeRequest(Stream.fromIterable([array.buffer])); - const items = yield* pipe( - Request.encode(request), - Stream.runCollect, - Effect.map(Chunk.toReadonlyArray), - ); + const items = yield* pipe(Request.encode(request), Stream.runCollect); cx.expect(items.length).toBe(3); assertBody(cx, items[0]!, RequestBody.isBegin, Payload.MAX_SIZE); @@ -169,11 +149,7 @@ describe.concurrent("Request", () => { ]), ); - const items = yield* pipe( - Request.encode(request), - Stream.runCollect, - Effect.map(Chunk.toReadonlyArray), - ); + const items = yield* pipe(Request.encode(request), Stream.runCollect); cx.expect(items.length).toBe(1); assertBody(cx, items[0]!, RequestBody.isBegin, "helloworld").assertEnd(); @@ -189,7 +165,6 @@ describe.concurrent("Request - noDelay", () => { const items = yield* pipe( Request.encode(request, { noDelay: true }), Stream.runCollect, - Effect.map(Chunk.toReadonlyArray), ); cx.expect(items.length).toBe(1); @@ -210,7 +185,6 @@ describe.concurrent("Request - noDelay", () => { const items = yield* pipe( Request.encode(request, { noDelay: true }), Stream.runCollect, - Effect.map(Chunk.toReadonlyArray), ); cx.expect(items.length).toBe(1); @@ -227,7 +201,6 @@ describe.concurrent("Request - noDelay", () => { const items = yield* pipe( Request.encode(request, { noDelay: true }), Stream.runCollect, - Effect.map(Chunk.toReadonlyArray), ); cx.expect(items.length).toBe(2); @@ -245,7 +218,6 @@ describe.concurrent("Request - noDelay", () => { const items = yield* pipe( Request.encode(request, { noDelay: true }), Stream.runCollect, - Effect.map(Chunk.toReadonlyArray), ); cx.expect(items.length).toBe(3); @@ -269,7 +241,6 @@ describe.concurrent("Request - noDelay", () => { const items = yield* pipe( Request.encode(request, { noDelay: true }), Stream.runCollect, - Effect.map(Chunk.toReadonlyArray), ); cx.expect(items.length).toBe(2); diff --git a/libs/@local/harpc/client/typescript/tests/net/Transaction.test.ts b/libs/@local/harpc/client/typescript/tests/net/Transaction.test.ts new file mode 100644 index 00000000000..3efbc974739 --- /dev/null +++ b/libs/@local/harpc/client/typescript/tests/net/Transaction.test.ts @@ -0,0 +1,156 @@ +import { describe, it } from "@effect/vitest"; +import { + Cause, + Deferred, + Effect, + Exit, + HashSet, + pipe, + Queue, + Result, + Stream, +} from "effect"; + +import { Response as NetResponse, Transaction } from "../../src/net/index.js"; +import { ErrorCode, ResponseKind } from "../../src/types/index.js"; +import { + Payload, + Protocol, + ProtocolVersion, +} from "../../src/wire-protocol/models/index.js"; +import { RequestId } from "../../src/wire-protocol/models/request/index.js"; +import { + Response, + ResponseBegin, + ResponseBody, + ResponseFlags, + ResponseFrame, + ResponseHeader, +} from "../../src/wire-protocol/models/response/index.js"; + +const requestId = RequestId.makeUnchecked(1); + +const makeHeader = (endOfResponse: boolean) => + ResponseHeader.make( + Protocol.make(ProtocolVersion.V1), + requestId, + ResponseFlags.make( + HashSet.fromIterable( + endOfResponse ? ["endOfResponse"] : [], + ), + ), + ); + +const makeBegin = Effect.fn("makeBegin")(function* ( + text: string, + endOfResponse: boolean, +) { + const payload = yield* Payload.make(new TextEncoder().encode(text)); + + return Response.make( + makeHeader(endOfResponse), + ResponseBody.make( + Result.succeed(ResponseBegin.make(ResponseKind.ok(), payload)), + ), + ); +}); + +const makeFrame = Effect.fn("makeFrame")(function* ( + text: string, + endOfResponse: boolean, +) { + const payload = yield* Payload.make(new TextEncoder().encode(text)); + + return Response.make( + makeHeader(endOfResponse), + ResponseBody.make(Result.fail(ResponseFrame.make(payload))), + ); +}); + +const makeTransaction = Effect.fn("makeTransaction")(function* () { + const queue = yield* Queue.bounded< + Response.Response, + Transaction.TransactionLaggedError | Cause.Done + >(16); + // eslint-disable-next-line @typescript-eslint/no-invalid-void-type -- the drop handle carries no value + const drop = yield* Deferred.make(); + + return { + queue, + transaction: Transaction.makeUnchecked(requestId, queue, drop), + }; +}); + +const readText = (transaction: Transaction.Transaction) => + pipe( + Transaction.read(transaction).body, + Stream.runCollect, + Effect.map((buffers) => + buffers.map((buffer) => new TextDecoder().decode(buffer)).join(""), + ), + ); + +describe.concurrent("Transaction", () => { + it.effect("multi-packet response", (cx) => + Effect.gen(function* () { + const { queue, transaction } = yield* makeTransaction(); + const first = yield* makeBegin("first ", false); + const second = yield* makeFrame("second ", false); + const third = yield* makeFrame("third", true); + + yield* Queue.offerAll(queue, [first, second, third]); + yield* Queue.end(queue); + + const text = yield* readText(transaction); + + cx.expect(text).toBe("first second third"); + }), + ); + + it.effect("lagged", (cx) => + Effect.gen(function* () { + const { queue, transaction } = yield* makeTransaction(); + const begin = yield* makeBegin("partial", false); + + yield* Queue.offer(queue, begin); + yield* Queue.fail( + queue, + new Transaction.TransactionLaggedError({ id: requestId }), + ); + + const exit = yield* Effect.exit(readText(transaction)); + + cx.expect(Exit.isFailure(exit)).toBeTruthy(); + cx.expect( + Exit.isFailure(exit) && Cause.squash(exit.cause), + ).toBeInstanceOf(Transaction.TransactionLaggedError); + }), + ); + + it.effect("error response", (cx) => + Effect.gen(function* () { + const { queue, transaction } = yield* makeTransaction(); + const payload = yield* Payload.make(new TextEncoder().encode("boom")); + const response = Response.make( + makeHeader(true), + ResponseBody.make( + Result.succeed( + ResponseBegin.make( + ResponseKind.err(ErrorCode.makeUnchecked(1)), + payload, + ), + ), + ), + ); + + yield* Queue.offer(queue, response); + yield* Queue.end(queue); + + const exit = yield* Effect.exit(readText(transaction)); + + cx.expect( + Exit.isFailure(exit) && Cause.squash(exit.cause), + ).toBeInstanceOf(NetResponse.NetworkError); + }), + ); +}); diff --git a/libs/@local/harpc/client/typescript/tests/wire-protocol/codec.bench.ts b/libs/@local/harpc/client/typescript/tests/wire-protocol/codec.bench.ts index 825bbebb5b6..d75e5e305a8 100644 --- a/libs/@local/harpc/client/typescript/tests/wire-protocol/codec.bench.ts +++ b/libs/@local/harpc/client/typescript/tests/wire-protocol/codec.bench.ts @@ -1,63 +1,65 @@ -import { Either, FastCheck, pipe } from "effect"; -import { bench, describe } from "vitest"; +import { Arbitrary, Effect, pipe, Result } from "effect"; +import { describe, test } from "vitest"; -import { MutableBuffer, MutableBytes } from "../../src/binary/index.js"; -import { Request } from "../../src/wire-protocol/models/request/index.js"; -import { Response } from "../../src/wire-protocol/models/response/index.js"; +import { MutableBuffer, MutableBytes } from "@local/harpc-client/binary"; +import { Request } from "@local/harpc-client/wire-protocol/models/request"; +import { Response } from "@local/harpc-client/wire-protocol/models/response"; // using the same seed ensures that the same request is generated -const request = FastCheck.sample(Request.arbitrary(FastCheck), { - seed: 1662493168, - // eslint-disable-next-line unicorn/prevent-abbreviations - numRuns: 1, -}); +const request = await Effect.runPromise( + Arbitrary.sampleEffect(Request.arbitrary, { seed: 1662493168, count: 1 }), +); const requestEncoded = pipe( Request.encode(MutableBuffer.makeWrite(), request[0]!), - Either.andThen(MutableBuffer.take), - Either.getOrThrowWith((error) => { + Result.andThen(MutableBuffer.take), + Result.getOrThrowWith((error) => { return error; }), ); -const response = FastCheck.sample(Response.arbitrary(FastCheck), { - seed: 1662493168, - // eslint-disable-next-line unicorn/prevent-abbreviations - numRuns: 1, -}); +const response = await Effect.runPromise( + Arbitrary.sampleEffect(Response.arbitrary, { seed: 1662493168, count: 1 }), +); const responseEncoded = pipe( Response.encode(MutableBuffer.makeWrite(), response[0]!), - Either.andThen(MutableBuffer.take), - Either.getOrThrowWith((error) => { + Result.andThen(MutableBuffer.take), + Result.getOrThrowWith((error) => { return error; }), ); describe("request", () => { - bench("encode", () => { - Request.encode(MutableBuffer.makeWrite(), request[0]!).pipe( - Either.getOrThrow, - ); - }); + // eslint-disable-next-line vitest/expect-expect + test("codec", async ({ bench }) => { + await bench("encode", () => { + Request.encode(MutableBuffer.makeWrite(), request[0]!).pipe( + Result.getOrThrow, + ); + }).run(); - bench("decode", () => { - const buffer = MutableBuffer.makeRead(MutableBytes.from(requestEncoded)); + await bench("decode", () => { + const buffer = MutableBuffer.makeRead(MutableBytes.from(requestEncoded)); - Request.decode(buffer); + Request.decode(buffer).pipe(Result.getOrThrow); + }).run(); }); }); describe("response", () => { - bench("encode", () => { - Response.encode(MutableBuffer.makeWrite(), response[0]!).pipe( - Either.getOrThrow, - ); - }); + // eslint-disable-next-line vitest/expect-expect + test("codec", async ({ bench }) => { + await bench("encode", () => { + Response.encode(MutableBuffer.makeWrite(), response[0]!).pipe( + Result.getOrThrow, + ); + }).run(); - bench("decode", () => { - const buffer = MutableBuffer.makeRead(MutableBytes.from(responseEncoded)); + await bench("decode", () => { + const buffer = MutableBuffer.makeRead(MutableBytes.from(responseEncoded)); - Response.decode(buffer); + Response.decode(buffer).pipe(Result.getOrThrow); + }).run(); }); }); diff --git a/libs/@local/harpc/client/typescript/tests/wire-protocol/decode.test.ts b/libs/@local/harpc/client/typescript/tests/wire-protocol/decode.test.ts index fce71c6e67b..279dcf35967 100644 --- a/libs/@local/harpc/client/typescript/tests/wire-protocol/decode.test.ts +++ b/libs/@local/harpc/client/typescript/tests/wire-protocol/decode.test.ts @@ -1,6 +1,6 @@ -import { NodeContext } from "@effect/platform-node"; +import * as NodeServices from "@effect/platform-node/NodeServices"; import { describe, it } from "@effect/vitest"; -import { Effect, Equal, Schema } from "effect"; +import { Effect, Equal } from "effect"; import { MutableBuffer, MutableBytes } from "../../src/binary/index.js"; import { ResponseKind } from "../../src/types/index.js"; @@ -14,10 +14,6 @@ import { } from "../../src/wire-protocol/models/response/index.js"; import { callDecode } from "./utils.js"; -const ResponseHeaderFromSelf = Schema.declare(ResponseHeader.isResponseHeader, { - arbitrary: () => ResponseHeader.arbitrary, -}); - interface ResponseHeaderData { protocol: { version: number; @@ -36,10 +32,6 @@ const convertResponseHeader = ( flags: ResponseFlags.repr(header.flags), }); -const ResponseBeginFromSelf = Schema.declare(ResponseBegin.isResponseBegin, { - arbitrary: () => ResponseBegin.arbitrary, -}); - interface ResponseBeginData { kind: "Ok" | { Err: number }; payload: number[]; @@ -56,10 +48,6 @@ const convertResponseBegin = ( payload: [...begin.payload.buffer], }); -const ResponseFrameFromSelf = Schema.declare(ResponseFrame.isResponseFrame, { - arbitrary: () => ResponseFrame.arbitrary, -}); - interface ResponseFrameData { payload: number[]; } @@ -70,10 +58,6 @@ const convertResponseFrame = ( payload: [...frame.payload.buffer], }); -const ResponseFromSelf = Schema.declare(Response.isResponse, { - arbitrary: () => Response.arbitrary, -}); - interface ResponseData { header: ResponseHeaderData; body: { Begin: ResponseBeginData } | { Frame: ResponseFrameData }; @@ -90,7 +74,7 @@ const convertResponse = (response: Response.Response): ResponseData => ({ describe.concurrent("decode", () => { it.effect.prop( "decode response-header", - { header: ResponseHeaderFromSelf }, + { header: ResponseHeader.arbitrary }, ({ header }, cx) => Effect.gen(function* () { const input = convertResponseHeader(header); @@ -98,15 +82,17 @@ describe.concurrent("decode", () => { const array = yield* callDecode("response-header", input); const buffer = MutableBuffer.makeRead(MutableBytes.from(array.buffer)); - const received = yield* ResponseHeader.decode(buffer); + const received = yield* Effect.fromResult( + ResponseHeader.decode(buffer), + ); cx.expect(Equal.equals(received, header)).toBeTruthy(); - }).pipe(Effect.provide(NodeContext.layer)), + }).pipe(Effect.provide(NodeServices.layer)), ); it.effect.prop( "decode response-begin", - { begin: ResponseBeginFromSelf }, + { begin: ResponseBegin.arbitrary }, ({ begin }, cx) => Effect.gen(function* () { const input = convertResponseBegin(begin); @@ -114,15 +100,15 @@ describe.concurrent("decode", () => { const array = yield* callDecode("response-begin", input); const buffer = MutableBuffer.makeRead(MutableBytes.from(array.buffer)); - const received = yield* ResponseBegin.decode(buffer); + const received = yield* Effect.fromResult(ResponseBegin.decode(buffer)); cx.expect(Equal.equals(received, begin)).toBeTruthy(); - }).pipe(Effect.provide(NodeContext.layer)), + }).pipe(Effect.provide(NodeServices.layer)), ); it.effect.prop( "decode response-frame", - { frame: ResponseFrameFromSelf }, + { frame: ResponseFrame.arbitrary }, ({ frame }, cx) => Effect.gen(function* () { const input = convertResponseFrame(frame); @@ -130,15 +116,15 @@ describe.concurrent("decode", () => { const array = yield* callDecode("response-frame", input); const buffer = MutableBuffer.makeRead(MutableBytes.from(array.buffer)); - const received = yield* ResponseFrame.decode(buffer); + const received = yield* Effect.fromResult(ResponseFrame.decode(buffer)); cx.expect(Equal.equals(received, frame)).toBeTruthy(); - }).pipe(Effect.provide(NodeContext.layer)), + }).pipe(Effect.provide(NodeServices.layer)), ); it.effect.prop( "decode response", - { response: ResponseFromSelf }, + { response: Response.arbitrary }, ({ response: rawResponse }, cx) => Effect.gen(function* () { // we first need to make sure that the response is properly formed (this is done either way during the encoding step) @@ -149,9 +135,9 @@ describe.concurrent("decode", () => { const array = yield* callDecode("response", input); const buffer = MutableBuffer.makeRead(MutableBytes.from(array.buffer)); - const received = yield* Response.decode(buffer); + const received = yield* Effect.fromResult(Response.decode(buffer)); cx.expect(Equal.equals(received, response)).toBeTruthy(); - }).pipe(Effect.provide(NodeContext.layer)), + }).pipe(Effect.provide(NodeServices.layer)), ); }); diff --git a/libs/@local/harpc/client/typescript/tests/wire-protocol/encode.test.ts b/libs/@local/harpc/client/typescript/tests/wire-protocol/encode.test.ts index 71187048553..57762b077eb 100644 --- a/libs/@local/harpc/client/typescript/tests/wire-protocol/encode.test.ts +++ b/libs/@local/harpc/client/typescript/tests/wire-protocol/encode.test.ts @@ -1,6 +1,6 @@ -import { NodeContext } from "@effect/platform-node"; +import * as NodeServices from "@effect/platform-node/NodeServices"; import { type TestContext, describe, it } from "@effect/vitest"; -import { Effect, Option, Predicate, Schema } from "effect"; +import { Effect, Option, Predicate } from "effect"; import { MutableBuffer } from "../../src/binary/index.js"; import { @@ -13,10 +13,6 @@ import { } from "../../src/wire-protocol/models/request/index.js"; import { callEncode } from "./utils.js"; -const RequestHeaderFromSelf = Schema.declare(RequestHeader.isRequestHeader, { - arbitrary: () => RequestHeader.arbitrary, -}); - interface RequestHeaderData { protocol: { version: number; @@ -35,10 +31,6 @@ const assertRequestHeader = ( cx.expect(RequestFlags.repr(a.flags)).toBe(b.flags); }; -const RequestBeginFromSelf = Schema.declare(RequestBegin.isRequestBegin, { - arbitrary: () => RequestBegin.arbitrary, -}); - interface RequestBeginData { subsystem: { id: number; @@ -65,10 +57,6 @@ const assertRequestBegin = ( cx.expect([...a.payload.buffer]).toEqual(b.payload); }; -const RequestFrameFromSelf = Schema.declare(RequestFrame.isRequestFrame, { - arbitrary: () => RequestFrame.arbitrary, -}); - interface RequestFrameData { payload: number[]; } @@ -81,10 +69,6 @@ const assertRequestFrame = ( cx.expect([...a.payload.buffer]).toEqual(b.payload); }; -const RequestFromSelf = Schema.declare(Request.isRequest, { - arbitrary: () => Request.arbitrary, -}); - interface RequestData { header: RequestHeaderData; body: { Begin: RequestBeginData } | { Frame: RequestFrameData }; @@ -116,12 +100,12 @@ const assertRequest = (cx: TestContext, a: Request.Request, b: RequestData) => { describe.concurrent("encode", () => { it.effect.prop( "encode request-header", - { header: RequestHeaderFromSelf }, + { header: RequestHeader.arbitrary }, ({ header }, cx) => Effect.gen(function* () { const buffer = MutableBuffer.makeWrite(); - yield* RequestHeader.encode(buffer, header); + yield* Effect.fromResult(RequestHeader.encode(buffer, header)); const array = MutableBuffer.take(buffer); const received = yield* callEncode( @@ -130,17 +114,17 @@ describe.concurrent("encode", () => { ); assertRequestHeader(cx, header, received as RequestHeaderData); - }).pipe(Effect.provide(NodeContext.layer)), + }).pipe(Effect.provide(NodeServices.layer)), ); it.effect.prop( "encode request-begin", - { begin: RequestBeginFromSelf }, + { begin: RequestBegin.arbitrary }, ({ begin }, cx) => Effect.gen(function* () { const buffer = MutableBuffer.makeWrite(); - yield* RequestBegin.encode(buffer, begin); + yield* Effect.fromResult(RequestBegin.encode(buffer, begin)); const array = MutableBuffer.take(buffer); const received = yield* callEncode( @@ -149,17 +133,17 @@ describe.concurrent("encode", () => { ); assertRequestBegin(cx, begin, received as RequestBeginData); - }).pipe(Effect.provide(NodeContext.layer)), + }).pipe(Effect.provide(NodeServices.layer)), ); it.effect.prop( "encode request-frame", - { frame: RequestFrameFromSelf }, + { frame: RequestFrame.arbitrary }, ({ frame }, cx) => Effect.gen(function* () { const buffer = MutableBuffer.makeWrite(); - yield* RequestFrame.encode(buffer, frame); + yield* Effect.fromResult(RequestFrame.encode(buffer, frame)); const array = MutableBuffer.take(buffer); const received = yield* callEncode( @@ -168,22 +152,22 @@ describe.concurrent("encode", () => { ); assertRequestFrame(cx, frame, received as RequestFrameData); - }).pipe(Effect.provide(NodeContext.layer)), + }).pipe(Effect.provide(NodeServices.layer)), ); it.effect.prop( "encode request", - { request: RequestFromSelf }, + { request: Request.arbitrary }, ({ request }, cx) => Effect.gen(function* () { const buffer = MutableBuffer.makeWrite(); - yield* Request.encode(buffer, request); + yield* Effect.fromResult(Request.encode(buffer, request)); const array = MutableBuffer.take(buffer); const received = yield* callEncode("request", new Uint8Array(array)); assertRequest(cx, request, received as RequestData); - }).pipe(Effect.provide(NodeContext.layer)), + }).pipe(Effect.provide(NodeServices.layer)), ); }); diff --git a/libs/@local/harpc/client/typescript/tests/wire-protocol/roundtrip.test.ts b/libs/@local/harpc/client/typescript/tests/wire-protocol/roundtrip.test.ts new file mode 100644 index 00000000000..02e1af8eeac --- /dev/null +++ b/libs/@local/harpc/client/typescript/tests/wire-protocol/roundtrip.test.ts @@ -0,0 +1,25 @@ +import { describe, it } from "@effect/vitest"; +import { Effect, Equal } from "effect"; + +import { MutableBuffer, MutableBytes } from "../../src/binary/index.js"; +import { ResponseBegin } from "../../src/wire-protocol/models/response/index.js"; + +describe.concurrent("roundtrip", () => { + it.effect.prop( + "roundtrip response-begin", + { begin: ResponseBegin.arbitrary }, + ({ begin }, cx) => + Effect.gen(function* () { + const write = MutableBuffer.makeWrite(); + + yield* Effect.fromResult(ResponseBegin.encode(write, begin)); + + const read = MutableBuffer.makeRead( + MutableBytes.from(MutableBuffer.take(write)), + ); + const received = yield* Effect.fromResult(ResponseBegin.decode(read)); + + cx.expect(Equal.equals(received, begin)).toBeTruthy(); + }), + ); +}); diff --git a/libs/@local/harpc/client/typescript/tests/wire-protocol/utils.ts b/libs/@local/harpc/client/typescript/tests/wire-protocol/utils.ts index c6f4624d979..dd35ad383d1 100644 --- a/libs/@local/harpc/client/typescript/tests/wire-protocol/utils.ts +++ b/libs/@local/harpc/client/typescript/tests/wire-protocol/utils.ts @@ -1,5 +1,5 @@ -import { Command, Path } from "@effect/platform"; -import { Effect } from "effect"; +import { Effect, Path } from "effect"; +import { ChildProcess, ChildProcessSpawner } from "effect/process"; import type * as vitest from "vitest"; @@ -34,8 +34,9 @@ export const callEncode = Effect.fn("callEncode")(function* ( const buffer = Buffer.from(encoded); const base64 = buffer.toString("base64"); - const command = Command.make(binary, "encode", mode, base64); - const output = yield* Command.string(command); + const command = ChildProcess.make(binary, ["encode", mode, base64]); + const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; + const output = yield* spawner.string(command); const received = JSON.parse(output) as unknown; @@ -50,8 +51,9 @@ export const callDecode = Effect.fn("callDecode")(function* ( const json = JSON.stringify(payload); - const command = Command.make(binary, "decode", mode, json); - const output = yield* Command.string(command); + const command = ChildProcess.make(binary, ["decode", mode, json]); + const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; + const output = yield* spawner.string(command); // convert base64 to Uint8Array const buffer = Buffer.from(output, "base64"); diff --git a/libs/@local/hash-backend-utils/package.json b/libs/@local/hash-backend-utils/package.json index 9088a0d367e..e1d88f221bb 100644 --- a/libs/@local/hash-backend-utils/package.json +++ b/libs/@local/hash-backend-utils/package.json @@ -84,10 +84,11 @@ "@types/mime-types": "2.1.4", "@types/node": "catalog:", "@types/wait-on": "5.3.4", - "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-istanbul": "catalog:", "eslint": "9.39.4", "rimraf": "6.1.3", "typescript": "catalog:", + "vite": "catalog:", "vitest": "catalog:" } } diff --git a/libs/@local/hash-isomorphic-utils/package.json b/libs/@local/hash-isomorphic-utils/package.json index 4e2b622e5a1..a9c8bee65ef 100644 --- a/libs/@local/hash-isomorphic-utils/package.json +++ b/libs/@local/hash-isomorphic-utils/package.json @@ -72,13 +72,14 @@ "@types/lodash-es": "4.17.12", "@types/node": "catalog:", "@types/pluralize": "0.0.33", - "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-istanbul": "catalog:", "eslint": "9.39.4", "graphql": "16.11.0", "next": "16.4.1", "react": "19.2.6", "rimraf": "6.1.3", "typescript": "catalog:", + "vite": "catalog:", "vitest": "catalog:" } } diff --git a/libs/@local/repo-chores/node/package.json b/libs/@local/repo-chores/node/package.json index 1c97851b9f1..ef9922b82a0 100644 --- a/libs/@local/repo-chores/node/package.json +++ b/libs/@local/repo-chores/node/package.json @@ -39,6 +39,7 @@ "@types/node": "catalog:", "eslint": "9.39.4", "typescript": "catalog:", + "vite": "catalog:", "vitest": "catalog:" } } diff --git a/tests/hash-backend-integration/package.json b/tests/hash-backend-integration/package.json index 74d7c1b81b0..2a7b9f9a6a9 100644 --- a/tests/hash-backend-integration/package.json +++ b/tests/hash-backend-integration/package.json @@ -38,10 +38,11 @@ "@local/tsconfig": "workspace:*", "@tsconfig/bases": "catalog:", "@types/node": "catalog:", - "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-istanbul": "catalog:", "eslint": "9.39.4", "rimraf": "6.1.3", "typescript": "catalog:", + "vite": "catalog:", "vitest": "catalog:" } } diff --git a/yarn.lock b/yarn.lock index 4ef08469f47..bfd9a494e4f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -478,7 +478,7 @@ __metadata: "@types/node": "catalog:" "@types/papaparse": "npm:5.3.16" "@types/sanitize-html": "npm:2.16.0" - "@vitest/coverage-istanbul": "npm:4.1.10" + "@vitest/coverage-istanbul": "catalog:" ajv: "npm:8.18.0" ajv-formats: "npm:3.0.1" cache-manager: "npm:5.7.6" @@ -579,13 +579,13 @@ __metadata: "@types/node": "catalog:" "@types/sanitize-html": "npm:2.16.0" "@types/ws": "npm:8.18.1" - "@vitest/coverage-istanbul": "npm:4.1.10" + "@vitest/coverage-istanbul": "catalog:" agentkeepalive: "npm:4.6.0" app-root-path: "npm:3.1.0" axios: "npm:1.20.0" cors: "npm:2.8.5" dedent: "npm:1.7.0" - effect: "npm:3.21.0" + effect: "npm:4.0.3" eslint: "npm:9.39.4" exponential-backoff: "npm:3.1.3" express: "npm:5.2.0" @@ -615,6 +615,7 @@ __metadata: ts-json-schema-generator: "npm:1.5.1" tsx: "catalog:" typescript: "catalog:" + vite: "catalog:" vitest: "catalog:" wait-on: "npm:9.0.1" ws: "npm:8.21.0" @@ -789,6 +790,7 @@ __metadata: use-font-face-observer: "npm:1.3.0" use-intl: "npm:4.14.9" uuid: "npm:14.0.0" + vite: "catalog:" vitest: "catalog:" wait-on: "npm:9.0.1" web-worker: "npm:1.4.1" @@ -862,7 +864,7 @@ __metadata: "@ai-sdk/openai": "npm:3.0.114" "@ai-sdk/react": "npm:3.0.289" "@ark-ui/react": "npm:5.38.1" - "@fast-check/vitest": "npm:0.4.1" + "@fast-check/vitest": "catalog:" "@flue/sdk": "npm:2.3.0" "@hashintel/brunch-agent": "workspace:*" "@hashintel/ds-components": "workspace:*" @@ -2029,13 +2031,13 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^8.0.0": - version: 8.0.0 - resolution: "@babel/code-frame@npm:8.0.0" +"@babel/code-frame@npm:^8.0.0, @babel/code-frame@npm:^8.0.6": + version: 8.0.6 + resolution: "@babel/code-frame@npm:8.0.6" dependencies: - "@babel/helper-validator-identifier": "npm:^8.0.0" + "@babel/helper-validator-identifier": "npm:^8.0.6" js-tokens: "npm:^10.0.0" - checksum: 10c0/2ea8614018bcd8c86358ab6aa930508115d2205e5e111f736d355b150453818bdf487850f6dec5ec92a10bf27ba4536f4b3b8ad9204514e43d8d68ff2e542443 + checksum: 10c0/ae3022ce1e41a48e367712f32c51736624992c1b87be17714ce0970063935c511bccbea4e005db02cc4da87370b608b5861378fcab86a78c9764fa3bd2b6959a languageName: node linkType: hard @@ -2046,6 +2048,13 @@ __metadata: languageName: node linkType: hard +"@babel/compat-data@npm:^8.0.5": + version: 8.0.5 + resolution: "@babel/compat-data@npm:8.0.5" + checksum: 10c0/53931a4e15538655b2e720098afcc18405abfbc6b8f8df7d85320f3a6193145a3e5b1c87c61218f58fc4bd6c51cea6fa78092ee723e3fb12e089d89802a8a05a + languageName: node + linkType: hard + "@babel/core@npm:7.29.6": version: 7.29.6 resolution: "@babel/core@npm:7.29.6" @@ -2069,7 +2078,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.16.0, @babel/core@npm:^7.18.5, @babel/core@npm:^7.21.3, @babel/core@npm:^7.22.9, @babel/core@npm:^7.23.7, @babel/core@npm:^7.24.4, @babel/core@npm:^7.28.0, @babel/core@npm:^7.28.5, @babel/core@npm:^7.29.0, @babel/core@npm:^7.29.7": +"@babel/core@npm:^7.16.0, @babel/core@npm:^7.18.5, @babel/core@npm:^7.21.3, @babel/core@npm:^7.22.9, @babel/core@npm:^7.23.7, @babel/core@npm:^7.24.4, @babel/core@npm:^7.28.0, @babel/core@npm:^7.28.5, @babel/core@npm:^7.29.7": version: 7.29.7 resolution: "@babel/core@npm:7.29.7" dependencies: @@ -2092,6 +2101,30 @@ __metadata: languageName: node linkType: hard +"@babel/core@npm:^8.0.1": + version: 8.0.9 + resolution: "@babel/core@npm:8.0.9" + dependencies: + "@babel/code-frame": "npm:^8.0.6" + "@babel/generator": "npm:^8.0.6" + "@babel/helper-compilation-targets": "npm:^8.0.7" + "@babel/helpers": "npm:^8.0.8" + "@babel/parser": "npm:^8.0.8" + "@babel/template": "npm:^8.0.0" + "@babel/traverse": "npm:^8.0.7" + "@babel/types": "npm:^8.0.8" + "@types/gensync": "npm:^1.0.5" + convert-source-map: "npm:^2.0.0" + empathic: "npm:^2.0.1" + gensync: "npm:^1.0.0-beta.2" + import-meta-resolve: "npm:^4.2.0" + json5: "npm:^2.2.3" + obug: "npm:^3.0.0" + verkit: "npm:^0.5.0" + checksum: 10c0/8022755a5b8e734d97757637b14c995eb23a09d3722793ae8f46fe25e4a8f8f7224b8508909c7b8c13dfbe53691aed659aa8cbe02141a0555d4623379abbb736 + languageName: node + linkType: hard + "@babel/generator@npm:^7.18.13, @babel/generator@npm:^7.22.9, @babel/generator@npm:^7.28.5, @babel/generator@npm:^7.29.6, @babel/generator@npm:^7.29.7, @babel/generator@npm:^7.29.8": version: 7.29.8 resolution: "@babel/generator@npm:7.29.8" @@ -2105,17 +2138,17 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^8.0.0": - version: 8.0.0 - resolution: "@babel/generator@npm:8.0.0" +"@babel/generator@npm:^8.0.6": + version: 8.0.6 + resolution: "@babel/generator@npm:8.0.6" dependencies: - "@babel/parser": "npm:^8.0.0" - "@babel/types": "npm:^8.0.0" - "@jridgewell/gen-mapping": "npm:^0.3.12" - "@jridgewell/trace-mapping": "npm:^0.3.28" + "@babel/parser": "npm:^8.0.6" + "@babel/types": "npm:^8.0.6" + "@jridgewell/gen-mapping": "npm:0.4.0-beta.0" + "@jridgewell/trace-mapping": "npm:^0.3.31" "@types/jsesc": "npm:^2.5.0" jsesc: "npm:^3.0.2" - checksum: 10c0/2b2d171beaedcacca62164f0f39bc8962df5f9700a54c5515174276ea20b3a53933e9804e0b35c2be1059108a764447d99d0c5beb63ecbbf8c66035ca6c003c4 + checksum: 10c0/ea3b078547815e7ee2a865c9618bbdeaca83961690f036791c05fbdd9a5dbfa0e7bd1dc36434cffba6c8be508297bad798ae47096551a6c38a7ff2e4d139729d languageName: node linkType: hard @@ -2150,6 +2183,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-compilation-targets@npm:^8.0.7": + version: 8.0.7 + resolution: "@babel/helper-compilation-targets@npm:8.0.7" + dependencies: + "@babel/compat-data": "npm:^8.0.5" + "@babel/helper-validator-option": "npm:^8.0.0" + browserslist: "npm:^4.24.0" + flru: "npm:1.0.2" + verkit: "npm:^0.5.0" + checksum: 10c0/09d6c629b09c1c2ff97368ca430f767a581b0e9dbc4df5ba50c632d375aeea96d11e3847088dcbb9c5e478666985cdc6e7edb5d74298dfe153af9da096063a01 + languageName: node + linkType: hard + "@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.21.0, @babel/helper-create-class-features-plugin@npm:^7.25.9, @babel/helper-create-class-features-plugin@npm:^7.27.1, @babel/helper-create-class-features-plugin@npm:^7.28.3, @babel/helper-create-class-features-plugin@npm:^7.28.5": version: 7.28.5 resolution: "@babel/helper-create-class-features-plugin@npm:7.28.5" @@ -2219,10 +2265,10 @@ __metadata: languageName: node linkType: hard -"@babel/helper-globals@npm:^8.0.0": - version: 8.0.0 - resolution: "@babel/helper-globals@npm:8.0.0" - checksum: 10c0/c53a9fcf451df5c8d3aa72f282d1f058e2874e2ccbbdbb5572a805595d75a9355461822d01a6cac3128f5d9ab9a3a99538c6be4ebd728068afb20a65a4d1d986 +"@babel/helper-globals@npm:^8.0.6": + version: 8.0.6 + resolution: "@babel/helper-globals@npm:8.0.6" + checksum: 10c0/feaae266a8f3ef22dfc30659bdc711db7155cf919f2f9fe692cb3b2ae5bf63da88ea341898508eabd95a087d9110ac8b896714aea32a7fa76fd9d0d48964d93f languageName: node linkType: hard @@ -2369,10 +2415,10 @@ __metadata: languageName: node linkType: hard -"@babel/helper-string-parser@npm:^8.0.0": - version: 8.0.0 - resolution: "@babel/helper-string-parser@npm:8.0.0" - checksum: 10c0/b2272a9eaa63a1bc9ce2673d580e69620fd79786f3e3cf1891f406801f8211810f194f2739fef920f01a97ae06ae465b2dfd238ab8037a3182d0869939ca9a5d +"@babel/helper-string-parser@npm:^8.0.8": + version: 8.0.8 + resolution: "@babel/helper-string-parser@npm:8.0.8" + checksum: 10c0/f873560d947c4f4d539cbd31b00cf40f97a18bdeb4d0ae403fabe8f42a1aaba023712b11efa34fe89a6eb9cde9bd8bc2524bb5796f2b62f5be427728fb3597ab languageName: node linkType: hard @@ -2383,10 +2429,10 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^8.0.0, @babel/helper-validator-identifier@npm:^8.0.4": - version: 8.0.4 - resolution: "@babel/helper-validator-identifier@npm:8.0.4" - checksum: 10c0/9d3c639a42b70613016fda026487a3b8056df918cb40221a48ef666a3bd2574475e315ee509c552baef4bef55a627ee8ea530e9af5b376512ab248c37aeab336 +"@babel/helper-validator-identifier@npm:^8.0.6": + version: 8.0.6 + resolution: "@babel/helper-validator-identifier@npm:8.0.6" + checksum: 10c0/9170fe52f3c330945b259cfb5786fb0e1fb4bdafd4deedcb0d3cbe300e993c8df9ca2307734bd3009220799f3053d206557f78d942df0f41e565304e19d2595c languageName: node linkType: hard @@ -2397,6 +2443,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-option@npm:^8.0.0": + version: 8.0.0 + resolution: "@babel/helper-validator-option@npm:8.0.0" + checksum: 10c0/eb466b464479f75c15ba06f6c53862f10d90740350c9203b3d81c6f33d4193bf0a7b7b89de901f256fb639a1346475b48616734af89906d6b4fcf9a856d9f1f1 + languageName: node + linkType: hard + "@babel/helper-wrap-function@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-wrap-function@npm:7.27.1" @@ -2418,6 +2471,16 @@ __metadata: languageName: node linkType: hard +"@babel/helpers@npm:^8.0.8": + version: 8.0.8 + resolution: "@babel/helpers@npm:8.0.8" + dependencies: + "@babel/template": "npm:^8.0.0" + "@babel/types": "npm:^8.0.8" + checksum: 10c0/6fb05cfe61d7f45fd0a69fe1c32988228c56aab431ca2a6750fdae1bb4f7e4aee20c3f6ce26a1718680c9e2ede7649ece6d20d839c012a0b4d00f88adb47d2ae + languageName: node + linkType: hard + "@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.6, @babel/parser@npm:^7.24.4, @babel/parser@npm:^7.28.5, @babel/parser@npm:^7.29.3, @babel/parser@npm:^7.29.7, @babel/parser@npm:^7.29.8": version: 7.29.8 resolution: "@babel/parser@npm:7.29.8" @@ -2429,14 +2492,14 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^8.0.0, @babel/parser@npm:^8.0.4": - version: 8.0.4 - resolution: "@babel/parser@npm:8.0.4" +"@babel/parser@npm:^8.0.0, @babel/parser@npm:^8.0.4, @babel/parser@npm:^8.0.6, @babel/parser@npm:^8.0.7, @babel/parser@npm:^8.0.8": + version: 8.0.8 + resolution: "@babel/parser@npm:8.0.8" dependencies: - "@babel/types": "npm:^8.0.4" + "@babel/types": "npm:^8.0.8" bin: parser: ./bin/babel-parser.js - checksum: 10c0/b98ebc350e6583ccec0c59ab653e6c5967935826b8e03210a96e638a98b0c552587d4ca9cc44502964bac42463e2bab93ca1a6ac519279a25e190bd78f3ce513 + checksum: 10c0/972849212509027148d48d95f2b268abd3d6f72a804ace28fbe09221c1a97686251ba11c19808100169be1e37ba9880f12db980c243f6084eac53b41c44d7a52 languageName: node linkType: hard @@ -3664,18 +3727,18 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^8.0.0": - version: 8.0.4 - resolution: "@babel/traverse@npm:8.0.4" +"@babel/traverse@npm:^8.0.0, @babel/traverse@npm:^8.0.7": + version: 8.0.7 + resolution: "@babel/traverse@npm:8.0.7" dependencies: - "@babel/code-frame": "npm:^8.0.0" - "@babel/generator": "npm:^8.0.0" - "@babel/helper-globals": "npm:^8.0.0" - "@babel/parser": "npm:^8.0.4" + "@babel/code-frame": "npm:^8.0.6" + "@babel/generator": "npm:^8.0.6" + "@babel/helper-globals": "npm:^8.0.6" + "@babel/parser": "npm:^8.0.7" "@babel/template": "npm:^8.0.0" - "@babel/types": "npm:^8.0.4" - obug: "npm:^2.1.1" - checksum: 10c0/0b7917580320c10027f660c97b754f883d11430bd4c9f877b1f57f424f31fd5a1e7260170be08f0197cbcf8abe65078063864e358cf024c90b64504837f3112e + "@babel/types": "npm:^8.0.6" + obug: "npm:^3.0.0" + checksum: 10c0/191367a20371be56cfadac02b2ae3458be2d7bd0a5d66a60f64b3bff81f858f9acea36f2ee454e24f7267101d4787752334b34f2f9e1b23d22f29995452c3040 languageName: node linkType: hard @@ -3689,13 +3752,13 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^8.0.0, @babel/types@npm:^8.0.4": - version: 8.0.4 - resolution: "@babel/types@npm:8.0.4" +"@babel/types@npm:^8.0.0, @babel/types@npm:^8.0.6, @babel/types@npm:^8.0.8": + version: 8.0.8 + resolution: "@babel/types@npm:8.0.8" dependencies: - "@babel/helper-string-parser": "npm:^8.0.0" - "@babel/helper-validator-identifier": "npm:^8.0.4" - checksum: 10c0/c1549372b5544a797c9dd3cfba27c17e0c986cfadb1c4a99246743073e3be99c7c671572326be1739b313a2194e3bfe5a74b1bd213d80c4bbc2c520c8cb4ff1f + "@babel/helper-string-parser": "npm:^8.0.8" + "@babel/helper-validator-identifier": "npm:^8.0.6" + checksum: 10c0/972b46bdbd00f1638689adedd35d63e113f5789a71973f13266856d019d0d8c04921716c4ebad8395418343d54790448c4091e02f109e0c08826ed747bd53f5f languageName: node linkType: hard @@ -3756,13 +3819,6 @@ __metadata: languageName: node linkType: hard -"@blazediff/core@npm:1.9.1": - version: 1.9.1 - resolution: "@blazediff/core@npm:1.9.1" - checksum: 10c0/fd45cdd0544002341d74831a179ef693a81414abd348c1ff0c01086c0ea03f5e5ee284c4e16c2e6fb3670c265f90a3d85752b9360320efa9a835928e604dae77 - languageName: node - linkType: hard - "@blockprotocol/core@npm:0.1.5": version: 0.1.5 resolution: "@blockprotocol/core@npm:0.1.5" @@ -3860,16 +3916,17 @@ __metadata: "@types/node": "catalog:" "@types/react": "npm:19.2.14" "@types/semver": "npm:7.7.1" - "@vitest/coverage-istanbul": "npm:4.1.10" + "@vitest/coverage-istanbul": "catalog:" eslint: "npm:9.39.4" react: "npm:19.2.6" rimraf: "npm:6.1.3" - rolldown: "npm:1.2.6" + rolldown: "catalog:" rolldown-plugin-dts: "npm:0.28.3" semver: "npm:7.7.3" tslib: "npm:2.8.1" typescript: "catalog:" uuid: "npm:14.0.0" + vite: "catalog:" vitest: "catalog:" languageName: unknown linkType: soft @@ -4643,128 +4700,38 @@ __metadata: languageName: node linkType: hard -"@effect/cluster@npm:0.50.6": - version: 0.50.6 - resolution: "@effect/cluster@npm:0.50.6" - peerDependencies: - "@effect/platform": ^0.92.1 - "@effect/rpc": ^0.71.1 - "@effect/sql": ^0.46.0 - "@effect/workflow": ^0.11.5 - effect: ^3.18.4 - checksum: 10c0/56acbe388961b1641c576219de984a926f6e738837c53ccd032d7eccf06cfc506d1b8a87f04e793ea8877597d208e258f8ad59fff1ca566e1ff5ba76e80cfdda - languageName: node - linkType: hard - -"@effect/experimental@npm:0.56.0": - version: 0.56.0 - resolution: "@effect/experimental@npm:0.56.0" - dependencies: - uuid: "npm:^11.0.3" - peerDependencies: - "@effect/platform": ^0.92.0 - effect: ^3.18.0 - ioredis: ^5 - lmdb: ^3 - peerDependenciesMeta: - ioredis: - optional: true - lmdb: - optional: true - checksum: 10c0/0355701bf6bae36947e621649398816de4b07ed5225d8604ce43e0b51da07d65148adb60831fcd03f4baf51f4fd5db22aa4c5651b3a64d6f3b476b32cd15e389 - languageName: node - linkType: hard - -"@effect/platform-node-shared@npm:^0.51.6": - version: 0.51.6 - resolution: "@effect/platform-node-shared@npm:0.51.6" - dependencies: - "@parcel/watcher": "npm:^2.5.1" - multipasta: "npm:^0.2.7" - ws: "npm:^8.18.2" - peerDependencies: - "@effect/cluster": ^0.50.6 - "@effect/platform": ^0.92.1 - "@effect/rpc": ^0.71.1 - "@effect/sql": ^0.46.0 - effect: ^3.18.4 - checksum: 10c0/cd393ae3f93ee0dd8ab6e21d040135dca2f7506e9de98dee5b5ecc96b37c11adc0435ca2233d8a8f858995c042ce3c3e986ca8860a7e982733367621b4fd9300 - languageName: node - linkType: hard - -"@effect/platform-node@npm:0.98.4": - version: 0.98.4 - resolution: "@effect/platform-node@npm:0.98.4" - dependencies: - "@effect/platform-node-shared": "npm:^0.51.6" - mime: "npm:^3.0.0" - undici: "npm:^7.10.0" - ws: "npm:^8.18.2" - peerDependencies: - "@effect/cluster": ^0.50.6 - "@effect/platform": ^0.92.1 - "@effect/rpc": ^0.71.1 - "@effect/sql": ^0.46.0 - effect: ^3.18.4 - checksum: 10c0/38d5ee4b271d6fd3bea8e1781d95c811e66c9e97bb563466d6eb826d43a53d4689eb296288cc7befd0e9aa2a30d8b59beda096bda203c20e91f9d7f3cb2844ab - languageName: node - linkType: hard - -"@effect/platform@npm:0.92.1": - version: 0.92.1 - resolution: "@effect/platform@npm:0.92.1" - dependencies: - find-my-way-ts: "npm:^0.1.6" - msgpackr: "npm:^1.11.4" - multipasta: "npm:^0.2.7" - peerDependencies: - effect: ^3.18.1 - checksum: 10c0/bc2a96704525f5aaaff16edd4d478bade1154192956aa5f86d74ebdcc3a964683ff4ed5bb0c72f998301d8b75ac78e7d21da386f5a6edbb56942279eacd2626d - languageName: node - linkType: hard - -"@effect/rpc@npm:0.71.1": - version: 0.71.1 - resolution: "@effect/rpc@npm:0.71.1" +"@effect/platform-node-shared@npm:^4.0.3": + version: 4.0.3 + resolution: "@effect/platform-node-shared@npm:4.0.3" dependencies: - msgpackr: "npm:^1.11.4" + "@types/ws": "npm:^8.18.2" + ws: "npm:^8.22.0" peerDependencies: - "@effect/platform": ^0.92.1 - effect: ^3.18.4 - checksum: 10c0/7b6c38e3483379bd40d42f4e9e005d59e787f86749578e224978da170353db4da1418824d5c4f881687f30ca1d5d7bc9105e1659d7c645e146212ee75831e9ee + effect: ^4.0.3 + checksum: 10c0/cc33c8f4d32b333555eabc72c58a3273e571ab7db832be503e88ddc30d1293ec4ca91650aa5039e06ef9840ba403aaf3feea81003d6f870c00c8cc5a620a8078 languageName: node linkType: hard -"@effect/sql@npm:0.46.0": - version: 0.46.0 - resolution: "@effect/sql@npm:0.46.0" +"@effect/platform-node@npm:4.0.3": + version: 4.0.3 + resolution: "@effect/platform-node@npm:4.0.3" dependencies: - uuid: "npm:^11.0.3" + "@effect/platform-node-shared": "npm:^4.0.3" + undici: "npm:^8.11.2" peerDependencies: - "@effect/experimental": ^0.56.0 - "@effect/platform": ^0.92.0 - effect: ^3.18.0 - checksum: 10c0/a28382d4d35e30ac917f69b2f7a10567a31084c5285b81d007edb3181791e6013d935d211b132e85bea38075b915fe78e040df4eb8d6da22d1d79dda7eaf02b8 + effect: ^4.0.3 + redis: ">=5.0.0 <7.0.0" + checksum: 10c0/ec17b68e4186c5f681e034344b6ba2e2c098e9f0ac12199e981fd0085206a777daefead03f3a456c1a8bcfb750b5d18762ff19402fbed871907fd94450315aea languageName: node linkType: hard -"@effect/vitest@npm:0.29.0": - version: 0.29.0 - resolution: "@effect/vitest@npm:0.29.0" - peerDependencies: - effect: ^3.21.0 - vitest: ^3.2.0 - checksum: 10c0/fd316009e8bb781ced2268b843b401b71bcf40097ad64536e9f30eb4e8ff130eabefdd575779e5c03fd90fb0df43feaaf5b34b7275e76be8fff08500ada9ffe8 - languageName: node - linkType: hard - -"@effect/vitest@patch:@effect/vitest@npm%3A0.29.0#~/.yarn/patches/@effect-vitest-npm-0.29.0-1c8cf3c306.patch": - version: 0.29.0 - resolution: "@effect/vitest@patch:@effect/vitest@npm%3A0.29.0#~/.yarn/patches/@effect-vitest-npm-0.29.0-1c8cf3c306.patch::version=0.29.0&hash=a9b639" +"@effect/vitest@npm:4.0.3": + version: 4.0.3 + resolution: "@effect/vitest@npm:4.0.3" peerDependencies: - effect: ^3.21.0 - vitest: ^3.2.0 - checksum: 10c0/28127e1aa22928e58c0b09cf0494e38baac3fe0397223273136c78cce6b21650c7f73935e32a05e116d1c10e0b552552011bbe213a67de3975522712690a6e6f + effect: ^4.0.3 + vitest: ">=5.0.0 <6.0.0" + checksum: 10c0/6ab29316e9e05c1c0f5e4cdf495d7b561966cef407d57d1767c02f5d98023253e334f0173082f545edbfb89bbdac566ec6c71ae2fc8af023e0f9ce2224ceba45 languageName: node linkType: hard @@ -5700,14 +5667,14 @@ __metadata: languageName: node linkType: hard -"@fast-check/vitest@npm:0.4.1": - version: 0.4.1 - resolution: "@fast-check/vitest@npm:0.4.1" +"@fast-check/vitest@npm:0.5.0": + version: 0.5.0 + resolution: "@fast-check/vitest@npm:0.5.0" dependencies: fast-check: "npm:^3.0.0 || ^4.0.0" peerDependencies: - vitest: ^4.1.0 - checksum: 10c0/c558f443cbf79cfc18f81372d21129021a13e5d821b57876449d3cac254638ddc5c9736b687fc82dc78f53cf1d948a68787aff7f0d1700704168e1805af088d2 + vitest: ^4.1.0 || ^5.0.0 + checksum: 10c0/f7cfe2c67501fb2d3c10421f7297e80c66ed97224aa32c14b7c4739db0c96aded9c744b3e3ab338e13184e69c470bac90f05657862dc37a90ecef58ffda99124 languageName: node linkType: hard @@ -7006,7 +6973,6 @@ __metadata: "@types/react-dom": "npm:19.2.3" "@typescript/typescript6": "catalog:" "@vitejs/plugin-react": "npm:6.1.1" - "@vitest/browser-playwright": "npm:4.1.11" "@zag-js/dom-query": "npm:1.43.0" case-anything: "npm:3.1.0" colorjs.io: "npm:0.6.1" @@ -7037,7 +7003,6 @@ __metadata: vite: "catalog:" vite-plugin-svgr: "npm:5.2.0" vitest: "catalog:" - vitest-browser-react: "npm:^2.0.2" zod: "npm:4.6.7" peerDependencies: "@ark-ui/react": ^5.38.1 @@ -7071,7 +7036,7 @@ __metadata: oxlint-tsgolint: "npm:7.0.2003" react: "npm:19.2.6" react-dom: "npm:19.2.6" - rolldown: "npm:1.2.6" + rolldown: "catalog:" rolldown-plugin-dts: "npm:0.28.3" typescript: "catalog:" vite: "catalog:" @@ -7113,7 +7078,7 @@ __metadata: oxlint: "npm:1.86.0" oxlint-tsgolint: "npm:7.0.2003" pyodide: "npm:314.0.6" - rolldown: "npm:1.2.6" + rolldown: "catalog:" rolldown-plugin-dts: "npm:0.28.3" typescript: "catalog:" uuid: "npm:14.0.0" @@ -7166,7 +7131,7 @@ __metadata: react: "npm:19.2.6" react-dom: "npm:19.2.6" react-resizable-panels: "npm:4.6.5" - rolldown: "npm:1.2.6" + rolldown: "catalog:" rolldown-plugin-dts: "npm:0.28.3" storybook: "npm:10.6.2" typescript: "catalog:" @@ -7231,7 +7196,7 @@ __metadata: oxlint-tsgolint: "npm:7.0.2003" react: "npm:19.2.6" react-dom: "npm:19.2.6" - rolldown: "npm:1.2.6" + rolldown: "catalog:" rolldown-plugin-dts: "npm:0.28.3" storybook: "npm:10.6.2" typescript: "catalog:" @@ -8197,6 +8162,16 @@ __metadata: languageName: node linkType: hard +"@jridgewell/gen-mapping@npm:0.4.0-beta.0": + version: 0.4.0-beta.0 + resolution: "@jridgewell/gen-mapping@npm:0.4.0-beta.0" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.6.0-beta.0" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10c0/3c8e3d13318cac007834b2ebc065e99574f5d12c1059e7fb58ad50e3b1cc6e422f610e29c2b90afeaad967a0e69503352b8b29b25954985e6bc8dfdb0031d53b + languageName: node + linkType: hard + "@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.13, @jridgewell/gen-mapping@npm:^0.3.2, @jridgewell/gen-mapping@npm:^0.3.5": version: 0.3.13 resolution: "@jridgewell/gen-mapping@npm:0.3.13" @@ -8234,14 +8209,14 @@ __metadata: languageName: node linkType: hard -"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5, @jridgewell/sourcemap-codec@npm:^1.6.0": +"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5, @jridgewell/sourcemap-codec@npm:^1.6.0, @jridgewell/sourcemap-codec@npm:^1.6.0-beta.0": version: 1.6.0 resolution: "@jridgewell/sourcemap-codec@npm:1.6.0" checksum: 10c0/b5be700e45a775f218589c3466c4ffea630582b4988657652da464e5ab8a7d18bf928ee4fd2363fb346ede4bea9c6ff0bae05a538358c4565ece6199531b5f72 languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:0.3.31, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.28": +"@jridgewell/trace-mapping@npm:0.3.31, @jridgewell/trace-mapping@npm:^0.3.23, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.28, @jridgewell/trace-mapping@npm:^0.3.31": version: 0.3.31 resolution: "@jridgewell/trace-mapping@npm:0.3.31" dependencies: @@ -9187,7 +9162,7 @@ __metadata: "@types/node": "catalog:" "@typescript-eslint/eslint-plugin": "npm:8.71.0" "@typescript-eslint/parser": "npm:8.71.0" - effect: "npm:3.21.0" + effect: "npm:4.0.3" eslint: "npm:9.39.4" eslint-config-airbnb: "npm:19.0.4" eslint-config-flat-gitignore: "npm:2.2.1" @@ -9222,6 +9197,7 @@ __metadata: eslint: "npm:9.39.4" rimraf: "npm:6.1.3" typescript: "catalog:" + vite: "catalog:" vitest: "catalog:" languageName: unknown linkType: soft @@ -9252,13 +9228,8 @@ __metadata: dependencies: "@chainsafe/libp2p-noise": "npm:17.0.0" "@chainsafe/libp2p-yamux": "npm:8.0.1" - "@effect/cluster": "npm:0.50.6" - "@effect/experimental": "npm:0.56.0" - "@effect/platform": "npm:0.92.1" - "@effect/platform-node": "npm:0.98.4" - "@effect/rpc": "npm:0.71.1" - "@effect/sql": "npm:0.46.0" - "@effect/vitest": "patch:@effect/vitest@npm%3A0.29.0#~/.yarn/patches/@effect-vitest-npm-0.29.0-1c8cf3c306.patch" + "@effect/platform-node": "npm:4.0.3" + "@effect/vitest": "npm:4.0.3" "@libp2p/crypto": "npm:5.1.23" "@libp2p/identify": "npm:4.1.14" "@libp2p/interface": "npm:3.3.0" @@ -9270,8 +9241,8 @@ __metadata: "@multiformats/multiaddr": "npm:13.0.3" "@tsconfig/bases": "catalog:" "@types/node": "catalog:" - "@vitest/coverage-istanbul": "npm:4.1.10" - effect: "npm:3.21.0" + "@vitest/coverage-istanbul": "catalog:" + effect: "npm:4.0.3" eslint: "npm:9.39.4" it-stream-types: "npm:2.0.2" libp2p: "npm:3.3.11" @@ -9279,6 +9250,7 @@ __metadata: rimraf: "npm:6.1.3" typescript: "catalog:" uint8arraylist: "npm:3.0.2" + vite: "catalog:" vitest: "catalog:" languageName: unknown linkType: soft @@ -9333,7 +9305,7 @@ __metadata: "@types/mime-types": "npm:2.1.4" "@types/node": "catalog:" "@types/wait-on": "npm:5.3.4" - "@vitest/coverage-istanbul": "npm:4.1.10" + "@vitest/coverage-istanbul": "catalog:" agentkeepalive: "npm:4.6.0" axios: "npm:1.20.0" cache-manager: "npm:5.7.6" @@ -9347,6 +9319,7 @@ __metadata: rimraf: "npm:6.1.3" typescript: "catalog:" uuid: "npm:14.0.0" + vite: "catalog:" vitest: "catalog:" wait-on: "npm:9.0.1" winston: "npm:3.18.3" @@ -9408,12 +9381,13 @@ __metadata: "@local/tsconfig": "workspace:*" "@temporalio/client": "npm:1.20.2" "@tsconfig/bases": "catalog:" - "@vitest/coverage-istanbul": "npm:4.1.10" - effect: "npm:3.21.0" + "@vitest/coverage-istanbul": "catalog:" + effect: "npm:4.0.3" eslint: "npm:9.39.4" rimraf: "npm:6.1.3" typescript: "catalog:" uuid: "npm:14.0.0" + vite: "catalog:" vitest: "catalog:" languageName: unknown linkType: soft @@ -9461,7 +9435,7 @@ __metadata: "@types/lodash-es": "npm:4.17.12" "@types/node": "catalog:" "@types/pluralize": "npm:0.0.33" - "@vitest/coverage-istanbul": "npm:4.1.10" + "@vitest/coverage-istanbul": "catalog:" big.js: "npm:7.0.1" eslint: "npm:9.39.4" express: "npm:5.2.0" @@ -9487,6 +9461,7 @@ __metadata: tsx: "catalog:" typescript: "catalog:" uuid: "npm:14.0.0" + vite: "catalog:" vitest: "catalog:" zod: "npm:4.6.7" languageName: unknown @@ -9557,6 +9532,7 @@ __metadata: tinyglobby: "npm:0.2.17" tsx: "catalog:" typescript: "catalog:" + vite: "catalog:" vitest: "catalog:" zod: "npm:4.6.7" languageName: unknown @@ -11087,17 +11063,10 @@ __metadata: languageName: node linkType: hard -"@oxc-project/types@npm:=0.147.0": - version: 0.147.0 - resolution: "@oxc-project/types@npm:0.147.0" - checksum: 10c0/adec7c1d4c0a031a83afe976884695ff1467987da3f9e775d24bd596ca82346d3734cc9898f5645955050246a13621b4442696753a2d83d2954127fbdfbd5a5f - languageName: node - linkType: hard - -"@oxc-project/types@npm:=0.154.0": - version: 0.154.0 - resolution: "@oxc-project/types@npm:0.154.0" - checksum: 10c0/fa91599d087ea4d37c5a3b40dd8e2cb431a7d37730116069f2577dee0b104dc5abb06c96b931c517c8b86f618df1e0c7a37d24086f3cfe39d81eb6db59e70add +"@oxc-project/types@npm:=0.155.0": + version: 0.155.0 + resolution: "@oxc-project/types@npm:0.155.0" + checksum: 10c0/07227fb2c2e03b07453129f2407b49b165eadaa679a34dad68e0b0526420506cea223431807983413f6968053de873c13b05d3978a9a43cabb3999ca97ba2ec5 languageName: node linkType: hard @@ -12063,7 +12032,7 @@ __metadata: languageName: node linkType: hard -"@parcel/watcher@npm:^2.4.1, @parcel/watcher@npm:^2.5.1": +"@parcel/watcher@npm:^2.4.1": version: 2.5.1 resolution: "@parcel/watcher@npm:2.5.1" dependencies: @@ -13670,212 +13639,107 @@ __metadata: languageName: node linkType: hard -"@rolldown/binding-android-arm-eabi@npm:1.2.14": - version: 1.2.14 - resolution: "@rolldown/binding-android-arm-eabi@npm:1.2.14" +"@rolldown/binding-android-arm-eabi@npm:1.2.15": + version: 1.2.15 + resolution: "@rolldown/binding-android-arm-eabi@npm:1.2.15" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rolldown/binding-android-arm-eabi@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-android-arm-eabi@npm:1.2.6" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - -"@rolldown/binding-android-arm64@npm:1.2.14": - version: 1.2.14 - resolution: "@rolldown/binding-android-arm64@npm:1.2.14" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - -"@rolldown/binding-android-arm64@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-android-arm64@npm:1.2.6" +"@rolldown/binding-android-arm64@npm:1.2.15": + version: 1.2.15 + resolution: "@rolldown/binding-android-arm64@npm:1.2.15" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rolldown/binding-darwin-arm64@npm:1.2.14": - version: 1.2.14 - resolution: "@rolldown/binding-darwin-arm64@npm:1.2.14" +"@rolldown/binding-darwin-arm64@npm:1.2.15": + version: 1.2.15 + resolution: "@rolldown/binding-darwin-arm64@npm:1.2.15" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rolldown/binding-darwin-arm64@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-darwin-arm64@npm:1.2.6" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@rolldown/binding-darwin-x64@npm:1.2.14": - version: 1.2.14 - resolution: "@rolldown/binding-darwin-x64@npm:1.2.14" +"@rolldown/binding-darwin-x64@npm:1.2.15": + version: 1.2.15 + resolution: "@rolldown/binding-darwin-x64@npm:1.2.15" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rolldown/binding-darwin-x64@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-darwin-x64@npm:1.2.6" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@rolldown/binding-freebsd-x64@npm:1.2.14": - version: 1.2.14 - resolution: "@rolldown/binding-freebsd-x64@npm:1.2.14" +"@rolldown/binding-freebsd-x64@npm:1.2.15": + version: 1.2.15 + resolution: "@rolldown/binding-freebsd-x64@npm:1.2.15" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@rolldown/binding-freebsd-x64@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-freebsd-x64@npm:1.2.6" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@rolldown/binding-linux-arm-gnueabihf@npm:1.2.14": - version: 1.2.14 - resolution: "@rolldown/binding-linux-arm-gnueabihf@npm:1.2.14" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"@rolldown/binding-linux-arm-gnueabihf@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-linux-arm-gnueabihf@npm:1.2.6" +"@rolldown/binding-linux-arm-gnueabihf@npm:1.2.15": + version: 1.2.15 + resolution: "@rolldown/binding-linux-arm-gnueabihf@npm:1.2.15" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@rolldown/binding-linux-arm64-gnu@npm:1.2.14": - version: 1.2.14 - resolution: "@rolldown/binding-linux-arm64-gnu@npm:1.2.14" +"@rolldown/binding-linux-arm64-gnu@npm:1.2.15": + version: 1.2.15 + resolution: "@rolldown/binding-linux-arm64-gnu@npm:1.2.15" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rolldown/binding-linux-arm64-gnu@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-linux-arm64-gnu@npm:1.2.6" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@rolldown/binding-linux-arm64-musl@npm:1.2.14": - version: 1.2.14 - resolution: "@rolldown/binding-linux-arm64-musl@npm:1.2.14" +"@rolldown/binding-linux-arm64-musl@npm:1.2.15": + version: 1.2.15 + resolution: "@rolldown/binding-linux-arm64-musl@npm:1.2.15" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rolldown/binding-linux-arm64-musl@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-linux-arm64-musl@npm:1.2.6" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@rolldown/binding-linux-ppc64-gnu@npm:1.2.14": - version: 1.2.14 - resolution: "@rolldown/binding-linux-ppc64-gnu@npm:1.2.14" - conditions: os=linux & cpu=ppc64 & libc=glibc - languageName: node - linkType: hard - -"@rolldown/binding-linux-ppc64-gnu@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-linux-ppc64-gnu@npm:1.2.6" +"@rolldown/binding-linux-ppc64-gnu@npm:1.2.15": + version: 1.2.15 + resolution: "@rolldown/binding-linux-ppc64-gnu@npm:1.2.15" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rolldown/binding-linux-s390x-gnu@npm:1.2.14": - version: 1.2.14 - resolution: "@rolldown/binding-linux-s390x-gnu@npm:1.2.14" +"@rolldown/binding-linux-s390x-gnu@npm:1.2.15": + version: 1.2.15 + resolution: "@rolldown/binding-linux-s390x-gnu@npm:1.2.15" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@rolldown/binding-linux-s390x-gnu@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-linux-s390x-gnu@npm:1.2.6" - conditions: os=linux & cpu=s390x & libc=glibc - languageName: node - linkType: hard - -"@rolldown/binding-linux-x64-gnu@npm:1.2.14": - version: 1.2.14 - resolution: "@rolldown/binding-linux-x64-gnu@npm:1.2.14" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@rolldown/binding-linux-x64-gnu@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-linux-x64-gnu@npm:1.2.6" +"@rolldown/binding-linux-x64-gnu@npm:1.2.15": + version: 1.2.15 + resolution: "@rolldown/binding-linux-x64-gnu@npm:1.2.15" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rolldown/binding-linux-x64-musl@npm:1.2.14": - version: 1.2.14 - resolution: "@rolldown/binding-linux-x64-musl@npm:1.2.14" +"@rolldown/binding-linux-x64-musl@npm:1.2.15": + version: 1.2.15 + resolution: "@rolldown/binding-linux-x64-musl@npm:1.2.15" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rolldown/binding-linux-x64-musl@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-linux-x64-musl@npm:1.2.6" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@rolldown/binding-openharmony-arm64@npm:1.2.14": - version: 1.2.14 - resolution: "@rolldown/binding-openharmony-arm64@npm:1.2.14" +"@rolldown/binding-openharmony-arm64@npm:1.2.15": + version: 1.2.15 + resolution: "@rolldown/binding-openharmony-arm64@npm:1.2.15" conditions: os=openharmony & cpu=arm64 languageName: node linkType: hard -"@rolldown/binding-openharmony-arm64@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-openharmony-arm64@npm:1.2.6" - conditions: os=openharmony & cpu=arm64 - languageName: node - linkType: hard - -"@rolldown/binding-win32-arm64-msvc@npm:1.2.14": - version: 1.2.14 - resolution: "@rolldown/binding-win32-arm64-msvc@npm:1.2.14" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@rolldown/binding-win32-arm64-msvc@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-win32-arm64-msvc@npm:1.2.6" +"@rolldown/binding-win32-arm64-msvc@npm:1.2.15": + version: 1.2.15 + resolution: "@rolldown/binding-win32-arm64-msvc@npm:1.2.15" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rolldown/binding-win32-x64-msvc@npm:1.2.14": - version: 1.2.14 - resolution: "@rolldown/binding-win32-x64-msvc@npm:1.2.14" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@rolldown/binding-win32-x64-msvc@npm:1.2.6": - version: 1.2.6 - resolution: "@rolldown/binding-win32-x64-msvc@npm:1.2.6" +"@rolldown/binding-win32-x64-msvc@npm:1.2.15": + version: 1.2.15 + resolution: "@rolldown/binding-win32-x64-msvc@npm:1.2.15" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -16719,12 +16583,13 @@ __metadata: "@local/tsconfig": "workspace:*" "@tsconfig/bases": "catalog:" "@types/node": "catalog:" - "@vitest/coverage-istanbul": "npm:4.1.10" + "@vitest/coverage-istanbul": "catalog:" eslint: "npm:9.39.4" fractional-indexing: "npm:3.2.0" graphql: "npm:16.11.0" rimraf: "npm:6.1.3" typescript: "catalog:" + vite: "catalog:" vitest: "catalog:" languageName: unknown linkType: soft @@ -17453,6 +17318,13 @@ __metadata: languageName: node linkType: hard +"@types/gensync@npm:^1.0.5": + version: 1.0.5 + resolution: "@types/gensync@npm:1.0.5" + checksum: 10c0/7c37c8fc3b1a49efd8889f635a6204008f1c1cc86a09ac6a96e219cf3fc52cf1ff091c4dddc3160e93261d6e599fbba39f5fb698fbf936518d1c410289cdd640 + languageName: node + linkType: hard + "@types/geojson@npm:^7946.0.16, @types/geojson@npm:^7946.0.7": version: 7946.0.16 resolution: "@types/geojson@npm:7946.0.16" @@ -19034,58 +18906,22 @@ __metadata: languageName: node linkType: hard -"@vitest/browser-playwright@npm:4.1.11": - version: 4.1.11 - resolution: "@vitest/browser-playwright@npm:4.1.11" - dependencies: - "@vitest/browser": "npm:4.1.11" - "@vitest/mocker": "npm:4.1.11" - tinyrainbow: "npm:^3.1.0" - peerDependencies: - playwright: "*" - vitest: 4.1.11 - peerDependenciesMeta: - playwright: - optional: false - checksum: 10c0/1275e3b7a0a65700c46e309b3afd8a9d98ef36a8478c10a9ae6cb839963ed4fa661d24fe814ed7c32b09b390cc9045d0db54fc805834830af4a642e72d9e0f76 - languageName: node - linkType: hard - -"@vitest/browser@npm:4.1.11": - version: 4.1.11 - resolution: "@vitest/browser@npm:4.1.11" - dependencies: - "@blazediff/core": "npm:1.9.1" - "@vitest/mocker": "npm:4.1.11" - "@vitest/utils": "npm:4.1.11" - magic-string: "npm:^0.30.21" - pngjs: "npm:^7.0.0" - sirv: "npm:^3.0.2" - tinyrainbow: "npm:^3.1.0" - ws: "npm:^8.19.0" - peerDependencies: - vitest: 4.1.11 - checksum: 10c0/a16b95d043650e82e0706131454d259e660e11fca01d2ce9e336320a482626b2175051e12a93ea18efaf9a794f6cce221919fe59fe27fba04bd9f0e253e6957e - languageName: node - linkType: hard - -"@vitest/coverage-istanbul@npm:4.1.10": - version: 4.1.10 - resolution: "@vitest/coverage-istanbul@npm:4.1.10" +"@vitest/coverage-istanbul@npm:5.0.5": + version: 5.0.5 + resolution: "@vitest/coverage-istanbul@npm:5.0.5" dependencies: - "@babel/core": "npm:^7.29.0" - "@istanbuljs/schema": "npm:^0.1.3" "@jridgewell/gen-mapping": "npm:^0.3.13" "@jridgewell/trace-mapping": "npm:0.3.31" - istanbul-lib-coverage: "npm:^3.2.2" - istanbul-lib-report: "npm:^3.0.1" - istanbul-reports: "npm:^3.2.0" - magicast: "npm:^0.5.2" - obug: "npm:^2.1.1" - tinyrainbow: "npm:^3.1.0" + "@vitest/istanbul-lib-coverage": "npm:^1.0.2" + "@vitest/istanbul-lib-instrument": "npm:^1.0.2" + "@vitest/istanbul-lib-report": "npm:^1.0.2" + "@vitest/istanbul-lib-source-maps": "npm:^1.0.2" + magicast: "npm:^0.5.5" + obug: "npm:^3.0.0" + tinyrainbow: "npm:^3.2.0" peerDependencies: - vitest: 4.1.10 - checksum: 10c0/a426b0aff94482587a100db7e8db4e238fabf9e5bc4d33a319bd9cd4261b8972a7b3d78f2bc7cbc3d11b0b58b5d7cc487f96ab35a96c1c766c54f9b6d5eb4f78 + vitest: 5.0.5 + checksum: 10c0/02ac31527fe0ef97c05e72d455b18d1782b05702fa630b8df99423e476eaded003a5b5540e75c18837bd2323117a32e2814389fab996c560e0cb930af4c2a506 languageName: node linkType: hard @@ -19119,36 +18955,63 @@ __metadata: languageName: node linkType: hard -"@vitest/expect@npm:4.1.11": - version: 4.1.11 - resolution: "@vitest/expect@npm:4.1.11" +"@vitest/istanbul-lib-coverage@npm:1.0.2, @vitest/istanbul-lib-coverage@npm:^1.0.2": + version: 1.0.2 + resolution: "@vitest/istanbul-lib-coverage@npm:1.0.2" + checksum: 10c0/c839315f8c54fb1eb7d51c61cd908f78c2909bbd17ee0d3d8824764f7eed2785471c40ab29f065eee18b577b8275ece8d4100f0ca6c7a05a39a4128683c57292 + languageName: node + linkType: hard + +"@vitest/istanbul-lib-instrument@npm:^1.0.2": + version: 1.0.2 + resolution: "@vitest/istanbul-lib-instrument@npm:1.0.2" dependencies: - "@standard-schema/spec": "npm:^1.1.0" - "@types/chai": "npm:^5.2.2" - "@vitest/spy": "npm:4.1.11" - "@vitest/utils": "npm:4.1.11" - chai: "npm:^6.2.2" - tinyrainbow: "npm:^3.1.0" - checksum: 10c0/0aa5e0973aca93a58cbdc3041c6bfed5897e976124965203b96a23b811f4ca403590c7eb15802c8d8366ec27a1db0682451e8a91c4d06617636de262baf86e4b + "@babel/core": "npm:^8.0.1" + "@babel/parser": "npm:^8.0.4" + "@istanbuljs/schema": "npm:^0.1.3" + "@jridgewell/trace-mapping": "npm:^0.3.23" + "@vitest/istanbul-lib-coverage": "npm:1.0.2" + checksum: 10c0/b031cd6b85d80775376bf1a9679bcc82fed1333b3418403c1e6ffba3ca19196c6c2506ec450cd3ada29bf81f0977c7955306ed1ff65f45ad94aca39523656478 languageName: node linkType: hard -"@vitest/mocker@npm:4.1.11": - version: 4.1.11 - resolution: "@vitest/mocker@npm:4.1.11" +"@vitest/istanbul-lib-report@npm:^1.0.2": + version: 1.0.2 + resolution: "@vitest/istanbul-lib-report@npm:1.0.2" + dependencies: + "@vitest/istanbul-lib-coverage": "npm:1.0.2" + checksum: 10c0/9b0b3c898448dfe99a51a51238fd564efb1efdfd3dc46570ad6b51a592c9f26811de7be6d07756782d4d0ee71d2431b0592c63be0921f7776bf213a22d87f4d3 + languageName: node + linkType: hard + +"@vitest/istanbul-lib-source-maps@npm:^1.0.2": + version: 1.0.2 + resolution: "@vitest/istanbul-lib-source-maps@npm:1.0.2" dependencies: - "@vitest/spy": "npm:4.1.11" + "@jridgewell/trace-mapping": "npm:^0.3.23" + "@vitest/istanbul-lib-coverage": "npm:1.0.2" + obug: "npm:^2.1.4" + checksum: 10c0/670c20838a071ecd084fe9e09b3f6e548c257cc29bcf9bc9f331682c7ef61170d0789ca7d5e6397a5f32ac867bc80e53a80e34ae04ce7ba58923b2ad908d2339 + languageName: node + linkType: hard + +"@vitest/mocker@npm:5.0.5": + version: 5.0.5 + resolution: "@vitest/mocker@npm:5.0.5" + dependencies: + "@jridgewell/trace-mapping": "npm:0.3.31" + "@vitest/spy": "npm:5.0.5" estree-walker: "npm:^3.0.3" - magic-string: "npm:^0.30.21" + magic-string: "npm:^1.4.3" peerDependencies: - msw: ^2.4.9 + msw: ^2.4.9 || ^3.0.0 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: msw: optional: true vite: optional: true - checksum: 10c0/3111ea34bd5046f6c70bbd67cf8b89608ee8c41cb27ab2bd61d42f4b68810e9ea16a9a757a71bc254c105f73b407d00ebb6bab1ab0f7f5cdcc9d7d16602a3933 + checksum: 10c0/5d5573d6015ef948d6cb193feb025874b6776f35964745c6beb3e556467b6dbfcbb103c4ce01d2d50b7fb43b83f56172c5074e0dd3da4dc5673ea1870b69a722 languageName: node linkType: hard @@ -19161,37 +19024,6 @@ __metadata: languageName: node linkType: hard -"@vitest/pretty-format@npm:4.1.11": - version: 4.1.11 - resolution: "@vitest/pretty-format@npm:4.1.11" - dependencies: - tinyrainbow: "npm:^3.1.0" - checksum: 10c0/ad32525c73807c0b72f38dc29bc51fd5a17879dc650f37995a9c5adbb8526e15f787691f76aa8768448ec7ed5bf5ba2b12329eac8fda1428b4d6b8c036390f71 - languageName: node - linkType: hard - -"@vitest/runner@npm:4.1.11": - version: 4.1.11 - resolution: "@vitest/runner@npm:4.1.11" - dependencies: - "@vitest/utils": "npm:4.1.11" - pathe: "npm:^2.0.3" - checksum: 10c0/3c782b055e9e688e1785f7c8937bd1669bad1b0e5758cb8b844f918f30a324b1d21e174d46c941ce80ebf37f2b89b55b6d619a675025914a1ece6377b95909e2 - languageName: node - linkType: hard - -"@vitest/snapshot@npm:4.1.11": - version: 4.1.11 - resolution: "@vitest/snapshot@npm:4.1.11" - dependencies: - "@vitest/pretty-format": "npm:4.1.11" - "@vitest/utils": "npm:4.1.11" - magic-string: "npm:^0.30.21" - pathe: "npm:^2.0.3" - checksum: 10c0/35d82a7c2a3e4b57529c30387d568d9106b6bf960189214e5d8cb1f5288cb042305c2e5c7b0b2f8cb56a2c814973de0310bc56d72deb79427bea272b6224190c - languageName: node - linkType: hard - "@vitest/spy@npm:3.2.4": version: 3.2.4 resolution: "@vitest/spy@npm:3.2.4" @@ -19201,10 +19033,10 @@ __metadata: languageName: node linkType: hard -"@vitest/spy@npm:4.1.11": - version: 4.1.11 - resolution: "@vitest/spy@npm:4.1.11" - checksum: 10c0/06c68247a8efd21006abe7532fee17f30ba83c8cda3e0b952ef89e278d58058f4b1de69b6bbaa2ed614c568bf4f5769fcc76be42802dedf2bcdd9c0aae601740 +"@vitest/spy@npm:5.0.5": + version: 5.0.5 + resolution: "@vitest/spy@npm:5.0.5" + checksum: 10c0/a48d92e38497e587cbb17b0ddb85604abaddf367e1cd4e373000ab080198511253fd35bf6a0e9a973e052e728c3235070a0b33ba6f2da1998aa5d65b64299783 languageName: node linkType: hard @@ -19219,17 +19051,6 @@ __metadata: languageName: node linkType: hard -"@vitest/utils@npm:4.1.11": - version: 4.1.11 - resolution: "@vitest/utils@npm:4.1.11" - dependencies: - "@vitest/pretty-format": "npm:4.1.11" - convert-source-map: "npm:^2.0.0" - tinyrainbow: "npm:^3.1.0" - checksum: 10c0/a2c1ddc64333458c3e031465c1ee0440a7660fd1b298c54ccbf865ef1e5cf3ebdd6c5c75a5ea235d8a672498b394e7121f992b096f021f45014ab25e9abd1b52 - languageName: node - linkType: hard - "@vue/compiler-core@npm:3.5.25": version: 3.5.25 resolution: "@vue/compiler-core@npm:3.5.25" @@ -22335,10 +22156,10 @@ __metadata: languageName: node linkType: hard -"chai@npm:^6.2.2": - version: 6.2.2 - resolution: "chai@npm:6.2.2" - checksum: 10c0/e6c69e5f0c11dffe6ea13d0290936ebb68fcc1ad688b8e952e131df6a6d5797d5e860bc55cef1aca2e950c3e1f96daf79e9d5a70fb7dbaab4e46355e2635ed53 +"chai@npm:^6.3.0": + version: 6.3.0 + resolution: "chai@npm:6.3.0" + checksum: 10c0/fd1bf7fc41295ba1eba18a44d68e204b3cb11b79c9ad51fd071de3ee85323c20d94afc07a386f1f5ff44a5da4a116614d419fc44a2d459e4b5b574aef9af4431 languageName: node linkType: hard @@ -24432,13 +24253,10 @@ __metadata: languageName: node linkType: hard -"effect@npm:3.21.0": - version: 3.21.0 - resolution: "effect@npm:3.21.0" - dependencies: - "@standard-schema/spec": "npm:^1.0.0" - fast-check: "npm:^3.23.1" - checksum: 10c0/665cb8fd0862f334eeb1d0fbadb14913de358948c08929bfd079fd38903132ba54daa99da4c453f738c318fa5ce0de862bf8db08974d97a05d868f6bc685eb50 +"effect@npm:4.0.3": + version: 4.0.3 + resolution: "effect@npm:4.0.3" + checksum: 10c0/2b750bcd6372d89252f07602e5cc66f8ac21fb4481083e33764e84299d56909ac1e64ec16531a435af1c06f299e0cdec28a731204d7ab42ddd1b10de2b098c01 languageName: node linkType: hard @@ -24491,10 +24309,10 @@ __metadata: languageName: node linkType: hard -"empathic@npm:^2.0.0": - version: 2.0.0 - resolution: "empathic@npm:2.0.0" - checksum: 10c0/7d3b14b04a93b35c47bcc950467ec914fd241cd9acc0269b0ea160f13026ec110f520c90fae64720fde72cc1757b57f3f292fb606617b7fccac1f4d008a76506 +"empathic@npm:^2.0.0, empathic@npm:^2.0.1": + version: 2.1.0 + resolution: "empathic@npm:2.1.0" + checksum: 10c0/cf13e2919d680a22140d7cd1637a01f6cf9a727f21d3a54b23489ec01c80eab548b9d832d2e167d00e124a54377660c1d6fd2b5947d905366e4d22fde7b9e082 languageName: node linkType: hard @@ -24738,10 +24556,10 @@ __metadata: languageName: node linkType: hard -"es-module-lexer@npm:^2.0.0, es-module-lexer@npm:^2.1.0": - version: 2.1.0 - resolution: "es-module-lexer@npm:2.1.0" - checksum: 10c0/93bcf2454fa72d67fe3ccd0abef8ce7933f5840a319513418a643dd8e9c6aa8f49709cecfae02ded722805dd327232d30723a807cc52e6809d6ac697c62c29fb +"es-module-lexer@npm:^2.1.0, es-module-lexer@npm:^2.3.2": + version: 2.3.2 + resolution: "es-module-lexer@npm:2.3.2" + checksum: 10c0/5e7389424c43478439f12f9a6aca1750f6f99afa384fc3de329f4a45f152ab156671055008adaafc74960877abf8cc338aeebf6bed8c21297b146fd6eb7a22f8 languageName: node linkType: hard @@ -26207,10 +26025,10 @@ __metadata: languageName: node linkType: hard -"expect-type@npm:^1.3.0": - version: 1.3.0 - resolution: "expect-type@npm:1.3.0" - checksum: 10c0/8412b3fe4f392c420ab41dae220b09700e4e47c639a29ba7ba2e83cc6cffd2b4926f7ac9e47d7e277e8f4f02acda76fd6931cb81fd2b382fa9477ef9ada953fd +"expect-type@npm:^1.4.0": + version: 1.4.0 + resolution: "expect-type@npm:1.4.0" + checksum: 10c0/d40d76b8570695d36587beb3cc28494da2ca3ec8f04e67f5622ed2d372d850e401a9adef19c6835e1a8173903f157c79540b34c7b3fbd7cd8ce726cc903c57b7 languageName: node linkType: hard @@ -26386,15 +26204,6 @@ __metadata: languageName: node linkType: hard -"fast-check@npm:^3.23.1": - version: 3.23.2 - resolution: "fast-check@npm:3.23.2" - dependencies: - pure-rand: "npm:^6.1.0" - checksum: 10c0/16fcff3c80321ee765e23c3aebd0f6427f175c9c6c1753104ec658970162365dc2d56bda046d815e8f2e90634c07ba7d6f0bcfd327fbd576d98c56a18a9765ed - languageName: node - linkType: hard - "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -26713,13 +26522,6 @@ __metadata: languageName: node linkType: hard -"find-my-way-ts@npm:^0.1.6": - version: 0.1.6 - resolution: "find-my-way-ts@npm:0.1.6" - checksum: 10c0/16ad4b15275b56ee0ec361d0c61afbdff4c75bd0ac04112f6910f188cb1058096ba63529c2363914da6bb60266aa4def1025af04af26368ff87eb0df52f2862f - languageName: node - linkType: hard - "find-root@npm:^1.1.0": version: 1.1.0 resolution: "find-root@npm:1.1.0" @@ -26803,9 +26605,16 @@ __metadata: linkType: hard "flatted@npm:^3.2.9": - version: 3.4.2 - resolution: "flatted@npm:3.4.2" - checksum: 10c0/a65b67aae7172d6cdf63691be7de6c5cd5adbdfdfe2e9da1a09b617c9512ed794037741ee53d93114276bff3f93cd3b0d97d54f9b316e1e4885dde6e9ffdf7ed + version: 3.4.4 + resolution: "flatted@npm:3.4.4" + checksum: 10c0/a3a52a88ea5a4c333e5a1f097dcd87a037fa31c236a77cf46222c2aa4036ef895ab9bc76138a66d9dc22bdb3652128f9598cd26e7439561bf19f67276e2bc37e + languageName: node + linkType: hard + +"flru@npm:1.0.2": + version: 1.0.2 + resolution: "flru@npm:1.0.2" + checksum: 10c0/73b01b1df3f3f9d56a86c2102ac199ac72918ee7a00f8516be8dd4495da90ede9375873ad8902ca93a23c91bcc224aacf2dcf89bf7ce62efb9faf048b564b412 languageName: node linkType: hard @@ -28229,7 +28038,7 @@ __metadata: languageName: node linkType: hard -"html-escaper@npm:^2.0.0, html-escaper@npm:^2.0.2": +"html-escaper@npm:^2.0.2": version: 2.0.2 resolution: "html-escaper@npm:2.0.2" checksum: 10c0/208e8a12de1a6569edbb14544f4567e6ce8ecc30b9394fcaa4e7bb1e60c12a7c9a1ed27e31290817157e8626f3a4f29e76c8747030822eb84a6abb15c255f0a0 @@ -29724,34 +29533,6 @@ __metadata: languageName: node linkType: hard -"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.2": - version: 3.2.2 - resolution: "istanbul-lib-coverage@npm:3.2.2" - checksum: 10c0/6c7ff2106769e5f592ded1fb418f9f73b4411fd5a084387a5410538332b6567cd1763ff6b6cadca9b9eb2c443cce2f7ea7d7f1b8d315f9ce58539793b1e0922b - languageName: node - linkType: hard - -"istanbul-lib-report@npm:^3.0.0, istanbul-lib-report@npm:^3.0.1": - version: 3.0.1 - resolution: "istanbul-lib-report@npm:3.0.1" - dependencies: - istanbul-lib-coverage: "npm:^3.0.0" - make-dir: "npm:^4.0.0" - supports-color: "npm:^7.1.0" - checksum: 10c0/84323afb14392de8b6a5714bd7e9af845cfbd56cfe71ed276cda2f5f1201aea673c7111901227ee33e68e4364e288d73861eb2ed48f6679d1e69a43b6d9b3ba7 - languageName: node - linkType: hard - -"istanbul-reports@npm:^3.2.0": - version: 3.2.0 - resolution: "istanbul-reports@npm:3.2.0" - dependencies: - html-escaper: "npm:^2.0.0" - istanbul-lib-report: "npm:^3.0.0" - checksum: 10c0/d596317cfd9c22e1394f22a8d8ba0303d2074fe2e971887b32d870e4b33f8464b10f8ccbe6847808f7db485f084eba09e6c2ed706b3a978e4b52f07085b8f9bc - languageName: node - linkType: hard - "istextorbinary@npm:~9.5.0": version: 9.5.0 resolution: "istextorbinary@npm:9.5.0" @@ -31411,16 +31192,16 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:^1.0.0": - version: 1.4.3 - resolution: "magic-string@npm:1.4.3" +"magic-string@npm:^1.0.0, magic-string@npm:^1.4.3": + version: 1.4.5 + resolution: "magic-string@npm:1.4.5" dependencies: "@jridgewell/sourcemap-codec": "npm:^1.6.0" - checksum: 10c0/857743a1e7039d2e867505bb272a57cc605f610b90f6bf9ef6cbf9654e9cd64330ec35e564a58ca455350529872c3ecc01f37da934da130391237f9f593cc565 + checksum: 10c0/79295b85e19f2e18bb01b81671d27ae192546e88534dfcef2e36f2c04f45b39db497ce85a62efda0336356308cdc037a1c73fc0f1bd0945d12ae1e794163b247 languageName: node linkType: hard -"magicast@npm:^0.5.2": +"magicast@npm:^0.5.5": version: 0.5.5 resolution: "magicast@npm:0.5.5" dependencies: @@ -31445,15 +31226,6 @@ __metadata: languageName: node linkType: hard -"make-dir@npm:^4.0.0": - version: 4.0.0 - resolution: "make-dir@npm:4.0.0" - dependencies: - semver: "npm:^7.5.3" - checksum: 10c0/69b98a6c0b8e5c4fe9acb61608a9fbcfca1756d910f51e5dbe7a9e5cfb74fca9b8a0c8a0ffdf1294a740826c1ab4871d5bf3f62f72a3049e5eac6541ddffed68 - languageName: node - linkType: hard - "make-error@npm:^1.1.1": version: 1.3.6 resolution: "make-error@npm:1.3.6" @@ -32935,7 +32707,7 @@ __metadata: languageName: node linkType: hard -"msgpackr@npm:^1.11.2, msgpackr@npm:^1.11.4": +"msgpackr@npm:^1.11.2": version: 1.11.5 resolution: "msgpackr@npm:1.11.5" dependencies: @@ -32973,13 +32745,6 @@ __metadata: languageName: node linkType: hard -"multipasta@npm:^0.2.7": - version: 0.2.7 - resolution: "multipasta@npm:0.2.7" - checksum: 10c0/15917ac88aeefa5b8afac44b90d1e9d0d0ec7148b51e0766f07a69a220ecebcb6404539a856c45aa85a3d7fe517bc58febe81437146705f17ecd2961dc0b9fa5 - languageName: node - linkType: hard - "multipipe@npm:^1.0.2": version: 1.0.2 resolution: "multipipe@npm:1.0.2" @@ -33612,13 +33377,20 @@ __metadata: languageName: node linkType: hard -"obug@npm:^2.1.1, obug@npm:^2.1.4": +"obug@npm:^2.1.4": version: 2.1.4 resolution: "obug@npm:2.1.4" checksum: 10c0/34a0ee97cd88573cfd97d384c2a79f07118ae5680d7e45d1de6e99c74eddefe145e8ca27a2db02195a1ee5fded5aa22b924869c842728c201b9f109a27d0ef19 languageName: node linkType: hard +"obug@npm:^3.0.0": + version: 3.0.0 + resolution: "obug@npm:3.0.0" + checksum: 10c0/985625b70ea05a39956da94f406040a0c7d27b1699a14af87b1ea75cba915b5957b75c4acdaccaefa2a86eaf40fc968bc00f6c28755a91496fc91a92b1513b38 + languageName: node + linkType: hard + "oembed-providers@npm:1.0.20250926": version: 1.0.20250926 resolution: "oembed-providers@npm:1.0.20250926" @@ -35063,13 +34835,6 @@ __metadata: languageName: node linkType: hard -"pngjs@npm:^7.0.0": - version: 7.0.0 - resolution: "pngjs@npm:7.0.0" - checksum: 10c0/0d4c7a0fd476a9c33df7d0a2a73e1d56537628a668841f6995c2bca070cf30819f9254a64363266bc14ef2fee47659dd3b4f2b18eec7ab65143015139f497b38 - languageName: node - linkType: hard - "possible-typed-array-names@npm:^1.0.0": version: 1.0.0 resolution: "possible-typed-array-names@npm:1.0.0" @@ -35224,14 +34989,14 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.4.14, postcss@npm:^8.4.33, postcss@npm:^8.5.27, postcss@npm:^8.5.29, postcss@npm:^8.5.6": - version: 8.5.30 - resolution: "postcss@npm:8.5.30" +"postcss@npm:^8.4.14, postcss@npm:^8.4.33, postcss@npm:^8.5.27, postcss@npm:^8.5.30, postcss@npm:^8.5.6": + version: 8.5.31 + resolution: "postcss@npm:8.5.31" dependencies: nanoid: "npm:^3.3.20" picocolors: "npm:^1.1.1" source-map-js: "npm:^1.2.2" - checksum: 10c0/219cdc50ba3f2b6d0f8b779c4939514cb9d9f53cc9eb92dae1a06f2d6eb910b2ce339a3ee93e7c893b89e50241509fd92c04f0639af1cdf41a1e13983a476029 + checksum: 10c0/52f94c6655f86f568a803ce9c8eb3c749e109cc711d26644c4cde953b30c1b947a2f25af3b9453de68584ac655572f46ed8e830b8ab2f21dd226b3f640992e00 languageName: node linkType: hard @@ -35767,13 +35532,6 @@ __metadata: languageName: node linkType: hard -"pure-rand@npm:^6.1.0": - version: 6.1.0 - resolution: "pure-rand@npm:6.1.0" - checksum: 10c0/1abe217897bf74dcb3a0c9aba3555fe975023147b48db540aa2faf507aee91c03bf54f6aef0eb2bf59cc259a16d06b28eca37f0dc426d94f4692aeff02fb0e65 - languageName: node - linkType: hard - "pure-rand@npm:^8.0.0": version: 8.4.2 resolution: "pure-rand@npm:8.4.2" @@ -37345,26 +37103,26 @@ __metadata: languageName: node linkType: hard -"rolldown@npm:1.2.6": - version: 1.2.6 - resolution: "rolldown@npm:1.2.6" - dependencies: - "@oxc-project/types": "npm:=0.147.0" - "@rolldown/binding-android-arm-eabi": "npm:1.2.6" - "@rolldown/binding-android-arm64": "npm:1.2.6" - "@rolldown/binding-darwin-arm64": "npm:1.2.6" - "@rolldown/binding-darwin-x64": "npm:1.2.6" - "@rolldown/binding-freebsd-x64": "npm:1.2.6" - "@rolldown/binding-linux-arm-gnueabihf": "npm:1.2.6" - "@rolldown/binding-linux-arm64-gnu": "npm:1.2.6" - "@rolldown/binding-linux-arm64-musl": "npm:1.2.6" - "@rolldown/binding-linux-ppc64-gnu": "npm:1.2.6" - "@rolldown/binding-linux-s390x-gnu": "npm:1.2.6" - "@rolldown/binding-linux-x64-gnu": "npm:1.2.6" - "@rolldown/binding-linux-x64-musl": "npm:1.2.6" - "@rolldown/binding-openharmony-arm64": "npm:1.2.6" - "@rolldown/binding-win32-arm64-msvc": "npm:1.2.6" - "@rolldown/binding-win32-x64-msvc": "npm:1.2.6" +"rolldown@npm:1.2.15, rolldown@npm:~1.2.14": + version: 1.2.15 + resolution: "rolldown@npm:1.2.15" + dependencies: + "@oxc-project/types": "npm:=0.155.0" + "@rolldown/binding-android-arm-eabi": "npm:1.2.15" + "@rolldown/binding-android-arm64": "npm:1.2.15" + "@rolldown/binding-darwin-arm64": "npm:1.2.15" + "@rolldown/binding-darwin-x64": "npm:1.2.15" + "@rolldown/binding-freebsd-x64": "npm:1.2.15" + "@rolldown/binding-linux-arm-gnueabihf": "npm:1.2.15" + "@rolldown/binding-linux-arm64-gnu": "npm:1.2.15" + "@rolldown/binding-linux-arm64-musl": "npm:1.2.15" + "@rolldown/binding-linux-ppc64-gnu": "npm:1.2.15" + "@rolldown/binding-linux-s390x-gnu": "npm:1.2.15" + "@rolldown/binding-linux-x64-gnu": "npm:1.2.15" + "@rolldown/binding-linux-x64-musl": "npm:1.2.15" + "@rolldown/binding-openharmony-arm64": "npm:1.2.15" + "@rolldown/binding-win32-arm64-msvc": "npm:1.2.15" + "@rolldown/binding-win32-x64-msvc": "npm:1.2.15" "@rolldown/pluginutils": "npm:^1.0.0" dependenciesMeta: "@rolldown/binding-android-arm-eabi": @@ -37399,65 +37157,7 @@ __metadata: optional: true bin: rolldown: ./bin/cli.mjs - checksum: 10c0/34f8fd335f3ec8e55002aa4f2f6f0ffd4dc1f2c47f877d4ad37fbe62c97d3b63486705494e739b9e451cccf4c4bc4e0f14648d7f978427964c693c0165289308 - languageName: node - linkType: hard - -"rolldown@npm:~1.2.12": - version: 1.2.14 - resolution: "rolldown@npm:1.2.14" - dependencies: - "@oxc-project/types": "npm:=0.154.0" - "@rolldown/binding-android-arm-eabi": "npm:1.2.14" - "@rolldown/binding-android-arm64": "npm:1.2.14" - "@rolldown/binding-darwin-arm64": "npm:1.2.14" - "@rolldown/binding-darwin-x64": "npm:1.2.14" - "@rolldown/binding-freebsd-x64": "npm:1.2.14" - "@rolldown/binding-linux-arm-gnueabihf": "npm:1.2.14" - "@rolldown/binding-linux-arm64-gnu": "npm:1.2.14" - "@rolldown/binding-linux-arm64-musl": "npm:1.2.14" - "@rolldown/binding-linux-ppc64-gnu": "npm:1.2.14" - "@rolldown/binding-linux-s390x-gnu": "npm:1.2.14" - "@rolldown/binding-linux-x64-gnu": "npm:1.2.14" - "@rolldown/binding-linux-x64-musl": "npm:1.2.14" - "@rolldown/binding-openharmony-arm64": "npm:1.2.14" - "@rolldown/binding-win32-arm64-msvc": "npm:1.2.14" - "@rolldown/binding-win32-x64-msvc": "npm:1.2.14" - "@rolldown/pluginutils": "npm:^1.0.0" - dependenciesMeta: - "@rolldown/binding-android-arm-eabi": - optional: true - "@rolldown/binding-android-arm64": - optional: true - "@rolldown/binding-darwin-arm64": - optional: true - "@rolldown/binding-darwin-x64": - optional: true - "@rolldown/binding-freebsd-x64": - optional: true - "@rolldown/binding-linux-arm-gnueabihf": - optional: true - "@rolldown/binding-linux-arm64-gnu": - optional: true - "@rolldown/binding-linux-arm64-musl": - optional: true - "@rolldown/binding-linux-ppc64-gnu": - optional: true - "@rolldown/binding-linux-s390x-gnu": - optional: true - "@rolldown/binding-linux-x64-gnu": - optional: true - "@rolldown/binding-linux-x64-musl": - optional: true - "@rolldown/binding-openharmony-arm64": - optional: true - "@rolldown/binding-win32-arm64-msvc": - optional: true - "@rolldown/binding-win32-x64-msvc": - optional: true - bin: - rolldown: ./bin/cli.mjs - checksum: 10c0/61782e6764bb05e525517dc8b2d69b465033a48a6998b1fb21de01e787938f3f7a2aa1e8eee5d83c924d131cc629eeaea9fa56b69dd469f97b3c6bb7fb6ddcb2 + checksum: 10c0/084cbdcc222e534c9aff90e77488cdeb6a685a20a34e6e3ba77c3b8646723cea2f090f05522f452ed51217cce68b7aa67df8661b49b4ac0227a5edfcb0383b68 languageName: node linkType: hard @@ -37866,7 +37566,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.8.5, semver@npm:^7.3.5, semver@npm:^7.3.8, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.3, semver@npm:^7.7.1, semver@npm:^7.7.3, semver@npm:^7.8.1, semver@npm:^7.8.5": +"semver@npm:7.8.5, semver@npm:^7.3.5, semver@npm:^7.3.8, semver@npm:^7.5.2, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.3, semver@npm:^7.7.1, semver@npm:^7.7.3, semver@npm:^7.8.1, semver@npm:^7.8.5": version: 7.8.5 resolution: "semver@npm:7.8.5" bin: @@ -38269,13 +37969,6 @@ __metadata: languageName: node linkType: hard -"siginfo@npm:^2.0.0": - version: 2.0.0 - resolution: "siginfo@npm:2.0.0" - checksum: 10c0/3def8f8e516fbb34cb6ae415b07ccc5d9c018d85b4b8611e3dc6f8be6d1899f693a4382913c9ed51a06babb5201639d76453ab297d1c54a456544acf5c892e34 - languageName: node - linkType: hard - "sigma@npm:3.0.2": version: 3.0.2 resolution: "sigma@npm:3.0.2" @@ -38349,17 +38042,6 @@ __metadata: languageName: node linkType: hard -"sirv@npm:^3.0.2": - version: 3.0.2 - resolution: "sirv@npm:3.0.2" - dependencies: - "@polka/url": "npm:^1.0.0-next.24" - mrmime: "npm:^2.0.0" - totalist: "npm:^3.0.0" - checksum: 10c0/5930e4397afdb14fbae13751c3be983af4bda5c9aadec832607dc2af15a7162f7d518c71b30e83ae3644b9a24cea041543cc969e5fe2b80af6ce8ea3174b2d04 - languageName: node - linkType: hard - "sisteransi@npm:^1.0.5": version: 1.0.5 resolution: "sisteransi@npm:1.0.5" @@ -38651,13 +38333,6 @@ __metadata: languageName: node linkType: hard -"stackback@npm:0.0.2": - version: 0.0.2 - resolution: "stackback@npm:0.0.2" - checksum: 10c0/89a1416668f950236dd5ac9f9a6b2588e1b9b62b1b6ad8dff1bfc5d1a15dbf0aafc9b52d2226d00c28dffff212da464eaeebfc6b7578b9d180cef3e3782c5983 - languageName: node - linkType: hard - "stackframe@npm:^1.3.4": version: 1.3.4 resolution: "stackframe@npm:1.3.4" @@ -38712,7 +38387,7 @@ __metadata: languageName: node linkType: hard -"std-env@npm:^4.0.0-rc.1": +"std-env@npm:^4.3.0": version: 4.3.0 resolution: "std-env@npm:4.3.0" checksum: 10c0/1e90dc69f32f853375c6de45dbe7219c8399e2a3ab3a972fdcd1cf3c20fe0e3c13bf58d57d6193b551d37a81c50dfb3f51e07774e9e48a7dc5a22dabcad7acbd @@ -39548,10 +39223,10 @@ __metadata: languageName: node linkType: hard -"tinybench@npm:^2.9.0": - version: 2.9.0 - resolution: "tinybench@npm:2.9.0" - checksum: 10c0/c3500b0f60d2eb8db65250afe750b66d51623057ee88720b7f064894a6cb7eb93360ca824a60a31ab16dab30c7b1f06efe0795b352e37914a9d4bad86386a20c +"tinybench@npm:^6.2.2": + version: 6.2.2 + resolution: "tinybench@npm:6.2.2" + checksum: 10c0/f0e6391f4ca86875ce5a64510696323aa841c10495fdd1c6ca530457c7e77f2b3aa82d9d6f1553126420062b1008607257677ce2b25ff1948732a79d7a56514a languageName: node linkType: hard @@ -39562,7 +39237,7 @@ __metadata: languageName: node linkType: hard -"tinyexec@npm:^1.0.2, tinyexec@npm:^1.3.0, tinyexec@npm:^1.3.1": +"tinyexec@npm:^1.3.0, tinyexec@npm:^1.3.1": version: 1.3.1 resolution: "tinyexec@npm:1.3.1" checksum: 10c0/c590369cb3fa73cc18a3998caec8a00f9712d91309c881be3ac52b160fb2f80c7b1fbf3591858ab6abab47ad55385b0c86ec19982e32441a01f55298dab9ccd2 @@ -39593,10 +39268,10 @@ __metadata: languageName: node linkType: hard -"tinyrainbow@npm:^3.1.0": - version: 3.1.0 - resolution: "tinyrainbow@npm:3.1.0" - checksum: 10c0/f11cf387a26c5c9255bec141a90ac511b26172981b10c3e50053bc6700ea7d2336edcc4a3a21dbb8412fe7c013477d2ba4d7e4877800f3f8107be5105aad6511 +"tinyrainbow@npm:^3.2.0": + version: 3.2.0 + resolution: "tinyrainbow@npm:3.2.0" + checksum: 10c0/22d9c303cd807026898dcb5ac5ffbf725b5a2cc8d042449769aed8f1266be94de5e95206b76cac948f68facafba5b80e9a9257c82e5fed2651be3fecf2b624ab languageName: node linkType: hard @@ -40752,13 +40427,20 @@ __metadata: languageName: node linkType: hard -"undici@npm:^7.10.0, undici@npm:^7.28.0": +"undici@npm:^7.28.0": version: 7.30.1 resolution: "undici@npm:7.30.1" checksum: 10c0/c838089b010e8e28a9a5358d4bf4621e0c8d7bb70058b23e819667349c4c0b6791a7c8bc9bbe94ff0923db132faae0d9d9592b9743eda4f2b49466fa57482213 languageName: node linkType: hard +"undici@npm:^8.11.2": + version: 8.12.3 + resolution: "undici@npm:8.12.3" + checksum: 10c0/714919e62b4160eea195fb35c7f5c4907235741e47bfde8a014ac58f6d24df13434e23400d7f48e2c455fd2b259d27f07fce514f04a5b4e99936ba62cbc4bb71 + languageName: node + linkType: hard + "unfetch@npm:^4.2.0": version: 4.2.0 resolution: "unfetch@npm:4.2.0" @@ -41264,7 +40946,7 @@ __metadata: languageName: node linkType: hard -"uuid@npm:11.1.0, uuid@npm:^11.0.1, uuid@npm:^11.0.3, uuid@npm:^11.1.0": +"uuid@npm:11.1.0, uuid@npm:^11.0.1, uuid@npm:^11.1.0": version: 11.1.0 resolution: "uuid@npm:11.1.0" bin: @@ -41338,6 +41020,13 @@ __metadata: languageName: node linkType: hard +"verkit@npm:^0.5.0": + version: 0.5.0 + resolution: "verkit@npm:0.5.0" + checksum: 10c0/0bad45304bd0b3d2e56e4bdb422a43863c7a86902741eb632adb104ea37e1213706e08be4eaa7b3e28f843658be56ace16081d3ed3478477a5872f94a83ef7d0 + languageName: node + linkType: hard + "version-range@npm:^4.15.0": version: 4.15.0 resolution: "version-range@npm:4.15.0" @@ -41410,19 +41099,19 @@ __metadata: languageName: node linkType: hard -"vite@npm:8.3.4, vite@npm:^6.0.0 || ^7.0.0 || ^8.0.0": - version: 8.3.4 - resolution: "vite@npm:8.3.4" +"vite@npm:8.3.5": + version: 8.3.5 + resolution: "vite@npm:8.3.5" dependencies: fsevents: "npm:~2.3.3" lightningcss: "npm:^1.33.0" picomatch: "npm:^4.0.7" - postcss: "npm:^8.5.29" - rolldown: "npm:~1.2.12" + postcss: "npm:^8.5.30" + rolldown: "npm:~1.2.14" tinyglobby: "npm:^0.2.17" peerDependencies: "@types/node": ^20.19.0 || >=22.12.0 - "@vitejs/devtools": ^0.7.1 + "@vitejs/devtools": ^0.7.1 || ^0.8.0 esbuild: ^0.27.0 || ^0.28.0 jiti: ">=1.21.0" less: ^4.0.0 @@ -41463,65 +41152,40 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/63d7351fa21580fb646f0b594c64e97a56cdf15c55a57372a7adefe6287995fa7384cb5ddca14695ff7dca738ba00e0a3352fc24df711d9c501c5576f40f0867 - languageName: node - linkType: hard - -"vitest-browser-react@npm:^2.0.2": - version: 2.2.0 - resolution: "vitest-browser-react@npm:2.2.0" - peerDependencies: - "@types/react": ^18.0.0 || ^19.0.0 - "@types/react-dom": ^18.0.0 || ^19.0.0 - react: ^18.0.0 || ^19.0.0 - react-dom: ^18.0.0 || ^19.0.0 - vitest: ^4.0.0 - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-dom": - optional: true - checksum: 10c0/d2e582e564cf7f65f19a5a9c36b0b136e84fc6dabd42566703d79e0b220094a5a88a9197a42b2c4779f38977d79c8f3306387cd7edd2ef8e57790b921a759975 + checksum: 10c0/33991600925b6717429c14a2c2907554aed077489ee6ff7815f9f49d5de559f5173ccb0472f2b3f9eef2a49e2e014f6cb624db8d4adebb37baad3a8cbc15065a languageName: node linkType: hard -"vitest@npm:4.1.11": - version: 4.1.11 - resolution: "vitest@npm:4.1.11" - dependencies: - "@vitest/expect": "npm:4.1.11" - "@vitest/mocker": "npm:4.1.11" - "@vitest/pretty-format": "npm:4.1.11" - "@vitest/runner": "npm:4.1.11" - "@vitest/snapshot": "npm:4.1.11" - "@vitest/spy": "npm:4.1.11" - "@vitest/utils": "npm:4.1.11" - es-module-lexer: "npm:^2.0.0" - expect-type: "npm:^1.3.0" - magic-string: "npm:^0.30.21" - obug: "npm:^2.1.1" - pathe: "npm:^2.0.3" - picomatch: "npm:^4.0.3" - std-env: "npm:^4.0.0-rc.1" - tinybench: "npm:^2.9.0" - tinyexec: "npm:^1.0.2" - tinyglobby: "npm:^0.2.15" - tinyrainbow: "npm:^3.1.0" - vite: "npm:^6.0.0 || ^7.0.0 || ^8.0.0" - why-is-node-running: "npm:^2.3.0" +"vitest@npm:5.0.5": + version: 5.0.5 + resolution: "vitest@npm:5.0.5" + dependencies: + "@types/chai": "npm:^5.2.2" + "@vitest/mocker": "npm:5.0.5" + chai: "npm:^6.3.0" + es-module-lexer: "npm:^2.3.2" + expect-type: "npm:^1.4.0" + magic-string: "npm:^1.4.3" + obug: "npm:^3.0.0" + picomatch: "npm:^4.0.7" + std-env: "npm:^4.3.0" + tinybench: "npm:^6.2.2" + tinyexec: "npm:^1.3.1" + tinyglobby: "npm:^0.2.17" + why-is-node-running: "npm:3.2.1" peerDependencies: "@edge-runtime/vm": "*" "@opentelemetry/api": ^1.9.0 - "@types/node": ^20.0.0 || ^22.0.0 || >=24.0.0 - "@vitest/browser-playwright": 4.1.11 - "@vitest/browser-preview": 4.1.11 - "@vitest/browser-webdriverio": 4.1.11 - "@vitest/coverage-istanbul": 4.1.11 - "@vitest/coverage-v8": 4.1.11 - "@vitest/ui": 4.1.11 + "@types/node": ^22.0.0 || >=24.0.0 + "@vitest/browser-playwright": 5.0.5 + "@vitest/browser-preview": 5.0.5 + "@vitest/browser-webdriverio": ^5.0.0-beta.5 || >=5.0.0 + "@vitest/coverage-istanbul": 5.0.5 + "@vitest/coverage-v8": 5.0.5 + "@vitest/ui": 5.0.5 happy-dom: "*" jsdom: "*" - vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + vite: ^6.4.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: "@edge-runtime/vm": optional: true @@ -41549,7 +41213,7 @@ __metadata: optional: false bin: vitest: ./vitest.mjs - checksum: 10c0/3fa0948cf74adcccc8cbcdb4e6d30ada6933bdfb1816ff99200f3d3b689325b37dc483b22535b57b6d911f7a7b64eaa6a5f8da1606cfe7f2466f48000c21e296 + checksum: 10c0/b6e38164490c4ca0c2bbc4e74ec8f9052a344caab3f3bf0e8c4485b6493af0f789d7aafd41f4128f66d576f50d3c860f0674322add2b4d348b6ea250ec8c77c8 languageName: node linkType: hard @@ -42093,15 +41757,12 @@ __metadata: languageName: node linkType: hard -"why-is-node-running@npm:^2.3.0": - version: 2.3.0 - resolution: "why-is-node-running@npm:2.3.0" - dependencies: - siginfo: "npm:^2.0.0" - stackback: "npm:0.0.2" +"why-is-node-running@npm:3.2.1": + version: 3.2.1 + resolution: "why-is-node-running@npm:3.2.1" bin: why-is-node-running: cli.js - checksum: 10c0/1cde0b01b827d2cf4cb11db962f3958b9175d5d9e7ac7361d1a7b0e2dc6069a263e69118bd974c4f6d0a890ef4eedfe34cf3d5167ec14203dbc9a18620537054 + checksum: 10c0/e3f82673aac2c0a330fdbcf4b282ecdf7e9c773fa82fb4217db5b8b3d374cbb51e708d928f5b17999bc65bc1a5a90fad0f6bd794641bd15fdd525949ccee5e39 languageName: node linkType: hard @@ -42277,7 +41938,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:^8.17.1, ws@npm:^8.18.0, ws@npm:^8.18.2, ws@npm:^8.19.0, ws@npm:^8.21.0, ws@npm:^8.21.1, ws@npm:^8.21.3, ws@npm:^8.22.0, ws@npm:^8.5.0": +"ws@npm:^8.17.1, ws@npm:^8.18.0, ws@npm:^8.21.0, ws@npm:^8.21.1, ws@npm:^8.21.3, ws@npm:^8.22.0, ws@npm:^8.5.0": version: 8.22.0 resolution: "ws@npm:8.22.0" peerDependencies: