@@ -92,6 +92,136 @@ export interface CoreRow<TData extends RowData> {
9292 subRows : Row < TData > [ ]
9393}
9494
95+ const rowProtosByTable = new WeakMap < Table < any > , any > ( )
96+
97+
98+ /**
99+ * Creates a table-specific row prototype object to hold shared row methods, including from all the
100+ * features that have been registered on the table.
101+ */
102+ export function getRowProto < TData extends RowData > ( table : Table < TData > ) {
103+ let rowProto = rowProtosByTable . get ( table )
104+
105+ if ( ! rowProto ) {
106+ const obj : CoreRow < TData > = {
107+ // props are here only for typing; they are set on the instance at runtime
108+ id : 'unused' ,
109+ depth : 0 ,
110+ index : - 1 ,
111+ original : undefined as TData ,
112+ subRows : [ ] ,
113+ _valuesCache : { } ,
114+ _uniqueValuesCache : { } ,
115+
116+
117+ getValue ( columnId : string ) {
118+ if ( this . _valuesCache . hasOwnProperty ( columnId ) ) {
119+ return this . _valuesCache [ columnId ]
120+ }
121+
122+ const column = table . getColumn ( columnId )
123+
124+ if ( ! column ?. accessorFn ) {
125+ return undefined
126+ }
127+
128+ this . _valuesCache [ columnId ] = column . accessorFn (
129+ this . original as TData ,
130+ this . index
131+ )
132+
133+ return this . _valuesCache [ columnId ] as any
134+ } ,
135+
136+ getUniqueValues ( columnId : string ) {
137+ if ( ! this . hasOwnProperty ( '_uniqueValuesCache' ) ) {
138+ // lazy-init cache on the instance
139+ this . _uniqueValuesCache = { } ;
140+ }
141+
142+ if ( this . _uniqueValuesCache . hasOwnProperty ( columnId ) ) {
143+ return this . _uniqueValuesCache [ columnId ]
144+ }
145+
146+ const column = table . getColumn ( columnId )
147+
148+ if ( ! column ?. accessorFn ) {
149+ return undefined
150+ }
151+
152+ if ( ! column . columnDef . getUniqueValues ) {
153+ this . _uniqueValuesCache [ columnId ] = [ this . getValue ( columnId ) ]
154+ return this . _uniqueValuesCache [ columnId ]
155+ }
156+
157+ this . _uniqueValuesCache [ columnId ] = column . columnDef . getUniqueValues (
158+ this . original as TData ,
159+ this . index
160+ )
161+
162+ return this . _uniqueValuesCache [ columnId ] as any
163+ } ,
164+
165+ renderValue ( columnId : string ) {
166+ return this . getValue ( columnId ) ?? table . options . renderFallbackValue
167+ } ,
168+
169+ getLeafRows ( ) {
170+ return flattenBy ( this . subRows , d => d . subRows )
171+ } ,
172+
173+ getParentRow ( ) {
174+ return this . parentId ? table . getRow ( this . parentId , true ) : undefined
175+ } ,
176+
177+ getParentRows ( ) {
178+ let parentRows : Row < TData > [ ] = [ ]
179+ let currentRow = this
180+ while ( true ) {
181+ const parentRow = currentRow . getParentRow ( )
182+ if ( ! parentRow ) break
183+ parentRows . push ( parentRow )
184+ currentRow = parentRow
185+ }
186+ return parentRows . reverse ( )
187+ } ,
188+
189+ getAllCells : memo (
190+ function ( this : Row < TData > ) {
191+ return [ this , table . getAllLeafColumns ( ) ]
192+ } ,
193+ ( row , leafColumns ) => {
194+ return leafColumns . map ( column => {
195+ return createCell ( table , row , column , column . id )
196+ } )
197+ } ,
198+ getMemoOptions ( table . options , 'debugRows' , 'getAllCells' )
199+ ) ,
200+
201+ _getAllCellsByColumnId : memo (
202+ function ( this : Row < TData > ) {
203+ return [ this . getAllCells ( ) ]
204+ } ,
205+ allCells => {
206+ return allCells . reduce (
207+ ( acc , cell ) => {
208+ acc [ cell . column . id ] = cell
209+ return acc
210+ } ,
211+ { } as Record < string , Cell < TData , unknown > >
212+ )
213+ } ,
214+ getMemoOptions ( table . options , 'debugRows' , 'getAllCellsByColumnId' )
215+ ) ,
216+ }
217+
218+ rowProtosByTable . set ( table , obj )
219+ rowProto = obj
220+ }
221+
222+ return rowProto as CoreRow < TData >
223+ }
224+
95225export const createRow = < TData extends RowData > (
96226 table : Table < TData > ,
97227 id : string ,
@@ -101,95 +231,18 @@ export const createRow = <TData extends RowData>(
101231 subRows ?: Row < TData > [ ] ,
102232 parentId ?: string
103233) : Row < TData > => {
104- let row : CoreRow < TData > = {
234+ const row : CoreRow < TData > = Object . create ( getRowProto ( table ) )
235+ Object . assign ( row , {
105236 id,
106237 index : rowIndex ,
107238 original,
108239 depth,
109240 parentId,
110241 _valuesCache : { } ,
111- _uniqueValuesCache : { } ,
112- getValue : columnId => {
113- if ( row . _valuesCache . hasOwnProperty ( columnId ) ) {
114- return row . _valuesCache [ columnId ]
115- }
116-
117- const column = table . getColumn ( columnId )
118-
119- if ( ! column ?. accessorFn ) {
120- return undefined
121- }
122-
123- row . _valuesCache [ columnId ] = column . accessorFn (
124- row . original as TData ,
125- rowIndex
126- )
127-
128- return row . _valuesCache [ columnId ] as any
129- } ,
130- getUniqueValues : columnId => {
131- if ( row . _uniqueValuesCache . hasOwnProperty ( columnId ) ) {
132- return row . _uniqueValuesCache [ columnId ]
133- }
134-
135- const column = table . getColumn ( columnId )
136-
137- if ( ! column ?. accessorFn ) {
138- return undefined
139- }
140-
141- if ( ! column . columnDef . getUniqueValues ) {
142- row . _uniqueValuesCache [ columnId ] = [ row . getValue ( columnId ) ]
143- return row . _uniqueValuesCache [ columnId ]
144- }
145-
146- row . _uniqueValuesCache [ columnId ] = column . columnDef . getUniqueValues (
147- row . original as TData ,
148- rowIndex
149- )
150-
151- return row . _uniqueValuesCache [ columnId ] as any
152- } ,
153- renderValue : columnId =>
154- row . getValue ( columnId ) ?? table . options . renderFallbackValue ,
155- subRows : subRows ?? [ ] ,
156- getLeafRows : ( ) => flattenBy ( row . subRows , d => d . subRows ) ,
157- getParentRow : ( ) =>
158- row . parentId ? table . getRow ( row . parentId , true ) : undefined ,
159- getParentRows : ( ) => {
160- let parentRows : Row < TData > [ ] = [ ]
161- let currentRow = row
162- while ( true ) {
163- const parentRow = currentRow . getParentRow ( )
164- if ( ! parentRow ) break
165- parentRows . push ( parentRow )
166- currentRow = parentRow
167- }
168- return parentRows . reverse ( )
169- } ,
170- getAllCells : memo (
171- ( ) => [ table . getAllLeafColumns ( ) ] ,
172- leafColumns => {
173- return leafColumns . map ( column => {
174- return createCell ( table , row as Row < TData > , column , column . id )
175- } )
176- } ,
177- getMemoOptions ( table . options , 'debugRows' , 'getAllCells' )
178- ) ,
179-
180- _getAllCellsByColumnId : memo (
181- ( ) => [ row . getAllCells ( ) ] ,
182- allCells => {
183- return allCells . reduce (
184- ( acc , cell ) => {
185- acc [ cell . column . id ] = cell
186- return acc
187- } ,
188- { } as Record < string , Cell < TData , unknown > >
189- )
190- } ,
191- getMemoOptions ( table . options , 'debugRows' , 'getAllCellsByColumnId' )
192- ) ,
242+ } )
243+
244+ if ( subRows ) {
245+ row . subRows = subRows
193246 }
194247
195248 for ( let i = 0 ; i < table . _features . length ; i ++ ) {
0 commit comments