Skip to content

Commit e2e0ca5

Browse files
committed
refactor: migrate remaining .ts modules from runtime store to RuntimeClient
- Create `local-runtime-config.ts` with shared `LOCAL_HOST` and `LOCAL_INSTANCE_ID` constants for web-local - Migrate web-local load functions and layout to use constants instead of reading from the runtime store - Add `getJwt` parameter to `SSEFetchClient.start()`, removing its direct import of the runtime store - Thread `RuntimeClient` through `updateDevJWT` (dual-write bridge) - Decouple `local-service.ts` from runtime store via `setLocalServiceHost()` - Replace `Runtime` type import in `selectors.ts` with inline type - Rewrite `query-options.ts` to use `fetch` instead of `httpClient` - Rewrite `open-query.ts` to use `fetch` instead of `httpClient` - Rewrite `getFeatureFlags()` to use `fetch` instead of `httpClient` - Migrate `download-report.ts` to accept `host` via mutation data
1 parent 15ec565 commit e2e0ca5

20 files changed

Lines changed: 204 additions & 169 deletions

File tree

web-admin/src/features/projects/download-report.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
createQueryServiceExportReport,
55
type RpcStatus,
66
} from "@rilldata/web-common/runtime-client";
7-
import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
87
import {
98
createMutation,
109
type CreateMutationOptions,
@@ -17,6 +16,7 @@ export type DownloadReportRequest = {
1716
reportId: string;
1817
executionTime: string;
1918
originBaseUrl: string;
19+
host: string;
2020
};
2121

2222
export function createDownloadReportMutation<
@@ -48,7 +48,7 @@ export function createDownloadReportMutation<
4848
originBaseUrl: data.originBaseUrl,
4949
},
5050
});
51-
const downloadUrl = `${get(runtime).host}${exportResp.downloadUrlPath}`;
51+
const downloadUrl = `${data.host}${exportResp.downloadUrlPath}`;
5252
window.open(downloadUrl, "_self");
5353
};
5454

web-admin/src/features/projects/selectors.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import {
2020
useResourceV2,
2121
} from "@rilldata/web-common/features/entity-management/resource-selectors";
2222
import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient";
23-
import type { Runtime } from "@rilldata/web-common/runtime-client/runtime-store";
2423
import { derived, type Readable } from "svelte/store";
2524

2625
export function getProjectPermissions(orgName: string, projName: string) {
@@ -137,13 +136,16 @@ export async function fetchProjectDeploymentDetails(
137136
return {
138137
projectPermissions: projResp.projectPermissions,
139138
project: projResp.project,
140-
runtime: <Runtime>{
141-
host: projResp.deployment?.runtimeHost,
142-
instanceId: projResp.deployment?.runtimeInstanceId,
143-
jwt: {
144-
token: projResp.jwt,
145-
authContext: token ? "magic" : "user",
146-
},
139+
runtime: {
140+
host: projResp.deployment?.runtimeHost ?? "",
141+
instanceId: projResp.deployment?.runtimeInstanceId ?? "",
142+
jwt: projResp.jwt
143+
? {
144+
token: projResp.jwt,
145+
receivedAt: Date.now(),
146+
authContext: (token ? "magic" : "user") as string,
147+
}
148+
: undefined,
147149
},
148150
};
149151
}

web-admin/src/routes/[organization]/[project]/-/reports/[report]/export/+page.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
reportId,
2727
executionTime,
2828
originBaseUrl: window.location.origin,
29+
host: $runtime.host,
2930
},
3031
});
3132
}

web-common/src/features/chat/core/conversation.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ export class Conversation {
357357
await this.sseClient!.start(baseUrl, {
358358
method: "POST",
359359
body: requestBody,
360+
getJwt: () => this.client.getJwt(),
360361
});
361362
}
362363

