mirror of
https://github.com/hoppscotch/hoppscotch.git
synced 2026-04-25 16:55:59 +03:00
[PR #4684] [MERGED] feat: platform independent core and the new desktop app #4900
Labels
No labels
CodeDay
a11y
browser limited
bug
bug fix
cli
core
critical
design
desktop
discussion
docker
documentation
duplicate
enterprise
feature
feature
fosshack
future
good first issue
hacktoberfest
help wanted
i18n
invalid
major
minor
need information
need testing
not applicable to hoppscotch
not reproducible
pull-request
question
refactor
resolved
sandbox
self-host
spam
stale
testmu
wip
wont fix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/hoppscotch#4900
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/hoppscotch/hoppscotch/pull/4684
Author: @CuriousCorrelation
Created: 1/21/2025
Status: ✅ Merged
Merged: 2/27/2025
Merged by: @AndrewBastin
Base:
next← Head:desktop/feat/crossover📝 Commits (10+)
df18e3dfeat(desktop): init1bfbe4afeat(desktop): external app download and setupa4ffd72feat(desktop): offload app load to plugin systemc5f3ca0perf(desktop): add rdbms facade and caching layer37657f2feat: parallelize signing, shared trust, lru cache7706527feat: webapp encoder + compressor + hasher server37b292dfeat(desktop): app autoupdate with hashed loaderf1f68d3feat(kernel): inithoppscotch-kernel2410e4cfeat(kernel):iocb0528dfeat(kernel):network📊 Changes
465 files changed (+53981 additions, -4017 deletions)
View changed files
📝
.dockerignore(+33 -0)📝
.env.example(+8 -1)➕
.envrc(+3 -0)📝
.gitignore(+10 -0)📝
aio-subpath-access.Caddyfile(+5 -0)📝
aio_run.mjs(+7 -0)➕
devenv.lock(+140 -0)➕
devenv.nix(+189 -0)📝
devenv.yaml(+0 -0)📝
docker-compose.yml(+91 -2)📝
packages/codemirror-lang-graphql/tsconfig.json(+1 -0)➖
packages/hoppscotch-agent/.envrc(+0 -3)📝
packages/hoppscotch-agent/package.json(+2 -0)📝
packages/hoppscotch-agent/src-tauri/Cargo.lock(+1063 -574)📝
packages/hoppscotch-agent/src-tauri/Cargo.toml(+6 -7)📝
packages/hoppscotch-agent/src-tauri/capabilities/default.json(+1 -0)➕
packages/hoppscotch-agent/src-tauri/src/command.rs(+40 -0)📝
packages/hoppscotch-agent/src-tauri/src/controller.rs(+271 -92)📝
packages/hoppscotch-agent/src-tauri/src/dialog.rs(+4 -4)📝
packages/hoppscotch-agent/src-tauri/src/error.rs(+14 -2)...and 80 more files
📄 Description
This PR introduces the ability for the Hoppscotch Desktop app to connect to any self-hosted instances and some other major improvements. It makes the core of the Hoppscotch app platform independent via the new Hoppscotch Kernel. It also implements a new relay architecture that adds support for several flows, bringing feature parity between the web app and the desktop app.
Closes the HFE-672 initiative
Changes
hoppscotch-common:InterceptorServiceor ratherKernelInterceptorServicenow use@hoppscotch-kernel/relayaxios@hoppscotch/plugin-relayRelayRequestand returnsRelayResponsewhere response body isUint8ArrayEach interceptor now has its own store
And native interceptor (native to the platform, different from "native" named interceptors) are initialized via the
InitializationService.PersistenceServiceto get settings fromlocalStoragePersistenceService;PersistenceService.store.tsfile that is called in theSettingspage which is then called inInterceptorServicePersistenceServicenow use@hoppscotch-kernel/storelocalStoragewithsuperjsonserializationtauri-apps/plugin-storewithserdeserializationPersistenceServicestorekernel module.getLocalConfigandsetLocalConfigare now async operations that can fail (previously they'd fail silently or throw)getLocalConfigandsetLocalConfigare now asynchronous, all of their call sites are converted to async function, some are moved toonMountto avoidSuspense.InspectorServicenow queries active interceptor to understand capabilitiescomposables/pickeralong withfunctional/domain-settingshandle interceptor settings, mainly related to how settings are transformed intoRelayRequest, a combination ofOmitandPick.app/KernelInterceptorhandles the settings page for the new interceptor servicessrc/kernelgetModule = <K extends keyof KernelAPI>(name: K): NonNullable<KernelAPI[K]>src/helpers/kernelcommon/authhandles transformingtype HoppAuth = HoppRESTRequest["auth"]intoRelayRequest["auth"]oauthservices, these are mainly for oauth rest/gqlcommon/contenthandles transformingHoppRESTReqBodyintoContentTypecontentfrom@hoppscotch/kernelas transformerrest/request&rest/responsehandle REST-specific transformationsgql/request&gql/responsehandle GraphQL-specific flowsrestandgqlare helpers that replace usage fromhelpers/graphql/connection.tsandhelpers/network.tsInterceptors and their domain settings
@hoppscotch-kernel/store(same reason why interceptors now use separate store)PersistenceServiceNative.vueimplements unified settings management,Settingspanel shows inheritance state of each optionRelayRequestformathoppscotch-desktop:Custom protocol handler at load level translates all web app resource requests
LruCacheand disk-based cache when memory pressure high or cold loadsCSPrules fromtauri.config.json, this is important especially on Windows. This also includes Headers likex-content-type-options=nosniffFileStoreabstractios which essentially is wrapper over platform-specific APIs (fs)Bundle verification works through multi-stage process where the
KeyManagerfetches Ed25519 keys from server, at<app_config>/key/BundleVerifiermakes sure integrity at three levels, Bundle-level signature verification first, per-fileblake3hash verification next, all done in parallel.VerifiedBundlemaintains post-verification state, files being accessible through verified content map, with priginal zip preserved for cache rebuildsWindow management differs per platform
NSWindowDelegatefor behaviors, better traffic light repositioning based on content, and vibrancy tied to web app themeDWMAPI calls for window frame customization, theme synchronization through messages, custom window procedure for titlebarNetworking:
RelayRequest, a transformation ofHoppRESTRequestrequest.rstransforms incoming requests to curl format, then sets up basic parameters (method, url, version)response.rstransforms curl responses back to Hopp format, it extracts status, headers and bodyhoppscotch-selfhost-web:webapp-server:New static server for serving built
hoppscotch-selfhost-webSigningKeyPairhandles key management, generation and storage viaed25519BundleManagerandBundleBuilderhandles bundling and packingAPI layer exposes three core endpoints:
hoppscotch-agent:<app_data_dir>/hoppscotch-agent-YYYY-MM-DD.log.POST /log-sinkaccepting Authorization bearer token and encrypted payloadhoppscotch-backend:hoppscotch-selfhost-web'splatform/authimplementation.AuthorizationheaderNote to reviewers
Simplest way to test out app server and desktop app would be as follows:
then
This will start up a webapp server (like mentioned in the web section above). This server serves selfhosted app (purely for testing purposes, for prod-like setup use
docker compose --profile default up --buildmore info later)Now if this is the first time running the app, do a full build via
but for any subsequent run, do this instead (much faster)
The difference being vendored vs purely selfhost shell, for all intents and purposes,
pnpm dev:fullis a safer bet and for build, when in doubtpnpm build:full.Remember, all the commands assumes you have
cargo(withrustupwithnightlytoolchainrustup default nightly) andpnpminstalled on your machine, otherwise for fully reproducible development environment, best way to setup all instances and app suite would be as follows:This will load a reproducible development environment (with docker powered by
colima), thenfollowed by
This will setup docker with minimal system requirements, finally the same instructions as before
and then in a different terminal instance this (if it's your first time running the app from scratch)
or this (if you've already built vendored app)
or for fully functional all service setup, try
See
docker-compose.ymlin monorepo root for more detailed information.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.