Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Interactivity API: implement the new store() API #11065

Closed
26 tasks done
DAreRodz opened this issue Sep 28, 2023 · 6 comments · Fixed by #11071
Closed
26 tasks done

Interactivity API: implement the new store() API #11065

DAreRodz opened this issue Sep 28, 2023 · 6 comments · Fixed by #11071
Labels
type: enhancement The issue is a request for an enhancement.

Comments

@DAreRodz
Copy link
Collaborator

DAreRodz commented Sep 28, 2023

This tracking issue lists all the requirements to implement the new store() API, which is the Interactivity API's state manager.

The whole API proposal is extensively detailed in WordPress/gutenberg#53586, and the idea is to first develop store() here in WooCommerce Blocks and, once most of the API is tested and functioning, move all the code to Gutenberg and add proper, automated testing, documentation, etc.

This feature is being implemented in the following PR:

You can check an example of the Product Button using it in the following branch:

Tasks

  • The default namespace is stored in data-wp-interactive
  • The namespace is passed as a string during store creation
  • Stores return stable references to their properties
  • External stores can be accessed using the same API
  • Multiple parts of the same store can be defined in different files
  • Objects returned by store() are typed
  • External consumers can import a typed store
  • Contextual values like context or ref should be accessed inside the functions
  • Actions are just regular JavaScript functions
  • Derived state (selectors) can use getters
  • Derived state (selectors) can be moved back to state
  • Defining the initial state in the server
  • Types from the initial server state
  • Accessing other namespaces in the directives
  • Creating and accessing context from other namespaces in the directives
  • Accessing context from other namespaces in the store
  • Typing contexts
  • Async Actions should use generators instead of async/await
  • Stores should be able to import logic dynamically
  • Stores should be able to build façades of their public APIs
  • Stores should be able to define getters and functions anywhere (not only in state or actions)
  • Element-related APIs (getElement()) New Interactivity `store()` API proposal WordPress/gutenberg#53586 (reply in thread)
  • Private stores Private store references WordPress/gutenberg#51596 (comment)
  • Deep merge the raw stores instead of the proxies

Migration

@DAreRodz DAreRodz added the type: enhancement The issue is a request for an enhancement. label Sep 28, 2023
@luisherranz
Copy link
Collaborator

Derived state (selectors) can be moved back to state

We need to think about this one. As of now, my only idea is to make the usage computed in getters optional in deepsignal using an options import similar to Preact's:

import { options } from "deepsignal";

options.computedGetters = false;

It's kind of a shame because when the value doesn't depend on the scope (context, element state, element ref), the computed's are fine.

@luisherranz
Copy link
Collaborator

As we're going to be proxying state anyway, maybe we could detect getters on our side and if they are run inside of a scope, move them to a map and wrap them with computeds ourselves. I'll try that in the next days 🙂

@luisherranz
Copy link
Collaborator

maybe we could detect getters on our side and if they are run inside of a scope, move them to a map and wrap them with computeds ourselves

It worked fine. I commented on the PR:

@luisherranz
Copy link
Collaborator

Now that this is completed, we've added a list of tasks for the next steps to the Gutenberg's Tracking Issue:

We can keep using this Tracking Issue to keep track of the individual tasks that we need to accomplish in Woo, like the migration of the different blocks.

Our next step is to open a PR with the new store() API in Gutenberg to make sure that the e2e tests that we have in Gutenberg pass.

@luisherranz
Copy link
Collaborator

luisherranz commented Nov 2, 2023

Okay, now that that is completed, the next task is to migrate all the existing blocks:

  • Product Button block
  • Products Collection block
  • Product Gallery block

@DAreRodz and I will take care of the Product Button and Products Collection blocks, and we'll help the Woo team with the rest of the blocks.

Once we've merged the interactivity-api-new-store-api branch in trunk, we will start migrating the blocks that are still in progress:

  • Filter blocks

@sunyatasattva could you please take a look and update the list of blocks if necessary?

@DAreRodz
Copy link
Collaborator Author

DAreRodz commented Nov 17, 2023

All the migration work is done (only awaiting approval in #11071 and e2e tests to be fixed).

As a wrap-up, I'll summarize the tasks for subsequent PRs and all the notes left in the comments―all related to the Interactivity API runtime.

Tasks

  • Uncomment prefetch in the navigation-link directive. (link)
  • Use TSDocs to document the new APIs. (link)
  • Add elementState to the resolve scope. (link)

Notes

  • We must wrap error logs with if (SCRIPT_DEBUG) blocks in Gutenberg. (link, link)
  • We could consider removing the deep immutable logic from the getElement() production version. (link)
  • An API to access "computed"s would be required for future wp-text and wp-bind optimizations. (link)
  • We could (unlikely) face the case where a getter might run outside of scope and still need access to the default namespace. (link)

cc: @luisherranz

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
type: enhancement The issue is a request for an enhancement.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants