@ea-lab/reactive-json-docs 2.1.0 → 2.3.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.
package/package.json
CHANGED
|
@@ -266,11 +266,173 @@ additionalDataSource:
|
|
|
266
266
|
```
|
|
267
267
|
|
|
268
268
|
### Properties
|
|
269
|
-
- **`src`** (required): URL of the data source
|
|
270
|
-
- **`path`** (optional): Path where to place the data (template syntax)
|
|
271
|
-
- **`method`** (optional): HTTP method (GET, POST, etc.)
|
|
272
|
-
- **`dataMapping`** (optional): Configure selective data dispatch using mapping processors
|
|
273
|
-
- **`blocking`** (optional): If `true`, waits for loading before displaying
|
|
269
|
+
- **`src`** (required): URL of the data source. Can be a **string** (used as-is) or an **array of segments** — see [Dynamic URLs](#dynamic-urls-with-src-as-array) below.
|
|
270
|
+
- **`path`** (optional): Path where to place the data (template syntax).
|
|
271
|
+
- **`method`** (optional): HTTP method (GET, POST, etc.).
|
|
272
|
+
- **`dataMapping`** (optional): Configure selective data dispatch using mapping processors.
|
|
273
|
+
- **`blocking`** (optional): If `true`, waits for loading before displaying.
|
|
274
|
+
- **`fallbackDataSource`** (optional): An alternate source tried when the primary fails — see [Fallback Sources](#fallback-sources) below.
|
|
275
|
+
|
|
276
|
+
### Dynamic URLs with `src` as Array
|
|
277
|
+
|
|
278
|
+
When `src` is an array, each element is processed individually and the results are assembled into the final URL. The array can mix three kinds of elements:
|
|
279
|
+
|
|
280
|
+
#### 1. Plain strings and store references
|
|
281
|
+
|
|
282
|
+
A plain string is used as a literal. A string starting with `~~.` or `~.` is resolved from the root store data (both notations are equivalent in this context).
|
|
283
|
+
|
|
284
|
+
```yaml
|
|
285
|
+
additionalDataSource:
|
|
286
|
+
- src:
|
|
287
|
+
- "/api/items/"
|
|
288
|
+
- ~~.itemId # resolved from root data
|
|
289
|
+
- "/details"
|
|
290
|
+
path: ~~.itemDetails
|
|
291
|
+
blocking: true
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
#### 2. Segment objects — `{ segment, required? }`
|
|
295
|
+
|
|
296
|
+
A segment object resolves a dynamic value and inserts it as a path part.
|
|
297
|
+
|
|
298
|
+
```yaml
|
|
299
|
+
additionalDataSource:
|
|
300
|
+
- src:
|
|
301
|
+
- "/api/"
|
|
302
|
+
- segment: ~~.category # resolved as a path segment
|
|
303
|
+
- "/items"
|
|
304
|
+
path: ~~.items
|
|
305
|
+
blocking: true
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
When `required: true` is set and the segment resolves to `null` or empty, the entire URL is aborted (returns `null`) instead of producing a broken URL. This triggers the `fallbackDataSource` if one is defined, otherwise the source is skipped with a warning.
|
|
309
|
+
|
|
310
|
+
```yaml
|
|
311
|
+
additionalDataSource:
|
|
312
|
+
- src:
|
|
313
|
+
- "/api/items/"
|
|
314
|
+
- segment: ~~.requiredId
|
|
315
|
+
required: true # abort URL if null
|
|
316
|
+
fallbackDataSource:
|
|
317
|
+
src: "/api/items/default"
|
|
318
|
+
path: ~~.item
|
|
319
|
+
path: ~~.item
|
|
320
|
+
blocking: true
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
#### 3. Query param objects — `{ param, value, required? }`
|
|
324
|
+
|
|
325
|
+
A param object adds a key-value pair to the URL query string. Both the key and the value accept store references.
|
|
326
|
+
|
|
327
|
+
```yaml
|
|
328
|
+
additionalDataSource:
|
|
329
|
+
- src:
|
|
330
|
+
- "/api/items"
|
|
331
|
+
- param: id
|
|
332
|
+
value: ~~.itemId # ?id=<itemId>
|
|
333
|
+
- param: ~~.filterParamName
|
|
334
|
+
value: ~~.filterValue # dynamic key and value
|
|
335
|
+
path: ~~.items
|
|
336
|
+
blocking: true
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
**Null handling for params:**
|
|
340
|
+
- If either the key or the value resolves to `null`/empty and `required` is absent or `false`, the param is **silently omitted** from the URL.
|
|
341
|
+
- If either resolves to `null`/empty and `required: true` is set, the entire URL is **aborted**, triggering `fallbackDataSource` if defined.
|
|
342
|
+
|
|
343
|
+
```yaml
|
|
344
|
+
additionalDataSource:
|
|
345
|
+
- src:
|
|
346
|
+
- "/api/search"
|
|
347
|
+
- param: q
|
|
348
|
+
value: ~~.searchQuery # omitted if null
|
|
349
|
+
- param: type
|
|
350
|
+
value: ~~.filterType
|
|
351
|
+
required: true # abort if null
|
|
352
|
+
path: ~~.results
|
|
353
|
+
blocking: true
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
#### Mixing all three types
|
|
357
|
+
|
|
358
|
+
Path parts (plain strings, `~~.`/`~.` strings, and `segment` objects) are concatenated in order. All `param` objects are collected and appended as a query string after the path.
|
|
359
|
+
|
|
360
|
+
```yaml
|
|
361
|
+
additionalDataSource:
|
|
362
|
+
- src:
|
|
363
|
+
- "/api/"
|
|
364
|
+
- segment: ~~.category # path: /api/electronics
|
|
365
|
+
required: true # abort URL if category is null
|
|
366
|
+
- "/items" # path: /api/electronics/items
|
|
367
|
+
- param: id
|
|
368
|
+
value: ~~.itemId # ?id=42
|
|
369
|
+
- param: ~~.extraKey
|
|
370
|
+
value: ~~.extraValue # &q=hello
|
|
371
|
+
path: ~~.result
|
|
372
|
+
blocking: true
|
|
373
|
+
# Resolved URL: /api/electronics/items?id=42&q=hello
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
This is particularly useful when an RjBuild is loaded inside a `ReactiveJsonSubroot` with `dataOverride`, where dynamic values (like entity IDs) are injected by the parent.
|
|
377
|
+
|
|
378
|
+
```yaml
|
|
379
|
+
# Parent RjBuild passes taskId via dataOverride
|
|
380
|
+
- type: ReactiveJsonSubroot
|
|
381
|
+
rjOptions:
|
|
382
|
+
rjBuildUrl: "/components/TimeLogManager.yaml"
|
|
383
|
+
dataOverride:
|
|
384
|
+
taskId: ~.task.id
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
```yaml
|
|
388
|
+
# TimeLogManager.yaml — uses taskId as a query param
|
|
389
|
+
additionalDataSource:
|
|
390
|
+
- src:
|
|
391
|
+
- "/api/time-logs"
|
|
392
|
+
- param: "filter[task]"
|
|
393
|
+
value: ~~.taskId
|
|
394
|
+
required: true
|
|
395
|
+
path: ~~.timeLogs
|
|
396
|
+
blocking: true
|
|
397
|
+
|
|
398
|
+
data:
|
|
399
|
+
taskId: "" # Will be overridden by dataOverride
|
|
400
|
+
timeLogs: []
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Fallback Sources
|
|
404
|
+
|
|
405
|
+
The `fallbackDataSource` property defines an alternate source that is tried automatically when the primary source cannot be used. It accepts the same structure as a regular `additionalDataSource` item, including its own `fallbackDataSource` for chaining.
|
|
406
|
+
|
|
407
|
+
A fallback is triggered in two situations:
|
|
408
|
+
|
|
409
|
+
1. **The URL cannot be resolved** — a segment or param marked `required: true` resolved to `null` or empty.
|
|
410
|
+
2. **The HTTP request fails** — the server returns an error (4xx, 5xx, network failure, etc.).
|
|
411
|
+
|
|
412
|
+
```yaml
|
|
413
|
+
additionalDataSource:
|
|
414
|
+
# Fallback on missing required param
|
|
415
|
+
- src:
|
|
416
|
+
- "/api/items"
|
|
417
|
+
- param: id
|
|
418
|
+
value: ~~.selectedId
|
|
419
|
+
required: true
|
|
420
|
+
path: ~~.item
|
|
421
|
+
fallbackDataSource:
|
|
422
|
+
src: "/api/items/default"
|
|
423
|
+
path: ~~.item
|
|
424
|
+
blocking: true
|
|
425
|
+
|
|
426
|
+
# Fallback on HTTP error
|
|
427
|
+
- src: "/api/live-config"
|
|
428
|
+
path: ~~.config
|
|
429
|
+
fallbackDataSource:
|
|
430
|
+
src: "/api/config-cache"
|
|
431
|
+
path: ~~.config
|
|
432
|
+
blocking: true
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
When a fallback is triggered, a warning is logged in the console explaining the reason. If no fallback is defined and the primary fails, the source is skipped with a warning.
|
|
274
436
|
|
|
275
437
|
### Loading Modes
|
|
276
438
|
|
|
@@ -332,30 +494,47 @@ additionalDataSource:
|
|
|
332
494
|
### Complete Example
|
|
333
495
|
|
|
334
496
|
```yaml
|
|
335
|
-
renderView:
|
|
336
|
-
- type: div
|
|
337
|
-
content:
|
|
338
|
-
- type: h1
|
|
339
|
-
content: ["Hello ", ~~.currentUser.name]
|
|
340
|
-
- type: p
|
|
341
|
-
content: ["Version: ", ~~.systemConfig.version]
|
|
342
|
-
|
|
343
497
|
data:
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
498
|
+
userId: "42"
|
|
499
|
+
section: "reports"
|
|
500
|
+
formatParam: "json"
|
|
501
|
+
optionalFilter: null # null → param silently omitted
|
|
502
|
+
fallbackSection: "home"
|
|
348
503
|
|
|
349
504
|
additionalDataSource:
|
|
350
|
-
#
|
|
505
|
+
# Static URL — simple string form
|
|
351
506
|
- src: "/api/user-profile.json"
|
|
352
507
|
path: ~~.currentUser
|
|
353
508
|
blocking: true
|
|
354
|
-
|
|
355
|
-
#
|
|
356
|
-
- src:
|
|
509
|
+
|
|
510
|
+
# Dynamic path segment + query params
|
|
511
|
+
- src:
|
|
512
|
+
- "/api/"
|
|
513
|
+
- segment: ~~.section # e.g. /api/reports
|
|
514
|
+
- param: userId
|
|
515
|
+
value: ~~.userId # ?userId=42
|
|
516
|
+
- param: format
|
|
517
|
+
value: ~~.formatParam # &format=json
|
|
518
|
+
- param: filter
|
|
519
|
+
value: ~~.optionalFilter # null → omitted
|
|
520
|
+
path: ~~.sectionData
|
|
521
|
+
blocking: true
|
|
522
|
+
|
|
523
|
+
# Required param with fallback on failure or HTTP error
|
|
524
|
+
- src: "/api/system-config"
|
|
357
525
|
path: ~~.systemConfig
|
|
526
|
+
fallbackDataSource:
|
|
527
|
+
src: "/api/system-config-cache"
|
|
528
|
+
path: ~~.systemConfig
|
|
358
529
|
blocking: false
|
|
530
|
+
|
|
531
|
+
renderView:
|
|
532
|
+
- type: div
|
|
533
|
+
content:
|
|
534
|
+
- type: h1
|
|
535
|
+
content: ["Hello ", ~~.currentUser.name]
|
|
536
|
+
- type: p
|
|
537
|
+
content: ["Version: ", ~~.systemConfig.version]
|
|
359
538
|
```
|
|
360
539
|
|
|
361
540
|
## Best Practices
|
|
@@ -305,11 +305,165 @@ renderView:
|
|
|
305
305
|
content: |
|
|
306
306
|
|
|
307
307
|
### Properties
|
|
308
|
-
- **`src`** (required): URL of the data source
|
|
309
|
-
- **`path`** (optional): Path where to place the data (template syntax)
|
|
310
|
-
- **`method`** (optional): HTTP method (GET, POST, etc.)
|
|
311
|
-
- **`dataMapping`** (optional): Configure selective data dispatch using mapping processors
|
|
312
|
-
- **`blocking`** (optional): If `true`, waits for loading before displaying
|
|
308
|
+
- **`src`** (required): URL of the data source. Can be a **string** (used as-is) or an **array of segments** — see [Dynamic URLs](#dynamic-urls-with-src-as-array) below.
|
|
309
|
+
- **`path`** (optional): Path where to place the data (template syntax).
|
|
310
|
+
- **`method`** (optional): HTTP method (GET, POST, etc.).
|
|
311
|
+
- **`dataMapping`** (optional): Configure selective data dispatch using mapping processors.
|
|
312
|
+
- **`blocking`** (optional): If `true`, waits for loading before displaying.
|
|
313
|
+
- **`fallbackDataSource`** (optional): An alternate source tried when the primary fails — see [Fallback Sources](#fallback-sources) below.
|
|
314
|
+
|
|
315
|
+
### Dynamic URLs with `src` as Array
|
|
316
|
+
|
|
317
|
+
When `src` is an array, each element is processed individually and the results are assembled into the final URL. The array can mix three kinds of elements:
|
|
318
|
+
|
|
319
|
+
#### 1. Plain strings and store references
|
|
320
|
+
|
|
321
|
+
A plain string is used as a literal. A string starting with `~~.` or `~.` is resolved from the root store data (both notations are equivalent in this context).
|
|
322
|
+
|
|
323
|
+
- type: TabbedSerializer
|
|
324
|
+
yamlSerializedContent: |
|
|
325
|
+
additionalDataSource:
|
|
326
|
+
- src:
|
|
327
|
+
- "/api/items/"
|
|
328
|
+
- ~~.itemId # resolved from root data
|
|
329
|
+
- "/details"
|
|
330
|
+
path: ~~.itemDetails
|
|
331
|
+
blocking: true
|
|
332
|
+
|
|
333
|
+
- type: Markdown
|
|
334
|
+
content: |
|
|
335
|
+
|
|
336
|
+
#### 2. Segment objects — `{ segment, required? }`
|
|
337
|
+
|
|
338
|
+
A segment object resolves a dynamic value and inserts it as a path part. When `required: true` is set and the segment resolves to `null` or empty, the entire URL is aborted instead of producing a broken URL. This triggers `fallbackDataSource` if one is defined.
|
|
339
|
+
|
|
340
|
+
- type: TabbedSerializer
|
|
341
|
+
yamlSerializedContent: |
|
|
342
|
+
additionalDataSource:
|
|
343
|
+
- src:
|
|
344
|
+
- "/api/"
|
|
345
|
+
- segment: ~~.category # resolved as a path segment
|
|
346
|
+
required: true # abort URL if null
|
|
347
|
+
- "/items"
|
|
348
|
+
path: ~~.items
|
|
349
|
+
blocking: true
|
|
350
|
+
|
|
351
|
+
- type: Markdown
|
|
352
|
+
content: |
|
|
353
|
+
|
|
354
|
+
#### 3. Query param objects — `{ param, value, required? }`
|
|
355
|
+
|
|
356
|
+
A param object adds a key-value pair to the URL query string. Both the key and the value accept store references.
|
|
357
|
+
|
|
358
|
+
**Null handling:**
|
|
359
|
+
- If either the key or the value resolves to `null`/empty and `required` is absent or `false`, the param is **silently omitted** from the URL.
|
|
360
|
+
- If either resolves to `null`/empty and `required: true` is set, the entire URL is **aborted**, triggering `fallbackDataSource` if defined.
|
|
361
|
+
|
|
362
|
+
- type: TabbedSerializer
|
|
363
|
+
yamlSerializedContent: |
|
|
364
|
+
additionalDataSource:
|
|
365
|
+
- src:
|
|
366
|
+
- "/api/search"
|
|
367
|
+
- param: q
|
|
368
|
+
value: ~~.searchQuery # omitted if null
|
|
369
|
+
- param: ~~.filterParamName # dynamic key
|
|
370
|
+
value: ~~.filterValue # dynamic value
|
|
371
|
+
- param: type
|
|
372
|
+
value: ~~.filterType
|
|
373
|
+
required: true # abort if null
|
|
374
|
+
path: ~~.results
|
|
375
|
+
blocking: true
|
|
376
|
+
|
|
377
|
+
- type: Markdown
|
|
378
|
+
content: |
|
|
379
|
+
|
|
380
|
+
#### Mixing all three types
|
|
381
|
+
|
|
382
|
+
Path parts (plain strings, `~~.`/`~.` strings, and `segment` objects) are concatenated in order. All `param` objects are collected and appended as a query string after the path.
|
|
383
|
+
|
|
384
|
+
- type: TabbedSerializer
|
|
385
|
+
yamlSerializedContent: |
|
|
386
|
+
additionalDataSource:
|
|
387
|
+
- src:
|
|
388
|
+
- "/api/"
|
|
389
|
+
- segment: ~~.category # path: /api/electronics
|
|
390
|
+
required: true # abort URL if category is null
|
|
391
|
+
- "/items" # path: /api/electronics/items
|
|
392
|
+
- param: id
|
|
393
|
+
value: ~~.itemId # ?id=42
|
|
394
|
+
- param: ~~.extraKey
|
|
395
|
+
value: ~~.extraValue # &q=hello
|
|
396
|
+
path: ~~.result
|
|
397
|
+
blocking: true
|
|
398
|
+
# Resolved URL: /api/electronics/items?id=42&q=hello
|
|
399
|
+
|
|
400
|
+
- type: Markdown
|
|
401
|
+
content: |
|
|
402
|
+
|
|
403
|
+
This is particularly useful when an RjBuild is loaded inside a `ReactiveJsonSubroot` with `dataOverride`, where dynamic values (like entity IDs) are injected by the parent.
|
|
404
|
+
|
|
405
|
+
- type: TabbedSerializer
|
|
406
|
+
yamlSerializedContent: |
|
|
407
|
+
# Parent RjBuild passes taskId via dataOverride
|
|
408
|
+
renderView:
|
|
409
|
+
- type: ReactiveJsonSubroot
|
|
410
|
+
rjOptions:
|
|
411
|
+
rjBuildUrl: "/components/TimeLogManager.yaml"
|
|
412
|
+
dataOverride:
|
|
413
|
+
taskId: ~.task.id
|
|
414
|
+
|
|
415
|
+
- type: TabbedSerializer
|
|
416
|
+
yamlSerializedContent: |
|
|
417
|
+
# TimeLogManager.yaml — uses taskId as a query param
|
|
418
|
+
additionalDataSource:
|
|
419
|
+
- src:
|
|
420
|
+
- "/api/time-logs"
|
|
421
|
+
- param: "filter[task]"
|
|
422
|
+
value: ~~.taskId
|
|
423
|
+
required: true
|
|
424
|
+
path: ~~.timeLogs
|
|
425
|
+
blocking: true
|
|
426
|
+
|
|
427
|
+
data:
|
|
428
|
+
taskId: "" # Will be overridden by dataOverride
|
|
429
|
+
timeLogs: []
|
|
430
|
+
|
|
431
|
+
- type: Markdown
|
|
432
|
+
content: |
|
|
433
|
+
|
|
434
|
+
### Fallback Sources
|
|
435
|
+
|
|
436
|
+
The `fallbackDataSource` property defines an alternate source that is tried automatically when the primary source cannot be used. It accepts the same structure as a regular `additionalDataSource` item, including its own `fallbackDataSource` for chaining.
|
|
437
|
+
|
|
438
|
+
A fallback is triggered in two situations:
|
|
439
|
+
|
|
440
|
+
1. **The URL cannot be resolved** — a segment or param marked `required: true` resolved to `null` or empty.
|
|
441
|
+
2. **The HTTP request fails** — the server returns an error (4xx, 5xx, network failure, etc.).
|
|
442
|
+
|
|
443
|
+
When a fallback is triggered, a warning is logged in the console explaining the reason.
|
|
444
|
+
|
|
445
|
+
- type: TabbedSerializer
|
|
446
|
+
yamlSerializedContent: |
|
|
447
|
+
additionalDataSource:
|
|
448
|
+
# Fallback on missing required param
|
|
449
|
+
- src:
|
|
450
|
+
- "/api/items"
|
|
451
|
+
- param: id
|
|
452
|
+
value: ~~.selectedId
|
|
453
|
+
required: true
|
|
454
|
+
path: ~~.item
|
|
455
|
+
fallbackDataSource:
|
|
456
|
+
src: "/api/items/default"
|
|
457
|
+
path: ~~.item
|
|
458
|
+
blocking: true
|
|
459
|
+
|
|
460
|
+
# Fallback on HTTP error
|
|
461
|
+
- src: "/api/live-config"
|
|
462
|
+
path: ~~.config
|
|
463
|
+
fallbackDataSource:
|
|
464
|
+
src: "/api/config-cache"
|
|
465
|
+
path: ~~.config
|
|
466
|
+
blocking: true
|
|
313
467
|
|
|
314
468
|
### Loading Modes
|
|
315
469
|
|
|
@@ -391,31 +545,48 @@ renderView:
|
|
|
391
545
|
|
|
392
546
|
- type: TabbedSerializer
|
|
393
547
|
yamlSerializedContent: |
|
|
394
|
-
renderView:
|
|
395
|
-
- type: div
|
|
396
|
-
content:
|
|
397
|
-
- type: h1
|
|
398
|
-
content: ["Hello ", ~~.currentUser.name]
|
|
399
|
-
- type: p
|
|
400
|
-
content: ["Version: ", ~~.systemConfig.version]
|
|
401
|
-
|
|
402
548
|
data:
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
549
|
+
userId: "42"
|
|
550
|
+
section: "reports"
|
|
551
|
+
formatParam: "json"
|
|
552
|
+
optionalFilter: null # null → param silently omitted
|
|
407
553
|
|
|
408
554
|
additionalDataSource:
|
|
409
|
-
#
|
|
555
|
+
# Static URL — simple string form
|
|
410
556
|
- src: "/api/user-profile.json"
|
|
411
557
|
path: ~~.currentUser
|
|
412
558
|
blocking: true
|
|
413
|
-
|
|
414
|
-
#
|
|
415
|
-
- src:
|
|
559
|
+
|
|
560
|
+
# Dynamic path segment + query params
|
|
561
|
+
- src:
|
|
562
|
+
- "/api/"
|
|
563
|
+
- segment: ~~.section # e.g. /api/reports
|
|
564
|
+
required: true
|
|
565
|
+
- param: userId
|
|
566
|
+
value: ~~.userId # ?userId=42
|
|
567
|
+
- param: format
|
|
568
|
+
value: ~~.formatParam # &format=json
|
|
569
|
+
- param: filter
|
|
570
|
+
value: ~~.optionalFilter # null → omitted
|
|
571
|
+
path: ~~.sectionData
|
|
572
|
+
blocking: true
|
|
573
|
+
|
|
574
|
+
# Fallback on HTTP error or unavailable source
|
|
575
|
+
- src: "/api/system-config"
|
|
416
576
|
path: ~~.systemConfig
|
|
577
|
+
fallbackDataSource:
|
|
578
|
+
src: "/api/system-config-cache"
|
|
579
|
+
path: ~~.systemConfig
|
|
417
580
|
blocking: false
|
|
418
581
|
|
|
582
|
+
renderView:
|
|
583
|
+
- type: div
|
|
584
|
+
content:
|
|
585
|
+
- type: h1
|
|
586
|
+
content: ["Hello ", ~~.currentUser.name]
|
|
587
|
+
- type: p
|
|
588
|
+
content: ["Version: ", ~~.systemConfig.version]
|
|
589
|
+
|
|
419
590
|
- type: Markdown
|
|
420
591
|
content: |
|
|
421
592
|
|