@ea-lab/reactive-json-docs 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/package.json +2 -2
  2. package/public/rjbuild/docs/advanced-concepts/data-mapping.md +76 -0
  3. package/public/rjbuild/docs/advanced-concepts/data-mapping.yaml +140 -0
  4. package/public/rjbuild/docs/advanced-concepts/data-processors.md +373 -0
  5. package/public/rjbuild/docs/advanced-concepts/data-processors.yaml +309 -0
  6. package/public/rjbuild/docs/advanced-concepts/index.md +9 -0
  7. package/public/rjbuild/docs/advanced-concepts/index.yaml +15 -0
  8. package/public/rjbuild/docs/{extend → advanced-concepts/plugins}/component-development-guide-llm.md +2 -0
  9. package/public/rjbuild/docs/{extend → advanced-concepts/plugins}/plugin-system.md +2 -0
  10. package/public/rjbuild/docs/{extend → advanced-concepts/plugins}/plugin-system.yaml +2 -0
  11. package/public/rjbuild/docs/core/dataMapping/index.md +31 -0
  12. package/public/rjbuild/docs/core/dataMapping/index.yaml +24 -0
  13. package/public/rjbuild/docs/core/dataMapping/simpleMapping.md +131 -0
  14. package/public/rjbuild/docs/core/dataMapping/simpleMapping.yaml +376 -0
  15. package/public/rjbuild/docs/core/element/special/ReactiveJsonSubroot.md +4 -3
  16. package/public/rjbuild/docs/core/element/special/ReactiveJsonSubroot.yaml +114 -6
  17. package/public/rjbuild/docs/{getting-started.md → getting-started/index.md} +2 -2
  18. package/public/rjbuild/docs/{getting-started.yaml → getting-started/index.yaml} +4 -2
  19. package/public/rjbuild/docs/getting-started/rjbuild-structure.md +352 -0
  20. package/public/rjbuild/docs/getting-started/rjbuild-structure.yaml +415 -0
  21. package/public/rjbuild/docs/install.yaml +682 -681
  22. /package/public/rjbuild/docs/{extend → advanced-concepts/plugins}/component-development.md +0 -0
  23. /package/public/rjbuild/docs/{extend → advanced-concepts/plugins}/component-development.yaml +0 -0
  24. /package/public/rjbuild/docs/{extend → advanced-concepts/plugins}/index.md +0 -0
  25. /package/public/rjbuild/docs/{extend → advanced-concepts/plugins}/index.yaml +0 -0
  26. /package/public/rjbuild/docs/{template.md → getting-started/template.md} +0 -0
  27. /package/public/rjbuild/docs/{template.yaml → getting-started/template.yaml} +0 -0