web-common/src/features/dashboards/granular-access-policies/ViewAsButton.svelte

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
active={viewAsMenuOpen}
4646
removeTooltipText="Clear view"
4747
onRemove={() => {
48-
updateDevJWT(queryClient, instanceId, null);
48+
updateDevJWT(queryClient, instanceId, null, client);
4949
}}
5050
>
5151
<div slot="body">
@@ -62,7 +62,7 @@
6262
{#each $mockUsers.data as user (user?.email)}
6363
<DropdownMenu.Item
6464
on:click={() => {
65-
updateDevJWT(queryClient, instanceId, user);
65+
updateDevJWT(queryClient, instanceId, user, client);
6666
}}
6767
class="flex gap-x-2 items-center"
6868
>

web-common/src/features/dashboards/granular-access-policies/resetSelectedMockUserAfterNavigate.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { beforeNavigate } from "$app/navigation";
22
import { selectedMockUserStore } from "@rilldata/web-common/features/dashboards/granular-access-policies/stores";
33
import { updateDevJWT } from "@rilldata/web-common/features/dashboards/granular-access-policies/updateDevJWT";
4+
import type { RuntimeClient } from "@rilldata/web-common/runtime-client/v2";
45
import type { QueryClient } from "@tanstack/svelte-query";
56
import { get } from "svelte/store";
67

@@ -16,6 +17,7 @@ import { get } from "svelte/store";
1617
export function resetSelectedMockUserAfterNavigate(
1718
queryClient: QueryClient,
1819
instanceId: string,
20+
runtimeClient?: RuntimeClient,
1921
) {
2022
beforeNavigate(({ to, from }) => {
2123
if (!to?.params || !from?.params) return;
@@ -24,7 +26,9 @@ export function resetSelectedMockUserAfterNavigate(
2426
from.params.name !== to.params.name &&
2527
get(selectedMockUserStore) !== null
2628
) {
27-
updateDevJWT(queryClient, instanceId, null).catch(console.error);
29+
updateDevJWT(queryClient, instanceId, null, runtimeClient).catch(
30+
console.error,
31+
);
2832
}
2933
});
3034
}

web-common/src/features/dashboards/granular-access-policies/updateDevJWT.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,21 @@ import type { MockUser } from "@rilldata/web-common/features/dashboards/granular
66
import { runtimeServiceIssueDevJWT } from "@rilldata/web-common/runtime-client";
77
import { invalidateAllMetricsViews } from "@rilldata/web-common/runtime-client/invalidation";
88
import { runtime } from "@rilldata/web-common/runtime-client/runtime-store";
9+
import type { RuntimeClient } from "@rilldata/web-common/runtime-client/v2";
910
import type { QueryClient } from "@tanstack/svelte-query";
1011

1112
export async function updateDevJWT(
1213
queryClient: QueryClient,
1314
instanceId: string,
1415
mockUser: MockUser | null,
16+
runtimeClient?: RuntimeClient,
1517
) {
1618
selectedMockUserStore.set(mockUser);
1719

1820
if (mockUser === null) {
1921
selectedMockUserJWT.set(null);
22+
runtimeClient?.updateJwt(undefined, "user");
23+
// BRIDGE (temporary): keep global store in sync for unmigrated consumers
2024
runtime.update((runtimeState) => {
2125
runtimeState.jwt = undefined;
2226
return runtimeState;
@@ -36,7 +40,8 @@ export async function updateDevJWT(
3640
if (!jwt) throw new Error("No JWT returned");
3741

3842
selectedMockUserJWT.set(jwt);
39-
43+
runtimeClient?.updateJwt(jwt, "mock");
44+
// BRIDGE (temporary): keep global store in sync for unmigrated consumers
4045
runtime.update((runtimeState) => {
4146
runtimeState.jwt = {
4247
token: jwt,

web-common/src/features/explore-mappers/open-query.ts

Lines changed: 49 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,49 @@ import {
1515
} from "@rilldata/web-common/runtime-client";
1616
import type { Schema as MetricsResolverQuery } from "@rilldata/web-common/runtime-client/gen/resolvers/metrics/schema.ts";
1717
import { error, redirect } from "@sveltejs/kit";
18-
import type { Runtime } from "@rilldata/web-common/runtime-client/runtime-store.ts";
19-
import httpClient from "@rilldata/web-common/runtime-client/http-client.ts";
2018
import { getTimeControlState } from "@rilldata/web-common/features/dashboards/time-controls/time-control-store.ts";
2119
import { convertPartialExploreStateToUrlParams } from "@rilldata/web-common/features/dashboards/url-state/convert-partial-explore-state-to-url-params.ts";
2220
import { createLinkError } from "@rilldata/web-common/features/explore-mappers/explore-validation.ts";
2321
import { ExploreLinkErrorType } from "@rilldata/web-common/features/explore-mappers/types.ts";
2422

23+
interface RuntimeInfo {
24+
host: string;
25+
instanceId: string;
26+
jwt?: { token: string } | undefined;
27+
}
28+
29+
async function runtimeFetch<T>(
30+
runtime: RuntimeInfo,
31+
path: string,
32+
opts?: { method?: string; body?: unknown; signal?: AbortSignal },
33+
): Promise<T> {
34+
const headers: Record<string, string> = {
35+
"Content-Type": "application/json",
36+
};
37+
if (runtime.jwt) {
38+
headers["Authorization"] = `Bearer ${runtime.jwt.token}`;
39+
}
40+
const resp = await fetch(`${runtime.host}${path}`, {
41+
method: opts?.method ?? "GET",
42+
headers,
43+
...(opts?.body !== undefined ? { body: JSON.stringify(opts.body) } : {}),
44+
signal: opts?.signal,
45+
});
46+
if (!resp.ok) {
47+
const data = await resp.json().catch(() => ({}));
48+
throw { response: { status: resp.status, data } };
49+
}
50+
return (await resp.json()) as T;
51+
}
52+
2553
export async function openQuery({
2654
url,
2755
organization,
2856
project,
2957
runtime,
3058
}: {
3159
url: URL;
32-
runtime: Runtime;
60+
runtime: RuntimeInfo;
3361
organization?: string;
3462
project?: string;
3563
}) {
@@ -106,30 +134,21 @@ export async function openQuery({
106134
* TODO: try to find an explore that has as many measures/dimensions in the query
107135
*/
108136
async function findExploreForMetricsView(
109-
runtime: Runtime,
137+
runtime: RuntimeInfo,
110138
metricsViewName: string,
111139
): Promise<string> {
112-
// List all explore resources
113140
const exploreResources = await queryClient.fetchQuery({
114141
queryKey: getRuntimeServiceListResourcesQueryKey(runtime.instanceId, {
115142
kind: ResourceKind.Explore,
116143
}),
117144
queryFn: ({ signal }) =>
118-
httpClient<V1ListResourcesResponse>({
119-
url: `/v1/instances/${runtime.instanceId}/resources`,
120-
method: "GET",
121-
params: { kind: ResourceKind.Explore },
122-
signal,
123-
baseUrl: runtime.host,
124-
headers: runtime.jwt
125-
? {
126-
Authorization: `Bearer ${runtime.jwt?.token}`,
127-
}
128-
: undefined,
129-
}),
145+
runtimeFetch<V1ListResourcesResponse>(
146+
runtime,
147+
`/v1/instances/${runtime.instanceId}/resources?kind=${ResourceKind.Explore}`,
148+
{ signal },
149+
),
130150
});
131151

132-
// Look for an explore that references this metrics view
133152
if (exploreResources.resources) {
134153
for (const resource of exploreResources.resources) {
135154
if (resource.explore?.state?.validSpec?.metricsView === metricsViewName) {
@@ -138,31 +157,22 @@ async function findExploreForMetricsView(
138157
}
139158
}
140159

141-
// If no explore found, throw an error
142160
throw new Error(
143161
`No explore dashboard found for metrics view: ${metricsViewName}`,
144162
);
145163
}
146164

147-
async function getExploreSpecs(runtime: Runtime, exploreName: string) {
148-
// Get explore and metrics view specs
165+
async function getExploreSpecs(runtime: RuntimeInfo, exploreName: string) {
149166
const getExploreResponse = await queryClient.fetchQuery({
150167
queryKey: getRuntimeServiceGetExploreQueryKey(runtime.instanceId, {
151168
name: exploreName,
152169
}),
153170
queryFn: ({ signal }) =>
154-
httpClient<V1GetExploreResponse>({
155-
url: `/v1/instances/${runtime.instanceId}/resources/explore`,
156-
method: "GET",
157-
params: { name: exploreName },
158-
signal,
159-
baseUrl: runtime.host,
160-
headers: runtime.jwt
161-
? {
162-
Authorization: `Bearer ${runtime.jwt?.token}`,
163-
}
164-
: undefined,
165-
}),
171+
runtimeFetch<V1GetExploreResponse>(
172+
runtime,
173+
`/v1/instances/${runtime.instanceId}/resources/explore?name=${encodeURIComponent(exploreName)}`,
174+
{ signal },
175+
),
166176
});
167177
const exploreResource = getExploreResponse.explore;
168178
const metricsViewResource = getExploreResponse.metricsView;
@@ -185,7 +195,7 @@ async function getExploreSpecs(runtime: Runtime, exploreName: string) {
185195
* Generates the explore page URL with proper search parameters
186196
*/
187197
async function generateExploreLink(
188-
runtime: Runtime,
198+
runtime: RuntimeInfo,
189199
exploreState: Partial<ExploreState>,
190200
metricsViewSpec: V1MetricsViewSpec,
191201
exploreSpec: V1ExploreSpec,
@@ -194,29 +204,18 @@ async function generateExploreLink(
194204
project?: string | undefined,
195205
): Promise<string> {
196206
try {
197-
// Build base URL
198207
const url = getUrlForExplore(exploreName, organization, project);
199208

200209
const metricsViewName = exploreSpec.metricsView;
201210
let fullTimeRange: V1MetricsViewTimeRangeResponse | undefined;
202211
if (metricsViewSpec.timeDimension && metricsViewName) {
203212
fullTimeRange = await queryClient.fetchQuery({
204213
queryFn: ({ signal }) =>
205-
httpClient<V1MetricsViewTimeRangeResponse>({
206-
url: `/v1/instances/${runtime.instanceId}/queries/metrics-views/${metricsViewName}/time-range-summary`,
207-
method: "POST",
208-
headers: {
209-
"Content-Type": "application/json",
210-
...(runtime.jwt
211-
? {
212-
Authorization: `Bearer ${runtime.jwt?.token}`,
213-
}
214-
: {}),
215-
},
216-
data: {},
217-
signal,
218-
baseUrl: runtime.host,
219-
}),
214+
runtimeFetch<V1MetricsViewTimeRangeResponse>(
215+
runtime,
216+
`/v1/instances/${runtime.instanceId}/queries/metrics-views/${encodeURIComponent(metricsViewName)}/time-range-summary`,
217+
{ method: "POST", body: {}, signal },
218+
),
220219
queryKey: getQueryServiceMetricsViewTimeRangeQueryKey(
221220
runtime.instanceId,
222221
metricsViewName,
@@ -227,9 +226,6 @@ async function generateExploreLink(
227226
});
228227
}
229228

230-
// This is just for an initial redirect.
231-
// DashboardStateDataLoader will handle compression etc. during init
232-
// So no need to use getCleanedUrlParamsForGoto
233229
const searchParams = convertPartialExploreStateToUrlParams(
234230
exploreSpec,
235231
metricsViewSpec,

0 commit comments

Comments
 (0)