zalando-incubator / tessellate

Server-side React render service.
https://zalando-incubator.github.io/tessellate
MIT License
151 stars 23 forks source link

Tree-relative property IDs #80

Closed mfellner closed 7 years ago

mfellner commented 7 years ago

What

tessellate-bundler should assign the absolute property IDs for inlining properties into a bundle based on the position of an element node in the Tessellate JSON component tree (layout tree).

Why

Currently absolute UUIDs are used to map properties (key-value objects) from Tessellate JSON to the respective components (see script-builder). This makes it impossible to override such properties with externally loaded data in tessellate-fragment because the UUIDs are unknown.

It also requires using an absolute naming scheme for individual property value-keys in React components that require externally loaded data.

If property IDs can be computed based on the location of a React component in the layout tree then it is possible to define a data structure for property data. This data structure can be applied to a React component tree.

Proposal

script-builder assigns sequential integer IDs to property sets (props attribute of each element node) during the DFS traversal of the Tessellate JSON (layout JSON) tree.

FragmentScript uses deep-merging to merge BUNDLED_PROPS and injected props.

Data structure for property data (Tessellate Content JSON)

tessellate-fragment should support Tessellate Content JSON when loading external data for properties.

Example Tessellate JSON

type: div
props: null
children:
- type: h1
  props: null
  children:
  - Hello, World!
- type: a
  props:
    href: https://tech.zalando.com
  children:
  - Zalando Technology

Example Content JSON A

props: null
children:
- props: null
  children: []
- props:
    href: https://tech.zalando.com
  children: []
$schema: http://json-schema.org/draft-04/schema#
type: object
properties:
  props:
    oneOf:
    - type: object
    - type: 'null'
  children:
    type: array
    items:
      "$ref": "#"
required:
  - props
  - children
additionalProperties: false

Example Content JSON B

2:
  href: https://tech.zalando.com
$schema: http://json-schema.org/draft-04/schema#
type: object
patternProperties:
  "^[1-9]+[0-9]*$":
    type: object
additionalProperties: false
mfellner commented 7 years ago

After some research I would suggest a different approach: JSON pointers. See https://github.com/mfellner/react-json-pointer-example for an example.

mfellner commented 7 years ago

Closing in favour of JSON pointer solution implemented in https://github.com/zalando-incubator/tessellate/pull/96.