-
-
Notifications
You must be signed in to change notification settings - Fork 189
Expand file tree
/
Copy pathdataSlice.ts
More file actions
133 lines (112 loc) · 3.03 KB
/
dataSlice.ts
File metadata and controls
133 lines (112 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import type { StateCreator } from 'zustand'
export interface PathData {
path?: string
value: unknown
timestamp?: string
$source?: string
pgn?: string
sentence?: string
[key: string]: unknown
}
export interface RendererConfig {
module?: string
name?: string
options?: Record<string, unknown>
}
export interface MetaData {
units?: string
description?: string
renderer?: RendererConfig
[key: string]: unknown
}
export interface DataSliceState {
/** Nested data: { context: { path$source: PathData } } */
signalkData: Record<string, Record<string, PathData>>
/** Nested metadata: { context: { path: MetaData } } */
signalkMeta: Record<string, Record<string, MetaData>>
/** Version counter - increments when structure changes (new paths added) */
dataVersion: number
}
export interface DataSliceActions {
updatePath: (
context: string,
path$SourceKey: string,
pathData: PathData
) => void
updateMeta: (
context: string,
path: string,
metaData: Partial<MetaData>
) => void
getPathData: (context: string, path$SourceKey: string) => PathData | undefined
getMeta: (context: string, path: string) => MetaData | undefined
getPath$SourceKeys: (context: string) => string[]
getContexts: () => string[]
clearData: () => void
}
export type DataSlice = DataSliceState & DataSliceActions
const initialDataState: DataSliceState = {
signalkData: {},
signalkMeta: {},
dataVersion: 0
}
export const createDataSlice: StateCreator<DataSlice, [], [], DataSlice> = (
set,
get
) => ({
...initialDataState,
updatePath: (context, path$SourceKey, pathData) => {
set((state) => {
const contextData = state.signalkData[context] || {}
const isNew = !contextData[path$SourceKey]
const newContextData = {
...contextData,
[path$SourceKey]: pathData
}
const newSignalkData = {
...state.signalkData,
[context]: newContextData
}
// Increment version only for new paths
const newVersion = isNew ? state.dataVersion + 1 : state.dataVersion
return {
signalkData: newSignalkData,
dataVersion: newVersion
}
})
},
updateMeta: (context, path, metaData) => {
set((state) => {
const contextMeta = state.signalkMeta[context] || {}
const newContextMeta = {
...contextMeta,
[path]: { ...contextMeta[path], ...metaData } as MetaData
}
return {
signalkMeta: {
...state.signalkMeta,
[context]: newContextMeta
}
}
})
},
getPathData: (context, path$SourceKey) => {
const state = get()
return state.signalkData[context]?.[path$SourceKey]
},
getMeta: (context, path) => {
const state = get()
return state.signalkMeta[context]?.[path]
},
getPath$SourceKeys: (context) => {
const state = get()
return Object.keys(state.signalkData[context] || {})
},
getContexts: () => {
const state = get()
return Object.keys(state.signalkData)
},
clearData: () => {
set(initialDataState)
}
})