client-py connected
This commit is contained in:
@@ -66,7 +66,8 @@ export type {
|
||||
PathTriggerHandler,
|
||||
PathTriggerContext,
|
||||
ChartState,
|
||||
ChartStore,
|
||||
ShapesStore,
|
||||
IndicatorsStore,
|
||||
ChannelState,
|
||||
ChannelInfo,
|
||||
WorkspaceStores,
|
||||
|
||||
@@ -404,4 +404,28 @@ export class SyncRegistry {
|
||||
}
|
||||
return states;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get patches since a given sequence number for a store.
|
||||
* Returns empty array if no patches available since that sequence.
|
||||
*/
|
||||
getPatchesSince(storeName: string, sinceSeq: number): JsonPatchOp[] | null {
|
||||
const entry = this.entries.get(storeName);
|
||||
if (!entry) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const catchupPatches = entry.getCatchupPatches(sinceSeq);
|
||||
if (catchupPatches === null) {
|
||||
return null; // History not available
|
||||
}
|
||||
|
||||
// Flatten all patches into a single array
|
||||
const allPatches: JsonPatchOp[] = [];
|
||||
for (const { patch } of catchupPatches) {
|
||||
allPatches.push(...patch);
|
||||
}
|
||||
|
||||
return allPatches;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,17 +84,19 @@ export const DEFAULT_STORES: StoreConfig[] = [
|
||||
symbol: 'BINANCE:BTC/USDT',
|
||||
start_time: null,
|
||||
end_time: null,
|
||||
interval: '15',
|
||||
period: '15',
|
||||
selected_shapes: [],
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'chartStore',
|
||||
name: 'shapes',
|
||||
persistent: true,
|
||||
initialState: () => ({
|
||||
drawings: {},
|
||||
templates: {},
|
||||
}),
|
||||
initialState: () => ({}),
|
||||
},
|
||||
{
|
||||
name: 'indicators',
|
||||
persistent: true,
|
||||
initialState: () => ({}),
|
||||
},
|
||||
{
|
||||
name: 'channelState',
|
||||
@@ -198,22 +200,70 @@ export interface PathTrigger {
|
||||
*/
|
||||
export interface ChartState {
|
||||
symbol: string;
|
||||
start_time: number | null;
|
||||
end_time: number | null;
|
||||
interval: string;
|
||||
selected_shapes: string[];
|
||||
start_time: number | null; // unix timestamp
|
||||
end_time: number | null; // unix timestamp
|
||||
period: string; // OHLC duration (e.g., '15' for 15 minutes)
|
||||
selected_shapes: string[]; // list of shape ID's
|
||||
}
|
||||
|
||||
/**
|
||||
* Chart store - persistent, stores drawings and templates.
|
||||
* Control point for shapes (drawings/annotations).
|
||||
*/
|
||||
export interface ChartStore {
|
||||
drawings: Record<string, unknown>;
|
||||
templates: Record<string, unknown>;
|
||||
export interface ControlPoint {
|
||||
time: number; // unix timestamp
|
||||
price: number;
|
||||
channel?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shape (drawing/annotation) on TradingView chart.
|
||||
*/
|
||||
export interface Shape {
|
||||
id: string;
|
||||
type: string;
|
||||
points: ControlPoint[];
|
||||
color?: string;
|
||||
line_width?: number;
|
||||
line_style?: string;
|
||||
properties?: Record<string, any>;
|
||||
symbol?: string;
|
||||
created_at?: number;
|
||||
modified_at?: number;
|
||||
original_id?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shapes store - persistent, stores TradingView drawings and annotations.
|
||||
*/
|
||||
export type ShapesStore = Record<string, Shape>;
|
||||
|
||||
/**
|
||||
* Indicator instance on TradingView chart.
|
||||
*/
|
||||
export interface IndicatorInstance {
|
||||
id: string;
|
||||
talib_name: string;
|
||||
instance_name: string;
|
||||
parameters: Record<string, any>;
|
||||
tv_study_id?: string;
|
||||
tv_indicator_name?: string;
|
||||
tv_inputs?: Record<string, any>;
|
||||
visible: boolean;
|
||||
pane: string;
|
||||
symbol?: string;
|
||||
created_at?: number;
|
||||
modified_at?: number;
|
||||
original_id?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicators store - persistent, stores TradingView studies/indicators.
|
||||
*/
|
||||
export type IndicatorsStore = Record<string, IndicatorInstance>;
|
||||
|
||||
/**
|
||||
* Channel state - transient, tracks connected channels.
|
||||
* NOTE: This store is gateway-only and should NOT be synced to web clients.
|
||||
*/
|
||||
export interface ChannelState {
|
||||
connected: Record<string, ChannelInfo>;
|
||||
@@ -233,7 +283,8 @@ export interface ChannelInfo {
|
||||
*/
|
||||
export interface WorkspaceStores {
|
||||
chartState: ChartState;
|
||||
chartStore: ChartStore;
|
||||
shapes: ShapesStore;
|
||||
indicators: IndicatorsStore;
|
||||
channelState: ChannelState;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
@@ -271,6 +271,53 @@ export class WorkspaceManager {
|
||||
return this.registry.getStoreNames();
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize entire workspace state as JSON.
|
||||
*/
|
||||
serializeState(): string {
|
||||
const state: Record<string, unknown> = {};
|
||||
|
||||
for (const storeConfig of this.stores) {
|
||||
const storeState = this.registry.getState(storeConfig.name);
|
||||
if (storeState !== undefined) {
|
||||
state[storeConfig.name] = storeState;
|
||||
}
|
||||
}
|
||||
|
||||
return JSON.stringify(state, null, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the highest sequence number across all stores.
|
||||
*/
|
||||
getCurrentSeq(): number {
|
||||
let maxSeq = 0;
|
||||
for (const storeName of this.registry.getStoreNames()) {
|
||||
const seq = this.registry.getSeq(storeName);
|
||||
if (seq > maxSeq) {
|
||||
maxSeq = seq;
|
||||
}
|
||||
}
|
||||
return maxSeq;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all patches since a given sequence number across all stores.
|
||||
* Returns patches grouped by store name.
|
||||
*/
|
||||
getChangesSince(sinceSeq: number): Record<string, JsonPatchOp[]> {
|
||||
const changes: Record<string, JsonPatchOp[]> = {};
|
||||
|
||||
for (const storeConfig of this.stores) {
|
||||
const patches = this.registry.getPatchesSince(storeConfig.name, sinceSeq);
|
||||
if (patches && patches.length > 0) {
|
||||
changes[storeConfig.name] = patches;
|
||||
}
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Path Triggers
|
||||
// ===========================================================================
|
||||
|
||||
Reference in New Issue
Block a user