@skyvexsoftware/stratos-sdk 0.7.7 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -0
- package/dist/api/vaApi.d.ts +33 -0
- package/dist/api/vaApi.js +107 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useVaApi.d.ts +27 -0
- package/dist/hooks/useVaApi.js +28 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -0
- package/dist/types/context.d.ts +43 -1
- package/dist/ui/button.d.ts +2 -2
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -130,11 +130,31 @@ Individual hooks are also available:
|
|
|
130
130
|
| `useTrackingSession()` | High-level tracking state with derived fields |
|
|
131
131
|
| `useLandingAnalysis()` | Landing rate, bounces, and settled analysis |
|
|
132
132
|
| `useShellAuth()` | Authentication state and token |
|
|
133
|
+
| `useVaApi()` | Shared axios instance for the bound VA's API |
|
|
133
134
|
| `useShellConfig()` | Scoped configuration access |
|
|
134
135
|
| `useShellNavigation()` | Route navigation utilities |
|
|
135
136
|
| `useShellToast()` | Toast/notification functions |
|
|
136
137
|
| `usePluginLogger()` | Scoped renderer-side logger |
|
|
137
138
|
|
|
139
|
+
### VA API client
|
|
140
|
+
|
|
141
|
+
For HTTP calls to the bound airline's API, use `useVaApi()` (renderer) or `ctx.airline.createClient()` (background). Both return an [axios](https://axios-http.com/) instance that the shell pre-configures with the airline's `base_url`, the pilot's bearer token, and a `401` → refresh → retry interceptor:
|
|
142
|
+
|
|
143
|
+
```tsx
|
|
144
|
+
import { useVaApi } from "@skyvexsoftware/stratos-sdk";
|
|
145
|
+
|
|
146
|
+
const va = useVaApi();
|
|
147
|
+
const { data } = await va.get("/pilot/verify");
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
The renderer-side instance is provided by `PluginShellProvider` and **shared across the shell and every plugin UI** — concurrent `401`s coalesce onto a single refresh roundtrip rather than each plugin firing its own.
|
|
151
|
+
|
|
152
|
+
#### About the axios dependency
|
|
153
|
+
|
|
154
|
+
`axios` is a regular dependency of this SDK, so plugins **don't need to declare it** in their own `package.json` if they only consume it through `useVaApi()` / `ctx.airline.createClient()`. The plugin's bundle won't ship its own copy either — the shell's instance is reused at runtime through the plugin context.
|
|
155
|
+
|
|
156
|
+
Only add `axios` to your plugin's deps if you import it directly — for example to call `axios.isAxiosError(err)` for narrowing or to build your own custom instance. If you do, pin the same major version as the SDK to avoid runtime surprises.
|
|
157
|
+
|
|
138
158
|
### Background Module
|
|
139
159
|
|
|
140
160
|
Optional main-process code with access to IPC, Express routes, SQLite, and more. Must use the `createPlugin` helper (imported from the `/helpers` subpath) with a default export:
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VA API client — singleton axios instance for plugins to call the bound
|
|
3
|
+
* airline's API. Transparently refreshes the access token on 401.
|
|
4
|
+
*
|
|
5
|
+
* Usage from a plugin component:
|
|
6
|
+
*
|
|
7
|
+
* import { useVaApi } from "@skyvexsoftware/stratos-sdk";
|
|
8
|
+
*
|
|
9
|
+
* const va = useVaApi();
|
|
10
|
+
* const profile = await va.get<{ pilotID: string }>("/pilot/verify");
|
|
11
|
+
*
|
|
12
|
+
* Refresh behaviour:
|
|
13
|
+
* - On 401 we ask the shell to refresh (POST /api/auth/va/refresh).
|
|
14
|
+
* - If refresh succeeds, the request is retried exactly once.
|
|
15
|
+
* - If refresh fails or the VA isn't configured for refresh, the 401
|
|
16
|
+
* surfaces to the caller and the shell's existing re-auth flow takes
|
|
17
|
+
* over (the auth state will flip on the next /api/auth poll).
|
|
18
|
+
*
|
|
19
|
+
* The token and baseURL are pulled from the local shell server on every
|
|
20
|
+
* request, so plugins don't need to subscribe to auth changes — the
|
|
21
|
+
* latest token is always used.
|
|
22
|
+
*
|
|
23
|
+
* Concurrency: a single in-flight refresh promise is shared across all
|
|
24
|
+
* callers of this client. Concurrent 401s coalesce onto the same refresh,
|
|
25
|
+
* and outbound requests issued while a refresh is running wait for it to
|
|
26
|
+
* settle before reading the bearer — otherwise they'd send the stale token
|
|
27
|
+
* and get a redundant 401.
|
|
28
|
+
*/
|
|
29
|
+
import { AxiosInstance } from "axios";
|
|
30
|
+
/** Singleton axios instance for VA API calls with auto-refresh on 401. */
|
|
31
|
+
export declare const vaApi: AxiosInstance;
|
|
32
|
+
export default vaApi;
|
|
33
|
+
//# sourceMappingURL=vaApi.d.ts.map
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VA API client — singleton axios instance for plugins to call the bound
|
|
3
|
+
* airline's API. Transparently refreshes the access token on 401.
|
|
4
|
+
*
|
|
5
|
+
* Usage from a plugin component:
|
|
6
|
+
*
|
|
7
|
+
* import { useVaApi } from "@skyvexsoftware/stratos-sdk";
|
|
8
|
+
*
|
|
9
|
+
* const va = useVaApi();
|
|
10
|
+
* const profile = await va.get<{ pilotID: string }>("/pilot/verify");
|
|
11
|
+
*
|
|
12
|
+
* Refresh behaviour:
|
|
13
|
+
* - On 401 we ask the shell to refresh (POST /api/auth/va/refresh).
|
|
14
|
+
* - If refresh succeeds, the request is retried exactly once.
|
|
15
|
+
* - If refresh fails or the VA isn't configured for refresh, the 401
|
|
16
|
+
* surfaces to the caller and the shell's existing re-auth flow takes
|
|
17
|
+
* over (the auth state will flip on the next /api/auth poll).
|
|
18
|
+
*
|
|
19
|
+
* The token and baseURL are pulled from the local shell server on every
|
|
20
|
+
* request, so plugins don't need to subscribe to auth changes — the
|
|
21
|
+
* latest token is always used.
|
|
22
|
+
*
|
|
23
|
+
* Concurrency: a single in-flight refresh promise is shared across all
|
|
24
|
+
* callers of this client. Concurrent 401s coalesce onto the same refresh,
|
|
25
|
+
* and outbound requests issued while a refresh is running wait for it to
|
|
26
|
+
* settle before reading the bearer — otherwise they'd send the stale token
|
|
27
|
+
* and get a redundant 401.
|
|
28
|
+
*/
|
|
29
|
+
import axios from "axios";
|
|
30
|
+
import { STRATOS_APP_BASE } from "../helpers/server";
|
|
31
|
+
const SHELL_API = `${STRATOS_APP_BASE}/api`;
|
|
32
|
+
async function readAuth() {
|
|
33
|
+
try {
|
|
34
|
+
const res = await axios.get(`${SHELL_API}/auth`);
|
|
35
|
+
return {
|
|
36
|
+
vaBaseUrl: res.data.data?.vaBaseUrl ?? null,
|
|
37
|
+
vaToken: res.data.data?.vaToken ?? null,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return { vaBaseUrl: null, vaToken: null };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
let refreshInflight = null;
|
|
45
|
+
function ensureRefresh() {
|
|
46
|
+
if (refreshInflight)
|
|
47
|
+
return refreshInflight;
|
|
48
|
+
refreshInflight = (async () => {
|
|
49
|
+
try {
|
|
50
|
+
const res = await axios.post(`${SHELL_API}/auth/va/refresh`);
|
|
51
|
+
return !!res.data.refreshed;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
})().finally(() => {
|
|
57
|
+
refreshInflight = null;
|
|
58
|
+
});
|
|
59
|
+
return refreshInflight;
|
|
60
|
+
}
|
|
61
|
+
class VaApiClient {
|
|
62
|
+
constructor() {
|
|
63
|
+
this.axiosInstance = axios.create({
|
|
64
|
+
timeout: 15000,
|
|
65
|
+
headers: {
|
|
66
|
+
"Content-Type": "application/json",
|
|
67
|
+
Accept: "application/json",
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
this.axiosInstance.interceptors.request.use(async (config) => {
|
|
71
|
+
// Wait for any in-flight refresh so we read the post-refresh bearer
|
|
72
|
+
// instead of racing the write.
|
|
73
|
+
if (refreshInflight)
|
|
74
|
+
await refreshInflight;
|
|
75
|
+
const auth = await readAuth();
|
|
76
|
+
if (auth.vaBaseUrl)
|
|
77
|
+
config.baseURL = auth.vaBaseUrl;
|
|
78
|
+
if (auth.vaToken)
|
|
79
|
+
config.headers.Authorization = `Bearer ${auth.vaToken}`;
|
|
80
|
+
return config;
|
|
81
|
+
});
|
|
82
|
+
this.axiosInstance.interceptors.response.use((response) => response, async (error) => {
|
|
83
|
+
const original = error.config;
|
|
84
|
+
if (error.response?.status !== 401 ||
|
|
85
|
+
!original ||
|
|
86
|
+
original.__vaRetried) {
|
|
87
|
+
return Promise.reject(error);
|
|
88
|
+
}
|
|
89
|
+
original.__vaRetried = true;
|
|
90
|
+
const refreshed = await ensureRefresh();
|
|
91
|
+
if (!refreshed)
|
|
92
|
+
return Promise.reject(error);
|
|
93
|
+
return await this.axiosInstance.request(original);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
static getInstance() {
|
|
97
|
+
if (!VaApiClient.instance)
|
|
98
|
+
VaApiClient.instance = new VaApiClient();
|
|
99
|
+
return VaApiClient.instance;
|
|
100
|
+
}
|
|
101
|
+
get axios() {
|
|
102
|
+
return this.axiosInstance;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/** Singleton axios instance for VA API calls with auto-refresh on 401. */
|
|
106
|
+
export const vaApi = VaApiClient.getInstance().axios;
|
|
107
|
+
export default vaApi;
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { useSimData, simDataKeys } from "./useSimData";
|
|
|
7
7
|
export { useTrackingSession, trackingSessionKeys } from "./useTrackingSession";
|
|
8
8
|
export { usePluginLogger } from "./usePluginLogger";
|
|
9
9
|
export { useShellAuth } from "./useShellAuth";
|
|
10
|
+
export { useVaApi } from "./useVaApi";
|
|
10
11
|
export { useShellConfig } from "./useShellConfig";
|
|
11
12
|
export { useShellNavigation } from "./useShellNavigation";
|
|
12
13
|
export { useShellToast } from "./useShellToast";
|
package/dist/hooks/index.js
CHANGED
|
@@ -7,6 +7,7 @@ export { useSimData, simDataKeys } from "./useSimData";
|
|
|
7
7
|
export { useTrackingSession, trackingSessionKeys } from "./useTrackingSession";
|
|
8
8
|
export { usePluginLogger } from "./usePluginLogger";
|
|
9
9
|
export { useShellAuth } from "./useShellAuth";
|
|
10
|
+
export { useVaApi } from "./useVaApi";
|
|
10
11
|
export { useShellConfig } from "./useShellConfig";
|
|
11
12
|
export { useShellNavigation } from "./useShellNavigation";
|
|
12
13
|
export { useShellToast } from "./useShellToast";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { AxiosInstance } from "axios";
|
|
2
|
+
/**
|
|
3
|
+
* Returns the shared axios instance for the bound airline's API.
|
|
4
|
+
*
|
|
5
|
+
* The shell provides a single instance through PluginShellProvider so all
|
|
6
|
+
* plugin UIs (and the shell itself) coalesce concurrent 401s onto one
|
|
7
|
+
* refresh — the in-flight refresh promise lives on the shared instance,
|
|
8
|
+
* so a 401 in plugin A and plugin B at the same time fires exactly one
|
|
9
|
+
* `POST /api/auth/va/refresh`.
|
|
10
|
+
*
|
|
11
|
+
* Behaviour (set up by the shell):
|
|
12
|
+
* - baseURL is the airline's base_url (resolved per request).
|
|
13
|
+
* - Authorization is the current pilot's VA bearer.
|
|
14
|
+
* - On 401, the shell refreshes the access token at the VA's refresh URL.
|
|
15
|
+
* Success → request retried once. Failure → 401 propagates and the
|
|
16
|
+
* shell's existing re-auth flow takes over.
|
|
17
|
+
*
|
|
18
|
+
* Must be used inside a PluginShellProvider tree. For non-React callers
|
|
19
|
+
* (helpers, services, tests), import the standalone `vaApi` export instead.
|
|
20
|
+
*
|
|
21
|
+
* Example:
|
|
22
|
+
*
|
|
23
|
+
* const va = useVaApi();
|
|
24
|
+
* const { data } = await va.get<{ pilotID: string }>("/pilot/verify");
|
|
25
|
+
*/
|
|
26
|
+
export declare function useVaApi(): AxiosInstance;
|
|
27
|
+
//# sourceMappingURL=useVaApi.d.ts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { usePluginContext } from "./context";
|
|
2
|
+
/**
|
|
3
|
+
* Returns the shared axios instance for the bound airline's API.
|
|
4
|
+
*
|
|
5
|
+
* The shell provides a single instance through PluginShellProvider so all
|
|
6
|
+
* plugin UIs (and the shell itself) coalesce concurrent 401s onto one
|
|
7
|
+
* refresh — the in-flight refresh promise lives on the shared instance,
|
|
8
|
+
* so a 401 in plugin A and plugin B at the same time fires exactly one
|
|
9
|
+
* `POST /api/auth/va/refresh`.
|
|
10
|
+
*
|
|
11
|
+
* Behaviour (set up by the shell):
|
|
12
|
+
* - baseURL is the airline's base_url (resolved per request).
|
|
13
|
+
* - Authorization is the current pilot's VA bearer.
|
|
14
|
+
* - On 401, the shell refreshes the access token at the VA's refresh URL.
|
|
15
|
+
* Success → request retried once. Failure → 401 propagates and the
|
|
16
|
+
* shell's existing re-auth flow takes over.
|
|
17
|
+
*
|
|
18
|
+
* Must be used inside a PluginShellProvider tree. For non-React callers
|
|
19
|
+
* (helpers, services, tests), import the standalone `vaApi` export instead.
|
|
20
|
+
*
|
|
21
|
+
* Example:
|
|
22
|
+
*
|
|
23
|
+
* const va = useVaApi();
|
|
24
|
+
* const { data } = await va.get<{ pilotID: string }>("/pilot/verify");
|
|
25
|
+
*/
|
|
26
|
+
export function useVaApi() {
|
|
27
|
+
return usePluginContext().vaApi;
|
|
28
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type { PluginAuthor, PluginManifest } from "./types/manifest";
|
|
2
|
-
export type { PluginAirline, PluginAirlineAccessor, PluginAuthAccessor, PluginConfigStore, PluginContext, PluginDatabaseAccessor, PluginIPCRegistrar, PluginLogger, PluginNavigationHelper, PluginPilotUser, PluginServerRegistrar, PluginToastAPI, PluginUIContext, PluginSettingType, PluginSettingOption, PluginSettingDefinition, PluginAvailableSettings, BooleanSettingDef, TextSettingDef, LongtextSettingDef, NumberSettingDef, RangeSettingDef, ListSettingDef, RadioSettingDef, DateSettingDef, JsonSettingDef, } from "./types/context";
|
|
2
|
+
export type { PluginAirline, PluginAirlineAccessor, PluginAuthAccessor, PluginVaApiClient, PluginConfigStore, PluginContext, PluginDatabaseAccessor, PluginIPCRegistrar, PluginLogger, PluginNavigationHelper, PluginPilotUser, PluginServerRegistrar, PluginToastAPI, PluginUIContext, PluginSettingType, PluginSettingOption, PluginSettingDefinition, PluginAvailableSettings, BooleanSettingDef, TextSettingDef, LongtextSettingDef, NumberSettingDef, RangeSettingDef, ListSettingDef, RadioSettingDef, DateSettingDef, JsonSettingDef, } from "./types/context";
|
|
3
3
|
export type { PluginBackgroundModule, PluginRouteComponent, PluginUIModule, } from "./types/module";
|
|
4
4
|
export { FlightPhase, SimulatorType, EventCategory, } from "./shared-types/simulator";
|
|
5
5
|
export type { BounceData, CapturePoint, FlightData, FlightDataSnapshot, FlightEventPayload, FlightEventsSnapshot, FlightLandingPayload, FlightLogEvent, FlightPhasePayload, FlightPhaseSnapshot, FlightStateDebugInfo, FlightTrends, HistoryReportEntry, LandingAnalysis, LandingAnalysisSnapshot, LandingAnalyzerDebugState, LandingSample, PendingPhaseTransition, SimDataSnapshot, SimulatorStatus, } from "./shared-types/simulator";
|
|
@@ -7,6 +7,7 @@ export type { ThemeMode } from "./shared-types/theme";
|
|
|
7
7
|
export type { FlightPlan, FlightStatus, CurrentFlight, FlightComment, PreflightCheck, PreflightCheckResult, StartFlightOptions, FlightManagerPayload, StartFlightResult, RecoverableFlight, } from "./shared-types/flight-manager";
|
|
8
8
|
export { createPlugin } from "./helpers/createPlugin";
|
|
9
9
|
export { STRATOS_APP_PORT, STRATOS_APP_BASE } from "./helpers/server";
|
|
10
|
+
export { vaApi } from "./api/vaApi";
|
|
10
11
|
export { weightToLbs, weightFromLbs, altitudeToFt, altitudeFromFt, verticalSpeedFromFpm, verticalSpeedToFpm, distanceToNm, distanceFromNm, formatWeight, formatAltitude, formatDistance, formatVerticalSpeed, } from "./helpers/units";
|
|
11
12
|
export type { WeightUnit, AltitudeUnit, DistanceUnit, UnitPreferences, } from "./helpers/units";
|
|
12
13
|
export { PluginUICtx, usePluginContext } from "./hooks/context";
|
|
@@ -18,6 +19,7 @@ export { useSimData, simDataKeys } from "./hooks/useSimData";
|
|
|
18
19
|
export { useTrackingSession, trackingSessionKeys, } from "./hooks/useTrackingSession";
|
|
19
20
|
export { usePluginLogger } from "./hooks/usePluginLogger";
|
|
20
21
|
export { useShellAuth } from "./hooks/useShellAuth";
|
|
22
|
+
export { useVaApi } from "./hooks/useVaApi";
|
|
21
23
|
export { useShellConfig } from "./hooks/useShellConfig";
|
|
22
24
|
export { useShellNavigation } from "./hooks/useShellNavigation";
|
|
23
25
|
export { useShellToast } from "./hooks/useShellToast";
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export { FlightPhase, SimulatorType, EventCategory, } from "./shared-types/simul
|
|
|
3
3
|
// ── Helper Functions ───────────────────────────────────────────────────
|
|
4
4
|
export { createPlugin } from "./helpers/createPlugin";
|
|
5
5
|
export { STRATOS_APP_PORT, STRATOS_APP_BASE } from "./helpers/server";
|
|
6
|
+
export { vaApi } from "./api/vaApi";
|
|
6
7
|
export { weightToLbs, weightFromLbs, altitudeToFt, altitudeFromFt, verticalSpeedFromFpm, verticalSpeedToFpm, distanceToNm, distanceFromNm, formatWeight, formatAltitude, formatDistance, formatVerticalSpeed, } from "./helpers/units";
|
|
7
8
|
// ── React Hooks ────────────────────────────────────────────────────────
|
|
8
9
|
export { PluginUICtx, usePluginContext } from "./hooks/context";
|
|
@@ -14,6 +15,7 @@ export { useSimData, simDataKeys } from "./hooks/useSimData";
|
|
|
14
15
|
export { useTrackingSession, trackingSessionKeys, } from "./hooks/useTrackingSession";
|
|
15
16
|
export { usePluginLogger } from "./hooks/usePluginLogger";
|
|
16
17
|
export { useShellAuth } from "./hooks/useShellAuth";
|
|
18
|
+
export { useVaApi } from "./hooks/useVaApi";
|
|
17
19
|
export { useShellConfig } from "./hooks/useShellConfig";
|
|
18
20
|
export { useShellNavigation } from "./hooks/useShellNavigation";
|
|
19
21
|
export { useShellToast } from "./hooks/useShellToast";
|
package/dist/types/context.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Defines the context objects the shell provides to plugins
|
|
5
5
|
* for both background (main process) and UI (renderer) usage.
|
|
6
6
|
*/
|
|
7
|
+
import type { AxiosInstance } from "axios";
|
|
7
8
|
/** All supported setting control types */
|
|
8
9
|
export type PluginSettingType = "boolean" | "text" | "longtext" | "number" | "range" | "list" | "radio" | "date" | "json";
|
|
9
10
|
/** Option entry for list and radio settings */
|
|
@@ -129,10 +130,32 @@ export type PluginAirline = {
|
|
|
129
130
|
/** Bearer for this airline's API. Null if the VA session has expired. */
|
|
130
131
|
token: string | null;
|
|
131
132
|
};
|
|
133
|
+
/**
|
|
134
|
+
* Pre-configured axios instance for the bound airline's API.
|
|
135
|
+
*
|
|
136
|
+
* - baseURL is the airline's base_url
|
|
137
|
+
* - Authorization header is the current VA bearer (resolved per-request)
|
|
138
|
+
* - On 401, the shell refreshes the VA access token if a refresh URL is
|
|
139
|
+
* configured, then retries the request exactly once. If refresh fails
|
|
140
|
+
* or isn't supported, the 401 surfaces to the caller.
|
|
141
|
+
*
|
|
142
|
+
* Use this instead of raw fetch(`${airline.baseUrl}/...`) so plugins get
|
|
143
|
+
* refresh-token handling for free.
|
|
144
|
+
*
|
|
145
|
+
* Aliased here for clarity at the plugin contract surface — at runtime
|
|
146
|
+
* this is the same shape as an axios `AxiosInstance`.
|
|
147
|
+
*/
|
|
148
|
+
export type PluginVaApiClient = AxiosInstance;
|
|
132
149
|
/** Read-only accessor for the currently-bound airline. */
|
|
133
150
|
export type PluginAirlineAccessor = {
|
|
134
151
|
/** Returns the current airline, or null if no VA session is active. */
|
|
135
152
|
getCurrent(): Promise<PluginAirline | null>;
|
|
153
|
+
/**
|
|
154
|
+
* Returns an axios instance pre-configured for this airline's API
|
|
155
|
+
* with auto-refresh on 401. Safe to cache for the lifetime of the
|
|
156
|
+
* background module.
|
|
157
|
+
*/
|
|
158
|
+
createClient(): PluginVaApiClient;
|
|
136
159
|
};
|
|
137
160
|
/** Express route registration helper for background plugins */
|
|
138
161
|
export type PluginServerRegistrar = {
|
|
@@ -203,6 +226,13 @@ export type PluginToastAPI = {
|
|
|
203
226
|
* Provides shared hooks and utilities from the shell.
|
|
204
227
|
*/
|
|
205
228
|
export type PluginUIContext = {
|
|
229
|
+
/**
|
|
230
|
+
* Shared axios instance for the bound airline's API, with auto-refresh on
|
|
231
|
+
* 401. Provided by the shell so all plugin UIs and the shell itself share
|
|
232
|
+
* one in-flight refresh promise — concurrent 401s coalesce to a single
|
|
233
|
+
* `POST /api/auth/va/refresh`. Reach this through `useVaApi()`.
|
|
234
|
+
*/
|
|
235
|
+
vaApi: AxiosInstance;
|
|
206
236
|
/** The plugin's unique ID */
|
|
207
237
|
pluginId: string;
|
|
208
238
|
/** Auth state from the shell */
|
|
@@ -229,7 +259,19 @@ export type PluginUIContext = {
|
|
|
229
259
|
get<T>(key: string): T | undefined;
|
|
230
260
|
get<T>(key: string, defaultValue: T): T;
|
|
231
261
|
};
|
|
232
|
-
/**
|
|
262
|
+
/**
|
|
263
|
+
* Real-time bridge between this plugin's background and UI modules.
|
|
264
|
+
*
|
|
265
|
+
* - `on(event, handler)` subscribes to broadcasts the background made via
|
|
266
|
+
* `ctx.ipc.send(event, payload)`. The shell scopes the channel to the
|
|
267
|
+
* current plugin id automatically — pass the leaf event name on both
|
|
268
|
+
* ends. Plugin A's UI cannot receive plugin B's broadcasts.
|
|
269
|
+
* - `off(event, handler)` removes a previously registered handler.
|
|
270
|
+
* - `emit` is intentionally not implemented. Send UI→background traffic
|
|
271
|
+
* through HTTP routes registered via `ctx.server.registerRouter`.
|
|
272
|
+
* - `connected` is always `true` in the renderer; the underlying Electron
|
|
273
|
+
* IPC pipe has no connection lifecycle.
|
|
274
|
+
*/
|
|
233
275
|
socket: {
|
|
234
276
|
connected: boolean;
|
|
235
277
|
emit(event: string, data: unknown): void;
|
package/dist/ui/button.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { type VariantProps } from "class-variance-authority";
|
|
3
3
|
declare const buttonVariants: (props?: ({
|
|
4
|
-
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "
|
|
4
|
+
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | "pill-pause" | "pill-resume" | "pill-end" | "pill-submit" | null | undefined;
|
|
5
5
|
size?: "default" | "sm" | "lg" | "icon" | "pill" | null | undefined;
|
|
6
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
7
|
export type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<typeof buttonVariants> & {
|
|
8
8
|
asChild?: boolean;
|
|
9
9
|
};
|
|
10
10
|
declare const Button: React.ForwardRefExoticComponent<React.ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<(props?: ({
|
|
11
|
-
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "
|
|
11
|
+
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | "pill-pause" | "pill-resume" | "pill-end" | "pill-submit" | null | undefined;
|
|
12
12
|
size?: "default" | "sm" | "lg" | "icon" | "pill" | null | undefined;
|
|
13
13
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string> & {
|
|
14
14
|
asChild?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skyvexsoftware/stratos-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Plugin SDK for Stratos — types, hooks, and UI components",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Skyvex Software Pty Ltd",
|
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"@radix-ui/react-switch": "^1.2.0",
|
|
95
95
|
"@radix-ui/react-tabs": "^1.1.0",
|
|
96
96
|
"@radix-ui/react-tooltip": "^1.1.0",
|
|
97
|
-
"@tanstack/react-query": "^5.
|
|
97
|
+
"@tanstack/react-query": "^5.99.0",
|
|
98
98
|
"@vitejs/plugin-react": "^5.0.0",
|
|
99
99
|
"class-variance-authority": "^0.7.0",
|
|
100
100
|
"lucide-react": ">=0.300.0",
|
|
@@ -103,6 +103,7 @@
|
|
|
103
103
|
"vite": "^7.0.0"
|
|
104
104
|
},
|
|
105
105
|
"dependencies": {
|
|
106
|
+
"axios": "^1.15.0",
|
|
106
107
|
"clsx": "^2.1.1",
|
|
107
108
|
"magic-string": "^0.30.21",
|
|
108
109
|
"tailwind-merge": "^3.2.0"
|