wsh view works -- uses a WS event to send to the frontend

This commit is contained in:
sawka 2024-06-24 19:04:08 -07:00
parent 3d00a05aa0
commit 7bf64fb268
9 changed files with 90 additions and 18 deletions

View File

@ -1,7 +1,7 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
import { LayoutTreeActionType, LayoutTreeInsertNodeAction, newLayoutNode } from "@/faraday/index";
import { LayoutTreeAction, LayoutTreeActionType, LayoutTreeInsertNodeAction, newLayoutNode } from "@/faraday/index";
import { getLayoutStateAtomForTab } from "@/faraday/lib/layoutAtom";
import { layoutTreeStateReducer } from "@/faraday/lib/layoutState";
@ -216,6 +216,21 @@ function handleWSEventMessage(msg: WSEventType) {
}
return;
}
if (msg.eventtype == "layoutaction") {
const layoutAction: WSLayoutAction = msg.data;
if (layoutAction.actiontype == LayoutTreeActionType.InsertNode) {
const insertNodeAction: LayoutTreeInsertNodeAction<TabLayoutData> = {
type: LayoutTreeActionType.InsertNode,
node: newLayoutNode<TabLayoutData>(undefined, undefined, undefined, {
blockId: layoutAction.blockid,
}),
};
runLayoutAction(layoutAction.tabid, insertNodeAction);
} else {
console.log("unsupported layout action", layoutAction);
}
return;
}
// we send to two subjects just eventType and eventType|oref
// we don't use getORefSubject here because we don't want to create a new subject
const eventSubject = eventSubjects.get(msg.eventtype);
@ -263,6 +278,12 @@ function getApi(): ElectronApi {
return (window as any).api;
}
function runLayoutAction(tabId: string, action: LayoutTreeAction) {
const layoutStateAtom = getLayoutStateAtomForTab(tabId, WOS.getWaveObjectAtom<Tab>(WOS.makeORef("tab", tabId)));
const curState = globalStore.get(layoutStateAtom);
globalStore.set(layoutStateAtom, layoutTreeStateReducer(curState, action));
}
async function createBlock(blockDef: BlockDef) {
const rtOpts: RuntimeOpts = { termsize: { rows: 25, cols: 80 } };
const blockId = await services.ObjectService.CreateBlock(blockDef, rtOpts);
@ -271,12 +292,7 @@ async function createBlock(blockDef: BlockDef) {
node: newLayoutNode<TabLayoutData>(undefined, undefined, undefined, { blockId }),
};
const activeTabId = globalStore.get(atoms.uiContext).activetabid;
const layoutStateAtom = getLayoutStateAtomForTab(
activeTabId,
WOS.getWaveObjectAtom<Tab>(WOS.makeORef("tab", activeTabId))
);
const curState = globalStore.get(layoutStateAtom);
globalStore.set(layoutStateAtom, layoutTreeStateReducer(curState, insertNodeAction));
runLayoutAction(activeTabId, insertNodeAction);
}
// when file is not found, returns {data: null, fileInfo: null}

View File

