|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import { EventTarget } from "event-target-shim" |
|
|
import { ArrowDataframeProto, ArrowTable } from "./ArrowTable" |
|
|
|
|
|
|
|
|
export interface RenderData { |
|
|
args: any |
|
|
disabled: boolean |
|
|
} |
|
|
|
|
|
|
|
|
enum ComponentMessageType { |
|
|
|
|
|
|
|
|
|
|
|
COMPONENT_READY = "streamlit:componentReady", |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SET_COMPONENT_VALUE = "streamlit:setComponentValue", |
|
|
|
|
|
|
|
|
|
|
|
SET_FRAME_HEIGHT = "streamlit:setFrameHeight", |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export class Streamlit { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static readonly API_VERSION = 1 |
|
|
|
|
|
public static readonly RENDER_EVENT = "streamlit:render" |
|
|
|
|
|
|
|
|
public static readonly events = new EventTarget() |
|
|
|
|
|
private static registeredMessageListener = false |
|
|
private static lastFrameHeight?: number |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static setComponentReady = (): void => { |
|
|
if (!Streamlit.registeredMessageListener) { |
|
|
|
|
|
window.addEventListener("message", Streamlit.onMessageEvent) |
|
|
Streamlit.registeredMessageListener = true |
|
|
} |
|
|
|
|
|
Streamlit.sendBackMsg(ComponentMessageType.COMPONENT_READY, { |
|
|
apiVersion: Streamlit.API_VERSION, |
|
|
}) |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static setFrameHeight = (height?: number): void => { |
|
|
if (height === undefined) { |
|
|
|
|
|
|
|
|
|
|
|
height = document.body.scrollHeight + 10; |
|
|
} |
|
|
|
|
|
if (height === Streamlit.lastFrameHeight) { |
|
|
|
|
|
return |
|
|
} |
|
|
|
|
|
Streamlit.lastFrameHeight = height |
|
|
Streamlit.sendBackMsg(ComponentMessageType.SET_FRAME_HEIGHT, { height }) |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static setComponentValue = (value: any): void => { |
|
|
Streamlit.sendBackMsg(ComponentMessageType.SET_COMPONENT_VALUE, { value }) |
|
|
} |
|
|
|
|
|
|
|
|
private static onMessageEvent = (event: MessageEvent): void => { |
|
|
const type = event.data["type"] |
|
|
switch (type) { |
|
|
case Streamlit.RENDER_EVENT: |
|
|
Streamlit.onRenderMessage(event.data) |
|
|
break |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static onRenderMessage = (data: any): void => { |
|
|
let args = data["args"] |
|
|
if (args == null) { |
|
|
console.error( |
|
|
`Got null args in onRenderMessage. This should never happen` |
|
|
) |
|
|
args = {} |
|
|
} |
|
|
|
|
|
|
|
|
const dataframeArgs = |
|
|
data["dfs"] && data["dfs"].length > 0 |
|
|
? Streamlit.argsDataframeToObject(data["dfs"]) |
|
|
: {} |
|
|
|
|
|
args = { |
|
|
...args, |
|
|
...dataframeArgs, |
|
|
} |
|
|
|
|
|
const disabled = Boolean(data["disabled"]) |
|
|
|
|
|
|
|
|
const eventData = { disabled, args } |
|
|
const event = new CustomEvent<RenderData>(Streamlit.RENDER_EVENT, { |
|
|
detail: eventData, |
|
|
}) |
|
|
Streamlit.events.dispatchEvent(event) |
|
|
} |
|
|
|
|
|
private static argsDataframeToObject = ( |
|
|
argsDataframe: ArgsDataframe[] |
|
|
): object => { |
|
|
const argsDataframeArrow = argsDataframe.map( |
|
|
({ key, value }: ArgsDataframe) => [key, Streamlit.toArrowTable(value)] |
|
|
) |
|
|
return Object.fromEntries(argsDataframeArrow) |
|
|
} |
|
|
|
|
|
private static toArrowTable = (df: ArrowDataframeProto): ArrowTable => { |
|
|
const { data, index, columns } = df.data |
|
|
return new ArrowTable(data, index, columns) |
|
|
} |
|
|
|
|
|
|
|
|
private static sendBackMsg = (type: string, data?: any): void => { |
|
|
window.parent.postMessage( |
|
|
{ |
|
|
isStreamlitMessage: true, |
|
|
type: type, |
|
|
...data, |
|
|
}, |
|
|
"*" |
|
|
) |
|
|
} |
|
|
} |
|
|
|
|
|
interface ArgsDataframe { |
|
|
key: string |
|
|
value: ArrowDataframeProto |
|
|
} |
|
|
|