Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions projects/packages/premium-analytics/changelog/add-site-sync
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Add site-sync package (useSyncStatus hook) and configure apiFetch auth in init.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Expose the analytics initial-full-sync milestone (initial_full_sync_finished) on Jetpack's sync status REST response so the dashboard can read it live on every poll, not just at page load.
2 changes: 2 additions & 0 deletions projects/packages/premium-analytics/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
},
"dependencies": {
"@automattic/charts": "workspace:*",
"@automattic/jetpack-script-data": "workspace:*",
"@automattic/number-formatters": "workspace:*",
"@automattic/ui": "1.0.2",
"@date-fns/tz": "1.4.1",
Expand Down Expand Up @@ -68,6 +69,7 @@
"@storybook/react": "10.3.6",
"@tanstack/react-query-devtools": "5.90.2",
"@testing-library/dom": "10.4.1",
"@testing-library/react": "16.3.2",
"@types/jest": "30.0.0",
"@typescript/native-preview": "7.0.0-dev.20260225.1",
"@wordpress/base-styles": "8.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
"module": "build-module/index.mjs",
"wpScriptModuleExports": "./build-module/index.mjs",
"dependencies": {
"@automattic/jetpack-script-data": "workspace:*",
"@wordpress/api-fetch": "7.48.0",
"@wordpress/boot": "0.14.1",
"@wordpress/data": "10.48.0",
"@wordpress/icons": "^13.0.0"
Expand Down
32 changes: 32 additions & 0 deletions projects/packages/premium-analytics/packages/init/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,47 @@
/**
* External dependencies
*/
import { getScriptData } from '@automattic/jetpack-script-data';
import apiFetch from '@wordpress/api-fetch';
import { store as bootStore } from '@wordpress/boot';
import { dispatch } from '@wordpress/data';
import { chartBar } from '@wordpress/icons';

// apiFetch middleware registers onto a shared, process-wide chain. Guard so
// repeated init() calls (re-mount, HMR, a future second boot) don't stack
// duplicate root-URL/nonce middleware.
let authConfigured = false;

/**
* Configure the bundled apiFetch instance with the WordPress REST API root URL
* and authentication nonce from Jetpack script data. Runs once before routes
* render so shared packages (e.g. site-sync) can call the REST API.
*/
function setupApiFetch(): void {
if ( authConfigured ) {
return;
}
const site = getScriptData()?.site;
if ( site?.rest_root ) {
apiFetch.use( apiFetch.createRootURLMiddleware( site.rest_root ) );
}
if ( site?.rest_nonce ) {
apiFetch.use( apiFetch.createNonceMiddleware( site.rest_nonce ) );
}
// Only latch once we actually registered, so an early call before
// script-data is ready doesn't permanently skip configuration.
if ( site?.rest_root || site?.rest_nonce ) {
authConfigured = true;
}
}

/**
* Initialize the Jetpack Analytics app.
* Runs before routes render.
*/
export async function init(): Promise< void > {
setupApiFetch();

dispatch( bootStore ).updateMenuItem( 'dashboard', {
icon: chartBar,
} );
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"private": true,
"name": "@automattic/jetpack-premium-analytics-site-sync",
"version": "0.1.0",
"type": "module",
"wpScript": true,
"module": "build-module/index.mjs",
"wpScriptModuleExports": "./build-module/index.mjs",
"dependencies": {
"@automattic/jetpack-script-data": "workspace:*",
"@wordpress/api-fetch": "7.48.0",
"@wordpress/i18n": "^6.9.0",
"react": "18.3.1"
},
"devDependencies": {
"@testing-library/react": "16.3.2"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* External dependencies
*/
import apiFetch from '@wordpress/api-fetch';
/**
* Internal dependencies
*/
import { SYNC_STATUS_PATH } from '../constants';
import type { SyncStatusApiResponse } from '../types';

/**
* Fetch the current sync status from Jetpack core.
*
* @return The current sync status.
*/
export function fetchSyncStatus(): Promise< SyncStatusApiResponse > {
return apiFetch( { path: SYNC_STATUS_PATH } );
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* External dependencies
*/
import apiFetch from '@wordpress/api-fetch';
/**
* Internal dependencies
*/
import { FULL_SYNC_PATH } from '../constants';

/**
* Trigger a Jetpack full sync.
*
* @return The full-sync trigger response.
*/
export function triggerFullSync(): Promise< unknown > {
return apiFetch( { path: FULL_SYNC_PATH, method: 'POST' } );
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Polling interval in milliseconds.
*/
export const POLL_INTERVAL = 3_000;

/**
* Consecutive poll failures tolerated before polling gives up. A transient
* error (a network blip, a 500) is retried on the next tick; only a sustained
* run of failures stops polling and surfaces a terminal error.
*/
export const MAX_POLL_FAILURES = 3;

/**
* Jetpack core sync status endpoint (queue + full-sync state).
*/
export const SYNC_STATUS_PATH = '/jetpack/v4/sync/status';

/**
* Jetpack core full-sync trigger endpoint.
*/
export const FULL_SYNC_PATH = '/jetpack/v4/sync/full-sync';

/**
* Sync-module key whose progress gates the analytics dashboard. Mirrors the
* backend default (`Sync_Status_Tracker::ANALYTICS_SYNC_MODULE`).
*/
export const ANALYTICS_SYNC_MODULE = 'woocommerce_analytics';
Loading
Loading