@ -15,7 +15,7 @@ import type {
WritableLayoutNodeAtom,
WritableLayoutTreeStateAtom,
} from "./lib/model";
import { LayoutTreeActionType } from "./lib/model";
import { LayoutTreeAction, LayoutTreeActionType } from "./lib/model";
export {
LayoutTreeActionType,
@ -27,6 +27,7 @@ export {
};
export type {
LayoutNode,
LayoutTreeAction,
LayoutTreeCommitPendingAction,
LayoutTreeComputeMoveNodeAction,
LayoutTreeDeleteNodeAction,

View File

@ -288,6 +288,13 @@ declare global {
data64: string;
};
// eventbus.WSLayoutAction
type WSLayoutAction = {
tabid: string;
actiontype: string;
blockid: string;
};
// wconfig.WatcherUpdate
type WatcherUpdate = {
file: string;

View File

@ -128,7 +128,7 @@ func (bc *BlockController) UpdateControllerAndSendUpdate(updateFn func() bool) {
if sendUpdate {
log.Printf("sending blockcontroller update %#v\n", bc.GetRuntimeStatus())
go eventbus.SendEvent(eventbus.WSEventType{
EventType: "blockcontroller:status",
EventType: eventbus.WSEvent_BlockControllerStatus,
ORef: waveobj.MakeORef(wstore.OType_Block, bc.BlockId).String(),
Data: bc.GetRuntimeStatus(),
})
@ -146,7 +146,7 @@ func HandleTruncateBlockFile(blockId string, blockFile string) error {
return fmt.Errorf("error truncating blockfile: %w", err)
}
eventbus.SendEvent(eventbus.WSEventType{
EventType: "blockfile",
EventType: eventbus.WSEvent_BlockFile,
ORef: waveobj.MakeORef(wstore.OType_Block, blockId).String(),
Data: &eventbus.WSFileEventData{
ZoneId: blockId,
@ -166,7 +166,7 @@ func HandleAppendBlockFile(blockId string, blockFile string, data []byte) error
return fmt.Errorf("error appending to blockfile: %w", err)
}
eventbus.SendEvent(eventbus.WSEventType{
EventType: "blockfile",
EventType: eventbus.WSEvent_BlockFile,
ORef: waveobj.MakeORef(wstore.OType_Block, blockId).String(),
Data: &eventbus.WSFileEventData{
ZoneId: blockId,

View File

@ -98,7 +98,7 @@ func handleSetView(ctx context.Context, cmd *wshutil.BlockSetViewCommand, cmdCtx
return nil, fmt.Errorf("error getting block: %w", err)
}
eventbus.SendEvent(eventbus.WSEventType{
EventType: "waveobj:update",
EventType: eventbus.WSEvent_WaveObjUpdate,
ORef: waveobj.MakeORef(wstore.OType_Block, cmdCtx.BlockId).String(),
Data: wstore.WaveObjUpdate{
UpdateType: wstore.UpdateType_Update,
@ -190,7 +190,7 @@ func handleSetMeta(ctx context.Context, cmd *wshutil.BlockSetMetaCommand, cmdCtx
return nil, fmt.Errorf("error getting object (2): %w", err)
}
eventbus.SendEvent(eventbus.WSEventType{
EventType: "waveobj:update",
EventType: eventbus.WSEvent_WaveObjUpdate,
ORef: oref.String(),
Data: wstore.WaveObjUpdate{
UpdateType: wstore.UpdateType_Update,
@ -210,7 +210,7 @@ func handleAppendBlockFile(blockId string, blockFile string, data []byte) error
return fmt.Errorf("error appending to blockfile: %w", err)
}
eventbus.SendEvent(eventbus.WSEventType{
EventType: "blockfile",
EventType: eventbus.WSEvent_BlockFile,
ORef: waveobj.MakeORef(wstore.OType_Block, blockId).String(),
Data: &eventbus.WSFileEventData{
ZoneId: blockId,
@ -236,7 +236,7 @@ func handleAppendIJsonFile(blockId string, blockFile string, cmd map[string]any,
return fmt.Errorf("error appending to blockfile(ijson): %w", err)
}
eventbus.SendEvent(eventbus.WSEventType{
EventType: "blockfile",
EventType: eventbus.WSEvent_BlockFile,
ORef: waveobj.MakeORef(wstore.OType_Block, blockId).String(),
Data: &eventbus.WSFileEventData{
ZoneId: blockId,
@ -248,14 +248,23 @@ func handleAppendIJsonFile(blockId string, blockFile string, cmd map[string]any,
return nil
}
func sendWStoreUpdatesToEventBus(updates wstore.UpdatesRtnType) {
for _, update := range updates {
eventbus.SendEvent(eventbus.WSEventType{
EventType: eventbus.WSEvent_WaveObjUpdate,
ORef: waveobj.MakeORef(update.OType, update.OID).String(),
Data: update,
})
}
}
func handleCreateBlock(ctx context.Context, cmd *wshutil.CreateBlockCommand, cmdCtx wshutil.CmdContextType) (map[string]any, error) {
ctx = wstore.ContextWithUpdates(ctx)
tabId := cmdCtx.TabId
if cmd.TabId != "" {
tabId = cmd.TabId
}
log.Printf("handleCreateBlock %s %v\n", tabId, cmd.BlockDef)
blockData, err := wstore.CreateBlock(ctx, tabId, cmd.BlockDef, cmd.RtOpts)
log.Printf("blockData: %v err:%v\n", blockData, err)
if err != nil {
return nil, fmt.Errorf("error creating block: %w", err)
}
@ -265,5 +274,22 @@ func handleCreateBlock(ctx context.Context, cmd *wshutil.CreateBlockCommand, cmd
return nil, fmt.Errorf("error starting block controller: %w", err)
}
}
updates := wstore.ContextGetUpdatesRtn(ctx)
sendWStoreUpdatesToEventBus(updates)
windowId, err := wstore.DBFindWindowForTabId(ctx, tabId)
if err != nil {
return nil, fmt.Errorf("error finding window for tab: %w", err)
}
if windowId == "" {
return nil, fmt.Errorf("no window found for tab")
}
eventbus.SendEventToWindow(windowId, eventbus.WSEventType{
EventType: eventbus.WSEvent_LayoutAction,
Data: &eventbus.WSLayoutActionData{
ActionType: "insert",
TabId: tabId,
BlockId: blockData.OID,
},
})
return map[string]any{"blockId": blockData.OID}, nil
}

View File

@ -9,6 +9,14 @@ import (
"github.com/wavetermdev/thenextwave/pkg/waveobj"
)
const (
WSEvent_WaveObjUpdate = "waveobj:update"
WSEvent_BlockFile = "blockfile"
WSEvent_Config = "config"
WSEvent_BlockControllerStatus = "blockcontroller:status"
WSEvent_LayoutAction = "layoutaction"
)
type WSEventType struct {
EventType string `json:"eventtype"`
ORef string `json:"oref,omitempty"`
@ -33,6 +41,12 @@ type WindowWatchData struct {
WatchedORefs map[waveobj.ORef]bool
}
type WSLayoutActionData struct {
TabId string `json:"tabid"`
ActionType string `json:"actiontype"`
BlockId string `json:"blockid"`
}
var globalLock = &sync.Mutex{}
var wsMap = make(map[string]*WindowWatchData) // websocketid => WindowWatchData

View File

@ -31,6 +31,7 @@ var ExtraTypes = []any{
wstore.UIContext{},
eventbus.WSEventType{},
eventbus.WSFileEventData{},
eventbus.WSLayoutActionData{},
filestore.WaveFile{},
wconfig.SettingsConfigType{},
wconfig.WatcherUpdate{},

View File

@ -160,7 +160,7 @@ func (w *Watcher) Close() {
func (w *Watcher) broadcast(message WatcherUpdate) {
// send to frontend
eventbus.SendEvent(eventbus.WSEventType{
EventType: "config",
EventType: eventbus.WSEvent_Config,
Data: message,
})

View File

@ -256,3 +256,10 @@ func DBInsert(ctx context.Context, val waveobj.WaveObj) error {
return nil
})
}
func DBFindWindowForTabId(ctx context.Context, tabId string) (string, error) {
return WithTxRtn(ctx, func(tx *TxWrap) (string, error) {
query := "SELECT oid FROM db_window WHERE data->>'activetabid' = ?"
return tx.GetString(query, tabId), nil
})
}