Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
7869dab
add premium-analytics plugin
retrofox Apr 14, 2026
b6b3e00
add composer.lock for premium-analytics plugin
retrofox Apr 14, 2026
c63c65b
fix autoloader suffix version to match alpha tag
retrofox Apr 14, 2026
cce9082
update pnpm-lock.yaml for premium-analytics plugin
retrofox Apr 14, 2026
9bdde21
fix CI checks for premium-analytics plugin
retrofox Apr 14, 2026
851c081
remove wp-plugin-slug and update composer.lock
retrofox Apr 14, 2026
5865f61
remove textdomain phpcs config from internal plugin
retrofox Apr 14, 2026
35f7b41
remove i18n from internal plugin error strings
retrofox Apr 14, 2026
b81ec86
Update projects/plugins/premium-analytics/.gitattributes
retrofox Apr 14, 2026
ecf8b90
remove empty phpcs, phan baseline, and package.json
retrofox Apr 14, 2026
86ea16e
allow consumer to configure admin menu title
retrofox Apr 15, 2026
97db882
Merge branch 'trunk' into update/premium-analytics-plugin
retrofox Apr 15, 2026
4e68e5a
add placeholder test for premium-analytics plugin
retrofox Apr 15, 2026
61e4b82
add analytics package with wp-build SPA framework
retrofox Apr 10, 2026
3e8267b
add wpPlugin.packageSources via pnpm patch on @wordpress/build
retrofox Apr 14, 2026
3c5141d
add patches README documenting wp-build patch methodology
retrofox Apr 14, 2026
54d3669
add packageSources and number-formatters to premium-analytics
retrofox Apr 14, 2026
d444f71
add static and dynamic import examples for number-formatters
retrofox Apr 14, 2026
2787d7e
move wp-build patch to .pnpm-patches and remove patches dir
retrofox Apr 14, 2026
e9b7a96
fix pnpm-lock.yaml versions after rebase
retrofox Apr 15, 2026
bfa35ad
suppress phan warning for wp-build generated function
retrofox Apr 14, 2026
a0d4232
update phan baseline to match CI format
retrofox Apr 14, 2026
348dddc
add PHPUnit tests for script module collision behavior
retrofox Apr 14, 2026
a0abf75
add changelog for script module collision tests
retrofox Apr 14, 2026
f8a080c
update composer.lock for premium-analytics plugin
retrofox Apr 14, 2026
acb1e48
add changelog for premium-analytics plugin
retrofox Apr 14, 2026
46a4b2d
fix version mismatch in analytics package.json
retrofox Apr 14, 2026
fe28063
add changelog for analytics version fix
retrofox Apr 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
584 changes: 584 additions & 0 deletions .pnpm-patches/@wordpress__build@0.11.0.patch

Large diffs are not rendered by default.

2,261 changes: 1,208 additions & 1,053 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ ignoredOptionalDependencies:
# Dependencies needing patching.
patchedDependencies:

# Add wpPlugin.packageSources for cross-directory package discovery.
# Upstream PR: https://github.com/WordPress/gutenberg/pull/77226
'@wordpress/build@0.11.0': .pnpm-patches/@wordpress__build@0.11.0.patch

# Vite/esbuild doesn't like the `__esModule` + `exports["default"]` pattern, it winds up double-wrapping the default.
# See also https://github.com/WordPress/gutenberg/issues/39619
react-autosize-textarea: .pnpm-patches/react-autosize-textarea.patch
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Significance: patch
Type: changed
Comment: Patch significance.

