feat(extensions): add Tier 1 and Tier 2 storage APIs for extensions

Implement managed storage APIs for extensions with automatic namespace
isolation. Storage is automatically bound to extensions before module
execution, ensuring data privacy between extensions.

- Tier 1 (localState/sessionState): Browser-based storage with user isolation
- Tier 2 (ephemeralState): Server-side cache with TTL support
- Update webpack externals to support subpath imports like @apache-superset/core/storage
- Add storage documentation and update architecture docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Michael S. Molina
2026-04-07 16:17:04 -03:00
parent d796543f5a
commit bfcc05a56f
33 changed files with 2304 additions and 29 deletions

View File

@@ -164,8 +164,13 @@ Extensions configure Webpack to expose their entry points:
```javascript
externalsType: 'window',
externals: {
'@apache-superset/core': 'superset',
externals: ({ request }, callback) => {
// Map @apache-superset/core and subpaths to window.superset
if (request?.startsWith('@apache-superset/core')) {
const parts = request.replace('@apache-superset/core', 'superset').split('/');
return callback(null, parts);
}
callback();
},
plugins: [
new ModuleFederationPlugin({
@@ -187,7 +192,7 @@ This configuration does several important things:
**`exposes`** - Declares which modules are available to the host application. Superset always loads extensions by requesting the `./index` module from the remote container — this is a fixed convention, not a configurable value. Extensions must expose exactly `'./index': './src/index.tsx'` and place all API registrations (views, commands, menus, editors, event listeners) in that file. The module is executed as a side effect when the extension loads, so any call to `views.registerView`, `commands.registerCommand`, etc. made at the top level of `index.tsx` will run automatically.
**`externals` and `externalsType`** - Tell Webpack that when the extension imports `@apache-superset/core`, it should use `window.superset` at runtime instead of bundling its own copy. This ensures extensions use the host's implementation of shared packages.
**`externals` and `externalsType`** - Tell Webpack that when the extension imports from `@apache-superset/core` or its subpaths (like `@apache-superset/core/storage`), it should resolve to `window.superset` or `window.superset.storage` at runtime. The function-based externals returns an array of path segments, which Webpack uses for nested property access.
**`shared`** - Prevents duplication of common libraries like React and Ant Design. The `singleton: true` setting ensures only one instance of each library exists, avoiding version conflicts and reducing bundle size.