diff --git a/package.json b/package.json index 726e90887d..1dcd663fe7 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "@processmaker/vue-form-elements": "0.65.6", "@processmaker/vue-multiselect": "2.3.0", "@tinymce/tinymce-vue": "2.0.0", - "axios": "^0.27.2", + "axios": "^1.15.2", "bootstrap": "^4.5.3", "bootstrap-vue": "^2.18.1", "bpmn-font": "^0.10.0", diff --git a/resources/js/bootstrap.js b/resources/js/bootstrap.js index 0ea799903c..e8dceb55cc 100644 --- a/resources/js/bootstrap.js +++ b/resources/js/bootstrap.js @@ -4,7 +4,8 @@ import * as bootstrap from "bootstrap"; import TenantAwareEcho from "./common/TenantAwareEcho"; import { initSessionSync } from "./common/sessionSync"; import Router from "vue-router"; -import ScreenBuilder, { initializeScreenCache } from "@processmaker/screen-builder"; +import ScreenBuilder from "@processmaker/screen-builder"; +import attachScreenCacheAdapter from "./common/attachScreenCacheAdapter"; import * as VueDeepSet from "vue-deepset"; /** @@ -393,8 +394,9 @@ window.ProcessMaker.screen = { cacheTimeout: Number(screenCacheTimeout), secureHandlerToggleVisible: !!Number(screenSecureHandlerToggleVisible?.content), }; -// Initialize screen-builder cache -initializeScreenCache(window.ProcessMaker.apiClient, window.ProcessMaker.screen); +// Axios 1.x uses adapter name list on defaults.adapter, not a function. screen-builder's +// initializeScreenCache passes that through to cacheAdapterEnhancer and breaks dispatch. +attachScreenCacheAdapter(window.ProcessMaker.apiClient, window.ProcessMaker.screen); const clickTab = () => { const { hash } = window.location; diff --git a/resources/js/common/attachScreenCacheAdapter.js b/resources/js/common/attachScreenCacheAdapter.js new file mode 100644 index 0000000000..f9c41a4949 --- /dev/null +++ b/resources/js/common/attachScreenCacheAdapter.js @@ -0,0 +1,30 @@ +import { cacheAdapterEnhancer } from "axios-extensions"; +import * as LRUCacheModule from "lru-cache"; + +// Root install may hoist lru-cache@5 (default export only) or v10 (named LRUCache); screen-builder uses v10 API. +const LRUCache = LRUCacheModule.LRUCache ?? LRUCacheModule.default; + +/** + * Wraps the axios HTTP adapter with screen-builder GET caching (axios-extensions). + * Axios 1.x sets defaults.adapter to adapter names (e.g. ['xhr','http','fetch']), not a + * function; cacheAdapterEnhancer must receive the resolved adapter from getAdapter(). + * + * @param {import("axios").AxiosInstance} apiClient + * @param {{ cacheEnabled: boolean, cacheTimeout: number }} screen + */ +export default function attachScreenCacheAdapter(apiClient, screen) { + const raw = apiClient.defaults.adapter; + const baseAdapter = typeof raw === "function" + ? raw + : apiClient.getAdapter(raw); + + apiClient.defaults.adapter = cacheAdapterEnhancer(baseAdapter, { + enabledByDefault: screen.cacheEnabled, + cacheFlag: "useCache", + defaultCache: new LRUCache({ + max: 100, + ttl: screen.cacheTimeout, + maxAge: screen.cacheTimeout, + }), + }); +} diff --git a/resources/js/next/screenBuilder.js b/resources/js/next/screenBuilder.js index d0d009849e..b86d8d3c7e 100644 --- a/resources/js/next/screenBuilder.js +++ b/resources/js/next/screenBuilder.js @@ -1,6 +1,7 @@ import { getGlobalVariable, setGlobalVariable, getGlobalPMVariable, setGlobalPMVariable, } from "./globalVariables"; +import attachScreenCacheAdapter from "../common/attachScreenCacheAdapter"; const addScriptsToDOM = async function (scripts) { for (const script of scripts) { @@ -26,7 +27,6 @@ export default () => { import("@processmaker/screen-builder").then((ScreenBuilder) => { const apiClient = getGlobalPMVariable("apiClient"); - const { initializeScreenCache } = ScreenBuilder; // Configuration Global object used by ScreenBuilder // @link https://processmaker.atlassian.net/browse/FOUR-6833 Cache configuration const screenCacheEnabled = document.head.querySelector("meta[name=\"screen-cache-enabled\"]")?.content ?? "false"; @@ -42,8 +42,7 @@ export default () => { setGlobalVariable("ScreenBuilder", ScreenBuilder); setGlobalPMVariable("screen", screen); - // Initialize screen-builder cache - initializeScreenCache(apiClient, screen);// TODO: Its a bad practice to use the apiClient here + attachScreenCacheAdapter(apiClient, screen); if (screenBuilderScripts) { addScriptsToDOM(screenBuilderScripts).then(() => { // The order of the scripts is important, the screenBuilderScripts must be loaded before the ScreenBuilder.default diff --git a/webpack.mix.js b/webpack.mix.js index 01253ace95..3291eac28a 100644 --- a/webpack.mix.js +++ b/webpack.mix.js @@ -28,6 +28,11 @@ mix.webpackConfig({ alias: { "vue-monaco": path.resolve(__dirname, "resources/js/vue-monaco-amd.js"), styles: path.resolve(__dirname, "resources/sass"), + // axios-extensions still imports axios 0.x deep paths; axios 1 only exposes them via "unsafe" (or alias here). + "axios/lib/helpers/buildURL": path.resolve( + __dirname, + "node_modules/axios/lib/helpers/buildURL.js", + ), }, }, });