Add wpScriptModuleExports field for wp-build script module support
1 change: 1 addition & 0 deletions projects/js-packages/number-formatters/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"main": "./dist/cjs/index.cjs",
"module": "./dist/esm/index.js",
"types": "./dist/types/index.d.ts",
"wpScriptModuleExports": ".",
"scripts": {
"build": "pnpm run clean && pnpm run build:ts",
"build:ts": "duel --dirs",
Expand Down
16 changes: 16 additions & 0 deletions projects/packages/analytics/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Files not needed to be distributed in the package.
.gitattributes export-ignore
.github/ export-ignore
package.json export-ignore

# Files to include in the mirror repo, but excluded via gitignore
# Remember to end all directories with `/**` to properly tag every file.
/build/** production-include

# Files to exclude from the mirror repo, but included in the monorepo.
# Remember to end all directories with `/**` to properly tag every file.
.gitignore production-exclude
changelog/** production-exclude
.phpcs.dir.xml production-exclude
tests/** production-exclude
.phpcsignore production-exclude
6 changes: 6 additions & 0 deletions projects/packages/analytics/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
vendor/
node_modules/
build/
build-module/
composer.lock
.phpunit.cache/
20 changes: 20 additions & 0 deletions projects/packages/analytics/.phan/baseline.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
/**
* This is an automatically generated baseline for Phan issues.
* When Phan is invoked with --load-baseline=path/to/baseline.php,
* The pre-existing issues listed in this file won't be emitted.
*
* This file can be updated by invoking Phan with --save-baseline=path/to/baseline.php
* (can be combined with --load-baseline)
*/
return [
// # Issue statistics:
// PhanUndeclaredFunction : 1 occurrence

// Currently, file_suppressions and directory_suppressions are the only supported suppressions
'file_suppressions' => [
'src/class-analytics.php' => ['PhanUndeclaredFunction'],
],
// 'directory_suppressions' => ['src/directory_name' => ['PhanIssueName1', 'PhanIssueName2']] can be manually added if needed.
// (directory_suppressions will currently be ignored by subsequent calls to --save-baseline, but may be preserved in future Phan releases)
];
13 changes: 13 additions & 0 deletions projects/packages/analytics/.phan/config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php
/**
* This configuration will be read and overlaid on top of the
* default configuration. Command-line arguments will be applied
* after this file is read.
*
* @package automattic/jetpack-analytics
*/

// Require base config.
require __DIR__ . '/../../../../.phan/config.base.php';

return make_phan_config( dirname( __DIR__ ) );
24 changes: 24 additions & 0 deletions projects/packages/analytics/.phpcs.dir.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0"?>
<ruleset>

<rule ref="WordPress.WP.I18n">
<properties>
<property name="text_domain" type="array">
<element value="jetpack-analytics" />
</property>
</properties>
</rule>
<rule ref="Jetpack.Functions.I18n">
<properties>
<property name="text_domain" value="jetpack-analytics" />
</properties>
</rule>

<rule ref="WordPress.Utils.I18nTextDomainFixer">
<properties>
<property name="old_text_domain" type="array" />
<property name="new_text_domain" value="jetpack-analytics" />
</properties>
</rule>

</ruleset>
7 changes: 7 additions & 0 deletions projects/packages/analytics/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

132 changes: 132 additions & 0 deletions projects/packages/analytics/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Jetpack Analytics

Analytics dashboard package for Jetpack sites. Built on `@wordpress/build` and the
`@wordpress/boot` SPA framework.

## Architecture

This is a **Composer package** (`automattic/jetpack-analytics`) — not a plugin. Any plugin
can consume it by adding the dependency and calling `Analytics::init()`.

```
Package (this) Plugin (consumer)
┌─────────────────────┐ ┌──────────────────────┐
│ wp-build app │ │ autoloader │
│ ├── routes/ │ require │ Analytics::init() │
│ ├── packages/init/ │◄─────────│ │
│ ├── shims/ │ │ (that's it) │
│ └── build/ (gen) │ └──────────────────────┘
│ │
│ src/class-analytics │
│ ├── load build.php │
│ ├── add_menu_page() │
│ └── sidebar items │
└─────────────────────┘
```

### How it works

1. `Analytics::init()` loads `build/build.php` — the auto-generated entry point from `@wordpress/build`
2. `build.php` registers an interceptor on `admin_init` that checks for `?page=jetpack-analytics`
3. When the page is requested, the interceptor renders a full-page HTML shell with `@wordpress/boot`
4. Boot initializes the SPA: sidebar, routing, init modules
5. Routes are loaded as ES modules — `routes/dashboard/stage.tsx` renders the dashboard

### Consumer plugins

The package is designed to be activated from different contexts:

- **Standalone plugin** (`projects/plugins/analytics/`) — thin wrapper, calls `Analytics::init()`
- **Jetpack plugin** — via feature flag, call `Analytics::init()` conditionally
- **Any other plugin** — `composer require automattic/jetpack-analytics` + `Analytics::init()`

## Requirements

- **PHP** >= 7.2
- **Gutenberg plugin** — provides `@wordpress/boot`, `@wordpress/route`, and `@wordpress/a11y`
as script modules. Required until WordPress Core 7.0+ ships these natively.

## Development

### Build

```bash
# From the package directory
pnpm run build

# Or via Jetpack CLI
jetpack build packages/analytics
```

### Watch

```bash
pnpm run watch
```

### Adding a new route

1. Create `routes/<name>/package.json`:
```json
{
"name": "<name>-route",
"route": {
"path": "/<name>",
"page": "jetpack-analytics"
}
}
```

2. Create `routes/<name>/stage.tsx` exporting `stage()`:
```tsx
export const stage = () => <div>My new page</div>;
```

3. Rebuild — `@wordpress/build` auto-discovers routes from `package.json` metadata.

4. Optionally register a sidebar item in `class-analytics.php`:
```php
jpa_register_jetpack_analytics_menu_item( 'name', 'Label', '/name' );
```

## Known issues

### Boot asset shim (`shims/boot-asset.php`)

`@wordpress/build` v0.10.0 removed local bundling of `@wordpress/boot` (expects Core 7.0+
or Gutenberg). However, the generated `page.php` template still looks for a local
`modules/boot/index.min.asset.php` to determine classic script prerequisites. Without it,
no scripts are enqueued and the page is blank.

The shim provides the dependency list so the template works. Gutenberg provides the actual
boot JS module at runtime. This shim can be removed when `@wordpress/build` updates the
template to handle external boot, or when the minimum WordPress version is 7.0+.

### Init module (`packages/init/`)

The init module serves two purposes:
1. Configures the dashboard menu icon via `@wordpress/boot` store
2. Triggers `@wordpress/build` to process `@wordpress/boot` as a module dependency — without
an init module that imports boot, the build has no reason to track it

## File structure

```
analytics/
├── composer.json # PHP package: automattic/jetpack-analytics
├── package.json # wp-build config, JS dependencies
├── tsconfig.json # TypeScript configuration
├── src/
│ └── class-analytics.php # PHP entry point
├── packages/
│ └── init/ # App initialization (runs before routes)
│ ├── package.json # { wpScript: true } module
│ └── src/index.ts
├── routes/
│ └── dashboard/ # Dashboard route (/)
│ ├── package.json # { route: { path: "/", page: "..." } }
│ └── stage.tsx # React component
├── shims/
│ └── boot-asset.php # Boot prereqs shim (see Known Issues)
└── build/ # Auto-generated by wp-build (gitignored)
```
4 changes: 4 additions & 0 deletions projects/packages/analytics/changelog/fix-version-mismatch
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Fixed version mismatch in package.json.
4 changes: 4 additions & 0 deletions projects/packages/analytics/changelog/initial-version
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: added

Initial version.
61 changes: 61 additions & 0 deletions projects/packages/analytics/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"name": "automattic/jetpack-analytics",
"description": "Analytics dashboard for Jetpack sites.",
"type": "jetpack-library",
"license": "GPL-2.0-or-later",
"require": {
"php": ">=7.2"
},
"require-dev": {
"yoast/phpunit-polyfills": "^4.0.0",
"automattic/jetpack-changelogger": "@dev",
"automattic/phpunit-select-config": "@dev"
},
"autoload": {
"classmap": [
"src/"
]
},
"scripts": {
"phpunit": [
"phpunit-select-config phpunit.#.xml.dist --colors=always"
],
"test-coverage": [
"php -dpcov.directory=. ./vendor/bin/phpunit-select-config phpunit.#.xml.dist --coverage-php \"$COVERAGE_DIR/php.cov\""
],
"test-php": [
"@composer phpunit"
],
"build-development": [
"pnpm run build"
],
"build-production": [
"pnpm run build-production"
]
},
"repositories": [
{
"type": "path",
"url": "../*",
"options": {
"monorepo": true
}
}
],
"minimum-stability": "dev",
"prefer-stable": true,
"extra": {
"autotagger": true,
"mirror-repo": "Automattic/jetpack-analytics",
"textdomain": "jetpack-analytics",
"version-constants": {
"::PACKAGE_VERSION": "src/class-analytics.php"
},
"changelogger": {
"link-template": "https://github.com/Automattic/jetpack-analytics/compare/${old}...${new}"
},
"branch-alias": {
"dev-trunk": "0.1.x-dev"
}
}
}
44 changes: 44 additions & 0 deletions projects/packages/analytics/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "jetpack-analytics-app",
"version": "0.1.0-alpha",
"private": true,
"type": "module",
"scripts": {
"build": "wp-build && mkdir -p build/modules/boot && cp shims/boot-asset.php build/modules/boot/index.min.asset.php",
"build-production": "NODE_ENV=production wp-build && mkdir -p build/modules/boot && cp shims/boot-asset.php build/modules/boot/index.min.asset.php",
"watch": "wp-build --watch"
},
"wpPlugin": {
"name": "jpa",
"packageNamespace": "jetpack-analytics",
"handlePrefix": "jetpack-analytics",
"pages": [
{
"id": "jetpack-analytics",
"init": [
"@jetpack-analytics/init"
]
}
],
"externalNamespaces": {
"wordpress": {
"global": "wp",
"handlePrefix": "wp"
}
}
},
"dependencies": {
"@wordpress/boot": "0.10.0",
"@wordpress/data": "10.43.0",
"@wordpress/i18n": "^6.9.0",
"@wordpress/icons": "^11.3.0",
"@wordpress/route": "0.9.0",
"react": "18.3.1",
"react-dom": "18.3.1"
},
"devDependencies": {
"@babel/core": "7.29.0",
"@wordpress/build": "0.11.0",
"browserslist": "4.25.2"
}
}
14 changes: 14 additions & 0 deletions projects/packages/analytics/packages/init/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"private": true,
"name": "@jetpack-analytics/init",
"version": "0.1.0",
"type": "module",
"wpScript": true,
"module": "build-module/index.mjs",
"wpScriptModuleExports": "./build-module/index.mjs",
"dependencies": {
"@wordpress/boot": "0.10.0",
"@wordpress/data": "10.43.0",
"@wordpress/icons": "^11.3.0"
}
}
16 changes: 16 additions & 0 deletions projects/packages/analytics/packages/init/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* External dependencies
*/
import { store as bootStore } from '@wordpress/boot';
import { dispatch } from '@wordpress/data';
import { chartBar } from '@wordpress/icons';

/**
* Initialize the Jetpack Analytics app.
* Runs before routes render.
*/
export async function init(): Promise< void > {
dispatch( bootStore ).updateMenuItem( 'dashboard', {
icon: chartBar,
} );
}
Loading
Loading