feat(media): Optimize Media Manager loading performance

Significant performance improvements to the 'Loading media...' phase:
- Reduced client-server round trips by consolidating the initial handshake (diagnostics + media fetch) into a single backend call: getMediaManagerInitialState.
- Implemented batched Google Drive metadata retrieval in GASDriveService using the Advanced Drive API, eliminating per-file property fetching calls.
- Switched to HtmlService templates in showMediaManager to pass initial SKU/Title data directly, enabling the UI shell to appear instantly upon opening.
- Updated documentation (ARCHITECTURE.md, MEMORY.md) to clarify Webpack global assignment requirements for GAS functions.
- Verified with comprehensive updates to unit and integration tests.
This commit is contained in:
Ben Miller
2025-12-31 09:46:56 -07:00
parent fc25e877f1
commit e39bc862cc
11 changed files with 314 additions and 150 deletions

View File

@ -8,7 +8,14 @@ import { Config } from "./config"
import { Product } from "./Product"
export function showMediaManager() {
const html = HtmlService.createHtmlOutputFromFile("MediaManager")
const productInfo = getSelectedProductInfo();
const template = HtmlService.createTemplateFromFile("MediaManager");
// Pass variables to template
(template as any).initialSku = productInfo ? productInfo.sku : "";
(template as any).initialTitle = productInfo ? productInfo.title : "";
const html = template.evaluate()
.setTitle("Media Manager")
.setWidth(1100)
.setHeight(750);
@ -193,6 +200,62 @@ export function getMediaDiagnostics(sku: string) {
}
}
export function getMediaManagerInitialState(providedSku?: string, providedTitle?: string): {
sku: string | null,
title: string,
diagnostics: any,
media: any[],
token: string
} {
let sku = providedSku;
let title = providedTitle || "";
if (!sku) {
const info = getSelectedProductInfo();
if (info) {
sku = info.sku;
title = info.title;
}
}
if (!sku) {
return {
sku: null,
title: "",
diagnostics: null,
media: [],
token: ScriptApp.getOAuthToken()
}
}
const config = new Config()
const driveService = new GASDriveService()
const shop = new Shop()
const shopifyMediaService = new ShopifyMediaService(shop)
const networkService = new GASNetworkService()
const mediaService = new MediaService(driveService, shopifyMediaService, networkService, config)
// Resolve Product ID
const product = new Product(sku)
try {
product.MatchToShopifyProduct(shop);
} catch (e) {
console.warn("MatchToShopifyProduct failed", e);
}
const shopifyId = product.shopify_id || ""
const initialState = mediaService.getInitialState(sku, shopifyId);
return {
sku,
title,
diagnostics: initialState.diagnostics,
media: initialState.media,
token: ScriptApp.getOAuthToken()
}
}
export function linkDriveFileToShopifyMedia(sku: string, driveId: string, shopifyId: string) {
const config = new Config()
const driveService = new GASDriveService()