Skip to content

Commit

Permalink
Add an optional hook for fetchScriptData
Browse files Browse the repository at this point in the history
  • Loading branch information
volkanceylan committed Oct 14, 2024
1 parent 745c60b commit d9d05bd
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 6 deletions.
14 changes: 14 additions & 0 deletions packages/corelib/dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1684,6 +1684,20 @@ export interface PropertyItemsData {
* @returns The hash or null if no such known registration
*/
export declare function getScriptDataHash(name: string, reload?: boolean): string;
/**
* Hook for script data related operations
*/
export declare const scriptDataHooks: {
/**
* Provides a hook to override the default fetchScriptData implementation,
* it falls back to the default implementation if undefined is returned.
* It is recommended to use this hook mainly for test purposes.
* If the sync parameter is true (legacy/compat), then the result should be returned synchronously.
* DynJS parameter is true if the script is requested to be loaded via a dynamic script,
* and not a JSON request. This parameter is only true for the legacy/compat sync mode.
*/
fetchScriptData: <TData>(name: string, sync?: boolean, dynJS?: boolean) => TData | Promise<TData>;
};
/**
* Fetches a script data with given name via ~/DynamicData endpoint
* @param name Dynamic script name
Expand Down
21 changes: 21 additions & 0 deletions packages/corelib/src/base/scriptdata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,21 @@ export function getScriptDataHash(name: string, reload?: boolean): string {
return scriptDataHash[name];
}

/**
* Hook for script data related operations
*/
export const scriptDataHooks = {
/**
* Provides a hook to override the default fetchScriptData implementation,
* it falls back to the default implementation if undefined is returned.
* It is recommended to use this hook mainly for test purposes.
* If the sync parameter is true (legacy/compat), then the result should be returned synchronously.
* DynJS parameter is true if the script is requested to be loaded via a dynamic script,
* and not a JSON request. This parameter is only true for the legacy/compat sync mode.
*/
fetchScriptData: void 0 as <TData>(name: string, sync?: boolean, dynJS?: boolean) => TData | Promise<TData>
}

let fetchPromises: { [key: string]: Promise<any> } = {}

/**
Expand All @@ -52,6 +67,12 @@ let fetchPromises: { [key: string]: Promise<any> } = {}
* @returns A promise that will return data if successfull
*/
export function fetchScriptData<TData>(name: string): Promise<TData> {

const hookResult = scriptDataHooks.fetchScriptData?.<TData>(name);
if (hookResult != void 0) {
return Promise.resolve(hookResult);
}

let key = name + '?' + (getScriptDataHash(name) ?? '');

var promise: Promise<TData> = fetchPromises[key];
Expand Down
17 changes: 11 additions & 6 deletions packages/corelib/src/q/scriptdata-compat.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
Lookup, getColumnsScript, getFormScript, getGlobalObject, getLookupAsync, getRemoteDataAsync, getScriptData, getScriptDataHash, handleScriptDataError, peekScriptData, reloadLookupAsync,
requestFinished, requestStarting,
resolveUrl, setScriptData, type PropertyItem, type PropertyItemsData
resolveUrl, scriptDataHooks, setScriptData, type PropertyItem, type PropertyItemsData
} from "../base";

export namespace ScriptData {
Expand All @@ -24,6 +24,12 @@ export namespace ScriptData {
if (data != null)
return data;

data = scriptDataHooks.fetchScriptData?.<TData>(name, true, dynJS);
if (data !== void 0) {
set(name, data);
return data;
}

var url = resolveUrl(dynJS ? '~/DynJS.axd/' : '~/DynamicData/') + name + (dynJS ? '.js' : '') + '?v=' + (getScriptDataHash(name) ?? new Date().getTime());
var xhr = new XMLHttpRequest();
xhr.open("GET", url, false);
Expand All @@ -39,14 +45,13 @@ export namespace ScriptData {
script.text = xhr.responseText;
document.head.appendChild(script).parentNode.removeChild(script);
data = peekScriptData(name);
if (data == null)
handleScriptDataError(name);
}

data = JSON.parse(xhr.responseText);
else {
data = JSON.parse(xhr.responseText);
}
if (data == null)
handleScriptDataError(name);
if (name.startsWith("Lookup."))
if (!dynJS && name.startsWith("Lookup."))
data = new Lookup(data.Params, data.Items);
set(name, data);
return data;
Expand Down

0 comments on commit d9d05bd

Please sign in to comment.