返回 DeepSeek-Reasonix
read_versions.go
根目录 / desktop / internal / workspacestate / read_versions.go
1 package workspacestate
2
3 import (
4 "crypto/sha256"
5 "encoding/hex"
6 "encoding/json"
7 )
8
9 // ReadVersions contains only immutable invalidation tokens. It does not grant
10 // execution authority or retain a second mutable copy of registry records.
11 // Construct once per verified publication, then query only visible identities.
12 type ReadVersions struct {
13 sources map[string]string
14 sessions map[string]string
15 }
16
17 type sourceReadBinding struct {
18 Mapping SourceMapping
19 State SessionState
20 }
21
22 func readVersion(value any) string {
23 body, _ := json.Marshal(value)
24 digest := sha256.Sum256(body)
25 return hex.EncodeToString(digest[:])
26 }
27
28 // NewReadVersions reads the supplied snapshot without retaining or changing its
29 // mutable fields. Source aliases are resolved once per distinct saved path.
30 func NewReadVersions(state State) *ReadVersions {
31 v := &ReadVersions{sources: map[string]string{}, sessions: map[string]string{}}
32 byPath := map[string]map[string]sourceReadBinding{}
33 bySession := map[string]map[string]SourceMapping{}
34 pathKeys := map[string]string{}
35 for key, mapping := range state.SourceMappings {
36 pathKey, known := pathKeys[mapping.Path]
37 if !known {
38 pathKey, _ = sourcePathKey(mapping.Path)
39 pathKeys[mapping.Path] = pathKey
40 }
41 if pathKey != "" {
42 if byPath[pathKey] == nil {
43 byPath[pathKey] = map[string]sourceReadBinding{}
44 }
45 byPath[pathKey][key] = sourceReadBinding{mapping, state.SessionStates[mapping.SessionID]}
46 }
47 if bySession[mapping.SessionID] == nil {
48 bySession[mapping.SessionID] = map[string]SourceMapping{}
49 }
50 bySession[mapping.SessionID][key] = mapping
51 }
52 for path, bindings := range byPath {
53 v.sources[path] = readVersion(bindings)
54 }
55 for id, status := range state.SessionStates {
56 v.sessions[id] = readVersion([]any{status, bySession[id]})
57 }
58 // Preserve mapping-only identities as well. Older registries can omit the
59 // explicit lifecycle entry until their first owned mutation.
60 for id, mappings := range bySession {
61 if _, exists := v.sessions[id]; !exists {
62 v.sessions[id] = readVersion([]any{SessionState{}, mappings})
63 }
64 }
65 return v
66 }
67
68 func (v *ReadVersions) Source(path string) (string, error) {
69 if len(v.sources) == 0 {
70 return "", nil
71 }
72 key, err := sourcePathKey(path)
73 if err != nil {
74 return "", err
75 }
76 return v.sources[key], nil
77 }
78
79 func (v *ReadVersions) Session(id string) string { return v.sessions[id] }
80
81 func (r *ReadSnapshot) ReadVersions() *ReadVersions { return r.versions }
82
82 lines GO