@pega/lists-core
TypeScript icon, indicating that this package has built-in type declarations

8.0.0-build.39.5 • Public • Published

@pega/lists-core

Terminologies

  1. rsCore - rsCore refers to the core library. This library can be used to create different repeating structures like table, gallery etc.
  2. rsInternal - rsInternal is an object that represents the internal state of the core library. This is a singleton object and this is not exposed to the consumers of the rsCore library. As per requirement, the properties available on this object are made available to different building blocks of the core library like generators, reducers, middlewares(features), stateResolver.
  3. rsProps - rsProps object is used to store values which never change. This should be treated as a read only object. E.g. apiContext, formatters etc.
  4. rsStore - rsStore object can be used to store values which the features need to store without triggering a state update and these values change over time. E.g. autosizeTriggered, meta, ref for events like rowDragDropRef.
  5. generators - These are the objects that form the view object that the consumers of the core library are going to use to write their repeating structure component like table. Generators like view, row and column provides API methods that the end user can use to trigger state changes and getting updated view object in the core layer.
  6. reducers - reducers are used to update the state of the core library depending on the user action.
  7. middlewares or features - middlewares are the features that are responsible for creating or updating properties on the view object. Middlewares run in sync and for each action the middlewares are run. We have memoization on the features where we describe the properties whose change should execute the feature. If there is no change in the mentioned dependencies of the feature, the feature will not execute.
  8. stateResolver - StateResolver is responsible for orchestrating the data flow of the core library. It takes actions from the generator objects, run reducers to make state updates, run middlewares, implement the queue mechanism for the dispatch actions, fetch data and emit the final state to the external store. This is a singleton object and an instance of this is maintined on rsInternal object as rsStateResolver.

Initialization

  1. Core library exposes method initializeRsCore(args) that accepts constructor arguments that the consumer will call to get instance of core library.
  2. During initialization, the building blocks like reducers, middlewares, StateResolver are initialized and the first view object is constructured. The instances of these building blocks are set on the internal state of the core library rsInternal.
  3. From the rsInternal object, new object of type RsCore is created that contains only the publicly available methods to the consumer and this object is returned as a result of initializeRsCore method call. The consumer will be responsible for maintain the rsCore instance object.
  4. rsCore object can be used to get access to the view using rsCore.getView() or pubSubUtils by rsCore.getPubSubUtils().publish() etc.
  5. The consumer must set the parent container HTML Element under which RS is rendered via setDomContainer in rsCore.getView(). The dom container is used by RS core while executing dom related features like autosizing, animation etc.
  6. The consumer must set the header row HTML Element under which header cells are rendered via setItemElement in rsCore.getView(). The item element is used by RS core while executing dom related features like animation.

Data Flow

  1. After the initialization of the core library, the consumer has access to the view using rsCore.getView() which can be used to construct the view.
  2. The view object has APIs available on it which can be used to dispatch available user actions to the library. The view object has columns and rows objects which also has API methods available. The user can call these APIs with the required payload. e.g. view.type.applyFilter(params).
  3. The generator object will dispatch a corresponding action to the StateResolver.
  4. StateResolver will push the newly dispatched action to a queue and start the executing the actions availabel on the queue one by one.
  5. For each action, first the reducers will run to generate new state. The reducers will receive 3 parameters - (state, action, getView) - where state represents the current state, action represents the newly dispatched action with payload and getView will give the latest view. getView is required as some reducers require the meta and columns. The reducers will return the updated state.
  6. After the reducers, the middlewares will run with the updated state. The middlewares(feature files) will receive argument - getView, getRsStore, getRsProps, getState, getOriginalState, dispatch, queuedActions. As of now, we don't have any use case for getOriginalState but this is exposed for future use cases.

Notable differences due to architecture changes

  1. Core library moved to separate package RepeatingStructuresCore. This includes moving Reducers, Actions, Features, PubSub, some constants, utils and configs to the new package.
  2. Hide away direct access to ViewGenerator from the consumer. Instead initializeRsCore(args) is exposed that has to be used to initialize the core repo. This method internally will initialize the view object.
  3. Broke down instance variable and created new internal state of the core library rsInternal and exposed rsProps and rsStore for specific purposes on the internal instance.
  4. Broke useRepeat and moved the initialization of beforeRender, afterRender features and reducers to the core library. Moved apiContext.fetchData api call to the core.
  5. Broke useThunkReducer and moved the dispatch, state management and queue mechanism to the StateResolver. useThunkReducer is still available as it will act as an external store and StateResolver will emit state to the useThunkReducer to trigger state update.
  6. Defined featureProps to the features - getView, getRsStore, getRsProps, getState, getOriginalState, dispatch, queuedActions - with each prop serving a specific purpose. Earlier we were using instance variable to store anything and access as well. We are now restricting what is available to the features.
  7. Removed getComponent() from the ViewGenerator and ColumnGenerator as it's not core layer's responsibility to render the components. The core layer should only give the value for the cell, formatted value and the context of the cell to the consumer. The consumer can use these available values to render component in any framework of their choice.
  8. Moved generators out of Features folder to a separate folder for the Generators. Created new features prepareRows and prepareColumns which are inside Features folder.

Development Guidelines:

  1. RepeatingStructureCore is is a library that is implemented on the headlessUI pattern which means the library is only concerned about implementing the business logic, state management and exposing the necessary APIs for the consumers. The consumer is then responsible for creating their own UI using the library. Whenever you implement any features in the core library, think if you are making generic changes and not creating coupling between the view layer and the library.
  2. Don't import any framework specific code in core.
  3. Don't import anything from the RepeatingStructures view layer.
  4. Generators should not have rsCore specific internal methods like rsStore, rsProps etc assigned directly on this variable. This will expose the internals of the core library to the consumers. Instead use private properties in JS with #. E.g. this.#rsProps
  5. Similarly, anything that is put directly on the Row, Column and View generators using this variable becomes part of the library API contract as it will be exposed to outer world. Use private variables in JS to store any local values.
  6. For the Feature files that have an execute method, the will receive featureProps from the StateResolver. Use only the featureProps to run the feature files. rsInternal object shouldn't be used.
  7. For the feature files that rely on pubSub, rsInternal object can be used since these features are not executed by StateResolver and won't receive the featureProps.

Readme

Keywords

none

Package Sidebar

Install

npm i @pega/lists-core

Weekly Downloads

595

Version

8.0.0-build.39.5

License

SEE LICENSE IN LICENSE

Unpacked Size

2.38 MB

Total Files

464

Last publish

Collaborators

  • baipc
  • andrewlewis2
  • duddrc
  • ricmars
  • ssowersby
  • bob-difronzo
  • feenr-pega
  • cpmotion
  • pega-cosmos
  • ghosa4
  • sharv12
  • pgagnon
  • tumms2021389
  • vrspega
  • patilvishal
  • nikhilparmar