@@ -0,0 +1,309 @@
1
+ renderView:
2
+ - type: Markdown
3
+ content: |
4
+ # Data Processors
5
+
6
+ Data Processors are a powerful feature in Reactive-JSON that allow you to intercept and modify data received via `fetchData`, `submitData`, and `additionalDataSources`. This enables you to implement data transformation, validation, security filtering, and other data processing logic in a centralized and reusable way.
7
+
8
+ ## How Data Processors Work
9
+
10
+ When Reactive-JSON receives data from HTTP requests, it automatically passes the data through all registered Data Processors in order. Each processor:
11
+
12
+ 1. **Examines the request and response context** (URL, method, headers, status, etc.)
13
+ 2. **Receives the current data** being processed
14
+ 3. **Must return the data** - either transformed or unchanged
15
+ 4. **Chains with other processors** (processed data flows to the next processor)
16
+
17
+ - type: Markdown
18
+ content: |
19
+ ## Basic Structure
20
+
21
+ A Data Processor is a function that receives context and data, then **must return** the processed data:
22
+
23
+ - type: SyntaxHighlighter
24
+ language: javascript
25
+ content: |
26
+ const myDataProcessor = ({ requestContext, responseContext, dataToProcess, originalDataToProcess }) => {
27
+ // Check if we want to process this data
28
+ if (!requestContext.url.includes('/api/users')) {
29
+ return dataToProcess; // Return unchanged data
30
+ }
31
+
32
+ // Check response status
33
+ if (responseContext.status >= 400) {
34
+ return dataToProcess; // Return unchanged data
35
+ }
36
+
37
+ // Transform the data
38
+ const processedData = {
39
+ ...dataToProcess,
40
+ timestamp: new Date().toISOString(),
41
+ source: requestContext.url
42
+ };
43
+
44
+ return processedData; // Return transformed data
45
+ };
46
+
47
+ - type: Markdown
48
+ content: |
49
+ ## Function Parameters
50
+
51
+ - type: DefinitionList
52
+ content:
53
+ - term: requestContext
54
+ details:
55
+ type: Markdown
56
+ content: |
57
+ Information about the HTTP request:
58
+ - `url`: The URL that was called
59
+ - `method`: HTTP method (GET, POST, etc.)
60
+ - `headers`: Request headers object
61
+ - `body`: Request body (for POST, PUT, etc.)
62
+
63
+ - term: responseContext
64
+ details:
65
+ type: Markdown
66
+ content: |
67
+ Information about the HTTP response:
68
+ - `headers`: Response headers object
69
+ - `status`: HTTP status code (200, 404, etc.)
70
+ - `data`: Raw response data
71
+
72
+ - term: dataToProcess
73
+ details:
74
+ type: Markdown
75
+ content: |
76
+ The data currently being processed. This may have been modified by previous Data Processors in the chain.
77
+
78
+ - term: originalDataToProcess
79
+ details:
80
+ type: Markdown
81
+ content: |
82
+ The original data before any processing, useful for comparison or logging.
83
+
84
+ - type: Markdown
85
+ content: |
86
+ ## Plugin Registration
87
+
88
+ Data Processors are registered through the plugin system:
89
+
90
+ - type: SyntaxHighlighter
91
+ language: javascript
92
+ content: |
93
+ import { mergeComponentCollections } from "@ea-lab/reactive-json";
94
+
95
+ const myPlugins = {
96
+ element: {
97
+ // Your custom components
98
+ },
99
+ dataProcessor: {
100
+ "timestamp-processor": {
101
+ callback: timestampProcessor,
102
+ order: 0
103
+ },
104
+ "security-filter": {
105
+ callback: securityProcessor,
106
+ order: 10
107
+ }
108
+ }
109
+ };
110
+
111
+ export const MyReactiveJsonRoot = (props) => {
112
+ const plugins = mergeComponentCollections([myPlugins]);
113
+ return <ReactiveJsonRoot {...props} plugins={plugins} />;
114
+ };
115
+
116
+ - type: Markdown
117
+ content: |
118
+ ### Plugin Structure
119
+
120
+ - type: DefinitionList
121
+ content:
122
+ - term: Key
123
+ details: Unique identifier for the processor.
124
+ - term: callback
125
+ details: The processor function.
126
+ - term:
127
+ code: order
128
+ after: "(number)"
129
+ details: Execution order (lower numbers run first).
130
+
131
+ - type: Markdown
132
+ content: |
133
+ ## Common Use Cases
134
+
135
+ ### Adding Timestamps
136
+
137
+ - type: SyntaxHighlighter
138
+ language: javascript
139
+ content: |
140
+ const timestampProcessor = ({ requestContext, responseContext, dataToProcess, originalDataToProcess }) => {
141
+ if (typeof dataToProcess !== 'object' || dataToProcess === null) {
142
+ return dataToProcess; // Return unchanged for non-objects
143
+ }
144
+
145
+ return {
146
+ ...dataToProcess,
147
+ __metadata: {
148
+ processedAt: new Date().toISOString(),
149
+ sourceUrl: requestContext.url,
150
+ responseStatus: responseContext.status
151
+ }
152
+ };
153
+ };
154
+
155
+ - type: Markdown
156
+ content: |
157
+ ### Security Filtering
158
+
159
+ - type: SyntaxHighlighter
160
+ language: javascript
161
+ content: |
162
+ const securityProcessor = ({ requestContext, responseContext, dataToProcess, originalDataToProcess }) => {
163
+ // Only filter external API responses
164
+ if (!requestContext.url.includes('external-api')) {
165
+ return dataToProcess; // Return unchanged
166
+ }
167
+
168
+ if (typeof dataToProcess !== 'object' || dataToProcess === null) {
169
+ return dataToProcess; // Return unchanged for non-objects
170
+ }
171
+
172
+ // Remove sensitive fields
173
+ const sensitiveFields = ['password', 'secret', 'apiKey', 'token'];
174
+ const cleanedData = { ...dataToProcess };
175
+
176
+ sensitiveFields.forEach(field => {
177
+ if (cleanedData.hasOwnProperty(field)) {
178
+ delete cleanedData[field];
179
+ console.log(`🔒 Removed sensitive field: ${field}`);
180
+ }
181
+ });
182
+
183
+ return cleanedData;
184
+ };
185
+
186
+ - type: Markdown
187
+ content: |
188
+ ### Data Format Transformation
189
+
190
+ - type: SyntaxHighlighter
191
+ language: javascript
192
+ content: |
193
+ const dateFormatProcessor = ({ requestContext, responseContext, dataToProcess, originalDataToProcess }) => {
194
+ if (typeof dataToProcess !== 'object' || dataToProcess === null) {
195
+ return dataToProcess; // Return unchanged for non-objects
196
+ }
197
+
198
+ const processedData = { ...dataToProcess };
199
+
200
+ // Convert DD/MM/YYYY dates to YYYY-MM-DD
201
+ Object.keys(processedData).forEach(key => {
202
+ if (typeof processedData[key] === 'string' && /^\d{2}\/\d{2}\/\d{4}$/.test(processedData[key])) {
203
+ const [day, month, year] = processedData[key].split('/');
204
+ processedData[key] = `${year}-${month}-${day}`;
205
+ }
206
+ });
207
+
208
+ return processedData;
209
+ };
210
+
211
+ - type: Markdown
212
+ content: |
213
+ ## Best Practices
214
+
215
+ ### Always Return Data
216
+ Data Processors **must always return data**. To skip processing, return the original data:
217
+
218
+ - type: SyntaxHighlighter
219
+ language: javascript
220
+ content: |
221
+ const myProcessor = ({ requestContext, responseContext, dataToProcess, originalDataToProcess }) => {
222
+ // Skip processing for certain conditions
223
+ if (!requestContext.url.includes('/api/')) {
224
+ return dataToProcess; // Return unchanged
225
+ }
226
+ if (responseContext.status >= 400) {
227
+ return dataToProcess; // Return unchanged
228
+ }
229
+ if (typeof dataToProcess !== 'object') {
230
+ return dataToProcess; // Return unchanged
231
+ }
232
+
233
+ // Process and return transformed data
234
+ return { ...dataToProcess, processed: true };
235
+ };
236
+
237
+ - type: Markdown
238
+ content: |
239
+ ### Immutable Updates
240
+ Always clone data before modifying:
241
+
242
+ - type: SyntaxHighlighter
243
+ language: javascript
244
+ content: |
245
+ const processedData = { ...dataToProcess }; // Shallow clone
246
+ // Or for deep cloning, use JSON.parse(JSON.stringify(...)):
247
+ const processedData = JSON.parse(JSON.stringify(dataToProcess));
248
+ // Or with lodash:
249
+ const processedData = _.cloneDeep(dataToProcess);
250
+
251
+ - type: Markdown
252
+ content: |
253
+ ### Error Handling
254
+ The system automatically catches errors, but you can add your own:
255
+
256
+ - type: SyntaxHighlighter
257
+ language: javascript
258
+ content: |
259
+ const safeProcessor = ({ requestContext, responseContext, dataToProcess, originalDataToProcess }) => {
260
+ try {
261
+ // Your processing logic
262
+ return processedData;
263
+ } catch (error) {
264
+ console.error('Processing failed:', error);
265
+ return dataToProcess; // Return original data on error
266
+ }
267
+ };
268
+
269
+ - type: Markdown
270
+ content: |
271
+ ## RjBuild vs Data Processing
272
+
273
+ The system automatically detects whether the response is a complete RjBuild or just data:
274
+
275
+ - **Complete RjBuild**: Processors only modify the `data` section
276
+ - **Data only**: Processors modify the entire response
277
+
278
+ This happens automatically based on the `updateOnlyData` parameter in `fetchData`/`submitData`.
279
+
280
+ ## Execution Context
281
+
282
+ ### With `fetchData`/`submitData`
283
+
284
+ - type: SyntaxHighlighter
285
+ language: yaml
286
+ content: |
287
+ - type: button
288
+ content: "Load User Data"
289
+ actions:
290
+ - what: fetchData
291
+ on: click
292
+ url: "/api/users/123"
293
+ refreshAppOnResponse: true
294
+ updateOnlyData: false # The response is expected to be a complete RjBuild.
295
+ # When the response is a complete RjBuild, the processors will receive the data only.
296
+
297
+ - type: Markdown
298
+ content: |
299
+ ### With `additionalDataSources`
300
+
301
+ - type: SyntaxHighlighter
302
+ language: yaml
303
+ content: |
304
+ additionalDataSource:
305
+ - src: "/api/config"
306
+ path: "~~.config"
307
+ # Processors will automatically process this data
308
+
309
+ data:
@@ -0,0 +1,9 @@
1
+ # Advanced Concepts
2
+
3
+ This section covers advanced features and concepts in Reactive-JSON that enable more sophisticated data processing and application behavior.
4
+
5
+ ## Topics
6
+
7
+ - **[Data Mapping](data-mapping.md)**: Learn how to selectively dispatch and transform response data using the Data Mapping system
8
+ - **[Data Processors](data-processors.md)**: Learn how to intercept and modify data from HTTP requests using the DataProcessor system
9
+ - **[Plugins](plugins/index.md)**: Learn how to extend Reactive-JSON with custom components and plugins.
@@ -0,0 +1,15 @@
1
+ renderView:
2
+ - type: Markdown
3
+ content: |
4
+ # Advanced Concepts
5
+
6
+ This section covers advanced features and concepts in Reactive-JSON that enable more sophisticated data processing and application behavior.
7
+
8
+ ## Topics
9
+
10
+ - **[Data Mapping](data-mapping)**: Learn how to selectively dispatch and transform response data using the Data Mapping system.
11
+ - **[Data Processors](data-processors)**: Learn how to intercept and modify data from HTTP requests using the DataProcessor system.
12
+ - **[Plugins](plugins/index)**: Learn how to extend Reactive-JSON with custom components and plugins.
13
+
14
+ data:
15
+ page_title: "Advanced Concepts - Reactive-JSON Documentation"
@@ -277,6 +277,8 @@ export const CustomRoot = (props) => {
277
277
  ```js
278
278
  {
279
279
  action: { /* Action components */ },
280
+ dataMapping: { /* Data mapping processors */ },
281
+ dataProcessor: { /* Data processing functions */ },
280
282
  element: { /* Element components */ },
281
283
  hook: { /* React hooks */ },
282
284
  reaction: { /* Reaction functions */ },
@@ -12,6 +12,8 @@ A plugin is a JavaScript object that exports components organized by type. The s
12
12
  - **action**: Components that perform side effects or modify behavior
13
13
  - **reaction**: Event-driven components that respond to user interactions
14
14
  - **hook**: React hooks that provide additional functionality
15
+ - **dataProcessor**: Functions that intercept and modify HTTP response data
16
+ - **dataMapping**: Processors that selectively dispatch response data to specific locations
15
17
 
16
18
  ## Plugin Registration
17
19
 
@@ -15,6 +15,8 @@ renderView:
15
15
  - **action**: Components that perform side effects or modify behavior
16
16
  - **reaction**: Event-driven components that respond to user interactions
17
17
  - **hook**: React hooks that provide additional functionality
18
+ - **dataProcessor**: Functions that intercept and modify HTTP response data
19
+ - **dataMapping**: Processors that selectively dispatch response data to specific locations
18
20
 
19
21
  ## Plugin Registration
20
22
 
@@ -0,0 +1,31 @@
1
+ # Data Mapping Components
2
+
3
+ Data mapping components process and transform HTTP response data to specific locations in your application state. These components work with `fetchData`, `submitData` reactions, and `additionalDataSources`.
4
+
5
+ ## Core Data Mappers
6
+
7
+ ### SimpleMapping
8
+ The foundational data mapper that provides string-based mappings for selective data dispatch.
9
+
10
+ - **Purpose**: Map HTTP response fields to application data paths
11
+ - **Configuration**: YAML-based string mappings with destination templates
12
+ - **Features**: Required fields, default values, error handling, update modes
13
+ - **Use Cases**: User profiles, settings, API data transformation
14
+ - **Documentation**: [SimpleMapping Guide](simpleMapping.md) | [Interactive Examples](simpleMapping)
15
+
16
+ ## Architecture
17
+
18
+ Data mapping processes HTTP response data to selectively dispatch it to application state:
19
+
20
+ 1. **HTTP Request** → Server responds with data
21
+ 2. **Data Mapping** → Selectively dispatch response data to application state
22
+ 3. **Application State** → Updated with mapped data
23
+
24
+ ## Creating Custom Data Mappers
25
+
26
+ For information about creating custom data mappers and the broader Data Mapping system architecture, see the [Data Mapping Documentation](../../advanced-concepts/data-mapping).
27
+
28
+ ## Related
29
+
30
+ - [Data Mapping System](../../advanced-concepts/data-mapping) - System overview and custom mappers
31
+ - [Plugin System](../../advanced-concepts/plugins/plugin-system) - Component architecture
@@ -0,0 +1,24 @@
1
+ renderView:
2
+ - type: Markdown
3
+ content: |
4
+ # Data Mapping Components
5
+
6
+ Data mapping components process and transform HTTP response data to specific locations in your application state. These components work with `fetchData`, `submitData` reactions, and `additionalDataSources`.
7
+
8
+ ## Core Data Mappers
9
+
10
+ ### [SimpleMapping](simpleMapping)
11
+ The foundational data mapper that provides string-based mappings for selective data dispatch.
12
+
13
+ - **Purpose**: Map HTTP response fields to application data paths
14
+ - **Configuration**: YAML-based string mappings with destination templates
15
+ - **Features**: Required fields, default values, error handling, update modes
16
+ - **Use Cases**: User profiles, settings, API data transformation
17
+
18
+ ## Creating Custom Data Mappers
19
+
20
+ For information about creating custom data mappers and the broader Data Mapping system architecture, see the **[Data Mapping Documentation](../../advanced-concepts/data-mapping)**.
21
+
22
+ templates:
23
+
24
+ data:
@@ -0,0 +1,131 @@
1
+ # SimpleMapping
2
+
3
+ SimpleMapping is the core data mapping processor in Reactive-JSON that enables selective dispatch and transformation of HTTP response data to specific locations in your application state. It provides a straightforward, configuration-driven approach to map response fields to application data paths.
4
+
5
+ ## Properties
6
+
7
+ ### stringMap Configuration
8
+
9
+ - `value` (string, required): Source path in the HTTP response (e.g., `user.firstName`)
10
+ - `required` (boolean, optional, default: true): Whether the source value must exist
11
+ - `defaultValue` (any, optional): Fallback value when source is missing and not required
12
+ - `updateMode` (string, optional, default: "replace"): How to apply the value (`replace`, `add`, `move`, `remove`)
13
+
14
+ ### onErrorMap Configuration
15
+
16
+ - `value` (string, required): Can be either static values (e.g., `Error occurred`) or template references (e.g., `~~.errorTimestamp`)
17
+
18
+ ## Configuration Structure
19
+
20
+ The `onErrorMap` works like `stringMap`, but provides fallback values when main mappings fail. Same key-value structure as `stringMap` (destination → configuration). Applied only when corresponding `stringMap` entries fail and are marked as `required: true`.
21
+
22
+ ## Basic Example
23
+
24
+ ```yaml
25
+ - what: fetchData
26
+ url: "/api/user-profile"
27
+ updateOnlyData: true
28
+ dataMapping:
29
+ simpleMapping:
30
+ stringMap:
31
+ "~~.currentUser.name":
32
+ value: "user.firstName"
33
+ "~~.currentUser.email":
34
+ value: "user.email"
35
+ "~~.settings.theme":
36
+ value: "user.preferences.theme"
37
+ required: false
38
+ defaultValue: "light"
39
+
40
+ data:
41
+ currentUser: {}
42
+ settings: {}
43
+ ```
44
+
45
+ ## Error Handling Example
46
+
47
+ ```yaml
48
+ - what: fetchData
49
+ url: "/api/incomplete-data"
50
+ updateOnlyData: true
51
+ dataMapping:
52
+ simpleMapping:
53
+ stringMap:
54
+ "~~.profile.name":
55
+ value: "user.name"
56
+ required: true
57
+ "~~.profile.email":
58
+ value: "user.email"
59
+ required: true
60
+ onErrorMap:
61
+ "~~.profile.status":
62
+ value: "Error loading profile"
63
+ "~~.profile.name":
64
+ value: "Unknown User"
65
+ "~~.profile.email":
66
+ value: "unknown@example.com"
67
+ "~~.profile.loadedAt":
68
+ value: "~~.currentTimestamp"
69
+
70
+ data:
71
+ profile: {}
72
+ currentTimestamp: "2024-01-15T10:30:00Z"
73
+ ```
74
+
75
+ ## Advanced Configuration
76
+
77
+ ```yaml
78
+ dataMapping:
79
+ simpleMapping:
80
+ stringMap:
81
+ "~~.order.id":
82
+ value: "order.id"
83
+ "~~.order.customerName":
84
+ value: "order.customer.name"
85
+ "~~.order.customerEmail":
86
+ value: "order.customer.contact.email"
87
+ "~~.order.total":
88
+ value: "order.billing.total"
89
+ "~~.order.currency":
90
+ value: "order.billing.currency"
91
+ required: false
92
+ defaultValue: "USD"
93
+ ```
94
+
95
+ ## Integration with additionalDataSources
96
+
97
+ ```yaml
98
+ additionalDataSource:
99
+ - src: "/api/user-profile"
100
+ blocking: true
101
+ dataMapping:
102
+ simpleMapping:
103
+ stringMap:
104
+ "~~.profile.displayName":
105
+ value: "user.name"
106
+ "~~.profile.email":
107
+ value: "user.email"
108
+ "~~.settings.theme":
109
+ value: "user.preferences.theme"
110
+ required: false
111
+ defaultValue: "light"
112
+
113
+ data:
114
+ profile: {}
115
+ settings: {}
116
+ ```
117
+
118
+ ## Usage Context
119
+
120
+ SimpleMapping is automatically available as part of the core Reactive-JSON plugins and can be used in:
121
+
122
+ - **fetchData reactions**: Process API responses selectively
123
+ - **submitData reactions**: Handle server responses after form submissions
124
+ - **additionalDataSources**: Map initial data loading responses
125
+
126
+ ## Related
127
+
128
+ - [Data Mapping System Overview](../../advanced-concepts/data-mapping) - Complete system architecture and custom mappers
129
+ - [FetchData Reaction](../reaction/fetchData) - HTTP request handling with data mapping
130
+ - [SubmitData Reaction](../reaction/submitData) - Form submission with data mapping
131
+ - [Plugin System](../../advanced-concepts/plugins/plugin-system) - Component architecture