From 25c2e43f679a8bf623024cb99529b69e64867ba0 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud <7252775+indietyp@users.noreply.github.com> Date: Tue, 6 Oct 2026 23:14:00 +0200 Subject: [PATCH 01/17] chore: centralize vitest dependencies in catalog --- .yarnrc.yml | 5 +- apps/hash-ai-worker-ts/package.json | 2 +- apps/hash-api/package.json | 3 +- apps/hash-frontend/package.json | 1 + apps/petrinaut-website/package.json | 2 +- .../type-system/typescript/package.json | 3 +- libs/@hashintel/ds-components/package.json | 2 +- libs/@local/graph/sdk/typescript/package.json | 3 +- .../harpc/client/typescript/package.json | 3 +- libs/@local/hash-backend-utils/package.json | 3 +- .../@local/hash-isomorphic-utils/package.json | 3 +- libs/@local/repo-chores/node/package.json | 1 + tests/hash-backend-integration/package.json | 3 +- yarn.lock | 622 ++++++++++++------ 14 files changed, 427 insertions(+), 229 deletions(-) diff --git a/.yarnrc.yml b/.yarnrc.yml index e949e6ea854..6404163e47e 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -40,7 +40,10 @@ catalog: typescript: "7.0.2" "@typescript/typescript6": "6.0.2" vite: "8.3.4" - vitest: "4.1.11" + vitest: "5.0.2" + "@vitest/browser-playwright": "5.0.2" + "@vitest/coverage-istanbul": "5.0.2" + "@fast-check/vitest": "0.5.0" "@tsconfig/bases": "1.0.28" "@types/node": "22.18.13" 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..b49b5487eef 100644 --- a/apps/hash-api/package.json +++ b/apps/hash-api/package.json @@ -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-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/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/libs/@blockprotocol/type-system/typescript/package.json b/libs/@blockprotocol/type-system/typescript/package.json index f9d9d3dcd2c..0abaeae8499 100644 --- a/libs/@blockprotocol/type-system/typescript/package.json +++ b/libs/@blockprotocol/type-system/typescript/package.json @@ -63,7 +63,7 @@ "@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", @@ -71,6 +71,7 @@ "rolldown-plugin-dts": "0.28.3", "tslib": "2.8.1", "typescript": "catalog:", + "vite": "catalog:", "vitest": "catalog:" } } diff --git a/libs/@hashintel/ds-components/package.json b/libs/@hashintel/ds-components/package.json index aa9451a5f49..7fefea538b7 100644 --- a/libs/@hashintel/ds-components/package.json +++ b/libs/@hashintel/ds-components/package.json @@ -129,7 +129,7 @@ "@types/react-dom": "19.2.3", "@typescript/typescript6": "catalog:", "@vitejs/plugin-react": "6.1.1", - "@vitest/browser-playwright": "4.1.11", + "@vitest/browser-playwright": "catalog:", "case-anything": "3.1.0", "esbuild-plugin-svgr": "3.1.1", "eslint": "9.39.4", diff --git a/libs/@local/graph/sdk/typescript/package.json b/libs/@local/graph/sdk/typescript/package.json index 1433d036a6e..58bc1361047 100644 --- a/libs/@local/graph/sdk/typescript/package.json +++ b/libs/@local/graph/sdk/typescript/package.json @@ -38,10 +38,11 @@ "@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/harpc/client/typescript/package.json b/libs/@local/harpc/client/typescript/package.json index c903656d5c5..535cbfee78f 100644 --- a/libs/@local/harpc/client/typescript/package.json +++ b/libs/@local/harpc/client/typescript/package.json @@ -50,10 +50,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/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..9dd25c331fc 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,7 +579,7 @@ __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" @@ -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:*" @@ -2039,6 +2041,16 @@ __metadata: languageName: node linkType: hard +"@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.6" + js-tokens: "npm:^10.0.0" + checksum: 10c0/ae3022ce1e41a48e367712f32c51736624992c1b87be17714ce0970063935c511bccbea4e005db02cc4da87370b608b5861378fcab86a78c9764fa3bd2b6959a + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.27.7, @babel/compat-data@npm:^7.28.0, @babel/compat-data@npm:^7.29.7": version: 7.29.7 resolution: "@babel/compat-data@npm:7.29.7" @@ -2046,6 +2058,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 +2088,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 +2111,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" @@ -2119,6 +2162,20 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^8.0.6": + version: 8.0.6 + resolution: "@babel/generator@npm:8.0.6" + dependencies: + "@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/ea3b078547815e7ee2a865c9618bbdeaca83961690f036791c05fbdd9a5dbfa0e7bd1dc36434cffba6c8be508297bad798ae47096551a6c38a7ff2e4d139729d + languageName: node + linkType: hard + "@babel/helper-annotate-as-pure@npm:^7.18.6, @babel/helper-annotate-as-pure@npm:^7.27.1, @babel/helper-annotate-as-pure@npm:^7.27.3": version: 7.27.3 resolution: "@babel/helper-annotate-as-pure@npm:7.27.3" @@ -2150,6 +2207,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" @@ -2226,6 +2296,13 @@ __metadata: languageName: node linkType: hard +"@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 + "@babel/helper-member-expression-to-functions@npm:^7.27.1, @babel/helper-member-expression-to-functions@npm:^7.28.5": version: 7.28.5 resolution: "@babel/helper-member-expression-to-functions@npm:7.28.5" @@ -2376,6 +2453,13 @@ __metadata: languageName: node linkType: hard +"@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 + "@babel/helper-validator-identifier@npm:^7.28.5, @babel/helper-validator-identifier@npm:^7.29.7": version: 7.29.7 resolution: "@babel/helper-validator-identifier@npm:7.29.7" @@ -2390,6 +2474,13 @@ __metadata: languageName: node linkType: hard +"@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 + "@babel/helper-validator-option@npm:^7.27.1, @babel/helper-validator-option@npm:^7.29.7": version: 7.29.7 resolution: "@babel/helper-validator-option@npm:7.29.7" @@ -2397,6 +2488,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 +2516,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" @@ -2440,6 +2548,17 @@ __metadata: languageName: node linkType: hard +"@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.8" + bin: + parser: ./bin/babel-parser.js + checksum: 10c0/972849212509027148d48d95f2b268abd3d6f72a804ace28fbe09221c1a97686251ba11c19808100169be1e37ba9880f12db980c243f6084eac53b41c44d7a52 + languageName: node + linkType: hard + "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.27.1": version: 7.27.1 resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.27.1" @@ -3679,6 +3798,21 @@ __metadata: languageName: node linkType: hard +"@babel/traverse@npm:^8.0.7": + version: 8.0.7 + resolution: "@babel/traverse@npm:8.0.7" + dependencies: + "@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.6" + obug: "npm:^3.0.0" + checksum: 10c0/191367a20371be56cfadac02b2ae3458be2d7bd0a5d66a60f64b3bff81f858f9acea36f2ee454e24f7267101d4787752334b34f2f9e1b23d22f29995452c3040 + languageName: node + linkType: hard + "@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.13, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.6, @babel/types@npm:^7.26.10, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.5, @babel/types@npm:^7.29.0, @babel/types@npm:^7.29.7, @babel/types@npm:^7.29.8, @babel/types@npm:^7.4.4": version: 7.29.8 resolution: "@babel/types@npm:7.29.8" @@ -3699,6 +3833,16 @@ __metadata: languageName: node linkType: hard +"@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.8" + "@babel/helper-validator-identifier": "npm:^8.0.6" + checksum: 10c0/972b46bdbd00f1638689adedd35d63e113f5789a71973f13266856d019d0d8c04921716c4ebad8395418343d54790448c4091e02f109e0c08826ed747bd53f5f + languageName: node + linkType: hard + "@base-ui/react@npm:1.8.0": version: 1.8.0 resolution: "@base-ui/react@npm:1.8.0" @@ -3756,10 +3900,10 @@ __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 +"@blazediff/core@npm:1.10.0": + version: 1.10.0 + resolution: "@blazediff/core@npm:1.10.0" + checksum: 10c0/4b6095d39338fccd09964fff06f6c5a75628e6296cb2d598149376a876b5c390e083a3769e6ebdaeaa53550f29f1ed5744688df66e4f10b0be0bbc41e9393c8c languageName: node linkType: hard @@ -3860,7 +4004,7 @@ __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" @@ -3870,6 +4014,7 @@ __metadata: tslib: "npm:2.8.1" typescript: "catalog:" uuid: "npm:14.0.0" + vite: "catalog:" vitest: "catalog:" languageName: unknown linkType: soft @@ -5700,14 +5845,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 +7151,7 @@ __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" + "@vitest/browser-playwright": "catalog:" "@zag-js/dom-query": "npm:1.43.0" case-anything: "npm:3.1.0" colorjs.io: "npm:0.6.1" @@ -8197,6 +8342,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 +8389,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: @@ -9270,7 +9425,7 @@ __metadata: "@multiformats/multiaddr": "npm:13.0.3" "@tsconfig/bases": "catalog:" "@types/node": "catalog:" - "@vitest/coverage-istanbul": "npm:4.1.10" + "@vitest/coverage-istanbul": "catalog:" effect: "npm:3.21.0" eslint: "npm:9.39.4" it-stream-types: "npm:2.0.2" @@ -9279,6 +9434,7 @@ __metadata: rimraf: "npm:6.1.3" typescript: "catalog:" uint8arraylist: "npm:3.0.2" + vite: "catalog:" vitest: "catalog:" languageName: unknown linkType: soft @@ -9333,7 +9489,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 +9503,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 +9565,13 @@ __metadata: "@local/tsconfig": "workspace:*" "@temporalio/client": "npm:1.20.2" "@tsconfig/bases": "catalog:" - "@vitest/coverage-istanbul": "npm:4.1.10" + "@vitest/coverage-istanbul": "catalog:" effect: "npm:3.21.0" 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 +9619,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 +9645,7 @@ __metadata: tsx: "catalog:" typescript: "catalog:" uuid: "npm:14.0.0" + vite: "catalog:" vitest: "catalog:" zod: "npm:4.6.7" languageName: unknown @@ -9557,6 +9716,7 @@ __metadata: tinyglobby: "npm:0.2.17" tsx: "catalog:" typescript: "catalog:" + vite: "catalog:" vitest: "catalog:" zod: "npm:4.6.7" languageName: unknown @@ -16719,12 +16879,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 +17614,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 +19202,58 @@ __metadata: languageName: node linkType: hard -"@vitest/browser-playwright@npm:4.1.11": - version: 4.1.11 - resolution: "@vitest/browser-playwright@npm:4.1.11" +"@vitest/browser-playwright@npm:5.0.2": + version: 5.0.2 + resolution: "@vitest/browser-playwright@npm:5.0.2" dependencies: - "@vitest/browser": "npm:4.1.11" - "@vitest/mocker": "npm:4.1.11" - tinyrainbow: "npm:^3.1.0" + "@vitest/browser": "npm:5.0.2" + "@vitest/mocker": "npm:5.0.2" + tinyrainbow: "npm:^3.1.1" peerDependencies: playwright: "*" - vitest: 4.1.11 + vitest: 5.0.2 peerDependenciesMeta: playwright: optional: false - checksum: 10c0/1275e3b7a0a65700c46e309b3afd8a9d98ef36a8478c10a9ae6cb839963ed4fa661d24fe814ed7c32b09b390cc9045d0db54fc805834830af4a642e72d9e0f76 + checksum: 10c0/b9d5f3230c4881170fb99f3982d9c3511eee738408cf2dfb0a8c4aaa791ddae9dc57c01cad77f460e3081385d1c3e56c7d280a6975c03b172378f4917f71c495 languageName: node linkType: hard -"@vitest/browser@npm:4.1.11": - version: 4.1.11 - resolution: "@vitest/browser@npm:4.1.11" +"@vitest/browser@npm:5.0.2": + version: 5.0.2 + resolution: "@vitest/browser@npm:5.0.2" 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" + "@blazediff/core": "npm:1.10.0" + "@vitest/mocker": "npm:5.0.2" + "@vitest/ui": "npm:5.0.2" + "@vitest/utils": "npm:5.0.2" + magic-string: "npm:^1.2.3" pngjs: "npm:^7.0.0" sirv: "npm:^3.0.2" - tinyrainbow: "npm:^3.1.0" - ws: "npm:^8.19.0" + tinyrainbow: "npm:^3.1.1" + ws: "npm:^8.21.3" peerDependencies: - vitest: 4.1.11 - checksum: 10c0/a16b95d043650e82e0706131454d259e660e11fca01d2ce9e336320a482626b2175051e12a93ea18efaf9a794f6cce221919fe59fe27fba04bd9f0e253e6957e + vitest: 5.0.2 + checksum: 10c0/3fa0fd6d4e47ef3bcb352f4f7a9deb331943ba07109ddfa73ca421397fab373dcd16e0cd3b47fd7cd060dcffd02dc9b5681ceaa2474697d71df4eb32315c5c47 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.2": + version: 5.0.2 + resolution: "@vitest/coverage-istanbul@npm:5.0.2" 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.0" + "@vitest/istanbul-lib-instrument": "npm:^1.0.0" + "@vitest/istanbul-lib-report": "npm:^1.0.0" + "@vitest/istanbul-lib-source-maps": "npm:^1.0.0" + magicast: "npm:^0.5.4" + obug: "npm:^2.1.4" + tinyrainbow: "npm:^3.1.1" peerDependencies: - vitest: 4.1.10 - checksum: 10c0/a426b0aff94482587a100db7e8db4e238fabf9e5bc4d33a319bd9cd4261b8972a7b3d78f2bc7cbc3d11b0b58b5d7cc487f96ab35a96c1c766c54f9b6d5eb4f78 + vitest: 5.0.2 + checksum: 10c0/f67e1da4d2d30405cfbdabff890ca37c01e56bfda40ab1d8fa90c68b2fa5597162483e887cedf7f4248ae17d2098644a66ed98243b86e3a17ca22aa7e1da45cf languageName: node linkType: hard @@ -19119,27 +19287,54 @@ __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.0": + 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.0": + 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.0": + 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.0": + 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.2": + version: 5.0.2 + resolution: "@vitest/mocker@npm:5.0.2" + dependencies: + "@jridgewell/trace-mapping": "npm:0.3.31" + "@vitest/spy": "npm:5.0.2" estree-walker: "npm:^3.0.3" - magic-string: "npm:^0.30.21" + magic-string: "npm:^1.2.3" peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -19148,7 +19343,7 @@ __metadata: optional: true vite: optional: true - checksum: 10c0/3111ea34bd5046f6c70bbd67cf8b89608ee8c41cb27ab2bd61d42f4b68810e9ea16a9a757a71bc254c105f73b407d00ebb6bab1ab0f7f5cdcc9d7d16602a3933 + checksum: 10c0/e2d847563d47b61e9f3e5ed2d86af42b753311cd52c94ef7226398fd6f810b96ca4737855bcc4a59d78a0300859db50693d831ab29ca6334b159cc8e870f8149 languageName: node linkType: hard @@ -19161,34 +19356,12 @@ __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" +"@vitest/pretty-format@npm:5.0.2": + version: 5.0.2 + resolution: "@vitest/pretty-format@npm:5.0.2" 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 + tinyrainbow: "npm:^3.1.1" + checksum: 10c0/fd3a6c7ab541ca1cf9b21cc8f44e141f50e5d07eb456edb85f1f9eacfd3a276a9ab5a442cbc35c023c3fc0f05cf2bfa022a7960d33538a2872db2043bf207616 languageName: node linkType: hard @@ -19201,10 +19374,26 @@ __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.2": + version: 5.0.2 + resolution: "@vitest/spy@npm:5.0.2" + checksum: 10c0/4a52231cc7b5b8959bb15a700a761464051a6d0cc35a231fc92fd4f58d10a01012671a20ea37ebc79e98bdd5dc257a3c52db10d6a592944560fb69651f6f1296 + languageName: node + linkType: hard + +"@vitest/ui@npm:5.0.2": + version: 5.0.2 + resolution: "@vitest/ui@npm:5.0.2" + dependencies: + "@vitest/utils": "npm:5.0.2" + fflate: "npm:^0.8.3" + flatted: "npm:^3.4.4" + pathe: "npm:^2.0.3" + sirv: "npm:^3.0.2" + tinyrainbow: "npm:^3.1.1" + peerDependencies: + vitest: 5.0.2 + checksum: 10c0/f232eae237a794b211a1c23ce10e98d125233070af23caaa92e7b89222a6118030df05525c094f493d650bfdcc190636763da1d5e3ed35976a59e6eefa0db5de languageName: node linkType: hard @@ -19219,14 +19408,14 @@ __metadata: languageName: node linkType: hard -"@vitest/utils@npm:4.1.11": - version: 4.1.11 - resolution: "@vitest/utils@npm:4.1.11" +"@vitest/utils@npm:5.0.2": + version: 5.0.2 + resolution: "@vitest/utils@npm:5.0.2" dependencies: - "@vitest/pretty-format": "npm:4.1.11" + "@vitest/pretty-format": "npm:5.0.2" convert-source-map: "npm:^2.0.0" - tinyrainbow: "npm:^3.1.0" - checksum: 10c0/a2c1ddc64333458c3e031465c1ee0440a7660fd1b298c54ccbf865ef1e5cf3ebdd6c5c75a5ea235d8a672498b394e7121f992b096f021f45014ab25e9abd1b52 + tinyrainbow: "npm:^3.1.1" + checksum: 10c0/5711e43595ce7afe83d0989f301ad6bc00605786fc39242953d2885fbdee2956e51d4ee32ad005234b4d81887538c385d480fe635d609a1646eb530d5b0802b6 languageName: node linkType: hard @@ -24498,6 +24687,13 @@ __metadata: languageName: node linkType: hard +"empathic@npm:^2.0.1": + version: 2.1.0 + resolution: "empathic@npm:2.1.0" + checksum: 10c0/cf13e2919d680a22140d7cd1637a01f6cf9a727f21d3a54b23489ec01c80eab548b9d832d2e167d00e124a54377660c1d6fd2b5947d905366e4d22fde7b9e082 + languageName: node + linkType: hard + "enabled@npm:2.0.x": version: 2.0.0 resolution: "enabled@npm:2.0.0" @@ -24738,13 +24934,20 @@ __metadata: languageName: node linkType: hard -"es-module-lexer@npm:^2.0.0, es-module-lexer@npm:^2.1.0": +"es-module-lexer@npm:^2.1.0": version: 2.1.0 resolution: "es-module-lexer@npm:2.1.0" checksum: 10c0/93bcf2454fa72d67fe3ccd0abef8ce7933f5840a319513418a643dd8e9c6aa8f49709cecfae02ded722805dd327232d30723a807cc52e6809d6ac697c62c29fb languageName: node linkType: hard +"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 + "es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1": version: 1.1.1 resolution: "es-object-atoms@npm:1.1.1" @@ -26207,10 +26410,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 @@ -26610,6 +26813,13 @@ __metadata: languageName: node linkType: hard +"fflate@npm:^0.8.3": + version: 0.8.3 + resolution: "fflate@npm:0.8.3" + checksum: 10c0/eab181ca37f5348ae76d4b6f840e0026e30220e33153289ac942222d8b9638237d486507dbcc09878d724095bd354993a2ee48bbee99c8f2c6440d4448719aa7 + languageName: node + linkType: hard + "figures@npm:^3.2.0": version: 3.2.0 resolution: "figures@npm:3.2.0" @@ -26809,6 +27019,20 @@ __metadata: languageName: node linkType: hard +"flatted@npm:^3.4.4": + 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 + "fn.name@npm:1.x.x": version: 1.1.0 resolution: "fn.name@npm:1.1.0" @@ -28229,7 +28453,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 +29948,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" @@ -31420,7 +31616,16 @@ __metadata: languageName: node linkType: hard -"magicast@npm:^0.5.2": +"magic-string@npm:^1.2.3": + version: 1.4.5 + resolution: "magic-string@npm:1.4.5" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.6.0" + checksum: 10c0/79295b85e19f2e18bb01b81671d27ae192546e88534dfcef2e36f2c04f45b39db497ce85a62efda0336356308cdc037a1c73fc0f1bd0945d12ae1e794163b247 + languageName: node + linkType: hard + +"magicast@npm:^0.5.4": version: 0.5.5 resolution: "magicast@npm:0.5.5" dependencies: @@ -31445,15 +31650,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" @@ -33619,6 +33815,13 @@ __metadata: 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" @@ -37866,7 +38069,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 +38472,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" @@ -38651,13 +38847,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 +38901,7 @@ __metadata: languageName: node linkType: hard -"std-env@npm:^4.0.0-rc.1": +"std-env@npm:^4.2.0": version: 4.3.0 resolution: "std-env@npm:4.3.0" checksum: 10c0/1e90dc69f32f853375c6de45dbe7219c8399e2a3ab3a972fdcd1cf3c20fe0e3c13bf58d57d6193b551d37a81c50dfb3f51e07774e9e48a7dc5a22dabcad7acbd @@ -39548,10 +39737,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.1.4": + version: 6.2.2 + resolution: "tinybench@npm:6.2.2" + checksum: 10c0/f0e6391f4ca86875ce5a64510696323aa841c10495fdd1c6ca530457c7e77f2b3aa82d9d6f1553126420062b1008607257677ce2b25ff1948732a79d7a56514a languageName: node linkType: hard @@ -39562,7 +39751,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 +39782,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.1.1": + version: 3.2.0 + resolution: "tinyrainbow@npm:3.2.0" + checksum: 10c0/22d9c303cd807026898dcb5ac5ffbf725b5a2cc8d042449769aed8f1266be94de5e95206b76cac948f68facafba5b80e9a9257c82e5fed2651be3fecf2b624ab languageName: node linkType: hard @@ -41338,6 +41527,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,7 +41606,7 @@ __metadata: languageName: node linkType: hard -"vite@npm:8.3.4, vite@npm:^6.0.0 || ^7.0.0 || ^8.0.0": +"vite@npm:8.3.4": version: 8.3.4 resolution: "vite@npm:8.3.4" dependencies: @@ -41485,43 +41681,36 @@ __metadata: 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.2": + version: 5.0.2 + resolution: "vitest@npm:5.0.2" + dependencies: + "@types/chai": "npm:^5.2.2" + "@vitest/mocker": "npm:5.0.2" + chai: "npm:^6.2.2" + es-module-lexer: "npm:^2.3.2" + expect-type: "npm:^1.4.0" + magic-string: "npm:^1.2.3" + obug: "npm:^2.1.4" + picomatch: "npm:^4.0.7" + std-env: "npm:^4.2.0" + tinybench: "npm:^6.1.4" + tinyexec: "npm:^1.3.0" + 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.2 + "@vitest/browser-preview": 5.0.2 + "@vitest/browser-webdriverio": ^5.0.0-beta.5 || >=5.0.0 + "@vitest/coverage-istanbul": 5.0.2 + "@vitest/coverage-v8": 5.0.2 + "@vitest/ui": 5.0.2 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 +41738,7 @@ __metadata: optional: false bin: vitest: ./vitest.mjs - checksum: 10c0/3fa0948cf74adcccc8cbcdb4e6d30ada6933bdfb1816ff99200f3d3b689325b37dc483b22535b57b6d911f7a7b64eaa6a5f8da1606cfe7f2466f48000c21e296 + checksum: 10c0/e86919375db85ddecc6308076341f66a9d51c3b28aa7966ea6bcb0f45234b5e2883602c17e509abfa6d729aaf8113b3adf7b59a8316079c2c9a48dbb1b248897 languageName: node linkType: hard @@ -42093,15 +42282,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.3 + resolution: "why-is-node-running@npm:3.2.3" bin: why-is-node-running: cli.js - checksum: 10c0/1cde0b01b827d2cf4cb11db962f3958b9175d5d9e7ac7361d1a7b0e2dc6069a263e69118bd974c4f6d0a890ef4eedfe34cf3d5167ec14203dbc9a18620537054 + checksum: 10c0/312c87f0704765fe2bb680fcc1768807c39c987d8e94c363a05ea29b0cbea3de57c6595745c7969f73cca079a70303f88fb247f84749640d5b02310c0a4b2ecf languageName: node linkType: hard @@ -42277,7 +42463,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.18.2, 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: From b2916aac2ad32bf605e65b40d73b54ee0960b94b Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud <7252775+indietyp@users.noreply.github.com> Date: Tue, 6 Oct 2026 23:30:55 +0200 Subject: [PATCH 02/17] fix: isolate effect hooks in concurrent tests --- ...@effect-vitest-npm-0.29.0-1c8cf3c306.patch | 55 ++++++++++++------- .../src/provider-registration.test.ts | 50 +++++++++-------- yarn.lock | 4 +- 3 files changed, 65 insertions(+), 44 deletions(-) diff --git a/.yarn/patches/@effect-vitest-npm-0.29.0-1c8cf3c306.patch b/.yarn/patches/@effect-vitest-npm-0.29.0-1c8cf3c306.patch index 377271df330..d894299f8cd 100644 --- a/.yarn/patches/@effect-vitest-npm-0.29.0-1c8cf3c306.patch +++ b/.yarn/patches/@effect-vitest-npm-0.29.0-1c8cf3c306.patch @@ -1,35 +1,39 @@ diff --git a/dist/cjs/internal/internal.js b/dist/cjs/internal/internal.js -index dee6eec6cd0646708773eb9e89d4e835858b3f5c..b9ce97e9b481980ff5a9092bf09c8d3179fed495 100644 +index dee6eec..14424ac 100644 --- a/dist/cjs/internal/internal.js +++ b/dist/cjs/internal/internal.js -@@ -28,7 +28,9 @@ const defaultApi = /*#__PURE__*/Object.assign(V.it, { +@@ -28,7 +28,11 @@ 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)); ++ // Register on the test's own context, which concurrent tests do not share. ++ // Vitest 4.0 contexts had no onTestFinished, so use the global hook there. ++ if (ctx) { ++ (ctx.onTestFinished ?? 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 +index adb6b21..379aee7 100644 --- a/dist/esm/internal/internal.js +++ b/dist/esm/internal/internal.js -@@ -21,7 +21,9 @@ const defaultApi = /*#__PURE__*/Object.assign(V.it, { +@@ -21,7 +21,11 @@ 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)); ++ // Register on the test's own context, which concurrent tests do not share. ++ // Vitest 4.0 contexts had no onTestFinished, so use the global hook there. ++ if (ctx) { ++ (ctx.onTestFinished ?? 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 +index 1ceac68..ac43401 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ @@ -37,22 +41,33 @@ index 1ceac68f8e5cfed5d014c4066414c4f8eec67a69..3c5cac8abdae6087e927fab2669b736c "homepage": "https://effect.website", "peerDependencies": { - "vitest": "^3.2.0", -+ "vitest": "^3.2.0 || ^4.0.0", ++ "vitest": "^3.2.0 || ^4.0.0 || ^5.0.0", "effect": "^3.21.0" }, "publishConfig": { diff --git a/src/internal/internal.ts b/src/internal/internal.ts -index bd11019b8ad51bd49cc3015f8c69aac04ad18822..1d8a04e1ae3d195d75553fb3944efdd9720f64ca 100644 +index bd11019..9313f73 100644 --- a/src/internal/internal.ts +++ b/src/internal/internal.ts -@@ -29,7 +29,9 @@ const runPromise = (ctx?: Vitest.TestContext) => (effect: Effect.Effect (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 +- Fiber.interrupt(exitFiber).pipe( +- Effect.asVoid, +- Effect.runPromise ++ // Register on the test's own context, which concurrent tests do not share. ++ // Vitest 4.0 contexts had no onTestFinished, so use the global hook there. ++ if (ctx) { ++ ;(ctx.onTestFinished ?? V.onTestFinished)(() => ++ Fiber.interrupt(exitFiber).pipe( ++ Effect.asVoid, ++ Effect.runPromise ++ ) + ) +- ) ++ } + + const exit = yield* Fiber.join(exitFiber) + if (Exit.isSuccess(exit)) { diff --git a/apps/brunch-agent/src/provider-registration.test.ts b/apps/brunch-agent/src/provider-registration.test.ts index dfeb276ef95..9ed808d9b55 100644 --- a/apps/brunch-agent/src/provider-registration.test.ts +++ b/apps/brunch-agent/src/provider-registration.test.ts @@ -52,29 +52,36 @@ vi.mock( }; }, ); +let registeredProviders: Parameters[0][] = []; +let instrumentations: Parameters[0][] = []; +let nativeOpenRouterProvider: Provider | undefined; + beforeAll(async () => { await import("./app"); + registeredProviders = vi + .mocked(setProvider) + .mock.calls.map(([provider]) => provider); + instrumentations = vi + .mocked(instrument) + .mock.calls.map(([instrumentation]) => instrumentation); + const { openrouterProvider } = + await import("@earendil-works/pi-ai/providers/openrouter"); + const result = vi.mocked(openrouterProvider).mock.results[0]; + nativeOpenRouterProvider = + result?.type === "return" ? result.value : undefined; }); test("app registration admits the Anthropic, OpenAI and OpenRouter providers", () => { - const ids = vi - .mocked(setProvider) - .mock.calls.map(([entry]) => entry.id) - .sort(); + const ids = registeredProviders.map((provider) => provider.id).sort(); expect(ids).toEqual(["anthropic", "openai", "openrouter"]); }); test("app registration admits native OpenRouter with GPT-6.1 Sol and its API-key auth", async () => { - const { openrouterProvider } = - await import("@earendil-works/pi-ai/providers/openrouter"); - const native = vi.mocked(openrouterProvider).mock.results[0]?.value as - | Provider - | undefined; + const native = nativeOpenRouterProvider; expect(native).toBeDefined(); - const provider = vi - .mocked(setProvider) - .mock.calls.map(([entry]) => entry) - .find((entry) => entry.id === "openrouter")!; + const provider = registeredProviders.find( + (provider) => provider.id === "openrouter", + )!; expect(provider.auth).toBe(native!.auth); // The catalogue extension keeps native streams, so a different stream is the admission wrapper. expect(Reflect.get(provider, "streamSimple")).not.toBe( @@ -108,16 +115,15 @@ const drain = async (stream: ReturnType) => { }; test("app registration scopes admission to the Petrinaut agent's execution, isolating concurrent agents and delegated tasks", async () => { - const registration = vi - .mocked(instrument) - .mock.calls.find( - ([entry]) => entry.key === Symbol.for("brunch.buffered-tool-admission"), - )?.[0]; + const registration = instrumentations.find( + (instrumentation) => + instrumentation.key === Symbol.for("brunch.buffered-tool-admission"), + ); expect(registration).toBeDefined(); - const provider = vi - .mocked(setProvider) - .mock.calls.map(([entry]) => entry) - .find((entry) => entry.id === "anthropic")!; + const provider = registeredProviders.find( + (provider) => provider.id === "anthropic", + )!; + expect(provider.auth).toBe(faux.provider.auth); expect(provider.getModels()).toEqual(faux.provider.getModels()); const model = provider.getModels()[0]!; diff --git a/yarn.lock b/yarn.lock index 9dd25c331fc..609d47005ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4905,11 +4905,11 @@ __metadata: "@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" + 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=bc0d2f" peerDependencies: effect: ^3.21.0 vitest: ^3.2.0 - checksum: 10c0/28127e1aa22928e58c0b09cf0494e38baac3fe0397223273136c78cce6b21650c7f73935e32a05e116d1c10e0b552552011bbe213a67de3975522712690a6e6f + checksum: 10c0/9279825836f9efa7f2da6c94162a2b5782963a4c8a1cb63cc76ea534436d20220051cbe2211a97f4e7768bcea45c4642d3bcae51ac1f9491f0b885caaff436b3 languageName: node linkType: hard From 193649e9b8c6db1280cb1190cd95f7cf23a1ea61 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud <7252775+indietyp@users.noreply.github.com> Date: Wed, 7 Oct 2026 16:37:08 +0200 Subject: [PATCH 03/17] test: migrate codec benchmarks to vitest bench API --- .../tests/wire-protocol/codec.bench.ts | 40 +++++++++++-------- 1 file changed, 23 insertions(+), 17 deletions(-) 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..da5462a595a 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,5 +1,5 @@ import { Either, FastCheck, pipe } from "effect"; -import { bench, describe } from "vitest"; +import { describe, test } from "vitest"; import { MutableBuffer, MutableBytes } from "../../src/binary/index.js"; import { Request } from "../../src/wire-protocol/models/request/index.js"; @@ -35,29 +35,35 @@ const responseEncoded = pipe( ); 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( + Either.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); + }).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( + Either.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); + }).run(); }); }); From f053c7921ff47edf356666c8302146f3d37d6be9 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud <7252775+indietyp@users.noreply.github.com> Date: Mon, 26 Oct 2026 10:20:03 +0100 Subject: [PATCH 04/17] chore: update vitest dependencies to 5.0.5 --- .yarnrc.yml | 6 +- yarn.lock | 188 ++++++++++++++++++++++++++-------------------------- 2 files changed, 97 insertions(+), 97 deletions(-) diff --git a/.yarnrc.yml b/.yarnrc.yml index 6404163e47e..de27630db03 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -40,9 +40,9 @@ catalog: typescript: "7.0.2" "@typescript/typescript6": "6.0.2" vite: "8.3.4" - vitest: "5.0.2" - "@vitest/browser-playwright": "5.0.2" - "@vitest/coverage-istanbul": "5.0.2" + vitest: "5.0.5" + "@vitest/browser-playwright": "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/yarn.lock b/yarn.lock index 609d47005ac..a9ac8ba069f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19202,58 +19202,58 @@ __metadata: languageName: node linkType: hard -"@vitest/browser-playwright@npm:5.0.2": - version: 5.0.2 - resolution: "@vitest/browser-playwright@npm:5.0.2" +"@vitest/browser-playwright@npm:5.0.5": + version: 5.0.5 + resolution: "@vitest/browser-playwright@npm:5.0.5" dependencies: - "@vitest/browser": "npm:5.0.2" - "@vitest/mocker": "npm:5.0.2" - tinyrainbow: "npm:^3.1.1" + "@vitest/browser": "npm:5.0.5" + "@vitest/mocker": "npm:5.0.5" + tinyrainbow: "npm:^3.2.0" peerDependencies: playwright: "*" - vitest: 5.0.2 + vitest: 5.0.5 peerDependenciesMeta: playwright: optional: false - checksum: 10c0/b9d5f3230c4881170fb99f3982d9c3511eee738408cf2dfb0a8c4aaa791ddae9dc57c01cad77f460e3081385d1c3e56c7d280a6975c03b172378f4917f71c495 + checksum: 10c0/f788f48d07d2e1680cddfef4db22506e1a9783c27a37bafcefdba36782ee0c5f6fc85a2008f9feaa305a877b4183c10b6edcd300136d479b2a1b83fbeb936082 languageName: node linkType: hard -"@vitest/browser@npm:5.0.2": - version: 5.0.2 - resolution: "@vitest/browser@npm:5.0.2" +"@vitest/browser@npm:5.0.5": + version: 5.0.5 + resolution: "@vitest/browser@npm:5.0.5" dependencies: "@blazediff/core": "npm:1.10.0" - "@vitest/mocker": "npm:5.0.2" - "@vitest/ui": "npm:5.0.2" - "@vitest/utils": "npm:5.0.2" - magic-string: "npm:^1.2.3" + "@vitest/mocker": "npm:5.0.5" + "@vitest/ui": "npm:5.0.5" + "@vitest/utils": "npm:5.0.5" + magic-string: "npm:^1.4.3" pngjs: "npm:^7.0.0" sirv: "npm:^3.0.2" - tinyrainbow: "npm:^3.1.1" - ws: "npm:^8.21.3" + tinyrainbow: "npm:^3.2.0" + ws: "npm:^8.22.0" peerDependencies: - vitest: 5.0.2 - checksum: 10c0/3fa0fd6d4e47ef3bcb352f4f7a9deb331943ba07109ddfa73ca421397fab373dcd16e0cd3b47fd7cd060dcffd02dc9b5681ceaa2474697d71df4eb32315c5c47 + vitest: 5.0.5 + checksum: 10c0/04e1a02bf752ecc86f01676a1f95dfcadc5472a4c0835ecb42aa0e0f6226cac8e0b6a1325cdc2c3d973b489dafdc97e22a039aac1abfff55bb9fb192b89e280f languageName: node linkType: hard -"@vitest/coverage-istanbul@npm:5.0.2": - version: 5.0.2 - resolution: "@vitest/coverage-istanbul@npm:5.0.2" +"@vitest/coverage-istanbul@npm:5.0.5": + version: 5.0.5 + resolution: "@vitest/coverage-istanbul@npm:5.0.5" dependencies: "@jridgewell/gen-mapping": "npm:^0.3.13" "@jridgewell/trace-mapping": "npm:0.3.31" - "@vitest/istanbul-lib-coverage": "npm:^1.0.0" - "@vitest/istanbul-lib-instrument": "npm:^1.0.0" - "@vitest/istanbul-lib-report": "npm:^1.0.0" - "@vitest/istanbul-lib-source-maps": "npm:^1.0.0" - magicast: "npm:^0.5.4" - obug: "npm:^2.1.4" - tinyrainbow: "npm:^3.1.1" + "@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: 5.0.2 - checksum: 10c0/f67e1da4d2d30405cfbdabff890ca37c01e56bfda40ab1d8fa90c68b2fa5597162483e887cedf7f4248ae17d2098644a66ed98243b86e3a17ca22aa7e1da45cf + vitest: 5.0.5 + checksum: 10c0/02ac31527fe0ef97c05e72d455b18d1782b05702fa630b8df99423e476eaded003a5b5540e75c18837bd2323117a32e2814389fab996c560e0cb930af4c2a506 languageName: node linkType: hard @@ -19287,14 +19287,14 @@ __metadata: languageName: node linkType: hard -"@vitest/istanbul-lib-coverage@npm:1.0.2, @vitest/istanbul-lib-coverage@npm:^1.0.0": +"@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.0": +"@vitest/istanbul-lib-instrument@npm:^1.0.2": version: 1.0.2 resolution: "@vitest/istanbul-lib-instrument@npm:1.0.2" dependencies: @@ -19307,7 +19307,7 @@ __metadata: languageName: node linkType: hard -"@vitest/istanbul-lib-report@npm:^1.0.0": +"@vitest/istanbul-lib-report@npm:^1.0.2": version: 1.0.2 resolution: "@vitest/istanbul-lib-report@npm:1.0.2" dependencies: @@ -19316,7 +19316,7 @@ __metadata: languageName: node linkType: hard -"@vitest/istanbul-lib-source-maps@npm:^1.0.0": +"@vitest/istanbul-lib-source-maps@npm:^1.0.2": version: 1.0.2 resolution: "@vitest/istanbul-lib-source-maps@npm:1.0.2" dependencies: @@ -19327,23 +19327,23 @@ __metadata: languageName: node linkType: hard -"@vitest/mocker@npm:5.0.2": - version: 5.0.2 - resolution: "@vitest/mocker@npm:5.0.2" +"@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.2" + "@vitest/spy": "npm:5.0.5" estree-walker: "npm:^3.0.3" - magic-string: "npm:^1.2.3" + 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/e2d847563d47b61e9f3e5ed2d86af42b753311cd52c94ef7226398fd6f810b96ca4737855bcc4a59d78a0300859db50693d831ab29ca6334b159cc8e870f8149 + checksum: 10c0/5d5573d6015ef948d6cb193feb025874b6776f35964745c6beb3e556467b6dbfcbb103c4ce01d2d50b7fb43b83f56172c5074e0dd3da4dc5673ea1870b69a722 languageName: node linkType: hard @@ -19356,12 +19356,12 @@ __metadata: languageName: node linkType: hard -"@vitest/pretty-format@npm:5.0.2": - version: 5.0.2 - resolution: "@vitest/pretty-format@npm:5.0.2" +"@vitest/pretty-format@npm:5.0.5": + version: 5.0.5 + resolution: "@vitest/pretty-format@npm:5.0.5" dependencies: - tinyrainbow: "npm:^3.1.1" - checksum: 10c0/fd3a6c7ab541ca1cf9b21cc8f44e141f50e5d07eb456edb85f1f9eacfd3a276a9ab5a442cbc35c023c3fc0f05cf2bfa022a7960d33538a2872db2043bf207616 + tinyrainbow: "npm:^3.2.0" + checksum: 10c0/7d484e42542e3e04ee669cfd2632c001ca3c4493477c4fc539c3c1465cb511b9c46789f63aacf0fd40c312c023add17933b0864eb02d8640e44b69ffdad853c5 languageName: node linkType: hard @@ -19374,26 +19374,26 @@ __metadata: languageName: node linkType: hard -"@vitest/spy@npm:5.0.2": - version: 5.0.2 - resolution: "@vitest/spy@npm:5.0.2" - checksum: 10c0/4a52231cc7b5b8959bb15a700a761464051a6d0cc35a231fc92fd4f58d10a01012671a20ea37ebc79e98bdd5dc257a3c52db10d6a592944560fb69651f6f1296 +"@vitest/spy@npm:5.0.5": + version: 5.0.5 + resolution: "@vitest/spy@npm:5.0.5" + checksum: 10c0/a48d92e38497e587cbb17b0ddb85604abaddf367e1cd4e373000ab080198511253fd35bf6a0e9a973e052e728c3235070a0b33ba6f2da1998aa5d65b64299783 languageName: node linkType: hard -"@vitest/ui@npm:5.0.2": - version: 5.0.2 - resolution: "@vitest/ui@npm:5.0.2" +"@vitest/ui@npm:5.0.5": + version: 5.0.5 + resolution: "@vitest/ui@npm:5.0.5" dependencies: - "@vitest/utils": "npm:5.0.2" + "@vitest/utils": "npm:5.0.5" fflate: "npm:^0.8.3" flatted: "npm:^3.4.4" pathe: "npm:^2.0.3" sirv: "npm:^3.0.2" - tinyrainbow: "npm:^3.1.1" + tinyrainbow: "npm:^3.2.0" peerDependencies: - vitest: 5.0.2 - checksum: 10c0/f232eae237a794b211a1c23ce10e98d125233070af23caaa92e7b89222a6118030df05525c094f493d650bfdcc190636763da1d5e3ed35976a59e6eefa0db5de + vitest: 5.0.5 + checksum: 10c0/93f26d0fa82f5fd5a4ac1a830a23424f6dd060e88a1352818eef8bfc8441039be400b2b596c6ca14f54425173f6875dc23e8a233be681379a06abf6b91906b9e languageName: node linkType: hard @@ -19408,14 +19408,14 @@ __metadata: languageName: node linkType: hard -"@vitest/utils@npm:5.0.2": - version: 5.0.2 - resolution: "@vitest/utils@npm:5.0.2" +"@vitest/utils@npm:5.0.5": + version: 5.0.5 + resolution: "@vitest/utils@npm:5.0.5" dependencies: - "@vitest/pretty-format": "npm:5.0.2" + "@vitest/pretty-format": "npm:5.0.5" convert-source-map: "npm:^2.0.0" - tinyrainbow: "npm:^3.1.1" - checksum: 10c0/5711e43595ce7afe83d0989f301ad6bc00605786fc39242953d2885fbdee2956e51d4ee32ad005234b4d81887538c385d480fe635d609a1646eb530d5b0802b6 + tinyrainbow: "npm:^3.2.0" + checksum: 10c0/424e7e2e8e2481385bc66a327531ae8c99fd63080778e17b8a75223bbd9d61d5c6d162db8e31ec7d6f17e6206cdc95e8d3d08b1fc8be3c9f50ee0ddf6862b641 languageName: node linkType: hard @@ -22524,10 +22524,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 @@ -31616,7 +31616,7 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:^1.2.3": +"magic-string@npm:^1.4.3": version: 1.4.5 resolution: "magic-string@npm:1.4.5" dependencies: @@ -31625,7 +31625,7 @@ __metadata: languageName: node linkType: hard -"magicast@npm:^0.5.4": +"magicast@npm:^0.5.5": version: 0.5.5 resolution: "magicast@npm:0.5.5" dependencies: @@ -38901,7 +38901,7 @@ __metadata: languageName: node linkType: hard -"std-env@npm:^4.2.0": +"std-env@npm:^4.3.0": version: 4.3.0 resolution: "std-env@npm:4.3.0" checksum: 10c0/1e90dc69f32f853375c6de45dbe7219c8399e2a3ab3a972fdcd1cf3c20fe0e3c13bf58d57d6193b551d37a81c50dfb3f51e07774e9e48a7dc5a22dabcad7acbd @@ -39737,7 +39737,7 @@ __metadata: languageName: node linkType: hard -"tinybench@npm:^6.1.4": +"tinybench@npm:^6.2.2": version: 6.2.2 resolution: "tinybench@npm:6.2.2" checksum: 10c0/f0e6391f4ca86875ce5a64510696323aa841c10495fdd1c6ca530457c7e77f2b3aa82d9d6f1553126420062b1008607257677ce2b25ff1948732a79d7a56514a @@ -39782,7 +39782,7 @@ __metadata: languageName: node linkType: hard -"tinyrainbow@npm:^3.1.1": +"tinyrainbow@npm:^3.2.0": version: 3.2.0 resolution: "tinyrainbow@npm:3.2.0" checksum: 10c0/22d9c303cd807026898dcb5ac5ffbf725b5a2cc8d042449769aed8f1266be94de5e95206b76cac948f68facafba5b80e9a9257c82e5fed2651be3fecf2b624ab @@ -41681,33 +41681,33 @@ __metadata: languageName: node linkType: hard -"vitest@npm:5.0.2": - version: 5.0.2 - resolution: "vitest@npm:5.0.2" +"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.2" - chai: "npm:^6.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.2.3" - obug: "npm:^2.1.4" + magic-string: "npm:^1.4.3" + obug: "npm:^3.0.0" picomatch: "npm:^4.0.7" - std-env: "npm:^4.2.0" - tinybench: "npm:^6.1.4" - tinyexec: "npm:^1.3.0" + 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" + why-is-node-running: "npm:3.2.1" peerDependencies: "@edge-runtime/vm": "*" "@opentelemetry/api": ^1.9.0 "@types/node": ^22.0.0 || >=24.0.0 - "@vitest/browser-playwright": 5.0.2 - "@vitest/browser-preview": 5.0.2 + "@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.2 - "@vitest/coverage-v8": 5.0.2 - "@vitest/ui": 5.0.2 + "@vitest/coverage-istanbul": 5.0.5 + "@vitest/coverage-v8": 5.0.5 + "@vitest/ui": 5.0.5 happy-dom: "*" jsdom: "*" vite: ^6.4.0 || ^7.0.0 || ^8.0.0 @@ -41738,7 +41738,7 @@ __metadata: optional: false bin: vitest: ./vitest.mjs - checksum: 10c0/e86919375db85ddecc6308076341f66a9d51c3b28aa7966ea6bcb0f45234b5e2883602c17e509abfa6d729aaf8113b3adf7b59a8316079c2c9a48dbb1b248897 + checksum: 10c0/b6e38164490c4ca0c2bbc4e74ec8f9052a344caab3f3bf0e8c4485b6493af0f789d7aafd41f4128f66d576f50d3c860f0674322add2b4d348b6ea250ec8c77c8 languageName: node linkType: hard @@ -42282,12 +42282,12 @@ __metadata: languageName: node linkType: hard -"why-is-node-running@npm:^3.2.1": - version: 3.2.3 - resolution: "why-is-node-running@npm:3.2.3" +"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/312c87f0704765fe2bb680fcc1768807c39c987d8e94c363a05ea29b0cbea3de57c6595745c7969f73cca079a70303f88fb247f84749640d5b02310c0a4b2ecf + checksum: 10c0/e3f82673aac2c0a330fdbcf4b282ecdf7e9c773fa82fb4217db5b8b3d374cbb51e708d928f5b17999bc65bc1a5a90fad0f6bd794641bd15fdd525949ccee5e39 languageName: node linkType: hard From 50a3aa730f17fb70ab716ae29a3c2c932af414d0 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud <7252775+indietyp@users.noreply.github.com> Date: Wed, 28 Oct 2026 13:54:43 +0100 Subject: [PATCH 05/17] chore: deduplicate compatible lockfile entries --- yarn.lock | 129 ++++-------------------------------------------------- 1 file changed, 9 insertions(+), 120 deletions(-) diff --git a/yarn.lock b/yarn.lock index a9ac8ba069f..f2aa76a8c36 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2031,17 +2031,7 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^8.0.0": - version: 8.0.0 - resolution: "@babel/code-frame@npm:8.0.0" - dependencies: - "@babel/helper-validator-identifier": "npm:^8.0.0" - js-tokens: "npm:^10.0.0" - checksum: 10c0/2ea8614018bcd8c86358ab6aa930508115d2205e5e111f736d355b150453818bdf487850f6dec5ec92a10bf27ba4536f4b3b8ad9204514e43d8d68ff2e542443 - languageName: node - linkType: hard - -"@babel/code-frame@npm:^8.0.6": +"@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: @@ -2148,20 +2138,6 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^8.0.0": - version: 8.0.0 - resolution: "@babel/generator@npm:8.0.0" - 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" - "@types/jsesc": "npm:^2.5.0" - jsesc: "npm:^3.0.2" - checksum: 10c0/2b2d171beaedcacca62164f0f39bc8962df5f9700a54c5515174276ea20b3a53933e9804e0b35c2be1059108a764447d99d0c5beb63ecbbf8c66035ca6c003c4 - languageName: node - linkType: hard - "@babel/generator@npm:^8.0.6": version: 8.0.6 resolution: "@babel/generator@npm:8.0.6" @@ -2289,13 +2265,6 @@ __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 - languageName: node - linkType: hard - "@babel/helper-globals@npm:^8.0.6": version: 8.0.6 resolution: "@babel/helper-globals@npm:8.0.6" @@ -2446,13 +2415,6 @@ __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 - languageName: node - linkType: hard - "@babel/helper-string-parser@npm:^8.0.8": version: 8.0.8 resolution: "@babel/helper-string-parser@npm:8.0.8" @@ -2467,13 +2429,6 @@ __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 - languageName: node - linkType: hard - "@babel/helper-validator-identifier@npm:^8.0.6": version: 8.0.6 resolution: "@babel/helper-validator-identifier@npm:8.0.6" @@ -2537,18 +2492,7 @@ __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" - dependencies: - "@babel/types": "npm:^8.0.4" - bin: - parser: ./bin/babel-parser.js - checksum: 10c0/b98ebc350e6583ccec0c59ab653e6c5967935826b8e03210a96e638a98b0c552587d4ca9cc44502964bac42463e2bab93ca1a6ac519279a25e190bd78f3ce513 - languageName: node - linkType: hard - -"@babel/parser@npm:^8.0.6, @babel/parser@npm:^8.0.7, @babel/parser@npm:^8.0.8": +"@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: @@ -3783,22 +3727,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^8.0.0": - version: 8.0.4 - resolution: "@babel/traverse@npm:8.0.4" - 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/template": "npm:^8.0.0" - "@babel/types": "npm:^8.0.4" - obug: "npm:^2.1.1" - checksum: 10c0/0b7917580320c10027f660c97b754f883d11430bd4c9f877b1f57f424f31fd5a1e7260170be08f0197cbcf8abe65078063864e358cf024c90b64504837f3112e - languageName: node - linkType: hard - -"@babel/traverse@npm:^8.0.7": +"@babel/traverse@npm:^8.0.0, @babel/traverse@npm:^8.0.7": version: 8.0.7 resolution: "@babel/traverse@npm:8.0.7" dependencies: @@ -3823,17 +3752,7 @@ __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" - dependencies: - "@babel/helper-string-parser": "npm:^8.0.0" - "@babel/helper-validator-identifier": "npm:^8.0.4" - checksum: 10c0/c1549372b5544a797c9dd3cfba27c17e0c986cfadb1c4a99246743073e3be99c7c671572326be1739b313a2194e3bfe5a74b1bd213d80c4bbc2c520c8cb4ff1f - languageName: node - linkType: hard - -"@babel/types@npm:^8.0.6, @babel/types@npm:^8.0.8": +"@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: @@ -24680,14 +24599,7 @@ __metadata: languageName: node linkType: hard -"empathic@npm:^2.0.0": - version: 2.0.0 - resolution: "empathic@npm:2.0.0" - checksum: 10c0/7d3b14b04a93b35c47bcc950467ec914fd241cd9acc0269b0ea160f13026ec110f520c90fae64720fde72cc1757b57f3f292fb606617b7fccac1f4d008a76506 - languageName: node - linkType: hard - -"empathic@npm:^2.0.1": +"empathic@npm:^2.0.0, empathic@npm:^2.0.1": version: 2.1.0 resolution: "empathic@npm:2.1.0" checksum: 10c0/cf13e2919d680a22140d7cd1637a01f6cf9a727f21d3a54b23489ec01c80eab548b9d832d2e167d00e124a54377660c1d6fd2b5947d905366e4d22fde7b9e082 @@ -24934,14 +24846,7 @@ __metadata: languageName: node linkType: hard -"es-module-lexer@npm:^2.1.0": - version: 2.1.0 - resolution: "es-module-lexer@npm:2.1.0" - checksum: 10c0/93bcf2454fa72d67fe3ccd0abef8ce7933f5840a319513418a643dd8e9c6aa8f49709cecfae02ded722805dd327232d30723a807cc52e6809d6ac697c62c29fb - languageName: node - linkType: hard - -"es-module-lexer@npm:^2.3.2": +"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 @@ -27012,14 +26917,7 @@ __metadata: languageName: node linkType: hard -"flatted@npm:^3.2.9": - version: 3.4.2 - resolution: "flatted@npm:3.4.2" - checksum: 10c0/a65b67aae7172d6cdf63691be7de6c5cd5adbdfdfe2e9da1a09b617c9512ed794037741ee53d93114276bff3f93cd3b0d97d54f9b316e1e4885dde6e9ffdf7ed - languageName: node - linkType: hard - -"flatted@npm:^3.4.4": +"flatted@npm:^3.2.9, flatted@npm:^3.4.4": version: 3.4.4 resolution: "flatted@npm:3.4.4" checksum: 10c0/a3a52a88ea5a4c333e5a1f097dcd87a037fa31c236a77cf46222c2aa4036ef895ab9bc76138a66d9dc22bdb3652128f9598cd26e7439561bf19f67276e2bc37e @@ -31607,16 +31505,7 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:^1.0.0": - version: 1.4.3 - resolution: "magic-string@npm:1.4.3" - dependencies: - "@jridgewell/sourcemap-codec": "npm:^1.6.0" - checksum: 10c0/857743a1e7039d2e867505bb272a57cc605f610b90f6bf9ef6cbf9654e9cd64330ec35e564a58ca455350529872c3ecc01f37da934da130391237f9f593cc565 - languageName: node - linkType: hard - -"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: @@ -33808,7 +33697,7 @@ __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 From 4c80ed5a55040d2c1c73692a63d967282bfa5357 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud <7252775+indietyp@users.noreply.github.com> Date: Fri, 30 Oct 2026 09:21:15 +0100 Subject: [PATCH 06/17] chore: add vite as flow-petri-net dev dependency --- libs/@local/flow-petri-net/package.json | 1 + yarn.lock | 1 + 2 files changed, 2 insertions(+) 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/yarn.lock b/yarn.lock index f2aa76a8c36..953d3b29ad5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9296,6 +9296,7 @@ __metadata: eslint: "npm:9.39.4" rimraf: "npm:6.1.3" typescript: "catalog:" + vite: "catalog:" vitest: "catalog:" languageName: unknown linkType: soft From daa240c87d3a59d8ff76fd87d8778bba3f7b9895 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud <7252775+indietyp@users.noreply.github.com> Date: Fri, 30 Oct 2026 16:57:09 +0100 Subject: [PATCH 07/17] chore: update vite and drop browser vitest deps --- .yarnrc.yml | 3 +- .../src/provider-registration.test.ts | 7 +- libs/@hashintel/ds-components/package.json | 2 - .../harpc/client/typescript/package.json | 1 + .../tests/wire-protocol/codec.bench.ts | 10 +- yarn.lock | 288 +++++------------- 6 files changed, 93 insertions(+), 218 deletions(-) diff --git a/.yarnrc.yml b/.yarnrc.yml index de27630db03..dfd31fd4d8f 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -39,9 +39,8 @@ catalog: tsx: "4.20.6" typescript: "7.0.2" "@typescript/typescript6": "6.0.2" - vite: "8.3.4" + vite: "8.3.5" vitest: "5.0.5" - "@vitest/browser-playwright": "5.0.5" "@vitest/coverage-istanbul": "5.0.5" "@fast-check/vitest": "0.5.0" "@tsconfig/bases": "1.0.28" diff --git a/apps/brunch-agent/src/provider-registration.test.ts b/apps/brunch-agent/src/provider-registration.test.ts index 9ed808d9b55..b4be2d5a74e 100644 --- a/apps/brunch-agent/src/provider-registration.test.ts +++ b/apps/brunch-agent/src/provider-registration.test.ts @@ -71,12 +71,12 @@ beforeAll(async () => { result?.type === "return" ? result.value : undefined; }); -test("app registration admits the Anthropic, OpenAI and OpenRouter providers", () => { +test("registered providers", () => { const ids = registeredProviders.map((provider) => provider.id).sort(); expect(ids).toEqual(["anthropic", "openai", "openrouter"]); }); -test("app registration admits native OpenRouter with GPT-6.1 Sol and its API-key auth", async () => { +test("native OpenRouter provider", async () => { const native = nativeOpenRouterProvider; expect(native).toBeDefined(); const provider = registeredProviders.find( @@ -114,7 +114,8 @@ const drain = async (stream: ReturnType) => { return stream.result(); }; -test("app registration scopes admission to the Petrinaut agent's execution, isolating concurrent agents and delegated tasks", async () => { +// Admission applies to the Petrinaut agent's own execution, so a concurrent unrelated agent and a task it delegates are not held by it. +test("admission scope", async () => { const registration = instrumentations.find( (instrumentation) => instrumentation.key === Symbol.for("brunch.buffered-tool-admission"), diff --git a/libs/@hashintel/ds-components/package.json b/libs/@hashintel/ds-components/package.json index 7fefea538b7..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": "catalog:", "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/@local/harpc/client/typescript/package.json b/libs/@local/harpc/client/typescript/package.json index 535cbfee78f..986765512f1 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 .", 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 da5462a595a..171562d4982 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,9 +1,9 @@ import { Either, FastCheck, pipe } 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), { @@ -46,7 +46,7 @@ describe("request", () => { await bench("decode", () => { const buffer = MutableBuffer.makeRead(MutableBytes.from(requestEncoded)); - Request.decode(buffer); + Request.decode(buffer).pipe(Either.getOrThrow); }).run(); }); }); @@ -63,7 +63,7 @@ describe("response", () => { await bench("decode", () => { const buffer = MutableBuffer.makeRead(MutableBytes.from(responseEncoded)); - Response.decode(buffer); + Response.decode(buffer).pipe(Either.getOrThrow); }).run(); }); }); diff --git a/yarn.lock b/yarn.lock index 953d3b29ad5..dfc13b020d4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3819,13 +3819,6 @@ __metadata: languageName: node linkType: hard -"@blazediff/core@npm:1.10.0": - version: 1.10.0 - resolution: "@blazediff/core@npm:1.10.0" - checksum: 10c0/4b6095d39338fccd09964fff06f6c5a75628e6296cb2d598149376a876b5c390e083a3769e6ebdaeaa53550f29f1ed5744688df66e4f10b0be0bbc41e9393c8c - languageName: node - linkType: hard - "@blockprotocol/core@npm:0.1.5": version: 0.1.5 resolution: "@blockprotocol/core@npm:0.1.5" @@ -7070,7 +7063,6 @@ __metadata: "@types/react-dom": "npm:19.2.3" "@typescript/typescript6": "catalog:" "@vitejs/plugin-react": "npm:6.1.1" - "@vitest/browser-playwright": "catalog:" "@zag-js/dom-query": "npm:1.43.0" case-anything: "npm:3.1.0" colorjs.io: "npm:0.6.1" @@ -7101,7 +7093,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 @@ -11174,10 +11165,10 @@ __metadata: 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 @@ -13750,9 +13741,9 @@ __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 @@ -13764,9 +13755,9 @@ __metadata: 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" +"@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 @@ -13778,9 +13769,9 @@ __metadata: 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 @@ -13792,9 +13783,9 @@ __metadata: 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 @@ -13806,9 +13797,9 @@ __metadata: 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 @@ -13820,9 +13811,9 @@ __metadata: 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" +"@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 @@ -13834,9 +13825,9 @@ __metadata: 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 @@ -13848,9 +13839,9 @@ __metadata: 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 @@ -13862,9 +13853,9 @@ __metadata: 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" +"@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 @@ -13876,9 +13867,9 @@ __metadata: 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 @@ -13890,9 +13881,9 @@ __metadata: 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" +"@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 @@ -13904,9 +13895,9 @@ __metadata: 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 @@ -13918,9 +13909,9 @@ __metadata: 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 @@ -13932,9 +13923,9 @@ __metadata: 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" +"@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 @@ -13946,9 +13937,9 @@ __metadata: 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" +"@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 @@ -19122,42 +19113,6 @@ __metadata: languageName: node linkType: hard -"@vitest/browser-playwright@npm:5.0.5": - version: 5.0.5 - resolution: "@vitest/browser-playwright@npm:5.0.5" - dependencies: - "@vitest/browser": "npm:5.0.5" - "@vitest/mocker": "npm:5.0.5" - tinyrainbow: "npm:^3.2.0" - peerDependencies: - playwright: "*" - vitest: 5.0.5 - peerDependenciesMeta: - playwright: - optional: false - checksum: 10c0/f788f48d07d2e1680cddfef4db22506e1a9783c27a37bafcefdba36782ee0c5f6fc85a2008f9feaa305a877b4183c10b6edcd300136d479b2a1b83fbeb936082 - languageName: node - linkType: hard - -"@vitest/browser@npm:5.0.5": - version: 5.0.5 - resolution: "@vitest/browser@npm:5.0.5" - dependencies: - "@blazediff/core": "npm:1.10.0" - "@vitest/mocker": "npm:5.0.5" - "@vitest/ui": "npm:5.0.5" - "@vitest/utils": "npm:5.0.5" - magic-string: "npm:^1.4.3" - pngjs: "npm:^7.0.0" - sirv: "npm:^3.0.2" - tinyrainbow: "npm:^3.2.0" - ws: "npm:^8.22.0" - peerDependencies: - vitest: 5.0.5 - checksum: 10c0/04e1a02bf752ecc86f01676a1f95dfcadc5472a4c0835ecb42aa0e0f6226cac8e0b6a1325cdc2c3d973b489dafdc97e22a039aac1abfff55bb9fb192b89e280f - languageName: node - linkType: hard - "@vitest/coverage-istanbul@npm:5.0.5": version: 5.0.5 resolution: "@vitest/coverage-istanbul@npm:5.0.5" @@ -19276,15 +19231,6 @@ __metadata: languageName: node linkType: hard -"@vitest/pretty-format@npm:5.0.5": - version: 5.0.5 - resolution: "@vitest/pretty-format@npm:5.0.5" - dependencies: - tinyrainbow: "npm:^3.2.0" - checksum: 10c0/7d484e42542e3e04ee669cfd2632c001ca3c4493477c4fc539c3c1465cb511b9c46789f63aacf0fd40c312c023add17933b0864eb02d8640e44b69ffdad853c5 - languageName: node - linkType: hard - "@vitest/spy@npm:3.2.4": version: 3.2.4 resolution: "@vitest/spy@npm:3.2.4" @@ -19301,22 +19247,6 @@ __metadata: languageName: node linkType: hard -"@vitest/ui@npm:5.0.5": - version: 5.0.5 - resolution: "@vitest/ui@npm:5.0.5" - dependencies: - "@vitest/utils": "npm:5.0.5" - fflate: "npm:^0.8.3" - flatted: "npm:^3.4.4" - pathe: "npm:^2.0.3" - sirv: "npm:^3.0.2" - tinyrainbow: "npm:^3.2.0" - peerDependencies: - vitest: 5.0.5 - checksum: 10c0/93f26d0fa82f5fd5a4ac1a830a23424f6dd060e88a1352818eef8bfc8441039be400b2b596c6ca14f54425173f6875dc23e8a233be681379a06abf6b91906b9e - languageName: node - linkType: hard - "@vitest/utils@npm:3.2.4": version: 3.2.4 resolution: "@vitest/utils@npm:3.2.4" @@ -19328,17 +19258,6 @@ __metadata: languageName: node linkType: hard -"@vitest/utils@npm:5.0.5": - version: 5.0.5 - resolution: "@vitest/utils@npm:5.0.5" - dependencies: - "@vitest/pretty-format": "npm:5.0.5" - convert-source-map: "npm:^2.0.0" - tinyrainbow: "npm:^3.2.0" - checksum: 10c0/424e7e2e8e2481385bc66a327531ae8c99fd63080778e17b8a75223bbd9d61d5c6d162db8e31ec7d6f17e6206cdc95e8d3d08b1fc8be3c9f50ee0ddf6862b641 - languageName: node - linkType: hard - "@vue/compiler-core@npm:3.5.25": version: 3.5.25 resolution: "@vue/compiler-core@npm:3.5.25" @@ -26719,13 +26638,6 @@ __metadata: languageName: node linkType: hard -"fflate@npm:^0.8.3": - version: 0.8.3 - resolution: "fflate@npm:0.8.3" - checksum: 10c0/eab181ca37f5348ae76d4b6f840e0026e30220e33153289ac942222d8b9638237d486507dbcc09878d724095bd354993a2ee48bbee99c8f2c6440d4448719aa7 - languageName: node - linkType: hard - "figures@npm:^3.2.0": version: 3.2.0 resolution: "figures@npm:3.2.0" @@ -26918,7 +26830,7 @@ __metadata: languageName: node linkType: hard -"flatted@npm:^3.2.9, flatted@npm:^3.4.4": +"flatted@npm:^3.2.9": version: 3.4.4 resolution: "flatted@npm:3.4.4" checksum: 10c0/a3a52a88ea5a4c333e5a1f097dcd87a037fa31c236a77cf46222c2aa4036ef895ab9bc76138a66d9dc22bdb3652128f9598cd26e7439561bf19f67276e2bc37e @@ -35156,13 +35068,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" @@ -35317,14 +35222,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 @@ -37496,26 +37401,26 @@ __metadata: 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@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": @@ -37550,7 +37455,7 @@ __metadata: optional: true bin: rolldown: ./bin/cli.mjs - checksum: 10c0/61782e6764bb05e525517dc8b2d69b465033a48a6998b1fb21de01e787938f3f7a2aa1e8eee5d83c924d131cc629eeaea9fa56b69dd469f97b3c6bb7fb6ddcb2 + checksum: 10c0/084cbdcc222e534c9aff90e77488cdeb6a685a20a34e6e3ba77c3b8646723cea2f090f05522f452ed51217cce68b7aa67df8661b49b4ac0227a5edfcb0383b68 languageName: node linkType: hard @@ -38435,17 +38340,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" @@ -41496,19 +41390,19 @@ __metadata: languageName: node linkType: hard -"vite@npm:8.3.4": - 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 @@ -41549,25 +41443,7 @@ __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 From 74ed5d4190601cc7239e722015a408974be88ec3 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud <7252775+indietyp@users.noreply.github.com> Date: Wed, 4 Nov 2026 16:16:24 +0100 Subject: [PATCH 08/17] chore: pin rolldown to a shared catalog version --- .yarnrc.yml | 1 + .../src/provider-registration.test.ts | 59 +++--- .../type-system/typescript/package.json | 2 +- libs/@hashintel/ds-icons/package.json | 2 +- libs/@hashintel/petrinaut-core/package.json | 2 +- libs/@hashintel/petrinaut/package.json | 2 +- libs/@hashintel/refractive/package.json | 2 +- yarn.lock | 182 +----------------- 8 files changed, 39 insertions(+), 213 deletions(-) diff --git a/.yarnrc.yml b/.yarnrc.yml index dfd31fd4d8f..9b7395c34a9 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -39,6 +39,7 @@ catalog: tsx: "4.20.6" typescript: "7.0.2" "@typescript/typescript6": "6.0.2" + rolldown: "1.2.15" vite: "8.3.5" vitest: "5.0.5" "@vitest/coverage-istanbul": "5.0.5" diff --git a/apps/brunch-agent/src/provider-registration.test.ts b/apps/brunch-agent/src/provider-registration.test.ts index b4be2d5a74e..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" }, @@ -52,36 +54,29 @@ vi.mock( }; }, ); -let registeredProviders: Parameters[0][] = []; -let instrumentations: Parameters[0][] = []; -let nativeOpenRouterProvider: Provider | undefined; - beforeAll(async () => { await import("./app"); - registeredProviders = vi - .mocked(setProvider) - .mock.calls.map(([provider]) => provider); - instrumentations = vi - .mocked(instrument) - .mock.calls.map(([instrumentation]) => instrumentation); - const { openrouterProvider } = - await import("@earendil-works/pi-ai/providers/openrouter"); - const result = vi.mocked(openrouterProvider).mock.results[0]; - nativeOpenRouterProvider = - result?.type === "return" ? result.value : undefined; }); -test("registered providers", () => { - const ids = registeredProviders.map((provider) => provider.id).sort(); +test("app registration admits the Anthropic, OpenAI and OpenRouter providers", () => { + const ids = vi + .mocked(setProvider) + .mock.calls.map(([entry]) => entry.id) + .sort(); expect(ids).toEqual(["anthropic", "openai", "openrouter"]); }); -test("native OpenRouter provider", async () => { - const native = nativeOpenRouterProvider; +test("app registration admits native OpenRouter with GPT-6.1 Sol and its API-key auth", async () => { + const { openrouterProvider } = + await import("@earendil-works/pi-ai/providers/openrouter"); + const native = vi.mocked(openrouterProvider).mock.results[0]?.value as + | Provider + | undefined; expect(native).toBeDefined(); - const provider = registeredProviders.find( - (provider) => provider.id === "openrouter", - )!; + const provider = vi + .mocked(setProvider) + .mock.calls.map(([entry]) => entry) + .find((entry) => entry.id === "openrouter")!; expect(provider.auth).toBe(native!.auth); // The catalogue extension keeps native streams, so a different stream is the admission wrapper. expect(Reflect.get(provider, "streamSimple")).not.toBe( @@ -114,17 +109,17 @@ const drain = async (stream: ReturnType) => { return stream.result(); }; -// Admission applies to the Petrinaut agent's own execution, so a concurrent unrelated agent and a task it delegates are not held by it. -test("admission scope", async () => { - const registration = instrumentations.find( - (instrumentation) => - instrumentation.key === Symbol.for("brunch.buffered-tool-admission"), - ); +test("app registration scopes admission to the Petrinaut agent's execution, isolating concurrent agents and delegated tasks", async () => { + const registration = vi + .mocked(instrument) + .mock.calls.find( + ([entry]) => entry.key === Symbol.for("brunch.buffered-tool-admission"), + )?.[0]; expect(registration).toBeDefined(); - const provider = registeredProviders.find( - (provider) => provider.id === "anthropic", - )!; - + const provider = vi + .mocked(setProvider) + .mock.calls.map(([entry]) => entry) + .find((entry) => entry.id === "anthropic")!; expect(provider.auth).toBe(faux.provider.auth); expect(provider.getModels()).toEqual(faux.provider.getModels()); const model = provider.getModels()[0]!; diff --git a/libs/@blockprotocol/type-system/typescript/package.json b/libs/@blockprotocol/type-system/typescript/package.json index 0abaeae8499..789dff2e9a9 100644 --- a/libs/@blockprotocol/type-system/typescript/package.json +++ b/libs/@blockprotocol/type-system/typescript/package.json @@ -67,7 +67,7 @@ "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:", 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/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/yarn.lock b/yarn.lock index dfc13b020d4..7d28451b366 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3920,7 +3920,7 @@ __metadata: 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" @@ -7126,7 +7126,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:" @@ -7168,7 +7168,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" @@ -7221,7 +7221,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:" @@ -7286,7 +7286,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:" @@ -11158,13 +11158,6 @@ __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.155.0": version: 0.155.0 resolution: "@oxc-project/types@npm:0.155.0" @@ -13748,13 +13741,6 @@ __metadata: 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.15": version: 1.2.15 resolution: "@rolldown/binding-android-arm64@npm:1.2.15" @@ -13762,13 +13748,6 @@ __metadata: 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" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - "@rolldown/binding-darwin-arm64@npm:1.2.15": version: 1.2.15 resolution: "@rolldown/binding-darwin-arm64@npm:1.2.15" @@ -13776,13 +13755,6 @@ __metadata: 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.15": version: 1.2.15 resolution: "@rolldown/binding-darwin-x64@npm:1.2.15" @@ -13790,13 +13762,6 @@ __metadata: 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.15": version: 1.2.15 resolution: "@rolldown/binding-freebsd-x64@npm:1.2.15" @@ -13804,13 +13769,6 @@ __metadata: 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.15": version: 1.2.15 resolution: "@rolldown/binding-linux-arm-gnueabihf@npm:1.2.15" @@ -13818,13 +13776,6 @@ __metadata: 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" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - "@rolldown/binding-linux-arm64-gnu@npm:1.2.15": version: 1.2.15 resolution: "@rolldown/binding-linux-arm64-gnu@npm:1.2.15" @@ -13832,13 +13783,6 @@ __metadata: 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.15": version: 1.2.15 resolution: "@rolldown/binding-linux-arm64-musl@npm:1.2.15" @@ -13846,13 +13790,6 @@ __metadata: 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.15": version: 1.2.15 resolution: "@rolldown/binding-linux-ppc64-gnu@npm:1.2.15" @@ -13860,13 +13797,6 @@ __metadata: 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" - conditions: os=linux & cpu=ppc64 & libc=glibc - languageName: node - linkType: hard - "@rolldown/binding-linux-s390x-gnu@npm:1.2.15": version: 1.2.15 resolution: "@rolldown/binding-linux-s390x-gnu@npm:1.2.15" @@ -13874,13 +13804,6 @@ __metadata: 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.15": version: 1.2.15 resolution: "@rolldown/binding-linux-x64-gnu@npm:1.2.15" @@ -13888,13 +13811,6 @@ __metadata: 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" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - "@rolldown/binding-linux-x64-musl@npm:1.2.15": version: 1.2.15 resolution: "@rolldown/binding-linux-x64-musl@npm:1.2.15" @@ -13902,13 +13818,6 @@ __metadata: 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.15": version: 1.2.15 resolution: "@rolldown/binding-openharmony-arm64@npm:1.2.15" @@ -13916,13 +13825,6 @@ __metadata: 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.15": version: 1.2.15 resolution: "@rolldown/binding-win32-arm64-msvc@npm:1.2.15" @@ -13930,13 +13832,6 @@ __metadata: 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" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - "@rolldown/binding-win32-x64-msvc@npm:1.2.15": version: 1.2.15 resolution: "@rolldown/binding-win32-x64-msvc@npm:1.2.15" @@ -13944,13 +13839,6 @@ __metadata: 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" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - "@rolldown/plugin-babel@npm:^0.2.3": version: 0.2.3 resolution: "@rolldown/plugin-babel@npm:0.2.3" @@ -37343,65 +37231,7 @@ __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/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/34f8fd335f3ec8e55002aa4f2f6f0ffd4dc1f2c47f877d4ad37fbe62c97d3b63486705494e739b9e451cccf4c4bc4e0f14648d7f978427964c693c0165289308 - languageName: node - linkType: hard - -"rolldown@npm:~1.2.14": +"rolldown@npm:1.2.15, rolldown@npm:~1.2.14": version: 1.2.15 resolution: "rolldown@npm:1.2.15" dependencies: From df0d1daa3b0c9afabf32ab33a6157b3272b0fb39 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud <7252775+indietyp@users.noreply.github.com> Date: Wed, 4 Nov 2026 16:25:34 +0100 Subject: [PATCH 09/17] chore: drop redundant vi.clearAllMocks calls --- .../src/agents/petrinaut/petrinaut-agent-mounting.test.ts | 1 - ...portunity-status-update-after-create-entity-hook.test.ts | 1 - .../primitive/entity/shared/mention-delivery.test.ts | 1 - .../src/graph/knowledge/system-types/notification.test.ts | 1 - .../src/graphql/resolvers/flows/flow-definition.test.ts | 1 - .../src/graphql/resolvers/flows/flow-schedule.test.ts | 1 - .../knowledge/notification/update-notifications.test.ts | 6 +----- .../product/production-schedule.test.tsx | 1 - .../app/local-storage-demo/assistant-labs-settings.test.tsx | 1 - .../documents/use-document-controller.test.ts | 1 - .../petrinaut-ai/chat/assistant-chat/chat-view.test.tsx | 1 - apps/petrinaut-website/src/routes/-share.test.tsx | 1 - .../src/sharing/share-snapshot-button.test.tsx | 1 - .../chat/ai-assistant-panel/ai-assistant-contents.test.tsx | 1 - .../src/ui/voice/live/live-conversation-control.test.tsx | 1 - .../sub-view/vertical/vertical-sub-views-container.test.tsx | 1 - .../petrinaut/src/ui/monaco/code-editor-activity.test.tsx | 1 - .../petrinaut/src/ui/monaco/code-navigation.test.tsx | 1 - .../components/BottomBar/use-keyboard-shortcuts.test.tsx | 1 - .../petrinaut/src/ui/views/Editor/editor-view.test.tsx | 1 - .../user-settings-dialog/settings-heading.test.tsx | 1 - .../experiments/create-experiment-drawer.test.tsx | 1 - libs/@hashintel/refractive/src/hoc/refractive.test.tsx | 1 - 23 files changed, 1 insertion(+), 27 deletions(-) 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/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-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/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/@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/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/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); }); From 0f9360ce131fedbea794f077776dbcd63b8d2b11 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud <7252775+indietyp@users.noreply.github.com> Date: Wed, 7 Oct 2026 17:48:44 +0200 Subject: [PATCH 10/17] chore: upgrade harpc to effect 4 RC --- ...@effect-vitest-npm-0.29.0-1c8cf3c306.patch | 73 ------ apps/hash-api/package.json | 2 +- apps/hash-api/src/index.ts | 17 +- libs/@local/eslint/package.json | 2 +- libs/@local/eslint/src/builtIn.ts | 8 +- libs/@local/graph/sdk/typescript/package.json | 2 +- libs/@local/graph/sdk/typescript/src/harpc.ts | 71 +++--- .../harpc/client/typescript/package.json | 11 +- .../typescript/src/binary/MutableBuffer.ts | 26 +-- .../client/typescript/src/codec/Decoder.ts | 21 +- .../client/typescript/src/codec/Encoder.ts | 21 +- .../typescript/src/codec/JsonDecoder.ts | 7 +- .../typescript/src/codec/JsonEncoder.ts | 4 +- .../harpc/client/typescript/src/net/Client.ts | 9 +- .../client/typescript/src/net/Connection.ts | 34 +-- .../typescript/src/net/NetworkLogger.ts | 22 +- .../client/typescript/src/net/Request.ts | 6 +- .../client/typescript/src/net/Response.ts | 6 +- .../client/typescript/src/net/Transaction.ts | 15 +- .../client/typescript/src/net/internal/dns.ts | 27 ++- .../typescript/src/net/internal/multiaddr.ts | 1 - .../src/net/internal/networkLogger.ts | 11 +- .../src/net/internal/peerConnection.ts | 6 +- .../typescript/src/net/internal/transport.ts | 31 ++- .../client/typescript/src/types/ErrorCode.ts | 17 +- .../src/types/ProcedureDescriptor.ts | 20 +- .../typescript/src/types/ProcedureId.ts | 22 +- .../typescript/src/types/ResponseKind.ts | 26 +-- .../src/types/SubsystemDescriptor.ts | 22 +- .../typescript/src/types/SubsystemId.ts | 22 +- .../client/typescript/src/types/Version.ts | 29 ++- .../harpc/client/typescript/src/utils.ts | 4 +- .../src/wire-protocol/RequestIdProducer.ts | 5 +- .../src/wire-protocol/models/Payload.ts | 44 ++-- .../src/wire-protocol/models/Protocol.ts | 27 +-- .../wire-protocol/models/ProtocolVersion.ts | 19 +- .../wire-protocol/models/request/Request.ts | 22 +- .../models/request/RequestBegin.ts | 31 ++- .../models/request/RequestBody.ts | 64 +++--- .../models/request/RequestFlags.ts | 37 ++-- .../models/request/RequestFrame.ts | 22 +- .../models/request/RequestHeader.ts | 29 +-- .../wire-protocol/models/request/RequestId.ts | 25 +-- .../wire-protocol/models/response/Response.ts | 22 +- .../models/response/ResponseBegin.ts | 27 +-- .../models/response/ResponseBody.ts | 56 ++--- .../models/response/ResponseFlags.ts | 35 ++- .../models/response/ResponseFrame.ts | 22 +- .../models/response/ResponseHeader.ts | 29 +-- .../stream/RequestToBytesStream.ts | 2 +- .../stream/ResponseFromBytesStream.ts | 5 +- .../tests/binary/MutableBuffer.test.ts | 40 ++-- .../tests/codec/JsonDecoder.test.ts | 14 +- .../tests/codec/JsonEncoder.test.ts | 5 +- .../typescript/tests/net/Request.test.ts | 43 +--- .../tests/wire-protocol/codec.bench.ts | 30 ++- .../tests/wire-protocol/decode.test.ts | 46 ++-- .../tests/wire-protocol/encode.test.ts | 44 ++-- .../typescript/tests/wire-protocol/utils.ts | 14 +- yarn.lock | 207 ++++-------------- 60 files changed, 616 insertions(+), 945 deletions(-) delete mode 100644 .yarn/patches/@effect-vitest-npm-0.29.0-1c8cf3c306.patch 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 d894299f8cd..00000000000 --- a/.yarn/patches/@effect-vitest-npm-0.29.0-1c8cf3c306.patch +++ /dev/null @@ -1,73 +0,0 @@ -diff --git a/dist/cjs/internal/internal.js b/dist/cjs/internal/internal.js -index dee6eec..14424ac 100644 ---- a/dist/cjs/internal/internal.js -+++ b/dist/cjs/internal/internal.js -@@ -28,7 +28,11 @@ 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)); -+ // Register on the test's own context, which concurrent tests do not share. -+ // Vitest 4.0 contexts had no onTestFinished, so use the global hook there. -+ if (ctx) { -+ (ctx.onTestFinished ?? 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 adb6b21..379aee7 100644 ---- a/dist/esm/internal/internal.js -+++ b/dist/esm/internal/internal.js -@@ -21,7 +21,11 @@ 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)); -+ // Register on the test's own context, which concurrent tests do not share. -+ // Vitest 4.0 contexts had no onTestFinished, so use the global hook there. -+ if (ctx) { -+ (ctx.onTestFinished ?? 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 1ceac68..ac43401 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 || ^5.0.0", - "effect": "^3.21.0" - }, - "publishConfig": { -diff --git a/src/internal/internal.ts b/src/internal/internal.ts -index bd11019..9313f73 100644 ---- a/src/internal/internal.ts -+++ b/src/internal/internal.ts -@@ -29,12 +29,16 @@ const runPromise = (ctx?: Vitest.TestContext) => (effect: Effect.Effect -- Fiber.interrupt(exitFiber).pipe( -- Effect.asVoid, -- Effect.runPromise -+ // Register on the test's own context, which concurrent tests do not share. -+ // Vitest 4.0 contexts had no onTestFinished, so use the global hook there. -+ if (ctx) { -+ ;(ctx.onTestFinished ?? V.onTestFinished)(() => -+ Fiber.interrupt(exitFiber).pipe( -+ Effect.asVoid, -+ Effect.runPromise -+ ) - ) -- ) -+ } - - const exit = yield* Fiber.join(exitFiber) - if (Exit.isSuccess(exit)) { diff --git a/apps/hash-api/package.json b/apps/hash-api/package.json index b49b5487eef..f6856ff1ff6 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.0-rc.118", "exponential-backoff": "3.1.3", "express": "5.2.0", "express-handlebars": "8.0.4", 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/libs/@local/eslint/package.json b/libs/@local/eslint/package.json index 0ac90215ab3..fd9dc5f68a3 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.0-rc.118", "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/graph/sdk/typescript/package.json b/libs/@local/graph/sdk/typescript/package.json index 58bc1361047..865486fb81e 100644 --- a/libs/@local/graph/sdk/typescript/package.json +++ b/libs/@local/graph/sdk/typescript/package.json @@ -31,7 +31,7 @@ "@local/hash-graph-client": "workspace:*", "@local/hash-graph-store": "workspace:*", "@temporalio/client": "1.20.2", - "effect": "3.21.0", + "effect": "4.0.0-rc.118", "uuid": "14.0.0" }, "devDependencies": { 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 986765512f1..b1b1930eafd 100644 --- a/libs/@local/harpc/client/typescript/package.json +++ b/libs/@local/harpc/client/typescript/package.json @@ -33,20 +33,15 @@ "@libp2p/tcp": "11.0.28", "@multiformats/dns": "1.0.10", "@multiformats/multiaddr": "13.0.3", - "effect": "3.21.0", + "effect": "4.0.0-rc.118", "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.0-rc.118", + "@effect/vitest": "4.0.0-rc.118", "@local/eslint": "workspace:*", "@local/tsconfig": "workspace:*", "@tsconfig/bases": "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..a3173e23457 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"; @@ -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..13d6c337071 100644 --- a/libs/@local/harpc/client/typescript/src/codec/JsonDecoder.ts +++ b/libs/@local/harpc/client/typescript/src/codec/JsonDecoder.ts @@ -94,14 +94,14 @@ const make = (options: Options) => ignoreBOM: true, }); - const schemaJson = Schema.parseJson(schema); - const decodeJson = Schema.decode(schemaJson); + const schemaJson = Schema.fromJsonString(schema); + const decodeJson = Schema.decodeEffect(schemaJson); let fragment = ""; return pipe( input, - Stream.mapConcatEffect((buffer) => + Stream.mapEffect((buffer) => Effect.gen(function* () { const [nextFragment, items] = yield* processArrayBuffer( buffer, @@ -116,6 +116,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..f0919ab2053 100644 --- a/libs/@local/harpc/client/typescript/src/net/Connection.ts +++ b/libs/@local/harpc/client/typescript/src/net/Connection.ts @@ -1,6 +1,6 @@ import { - type Scope, - Chunk, + type Cause, + Context, Deferred, Duration, Effect, @@ -9,10 +9,10 @@ import { 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 +32,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"); @@ -60,7 +61,7 @@ export interface ConnectionConfig { * * @defaultValue 200ms */ - lagTimeout?: Duration.DurationInput; + lagTimeout?: Duration.Input; /** * The size of the number of buffered responses to keep in memory. @@ -96,7 +97,7 @@ export interface Connection { } interface TransactionContext { - queue: Queue.Enqueue; + queue: Queue.Enqueue; drop: Effect.Effect; } @@ -119,7 +120,7 @@ const ConnectionProto: Omit< }; // 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) => @@ -139,7 +140,7 @@ const makeSink = (connection: ConnectionImpl) => const isOnline = yield* pipe( Queue.offer(transaction.value.queue, response), Effect.timeout(lagTimeout), - Effect.catchTag("TimeoutException", (timeout) => + Effect.catchTag("TimeoutError", (timeout) => Effect.gen(function* () { yield* Effect.logWarning( "transaction has lagged behind too far, dropping it", @@ -179,7 +180,7 @@ const wrapDrop = Effect.fn("wrapDrop")(function* ( } MutableHashMap.remove(connection.transactions, id); - yield* transaction.value.queue.shutdown; + yield* Queue.end(transaction.value.queue); // call user defined drop function const dropImpl = yield* Deferred.poll(drop); @@ -223,7 +224,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 +238,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 +255,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); @@ -275,7 +276,7 @@ export const makeUnchecked = Effect.fn("makeUnchecked")(function* ( }); // 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)); + yield* Effect.forkChild(task(self)); return self; }); @@ -301,7 +302,7 @@ export const send = Function.dual< const deferredDrop = yield* Deferred.make(); const drop = wrapDrop(impl, request.id, deferredDrop); - const queue = yield* Queue.bounded( + const queue = yield* Queue.bounded( impl.config.responseBufferSize ?? 16, ); @@ -312,11 +313,12 @@ export const send = Function.dual< MutableHashMap.set(impl.transactions, request.id, transactionContext); - yield* Effect.fork( + yield* Effect.forkChild( pipe( request, // Request.encode(), Stream.run(impl.duplex.write), + Effect.scoped, ), ); 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..02d4ca42644 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,7 @@ const processResponseStream = ( }, }); }), + Stream.flattenIterable, ); }; diff --git a/libs/@local/harpc/client/typescript/src/net/Transaction.ts b/libs/@local/harpc/client/typescript/src/net/Transaction.ts index 485aa60f03f..91724c6c4c5 100644 --- a/libs/@local/harpc/client/typescript/src/net/Transaction.ts +++ b/libs/@local/harpc/client/typescript/src/net/Transaction.ts @@ -1,4 +1,11 @@ -import { type Effect, type Queue, Deferred, Function } from "effect"; +import { + type Cause, + Deferred, + type Effect, + Function, + type Queue, + Stream, +} from "effect"; import { createProto } from "../utils.js"; import * as Response from "./Response.js"; @@ -17,7 +24,7 @@ export interface Transaction { } interface TransactionImpl extends Transaction { - readonly read: Queue.Dequeue; + readonly read: Queue.Dequeue; readonly drop: Deferred.Deferred; } @@ -29,7 +36,7 @@ const TransactionProto: Omit = { /** @internal */ export const makeUnchecked = ( id: RequestId.RequestId, - readQueue: Queue.Dequeue, + readQueue: Queue.Dequeue, drop: Deferred.Deferred, ): Transaction => createProto(TransactionProto, { id, read: readQueue, drop }); @@ -44,4 +51,4 @@ export const registerDestructor: { ); 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..b1028f39bc2 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 } 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,22 +126,23 @@ export const resolve = Effect.fn("resolve")(function* ( }); } - yield* Effect.fork(logEnvironment(hostname)); + yield* Effect.forkChild(logEnvironment(hostname)); - const [excluded, satisfying] = yield* Effect.partition( + const results = yield* Effect.forEach( resolvers, - Function.identity, - { - concurrency: "unbounded", - }, + (resolver) => Effect.result(resolver), + { concurrency: "unbounded" }, ); + const satisfying = Array.getSuccesses(results); + const excluded = Array.getFailures(results); + if (satisfying.length === 0) { // means that excluded is non empty 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,13 +159,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 = records.filter((record) => record.family === 4); + const excluded = records.filter((record) => record.family !== 4); // we cannot determine the TTL of lookup records, therefore we set it to infinity // `getaddrinfo` (the underlying call used by dns.lookup) does not return TTLs 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..ed1bba35716 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,8 @@ 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..70fecbfd2f8 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,26 @@ 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..a1ae08cac8f 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(buffer, 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..c70d53fab45 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,20 @@ 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..975e3c92f0a 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,12 @@ 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.toString()).toMatch(/Expected a valid JSON string/); }).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/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/wire-protocol/codec.bench.ts b/libs/@local/harpc/client/typescript/tests/wire-protocol/codec.bench.ts index 171562d4982..753f3037a6f 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,4 +1,4 @@ -import { Either, FastCheck, pipe } from "effect"; +import { Arbitrary, Effect, pipe, Result } from "effect"; import { describe, test } from "vitest"; import { MutableBuffer, MutableBytes } from "@local/harpc-client/binary"; @@ -6,30 +6,26 @@ 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; }), ); @@ -39,7 +35,7 @@ describe("request", () => { test("codec", async ({ bench }) => { await bench("encode", () => { Request.encode(MutableBuffer.makeWrite(), request[0]!).pipe( - Either.getOrThrow, + Result.getOrThrow, ); }).run(); @@ -56,7 +52,7 @@ describe("response", () => { test("codec", async ({ bench }) => { await bench("encode", () => { Response.encode(MutableBuffer.makeWrite(), response[0]!).pipe( - Either.getOrThrow, + 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..48fa77bc554 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 { NodeServices } from "@effect/platform-node"; 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..b8ddd9f29e1 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 { NodeServices } from "@effect/platform-node"; 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/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/yarn.lock b/yarn.lock index 7d28451b366..ff293ba2e6f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -585,7 +585,7 @@ __metadata: axios: "npm:1.20.0" cors: "npm:2.8.5" dedent: "npm:1.7.0" - effect: "npm:3.21.0" + effect: "npm:4.0.0-rc.118" eslint: "npm:9.39.4" exponential-backoff: "npm:3.1.3" express: "npm:5.2.0" @@ -4700,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.0-rc.118": + version: 4.0.6 + resolution: "@effect/platform-node-shared@npm:4.0.6" 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.6 + checksum: 10c0/2caee178bfc9a99e92733175e023208e7b5a01e6f95430d7003d2e0ec7febc57232dadfcdf2d747d8a7e82b329ba836d8b4a2d8afc670787c2980db5d6fdfd0f 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.0-rc.118": + version: 4.0.0-rc.118 + resolution: "@effect/platform-node@npm:4.0.0-rc.118" dependencies: - uuid: "npm:^11.0.3" - peerDependencies: - "@effect/experimental": ^0.56.0 - "@effect/platform": ^0.92.0 - effect: ^3.18.0 - checksum: 10c0/a28382d4d35e30ac917f69b2f7a10567a31084c5285b81d007edb3181791e6013d935d211b132e85bea38075b915fe78e040df4eb8d6da22d1d79dda7eaf02b8 - languageName: node - linkType: hard - -"@effect/vitest@npm:0.29.0": - version: 0.29.0 - resolution: "@effect/vitest@npm:0.29.0" + "@effect/platform-node-shared": "npm:^4.0.0-rc.118" + undici: "npm:^8.11.2" peerDependencies: - effect: ^3.21.0 - vitest: ^3.2.0 - checksum: 10c0/fd316009e8bb781ced2268b843b401b71bcf40097ad64536e9f30eb4e8ff130eabefdd575779e5c03fd90fb0df43feaaf5b34b7275e76be8fff08500ada9ffe8 + effect: ^4.0.0-rc.118 + redis: ">=5.0.0 <7.0.0" + checksum: 10c0/acc4f0e7f7fa3251cd8758146b39f21f2b1c6edeb254a7c8bff300b723182bee936708068be4780d236ef66b21f01a7113e8a5e94452e74fd50b07ef7849c59f 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=bc0d2f" +"@effect/vitest@npm:4.0.0-rc.118": + version: 4.0.0-rc.118 + resolution: "@effect/vitest@npm:4.0.0-rc.118" peerDependencies: - effect: ^3.21.0 - vitest: ^3.2.0 - checksum: 10c0/9279825836f9efa7f2da6c94162a2b5782963a4c8a1cb63cc76ea534436d20220051cbe2211a97f4e7768bcea45c4642d3bcae51ac1f9491f0b885caaff436b3 + effect: ^4.0.0-rc.118 + vitest: ">=5.0.0 <6.0.0" + checksum: 10c0/fb24e79969bdaebb88adcc4f054c9ed233ab5afb714421d9bf880eb9f48419767cc869a9ad6180c71251fdf20891fe14f30cfaa838a325e846c48331a05640ff languageName: node linkType: hard @@ -9252,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.0-rc.118" eslint: "npm:9.39.4" eslint-config-airbnb: "npm:19.0.4" eslint-config-flat-gitignore: "npm:2.2.1" @@ -9318,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.0-rc.118" + "@effect/vitest": "npm:4.0.0-rc.118" "@libp2p/crypto": "npm:5.1.23" "@libp2p/identify": "npm:4.1.14" "@libp2p/interface": "npm:3.3.0" @@ -9337,7 +9242,7 @@ __metadata: "@tsconfig/bases": "catalog:" "@types/node": "catalog:" "@vitest/coverage-istanbul": "catalog:" - effect: "npm:3.21.0" + effect: "npm:4.0.0-rc.118" eslint: "npm:9.39.4" it-stream-types: "npm:2.0.2" libp2p: "npm:3.3.11" @@ -9477,7 +9382,7 @@ __metadata: "@temporalio/client": "npm:1.20.2" "@tsconfig/bases": "catalog:" "@vitest/coverage-istanbul": "catalog:" - effect: "npm:3.21.0" + effect: "npm:4.0.0-rc.118" eslint: "npm:9.39.4" rimraf: "npm:6.1.3" typescript: "catalog:" @@ -12127,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: @@ -24348,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.0-rc.118": + version: 4.0.0-rc.118 + resolution: "effect@npm:4.0.0-rc.118" + checksum: 10c0/c8f95c3372909bc174e50b0e494145b8b77e13db126975b9d6e30cb3add4521d488e8b82734dae7cc6a2b9ce1a5e65aab7355577db5872c30448e72a6fa24fb0 languageName: node linkType: hard @@ -26302,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" @@ -26629,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" @@ -32821,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: @@ -32859,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" @@ -35653,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" @@ -40555,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" @@ -41067,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: @@ -42059,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.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: From f28695e96d7d5223fdeb718b508ecb3b1cc059fb Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud <7252775+indietyp@users.noreply.github.com> Date: Mon, 12 Oct 2026 21:12:18 +0200 Subject: [PATCH 11/17] chore: upgrade effect to stable 4.0.0 --- apps/hash-api/package.json | 2 +- libs/@local/eslint/package.json | 2 +- libs/@local/graph/sdk/typescript/package.json | 2 +- .../harpc/client/typescript/package.json | 6 +-- yarn.lock | 44 +++++++++---------- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/apps/hash-api/package.json b/apps/hash-api/package.json index f6856ff1ff6..0094a604952 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": "4.0.0-rc.118", + "effect": "4.0.0", "exponential-backoff": "3.1.3", "express": "5.2.0", "express-handlebars": "8.0.4", diff --git a/libs/@local/eslint/package.json b/libs/@local/eslint/package.json index fd9dc5f68a3..dea94303500 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": "4.0.0-rc.118", + "effect": "4.0.0", "eslint": "9.39.4", "eslint-config-airbnb": "19.0.4", "eslint-config-flat-gitignore": "2.2.1", diff --git a/libs/@local/graph/sdk/typescript/package.json b/libs/@local/graph/sdk/typescript/package.json index 865486fb81e..6580561b54f 100644 --- a/libs/@local/graph/sdk/typescript/package.json +++ b/libs/@local/graph/sdk/typescript/package.json @@ -31,7 +31,7 @@ "@local/hash-graph-client": "workspace:*", "@local/hash-graph-store": "workspace:*", "@temporalio/client": "1.20.2", - "effect": "4.0.0-rc.118", + "effect": "4.0.0", "uuid": "14.0.0" }, "devDependencies": { diff --git a/libs/@local/harpc/client/typescript/package.json b/libs/@local/harpc/client/typescript/package.json index b1b1930eafd..18d35de9413 100644 --- a/libs/@local/harpc/client/typescript/package.json +++ b/libs/@local/harpc/client/typescript/package.json @@ -33,15 +33,15 @@ "@libp2p/tcp": "11.0.28", "@multiformats/dns": "1.0.10", "@multiformats/multiaddr": "13.0.3", - "effect": "4.0.0-rc.118", + "effect": "4.0.0", "it-stream-types": "2.0.2", "libp2p": "3.3.11", "multiformats": "14.0.5", "uint8arraylist": "3.0.2" }, "devDependencies": { - "@effect/platform-node": "4.0.0-rc.118", - "@effect/vitest": "4.0.0-rc.118", + "@effect/platform-node": "4.0.0", + "@effect/vitest": "4.0.0", "@local/eslint": "workspace:*", "@local/tsconfig": "workspace:*", "@tsconfig/bases": "catalog:", diff --git a/yarn.lock b/yarn.lock index ff293ba2e6f..4fa019fd348 100644 --- a/yarn.lock +++ b/yarn.lock @@ -585,7 +585,7 @@ __metadata: axios: "npm:1.20.0" cors: "npm:2.8.5" dedent: "npm:1.7.0" - effect: "npm:4.0.0-rc.118" + effect: "npm:4.0.0" eslint: "npm:9.39.4" exponential-backoff: "npm:3.1.3" express: "npm:5.2.0" @@ -4700,7 +4700,7 @@ __metadata: languageName: node linkType: hard -"@effect/platform-node-shared@npm:^4.0.0-rc.118": +"@effect/platform-node-shared@npm:^4.0.0": version: 4.0.6 resolution: "@effect/platform-node-shared@npm:4.0.6" dependencies: @@ -4712,26 +4712,26 @@ __metadata: languageName: node linkType: hard -"@effect/platform-node@npm:4.0.0-rc.118": - version: 4.0.0-rc.118 - resolution: "@effect/platform-node@npm:4.0.0-rc.118" +"@effect/platform-node@npm:4.0.0": + version: 4.0.0 + resolution: "@effect/platform-node@npm:4.0.0" dependencies: - "@effect/platform-node-shared": "npm:^4.0.0-rc.118" + "@effect/platform-node-shared": "npm:^4.0.0" undici: "npm:^8.11.2" peerDependencies: - effect: ^4.0.0-rc.118 + effect: ^4.0.0 redis: ">=5.0.0 <7.0.0" - checksum: 10c0/acc4f0e7f7fa3251cd8758146b39f21f2b1c6edeb254a7c8bff300b723182bee936708068be4780d236ef66b21f01a7113e8a5e94452e74fd50b07ef7849c59f + checksum: 10c0/2657631ede73c0ff55daf6260e9fdfce16c18c98160d5ada7f15f8c92f4fcf3f9b8ce396d7853134f8005969ae71bff0fc8de603037c014f22a1169b1c6c4a9d languageName: node linkType: hard -"@effect/vitest@npm:4.0.0-rc.118": - version: 4.0.0-rc.118 - resolution: "@effect/vitest@npm:4.0.0-rc.118" +"@effect/vitest@npm:4.0.0": + version: 4.0.0 + resolution: "@effect/vitest@npm:4.0.0" peerDependencies: - effect: ^4.0.0-rc.118 + effect: ^4.0.0 vitest: ">=5.0.0 <6.0.0" - checksum: 10c0/fb24e79969bdaebb88adcc4f054c9ed233ab5afb714421d9bf880eb9f48419767cc869a9ad6180c71251fdf20891fe14f30cfaa838a325e846c48331a05640ff + checksum: 10c0/baec89578bc430c283f56b9f0346b38a403a6ac81194222d8888ead2f1d281379133b1fde6666b08b3e9e618e73bcd9c7ac632f821a0f1f74ffe8e3c34ad7681 languageName: node linkType: hard @@ -9162,7 +9162,7 @@ __metadata: "@types/node": "catalog:" "@typescript-eslint/eslint-plugin": "npm:8.71.0" "@typescript-eslint/parser": "npm:8.71.0" - effect: "npm:4.0.0-rc.118" + effect: "npm:4.0.0" eslint: "npm:9.39.4" eslint-config-airbnb: "npm:19.0.4" eslint-config-flat-gitignore: "npm:2.2.1" @@ -9228,8 +9228,8 @@ __metadata: dependencies: "@chainsafe/libp2p-noise": "npm:17.0.0" "@chainsafe/libp2p-yamux": "npm:8.0.1" - "@effect/platform-node": "npm:4.0.0-rc.118" - "@effect/vitest": "npm:4.0.0-rc.118" + "@effect/platform-node": "npm:4.0.0" + "@effect/vitest": "npm:4.0.0" "@libp2p/crypto": "npm:5.1.23" "@libp2p/identify": "npm:4.1.14" "@libp2p/interface": "npm:3.3.0" @@ -9242,7 +9242,7 @@ __metadata: "@tsconfig/bases": "catalog:" "@types/node": "catalog:" "@vitest/coverage-istanbul": "catalog:" - effect: "npm:4.0.0-rc.118" + effect: "npm:4.0.0" eslint: "npm:9.39.4" it-stream-types: "npm:2.0.2" libp2p: "npm:3.3.11" @@ -9382,7 +9382,7 @@ __metadata: "@temporalio/client": "npm:1.20.2" "@tsconfig/bases": "catalog:" "@vitest/coverage-istanbul": "catalog:" - effect: "npm:4.0.0-rc.118" + effect: "npm:4.0.0" eslint: "npm:9.39.4" rimraf: "npm:6.1.3" typescript: "catalog:" @@ -24253,10 +24253,10 @@ __metadata: languageName: node linkType: hard -"effect@npm:4.0.0-rc.118": - version: 4.0.0-rc.118 - resolution: "effect@npm:4.0.0-rc.118" - checksum: 10c0/c8f95c3372909bc174e50b0e494145b8b77e13db126975b9d6e30cb3add4521d488e8b82734dae7cc6a2b9ce1a5e65aab7355577db5872c30448e72a6fa24fb0 +"effect@npm:4.0.0": + version: 4.0.0 + resolution: "effect@npm:4.0.0" + checksum: 10c0/c9cd4c151a0d5141c82331e313fcfa5ba2ac99c6b3cc3d310eb92925286efe96487685f2a3b215a2470b9ee50b0e2f10c187149b820c696c9b1d7d0edd3a6e3c languageName: node linkType: hard From 6d0775c153cebe29bf7e39326e27f7485578d51a Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud <7252775+indietyp@users.noreply.github.com> Date: Mon, 19 Oct 2026 15:51:53 +0200 Subject: [PATCH 12/17] chore: upgrade effect to 4.0.3 --- apps/hash-api/package.json | 2 +- libs/@local/eslint/package.json | 2 +- libs/@local/graph/sdk/typescript/package.json | 2 +- .../harpc/client/typescript/package.json | 6 +-- .../typescript/src/types/ResponseKind.ts | 1 + .../models/request/RequestBody.ts | 1 + .../models/response/ResponseBody.ts | 1 + .../tests/wire-protocol/decode.test.ts | 2 +- .../tests/wire-protocol/encode.test.ts | 2 +- yarn.lock | 44 +++++++++---------- 10 files changed, 33 insertions(+), 30 deletions(-) diff --git a/apps/hash-api/package.json b/apps/hash-api/package.json index 0094a604952..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": "4.0.0", + "effect": "4.0.3", "exponential-backoff": "3.1.3", "express": "5.2.0", "express-handlebars": "8.0.4", diff --git a/libs/@local/eslint/package.json b/libs/@local/eslint/package.json index dea94303500..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": "4.0.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/graph/sdk/typescript/package.json b/libs/@local/graph/sdk/typescript/package.json index 6580561b54f..b2d8c48823e 100644 --- a/libs/@local/graph/sdk/typescript/package.json +++ b/libs/@local/graph/sdk/typescript/package.json @@ -31,7 +31,7 @@ "@local/hash-graph-client": "workspace:*", "@local/hash-graph-store": "workspace:*", "@temporalio/client": "1.20.2", - "effect": "4.0.0", + "effect": "4.0.3", "uuid": "14.0.0" }, "devDependencies": { diff --git a/libs/@local/harpc/client/typescript/package.json b/libs/@local/harpc/client/typescript/package.json index 18d35de9413..1c1f0be57e3 100644 --- a/libs/@local/harpc/client/typescript/package.json +++ b/libs/@local/harpc/client/typescript/package.json @@ -33,15 +33,15 @@ "@libp2p/tcp": "11.0.28", "@multiformats/dns": "1.0.10", "@multiformats/multiaddr": "13.0.3", - "effect": "4.0.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/platform-node": "4.0.0", - "@effect/vitest": "4.0.0", + "@effect/platform-node": "4.0.3", + "@effect/vitest": "4.0.3", "@local/eslint": "workspace:*", "@local/tsconfig": "workspace:*", "@tsconfig/bases": "catalog:", diff --git a/libs/@local/harpc/client/typescript/src/types/ResponseKind.ts b/libs/@local/harpc/client/typescript/src/types/ResponseKind.ts index ed1bba35716..632a630fe4c 100644 --- a/libs/@local/harpc/client/typescript/src/types/ResponseKind.ts +++ b/libs/@local/harpc/client/typescript/src/types/ResponseKind.ts @@ -190,6 +190,7 @@ export const getErr = ( 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/wire-protocol/models/request/RequestBody.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/models/request/RequestBody.ts index 70fecbfd2f8..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 @@ -195,6 +195,7 @@ const arbitraryRequestBegin = RequestBegin.arbitrary.pipe( 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/response/ResponseBody.ts b/libs/@local/harpc/client/typescript/src/wire-protocol/models/response/ResponseBody.ts index c70d53fab45..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 @@ -185,6 +185,7 @@ const arbitraryBegin = ResponseBegin.arbitrary.pipe( 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/tests/wire-protocol/decode.test.ts b/libs/@local/harpc/client/typescript/tests/wire-protocol/decode.test.ts index 48fa77bc554..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,4 +1,4 @@ -import { NodeServices } from "@effect/platform-node"; +import * as NodeServices from "@effect/platform-node/NodeServices"; import { describe, it } from "@effect/vitest"; import { Effect, Equal } from "effect"; 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 b8ddd9f29e1..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,4 +1,4 @@ -import { NodeServices } from "@effect/platform-node"; +import * as NodeServices from "@effect/platform-node/NodeServices"; import { type TestContext, describe, it } from "@effect/vitest"; import { Effect, Option, Predicate } from "effect"; diff --git a/yarn.lock b/yarn.lock index 4fa019fd348..df7e2403d53 100644 --- a/yarn.lock +++ b/yarn.lock @@ -585,7 +585,7 @@ __metadata: axios: "npm:1.20.0" cors: "npm:2.8.5" dedent: "npm:1.7.0" - effect: "npm:4.0.0" + effect: "npm:4.0.3" eslint: "npm:9.39.4" exponential-backoff: "npm:3.1.3" express: "npm:5.2.0" @@ -4700,7 +4700,7 @@ __metadata: languageName: node linkType: hard -"@effect/platform-node-shared@npm:^4.0.0": +"@effect/platform-node-shared@npm:^4.0.3": version: 4.0.6 resolution: "@effect/platform-node-shared@npm:4.0.6" dependencies: @@ -4712,26 +4712,26 @@ __metadata: languageName: node linkType: hard -"@effect/platform-node@npm:4.0.0": - version: 4.0.0 - resolution: "@effect/platform-node@npm:4.0.0" +"@effect/platform-node@npm:4.0.3": + version: 4.0.3 + resolution: "@effect/platform-node@npm:4.0.3" dependencies: - "@effect/platform-node-shared": "npm:^4.0.0" + "@effect/platform-node-shared": "npm:^4.0.3" undici: "npm:^8.11.2" peerDependencies: - effect: ^4.0.0 + effect: ^4.0.3 redis: ">=5.0.0 <7.0.0" - checksum: 10c0/2657631ede73c0ff55daf6260e9fdfce16c18c98160d5ada7f15f8c92f4fcf3f9b8ce396d7853134f8005969ae71bff0fc8de603037c014f22a1169b1c6c4a9d + checksum: 10c0/ec17b68e4186c5f681e034344b6ba2e2c098e9f0ac12199e981fd0085206a777daefead03f3a456c1a8bcfb750b5d18762ff19402fbed871907fd94450315aea languageName: node linkType: hard -"@effect/vitest@npm:4.0.0": - version: 4.0.0 - resolution: "@effect/vitest@npm:4.0.0" +"@effect/vitest@npm:4.0.3": + version: 4.0.3 + resolution: "@effect/vitest@npm:4.0.3" peerDependencies: - effect: ^4.0.0 + effect: ^4.0.3 vitest: ">=5.0.0 <6.0.0" - checksum: 10c0/baec89578bc430c283f56b9f0346b38a403a6ac81194222d8888ead2f1d281379133b1fde6666b08b3e9e618e73bcd9c7ac632f821a0f1f74ffe8e3c34ad7681 + checksum: 10c0/6ab29316e9e05c1c0f5e4cdf495d7b561966cef407d57d1767c02f5d98023253e334f0173082f545edbfb89bbdac566ec6c71ae2fc8af023e0f9ce2224ceba45 languageName: node linkType: hard @@ -9162,7 +9162,7 @@ __metadata: "@types/node": "catalog:" "@typescript-eslint/eslint-plugin": "npm:8.71.0" "@typescript-eslint/parser": "npm:8.71.0" - effect: "npm:4.0.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" @@ -9228,8 +9228,8 @@ __metadata: dependencies: "@chainsafe/libp2p-noise": "npm:17.0.0" "@chainsafe/libp2p-yamux": "npm:8.0.1" - "@effect/platform-node": "npm:4.0.0" - "@effect/vitest": "npm:4.0.0" + "@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" @@ -9242,7 +9242,7 @@ __metadata: "@tsconfig/bases": "catalog:" "@types/node": "catalog:" "@vitest/coverage-istanbul": "catalog:" - effect: "npm:4.0.0" + effect: "npm:4.0.3" eslint: "npm:9.39.4" it-stream-types: "npm:2.0.2" libp2p: "npm:3.3.11" @@ -9382,7 +9382,7 @@ __metadata: "@temporalio/client": "npm:1.20.2" "@tsconfig/bases": "catalog:" "@vitest/coverage-istanbul": "catalog:" - effect: "npm:4.0.0" + effect: "npm:4.0.3" eslint: "npm:9.39.4" rimraf: "npm:6.1.3" typescript: "catalog:" @@ -24253,10 +24253,10 @@ __metadata: languageName: node linkType: hard -"effect@npm:4.0.0": - version: 4.0.0 - resolution: "effect@npm:4.0.0" - checksum: 10c0/c9cd4c151a0d5141c82331e313fcfa5ba2ac99c6b3cc3d310eb92925286efe96487685f2a3b215a2470b9ee50b0e2f10c187149b820c696c9b1d7d0edd3a6e3c +"effect@npm:4.0.3": + version: 4.0.3 + resolution: "effect@npm:4.0.3" + checksum: 10c0/2b750bcd6372d89252f07602e5cc66f8ac21fb4481083e33764e84299d56909ac1e64ec16531a435af1c06f299e0cdec28a731204d7ab42ddd1b10de2b098c01 languageName: node linkType: hard From 2ea8dd6db5708fc0346642137405f789cd1ed677 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud <7252775+indietyp@users.noreply.github.com> Date: Mon, 26 Oct 2026 11:01:57 +0100 Subject: [PATCH 13/17] fix: surface lagged transaction errors --- .../client/typescript/src/net/Connection.ts | 53 ++++--- .../client/typescript/src/net/Transaction.ts | 21 ++- .../typescript/tests/net/Transaction.test.ts | 129 ++++++++++++++++++ yarn.lock | 8 +- 4 files changed, 187 insertions(+), 24 deletions(-) create mode 100644 libs/@local/harpc/client/typescript/tests/net/Transaction.test.ts diff --git a/libs/@local/harpc/client/typescript/src/net/Connection.ts b/libs/@local/harpc/client/typescript/src/net/Connection.ts index f0919ab2053..7cbab621f83 100644 --- a/libs/@local/harpc/client/typescript/src/net/Connection.ts +++ b/libs/@local/harpc/client/typescript/src/net/Connection.ts @@ -97,8 +97,12 @@ export interface Connection { } interface TransactionContext { - queue: Queue.Enqueue; + queue: Queue.Enqueue< + WireResponse.Response, + Transaction.TransactionLaggedError | Cause.Done + >; drop: Effect.Effect; + dropLagged: Effect.Effect; } interface ConnectionImpl extends Connection { @@ -137,21 +141,21 @@ 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("TimeoutError", (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.dropLagged; + + return; + } + + if (!offered.value) { yield* Effect.logWarning("transaction has been closed, dropping it"); yield* transaction.value.drop; @@ -170,6 +174,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); @@ -180,7 +185,7 @@ const wrapDrop = Effect.fn("wrapDrop")(function* ( } MutableHashMap.remove(connection.transactions, id); - yield* Queue.end(transaction.value.queue); + yield* close(transaction.value.queue); // call user defined drop function const dropImpl = yield* Deferred.poll(drop); @@ -300,15 +305,27 @@ 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 queue = yield* Queue.bounded( - impl.config.responseBufferSize ?? 16, + const drop = wrapDrop(impl, request.id, deferredDrop, Queue.end); + const dropLagged = wrapDrop( + impl, + request.id, + deferredDrop, + (transactionQueue) => + Queue.fail( + transactionQueue, + new Transaction.TransactionLaggedError({ id: request.id }), + ), ); + const queue = yield* Queue.bounded< + WireResponse.Response, + Transaction.TransactionLaggedError | Cause.Done + >(impl.config.responseBufferSize ?? 16); + const transactionContext: TransactionContext = { queue, drop, + dropLagged, }; MutableHashMap.set(impl.transactions, request.id, transactionContext); diff --git a/libs/@local/harpc/client/typescript/src/net/Transaction.ts b/libs/@local/harpc/client/typescript/src/net/Transaction.ts index 91724c6c4c5..ecb3dafe0c5 100644 --- a/libs/@local/harpc/client/typescript/src/net/Transaction.ts +++ b/libs/@local/harpc/client/typescript/src/net/Transaction.ts @@ -1,5 +1,6 @@ import { type Cause, + Data, Deferred, type Effect, Function, @@ -17,6 +18,16 @@ 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 interface Transaction { readonly [TypeId]: TypeId; @@ -24,7 +35,10 @@ export interface Transaction { } interface TransactionImpl extends Transaction { - readonly read: Queue.Dequeue; + readonly read: Queue.Dequeue< + WireResponse.Response, + TransactionLaggedError | Cause.Done + >; readonly drop: Deferred.Deferred; } @@ -36,7 +50,10 @@ const TransactionProto: Omit = { /** @internal */ export const makeUnchecked = ( id: RequestId.RequestId, - readQueue: Queue.Dequeue, + readQueue: Queue.Dequeue< + WireResponse.Response, + TransactionLaggedError | Cause.Done + >, drop: Deferred.Deferred, ): Transaction => createProto(TransactionProto, { id, read: readQueue, drop }); 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..c162ace0017 --- /dev/null +++ b/libs/@local/harpc/client/typescript/tests/net/Transaction.test.ts @@ -0,0 +1,129 @@ +import { describe, it } from "@effect/vitest"; +import { + Cause, + Deferred, + Effect, + Exit, + HashSet, + pipe, + Queue, + Result, + Stream, +} from "effect"; + +import { Transaction } from "../../src/net/index.js"; +import { 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(); + + yield* Queue.offerAll(queue, [ + yield* makeBegin("first ", false), + yield* makeFrame("second ", false), + yield* makeFrame("third", true), + ]); + 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(); + + yield* Queue.offer(queue, yield* makeBegin("partial", false)); + 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); + }), + ); +}); diff --git a/yarn.lock b/yarn.lock index df7e2403d53..bfd9a494e4f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4701,14 +4701,14 @@ __metadata: linkType: hard "@effect/platform-node-shared@npm:^4.0.3": - version: 4.0.6 - resolution: "@effect/platform-node-shared@npm:4.0.6" + version: 4.0.3 + resolution: "@effect/platform-node-shared@npm:4.0.3" dependencies: "@types/ws": "npm:^8.18.2" ws: "npm:^8.22.0" peerDependencies: - effect: ^4.0.6 - checksum: 10c0/2caee178bfc9a99e92733175e023208e7b5a01e6f95430d7003d2e0ec7febc57232dadfcdf2d747d8a7e82b329ba836d8b4a2d8afc670787c2980db5d6fdfd0f + effect: ^4.0.3 + checksum: 10c0/cc33c8f4d32b333555eabc72c58a3273e571ab7db832be503e88ddc30d1293ec4ca91650aa5039e06ef9840ba403aaf3feea81003d6f870c00c8cc5a620a8078 languageName: node linkType: hard From 0dd63742e722898ba5a8551c6c0a8b5234fd1525 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud <7252775+indietyp@users.noreply.github.com> Date: Fri, 30 Oct 2026 13:19:41 +0100 Subject: [PATCH 14/17] fix: surface trailing response errors --- .../client/typescript/src/net/Response.ts | 11 +++++++ .../typescript/tests/net/Transaction.test.ts | 31 +++++++++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/libs/@local/harpc/client/typescript/src/net/Response.ts b/libs/@local/harpc/client/typescript/src/net/Response.ts index 02d4ca42644..80ae3ee2746 100644 --- a/libs/@local/harpc/client/typescript/src/net/Response.ts +++ b/libs/@local/harpc/client/typescript/src/net/Response.ts @@ -137,6 +137,17 @@ 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/tests/net/Transaction.test.ts b/libs/@local/harpc/client/typescript/tests/net/Transaction.test.ts index c162ace0017..720430b1d50 100644 --- a/libs/@local/harpc/client/typescript/tests/net/Transaction.test.ts +++ b/libs/@local/harpc/client/typescript/tests/net/Transaction.test.ts @@ -11,8 +11,8 @@ import { Stream, } from "effect"; -import { Transaction } from "../../src/net/index.js"; -import { ResponseKind } from "../../src/types/index.js"; +import { Response as NetResponse, Transaction } from "../../src/net/index.js"; +import { ErrorCode, ResponseKind } from "../../src/types/index.js"; import { Payload, Protocol, @@ -126,4 +126,31 @@ describe.concurrent("Transaction", () => { ).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); + }), + ); }); From a0f0db2a4b0a2f4a2298cc0c9e9932128cb35a40 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud <7252775+indietyp@users.noreply.github.com> Date: Fri, 30 Oct 2026 13:48:49 +0100 Subject: [PATCH 15/17] fix: fail transactions when connection closes --- .../client/typescript/src/net/Connection.ts | 108 ++++++++---- .../client/typescript/src/net/Transaction.ts | 29 +++- .../typescript/tests/net/Connection.test.ts | 164 ++++++++++++++++++ 3 files changed, 267 insertions(+), 34 deletions(-) create mode 100644 libs/@local/harpc/client/typescript/tests/net/Connection.test.ts diff --git a/libs/@local/harpc/client/typescript/src/net/Connection.ts b/libs/@local/harpc/client/typescript/src/net/Connection.ts index 7cbab621f83..d713762e462 100644 --- a/libs/@local/harpc/client/typescript/src/net/Connection.ts +++ b/libs/@local/harpc/client/typescript/src/net/Connection.ts @@ -4,8 +4,10 @@ import { Deferred, Duration, Effect, + Exit, Function, MutableHashMap, + MutableRef, Option, pipe, Queue, @@ -99,10 +101,10 @@ export interface Connection { interface TransactionContext { queue: Queue.Enqueue< WireResponse.Response, - Transaction.TransactionLaggedError | Cause.Done + Transaction.TransactionError | Cause.Done >; drop: Effect.Effect; - dropLagged: Effect.Effect; + fail: (error: Transaction.TransactionError) => Effect.Effect; } interface ConnectionImpl extends Connection { @@ -111,6 +113,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; @@ -118,7 +125,7 @@ interface ConnectionImpl extends Connection { const ConnectionProto: Omit< ConnectionImpl, - "transactions" | "duplex" | "config" + "transactions" | "closed" | "duplex" | "config" > = { [TypeId]: TypeId, }; @@ -150,7 +157,9 @@ const makeSink = (connection: ConnectionImpl) => yield* Effect.logWarning( "transaction has lagged behind too far, dropping it", ).pipe(Effect.annotateLogs({ lagTimeout })); - yield* transaction.value.dropLagged; + yield* transaction.value.fail( + new Transaction.TransactionLaggedError({ id }), + ); return; } @@ -195,11 +204,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 */ @@ -271,19 +325,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.forkChild(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, @@ -306,26 +348,29 @@ 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, Queue.end); - const dropLagged = wrapDrop( - impl, - request.id, - deferredDrop, - (transactionQueue) => - Queue.fail( - transactionQueue, - new Transaction.TransactionLaggedError({ id: request.id }), - ), - ); + const fail = (error: Transaction.TransactionError) => + wrapDrop(impl, request.id, deferredDrop, (transactionQueue) => + Queue.fail(transactionQueue, error), + ); const queue = yield* Queue.bounded< WireResponse.Response, - Transaction.TransactionLaggedError | Cause.Done + 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, - dropLagged, + fail, }; MutableHashMap.set(impl.transactions, request.id, transactionContext); @@ -336,6 +381,7 @@ export const send = Function.dual< Request.encode(), Stream.run(impl.duplex.write), Effect.scoped, + Effect.catch(fail), ), ); diff --git a/libs/@local/harpc/client/typescript/src/net/Transaction.ts b/libs/@local/harpc/client/typescript/src/net/Transaction.ts index ecb3dafe0c5..1676cdd59f4 100644 --- a/libs/@local/harpc/client/typescript/src/net/Transaction.ts +++ b/libs/@local/harpc/client/typescript/src/net/Transaction.ts @@ -11,8 +11,13 @@ import { 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"); @@ -28,6 +33,24 @@ export class TransactionLaggedError extends Data.TaggedError( } } +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; @@ -37,7 +60,7 @@ export interface Transaction { interface TransactionImpl extends Transaction { readonly read: Queue.Dequeue< WireResponse.Response, - TransactionLaggedError | Cause.Done + TransactionError | Cause.Done >; readonly drop: Deferred.Deferred; @@ -52,7 +75,7 @@ export const makeUnchecked = ( id: RequestId.RequestId, readQueue: Queue.Dequeue< WireResponse.Response, - TransactionLaggedError | Cause.Done + TransactionError | Cause.Done >, drop: Deferred.Deferred, ): Transaction => createProto(TransactionProto, { id, read: readQueue, drop }); 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..f4463f8a491 --- /dev/null +++ b/libs/@local/harpc/client/typescript/tests/net/Connection.test.ts @@ -0,0 +1,164 @@ +import { describe, it } from "@effect/vitest"; +import { + Cause, + Effect, + Exit, + HashSet, + pipe, + Queue, + Result, + Sink, + Stream, +} from "effect"; + +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, +) { + const responses = yield* Queue.unbounded< + Response.Response, + Transport.TransportError | Cause.Done + >(); + + const connection = yield* Connection.makeFromDuplex( + { read: Stream.fromQueue(responses), write }, + {}, + ); + + 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 request = yield* makeRequest(); + + const first = yield* Connection.send(connection, request); + const second = yield* Connection.send(connection, yield* makeRequest()); + + yield* Queue.offer(responses, yield* makePartialResponse(request.id)); + 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 error = new Transport.TransportError({ cause: "reset" }); + + const transaction = yield* Connection.send(connection, request); + + yield* Queue.offer(responses, yield* makePartialResponse(request.id)); + 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 transaction = yield* Connection.send( + connection, + yield* makeRequest(), + ); + + 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 first = yield* Connection.send(connection, yield* makeRequest()); + + 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, yield* makeRequest()); + + cx.expect(yield* readError(second)).toBeInstanceOf( + Transaction.ConnectionClosedError, + ); + }).pipe(Effect.provide(RequestIdProducer.layer)), + ); +}); From 4ec6df95e649a0af2c09d4c3f916f763d80964f5 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud <7252775+indietyp@users.noreply.github.com> Date: Fri, 30 Oct 2026 14:24:01 +0100 Subject: [PATCH 16/17] fix: correct harpc response and decoding bugs --- .../client/typescript/src/codec/Decoder.ts | 2 +- .../typescript/src/codec/JsonDecoder.ts | 6 ++- .../client/typescript/src/net/Connection.ts | 5 +- .../client/typescript/src/net/Transaction.ts | 5 ++ .../client/typescript/src/net/internal/dns.ts | 14 +++--- .../models/response/ResponseBegin.ts | 2 +- .../tests/codec/JsonDecoder.test.ts | 12 ++++- .../typescript/tests/net/Connection.test.ts | 50 ++++++++++++++----- .../typescript/tests/net/Transaction.test.ts | 12 ++--- .../tests/wire-protocol/roundtrip.test.ts | 25 ++++++++++ 10 files changed, 100 insertions(+), 33 deletions(-) create mode 100644 libs/@local/harpc/client/typescript/tests/wire-protocol/roundtrip.test.ts diff --git a/libs/@local/harpc/client/typescript/src/codec/Decoder.ts b/libs/@local/harpc/client/typescript/src/codec/Decoder.ts index a3173e23457..c7697eb99e8 100644 --- a/libs/@local/harpc/client/typescript/src/codec/Decoder.ts +++ b/libs/@local/harpc/client/typescript/src/codec/Decoder.ts @@ -18,7 +18,7 @@ export class DecodingError extends Data.TaggedError("DecodingError")<{ cause: unknown; }> { get message() { - return "Failed to encode value"; + return "Failed to decode value"; } } diff --git a/libs/@local/harpc/client/typescript/src/codec/JsonDecoder.ts b/libs/@local/harpc/client/typescript/src/codec/JsonDecoder.ts index 13d6c337071..4c29f12daa5 100644 --- a/libs/@local/harpc/client/typescript/src/codec/JsonDecoder.ts +++ b/libs/@local/harpc/client/typescript/src/codec/JsonDecoder.ts @@ -94,8 +94,10 @@ const make = (options: Options) => ignoreBOM: true, }); - const schemaJson = Schema.fromJsonString(schema); - const decodeJson = Schema.decodeEffect(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 = ""; diff --git a/libs/@local/harpc/client/typescript/src/net/Connection.ts b/libs/@local/harpc/client/typescript/src/net/Connection.ts index d713762e462..0c61096f64e 100644 --- a/libs/@local/harpc/client/typescript/src/net/Connection.ts +++ b/libs/@local/harpc/client/typescript/src/net/Connection.ts @@ -58,8 +58,9 @@ 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 */ diff --git a/libs/@local/harpc/client/typescript/src/net/Transaction.ts b/libs/@local/harpc/client/typescript/src/net/Transaction.ts index 1676cdd59f4..14815296644 100644 --- a/libs/@local/harpc/client/typescript/src/net/Transaction.ts +++ b/libs/@local/harpc/client/typescript/src/net/Transaction.ts @@ -90,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(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 b1028f39bc2..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 } from "effect"; +import { Array, Cause, Data, Duration, Effect, Function, Result } from "effect"; import type { NonEmptyReadonlyArray } from "effect/Array"; @@ -128,15 +128,12 @@ export const resolve = Effect.fn("resolve")(function* ( yield* Effect.forkChild(logEnvironment(hostname)); - const results = yield* Effect.forEach( + const [satisfying, excluded] = yield* Effect.partition( resolvers, - (resolver) => Effect.result(resolver), + Function.identity, { concurrency: "unbounded" }, ); - const satisfying = Array.getSuccesses(results); - const excluded = Array.getFailures(results); - if (satisfying.length === 0) { // means that excluded is non empty @@ -162,8 +159,9 @@ export const lookup = Effect.fn("lookup")(function* ( yield* Effect.forkChild(logEnvironment(hostname)); // partition into A and AAAA records - const satisfying = records.filter((record) => record.family === 4); - const excluded = records.filter((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 // `getaddrinfo` (the underlying call used by dns.lookup) does not return TTLs 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 a1ae08cac8f..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 @@ -83,7 +83,7 @@ export const encode = implEncode((buffer, begin: ResponseBegin) => pipe( buffer, MutableBuffer.advance(17), - Result.andThen(ResponseKind.encode(buffer, begin.kind)), + Result.andThen(ResponseKind.encode(begin.kind)), Result.andThen(Payload.encode(begin.payload)), ), ); 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 975e3c92f0a..a9ec5342782 100644 --- a/libs/@local/harpc/client/typescript/tests/codec/JsonDecoder.test.ts +++ b/libs/@local/harpc/client/typescript/tests/codec/JsonDecoder.test.ts @@ -93,7 +93,17 @@ describe.concurrent("JsonDecoder", () => { Effect.flip, ); - cx.expect(error.toString()).toMatch(/Expected a valid JSON string/); + 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/net/Connection.test.ts b/libs/@local/harpc/client/typescript/tests/net/Connection.test.ts index f4463f8a491..dbb2ef8bf6d 100644 --- a/libs/@local/harpc/client/typescript/tests/net/Connection.test.ts +++ b/libs/@local/harpc/client/typescript/tests/net/Connection.test.ts @@ -10,6 +10,7 @@ import { Sink, Stream, } from "effect"; +import { TestClock } from "effect/testing"; import { Connection, @@ -43,6 +44,7 @@ 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, @@ -51,7 +53,7 @@ const makeConnection = Effect.fn("makeConnection")(function* ( const connection = yield* Connection.makeFromDuplex( { read: Stream.fromQueue(responses), write }, - {}, + config, ); return { connection, responses }; @@ -97,12 +99,14 @@ describe.concurrent("Connection", () => { it.effect("read end", (cx) => Effect.gen(function* () { const { connection, responses } = yield* makeConnection(Sink.drain); - const request = yield* makeRequest(); + const firstRequest = yield* makeRequest(); + const secondRequest = yield* makeRequest(); + const partial = yield* makePartialResponse(firstRequest.id); - const first = yield* Connection.send(connection, request); - const second = yield* Connection.send(connection, yield* makeRequest()); + const first = yield* Connection.send(connection, firstRequest); + const second = yield* Connection.send(connection, secondRequest); - yield* Queue.offer(responses, yield* makePartialResponse(request.id)); + yield* Queue.offer(responses, partial); yield* Queue.end(responses); cx.expect(yield* readError(first)).toBeInstanceOf( @@ -118,11 +122,12 @@ describe.concurrent("Connection", () => { 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, yield* makePartialResponse(request.id)); + yield* Queue.offer(responses, partial); yield* Queue.fail(responses, error); cx.expect(yield* readError(transaction)).toBe(error); @@ -133,11 +138,9 @@ describe.concurrent("Connection", () => { 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, - yield* makeRequest(), - ); + const transaction = yield* Connection.send(connection, request); cx.expect(yield* readError(transaction)).toBe(error); }).pipe(Effect.provide(RequestIdProducer.layer)), @@ -146,19 +149,42 @@ describe.concurrent("Connection", () => { 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, 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, yield* makeRequest()); + 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/Transaction.test.ts b/libs/@local/harpc/client/typescript/tests/net/Transaction.test.ts index 720430b1d50..3efbc974739 100644 --- a/libs/@local/harpc/client/typescript/tests/net/Transaction.test.ts +++ b/libs/@local/harpc/client/typescript/tests/net/Transaction.test.ts @@ -94,12 +94,11 @@ 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, [ - yield* makeBegin("first ", false), - yield* makeFrame("second ", false), - yield* makeFrame("third", true), - ]); + yield* Queue.offerAll(queue, [first, second, third]); yield* Queue.end(queue); const text = yield* readText(transaction); @@ -111,8 +110,9 @@ describe.concurrent("Transaction", () => { it.effect("lagged", (cx) => Effect.gen(function* () { const { queue, transaction } = yield* makeTransaction(); + const begin = yield* makeBegin("partial", false); - yield* Queue.offer(queue, yield* makeBegin("partial", false)); + yield* Queue.offer(queue, begin); yield* Queue.fail( queue, new Transaction.TransactionLaggedError({ id: requestId }), 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(); + }), + ); +}); From c2b4b39617822aa0bdee2c5cd14d893b927d7d86 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud <7252775+indietyp@users.noreply.github.com> Date: Mon, 2 Nov 2026 12:36:15 +0100 Subject: [PATCH 17/17] chore: switch codec bench to Result.getOrThrow --- .../client/typescript/tests/wire-protocol/codec.bench.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 753f3037a6f..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 @@ -42,7 +42,7 @@ describe("request", () => { await bench("decode", () => { const buffer = MutableBuffer.makeRead(MutableBytes.from(requestEncoded)); - Request.decode(buffer).pipe(Either.getOrThrow); + Request.decode(buffer).pipe(Result.getOrThrow); }).run(); }); }); @@ -59,7 +59,7 @@ describe("response", () => { await bench("decode", () => { const buffer = MutableBuffer.makeRead(MutableBytes.from(responseEncoded)); - Response.decode(buffer).pipe(Either.getOrThrow); + Response.decode(buffer).pipe(Result.getOrThrow); }).run(); }); });