mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-21 16:38:23 +01:00
setactivetab working, removed tombstones, created updatetype
This commit is contained in:
parent
b87786febf
commit
abedca2364
@ -41,10 +41,7 @@ function isValidWaveObj(val: WaveObj): boolean {
|
||||
if (val == null) {
|
||||
return false;
|
||||
}
|
||||
if (isBlank(val.otype) || isBlank(val.oid)) {
|
||||
return false;
|
||||
}
|
||||
if (!val.deleted && isBlankNum(val.version)) {
|
||||
if (isBlank(val.otype) || isBlank(val.oid) || isBlankNum(val.version)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -151,34 +148,34 @@ function useWaveObject<T>(oref: string): [T, boolean, (T) => void] {
|
||||
return [atomVal.value, atomVal.loading, simpleSet];
|
||||
}
|
||||
|
||||
function updateWaveObject(val: WaveObj) {
|
||||
if (val == null) {
|
||||
function updateWaveObject(update: WaveObjUpdate) {
|
||||
if (update == null) {
|
||||
return;
|
||||
}
|
||||
if (!isValidWaveObj(val)) {
|
||||
console.log("invalid wave object", val);
|
||||
return;
|
||||
}
|
||||
let oref = makeORef(val.otype, val.oid);
|
||||
let oref = makeORef(update.otype, update.oid);
|
||||
let wov = waveObjectValueCache.get(oref);
|
||||
if (wov == null) {
|
||||
wov = createWaveValueObject(oref, false);
|
||||
waveObjectValueCache.set(oref, wov);
|
||||
}
|
||||
if (val.deleted) {
|
||||
if (update.updatetype == "delete") {
|
||||
globalStore.set(wov.dataAtom, { value: null, loading: false });
|
||||
} else {
|
||||
let curValue: WaveObjectDataItemType<WaveObj> = globalStore.get(wov.dataAtom);
|
||||
if (curValue.value != null && curValue.value.version >= val.version) {
|
||||
if (!isValidWaveObj(update.obj)) {
|
||||
console.log("invalid wave object update", update);
|
||||
return;
|
||||
}
|
||||
globalStore.set(wov.dataAtom, { value: val, loading: false });
|
||||
let curValue: WaveObjectDataItemType<WaveObj> = globalStore.get(wov.dataAtom);
|
||||
if (curValue.value != null && curValue.value.version >= update.obj.version) {
|
||||
return;
|
||||
}
|
||||
globalStore.set(wov.dataAtom, { value: update.obj, loading: false });
|
||||
}
|
||||
wov.holdTime = Date.now() + defaultHoldTime;
|
||||
return;
|
||||
}
|
||||
|
||||
function updateWaveObjects(vals: WaveObj[]) {
|
||||
function updateWaveObjects(vals: WaveObjUpdate[]) {
|
||||
for (let val of vals) {
|
||||
updateWaveObject(val);
|
||||
}
|
||||
@ -194,7 +191,7 @@ function cleanWaveObjectCache() {
|
||||
}
|
||||
|
||||
Events.On("waveobj:update", (event: any) => {
|
||||
const data: WaveObj[] = event?.data;
|
||||
const data: WaveObjUpdate[] = event?.data;
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
@ -217,6 +214,7 @@ function wrapObjectServiceCall<T>(fnName: string, ...args: any[]): Promise<T> {
|
||||
);
|
||||
prtn = prtn.then((val) => {
|
||||
if (val.updates) {
|
||||
console.log(val.updates);
|
||||
updateWaveObjects(val.updates);
|
||||
}
|
||||
return val;
|
||||
@ -228,6 +226,10 @@ function AddTabToWorkspace(tabName: string, activateTab: boolean): Promise<{ tab
|
||||
return wrapObjectServiceCall("AddTabToWorkspace", tabName, activateTab);
|
||||
}
|
||||
|
||||
function SetActiveTab(tabId: string): Promise<void> {
|
||||
return wrapObjectServiceCall("SetActiveTab", tabId);
|
||||
}
|
||||
|
||||
function getStaticObjectValue<T>(oref: string, getFn: jotai.Getter): T {
|
||||
let wov = waveObjectValueCache.get(oref);
|
||||
if (wov == null) {
|
||||
@ -248,4 +250,5 @@ export {
|
||||
cleanWaveObjectCache,
|
||||
getStaticObjectValue,
|
||||
AddTabToWorkspace,
|
||||
SetActiveTab,
|
||||
};
|
||||
|
@ -24,7 +24,7 @@ function Tab({ tabId }: { tabId: string }) {
|
||||
if (tabId == null) {
|
||||
return;
|
||||
}
|
||||
// TODO
|
||||
WOS.SetActiveTab(tabId);
|
||||
}
|
||||
return (
|
||||
<div
|
||||
|
19
frontend/types/custom.d.ts
vendored
19
frontend/types/custom.d.ts
vendored
@ -11,10 +11,20 @@ declare global {
|
||||
oid: string;
|
||||
};
|
||||
|
||||
type Block = {
|
||||
type WaveObj = {
|
||||
otype: string;
|
||||
oid: string;
|
||||
version: number;
|
||||
};
|
||||
|
||||
type WaveObjUpdate = {
|
||||
updatetype: "update" | "delete";
|
||||
otype: string;
|
||||
oid: string;
|
||||
obj?: WaveObj;
|
||||
};
|
||||
|
||||
type Block = WaveObj & {
|
||||
blockdef: BlockDef;
|
||||
controller: string;
|
||||
view: string;
|
||||
@ -80,13 +90,6 @@ declare global {
|
||||
winsize?: WinSize;
|
||||
};
|
||||
|
||||
type WaveObj = {
|
||||
otype: string;
|
||||
oid: string;
|
||||
version: number;
|
||||
deleted?: boolean;
|
||||
};
|
||||
|
||||
type WaveWindow = {
|
||||
otype: string;
|
||||
oid: string;
|
||||
|
@ -5,6 +5,7 @@ package objectservice
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
@ -60,21 +61,18 @@ func updatesRtn(ctx context.Context, rtnVal map[string]any) (any, error) {
|
||||
if len(updates) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
var rtn []any
|
||||
for _, obj := range updates {
|
||||
if obj == nil {
|
||||
continue
|
||||
}
|
||||
jmap, err := waveobj.ToJsonMap(obj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error converting object to JSON: %w", err)
|
||||
}
|
||||
rtn = append(rtn, jmap)
|
||||
updateArr := make([]wstore.WaveObjUpdate, 0, len(updates))
|
||||
for _, update := range updates {
|
||||
updateArr = append(updateArr, update)
|
||||
}
|
||||
jval, err := json.Marshal(updateArr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error converting updates to JSON: %w", err)
|
||||
}
|
||||
if rtnVal == nil {
|
||||
rtnVal = make(map[string]any)
|
||||
}
|
||||
rtnVal["updates"] = rtn
|
||||
rtnVal["updates"] = json.RawMessage(jval)
|
||||
return rtnVal, nil
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,6 @@ const (
|
||||
OTypeKeyName = "otype"
|
||||
OIDKeyName = "oid"
|
||||
VersionKeyName = "version"
|
||||
DeletedKeyName = "deleted"
|
||||
|
||||
OIDGoFieldName = "OID"
|
||||
VersionGoFieldName = "Version"
|
||||
@ -33,15 +32,6 @@ type WaveObj interface {
|
||||
GetOType() string // should not depend on object state (should work with nil value)
|
||||
}
|
||||
|
||||
type WaveObjTombstone struct {
|
||||
OType string `json:"otype"`
|
||||
OID string `json:"oid"`
|
||||
}
|
||||
|
||||
func (w *WaveObjTombstone) GetOType() string {
|
||||
return w.OType
|
||||
}
|
||||
|
||||
type waveObjDesc struct {
|
||||
RType reflect.Type
|
||||
OIDField reflect.StructField
|
||||
@ -103,9 +93,6 @@ func getWaveObjDesc(otype string) *waveObjDesc {
|
||||
}
|
||||
|
||||
func GetOID(waveObj WaveObj) string {
|
||||
if tomb, ok := waveObj.(*WaveObjTombstone); ok {
|
||||
return tomb.OID
|
||||
}
|
||||
desc := getWaveObjDesc(waveObj.GetOType())
|
||||
if desc == nil {
|
||||
return ""
|
||||
@ -114,10 +101,6 @@ func GetOID(waveObj WaveObj) string {
|
||||
}
|
||||
|
||||
func SetOID(waveObj WaveObj, oid string) {
|
||||
if tomb, ok := waveObj.(*WaveObjTombstone); ok {
|
||||
tomb.OID = oid
|
||||
return
|
||||
}
|
||||
desc := getWaveObjDesc(waveObj.GetOType())
|
||||
if desc == nil {
|
||||
return
|
||||
@ -126,9 +109,6 @@ func SetOID(waveObj WaveObj, oid string) {
|
||||
}
|
||||
|
||||
func GetVersion(waveObj WaveObj) int {
|
||||
if _, ok := waveObj.(*WaveObjTombstone); ok {
|
||||
return 0
|
||||
}
|
||||
desc := getWaveObjDesc(waveObj.GetOType())
|
||||
if desc == nil {
|
||||
return 0
|
||||
@ -137,9 +117,6 @@ func GetVersion(waveObj WaveObj) int {
|
||||
}
|
||||
|
||||
func SetVersion(waveObj WaveObj, version int) {
|
||||
if _, ok := waveObj.(*WaveObjTombstone); ok {
|
||||
return
|
||||
}
|
||||
desc := getWaveObjDesc(waveObj.GetOType())
|
||||
if desc == nil {
|
||||
return
|
||||
@ -161,10 +138,6 @@ func ToJsonMap(w WaveObj) (map[string]any, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, ok := w.(*WaveObjTombstone); ok {
|
||||
m[DeletedKeyName] = true
|
||||
return m, nil
|
||||
}
|
||||
m[OTypeKeyName] = w.GetOType()
|
||||
m[OIDKeyName] = GetOID(w)
|
||||
m[VersionKeyName] = GetVersion(w)
|
||||
@ -179,39 +152,12 @@ func ToJson(w WaveObj) ([]byte, error) {
|
||||
return json.Marshal(m)
|
||||
}
|
||||
|
||||
func getMapBoolVal(m map[string]any, key string) bool {
|
||||
val, ok := m[key].(bool)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func getMapStringVal(m map[string]any, key string) string {
|
||||
val, ok := m[key].(string)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func IsTombstone(w WaveObj) bool {
|
||||
_, ok := w.(*WaveObjTombstone)
|
||||
return ok
|
||||
}
|
||||
|
||||
func FromJson(data []byte) (WaveObj, error) {
|
||||
var m map[string]any
|
||||
err := json.Unmarshal(data, &m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if getMapBoolVal(m, DeletedKeyName) {
|
||||
return &WaveObjTombstone{
|
||||
OType: getMapStringVal(m, OTypeKeyName),
|
||||
OID: getMapStringVal(m, OIDKeyName),
|
||||
}, nil
|
||||
}
|
||||
otype, ok := m[OTypeKeyName].(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("missing otype")
|
||||
@ -328,13 +274,12 @@ func generateTSTypeInternal(rtype reflect.Type) (string, []reflect.Type) {
|
||||
if tsRename, ok := tsRenameMap[tsTypeName]; ok {
|
||||
tsTypeName = tsRename
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf("type %s = {\n", tsTypeName))
|
||||
var isWaveObj bool
|
||||
if rtype.Implements(waveObjType) || reflect.PointerTo(rtype).Implements(waveObjType) {
|
||||
isWaveObj = true
|
||||
buf.WriteString(fmt.Sprintf(" %s: string;\n", OTypeKeyName))
|
||||
buf.WriteString(fmt.Sprintf(" %s: string;\n", OIDKeyName))
|
||||
buf.WriteString(fmt.Sprintf(" %s: number;\n", VersionKeyName))
|
||||
buf.WriteString(fmt.Sprintf("type %s = WaveObj & {\n", tsTypeName))
|
||||
} else {
|
||||
buf.WriteString(fmt.Sprintf("type %s = {\n", tsTypeName))
|
||||
}
|
||||
var subTypes []reflect.Type
|
||||
for i := 0; i < rtype.NumField(); i++ {
|
||||
|
@ -6,6 +6,7 @@ package wstore
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"reflect"
|
||||
@ -25,7 +26,7 @@ func init() {
|
||||
}
|
||||
|
||||
type contextUpdatesType struct {
|
||||
UpdatesStack []map[waveobj.ORef]waveobj.WaveObj
|
||||
UpdatesStack []map[waveobj.ORef]WaveObjUpdate
|
||||
}
|
||||
|
||||
func dumpUpdateStack(updates *contextUpdatesType) {
|
||||
@ -47,11 +48,11 @@ func ContextWithUpdates(ctx context.Context) context.Context {
|
||||
return ctx
|
||||
}
|
||||
return context.WithValue(ctx, waveObjUpdateKey, &contextUpdatesType{
|
||||
UpdatesStack: []map[waveobj.ORef]waveobj.WaveObj{make(map[waveobj.ORef]waveobj.WaveObj)},
|
||||
UpdatesStack: []map[waveobj.ORef]WaveObjUpdate{make(map[waveobj.ORef]WaveObjUpdate)},
|
||||
})
|
||||
}
|
||||
|
||||
func ContextGetUpdates(ctx context.Context) map[waveobj.ORef]waveobj.WaveObj {
|
||||
func ContextGetUpdates(ctx context.Context) map[waveobj.ORef]WaveObjUpdate {
|
||||
updatesVal := ctx.Value(waveObjUpdateKey)
|
||||
if updatesVal == nil {
|
||||
return nil
|
||||
@ -60,7 +61,7 @@ func ContextGetUpdates(ctx context.Context) map[waveobj.ORef]waveobj.WaveObj {
|
||||
if len(updates.UpdatesStack) == 1 {
|
||||
return updates.UpdatesStack[0]
|
||||
}
|
||||
rtn := make(map[waveobj.ORef]waveobj.WaveObj)
|
||||
rtn := make(map[waveobj.ORef]WaveObjUpdate)
|
||||
for _, update := range updates.UpdatesStack {
|
||||
for k, v := range update {
|
||||
rtn[k] = v
|
||||
@ -69,7 +70,7 @@ func ContextGetUpdates(ctx context.Context) map[waveobj.ORef]waveobj.WaveObj {
|
||||
return rtn
|
||||
}
|
||||
|
||||
func ContextGetUpdate(ctx context.Context, oref waveobj.ORef) waveobj.WaveObj {
|
||||
func ContextGetUpdate(ctx context.Context, oref waveobj.ORef) *WaveObjUpdate {
|
||||
updatesVal := ctx.Value(waveObjUpdateKey)
|
||||
if updatesVal == nil {
|
||||
return nil
|
||||
@ -77,23 +78,23 @@ func ContextGetUpdate(ctx context.Context, oref waveobj.ORef) waveobj.WaveObj {
|
||||
updates := updatesVal.(*contextUpdatesType)
|
||||
for idx := len(updates.UpdatesStack) - 1; idx >= 0; idx-- {
|
||||
if obj, ok := updates.UpdatesStack[idx][oref]; ok {
|
||||
return obj
|
||||
return &obj
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ContextAddUpdate(ctx context.Context, obj waveobj.WaveObj) {
|
||||
func ContextAddUpdate(ctx context.Context, update WaveObjUpdate) {
|
||||
updatesVal := ctx.Value(waveObjUpdateKey)
|
||||
if updatesVal == nil {
|
||||
return
|
||||
}
|
||||
updates := updatesVal.(*contextUpdatesType)
|
||||
oref := waveobj.ORef{
|
||||
OType: obj.GetOType(),
|
||||
OID: waveobj.GetOID(obj),
|
||||
OType: update.OType,
|
||||
OID: update.OID,
|
||||
}
|
||||
updates.UpdatesStack[len(updates.UpdatesStack)-1][oref] = obj
|
||||
updates.UpdatesStack[len(updates.UpdatesStack)-1][oref] = update
|
||||
}
|
||||
|
||||
func ContextUpdatesBeginTx(ctx context.Context) context.Context {
|
||||
@ -102,7 +103,7 @@ func ContextUpdatesBeginTx(ctx context.Context) context.Context {
|
||||
return ctx
|
||||
}
|
||||
updates := updatesVal.(*contextUpdatesType)
|
||||
updates.UpdatesStack = append(updates.UpdatesStack, make(map[waveobj.ORef]waveobj.WaveObj))
|
||||
updates.UpdatesStack = append(updates.UpdatesStack, make(map[waveobj.ORef]WaveObjUpdate))
|
||||
return ctx
|
||||
}
|
||||
|
||||
@ -136,6 +137,36 @@ func ContextUpdatesRollbackTx(ctx context.Context) {
|
||||
updates.UpdatesStack = updates.UpdatesStack[:len(updates.UpdatesStack)-1]
|
||||
}
|
||||
|
||||
type WaveObjTombstone struct {
|
||||
OType string `json:"otype"`
|
||||
OID string `json:"oid"`
|
||||
}
|
||||
|
||||
const (
|
||||
UpdateType_Update = "update"
|
||||
UpdateType_Delete = "delete"
|
||||
)
|
||||
|
||||
type WaveObjUpdate struct {
|
||||
UpdateType string `json:"updatetype"`
|
||||
OType string `json:"otype"`
|
||||
OID string `json:"oid"`
|
||||
Obj waveobj.WaveObj `json:"obj,omitempty"`
|
||||
}
|
||||
|
||||
func (update WaveObjUpdate) MarshalJSON() ([]byte, error) {
|
||||
rtn := make(map[string]any)
|
||||
rtn["updatetype"] = update.UpdateType
|
||||
rtn["otype"] = update.OType
|
||||
rtn["oid"] = update.OID
|
||||
var err error
|
||||
rtn["obj"], err = waveobj.ToJsonMap(update.Obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return json.Marshal(rtn)
|
||||
}
|
||||
|
||||
type UIContext struct {
|
||||
WindowId string `json:"windowid"`
|
||||
}
|
||||
|
@ -159,15 +159,12 @@ func DBDelete(ctx context.Context, otype string, id string) error {
|
||||
table := tableNameFromOType(otype)
|
||||
query := fmt.Sprintf("DELETE FROM %s WHERE oid = ?", table)
|
||||
tx.Exec(query, id)
|
||||
ContextAddUpdate(ctx, &waveobj.WaveObjTombstone{OType: otype, OID: id})
|
||||
ContextAddUpdate(ctx, WaveObjUpdate{UpdateType: UpdateType_Delete, OType: otype, OID: id})
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func DBUpdate(ctx context.Context, val waveobj.WaveObj) error {
|
||||
if waveobj.IsTombstone(val) {
|
||||
return fmt.Errorf("cannot update deleted object")
|
||||
}
|
||||
oid := waveobj.GetOID(val)
|
||||
if oid == "" {
|
||||
return fmt.Errorf("cannot update %T value with empty id", val)
|
||||
@ -181,15 +178,12 @@ func DBUpdate(ctx context.Context, val waveobj.WaveObj) error {
|
||||
query := fmt.Sprintf("UPDATE %s SET data = ?, version = version+1 WHERE oid = ? RETURNING version", table)
|
||||
newVersion := tx.GetInt(query, jsonData, oid)
|
||||
waveobj.SetVersion(val, newVersion)
|
||||
ContextAddUpdate(ctx, val)
|
||||
ContextAddUpdate(ctx, WaveObjUpdate{UpdateType: UpdateType_Update, OType: val.GetOType(), OID: oid, Obj: val})
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func DBInsert(ctx context.Context, val waveobj.WaveObj) error {
|
||||
if waveobj.IsTombstone(val) {
|
||||
return fmt.Errorf("cannot insert deleted object")
|
||||
}
|
||||
oid := waveobj.GetOID(val)
|
||||
if oid == "" {
|
||||
return fmt.Errorf("cannot insert %T value with empty id", val)
|
||||
@ -203,7 +197,7 @@ func DBInsert(ctx context.Context, val waveobj.WaveObj) error {
|
||||
waveobj.SetVersion(val, 1)
|
||||
query := fmt.Sprintf("INSERT INTO %s (oid, version, data) VALUES (?, ?, ?)", table)
|
||||
tx.Exec(query, oid, 1, jsonData)
|
||||
ContextAddUpdate(ctx, val)
|
||||
ContextAddUpdate(ctx, WaveObjUpdate{UpdateType: UpdateType_Update, OType: val.GetOType(), OID: oid, Obj: val})
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user