@@ -3,10 +3,12 @@ define([
33 './StagedChanges' ,
44 './CreatedNode' ,
55 'common/util/assert' ,
6+ 'underscore' ,
67] , function (
78 StagedChanges ,
89 CreatedNode ,
910 assert ,
11+ _ ,
1012) {
1113 function TwoPhaseCore ( logger , core ) {
1214 this . logger = logger ;
@@ -30,19 +32,110 @@ define([
3032
3133 passToCore ( 'persist' ) ;
3234 passToCore ( 'loadRoot' ) ;
33- passToCore ( 'loadByPath' ) ;
3435 passToCore ( 'loadSubTree' ) ;
35- passToCore ( 'getPointerPath' ) ;
3636 passToCore ( 'getParent' ) ;
3737 passToCore ( 'getNamespace' ) ;
38- passToCore ( 'getMetaType' ) ;
3938 passToCore ( 'getChildrenMeta' ) ;
4039 passToCore ( 'getChildrenPaths' ) ;
4140 passToCore ( 'addMember' ) ;
4241 passToCore ( 'isMetaNode' ) ;
4342 passToCore ( 'getOwnRegistry' ) ;
4443 passToCore ( 'getOwnAttribute' ) ;
4544 passToCore ( 'getAttributeNames' ) ;
45+ passToCore ( 'getValidAttributeNames' ) ;
46+ passToCore ( 'getValidPointerNames' ) ;
47+
48+ TwoPhaseCore . prototype . loadByPath = async function ( node , id ) {
49+ ensureNode ( node , 'loadByPath' ) ;
50+ if ( CreatedNode . isCreateId ( id ) ) {
51+ const changesets = this . queuedChanges . concat ( this ) ;
52+ for ( let i = 0 ; i < changesets . length ; i ++ ) {
53+ const createdNodes = changesets [ i ] . createdNodes ;
54+ const node = createdNodes . find ( node => node . id === id ) ;
55+ if ( node ) {
56+ return node ;
57+ }
58+ }
59+ } else {
60+ return this . core . loadByPath ( node , id ) ;
61+ }
62+ } ;
63+
64+ TwoPhaseCore . prototype . getMetaType = function ( node ) {
65+ ensureNode ( node , 'getMetaType' ) ;
66+ while ( node instanceof CreatedNode ) {
67+ node = node . base ;
68+ }
69+ return this . core . getMetaType ( node ) ;
70+ } ;
71+
72+ TwoPhaseCore . prototype . getOwnAttributeNames = function ( node ) {
73+ ensureNode ( node , 'getOwnAttributeNames' ) ;
74+ const isNewNode = node instanceof CreatedNode ;
75+ let names = [ ] ;
76+ if ( ! isNewNode ) {
77+ names = this . core . getOwnAttributeNames ( node ) ;
78+ }
79+
80+ function updateAttributeNames ( changes = { attr :{ } } , names ) {
81+ const [ setAttrs , delAttrs ] = Object . entries ( changes . attr )
82+ . reduce ( ( setAndDel , attr ) => {
83+ const [ sets , dels ] = setAndDel ;
84+ const [ name , value ] = attr ;
85+ if ( value === null ) {
86+ dels . push ( name ) ;
87+ } else {
88+ sets . push ( name ) ;
89+ }
90+ return setAndDel ;
91+ } , [ [ ] , [ ] ] ) ;
92+ names = _ . union ( names , setAttrs ) ;
93+ names = _ . without ( names , ...delAttrs ) ;
94+ return names ;
95+ }
96+
97+ this . _forAllNodeChanges (
98+ node ,
99+ changes => names = updateAttributeNames ( changes , names )
100+ ) ;
101+
102+ return names ;
103+ } ;
104+
105+ TwoPhaseCore . prototype . getOwnPointerNames = function ( node ) {
106+ ensureNode ( node , 'getOwnPointerNames' ) ;
107+ const isNewNode = node instanceof CreatedNode ;
108+ let names = [ ] ;
109+ if ( ! isNewNode ) {
110+ names = this . core . getOwnPointerNames ( node ) ;
111+ }
112+
113+ function updatePointerNames ( changes = { ptr :{ } } , names ) {
114+ const ptrNames = Object . keys ( changes . ptr ) ;
115+ return _ . union ( names , ptrNames ) ;
116+ }
117+
118+ this . _forAllNodeChanges (
119+ node ,
120+ changes => names = updatePointerNames ( changes , names )
121+ ) ;
122+
123+ return names ;
124+ } ;
125+
126+ TwoPhaseCore . prototype . _forAllNodeChanges = function ( node , fn ) {
127+ const nodeId = this . getPath ( node ) ;
128+ for ( let i = 0 ; i < this . queuedChanges . length ; i ++ ) {
129+ const changes = this . queuedChanges [ i ] . getNodeEdits ( nodeId ) ;
130+ if ( changes ) {
131+ fn ( changes ) ;
132+ }
133+ }
134+ const changes = this . getChangesForNode ( node ) ;
135+ if ( changes ) {
136+ fn ( changes ) ;
137+ }
138+ } ;
46139
47140 TwoPhaseCore . prototype . getBase = function ( node ) {
48141 ensureNode ( node , 'getBase' ) ;
@@ -100,6 +193,17 @@ define([
100193 return this . changes [ nodeId ] ;
101194 } ;
102195
196+ TwoPhaseCore . prototype . copyNode = function ( node , parent ) {
197+ assert ( node , 'Cannot copy invalid node' ) ;
198+ assert ( parent , 'Cannot copy node without parent' ) ;
199+ ensureNode ( node , 'copyNode' ) ;
200+ ensureNode ( parent , 'copyNode' ) ;
201+
202+ const newNode = new CreatedNode ( node , parent ) ;
203+ this . createdNodes . push ( newNode ) ;
204+ return newNode ;
205+ } ;
206+
103207 TwoPhaseCore . prototype . createNode = function ( desc ) {
104208 const { parent, base} = desc ;
105209 assert ( parent , 'Cannot create node without parent' ) ;
@@ -128,7 +232,9 @@ define([
128232 . reduce ( ( l1 , l2 ) => l1 . concat ( l2 ) ) ;
129233
130234 let children = allCreatedNodes . filter ( node => getId ( node . parent ) === nodeId ) ;
131- if ( ! ( node instanceof CreatedNode ) ) {
235+ if ( node instanceof CreatedNode ) {
236+ children = children . concat ( await node . getInheritedChildren ( this . core ) ) ;
237+ } else {
132238 children = children . concat ( await this . core . loadChildren ( node ) ) ;
133239 }
134240 return children ;
@@ -151,6 +257,28 @@ define([
151257 changes . attr [ attr ] = value ;
152258 } ;
153259
260+ TwoPhaseCore . prototype . getPointerPath = function ( node , name ) {
261+ ensureNode ( node , 'getPointerPath' ) ;
262+ let path = null ;
263+ if ( ! ( node instanceof CreatedNode ) ) {
264+ path = this . core . getPointerPath ( node , name ) ;
265+ } else if ( name === 'base' ) {
266+ path = this . getPath ( node . base ) ;
267+ }
268+
269+ this . _forAllNodeChanges (
270+ node ,
271+ changes => {
272+ if ( changes . ptr . hasOwnProperty ( name ) ) {
273+ const target = changes . ptr [ name ] ;
274+ path = target && this . getPath ( target ) ;
275+ }
276+ }
277+ ) ;
278+
279+ return path ;
280+ } ;
281+
154282 TwoPhaseCore . prototype . getAttribute = function ( node , attr ) {
155283 ensureNode ( node , 'getAttribute' ) ;
156284 var nodeId ;
0 commit comments