1+ import { Hash , HashedObject , HashedSet , MutableObject , MutationOp } from '../model' ;
2+ import { HistoryFragment } from '../history' ;
3+ import { MultiMap } from 'util/multimap' ;
4+ import { ArrayMap } from 'util/arraymap' ;
5+
6+ class StateTransition < T extends MutableObject > extends MutationOp {
7+
8+ static className = 'hss/v0/HistoryLog/StateTransition' ;
9+
10+ mutableHash ?: Hash ;
11+ start ?: Hash ;
12+ end ?: Hash ;
13+
14+ info ?: any ;
15+
16+ constructor ( log : HistoryLog < T > , mutableHash ?: Hash , start ?: Hash , end ?: Hash , info ?: any ) {
17+ super ( log ) ;
18+
19+ this . mutableHash = mutableHash ;
20+ this . start = start ;
21+ this . end = end ;
22+
23+ this . info = info ;
24+ }
25+
26+ getClassName ( ) : string {
27+ return StateTransition . className ;
28+ }
29+
30+ init ( ) : void {
31+
32+ }
33+
34+ async validate ( references : Map < string , HashedObject > ) : Promise < boolean > {
35+ return await super . validate ( references ) &&
36+ typeof ( this . mutableHash ) === 'string' &&
37+ ( this . start === undefined || typeof ( this . start ) === 'string' ) &&
38+ typeof ( this . end ) === 'string' &&
39+ ( this . info === undefined || HashedObject . isLiteral ( this . info ) ) ;
40+ }
41+ }
42+
43+ class VerifiedStateTransition < T extends MutableObject > extends StateTransition < T > {
44+
45+ static className = 'hss/v0/HistoryLog/VerifiedStateTransition' ;
46+
47+ mutable ?: T ;
48+ ops ?: HashedSet < MutationOp > ;
49+
50+ constructor ( log : HistoryLog < T > , mutable ?: T , start ?: Hash , end ?: Hash , info ?: any , ops ?: Map < Hash , MutationOp > ) {
51+ super ( log , mutable ?. getLastHash ( ) , start , end , info ) ;
52+
53+ this . mutable = mutable ;
54+ this . ops = new HashedSet ( ops ?. values ( ) ) ;
55+ }
56+ getClassName ( ) : string {
57+ return VerifiedStateTransition . className ;
58+ }
59+
60+ async validate ( references : Map < string , HashedObject > ) : Promise < boolean > {
61+ if ( ! ( await super . validate ( references ) ) ) {
62+ return false ;
63+ }
64+
65+ if ( this . mutable ?. getLastHash ( ) !== this . mutableHash ) {
66+ return false ;
67+ }
68+
69+ const frag = new HistoryFragment ( this . mutableHash as Hash ) ;
70+
71+ if ( ! ( this . ops instanceof HashedSet ) ) {
72+ return false ;
73+ }
74+
75+ for ( const op of this . ops ?. values ( ) ) {
76+ if ( ! ( op instanceof MutationOp ) ) {
77+ return false ;
78+ }
79+
80+ if ( ! ( op . getTargetObject ( ) . getLastHash ( ) !== this . mutable ?. getLastHash ( ) ) ) {
81+ return false ;
82+ }
83+
84+ const opHeader = await this . mutable ?. getOpHeader ( op . getLastHash ( ) ) ;
85+
86+ if ( opHeader === undefined ) {
87+ return false ;
88+ }
89+
90+ frag . add ( opHeader ) ;
91+ }
92+
93+ const start = new HashedSet < Hash > ( frag . getStartingOps ( ) . values ( ) ) ;
94+ const end = new HashedSet < Hash > ( frag . getTerminalOps ( ) . values ( ) ) ;
95+
96+ if ( this . start !== start . hash ( ) ) {
97+ return false ;
98+ }
99+
100+ if ( this . end !== end . hash ( ) ) {
101+ return false ;
102+ }
103+
104+ return true ;
105+ }
106+ }
107+
108+ class HistoryLogEntry < T extends MutableObject > extends MutationOp {
109+
110+ static className = 'hss/v0/HistoryLog/Entry' ;
111+
112+ transitions ?: HashedSet < StateTransition < T > > ;
113+
114+ constructor ( transitions ?: HashedSet < StateTransition < T > > ) {
115+ super ( ) ;
116+ this . transitions = transitions ;
117+ }
118+
119+ getClassName ( ) : string {
120+ return HistoryLogEntry . className ;
121+ }
122+
123+ init ( ) : void {
124+
125+ }
126+
127+ async validate ( references : Map < string , HashedObject > ) : Promise < boolean > {
128+
129+ if ( ! ( await super . validate ( references ) ) ) {
130+ return false ;
131+ }
132+
133+ if ( ! ( this . transitions instanceof HashedSet ) ) {
134+ return false ;
135+ }
136+
137+ //const seen = new Set<Hash>();
138+
139+ for ( const transition of this . transitions . values ( ) ) {
140+
141+ if ( ! ( transition instanceof StateTransition ) ) {
142+ return false ;
143+ }
144+
145+ /*if (seen.has(transition.mutable as Hash)) {
146+ return false;
147+ }
148+
149+ seen.add(transition.mutable as Hash);*/
150+ }
151+
152+ return true ;
153+ }
154+
155+ }
156+
157+ abstract class HistoryLog < T extends MutableObject > extends MutableObject {
158+
159+ _transitions : ArrayMap < Hash , StateTransition < T > > ;
160+ _pending : ArrayMap < Hash , StateTransition < T > > ;
161+
162+ _faulted : MultiMap < Hash , StateTransition < T > > ;
163+
164+ constructor ( ) {
165+ super ( [ StateTransition . className , VerifiedStateTransition . className , HistoryLogEntry . className ] , { supportsUndo : false } ) ;
166+
167+ this . _transitions = new ArrayMap ( false ) ;
168+ this . _pending = new ArrayMap ( false ) ;
169+
170+ this . _faulted = new MultiMap ( ) ;
171+ }
172+
173+ async attemptTransition ( fragment : HistoryFragment , timeout ?: number ) : Promise < HistoryLogEntry < T > > {
174+
175+ timeout ;
176+
177+ this . createAttemptTransitionOp ( fragment ) ;
178+
179+ throw new Error ( 'Unfinished' ) ;
180+ }
181+ async attemptVerifiedTransition ( fragment : HistoryFragment , mut : T , ops : Map < Hash , MutationOp > , timeout ?: number ) : Promise < boolean > {
182+
183+ timeout ;
184+
185+ this . createAttemptTransitionOp ( fragment , mut , ops ) ;
186+
187+ throw new Error ( 'Unfinished' ) ;
188+ }
189+
190+ private async createAttemptTransitionOp ( fragment : HistoryFragment , mut ?: T , ops ?: Map < Hash , MutationOp > ) {
191+ fragment ; mut ; ops ;
192+ throw new Error ( 'unfinished' ) ;
193+ }
194+
195+ getLastTransition ( mut : Hash ) : ( StateTransition < T > | undefined ) {
196+
197+ const txs = this . _transitions . get ( mut ) ;
198+
199+ if ( txs . length > 0 ) {
200+ return txs [ - 1 ] ;
201+ } else {
202+ return undefined ;
203+ }
204+
205+ }
206+
207+ mutate ( op : MutationOp , valid : boolean , cascade : boolean ) : Promise < boolean > {
208+
209+ valid ; cascade ;
210+
211+ if ( op instanceof StateTransition ) {
212+
213+ this . _pending . add ( op . mutableHash as Hash , op ) ;
214+ } else if ( op instanceof HistoryLogEntry ) {
215+
216+ }
217+
218+ throw new Error ( 'unfinished' )
219+ }
220+
221+ getMutableContents ( ) : MultiMap < string , HashedObject > {
222+ return new MultiMap ( ) ;
223+ }
224+
225+ getMutableContentByHash ( _hash : string ) : Set < HashedObject > {
226+ return new Set ( ) ;
227+ }
228+
229+ getClassName ( ) : string {
230+ throw new Error ( 'Method not implemented.' ) ;
231+ }
232+
233+ init ( ) : void {
234+ throw new Error ( 'Method not implemented.' ) ;
235+ }
236+
237+ validate ( _references : Map < string , HashedObject > ) : Promise < boolean > {
238+ throw new Error ( 'Method not implemented.' ) ;
239+ }
240+
241+ }
242+
243+ export { HistoryLog } ;
0 commit comments