Config entity for storing code components

Created on 15 January 2025, 5 days ago

Overview

Code components authored with the in-built code editor need a storage solution.

Proposed resolution

Introduce a config entity to store code components. Schema starting point:

โœจ Feature request
Status

Active

Version

0.0

Component

Data model

Created by

๐Ÿ‡ณ๐Ÿ‡ฑNetherlands balintbrews Amsterdam, NL

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @balintbrews
  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands balintbrews Amsterdam, NL
  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands balintbrews Amsterdam, NL
  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands balintbrews Amsterdam, NL
  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands balintbrews Amsterdam, NL
  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands balintbrews Amsterdam, NL
  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands balintbrews Amsterdam, NL
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    This blocks โœจ HTTP API for code component config entities Active , which blocks many other things in ๐ŸŒฑ [Meta] Plan for code components Active .

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    This blocks an entire chain of work, all the way up to #3499988-10: [PP-3] Editing code components โ†’ !

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    https://git.drupalcode.org/project/experience_builder/-/merge_requests/3... โ† no need to start from zero for config schema!

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States tedbow Ithaca, NY, USA

    Will work on this

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States tedbow Ithaca, NY, USA

    Just a start but I will unassign myself as others will be starting there day tomorrow before me.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States tedbow Ithaca, NY, USA
  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom f.mazeikis Brighton
  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    Based on prior discussions, I always thought we'd be building in-browser defined SDCs. That's what we had @tedbow do the https://git.drupalcode.org/project/experience_builder/-/tree/research_sd... PoC for.

    Now, this is different than that PoC, because we're assuming components to be entirely JS-defined, whereas SDC is pretty heavily assuming Twig.

    Based on the issue summary, it seems like we're now saying we should be loosely matching the architecture of SDC, but not be aiming to have these exposed as SDCs? That raises many subsequent questions:

    1. Where can I read the rationale behind that decision?
    2. Which aspects are expected to be identical to SDC, and which ones are not?
    3. Of the aspects that are expected to be identical, do we expect to chase upstream SDC changes (i.e. commit to maintaining compatibility)?

    We need clear answers to these questions are crucial to ensure we architect this new config entity right from the start: wherever we're matching SDC, we SHOULD reuse SDC infrastructure; wherever we're not, we MUST explicitly document what/how/why.

  • ๐Ÿ‡ณ๐Ÿ‡ฑNetherlands balintbrews Amsterdam, NL

    Based on prior discussions, I always thought we'd be building in-browser defined SDCs. That's what we had @tedbow do the https://git.drupalcode.org/project/experience_builder/-/tree/research_sd... PoC for.

    That was a POC done long before we worked on โœจ [exploratory] PoC of Preact+Tailwind components editable via CodeMirror or Monaco Active , where we already focused on entirely JavaScript-defined components, and which ended up as ๐ŸŒฑ [Meta] Plan for code components Active .

    Let me answer your questions ( #16 โœจ Config entity for storing code components Active ):

    1. This is where โœจ [exploratory] PoC of Preact+Tailwind components editable via CodeMirror or Monaco Active organically ended up, but we definitely left questions unanswered once we proved the core concepts. Other than the POC issue, the designs in Figma (soon to be shared with real links), and the parent issue for planning, we don't have a log of decisions.
      1. The schema to store props and slots;
      2. The way we render the component props form based on that schema.
    2. Let's see if we're in the absolute clear and in agreement about #2, and what implementation makes sense, then we can figure out the answer.

    Our requirements are to be able to store props and slots, then generate a component props form the same way we do for SDCs.

    Pinged @effulgentsia to add anything I missed that's relevant to the config entity.

  • ๐Ÿ‡ฌ๐Ÿ‡งUnited Kingdom f.mazeikis Brighton
  • ๐Ÿ‡บ๐Ÿ‡ธUnited States effulgentsia

    Where can I read the rationale behind that decision?

    Right here is the first place :)

    Back when we were doing the PoC referenced in #16, we hadn't yet come up with the concept of ComponentSource plugins. At that time, I was thinking that all components (e.g., Twig-based SDCs, Blocks, JS components, no-code components, etc.) could be exposed to the SDC plugin manager as SDCs. That would have required submitting an MR to change core's SDC plugin manager, or for XB to decorate core's SDC plugin manager. Which from an implementation perspective would have been fine if we had thought that was a good approach.

    Part of why I was thinking along those lines is that core's SDC plugin manager is named ComponentPluginManager and the way you render SDCs is with '#type' => 'component', so I was envisioning this as being the contract for all components, not just "stateless UI objects implemented by a Twig file and a YAML file colocated in the same directory".

    However, when it came time to implement Blocks as XB components, I think @pdureau said it best in #3462241-9: [PP-1] Decorate the SDC plugin manager and allow components defined in code โ†’ :

    Block plugins are stateful, context-aware, applicative objects.
    SDC components are stateless, context agnostic, UI objects.
    Different beasts.

    Which led to us now having ComponentSource plugins.

    Now that we have that concept, we can ask: what kinds of components should be SDCs, and what kinds of components should be some other kind of ComponentSource plugin. If we use @pdureau's definition above, then (in-browser-editable) (JS) Code Components could still be thought of SDCs as far as meeting that definition. However:

    • "SDC" stands for "single directory". There is no directory for the Code Components desired by this issue and its siblings: all the info is coming from the config entity described by this issue's summary.
    • Core's implementation of SDCs is coupled to there being a (non-config) YAML file and a Twig file; we'd have to change that implementation if we want the metadata coming from somewhere else (like config) and the code coming from somewhere else (like JS exclusively, no Twig).

    So our choices are:

    • Change the name and implementation of SDC so that it's no longer restricted to the concept of "single directory".
    • Change the implementation of SDC so that it's no longer restricted to the concept of "single directory", but retain the name despite it no longer being accurate.
    • Keep SDC as it is, and implement a new ComponentSource plugin for config-backed JS components.

    All of those options seem reasonable to me. #3 feels like a good pragmatic low-resistance choice.

    Which aspects are expected to be identical to SDC, and which ones are not?

    • Different: The metadata for an SDC lives in a non-config YAML file. The metadata for Code Components lives in the config entity proposed by this issue. Identical: The syntax and semantics of props and slots is the same.
    • Different: SDCs are rendered via Twig. Code Components are rendered (without Twig) to an <astro-island> element that references JS code from the config entity (detail about that to be discussed in โœจ Create a ComponentSource plugin for JS components Active ). Identical: Both SDCs and Code Components meet @pdureau's definition of "stateless [with respect to server state], context agnostic, UI objects."

    Of the aspects that are expected to be identical, do we expect to chase upstream SDC changes (i.e. commit to maintaining compatibility)?

    Ideally, yes, and if we can keep that parity without code duplication (i.e., use the same validation logic for props and slots, and the same way of mapping prop schema to field widgets, and the same props edit form, etc.), that would be best.

    In practice, some drift is acceptable. For example, when new JSON schema options for props get added for SDCs, it's okay if Code Components don't benefit from that until someone notices the discrepancy and submits an MR to bring them back to parity.

  • ๐Ÿ‡บ๐Ÿ‡ธUnited States effulgentsia

    Up until now, the XB team has been following a pseudo-scrum/pseudo-kanban process, but we're now shifting into more conventional scrum. We started a new 2-week sprint last Thursday (Jan 16). I'm tagging our current sprint's issues for visibility.

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    FYI: this also blocks โœจ Create a ComponentSource plugin for JS components Active .

    @balintbrews in #17: great, that answers #16.2, which is the most critical bit.

    #19: Thank you for this wonderful comment! ๐Ÿคฉ๐Ÿ™ Crediting @pdureau ๐Ÿ˜Š

  • ๐Ÿ‡ซ๐Ÿ‡ทFrance pdureau Paris

    Crediting @pdureau

    Thanks, it is an honor ๐Ÿ˜Š

    Code Components are rendered (without Twig) to an element t

    So, does that mean we are switching /ui/src/ to Astro (still using React component, but different framework) ?

  • ๐Ÿ‡ง๐Ÿ‡ชBelgium wim leers Ghent ๐Ÿ‡ง๐Ÿ‡ช๐Ÿ‡ช๐Ÿ‡บ

    I hear that

    ๐Ÿ™ This needs to be validated against the SDC json schema, because these are essentially config-defined SDCs. https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas...

    was not clear to neither @f.mazeikis nor @tedbow.

    The discussion on the issue is crystal-clear: both @balintbrews and @effulgentsia clarified above (#17 + #19) that these โ€œJS code componentsโ€ must have the exact same syntax and semantics for props and slots. Duplicating that validation logic from the SDC subsystem A) risks deviating, B) is pointless duplication.

    The technical implementation of how to achieve that is a bit tricky:

    • Drupal (config) entities are validated by validation constraints, not by JSON schema (which SDC uses)
    • Config entities' validation constraints are defined in config schema.
    • A single validation constraint can apply to a single value, or an entire tree of values. So we must define a new validation constraint for the props key-value pair that this new config entity will contain, and "just" apply JSON schema validation to it.

    I'll get that started.

  • ๐Ÿ‡ซ๐Ÿ‡ฎFinland lauriii Finland

    So, does that mean we are switching /ui/src/ to Astro (still using React component, but different framework) ?

    We are not shifting XB UI itself to using Astro. Astro is used for loading JavaScript code components in the preview and in the frontend. If you are not using JavaScript code components, Astro is not being used. Astro allows JavaScript code components to built with React, Preact, Svelte, Vue, and SolidJS. Experience Builder will provide an in-browser experience for authoring these components using Preact, and CLI tooling that allows adding components using other supported frameworks.

Production build 0.71.5 2024