diff --git a/README.md b/README.md index b676b53cb..2763e6810 100644 --- a/README.md +++ b/README.md @@ -44,21 +44,6 @@ $ npm install @seamapi/react [npm]: https://www.npmjs.com/ -### Peer dependencies - -If your project uses a recent version of npm, peer dependencies will be handled automatically. -If you package manager does not automatically install peer dependencies, install these packages: - -``` -@seamapi/http react react-dom -``` - -If using TypeScript, install these packages as development dependencies: - -``` -@seamapi/types @types/react @types/react-dom -``` - ## Usage ### With React diff --git a/package-lock.json b/package-lock.json index a66d4971a..c3ad4ade2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,8 @@ "license": "MIT", "dependencies": { "@floating-ui/react": "^0.27.5", + "@seamapi/http": "^1.45.0", + "@seamapi/react-query": "^0.2.0", "@tanstack/react-query": "^5.27.5", "classnames": "^2.3.2", "luxon": "^3.3.0", @@ -26,8 +28,7 @@ "@rxfork/r2wc-react-to-web-component": "^2.4.0", "@seamapi/fake-devicedb": "^1.6.1", "@seamapi/fake-seam-connect": "^1.76.0", - "@seamapi/http": "^1.40.1", - "@seamapi/types": "^1.395.3", + "@seamapi/types": "^1.441.1", "@storybook/addon-designs": "^7.0.1", "@storybook/addon-essentials": "^7.0.2", "@storybook/addon-links": "^7.0.2", @@ -84,8 +85,7 @@ "npm": ">= 9.0.0" }, "peerDependencies": { - "@seamapi/http": "^1.37.0", - "@seamapi/types": "^1.395.3", + "@seamapi/types": "^1.441.1", "@types/react": "^18.0.0 || ^19.0.0", "@types/react-dom": "^18.0.0 || ^19.0.0", "react": "^18.0.0 || ^19.0.0", @@ -5993,10 +5993,9 @@ } }, "node_modules/@seamapi/http": { - "version": "1.40.1", - "resolved": "https://registry.npmjs.org/@seamapi/http/-/http-1.40.1.tgz", - "integrity": "sha512-in/Mx88HTvoCYVrRP7J9Vztfzp/EHgu2LuQgyeRz7a9oya7Wxxcc1Ya5l3AijGUzpjvvDxfHJLHVgQMYDzZwJA==", - "dev": true, + "version": "1.45.0", + "resolved": "https://registry.npmjs.org/@seamapi/http/-/http-1.45.0.tgz", + "integrity": "sha512-ABLSJpMtVJh7euf+VLo5Z1yfGkv8v60vJgNv0dJhbDWtYz6fLsyyUI6h9OtlPlf89fNcr6DlwmtM0UkxEkiSzg==", "license": "MIT", "dependencies": { "@seamapi/url-search-params-serializer": "^2.0.0", @@ -6008,7 +6007,7 @@ "npm": ">=10.1.0" }, "peerDependencies": { - "@seamapi/types": "^1.420.2" + "@seamapi/types": "^1.439.0" }, "peerDependenciesMeta": { "@seamapi/types": { @@ -6016,11 +6015,44 @@ } } }, + "node_modules/@seamapi/react-query": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@seamapi/react-query/-/react-query-0.2.0.tgz", + "integrity": "sha512-HMaHGxs3jGLeOUXDzhIhTBqmGOB32mCbmi0oU3pt0/Uof+Wv5ZvRsWkEaAGBPy9htFDG/9qsx66oVE64SHI39Q==", + "license": "MIT", + "dependencies": { + "uuid": "^11.0.3" + }, + "engines": { + "node": ">=20.9.0", + "npm": ">=10.1.0" + }, + "peerDependencies": { + "@seamapi/http": "^1.45.0", + "@seamapi/types": "^1.441.1", + "@tanstack/react-query": "^5.27.5", + "@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" + }, + "peerDependenciesMeta": { + "@seamapi/types": { + "optional": true + }, + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@seamapi/types": { - "version": "1.429.0", - "resolved": "https://registry.npmjs.org/@seamapi/types/-/types-1.429.0.tgz", - "integrity": "sha512-5mtHvbVUthvyh6sPgkyfp42od2JjdX6lxNYNLvsAoky1UaWgOPrkBtpXobSElR6H1qd0CeTtzu1Eo32qupnRGw==", - "dev": true, + "version": "1.441.1", + "resolved": "https://registry.npmjs.org/@seamapi/types/-/types-1.441.1.tgz", + "integrity": "sha512-r1j/SgsmQW+4vm7MTmnRJwGqNYvkAdlDnkVhL3jSA6QW3VQtv/EMzd/jaSeakpUH9jli+1lgN+fLxrM2n9fu5A==", + "devOptional": true, "license": "MIT", "engines": { "node": ">=18.12.0", @@ -6034,7 +6066,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@seamapi/url-search-params-serializer/-/url-search-params-serializer-2.0.0.tgz", "integrity": "sha512-mXHTk9b4pVueFOKkpWyQG6yVK8YWPjr3ksdvBoKhSn8inrBM3Blp539BHuiT4GDfjYtgWq+/j3GN3JTDMuXxJQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=18.12.0", @@ -9049,7 +9080,7 @@ "version": "15.7.15", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@types/qs": { @@ -9070,7 +9101,7 @@ "version": "18.3.23", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz", "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -9081,7 +9112,7 @@ "version": "18.3.7", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", - "dev": true, + "devOptional": true, "license": "MIT", "peerDependencies": { "@types/react": "^18.0.0" @@ -10840,7 +10871,6 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, "license": "MIT" }, "node_modules/available-typed-arrays": { @@ -10863,7 +10893,6 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", - "dev": true, "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -10875,7 +10904,6 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-4.5.0.tgz", "integrity": "sha512-aR99oXhpEDGo0UuAlYcn2iGRds30k366Zfa05XWScR9QaQD4JYiP3/1Qt1u7YlefUOK+cn0CcwoL1oefavQUlQ==", - "dev": true, "license": "Apache-2.0", "dependencies": { "is-retry-allowed": "^2.2.0" @@ -11543,7 +11571,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -12069,7 +12096,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" @@ -12712,7 +12738,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/dashify": { @@ -13069,7 +13095,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.4.0" @@ -13456,7 +13481,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -13813,7 +13837,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -13823,7 +13846,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -13890,7 +13912,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -13903,7 +13924,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -16080,7 +16100,6 @@ "version": "1.15.9", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", - "dev": true, "funding": [ { "type": "individual", @@ -16295,7 +16314,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", - "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -16416,7 +16434,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -16539,7 +16556,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -16607,7 +16623,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -16864,7 +16879,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -17022,7 +17036,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -17035,7 +17048,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -17058,7 +17070,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -18029,7 +18040,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz", "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -19198,7 +19208,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -19542,7 +19551,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -19552,7 +19560,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -21164,7 +21171,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true, "license": "MIT" }, "node_modules/prr": { @@ -27477,7 +27483,7 @@ "version": "3.25.67", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.67.tgz", "integrity": "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==", - "dev": true, + "devOptional": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/package.json b/package.json index 56e24fb5f..4a8cf7247 100644 --- a/package.json +++ b/package.json @@ -109,8 +109,7 @@ "npm": ">= 9.0.0" }, "peerDependencies": { - "@seamapi/http": "^1.37.0", - "@seamapi/types": "^1.395.3", + "@seamapi/types": "^1.441.1", "@types/react": "^18.0.0 || ^19.0.0", "@types/react-dom": "^18.0.0 || ^19.0.0", "react": "^18.0.0 || ^19.0.0", @@ -129,6 +128,8 @@ }, "dependencies": { "@floating-ui/react": "^0.27.5", + "@seamapi/http": "^1.45.0", + "@seamapi/react-query": "^0.2.0", "@tanstack/react-query": "^5.27.5", "classnames": "^2.3.2", "luxon": "^3.3.0", @@ -145,8 +146,7 @@ "@rxfork/r2wc-react-to-web-component": "^2.4.0", "@seamapi/fake-devicedb": "^1.6.1", "@seamapi/fake-seam-connect": "^1.76.0", - "@seamapi/http": "^1.40.1", - "@seamapi/types": "^1.395.3", + "@seamapi/types": "^1.441.1", "@storybook/addon-designs": "^7.0.1", "@storybook/addon-essentials": "^7.0.2", "@storybook/addon-links": "^7.0.2", diff --git a/src/index.ts b/src/index.ts index ea9e4aaf6..85a27ee01 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,2 @@ +export * from '@seamapi/react-query' export * from 'lib/index.js' diff --git a/src/lib/index.ts b/src/lib/index.ts index 71a7d02f1..4842d5b89 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -1,4 +1,3 @@ export * from './seam/components/index.js' export * from './seam/index.js' export * from './seam/SeamProvider.js' -export * from './seam/SeamQueryProvider.js' diff --git a/src/lib/seam/SeamProvider.tsx b/src/lib/seam/SeamProvider.tsx index b0b9d5544..ca96caa8b 100644 --- a/src/lib/seam/SeamProvider.tsx +++ b/src/lib/seam/SeamProvider.tsx @@ -1,13 +1,13 @@ import type { SeamHttp } from '@seamapi/http/connect' -import type { QueryClient } from '@tanstack/react-query' -import { createContext, type PropsWithChildren, useMemo } from 'react' - import { SeamQueryProvider, type SeamQueryProviderPropsWithClient, type SeamQueryProviderPropsWithClientSessionToken, type SeamQueryProviderPropsWithPublishableKey, -} from 'lib/seam/SeamQueryProvider.js' +} from '@seamapi/react-query' +import type { QueryClient } from '@tanstack/react-query' +import { createContext, type PropsWithChildren, useMemo } from 'react' + import { useSeamFont } from 'lib/seam/use-seam-font.js' import { useSeamStyles } from 'lib/seam/use-seam-styles.js' import { diff --git a/src/lib/seam/SeamQueryProvider.tsx b/src/lib/seam/SeamQueryProvider.tsx deleted file mode 100644 index f231c6529..000000000 --- a/src/lib/seam/SeamQueryProvider.tsx +++ /dev/null @@ -1,356 +0,0 @@ -import type { - SeamHttp, - SeamHttpEndpoints, - SeamHttpOptionsWithClientSessionToken, -} from '@seamapi/http/connect' -import { - QueryClient, - QueryClientContext, - QueryClientProvider, -} from '@tanstack/react-query' -import { - createContext, - type PropsWithChildren, - useContext, - useEffect, - useMemo, -} from 'react' - -import { useSeamClient } from './use-seam-client.js' - -export interface SeamQueryContext { - client: SeamHttp | null - endpointClient: SeamHttpEndpoints | null - clientOptions?: SeamQueryProviderClientOptions | undefined - publishableKey?: string | undefined - userIdentifierKey?: string | undefined - clientSessionToken?: string | undefined - consoleSessionToken?: string | undefined - workspaceId?: string | undefined - queryKeyPrefix?: string | undefined -} - -export type SeamQueryProviderProps = - | SeamQueryProviderPropsWithClient - | SeamQueryProviderPropsWithPublishableKey - | SeamQueryProviderPropsWithClientSessionToken - | SeamQueryProviderPropsWithConsoleSessionToken - -export interface SeamQueryProviderPropsWithClient - extends SeamQueryProviderBaseProps { - client: SeamHttp - queryKeyPrefix: string -} - -export interface SeamQueryProviderPropsWithPublishableKey - extends SeamQueryProviderBaseProps, - SeamQueryProviderClientOptions { - publishableKey: string - userIdentifierKey?: string -} - -export interface SeamQueryProviderPropsWithClientSessionToken - extends SeamQueryProviderBaseProps, - SeamQueryProviderClientOptions { - clientSessionToken: string -} - -export interface SeamQueryProviderPropsWithConsoleSessionToken - extends SeamQueryProviderBaseProps, - SeamQueryProviderClientOptions { - consoleSessionToken: string - workspaceId?: string | undefined -} - -interface SeamQueryProviderBaseProps extends PropsWithChildren { - queryClient?: QueryClient | undefined - onSessionUpdate?: (client: SeamHttp) => void -} - -type SeamClientOptions = SeamHttpOptionsWithClientSessionToken - -export type SeamQueryProviderClientOptions = Pick< - SeamClientOptions, - 'endpoint' | 'isUndocumentedApiEnabled' -> - -const defaultQueryClient = new QueryClient() - -export function SeamQueryProvider({ - children, - onSessionUpdate = () => {}, - queryClient, - ...props -}: SeamQueryProviderProps): JSX.Element { - const value = useMemo(() => { - const context = createSeamQueryContextValue(props) - if ( - context.client == null && - context.publishableKey == null && - context.clientSessionToken == null && - context.consoleSessionToken == null - ) { - return defaultSeamQueryContextValue - } - return context - }, [props]) - - if ( - value.client == null && - value.publishableKey == null && - value.clientSessionToken == null && - value.consoleSessionToken == null - ) { - throw new Error( - `Must provide either a Seam client, clientSessionToken, publishableKey or consoleSessionToken.` - ) - } - - const { Provider } = seamContext - const queryClientFromContext = useContext(QueryClientContext) - - if ( - queryClientFromContext != null && - queryClient != null && - queryClientFromContext !== queryClient - ) { - throw new Error( - 'The QueryClient passed into SeamQueryProvider is different from the one in the existing QueryClientContext. Omit the queryClient prop from SeamProvider or SeamQueryProvider to use the existing QueryClient provided by the QueryClientProvider.' - ) - } - - return ( - - - {children} - - - ) -} - -function Session({ - onSessionUpdate, - children, -}: Required> & - PropsWithChildren): JSX.Element | null { - const { client } = useSeamClient() - useEffect(() => { - if (client != null) onSessionUpdate(client) - }, [onSessionUpdate, client]) - - return <>{children} -} - -const createDefaultSeamQueryContextValue = (): SeamQueryContext => { - try { - if (globalThis.seam == null) { - return { client: null, endpointClient: null } - } - return createSeamQueryContextValue(globalThis.seam) - } catch (err) { - // eslint-disable-next-line no-console - console.warn(err) - return { client: null, endpointClient: null } - } -} - -const createSeamQueryContextValue = ( - options: SeamQueryProviderProps -): SeamQueryContext => { - if (isSeamQueryProviderPropsWithClient(options)) { - if (options.queryKeyPrefix == null) { - throw new InvalidSeamQueryProviderProps( - 'The client prop must be used with a queryKeyPrefix prop.' - ) - } - return { - ...options, - endpointClient: null, - } - } - - if (isSeamQueryProviderPropsWithClientSessionToken(options)) { - const { clientSessionToken, ...clientOptions } = options - return { - clientSessionToken, - clientOptions, - client: null, - endpointClient: null, - } - } - - if (isSeamQueryProviderPropsWithPublishableKey(options)) { - const { publishableKey, userIdentifierKey, ...clientOptions } = options - return { - publishableKey, - userIdentifierKey, - clientOptions, - client: null, - endpointClient: null, - } - } - - if (isSeamQueryProviderPropsWithConsoleSessionToken(options)) { - const { consoleSessionToken, workspaceId, ...clientOptions } = options - return { - consoleSessionToken, - workspaceId, - clientOptions, - client: null, - endpointClient: null, - } - } - - return { client: null, endpointClient: null } -} - -const defaultSeamQueryContextValue = createDefaultSeamQueryContextValue() - -export const seamContext = createContext( - defaultSeamQueryContextValue -) - -export function useSeamQueryContext(): SeamQueryContext { - return useContext(seamContext) -} - -const isSeamQueryProviderPropsWithClient = ( - props: SeamQueryProviderProps -): props is SeamQueryProviderPropsWithClient => { - if (!('client' in props)) return false - - const { client, ...otherProps } = props - if (client == null) return false - - const otherNonNullProps = Object.values(otherProps).filter((v) => v != null) - if (otherNonNullProps.length > 0) { - throw new InvalidSeamQueryProviderProps( - `The client prop cannot be used with ${otherNonNullProps.join(' or ')}.` - ) - } - - return true -} - -const isSeamQueryProviderPropsWithPublishableKey = ( - props: SeamQueryProviderProps -): props is SeamQueryProviderPropsWithPublishableKey & - SeamQueryProviderClientOptions => { - if (!('publishableKey' in props)) return false - - const { publishableKey } = props - if (publishableKey == null) return false - - if ('client' in props && props.client != null) { - throw new InvalidSeamQueryProviderProps( - 'The client prop cannot be used with the publishableKey prop.' - ) - } - - if ('clientSessionToken' in props && props.clientSessionToken != null) { - throw new InvalidSeamQueryProviderProps( - 'The clientSessionToken prop cannot be used with the publishableKey prop.' - ) - } - - if ('consoleSessionToken' in props && props.consoleSessionToken != null) { - throw new InvalidSeamQueryProviderProps( - 'The consoleSessionToken prop cannot be used with the publishableKey prop.' - ) - } - - if ('workspaceId' in props && props.workspaceId != null) { - throw new InvalidSeamQueryProviderProps( - 'The workspaceId prop cannot be used with the publishableKey prop.' - ) - } - - return true -} - -const isSeamQueryProviderPropsWithClientSessionToken = ( - props: SeamQueryProviderProps -): props is SeamQueryProviderPropsWithClientSessionToken & - SeamQueryProviderClientOptions => { - if (!('clientSessionToken' in props)) return false - - const { clientSessionToken } = props - if (clientSessionToken == null) return false - - if ('client' in props && props.client != null) { - throw new InvalidSeamQueryProviderProps( - 'The client prop cannot be used with the clientSessionToken prop.' - ) - } - - if ('publishableKey' in props && props.publishableKey != null) { - throw new InvalidSeamQueryProviderProps( - 'The publishableKey prop cannot be used with the clientSessionToken prop.' - ) - } - - if ('userIdentifierKey' in props && props.userIdentifierKey != null) { - throw new InvalidSeamQueryProviderProps( - 'The userIdentifierKey prop cannot be used with the clientSessionToken prop.' - ) - } - - if ('consoleSessionToken' in props && props.consoleSessionToken != null) { - throw new InvalidSeamQueryProviderProps( - 'The consoleSessionToken prop cannot be used with the clientSessionToken prop.' - ) - } - - if ('workspaceId' in props && props.workspaceId != null) { - throw new InvalidSeamQueryProviderProps( - 'The workspaceId prop cannot be used with the clientSessionToken prop.' - ) - } - - return true -} - -const isSeamQueryProviderPropsWithConsoleSessionToken = ( - props: SeamQueryProviderProps -): props is SeamQueryProviderPropsWithConsoleSessionToken & - SeamQueryProviderClientOptions => { - if (!('consoleSessionToken' in props)) return false - - const { consoleSessionToken } = props - if (consoleSessionToken == null) return false - - if ('client' in props && props.client != null) { - throw new InvalidSeamQueryProviderProps( - 'The client prop cannot be used with the publishableKey prop.' - ) - } - - if ('clientSessionToken' in props && props.clientSessionToken != null) { - throw new InvalidSeamQueryProviderProps( - 'The clientSessionToken prop cannot be used with the publishableKey prop.' - ) - } - - if ('publishableKey' in props && props.publishableKey != null) { - throw new InvalidSeamQueryProviderProps( - 'The publishableKey prop cannot be used with the consoleSessionToken prop.' - ) - } - - if ('userIdentifierKey' in props && props.userIdentifierKey != null) { - throw new InvalidSeamQueryProviderProps( - 'The userIdentifierKey prop cannot be used with the consoleSessionToken prop.' - ) - } - - return true -} - -class InvalidSeamQueryProviderProps extends Error { - constructor(message: string) { - super(`SeamQueryProvider received invalid props: ${message}`) - this.name = this.constructor.name - } -} diff --git a/src/lib/seam/access-codes/use-access-code.ts b/src/lib/seam/access-codes/use-access-code.ts index b1ee269ce..d4f8c68fb 100644 --- a/src/lib/seam/access-codes/use-access-code.ts +++ b/src/lib/seam/access-codes/use-access-code.ts @@ -2,10 +2,10 @@ import type { AccessCodesGetParams, SeamHttpApiError, } from '@seamapi/http/connect' +import { useSeamClient } from '@seamapi/react-query' import type { AccessCode } from '@seamapi/types/connect' import { useQuery } from '@tanstack/react-query' -import { useSeamClient } from 'lib/seam/use-seam-client.js' import type { UseSeamQueryResultLegacy } from 'lib/seam/use-seam-query-result.js' export type UseAccessCodeParams = AccessCodesGetParams diff --git a/src/lib/seam/access-codes/use-access-codes.ts b/src/lib/seam/access-codes/use-access-codes.ts index 8eafc2d6b..68ae7b6f3 100644 --- a/src/lib/seam/access-codes/use-access-codes.ts +++ b/src/lib/seam/access-codes/use-access-codes.ts @@ -2,10 +2,10 @@ import type { AccessCodesListParams, SeamHttpApiError, } from '@seamapi/http/connect' +import { useSeamClient } from '@seamapi/react-query' import type { AccessCode } from '@seamapi/types/connect' import { useQuery, useQueryClient } from '@tanstack/react-query' -import { useSeamClient } from 'lib/seam/use-seam-client.js' import type { UseSeamQueryResultLegacy } from 'lib/seam/use-seam-query-result.js' export type UseAccessCodesParams = AccessCodesListParams diff --git a/src/lib/seam/access-codes/use-create-access-code.ts b/src/lib/seam/access-codes/use-create-access-code.ts index e79d944ea..ff8634082 100644 --- a/src/lib/seam/access-codes/use-create-access-code.ts +++ b/src/lib/seam/access-codes/use-create-access-code.ts @@ -1,9 +1,8 @@ -import { useQueryClient } from '@tanstack/react-query' - import { useSeamMutation, type UseSeamMutationResult, -} from '../use-seam-mutation.js' +} from '@seamapi/react-query' +import { useQueryClient } from '@tanstack/react-query' export function useCreateAccessCode(): UseSeamMutationResult<'/access_codes/create'> { const queryClient = useQueryClient() diff --git a/src/lib/seam/access-codes/use-delete-access-code.ts b/src/lib/seam/access-codes/use-delete-access-code.ts index d9feaee3d..8502c7657 100644 --- a/src/lib/seam/access-codes/use-delete-access-code.ts +++ b/src/lib/seam/access-codes/use-delete-access-code.ts @@ -2,6 +2,7 @@ import type { AccessCodesDeleteParams, SeamHttpApiError, } from '@seamapi/http/connect' +import { NullSeamClientError, useSeamClient } from '@seamapi/react-query' import type { AccessCode } from '@seamapi/types/connect' import { useMutation, @@ -9,8 +10,6 @@ import { useQueryClient, } from '@tanstack/react-query' -import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js' - export type UseDeleteAccessCodeParams = never export type UseDeleteAccessCodeData = undefined diff --git a/src/lib/seam/access-codes/use-generate-access-code-code.ts b/src/lib/seam/access-codes/use-generate-access-code-code.ts index 8ad7f5bce..ad6740126 100644 --- a/src/lib/seam/access-codes/use-generate-access-code-code.ts +++ b/src/lib/seam/access-codes/use-generate-access-code-code.ts @@ -2,10 +2,9 @@ import type { AccessCodesGenerateCodeParams, SeamHttpApiError, } from '@seamapi/http/connect' +import { NullSeamClientError, useSeamClient } from '@seamapi/react-query' import { useMutation, type UseMutationResult } from '@tanstack/react-query' -import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js' - export type UseGenerateAccessCodeCodeParams = never export type UseGenerateAccessCodeCodeData = string diff --git a/src/lib/seam/access-codes/use-update-access-code.ts b/src/lib/seam/access-codes/use-update-access-code.ts index 4dbb2e270..9a51a5309 100644 --- a/src/lib/seam/access-codes/use-update-access-code.ts +++ b/src/lib/seam/access-codes/use-update-access-code.ts @@ -2,6 +2,7 @@ import type { AccessCodesUpdateBody, SeamHttpApiError, } from '@seamapi/http/connect' +import { NullSeamClientError, useSeamClient } from '@seamapi/react-query' import type { AccessCode } from '@seamapi/types/connect' import { useMutation, @@ -9,8 +10,6 @@ import { useQueryClient, } from '@tanstack/react-query' -import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js' - export type UseUpdateAccessCodeParams = never export type UseUpdateAccessCodeData = undefined diff --git a/src/lib/seam/client-sessions/use-client-session.ts b/src/lib/seam/client-sessions/use-client-session.ts index 107c7168b..2b6d42751 100644 --- a/src/lib/seam/client-sessions/use-client-session.ts +++ b/src/lib/seam/client-sessions/use-client-session.ts @@ -1,8 +1,8 @@ import type { SeamHttpApiError } from '@seamapi/http/connect' +import { useSeamClient } from '@seamapi/react-query' import type { ClientSession } from '@seamapi/types/connect' import { useQuery } from '@tanstack/react-query' -import { useSeamClient } from 'lib/seam/use-seam-client.js' import type { UseSeamQueryResultLegacy } from 'lib/seam/use-seam-query-result.js' export type UseClientSessionParams = never diff --git a/src/lib/seam/components/SupportedDeviceTable/use-device-model.ts b/src/lib/seam/components/SupportedDeviceTable/use-device-model.ts index ef150e7e4..928fcb7bc 100644 --- a/src/lib/seam/components/SupportedDeviceTable/use-device-model.ts +++ b/src/lib/seam/components/SupportedDeviceTable/use-device-model.ts @@ -1,4 +1,5 @@ import type { SeamHttpApiError } from '@seamapi/http/connect' +import { useSeamClient } from '@seamapi/react-query' import type { DeviceModel, RouteRequestParams, @@ -6,7 +7,6 @@ import type { } from '@seamapi/types/devicedb' import { useQuery } from '@tanstack/react-query' -import { useSeamClient } from 'lib/seam/use-seam-client.js' import type { UseSeamQueryResultLegacy } from 'lib/seam/use-seam-query-result.js' export type UseDeviceModelParams = DeviceModelsGetParams diff --git a/src/lib/seam/components/SupportedDeviceTable/use-device-models.ts b/src/lib/seam/components/SupportedDeviceTable/use-device-models.ts index e6e3caa98..03d9fea45 100644 --- a/src/lib/seam/components/SupportedDeviceTable/use-device-models.ts +++ b/src/lib/seam/components/SupportedDeviceTable/use-device-models.ts @@ -1,4 +1,5 @@ import type { SeamHttpApiError } from '@seamapi/http/connect' +import { useSeamClient } from '@seamapi/react-query' import type { DeviceModel, RouteRequestParams, @@ -6,7 +7,6 @@ import type { } from '@seamapi/types/devicedb' import { useQuery, useQueryClient } from '@tanstack/react-query' -import { useSeamClient } from 'lib/seam/use-seam-client.js' import type { UseSeamQueryResultLegacy } from 'lib/seam/use-seam-query-result.js' export type UseDeviceModelsParams = DeviceModelsListParams diff --git a/src/lib/seam/components/SupportedDeviceTable/use-manufacturer.ts b/src/lib/seam/components/SupportedDeviceTable/use-manufacturer.ts index b4751cfde..3fe0ec4b4 100644 --- a/src/lib/seam/components/SupportedDeviceTable/use-manufacturer.ts +++ b/src/lib/seam/components/SupportedDeviceTable/use-manufacturer.ts @@ -1,4 +1,5 @@ import type { SeamHttpApiError } from '@seamapi/http/connect' +import { useSeamClient } from '@seamapi/react-query' import type { Manufacturer, RouteRequestParams, @@ -6,7 +7,6 @@ import type { } from '@seamapi/types/devicedb' import { useQuery } from '@tanstack/react-query' -import { useSeamClient } from 'lib/seam/use-seam-client.js' import type { UseSeamQueryResultLegacy } from 'lib/seam/use-seam-query-result.js' export type UseManufacturerParams = ManufacturersGetParams diff --git a/src/lib/seam/components/SupportedDeviceTable/use-manufacturers.ts b/src/lib/seam/components/SupportedDeviceTable/use-manufacturers.ts index 18df1027e..21251fd44 100644 --- a/src/lib/seam/components/SupportedDeviceTable/use-manufacturers.ts +++ b/src/lib/seam/components/SupportedDeviceTable/use-manufacturers.ts @@ -1,4 +1,5 @@ import type { SeamHttpApiError } from '@seamapi/http/connect' +import { useSeamClient } from '@seamapi/react-query' import type { Manufacturer, RouteRequestParams, @@ -6,7 +7,6 @@ import type { } from '@seamapi/types/devicedb' import { useQuery, useQueryClient } from '@tanstack/react-query' -import { useSeamClient } from 'lib/seam/use-seam-client.js' import type { UseSeamQueryResultLegacy } from 'lib/seam/use-seam-query-result.js' export type UseManufacturersParams = ManufacturersListParams diff --git a/src/lib/seam/connect-webviews/use-create-connect-webview.ts b/src/lib/seam/connect-webviews/use-create-connect-webview.ts index f4ee22101..58e7e7130 100644 --- a/src/lib/seam/connect-webviews/use-create-connect-webview.ts +++ b/src/lib/seam/connect-webviews/use-create-connect-webview.ts @@ -2,11 +2,11 @@ import type { ConnectWebviewsCreateBody, SeamHttpApiError, } from '@seamapi/http/connect' +import { NullSeamClientError, useSeamClient } from '@seamapi/react-query' import type { ConnectWebview } from '@seamapi/types/connect' import { useMutation, type UseMutationResult } from '@tanstack/react-query' import { useClientSession } from 'lib/seam/client-sessions/use-client-session.js' -import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js' export interface UseCreateConnectWebviewParams { willNavigateToWebview?: boolean diff --git a/src/lib/seam/connected-accounts/use-connected-account.ts b/src/lib/seam/connected-accounts/use-connected-account.ts index b617bb2de..3a7bd7041 100644 --- a/src/lib/seam/connected-accounts/use-connected-account.ts +++ b/src/lib/seam/connected-accounts/use-connected-account.ts @@ -2,10 +2,10 @@ import type { ConnectedAccountsGetParams, SeamHttpApiError, } from '@seamapi/http/connect' +import { useSeamClient } from '@seamapi/react-query' import type { ConnectedAccount } from '@seamapi/types/connect' import { useQuery } from '@tanstack/react-query' -import { useSeamClient } from 'lib/seam/use-seam-client.js' import type { UseSeamQueryResultLegacy } from 'lib/seam/use-seam-query-result.js' export type UseConnectedAccountParams = ConnectedAccountsGetParams diff --git a/src/lib/seam/devices/use-device-providers.ts b/src/lib/seam/devices/use-device-providers.ts index 685005f30..9e0a694a2 100644 --- a/src/lib/seam/devices/use-device-providers.ts +++ b/src/lib/seam/devices/use-device-providers.ts @@ -2,10 +2,10 @@ import type { DevicesListDeviceProvidersParams, SeamHttpApiError, } from '@seamapi/http/connect' +import { useSeamClient } from '@seamapi/react-query' import type { DeviceProvider } from '@seamapi/types/connect' import { useQuery } from '@tanstack/react-query' -import { useSeamClient } from 'lib/seam/use-seam-client.js' import type { UseSeamQueryResultLegacy } from 'lib/seam/use-seam-query-result.js' export type UseDeviceProvidersParams = DevicesListDeviceProvidersParams diff --git a/src/lib/seam/devices/use-device.ts b/src/lib/seam/devices/use-device.ts index 70ac48307..e5652c2ee 100644 --- a/src/lib/seam/devices/use-device.ts +++ b/src/lib/seam/devices/use-device.ts @@ -1,8 +1,8 @@ import type { DevicesGetParams, SeamHttpApiError } from '@seamapi/http/connect' +import { useSeamClient } from '@seamapi/react-query' import type { Device } from '@seamapi/types/connect' import { useQuery } from '@tanstack/react-query' -import { useSeamClient } from 'lib/seam/use-seam-client.js' import type { UseSeamQueryResultLegacy } from 'lib/seam/use-seam-query-result.js' export type UseDeviceParams = DevicesGetParams diff --git a/src/lib/seam/devices/use-devices.ts b/src/lib/seam/devices/use-devices.ts index 3392678f6..7f9d828e5 100644 --- a/src/lib/seam/devices/use-devices.ts +++ b/src/lib/seam/devices/use-devices.ts @@ -1,8 +1,8 @@ import type { DevicesListParams, SeamHttpApiError } from '@seamapi/http/connect' +import { useSeamClient } from '@seamapi/react-query' import type { Device } from '@seamapi/types/connect' import { useQuery, useQueryClient } from '@tanstack/react-query' -import { useSeamClient } from 'lib/seam/use-seam-client.js' import type { UseSeamQueryResultLegacy } from 'lib/seam/use-seam-query-result.js' export type UseDevicesParams = DevicesListParams diff --git a/src/lib/seam/devices/use-update-device-name.ts b/src/lib/seam/devices/use-update-device-name.ts index 8c7d03475..e78fe9a40 100644 --- a/src/lib/seam/devices/use-update-device-name.ts +++ b/src/lib/seam/devices/use-update-device-name.ts @@ -3,6 +3,7 @@ import type { DevicesUpdateBody, SeamHttpApiError, } from '@seamapi/http/connect' +import { NullSeamClientError, useSeamClient } from '@seamapi/react-query' import type { Device } from '@seamapi/types/connect' import { useMutation, @@ -10,8 +11,6 @@ import { useQueryClient, } from '@tanstack/react-query' -import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js' - export type UseUpdateDeviceNameParams = never export type UseUpdateDeviceNameData = undefined diff --git a/src/lib/seam/events/use-events.ts b/src/lib/seam/events/use-events.ts index ed89b3b0a..f2a573b3c 100644 --- a/src/lib/seam/events/use-events.ts +++ b/src/lib/seam/events/use-events.ts @@ -1,8 +1,8 @@ import type { EventsListParams, SeamHttpApiError } from '@seamapi/http/connect' +import { useSeamClient } from '@seamapi/react-query' import type { SeamEvent } from '@seamapi/types/connect' import { useQuery, useQueryClient } from '@tanstack/react-query' -import { useSeamClient } from 'lib/seam/use-seam-client.js' import type { UseSeamQueryResultLegacy } from 'lib/seam/use-seam-query-result.js' export type UseEventsParams = EventsListParams diff --git a/src/lib/seam/index.ts b/src/lib/seam/index.ts index 8eab32f0c..777551aca 100644 --- a/src/lib/seam/index.ts +++ b/src/lib/seam/index.ts @@ -11,10 +11,4 @@ export * from './devices/use-device.js' export * from './devices/use-device-providers.js' export * from './devices/use-devices.js' export * from './SeamProvider.js' -export * from './use-seam-client.js' -export * from './use-seam-infinite-query.js' -export * from './use-seam-mutation.js' -export * from './use-seam-mutation-without-workspace.js' -export * from './use-seam-query.js' export * from './use-seam-query-result.js' -export * from './use-seam-query-without-workspace.js' diff --git a/src/lib/seam/locks/use-toggle-lock.ts b/src/lib/seam/locks/use-toggle-lock.ts index 8c4a87b15..1d38f375c 100644 --- a/src/lib/seam/locks/use-toggle-lock.ts +++ b/src/lib/seam/locks/use-toggle-lock.ts @@ -3,6 +3,7 @@ import type { SeamActionAttemptTimeoutError, SeamHttpApiError, } from '@seamapi/http/connect' +import { NullSeamClientError, useSeamClient } from '@seamapi/react-query' import type { ActionAttempt, Device } from '@seamapi/types/connect' import { useMutation, @@ -10,8 +11,6 @@ import { useQueryClient, } from '@tanstack/react-query' -import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js' - export type UseToggleLockData = undefined export type UseToggleLockMutationVariables = Pick & { diff --git a/src/lib/seam/noise-sensors/use-noise-thresholds.ts b/src/lib/seam/noise-sensors/use-noise-thresholds.ts index e93fa4247..3110683c3 100644 --- a/src/lib/seam/noise-sensors/use-noise-thresholds.ts +++ b/src/lib/seam/noise-sensors/use-noise-thresholds.ts @@ -2,10 +2,10 @@ import type { NoiseSensorsNoiseThresholdsListParams, SeamHttpApiError, } from '@seamapi/http/connect' +import { useSeamClient } from '@seamapi/react-query' import type { NoiseThreshold } from '@seamapi/types/connect' import { useQuery, useQueryClient } from '@tanstack/react-query' -import { useSeamClient } from 'lib/seam/use-seam-client.js' import type { UseSeamQueryResultLegacy } from 'lib/seam/use-seam-query-result.js' export type UseNoiseThresholdsParams = NoiseSensorsNoiseThresholdsListParams diff --git a/src/lib/seam/thermostats/use-cool-thermostat.ts b/src/lib/seam/thermostats/use-cool-thermostat.ts index 6c196d5d6..21bf97c6c 100644 --- a/src/lib/seam/thermostats/use-cool-thermostat.ts +++ b/src/lib/seam/thermostats/use-cool-thermostat.ts @@ -4,6 +4,7 @@ import type { SeamHttpApiError, ThermostatsCoolBody, } from '@seamapi/http/connect' +import { NullSeamClientError, useSeamClient } from '@seamapi/react-query' import type { ActionAttempt, Device } from '@seamapi/types/connect' import { useMutation, @@ -15,7 +16,6 @@ import { getCoolingSetPointCelsius, getCoolingSetPointFahrenheit, } from 'lib/seam/thermostats/unit-conversion.js' -import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js' export type UseCoolThermostatParams = never diff --git a/src/lib/seam/thermostats/use-create-thermostat-climate-preset.ts b/src/lib/seam/thermostats/use-create-thermostat-climate-preset.ts index 12600dfd7..2277ba229 100644 --- a/src/lib/seam/thermostats/use-create-thermostat-climate-preset.ts +++ b/src/lib/seam/thermostats/use-create-thermostat-climate-preset.ts @@ -2,6 +2,7 @@ import type { SeamHttpApiError, ThermostatsCreateClimatePresetBody, } from '@seamapi/http/connect' +import { NullSeamClientError, useSeamClient } from '@seamapi/react-query' import { useMutation, type UseMutationResult, @@ -13,7 +14,6 @@ import type { ThermostatDevice, } from 'lib/seam/thermostats/thermostat-device.js' import { fahrenheitToCelsius } from 'lib/seam/thermostats/unit-conversion.js' -import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js' export type UseCreateThermostatClimatePresetParams = never export type UseCreateThermostatClimatePresetData = undefined diff --git a/src/lib/seam/thermostats/use-delete-thermostat-climate-preset.ts b/src/lib/seam/thermostats/use-delete-thermostat-climate-preset.ts index 3af8315e1..a7c89bd3e 100644 --- a/src/lib/seam/thermostats/use-delete-thermostat-climate-preset.ts +++ b/src/lib/seam/thermostats/use-delete-thermostat-climate-preset.ts @@ -2,6 +2,7 @@ import type { SeamHttpApiError, ThermostatsDeleteClimatePresetParams, } from '@seamapi/http/connect' +import { NullSeamClientError, useSeamClient } from '@seamapi/react-query' import { useMutation, type UseMutationResult, @@ -9,7 +10,6 @@ import { } from '@tanstack/react-query' import type { ThermostatDevice } from 'lib/seam/thermostats/thermostat-device.js' -import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js' export type UseDeleteThermostatClimatePresetParams = never diff --git a/src/lib/seam/thermostats/use-heat-cool-thermostat.ts b/src/lib/seam/thermostats/use-heat-cool-thermostat.ts index 2c9cb6591..a9e9533fd 100644 --- a/src/lib/seam/thermostats/use-heat-cool-thermostat.ts +++ b/src/lib/seam/thermostats/use-heat-cool-thermostat.ts @@ -4,6 +4,7 @@ import type { SeamHttpApiError, ThermostatsHeatCoolBody, } from '@seamapi/http/connect' +import { NullSeamClientError, useSeamClient } from '@seamapi/react-query' import type { ActionAttempt, Device } from '@seamapi/types/connect' import { useMutation, @@ -17,7 +18,6 @@ import { getHeatingSetPointCelsius, getHeatingSetPointFahrenheit, } from 'lib/seam/thermostats/unit-conversion.js' -import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js' export type UseHeatCoolThermostatParams = never diff --git a/src/lib/seam/thermostats/use-heat-thermostat.ts b/src/lib/seam/thermostats/use-heat-thermostat.ts index 8e1fccef9..77648aea0 100644 --- a/src/lib/seam/thermostats/use-heat-thermostat.ts +++ b/src/lib/seam/thermostats/use-heat-thermostat.ts @@ -4,6 +4,7 @@ import type { SeamHttpApiError, ThermostatsHeatBody, } from '@seamapi/http/connect' +import { NullSeamClientError, useSeamClient } from '@seamapi/react-query' import type { ActionAttempt, Device } from '@seamapi/types/connect' import { useMutation, @@ -15,7 +16,6 @@ import { getHeatingSetPointCelsius, getHeatingSetPointFahrenheit, } from 'lib/seam/thermostats/unit-conversion.js' -import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js' export type UseHeatThermostatParams = never diff --git a/src/lib/seam/thermostats/use-set-thermostat-fan-mode.ts b/src/lib/seam/thermostats/use-set-thermostat-fan-mode.ts index 7e3c70d29..8138485cc 100644 --- a/src/lib/seam/thermostats/use-set-thermostat-fan-mode.ts +++ b/src/lib/seam/thermostats/use-set-thermostat-fan-mode.ts @@ -4,6 +4,7 @@ import type { SeamHttpApiError, ThermostatsSetFanModeBody, } from '@seamapi/http/connect' +import { NullSeamClientError, useSeamClient } from '@seamapi/react-query' import type { ActionAttempt, Device } from '@seamapi/types/connect' import { useMutation, @@ -11,8 +12,6 @@ import { useQueryClient, } from '@tanstack/react-query' -import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js' - export type UseSetThermostatFanModeParams = never export type UseSetThermostatFanModeData = undefined diff --git a/src/lib/seam/thermostats/use-set-thermostat-off.ts b/src/lib/seam/thermostats/use-set-thermostat-off.ts index 7a36f7d9b..1343370b0 100644 --- a/src/lib/seam/thermostats/use-set-thermostat-off.ts +++ b/src/lib/seam/thermostats/use-set-thermostat-off.ts @@ -4,6 +4,7 @@ import type { SeamHttpApiError, ThermostatsOffBody, } from '@seamapi/http/connect' +import { NullSeamClientError, useSeamClient } from '@seamapi/react-query' import type { ActionAttempt, Device } from '@seamapi/types/connect' import { useMutation, @@ -11,8 +12,6 @@ import { useQueryClient, } from '@tanstack/react-query' -import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js' - export type UseSetThermostatOffParams = never export type UseSetThermostatOffData = undefined diff --git a/src/lib/seam/thermostats/use-update-thermostat-climate-preset.ts b/src/lib/seam/thermostats/use-update-thermostat-climate-preset.ts index e2802064c..b28c76471 100644 --- a/src/lib/seam/thermostats/use-update-thermostat-climate-preset.ts +++ b/src/lib/seam/thermostats/use-update-thermostat-climate-preset.ts @@ -2,6 +2,7 @@ import type { SeamHttpApiError, ThermostatsUpdateClimatePresetBody, } from '@seamapi/http/connect' +import { NullSeamClientError, useSeamClient } from '@seamapi/react-query' import { useMutation, type UseMutationResult, @@ -13,7 +14,6 @@ import type { ThermostatDevice, } from 'lib/seam/thermostats/thermostat-device.js' import { fahrenheitToCelsius } from 'lib/seam/thermostats/unit-conversion.js' -import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js' export type UseUpdateThermostatClimatePresetParams = never export type UseUpdateThermostatClimatePresetData = undefined diff --git a/src/lib/seam/use-seam-client.ts b/src/lib/seam/use-seam-client.ts deleted file mode 100644 index 697bb9dd5..000000000 --- a/src/lib/seam/use-seam-client.ts +++ /dev/null @@ -1,225 +0,0 @@ -import { - SeamHttp, - SeamHttpEndpoints, - SeamHttpEndpointsWithoutWorkspace, - SeamHttpWithoutWorkspace, -} from '@seamapi/http/connect' -import { useQuery } from '@tanstack/react-query' -import { useEffect } from 'react' -import { v4 as uuidv4 } from 'uuid' - -import { useSeamQueryContext } from './SeamQueryProvider.js' - -export function useSeamClient(): { - client: SeamHttp | null - endpointClient: SeamHttpEndpoints | null - clientWithoutWorkspace: SeamHttpWithoutWorkspace | null - endpointClientWithoutWorkspace: SeamHttpEndpointsWithoutWorkspace | null - queryKeyPrefixes: string[] - isPending: boolean - isError: boolean - error: unknown -} { - const { - client, - clientOptions, - publishableKey, - clientSessionToken, - consoleSessionToken, - workspaceId, - queryKeyPrefix, - ...context - } = useSeamQueryContext() - const userIdentifierKey = useUserIdentifierKeyOrFingerprint( - clientSessionToken != null ? '' : context.userIdentifierKey - ) - - const { isPending, isError, error, data } = useQuery<{ - client: SeamHttp | null - endpointClient: SeamHttpEndpoints | null - clientWithoutWorkspace: SeamHttpWithoutWorkspace | null - endpointClientWithoutWorkspace: SeamHttpEndpointsWithoutWorkspace | null - }>({ - queryKey: [ - ...getQueryKeyPrefixes({ queryKeyPrefix }), - 'client', - { - client, - clientOptions, - publishableKey, - userIdentifierKey, - clientSessionToken, - }, - ], - queryFn: async () => { - if (client != null) - return { - client, - endpointClient: SeamHttpEndpoints.fromClient(client.client), - clientWithoutWorkspace: null, - endpointClientWithoutWorkspace: null, - } - - if (clientSessionToken != null) { - const seam = SeamHttp.fromClientSessionToken( - clientSessionToken, - clientOptions - ) - - return { - client: seam, - endpointClient: SeamHttpEndpoints.fromClient(seam.client), - clientWithoutWorkspace: null, - endpointClientWithoutWorkspace: null, - } - } - - if (publishableKey != null) { - const seam = await SeamHttp.fromPublishableKey( - publishableKey, - userIdentifierKey, - clientOptions - ) - - return { - client: seam, - endpointClient: SeamHttpEndpoints.fromClient(seam.client), - clientWithoutWorkspace: null, - endpointClientWithoutWorkspace: null, - } - } - - if (consoleSessionToken != null) { - const clientWithoutWorkspace = - SeamHttpWithoutWorkspace.fromConsoleSessionToken(consoleSessionToken) - - const endpointClientWithoutWorkspace = - SeamHttpEndpointsWithoutWorkspace.fromClient( - clientWithoutWorkspace.client - ) - - if (workspaceId == null) { - return { - client: null, - endpointClient: null, - clientWithoutWorkspace, - endpointClientWithoutWorkspace, - } - } - - const seam = SeamHttp.fromConsoleSessionToken( - consoleSessionToken, - workspaceId, - clientOptions - ) - - return { - client: seam, - endpointClient: SeamHttpEndpoints.fromClient(seam.client), - clientWithoutWorkspace, - endpointClientWithoutWorkspace, - } - } - - throw new Error( - 'Missing either a client, publishableKey, clientSessionToken, or consoleSessionToken.' - ) - }, - }) - - return { - client: data?.client ?? null, - endpointClient: data?.endpointClient ?? null, - clientWithoutWorkspace: data?.clientWithoutWorkspace ?? null, - endpointClientWithoutWorkspace: - data?.endpointClientWithoutWorkspace ?? null, - queryKeyPrefixes: getQueryKeyPrefixes({ - queryKeyPrefix, - userIdentifierKey, - publishableKey, - clientSessionToken, - consoleSessionToken, - workspaceId, - }), - isPending, - isError, - error, - } -} - -export class NullSeamClientError extends Error { - constructor() { - super( - [ - 'Attempted to use a null Seam client.', - 'Either a hook using useSeamClient was called outside of a SeamProvider or SeamQueryProvider,', - 'or there was an error when creating the Seam client in useSeamClient,', - 'or useSeamClient is still loading the client.', - ].join(' ') - ) - this.name = this.constructor.name - Error.captureStackTrace(this, this.constructor) - } -} - -function useUserIdentifierKeyOrFingerprint( - userIdentifierKey: string | undefined -): string { - useEffect(() => { - if (userIdentifierKey != null) return - // eslint-disable-next-line no-console - console.warn(`Using an automatically generated fingerprint for the Seam userIdentifierKey! -The user interface will show warnings when using a fingerprint. -This is not recommended because the client session is now bound to this machine and is effectively ephemeral.`) - }, [userIdentifierKey]) - - if (userIdentifierKey != null) { - return userIdentifierKey - } - - const fingerprint = - globalThis.localStorage?.getItem('seam_user_fingerprint') ?? - `fingerprint_${uuidv4()}` - - globalThis.localStorage?.setItem('seam_user_fingerprint', fingerprint) - - return fingerprint -} - -const getQueryKeyPrefixes = ({ - queryKeyPrefix, - userIdentifierKey, - publishableKey, - clientSessionToken, - consoleSessionToken, - workspaceId, -}: { - queryKeyPrefix: string | undefined - userIdentifierKey?: string - publishableKey?: string | undefined - clientSessionToken?: string | undefined - consoleSessionToken?: string | undefined - workspaceId?: string | undefined -}): string[] => { - const seamPrefix = 'seam' - - if (queryKeyPrefix != null) return [seamPrefix, queryKeyPrefix] - - if (clientSessionToken != null) { - return [seamPrefix, clientSessionToken] - } - - if (publishableKey != null && userIdentifierKey != null) { - return [seamPrefix, publishableKey, userIdentifierKey] - } - - if (consoleSessionToken != null) { - if (workspaceId != null) { - return [seamPrefix, consoleSessionToken, workspaceId] - } - - return [seamPrefix, consoleSessionToken, 'without_workspace'] - } - - return [seamPrefix] -} diff --git a/src/lib/seam/use-seam-infinite-query.ts b/src/lib/seam/use-seam-infinite-query.ts deleted file mode 100644 index 4b649cfeb..000000000 --- a/src/lib/seam/use-seam-infinite-query.ts +++ /dev/null @@ -1,103 +0,0 @@ -import type { - SeamActionAttemptFailedError, - SeamActionAttemptTimeoutError, - SeamHttpApiError, - SeamHttpEndpointPaginatedQueryPaths, - SeamHttpEndpoints, - SeamHttpInvalidInputError, - SeamHttpRequest, - SeamPageCursor, -} from '@seamapi/http/connect' -import type { ActionAttempt } from '@seamapi/types/connect' -import { - type QueryKey, - useInfiniteQuery, - type UseInfiniteQueryOptions, - type UseInfiniteQueryResult, -} from '@tanstack/react-query' - -import { useSeamClient } from 'lib/seam/use-seam-client.js' - -export type UseSeamInfiniteQueryParameters< - T extends SeamHttpEndpointPaginatedQueryPaths, -> = Parameters[0] - -export type UseSeamInfiniteQueryResult< - T extends SeamHttpEndpointPaginatedQueryPaths, -> = UseInfiniteQueryResult, QueryError> - -export function useSeamInfiniteQuery< - T extends SeamHttpEndpointPaginatedQueryPaths, ->( - endpointPath: T, - parameters: UseSeamInfiniteQueryParameters = {}, - options: Parameters[1] & - QueryOptions, QueryError> = {} -): UseSeamInfiniteQueryResult & { queryKey: QueryKey } { - const { endpointClient: client, queryKeyPrefixes } = useSeamClient() - - if ('page_cursor' in (parameters ?? {})) { - throw new Error('Cannot use page_cursor with useSeamInfiniteQuery') - } - - const queryKey = [ - ...queryKeyPrefixes, - ...endpointPath.split('/').filter((v) => v !== ''), - parameters ?? {}, - ] - const result = useInfiniteQuery({ - enabled: client != null, - ...options, - queryKey, - initialPageParam: null, - getNextPageParam: (lastPage) => lastPage.nextPageCursor, - queryFn: async ({ pageParam }) => { - if (client == null) - return { - data: [] as Awaited>, - nextPageCursor: null, - } - // Using @ts-expect-error over any is preferred, but not possible here because TypeScript will run out of memory. - // Type assertion is needed here for performance reasons. The types are correct at runtime. - const endpoint = client[endpointPath] as (...args: any) => any - const request = endpoint(parameters, options) - const pages = client.createPaginator(request as SeamHttpRequest) - if (pageParam == null) { - const [data, { nextPageCursor }] = await pages.firstPage() - return { - data: data as Awaited>, - nextPageCursor, - } - } - // Type assertion is needed for pageParam since the Seam API expects a branded PageCursor type. - const [data, { nextPageCursor }] = await pages.nextPage( - pageParam as SeamPageCursor - ) - return { - data: data as Awaited>, - nextPageCursor, - } - }, - }) - return { ...result, queryKey } -} - -interface QueryData { - data: Awaited> - nextPageCursor: SeamPageCursor | null -} - -type QueryError = - | Error - | SeamHttpApiError - | SeamHttpInvalidInputError - | (QueryData['data'] extends ActionAttempt - ? - | SeamActionAttemptFailedError['data']> - | SeamActionAttemptTimeoutError['data']> - : never) - -type QueryOptions = Omit< - UseInfiniteQueryOptions, - 'queryKey' | 'queryFn' | 'initialPageParam' | 'getNextPageParam' -> diff --git a/src/lib/seam/use-seam-mutation-without-workspace.ts b/src/lib/seam/use-seam-mutation-without-workspace.ts deleted file mode 100644 index b1fe467a0..000000000 --- a/src/lib/seam/use-seam-mutation-without-workspace.ts +++ /dev/null @@ -1,56 +0,0 @@ -import type { - SeamHttpApiError, - SeamHttpEndpointsWithoutWorkspace, - SeamHttpEndpointWithoutWorkspaceMutationPaths, - SeamHttpInvalidInputError, -} from '@seamapi/http/connect' -import { - useMutation, - type UseMutationOptions, - type UseMutationResult, -} from '@tanstack/react-query' - -import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js' - -export type UseSeamMutationWithoutWorkspaceVariables< - T extends SeamHttpEndpointWithoutWorkspaceMutationPaths, -> = Parameters[0] - -export type UseSeamMutationWithoutWorkspaceResult< - T extends SeamHttpEndpointWithoutWorkspaceMutationPaths, -> = UseMutationResult< - MutationData, - MutationError, - UseSeamMutationWithoutWorkspaceVariables -> - -export function useSeamMutationWithoutWorkspace< - T extends SeamHttpEndpointWithoutWorkspaceMutationPaths, ->( - endpointPath: T, - options: Parameters[1] & - MutationOptions< - MutationData, - MutationError, - UseSeamMutationWithoutWorkspaceVariables - > = {} -): UseSeamMutationWithoutWorkspaceResult { - const { endpointClient: client } = useSeamClient() - return useMutation({ - ...options, - mutationFn: async (variables) => { - if (client === null) throw new NullSeamClientError() - // Using @ts-expect-error over any is preferred, but not possible here because TypeScript will run out of memory. - // Type assertion is needed here for performance reasons. The types are correct at runtime. - const endpoint = client[endpointPath] as (...args: any) => Promise - return await endpoint(variables, options) - }, - }) -} - -type MutationData = - Awaited> - -type MutationError = Error | SeamHttpApiError | SeamHttpInvalidInputError - -type MutationOptions = Omit, 'mutationFn'> diff --git a/src/lib/seam/use-seam-mutation.ts b/src/lib/seam/use-seam-mutation.ts deleted file mode 100644 index b54c789a2..000000000 --- a/src/lib/seam/use-seam-mutation.ts +++ /dev/null @@ -1,64 +0,0 @@ -import type { - SeamActionAttemptFailedError, - SeamActionAttemptTimeoutError, - SeamHttpApiError, - SeamHttpEndpointMutationPaths, - SeamHttpEndpoints, - SeamHttpInvalidInputError, -} from '@seamapi/http/connect' -import type { ActionAttempt } from '@seamapi/types/connect' -import { - useMutation, - type UseMutationOptions, - type UseMutationResult, -} from '@tanstack/react-query' - -import { NullSeamClientError, useSeamClient } from 'lib/seam/use-seam-client.js' - -export type UseSeamMutationVariables = - Parameters[0] - -export type UseSeamMutationResult = - UseMutationResult< - MutationData, - MutationError, - UseSeamMutationVariables - > - -export function useSeamMutation( - endpointPath: T, - options: Parameters[1] & - MutationOptions< - MutationData, - MutationError, - UseSeamMutationVariables - > = {} -): UseSeamMutationResult { - const { endpointClient: client } = useSeamClient() - return useMutation({ - ...options, - mutationFn: async (variables) => { - if (client === null) throw new NullSeamClientError() - // Using @ts-expect-error over any is preferred, but not possible here because TypeScript will run out of memory. - // Type assertion is needed here for performance reasons. The types are correct at runtime. - const endpoint = client[endpointPath] as (...args: any) => Promise - return await endpoint(variables, options) - }, - }) -} - -type MutationData = Awaited< - ReturnType -> - -type MutationError = - | Error - | SeamHttpApiError - | SeamHttpInvalidInputError - | (MutationData extends ActionAttempt - ? - | SeamActionAttemptFailedError> - | SeamActionAttemptTimeoutError> - : never) - -type MutationOptions = Omit, 'mutationFn'> diff --git a/src/lib/seam/use-seam-query-without-workspace.ts b/src/lib/seam/use-seam-query-without-workspace.ts deleted file mode 100644 index 79c9a1c9e..000000000 --- a/src/lib/seam/use-seam-query-without-workspace.ts +++ /dev/null @@ -1,59 +0,0 @@ -import type { - SeamHttpApiError, - SeamHttpEndpointsWithoutWorkspace, - SeamHttpEndpointWithoutWorkspaceQueryPaths, - SeamHttpInvalidInputError, -} from '@seamapi/http/connect' -import { - type QueryKey, - useQuery, - type UseQueryOptions, - type UseQueryResult, -} from '@tanstack/react-query' - -import { useSeamClient } from 'lib/seam/use-seam-client.js' - -export type UseSeamQueryWithoutWorkspaceParameters< - T extends SeamHttpEndpointWithoutWorkspaceQueryPaths, -> = Parameters[0] - -export type UseSeamQueryWithoutWorkspaceResult< - T extends SeamHttpEndpointWithoutWorkspaceQueryPaths, -> = UseQueryResult, QueryError> - -export function useSeamQueryWithoutWorkspace< - T extends SeamHttpEndpointWithoutWorkspaceQueryPaths, ->( - endpointPath: T, - parameters: UseSeamQueryWithoutWorkspaceParameters = {}, - options: Parameters[1] & - QueryOptions, QueryError> = {} -): UseSeamQueryWithoutWorkspaceResult & { queryKey: QueryKey } { - const { endpointClient: client, queryKeyPrefixes } = useSeamClient() - const queryKey = [ - ...queryKeyPrefixes, - ...endpointPath.split('/').filter((v) => v !== ''), - parameters ?? {}, - ] - const result = useQuery({ - enabled: client != null, - ...options, - queryKey, - queryFn: async () => { - if (client == null) return null - // Using @ts-expect-error over any is preferred, but not possible here because TypeScript will run out of memory. - // Type assertion is needed here for performance reasons. The types are correct at runtime. - const endpoint = client[endpointPath] as (...args: any) => Promise - return await endpoint(parameters, options) - }, - }) - return { ...result, queryKey } -} - -type QueryData = Awaited< - ReturnType -> - -type QueryError = Error | SeamHttpApiError | SeamHttpInvalidInputError - -type QueryOptions = Omit, 'queryKey' | 'queryFn'> diff --git a/src/lib/seam/use-seam-query.ts b/src/lib/seam/use-seam-query.ts deleted file mode 100644 index 12f10d5ca..000000000 --- a/src/lib/seam/use-seam-query.ts +++ /dev/null @@ -1,66 +0,0 @@ -import type { - SeamActionAttemptFailedError, - SeamActionAttemptTimeoutError, - SeamHttpApiError, - SeamHttpEndpointQueryPaths, - SeamHttpEndpoints, - SeamHttpInvalidInputError, -} from '@seamapi/http/connect' -import type { ActionAttempt } from '@seamapi/types/connect' -import { - type QueryKey, - useQuery, - type UseQueryOptions, - type UseQueryResult, -} from '@tanstack/react-query' - -import { useSeamClient } from 'lib/seam/use-seam-client.js' - -export type UseSeamQueryParameters = - Parameters[0] - -export type UseSeamQueryResult = - UseQueryResult, QueryError> - -export function useSeamQuery( - endpointPath: T, - parameters: UseSeamQueryParameters = {}, - options: Parameters[1] & - QueryOptions, SeamHttpApiError> = {} -): UseSeamQueryResult & { queryKey: QueryKey } { - const { endpointClient: client, queryKeyPrefixes } = useSeamClient() - const queryKey = [ - ...queryKeyPrefixes, - ...endpointPath.split('/').filter((v) => v !== ''), - parameters ?? {}, - ] - const result = useQuery({ - enabled: client != null, - ...options, - queryKey, - queryFn: async () => { - if (client == null) return null - // Using @ts-expect-error over any is preferred, but not possible here because TypeScript will run out of memory. - // Type assertion is needed here for performance reasons. The types are correct at runtime. - const endpoint = client[endpointPath] as (...args: any) => Promise - return await endpoint(parameters, options) - }, - }) - return { ...result, queryKey } -} - -type QueryData = Awaited< - ReturnType -> - -type QueryError = - | Error - | SeamHttpApiError - | SeamHttpInvalidInputError - | (QueryData extends ActionAttempt - ? - | SeamActionAttemptFailedError> - | SeamActionAttemptTimeoutError> - : never) - -type QueryOptions = Omit, 'queryKey' | 'queryFn'> diff --git a/src/lib/telemetry/hooks.ts b/src/lib/telemetry/hooks.ts index 7a0c403e7..059fb66dd 100644 --- a/src/lib/telemetry/hooks.ts +++ b/src/lib/telemetry/hooks.ts @@ -1,7 +1,7 @@ +import { useSeamQueryContext } from '@seamapi/react-query' import { useEffect, useLayoutEffect } from 'react' import { useClientSession } from 'lib/seam/client-sessions/use-client-session.js' -import { useSeamQueryContext } from 'lib/seam/SeamQueryProvider.js' import type { TelemetryClient } from './client.js' import { useTelemetryContext } from './TelemetryProvider.js'