feat(console-web): replace TanStack UI with Solid host pages
- move the management frontend under the wasmeld-console crate\n- use a persistent Host shell with disposable iframe page documents\n- version Host/Page postMessage state and command contracts\n- migrate runtime, service, WIT, invocation, and settings workflows\n- add Tailwind CSS v4, responsive layouts, and Host-owned dialogs\n- emit a dependency-free PWA worker with API cache exclusions\n- remove the superseded root TanStack Start application
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
import type { BackendSnapshot } from "../lib/api";
|
||||
import type { ConnectionState, View } from "../lib/model";
|
||||
|
||||
export const SDK_CHANNEL = "wasmeld-console";
|
||||
|
||||
/**
|
||||
* Compatibility version for the same-origin Host/Page document protocol.
|
||||
*
|
||||
* Additive optional messages may keep the version. Removing a field or
|
||||
* changing its meaning requires a version bump and an atomic Host/Page
|
||||
* release, which is naturally provided by the embedded Console binary.
|
||||
*/
|
||||
export const SDK_VERSION = 1;
|
||||
|
||||
export type RuntimeAction = "start" | "stop" | "restart";
|
||||
export type ServiceAction = "start" | "stop" | "restart";
|
||||
|
||||
export type HostSharedState = {
|
||||
// This is a serializable snapshot, never a Solid signal crossing realms.
|
||||
view: View;
|
||||
snapshot: BackendSnapshot | null;
|
||||
connection: ConnectionState;
|
||||
query: string;
|
||||
apiBase: string;
|
||||
runtimeAction: RuntimeAction | null;
|
||||
serviceAction: string | null;
|
||||
deploymentAction: string | null;
|
||||
};
|
||||
|
||||
export type PageCommand =
|
||||
| { type: "refresh" }
|
||||
| { type: "navigate"; view: View }
|
||||
| { type: "open-register" }
|
||||
| { type: "open-wit-publish" }
|
||||
| { type: "open-invoke"; serviceKey: string }
|
||||
| { type: "open-activate"; serviceKey: string }
|
||||
| { type: "runtime-action"; action: RuntimeAction }
|
||||
| { type: "service-action"; serviceKey: string; action: ServiceAction }
|
||||
| { type: "save-api-base"; value: string };
|
||||
|
||||
export type PageMessage =
|
||||
| {
|
||||
channel: typeof SDK_CHANNEL;
|
||||
version: typeof SDK_VERSION;
|
||||
source: "page";
|
||||
type: "ready";
|
||||
view: View;
|
||||
}
|
||||
| {
|
||||
channel: typeof SDK_CHANNEL;
|
||||
version: typeof SDK_VERSION;
|
||||
source: "page";
|
||||
type: "command";
|
||||
view: View;
|
||||
command: PageCommand;
|
||||
};
|
||||
|
||||
export type HostMessage =
|
||||
| {
|
||||
channel: typeof SDK_CHANNEL;
|
||||
version: typeof SDK_VERSION;
|
||||
source: "host";
|
||||
type: "state";
|
||||
state: HostSharedState;
|
||||
}
|
||||
| {
|
||||
channel: typeof SDK_CHANNEL;
|
||||
version: typeof SDK_VERSION;
|
||||
source: "host";
|
||||
type: "dispose";
|
||||
};
|
||||
|
||||
export function isPageMessage(value: unknown): value is PageMessage {
|
||||
if (!isRecord(value)) return false;
|
||||
return (
|
||||
value.channel === SDK_CHANNEL &&
|
||||
value.version === SDK_VERSION &&
|
||||
value.source === "page" &&
|
||||
(value.type === "ready" || value.type === "command")
|
||||
);
|
||||
}
|
||||
|
||||
export function isHostMessage(value: unknown): value is HostMessage {
|
||||
if (!isRecord(value)) return false;
|
||||
return (
|
||||
value.channel === SDK_CHANNEL &&
|
||||
value.version === SDK_VERSION &&
|
||||
value.source === "host" &&
|
||||
(value.type === "state" || value.type === "dispose")
|
||||
);
|
||||
}
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === "object" && value !== null;
|
||||
}
|
||||
Reference in New Issue
Block a user