@servicetitan/web-components 34.0.1 → 34.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/common.d.ts CHANGED
@@ -22,8 +22,8 @@ export interface Entries {
22
22
  exposedInstanceDependencies?: ExposedInstanceDependencies;
23
23
  eventBus?: EventBus;
24
24
  basename?: string;
25
- onReady: () => void;
26
- onDispose: () => void;
25
+ onReady?: () => void;
26
+ onDispose?: () => void;
27
27
  }
28
28
  export interface IWebComponent {
29
29
  provide(entries: Entries): void;
@@ -43,6 +43,5 @@ export declare function getJson<T = any>(url: string, { retries, retryDelay, onR
43
43
  headers: Headers;
44
44
  url: string;
45
45
  }>;
46
- export declare function useCancelation(): AbortController;
47
46
  export {};
48
47
  //# sourceMappingURL=common.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,WAAW,2BAA2B;IACxC,YAAY,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,SAAS,CAAA;KAAE,CAAC;CAC7D;AAED,eAAO,MAAM,cAAc,uDAAwC,CAAC;AACpE,eAAO,MAAM,0BAA0B,oEAEtC,CAAC;AACF,eAAO,MAAM,mCAAmC,4EAE/C,CAAC;AACF,eAAO,MAAM,sBAAsB,wDAAiD,CAAC;AACrF,eAAO,MAAM,iBAAiB,2DAA+C,CAAC;AAE9E,MAAM,WAAW,OAAO;IACpB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;IAC1D,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC1B,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,cAAe,SAAQ,WAAW;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;CAC9C;AAUD,wBAAsB,OAAO,CAAC,CAAC,GAAG,GAAG,EACjC,GAAG,EAAE,MAAM,EACX,EAAE,OAAW,EAAE,UAAiB,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,GAAE,cAAmB,GACnF,OAAO,CAAC;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAiDrD;AAED,wBAAgB,cAAc,oBAE7B"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAEhD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,WAAW,2BAA2B;IACxC,YAAY,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,SAAS,CAAA;KAAE,CAAC;CAC7D;AAED,eAAO,MAAM,cAAc,uDAAwC,CAAC;AACpE,eAAO,MAAM,0BAA0B,oEAEtC,CAAC;AACF,eAAO,MAAM,mCAAmC,4EAE/C,CAAC;AACF,eAAO,MAAM,sBAAsB,wDAAiD,CAAC;AACrF,eAAO,MAAM,iBAAiB,2DAA+C,CAAC;AAE9E,MAAM,WAAW,OAAO;IACpB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;IAC1D,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC1B,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,cAAe,SAAQ,WAAW;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;CAC9C;AAUD,wBAAsB,OAAO,CAAC,CAAC,GAAG,GAAG,EACjC,GAAG,EAAE,MAAM,EACX,EAAE,OAAW,EAAE,UAAiB,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,GAAE,cAAmB,GACnF,OAAO,CAAC;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAiDrD"}
package/dist/common.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import { symbolToken } from '@servicetitan/react-ioc';
2
- import { useRef } from 'react';
3
2
  export const BASENAME_TOKEN = symbolToken('BASENAME_TOKEN');
4
3
  export const EXPOSED_DEPENDENCIES_TOKEN = symbolToken('EXPOSED_DEPENDENCIES_TOKEN');
5
4
  export const EXPOSED_INSTANCE_DEPENDENCIES_TOKEN = symbolToken('EXPOSED_INSTANCE_DEPENDENCIES_TOKEN');
@@ -57,8 +56,5 @@ export async function getJson(url, { retries = 5, retryDelay = 1000, onRequestEr
57
56
  url: (_response_url = response.url) !== null && _response_url !== void 0 ? _response_url : url
58
57
  };
59
58
  }
60
- export function useCancelation() {
61
- return useRef(new AbortController()).current;
62
- }
63
59
 
64
60
  //# sourceMappingURL=common.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/common.ts"],"sourcesContent":["import { type LDService } from '@servicetitan/launchdarkly-service';\nimport { Log } from '@servicetitan/log-service';\nimport { symbolToken } from '@servicetitan/react-ioc';\nimport { ExposedDependencies } from '@servicetitan/startup-utils';\nimport { useRef } from 'react';\nimport { EventBus } from './event-bus';\nimport { HistoryManager } from './history-manager';\n\nexport interface ExposedInstanceDependencies {\n launchDarkly?: { version: string; ldService?: LDService };\n}\n\nexport const BASENAME_TOKEN = symbolToken<string>('BASENAME_TOKEN');\nexport const EXPOSED_DEPENDENCIES_TOKEN = symbolToken<ExposedDependencies>(\n 'EXPOSED_DEPENDENCIES_TOKEN'\n);\nexport const EXPOSED_INSTANCE_DEPENDENCIES_TOKEN = symbolToken<ExposedInstanceDependencies>(\n 'EXPOSED_INSTANCE_DEPENDENCIES_TOKEN'\n);\nexport const IS_WEB_COMPONENT_TOKEN = symbolToken<boolean>('IS_WEB_COMPONENT_TOKEN');\nexport const RENDER_ROOT_TOKEN = symbolToken<ShadowRoot>('RENDER_ROOT_TOKEN');\n\nexport interface Entries {\n ldService?: LDService;\n logService?: Log;\n historyManager?: HistoryManager;\n exposedDependencies?: ExposedDependencies;\n exposedInstanceDependencies?: ExposedInstanceDependencies;\n eventBus?: EventBus;\n basename?: string;\n onReady: () => void;\n onDispose: () => void;\n}\n\nexport interface IWebComponent {\n provide(entries: Entries): void;\n}\n\nexport interface GetJsonError {\n status: number;\n body: string;\n json: object;\n}\n\ninterface GetJsonOptions extends RequestInit {\n retries?: number;\n retryDelay?: number;\n onRequestError?(error: GetJsonError): void;\n}\n\nfunction createNetworkError(message: string) {\n const error = new Error(message);\n\n error.name = 'NetworkError';\n\n return error;\n}\n\nexport async function getJson<T = any>(\n url: string,\n { retries = 5, retryDelay = 1000, onRequestError, ...config }: GetJsonOptions = {}\n): Promise<{ data: T; headers: Headers; url: string }> {\n let response: Response;\n try {\n response = await fetch(url, config);\n } catch {\n if (retries > 0 && !config.signal?.aborted) {\n return new Promise((resolve, reject) => {\n const { signal } = config;\n\n const timeoutId = window.setTimeout(() => {\n getJson(url, {\n ...config,\n onRequestError,\n retries: retries - 1,\n retryDelay: retryDelay * 4,\n }).then(resolve, reject);\n }, retryDelay);\n\n const abortHandler = () => {\n window.clearTimeout(timeoutId);\n signal?.removeEventListener('abort', abortHandler);\n reject(signal?.reason);\n };\n\n signal?.addEventListener('abort', abortHandler);\n });\n }\n\n throw createNetworkError(`Failed to fetch: \"${url}\".`);\n }\n\n const responseJSON = await response.json().catch(() => ({}));\n\n if (!response.ok) {\n let message = `Requesting \"${url}\" failed with status code ${response.status}.`;\n\n try {\n message += ` Details: ${await response.text()}.`;\n } catch {} // eslint-disable-line no-empty\n\n onRequestError?.({\n status: response.status,\n json: responseJSON,\n body: await response.text().catch(() => ''),\n });\n throw createNetworkError(message);\n }\n\n return { data: responseJSON, headers: response.headers, url: response.url ?? url };\n}\n\nexport function useCancelation() {\n return useRef(new AbortController()).current;\n}\n"],"names":["symbolToken","useRef","BASENAME_TOKEN","EXPOSED_DEPENDENCIES_TOKEN","EXPOSED_INSTANCE_DEPENDENCIES_TOKEN","IS_WEB_COMPONENT_TOKEN","RENDER_ROOT_TOKEN","createNetworkError","message","error","Error","name","getJson","url","retries","retryDelay","onRequestError","config","response","fetch","signal","aborted","Promise","resolve","reject","timeoutId","window","setTimeout","then","abortHandler","clearTimeout","removeEventListener","reason","addEventListener","responseJSON","json","catch","ok","status","text","body","data","headers","useCancelation","AbortController","current"],"mappings":"AAEA,SAASA,WAAW,QAAQ,0BAA0B;AAEtD,SAASC,MAAM,QAAQ,QAAQ;AAQ/B,OAAO,MAAMC,iBAAiBF,YAAoB,kBAAkB;AACpE,OAAO,MAAMG,6BAA6BH,YACtC,8BACF;AACF,OAAO,MAAMI,sCAAsCJ,YAC/C,uCACF;AACF,OAAO,MAAMK,yBAAyBL,YAAqB,0BAA0B;AACrF,OAAO,MAAMM,oBAAoBN,YAAwB,qBAAqB;AA8B9E,SAASO,mBAAmBC,OAAe;IACvC,MAAMC,QAAQ,IAAIC,MAAMF;IAExBC,MAAME,IAAI,GAAG;IAEb,OAAOF;AACX;AAEA,OAAO,eAAeG,QAClBC,GAAW,EACX,EAAEC,UAAU,CAAC,EAAEC,aAAa,IAAI,EAAEC,cAAc,EAAE,GAAGC,QAAwB,GAAG,CAAC,CAAC;QAiDrBC;IA/C7D,IAAIA;IACJ,IAAI;QACAA,WAAW,MAAMC,MAAMN,KAAKI;IAChC,EAAE,eAAM;YACgBA;QAApB,IAAIH,UAAU,KAAK,GAACG,iBAAAA,OAAOG,MAAM,cAAbH,qCAAAA,eAAeI,OAAO,GAAE;YACxC,OAAO,IAAIC,QAAQ,CAACC,SAASC;gBACzB,MAAM,EAAEJ,MAAM,EAAE,GAAGH;gBAEnB,MAAMQ,YAAYC,OAAOC,UAAU,CAAC;oBAChCf,QAAQC,KAAK;wBACT,GAAGI,MAAM;wBACTD;wBACAF,SAASA,UAAU;wBACnBC,YAAYA,aAAa;oBAC7B,GAAGa,IAAI,CAACL,SAASC;gBACrB,GAAGT;gBAEH,MAAMc,eAAe;oBACjBH,OAAOI,YAAY,CAACL;oBACpBL,mBAAAA,6BAAAA,OAAQW,mBAAmB,CAAC,SAASF;oBACrCL,OAAOJ,mBAAAA,6BAAAA,OAAQY,MAAM;gBACzB;gBAEAZ,mBAAAA,6BAAAA,OAAQa,gBAAgB,CAAC,SAASJ;YACtC;QACJ;QAEA,MAAMtB,mBAAmB,CAAC,kBAAkB,EAAEM,IAAI,EAAE,CAAC;IACzD;IAEA,MAAMqB,eAAe,MAAMhB,SAASiB,IAAI,GAAGC,KAAK,CAAC,IAAO,CAAA,CAAC,CAAA;IAEzD,IAAI,CAAClB,SAASmB,EAAE,EAAE;QACd,IAAI7B,UAAU,CAAC,YAAY,EAAEK,IAAI,0BAA0B,EAAEK,SAASoB,MAAM,CAAC,CAAC,CAAC;QAE/E,IAAI;YACA9B,WAAW,CAAC,UAAU,EAAE,MAAMU,SAASqB,IAAI,GAAG,CAAC,CAAC;QACpD,EAAE,eAAM,CAAC,EAAE,+BAA+B;QAE1CvB,2BAAAA,qCAAAA,eAAiB;YACbsB,QAAQpB,SAASoB,MAAM;YACvBH,MAAMD;YACNM,MAAM,MAAMtB,SAASqB,IAAI,GAAGH,KAAK,CAAC,IAAM;QAC5C;QACA,MAAM7B,mBAAmBC;IAC7B;IAEA,OAAO;QAAEiC,MAAMP;QAAcQ,SAASxB,SAASwB,OAAO;QAAE7B,GAAG,GAAEK,gBAAAA,SAASL,GAAG,cAAZK,2BAAAA,gBAAgBL;IAAI;AACrF;AAEA,OAAO,SAAS8B;IACZ,OAAO1C,OAAO,IAAI2C,mBAAmBC,OAAO;AAChD"}
1
+ {"version":3,"sources":["../src/common.ts"],"sourcesContent":["import { type LDService } from '@servicetitan/launchdarkly-service';\nimport { Log } from '@servicetitan/log-service';\nimport { symbolToken } from '@servicetitan/react-ioc';\nimport { ExposedDependencies } from '@servicetitan/startup-utils';\nimport { EventBus } from './event-bus';\nimport { HistoryManager } from './history-manager';\n\nexport interface ExposedInstanceDependencies {\n launchDarkly?: { version: string; ldService?: LDService };\n}\n\nexport const BASENAME_TOKEN = symbolToken<string>('BASENAME_TOKEN');\nexport const EXPOSED_DEPENDENCIES_TOKEN = symbolToken<ExposedDependencies>(\n 'EXPOSED_DEPENDENCIES_TOKEN'\n);\nexport const EXPOSED_INSTANCE_DEPENDENCIES_TOKEN = symbolToken<ExposedInstanceDependencies>(\n 'EXPOSED_INSTANCE_DEPENDENCIES_TOKEN'\n);\nexport const IS_WEB_COMPONENT_TOKEN = symbolToken<boolean>('IS_WEB_COMPONENT_TOKEN');\nexport const RENDER_ROOT_TOKEN = symbolToken<ShadowRoot>('RENDER_ROOT_TOKEN');\n\nexport interface Entries {\n ldService?: LDService;\n logService?: Log;\n historyManager?: HistoryManager;\n exposedDependencies?: ExposedDependencies;\n exposedInstanceDependencies?: ExposedInstanceDependencies;\n eventBus?: EventBus;\n basename?: string;\n onReady?: () => void;\n onDispose?: () => void;\n}\n\nexport interface IWebComponent {\n provide(entries: Entries): void;\n}\n\nexport interface GetJsonError {\n status: number;\n body: string;\n json: object;\n}\n\ninterface GetJsonOptions extends RequestInit {\n retries?: number;\n retryDelay?: number;\n onRequestError?(error: GetJsonError): void;\n}\n\nfunction createNetworkError(message: string) {\n const error = new Error(message);\n\n error.name = 'NetworkError';\n\n return error;\n}\n\nexport async function getJson<T = any>(\n url: string,\n { retries = 5, retryDelay = 1000, onRequestError, ...config }: GetJsonOptions = {}\n): Promise<{ data: T; headers: Headers; url: string }> {\n let response: Response;\n try {\n response = await fetch(url, config);\n } catch {\n if (retries > 0 && !config.signal?.aborted) {\n return new Promise((resolve, reject) => {\n const { signal } = config;\n\n const timeoutId = window.setTimeout(() => {\n getJson(url, {\n ...config,\n onRequestError,\n retries: retries - 1,\n retryDelay: retryDelay * 4,\n }).then(resolve, reject);\n }, retryDelay);\n\n const abortHandler = () => {\n window.clearTimeout(timeoutId);\n signal?.removeEventListener('abort', abortHandler);\n reject(signal?.reason);\n };\n\n signal?.addEventListener('abort', abortHandler);\n });\n }\n\n throw createNetworkError(`Failed to fetch: \"${url}\".`);\n }\n\n const responseJSON = await response.json().catch(() => ({}));\n\n if (!response.ok) {\n let message = `Requesting \"${url}\" failed with status code ${response.status}.`;\n\n try {\n message += ` Details: ${await response.text()}.`;\n } catch {} // eslint-disable-line no-empty\n\n onRequestError?.({\n status: response.status,\n json: responseJSON,\n body: await response.text().catch(() => ''),\n });\n throw createNetworkError(message);\n }\n\n return { data: responseJSON, headers: response.headers, url: response.url ?? url };\n}\n"],"names":["symbolToken","BASENAME_TOKEN","EXPOSED_DEPENDENCIES_TOKEN","EXPOSED_INSTANCE_DEPENDENCIES_TOKEN","IS_WEB_COMPONENT_TOKEN","RENDER_ROOT_TOKEN","createNetworkError","message","error","Error","name","getJson","url","retries","retryDelay","onRequestError","config","response","fetch","signal","aborted","Promise","resolve","reject","timeoutId","window","setTimeout","then","abortHandler","clearTimeout","removeEventListener","reason","addEventListener","responseJSON","json","catch","ok","status","text","body","data","headers"],"mappings":"AAEA,SAASA,WAAW,QAAQ,0BAA0B;AAStD,OAAO,MAAMC,iBAAiBD,YAAoB,kBAAkB;AACpE,OAAO,MAAME,6BAA6BF,YACtC,8BACF;AACF,OAAO,MAAMG,sCAAsCH,YAC/C,uCACF;AACF,OAAO,MAAMI,yBAAyBJ,YAAqB,0BAA0B;AACrF,OAAO,MAAMK,oBAAoBL,YAAwB,qBAAqB;AA8B9E,SAASM,mBAAmBC,OAAe;IACvC,MAAMC,QAAQ,IAAIC,MAAMF;IAExBC,MAAME,IAAI,GAAG;IAEb,OAAOF;AACX;AAEA,OAAO,eAAeG,QAClBC,GAAW,EACX,EAAEC,UAAU,CAAC,EAAEC,aAAa,IAAI,EAAEC,cAAc,EAAE,GAAGC,QAAwB,GAAG,CAAC,CAAC;QAiDrBC;IA/C7D,IAAIA;IACJ,IAAI;QACAA,WAAW,MAAMC,MAAMN,KAAKI;IAChC,EAAE,eAAM;YACgBA;QAApB,IAAIH,UAAU,KAAK,GAACG,iBAAAA,OAAOG,MAAM,cAAbH,qCAAAA,eAAeI,OAAO,GAAE;YACxC,OAAO,IAAIC,QAAQ,CAACC,SAASC;gBACzB,MAAM,EAAEJ,MAAM,EAAE,GAAGH;gBAEnB,MAAMQ,YAAYC,OAAOC,UAAU,CAAC;oBAChCf,QAAQC,KAAK;wBACT,GAAGI,MAAM;wBACTD;wBACAF,SAASA,UAAU;wBACnBC,YAAYA,aAAa;oBAC7B,GAAGa,IAAI,CAACL,SAASC;gBACrB,GAAGT;gBAEH,MAAMc,eAAe;oBACjBH,OAAOI,YAAY,CAACL;oBACpBL,mBAAAA,6BAAAA,OAAQW,mBAAmB,CAAC,SAASF;oBACrCL,OAAOJ,mBAAAA,6BAAAA,OAAQY,MAAM;gBACzB;gBAEAZ,mBAAAA,6BAAAA,OAAQa,gBAAgB,CAAC,SAASJ;YACtC;QACJ;QAEA,MAAMtB,mBAAmB,CAAC,kBAAkB,EAAEM,IAAI,EAAE,CAAC;IACzD;IAEA,MAAMqB,eAAe,MAAMhB,SAASiB,IAAI,GAAGC,KAAK,CAAC,IAAO,CAAA,CAAC,CAAA;IAEzD,IAAI,CAAClB,SAASmB,EAAE,EAAE;QACd,IAAI7B,UAAU,CAAC,YAAY,EAAEK,IAAI,0BAA0B,EAAEK,SAASoB,MAAM,CAAC,CAAC,CAAC;QAE/E,IAAI;YACA9B,WAAW,CAAC,UAAU,EAAE,MAAMU,SAASqB,IAAI,GAAG,CAAC,CAAC;QACpD,EAAE,eAAM,CAAC,EAAE,+BAA+B;QAE1CvB,2BAAAA,qCAAAA,eAAiB;YACbsB,QAAQpB,SAASoB,MAAM;YACvBH,MAAMD;YACNM,MAAM,MAAMtB,SAASqB,IAAI,GAAGH,KAAK,CAAC,IAAM;QAC5C;QACA,MAAM7B,mBAAmBC;IAC7B;IAEA,OAAO;QAAEiC,MAAMP;QAAcQ,SAASxB,SAASwB,OAAO;QAAE7B,GAAG,GAAEK,gBAAAA,SAASL,GAAG,cAAZK,2BAAAA,gBAAgBL;IAAI;AACrF"}
@@ -1,14 +1,8 @@
1
- type JSONPrimitive = string | number | boolean | null | undefined;
2
- type JSON = {
3
- [key: string]: JSONPrimitive | JSON[] | JSON;
4
- };
5
- export type MFEContextData<T> = {
6
- [P in keyof T]: T[P] extends JSONPrimitive ? T[P] : T[P] extends (infer U)[] ? MFEContextData<U>[] : T[P] extends JSON ? MFEContextData<T[P]> : never;
7
- };
1
+ import { JSON, Serializable } from '../types';
2
+ export type MFEContextData<T> = Serializable<T>;
8
3
  /**
9
4
  * Context used to pass data from the host to the MFEs
10
5
  */
11
6
  export declare const MFEDataContext: import("react").Context<JSON>;
12
7
  export declare function useMFEDataContext<T extends MFEContextData<T>>(): T;
13
- export {};
14
8
  //# sourceMappingURL=mfe-data-context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mfe-data-context.d.ts","sourceRoot":"","sources":["../../src/contexts/mfe-data-context.ts"],"names":[],"mappings":"AAEA,KAAK,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC;AAGlE,KAAK,IAAI,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,EAAE,GAAG,IAAI,CAAA;CAAE,CAAC;AAG7D,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;KAC3B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,aAAa,GACpC,CAAC,CAAC,CAAC,CAAC,GACJ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GACtB,cAAc,CAAC,CAAC,CAAC,EAAE,GACnB,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,GACf,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACpB,KAAK;CAClB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,+BAA0B,CAAC;AAEtD,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,cAAc,CAAC,CAAC,CAAC,OAI5D"}
1
+ {"version":3,"file":"mfe-data-context.d.ts","sourceRoot":"","sources":["../../src/contexts/mfe-data-context.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE9C,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;AAEhD;;GAEG;AACH,eAAO,MAAM,cAAc,+BAA0B,CAAC;AAEtD,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,cAAc,CAAC,CAAC,CAAC,OAI5D"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/contexts/mfe-data-context.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\n\ntype JSONPrimitive = string | number | boolean | null | undefined;\n\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\ntype JSON = { [key: string]: JSONPrimitive | JSON[] | JSON };\n\n// Type complexity below is required to support Interfaces being used\nexport type MFEContextData<T> = {\n [P in keyof T]: T[P] extends JSONPrimitive\n ? T[P]\n : T[P] extends (infer U)[]\n ? MFEContextData<U>[]\n : T[P] extends JSON\n ? MFEContextData<T[P]>\n : never;\n};\n\n/**\n * Context used to pass data from the host to the MFEs\n */\nexport const MFEDataContext = createContext<JSON>({});\n\nexport function useMFEDataContext<T extends MFEContextData<T>>() {\n const context = useContext(MFEDataContext) as T;\n\n return context;\n}\n"],"names":["createContext","useContext","MFEDataContext","useMFEDataContext","context"],"mappings":"AAAA,SAASA,aAAa,EAAEC,UAAU,QAAQ,QAAQ;AAkBlD;;CAEC,GACD,OAAO,MAAMC,iBAAiBF,cAAoB,CAAC,GAAG;AAEtD,OAAO,SAASG;IACZ,MAAMC,UAAUH,WAAWC;IAE3B,OAAOE;AACX"}
1
+ {"version":3,"sources":["../../src/contexts/mfe-data-context.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\n\nimport { JSON, Serializable } from '../types';\n\nexport type MFEContextData<T> = Serializable<T>;\n\n/**\n * Context used to pass data from the host to the MFEs\n */\nexport const MFEDataContext = createContext<JSON>({});\n\nexport function useMFEDataContext<T extends MFEContextData<T>>() {\n const context = useContext(MFEDataContext) as T;\n\n return context;\n}\n"],"names":["createContext","useContext","MFEDataContext","useMFEDataContext","context"],"mappings":"AAAA,SAASA,aAAa,EAAEC,UAAU,QAAQ,QAAQ;AAMlD;;CAEC,GACD,OAAO,MAAMC,iBAAiBF,cAAoB,CAAC,GAAG;AAEtD,OAAO,SAASG;IACZ,MAAMC,UAAUH,WAAWC;IAE3B,OAAOE;AACX"}
@@ -29,6 +29,32 @@ describe(`[web-components] ${useMFEDataContext.name}`, ()=>{
29
29
  expect(subject(Wrapper).result.current).toEqual({});
30
30
  });
31
31
  });
32
+ describe('type definitions', ()=>{
33
+ test('accepts properties typed as JSON', ()=>{
34
+ renderHook(()=>useMFEDataContext());
35
+ });
36
+ test('accepts properties typed as Record<string, JSON>', ()=>{
37
+ renderHook(()=>useMFEDataContext());
38
+ });
39
+ test('accepts primitive properties', ()=>{
40
+ renderHook(()=>useMFEDataContext());
41
+ });
42
+ test('accepts nested objects and arrays', ()=>{
43
+ renderHook(()=>useMFEDataContext());
44
+ });
45
+ test('rejects non-serializable properties', ()=>{
46
+ // @ts-expect-error Type '() => void' is not assignable to type 'never'.
47
+ renderHook(()=>useMFEDataContext());
48
+ // @ts-expect-error Type 'Date' is not assignable to type 'never'.
49
+ renderHook(()=>useMFEDataContext());
50
+ // @ts-expect-error Type 'Map<string, any>' is not assignable to type 'never'.
51
+ renderHook(()=>useMFEDataContext());
52
+ // @ts-expect-error Type 'Set<string>' is not assignable to type 'never'.
53
+ renderHook(()=>useMFEDataContext());
54
+ // @ts-expect-error Type 'symbol' is not assignable to type 'never'.
55
+ renderHook(()=>useMFEDataContext());
56
+ });
57
+ });
32
58
  });
33
59
 
34
60
  //# sourceMappingURL=mfe-data-context.test.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/contexts/tests/mfe-data-context.test.tsx"],"sourcesContent":["import { renderHook } from '@testing-library/react';\nimport { FC, PropsWithChildren } from 'react';\nimport { MFEDataContext, useMFEDataContext } from '../mfe-data-context';\n\ndescribe(`[web-components] ${useMFEDataContext.name}`, () => {\n const subject = (wrapper?: FC) => renderHook(() => useMFEDataContext(), { wrapper });\n\n describe('when the MFEDataContext is provided by a parent', () => {\n const data = { foo: 'bar' };\n const Wrapper: FC<PropsWithChildren> = ({ children }) => {\n return <MFEDataContext.Provider value={data}>{children}</MFEDataContext.Provider>;\n };\n\n test('returns the context', () => {\n expect(subject(Wrapper).result.current).toEqual(data);\n });\n });\n\n describe('when the MFEDataContext is not provided by a parent', () => {\n const Wrapper: FC<PropsWithChildren> = ({ children }) => {\n return <div>{children}</div>;\n };\n\n test('returns an empty object', () => {\n expect(subject(Wrapper).result.current).toEqual({});\n });\n });\n});\n"],"names":["renderHook","MFEDataContext","useMFEDataContext","describe","name","subject","wrapper","data","foo","Wrapper","children","Provider","value","test","expect","result","current","toEqual","div"],"mappings":";AAAA,SAASA,UAAU,QAAQ,yBAAyB;AAEpD,SAASC,cAAc,EAAEC,iBAAiB,QAAQ,sBAAsB;AAExEC,SAAS,CAAC,iBAAiB,EAAED,kBAAkBE,IAAI,EAAE,EAAE;IACnD,MAAMC,UAAU,CAACC,UAAiBN,WAAW,IAAME,qBAAqB;YAAEI;QAAQ;IAElFH,SAAS,mDAAmD;QACxD,MAAMI,OAAO;YAAEC,KAAK;QAAM;QAC1B,MAAMC,UAAiC,CAAC,EAAEC,QAAQ,EAAE;YAChD,qBAAO,KAACT,eAAeU,QAAQ;gBAACC,OAAOL;0BAAOG;;QAClD;QAEAG,KAAK,uBAAuB;YACxBC,OAAOT,QAAQI,SAASM,MAAM,CAACC,OAAO,EAAEC,OAAO,CAACV;QACpD;IACJ;IAEAJ,SAAS,uDAAuD;QAC5D,MAAMM,UAAiC,CAAC,EAAEC,QAAQ,EAAE;YAChD,qBAAO,KAACQ;0BAAKR;;QACjB;QAEAG,KAAK,2BAA2B;YAC5BC,OAAOT,QAAQI,SAASM,MAAM,CAACC,OAAO,EAAEC,OAAO,CAAC,CAAC;QACrD;IACJ;AACJ"}
1
+ {"version":3,"sources":["../../../src/contexts/tests/mfe-data-context.test.tsx"],"sourcesContent":["import { renderHook } from '@testing-library/react';\nimport { FC, PropsWithChildren } from 'react';\nimport { JSON } from '../../types';\nimport { MFEDataContext, useMFEDataContext } from '../mfe-data-context';\n\ndescribe(`[web-components] ${useMFEDataContext.name}`, () => {\n const subject = (wrapper?: FC) => renderHook(() => useMFEDataContext(), { wrapper });\n\n describe('when the MFEDataContext is provided by a parent', () => {\n const data = { foo: 'bar' };\n const Wrapper: FC<PropsWithChildren> = ({ children }) => {\n return <MFEDataContext.Provider value={data}>{children}</MFEDataContext.Provider>;\n };\n\n test('returns the context', () => {\n expect(subject(Wrapper).result.current).toEqual(data);\n });\n });\n\n describe('when the MFEDataContext is not provided by a parent', () => {\n const Wrapper: FC<PropsWithChildren> = ({ children }) => {\n return <div>{children}</div>;\n };\n\n test('returns an empty object', () => {\n expect(subject(Wrapper).result.current).toEqual({});\n });\n });\n\n describe('type definitions', () => {\n test('accepts properties typed as JSON', () => {\n renderHook(() => useMFEDataContext<{ data: JSON }>());\n });\n\n test('accepts properties typed as Record<string, JSON>', () => {\n renderHook(() => useMFEDataContext<{ metadata: Record<string, JSON> }>());\n });\n\n test('accepts primitive properties', () => {\n renderHook(() => useMFEDataContext<{ name: string; count: number; active: boolean }>());\n });\n\n test('accepts nested objects and arrays', () => {\n renderHook(() => useMFEDataContext<{ nested: { value: number }; list: string[] }>());\n });\n\n test('rejects non-serializable properties', () => {\n // @ts-expect-error Type '() => void' is not assignable to type 'never'.\n renderHook(() => useMFEDataContext<{ callback: () => void }>());\n\n // @ts-expect-error Type 'Date' is not assignable to type 'never'.\n renderHook(() => useMFEDataContext<{ created: Date }>());\n\n // @ts-expect-error Type 'Map<string, any>' is not assignable to type 'never'.\n renderHook(() => useMFEDataContext<{ lookup: Map<string, any> }>());\n\n // @ts-expect-error Type 'Set<string>' is not assignable to type 'never'.\n renderHook(() => useMFEDataContext<{ tags: Set<string> }>());\n\n // @ts-expect-error Type 'symbol' is not assignable to type 'never'.\n renderHook(() => useMFEDataContext<{ id: symbol }>());\n });\n });\n});\n"],"names":["renderHook","MFEDataContext","useMFEDataContext","describe","name","subject","wrapper","data","foo","Wrapper","children","Provider","value","test","expect","result","current","toEqual","div"],"mappings":";AAAA,SAASA,UAAU,QAAQ,yBAAyB;AAGpD,SAASC,cAAc,EAAEC,iBAAiB,QAAQ,sBAAsB;AAExEC,SAAS,CAAC,iBAAiB,EAAED,kBAAkBE,IAAI,EAAE,EAAE;IACnD,MAAMC,UAAU,CAACC,UAAiBN,WAAW,IAAME,qBAAqB;YAAEI;QAAQ;IAElFH,SAAS,mDAAmD;QACxD,MAAMI,OAAO;YAAEC,KAAK;QAAM;QAC1B,MAAMC,UAAiC,CAAC,EAAEC,QAAQ,EAAE;YAChD,qBAAO,KAACT,eAAeU,QAAQ;gBAACC,OAAOL;0BAAOG;;QAClD;QAEAG,KAAK,uBAAuB;YACxBC,OAAOT,QAAQI,SAASM,MAAM,CAACC,OAAO,EAAEC,OAAO,CAACV;QACpD;IACJ;IAEAJ,SAAS,uDAAuD;QAC5D,MAAMM,UAAiC,CAAC,EAAEC,QAAQ,EAAE;YAChD,qBAAO,KAACQ;0BAAKR;;QACjB;QAEAG,KAAK,2BAA2B;YAC5BC,OAAOT,QAAQI,SAASM,MAAM,CAACC,OAAO,EAAEC,OAAO,CAAC,CAAC;QACrD;IACJ;IAEAd,SAAS,oBAAoB;QACzBU,KAAK,oCAAoC;YACrCb,WAAW,IAAME;QACrB;QAEAW,KAAK,oDAAoD;YACrDb,WAAW,IAAME;QACrB;QAEAW,KAAK,gCAAgC;YACjCb,WAAW,IAAME;QACrB;QAEAW,KAAK,qCAAqC;YACtCb,WAAW,IAAME;QACrB;QAEAW,KAAK,uCAAuC;YACxC,wEAAwE;YACxEb,WAAW,IAAME;YAEjB,kEAAkE;YAClEF,WAAW,IAAME;YAEjB,8EAA8E;YAC9EF,WAAW,IAAME;YAEjB,yEAAyE;YACzEF,WAAW,IAAME;YAEjB,oEAAoE;YACpEF,WAAW,IAAME;QACrB;IACJ;AACJ"}
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.tsx"],"names":[],"mappings":"AAKA,OAAO,EAEH,SAAS,EACT,GAAG,EAQN,MAAM,OAAO,CAAC;AACf,OAAO,EAIH,YAAY,EAEf,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,EAAmB,QAAQ,EAAE,MAAM,aAAa,CAAC;AAWxD,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC;AAEjC,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;AAEzD,MAAM,WAAW,uBAAuB,CAAC,CAAC,GAAG,EAAE;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uHAAuH;IACvH,IAAI,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,YAAY,CAAC;IAC/B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,cAAc,CAAC,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC;CACjD;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,IAAI,CAC7B,uBAAuB,CAAC,CAAC,CAAC,EACxB,KAAK,GACL,aAAa,GACb,MAAM,GACN,UAAU,GACV,iBAAiB,GACjB,wBAAwB,GACxB,eAAe,GACf,WAAW,GACX,SAAS,GACT,OAAO,GACP,gBAAgB,CACrB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,uBAAuB,EAAE,MAAM,GAAG,WAAW,CAAC,GAAG;IAChF,eAAe,EAAE,MAAM,GAAG,CAAC,OAAO,CAAC;CACtC,CAAC;AAEF,QAAA,MAAM,kBAAkB,GAAI,CAAC,EAAG,OAAO,uBAAuB,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,SAAS,CAAC,4CAyErF,CAAC;AAEF,eAAO,MAAM,MAAM,EAAqC,CAAC,CAAC,GAAG,EAAE,EAC3D,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,CAAA;CAAE,KACxD,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.tsx"],"names":[],"mappings":"AAKA,OAAO,EAEH,SAAS,EACT,GAAG,EAQN,MAAM,OAAO,CAAC;AACf,OAAO,EAIH,YAAY,EACf,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,EAAmB,QAAQ,EAAE,MAAM,aAAa,CAAC;AAWxD,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC;AAEjC,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;AAEzD,MAAM,WAAW,uBAAuB,CAAC,CAAC,GAAG,EAAE;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uHAAuH;IACvH,IAAI,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,YAAY,CAAC;IAC/B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,aAAa,CAAC,EAAE,YAAY,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,cAAc,CAAC,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC;CACjD;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,IAAI,CAC7B,uBAAuB,CAAC,CAAC,CAAC,EACxB,KAAK,GACL,aAAa,GACb,MAAM,GACN,UAAU,GACV,iBAAiB,GACjB,wBAAwB,GACxB,eAAe,GACf,WAAW,GACX,SAAS,GACT,OAAO,GACP,gBAAgB,CACrB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,uBAAuB,EAAE,MAAM,GAAG,WAAW,CAAC,GAAG;IAChF,eAAe,EAAE,MAAM,GAAG,CAAC,OAAO,CAAC;CACtC,CAAC;AAEF,QAAA,MAAM,kBAAkB,GAAI,CAAC,EAAG,OAAO,uBAAuB,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,SAAS,CAAC,4CAsErF,CAAC;AAEF,eAAO,MAAM,MAAM,EAAqC,CAAC,CAAC,GAAG,EAAE,EAC3D,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,CAAA;CAAE,KACxD,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
package/dist/loader.js CHANGED
@@ -3,7 +3,7 @@ import { ErrorBoundary } from '@servicetitan/error-boundary';
3
3
  import { Log } from '@servicetitan/log-service';
4
4
  import { useOptionalDependencies } from '@servicetitan/react-ioc';
5
5
  import { Suspense, forwardRef, lazy, useEffect, useImperativeHandle, useMemo, useRef } from 'react';
6
- import { EXPOSED_DEPENDENCIES_TOKEN, EXPOSED_INSTANCE_DEPENDENCIES_TOKEN, useCancelation } from './common';
6
+ import { EXPOSED_DEPENDENCIES_TOKEN, EXPOSED_INSTANCE_DEPENDENCIES_TOKEN } from './common';
7
7
  import { Delayed } from './delayed';
8
8
  import { EVENT_BUS_TOKEN, EventBus } from './event-bus';
9
9
  import { EXPOSED_DEPENDENCIES, EXPOSED_INSTANCE_DEPENDENCIES } from './globals';
@@ -16,7 +16,6 @@ const UnrestrictedLoader = (props, ref)=>{
16
16
  const [logService, exposedDependencies = EXPOSED_DEPENDENCIES, eventBus = bus] = useOptionalDependencies(Log, EXPOSED_DEPENDENCIES_TOKEN, EVENT_BUS_TOKEN);
17
17
  let [exposedInstanceDependencies = EXPOSED_INSTANCE_DEPENDENCIES] = useOptionalDependencies(EXPOSED_INSTANCE_DEPENDENCIES_TOKEN);
18
18
  const [ldService] = useOptionalDependencies((_getLDServiceToken = getLDServiceToken()) !== null && _getLDServiceToken !== void 0 ? _getLDServiceToken : Symbol());
19
- const cancelation = useCancelation();
20
19
  const LoadingFallback = useMemo(()=>{
21
20
  const message = `Loading${isLocalHost(src) ? ` ${src}` : ''}...`;
22
21
  return getFallback(loadingFallback, message, {
@@ -38,7 +37,9 @@ const UnrestrictedLoader = (props, ref)=>{
38
37
  exposedInstanceDependencies,
39
38
  ldService
40
39
  ]);
41
- const Loader = useMemo(()=>lazyLoader({
40
+ const Loader = useMemo(()=>{
41
+ const cancelation = new AbortController();
42
+ return lazyLoader({
42
43
  basename,
43
44
  cache,
44
45
  cancelation,
@@ -51,10 +52,10 @@ const UnrestrictedLoader = (props, ref)=>{
51
52
  onRequestError,
52
53
  retries,
53
54
  src
54
- }), [
55
+ });
56
+ }, [
55
57
  basename,
56
58
  cache,
57
- cancelation,
58
59
  exposedDependencies,
59
60
  exposedInstanceDependencies,
60
61
  eventBus,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/loader.tsx"],"sourcesContent":["import { ErrorBoundary } from '@servicetitan/error-boundary';\nimport { type LDService } from '@servicetitan/launchdarkly-service';\nimport { Log } from '@servicetitan/log-service';\nimport { useOptionalDependencies } from '@servicetitan/react-ioc';\nimport { ExposedDependencies } from '@servicetitan/startup-utils';\nimport {\n ReactElement,\n ReactNode,\n Ref,\n Suspense,\n forwardRef,\n lazy,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n} from 'react';\nimport {\n EXPOSED_DEPENDENCIES_TOKEN,\n EXPOSED_INSTANCE_DEPENDENCIES_TOKEN,\n ExposedInstanceDependencies,\n GetJsonError,\n useCancelation,\n} from './common';\nimport { MFEContextData } from './contexts/mfe-data-context';\nimport { Delayed } from './delayed';\nimport { EVENT_BUS_TOKEN, EventBus } from './event-bus';\nimport { EXPOSED_DEPENDENCIES, EXPOSED_INSTANCE_DEPENDENCIES } from './globals';\nimport {\n BundleInfo,\n getBundleInfo,\n getLDServiceToken,\n loadScripts,\n validateBundleInfo,\n webComponent,\n} from './utils';\n\nexport type LoaderRef = EventBus;\n\nexport type FallbackNode = NonNullable<ReactNode> | null;\n\nexport interface UnrestrictedLoaderProps<T = {}> {\n src: string;\n fallbackSrc?: string;\n /** Values in the object will be stringified and then parsed before being delivered to the MFE via props or context. */\n data?: MFEContextData<T>;\n basename?: string;\n loadingFallback?: FallbackNode;\n loadingFallbackDelayed?: boolean;\n errorFallback?: FallbackNode;\n className?: string;\n retries?: number;\n isHeadless?: boolean;\n cache?: boolean | number;\n onRequestError?(error: GetJsonError): boolean;\n}\n\nexport type LoaderProps<T> = Pick<\n UnrestrictedLoaderProps<T>,\n | 'src'\n | 'fallbackSrc'\n | 'data'\n | 'basename'\n | 'loadingFallback'\n | 'loadingFallbackDelayed'\n | 'errorFallback'\n | 'className'\n | 'retries'\n | 'cache'\n | 'onRequestError'\n>;\n\nexport type LoaderDataProps = Pick<UnrestrictedLoaderProps, 'data' | 'className'> & {\n LoadingFallback: () => JSX.Element;\n};\n\nconst UnrestrictedLoader = <T,>(props: UnrestrictedLoaderProps<T>, ref: Ref<LoaderRef>) => {\n const { cache = -1, basename, fallbackSrc, isHeadless, onRequestError, retries, src } = props;\n const { loadingFallback, loadingFallbackDelayed = true } = props;\n\n const bus = useEventBus();\n const [logService, exposedDependencies = EXPOSED_DEPENDENCIES, eventBus = bus] =\n useOptionalDependencies(Log, EXPOSED_DEPENDENCIES_TOKEN, EVENT_BUS_TOKEN);\n let [exposedInstanceDependencies = EXPOSED_INSTANCE_DEPENDENCIES] = useOptionalDependencies(\n EXPOSED_INSTANCE_DEPENDENCIES_TOKEN\n );\n const [ldService] = useOptionalDependencies(getLDServiceToken() ?? Symbol());\n const cancelation = useCancelation();\n\n const LoadingFallback = useMemo(() => {\n const message = `Loading${isLocalHost(src) ? ` ${src}` : ''}...`;\n return getFallback(loadingFallback, message, { delayed: loadingFallbackDelayed });\n }, [loadingFallback, loadingFallbackDelayed, src]);\n\n const ErrorFallback = useMemo(() => {\n const message = `Something went wrong${isLocalHost(src) ? ` loading ${src}` : ''}`;\n return getFallback(props.errorFallback, message);\n }, [props.errorFallback, src]);\n\n exposedInstanceDependencies = useMemo(\n () => ensureLDService(exposedInstanceDependencies, ldService),\n [exposedInstanceDependencies, ldService]\n );\n\n const Loader = useMemo(\n () =>\n lazyLoader({\n basename,\n cache,\n cancelation,\n exposedDependencies,\n exposedInstanceDependencies,\n eventBus,\n fallbackSrc,\n isHeadless,\n logService,\n onRequestError,\n retries,\n src,\n }),\n [\n basename,\n cache,\n cancelation,\n exposedDependencies,\n exposedInstanceDependencies,\n eventBus,\n fallbackSrc,\n isHeadless,\n logService,\n onRequestError,\n retries,\n src,\n ]\n );\n\n useImperativeHandle(ref, () => eventBus, [eventBus]);\n\n return (\n <ErrorBoundary moduleName={src} fallback={ErrorFallback}>\n <Suspense fallback={<LoadingFallback />}>\n <Loader\n data={props.data ?? {}}\n className={props.className}\n LoadingFallback={LoadingFallback}\n />\n </Suspense>\n </ErrorBoundary>\n );\n};\n\nexport const Loader = forwardRef(UnrestrictedLoader) as <T = {}>(\n props: LoaderProps<NoInfer<T>> & { ref?: Ref<LoaderRef> }\n) => ReturnType<typeof UnrestrictedLoader>;\n\ntype LazyLoaderProps = UnrestrictedLoaderProps<any> & {\n cancelation: AbortController;\n exposedDependencies?: ExposedDependencies;\n exposedInstanceDependencies?: ExposedInstanceDependencies;\n eventBus: EventBus;\n logService?: Log;\n cache: Required<UnrestrictedLoaderProps<any>>['cache'];\n};\n\nfunction lazyLoader(props: LazyLoaderProps) {\n const { cancelation } = props;\n\n const LazyWebComponent = lazyWebComponent(props);\n\n return (props: LoaderDataProps) => {\n useEffect(() => {\n return () => {\n cancelation.abort();\n };\n }, []);\n\n return (\n <LazyWebComponent\n data={props.data}\n className={props.className}\n LoadingFallback={props.LoadingFallback}\n />\n );\n };\n}\n\nfunction lazyWebComponent(props: LazyLoaderProps) {\n const {\n basename,\n cache,\n cancelation,\n exposedDependencies,\n exposedInstanceDependencies,\n eventBus,\n fallbackSrc,\n isHeadless,\n logService,\n onRequestError,\n retries,\n src,\n } = props;\n\n return lazy<(_: LoaderDataProps) => JSX.Element | null>(async () => {\n let bundleInfo: BundleInfo;\n try {\n bundleInfo = await getBundleInfo({\n cache,\n mainPackageUrl: src,\n fallbackPackageUrl: fallbackSrc,\n isHeadless,\n exposedDependencies,\n exposedInstanceDependencies,\n signal: cancelation.signal,\n retries,\n onRequestError,\n });\n } catch (e) {\n if (cancelation.signal.aborted) {\n return {\n default: () => null,\n };\n }\n\n throw e;\n }\n\n validateBundleInfo(bundleInfo, {\n exposedDependencies,\n exposedInstanceDependencies,\n logService,\n packageUrl: src,\n });\n\n await loadScripts(bundleInfo);\n\n const ldService = bundleInfo.mfeHasCompatibleLaunchDarklyVersion\n ? exposedInstanceDependencies?.launchDarkly?.ldService\n : undefined;\n\n return {\n default: webComponent({\n basename,\n bundleInfo,\n eventBus,\n exposedDependencies,\n exposedInstanceDependencies,\n ldService,\n logService,\n }),\n };\n });\n}\n\nfunction getFallback(\n node: FallbackNode | undefined,\n message: string,\n { delayed = false }: { delayed?: boolean } = {}\n) {\n const fallbackNode = node !== undefined ? (node as ReactElement) : <h2>{message}</h2>;\n return delayed ? () => <Delayed>{fallbackNode}</Delayed> : () => fallbackNode;\n}\n\nfunction isLocalHost(source: string) {\n return ['localhost', '127.0.0.1'].some(host => source.indexOf(host) >= 0);\n}\n\nfunction ensureLDService(\n exposedInstanceDependencies?: ExposedInstanceDependencies,\n ldService?: LDService\n) {\n const launchDarkly = exposedInstanceDependencies?.launchDarkly;\n if (launchDarkly?.version && !launchDarkly.ldService && ldService) {\n return { ...exposedInstanceDependencies, launchDarkly: { ...launchDarkly, ldService } };\n }\n return exposedInstanceDependencies;\n}\n\nfunction useEventBus() {\n return useRef(new EventBus()).current;\n}\n"],"names":["ErrorBoundary","Log","useOptionalDependencies","Suspense","forwardRef","lazy","useEffect","useImperativeHandle","useMemo","useRef","EXPOSED_DEPENDENCIES_TOKEN","EXPOSED_INSTANCE_DEPENDENCIES_TOKEN","useCancelation","Delayed","EVENT_BUS_TOKEN","EventBus","EXPOSED_DEPENDENCIES","EXPOSED_INSTANCE_DEPENDENCIES","getBundleInfo","getLDServiceToken","loadScripts","validateBundleInfo","webComponent","UnrestrictedLoader","props","ref","cache","basename","fallbackSrc","isHeadless","onRequestError","retries","src","loadingFallback","loadingFallbackDelayed","bus","useEventBus","logService","exposedDependencies","eventBus","exposedInstanceDependencies","ldService","Symbol","cancelation","LoadingFallback","message","isLocalHost","getFallback","delayed","ErrorFallback","errorFallback","ensureLDService","Loader","lazyLoader","moduleName","fallback","data","className","LazyWebComponent","lazyWebComponent","abort","bundleInfo","mainPackageUrl","fallbackPackageUrl","signal","e","aborted","default","packageUrl","mfeHasCompatibleLaunchDarklyVersion","launchDarkly","undefined","node","fallbackNode","h2","source","some","host","indexOf","version","current"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/loader.tsx"],"sourcesContent":["import { ErrorBoundary } from '@servicetitan/error-boundary';\nimport { type LDService } from '@servicetitan/launchdarkly-service';\nimport { Log } from '@servicetitan/log-service';\nimport { useOptionalDependencies } from '@servicetitan/react-ioc';\nimport { ExposedDependencies } from '@servicetitan/startup-utils';\nimport {\n ReactElement,\n ReactNode,\n Ref,\n Suspense,\n forwardRef,\n lazy,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n} from 'react';\nimport {\n EXPOSED_DEPENDENCIES_TOKEN,\n EXPOSED_INSTANCE_DEPENDENCIES_TOKEN,\n ExposedInstanceDependencies,\n GetJsonError,\n} from './common';\nimport { MFEContextData } from './contexts/mfe-data-context';\nimport { Delayed } from './delayed';\nimport { EVENT_BUS_TOKEN, EventBus } from './event-bus';\nimport { EXPOSED_DEPENDENCIES, EXPOSED_INSTANCE_DEPENDENCIES } from './globals';\nimport {\n BundleInfo,\n getBundleInfo,\n getLDServiceToken,\n loadScripts,\n validateBundleInfo,\n webComponent,\n} from './utils';\n\nexport type LoaderRef = EventBus;\n\nexport type FallbackNode = NonNullable<ReactNode> | null;\n\nexport interface UnrestrictedLoaderProps<T = {}> {\n src: string;\n fallbackSrc?: string;\n /** Values in the object will be stringified and then parsed before being delivered to the MFE via props or context. */\n data?: MFEContextData<T>;\n basename?: string;\n loadingFallback?: FallbackNode;\n loadingFallbackDelayed?: boolean;\n errorFallback?: FallbackNode;\n className?: string;\n retries?: number;\n isHeadless?: boolean;\n cache?: boolean | number;\n onRequestError?(error: GetJsonError): boolean;\n}\n\nexport type LoaderProps<T> = Pick<\n UnrestrictedLoaderProps<T>,\n | 'src'\n | 'fallbackSrc'\n | 'data'\n | 'basename'\n | 'loadingFallback'\n | 'loadingFallbackDelayed'\n | 'errorFallback'\n | 'className'\n | 'retries'\n | 'cache'\n | 'onRequestError'\n>;\n\nexport type LoaderDataProps = Pick<UnrestrictedLoaderProps, 'data' | 'className'> & {\n LoadingFallback: () => JSX.Element;\n};\n\nconst UnrestrictedLoader = <T,>(props: UnrestrictedLoaderProps<T>, ref: Ref<LoaderRef>) => {\n const { cache = -1, basename, fallbackSrc, isHeadless, onRequestError, retries, src } = props;\n const { loadingFallback, loadingFallbackDelayed = true } = props;\n\n const bus = useEventBus();\n const [logService, exposedDependencies = EXPOSED_DEPENDENCIES, eventBus = bus] =\n useOptionalDependencies(Log, EXPOSED_DEPENDENCIES_TOKEN, EVENT_BUS_TOKEN);\n let [exposedInstanceDependencies = EXPOSED_INSTANCE_DEPENDENCIES] = useOptionalDependencies(\n EXPOSED_INSTANCE_DEPENDENCIES_TOKEN\n );\n const [ldService] = useOptionalDependencies(getLDServiceToken() ?? Symbol());\n\n const LoadingFallback = useMemo(() => {\n const message = `Loading${isLocalHost(src) ? ` ${src}` : ''}...`;\n return getFallback(loadingFallback, message, { delayed: loadingFallbackDelayed });\n }, [loadingFallback, loadingFallbackDelayed, src]);\n\n const ErrorFallback = useMemo(() => {\n const message = `Something went wrong${isLocalHost(src) ? ` loading ${src}` : ''}`;\n return getFallback(props.errorFallback, message);\n }, [props.errorFallback, src]);\n\n exposedInstanceDependencies = useMemo(\n () => ensureLDService(exposedInstanceDependencies, ldService),\n [exposedInstanceDependencies, ldService]\n );\n\n const Loader = useMemo(() => {\n const cancelation = new AbortController();\n return lazyLoader({\n basename,\n cache,\n cancelation,\n exposedDependencies,\n exposedInstanceDependencies,\n eventBus,\n fallbackSrc,\n isHeadless,\n logService,\n onRequestError,\n retries,\n src,\n });\n }, [\n basename,\n cache,\n exposedDependencies,\n exposedInstanceDependencies,\n eventBus,\n fallbackSrc,\n isHeadless,\n logService,\n onRequestError,\n retries,\n src,\n ]);\n\n useImperativeHandle(ref, () => eventBus, [eventBus]);\n\n return (\n <ErrorBoundary moduleName={src} fallback={ErrorFallback}>\n <Suspense fallback={<LoadingFallback />}>\n <Loader\n data={props.data ?? {}}\n className={props.className}\n LoadingFallback={LoadingFallback}\n />\n </Suspense>\n </ErrorBoundary>\n );\n};\n\nexport const Loader = forwardRef(UnrestrictedLoader) as <T = {}>(\n props: LoaderProps<NoInfer<T>> & { ref?: Ref<LoaderRef> }\n) => ReturnType<typeof UnrestrictedLoader>;\n\ntype LazyLoaderProps = UnrestrictedLoaderProps<any> & {\n cancelation: AbortController;\n exposedDependencies?: ExposedDependencies;\n exposedInstanceDependencies?: ExposedInstanceDependencies;\n eventBus: EventBus;\n logService?: Log;\n cache: Required<UnrestrictedLoaderProps<any>>['cache'];\n};\n\nfunction lazyLoader(props: LazyLoaderProps) {\n const { cancelation } = props;\n\n const LazyWebComponent = lazyWebComponent(props);\n\n return (props: LoaderDataProps) => {\n useEffect(() => {\n return () => {\n cancelation.abort();\n };\n }, []);\n\n return (\n <LazyWebComponent\n data={props.data}\n className={props.className}\n LoadingFallback={props.LoadingFallback}\n />\n );\n };\n}\n\nfunction lazyWebComponent(props: LazyLoaderProps) {\n const {\n basename,\n cache,\n cancelation,\n exposedDependencies,\n exposedInstanceDependencies,\n eventBus,\n fallbackSrc,\n isHeadless,\n logService,\n onRequestError,\n retries,\n src,\n } = props;\n\n return lazy<(_: LoaderDataProps) => JSX.Element | null>(async () => {\n let bundleInfo: BundleInfo;\n try {\n bundleInfo = await getBundleInfo({\n cache,\n mainPackageUrl: src,\n fallbackPackageUrl: fallbackSrc,\n isHeadless,\n exposedDependencies,\n exposedInstanceDependencies,\n signal: cancelation.signal,\n retries,\n onRequestError,\n });\n } catch (e) {\n if (cancelation.signal.aborted) {\n return {\n default: () => null,\n };\n }\n\n throw e;\n }\n\n validateBundleInfo(bundleInfo, {\n exposedDependencies,\n exposedInstanceDependencies,\n logService,\n packageUrl: src,\n });\n\n await loadScripts(bundleInfo);\n\n const ldService = bundleInfo.mfeHasCompatibleLaunchDarklyVersion\n ? exposedInstanceDependencies?.launchDarkly?.ldService\n : undefined;\n\n return {\n default: webComponent({\n basename,\n bundleInfo,\n eventBus,\n exposedDependencies,\n exposedInstanceDependencies,\n ldService,\n logService,\n }),\n };\n });\n}\n\nfunction getFallback(\n node: FallbackNode | undefined,\n message: string,\n { delayed = false }: { delayed?: boolean } = {}\n) {\n const fallbackNode = node !== undefined ? (node as ReactElement) : <h2>{message}</h2>;\n return delayed ? () => <Delayed>{fallbackNode}</Delayed> : () => fallbackNode;\n}\n\nfunction isLocalHost(source: string) {\n return ['localhost', '127.0.0.1'].some(host => source.indexOf(host) >= 0);\n}\n\nfunction ensureLDService(\n exposedInstanceDependencies?: ExposedInstanceDependencies,\n ldService?: LDService\n) {\n const launchDarkly = exposedInstanceDependencies?.launchDarkly;\n if (launchDarkly?.version && !launchDarkly.ldService && ldService) {\n return { ...exposedInstanceDependencies, launchDarkly: { ...launchDarkly, ldService } };\n }\n return exposedInstanceDependencies;\n}\n\nfunction useEventBus() {\n return useRef(new EventBus()).current;\n}\n"],"names":["ErrorBoundary","Log","useOptionalDependencies","Suspense","forwardRef","lazy","useEffect","useImperativeHandle","useMemo","useRef","EXPOSED_DEPENDENCIES_TOKEN","EXPOSED_INSTANCE_DEPENDENCIES_TOKEN","Delayed","EVENT_BUS_TOKEN","EventBus","EXPOSED_DEPENDENCIES","EXPOSED_INSTANCE_DEPENDENCIES","getBundleInfo","getLDServiceToken","loadScripts","validateBundleInfo","webComponent","UnrestrictedLoader","props","ref","cache","basename","fallbackSrc","isHeadless","onRequestError","retries","src","loadingFallback","loadingFallbackDelayed","bus","useEventBus","logService","exposedDependencies","eventBus","exposedInstanceDependencies","ldService","Symbol","LoadingFallback","message","isLocalHost","getFallback","delayed","ErrorFallback","errorFallback","ensureLDService","Loader","cancelation","AbortController","lazyLoader","moduleName","fallback","data","className","LazyWebComponent","lazyWebComponent","abort","bundleInfo","mainPackageUrl","fallbackPackageUrl","signal","e","aborted","default","packageUrl","mfeHasCompatibleLaunchDarklyVersion","launchDarkly","undefined","node","fallbackNode","h2","source","some","host","indexOf","version","current"],"mappings":"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"}
package/dist/register.js CHANGED
@@ -80,15 +80,15 @@ export function register(Component, light, options) {
80
80
  this.styles.elements.push(...this.attachStyles(this.root, styleUrls), ...this.attachStyles(this.portal, styleUrls));
81
81
  }
82
82
  disconnectedCallback() {
83
- var _this_root, _this_view, _this_onDispose, _this;
84
- if (!this.root || ((_this_root = this.root) === null || _this_root === void 0 ? void 0 : _this_root.isConnected)) {
83
+ var _this_view, _document_body, _this_onDispose, _this;
84
+ if (!this.root || this.root.isConnected) {
85
85
  return;
86
86
  }
87
87
  for (const element of this.styles.elements){
88
88
  element.remove();
89
89
  }
90
90
  (_this_view = this.view) === null || _this_view === void 0 ? void 0 : _this_view.unmount();
91
- document.body.removeChild(this.portal.host);
91
+ (_document_body = document.body) === null || _document_body === void 0 ? void 0 : _document_body.removeChild(this.portal.host);
92
92
  this.root = undefined;
93
93
  this.portal = undefined;
94
94
  this.portalAnvilContainer = undefined;
@@ -149,7 +149,7 @@ export function register(Component, light, options) {
149
149
  for (const [key, value] of Object.entries(entries)){
150
150
  this[key] = value;
151
151
  }
152
- if (this.styles.loaded === this.styles.total && Object.values(entries).some((v)=>!!v)) {
152
+ if (this.styles.loaded === this.styles.total) {
153
153
  this.render();
154
154
  }
155
155
  }), _define_property(this, "handleLoad", ()=>{
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/register.tsx"],"sourcesContent":["import { type LDService } from '@servicetitan/launchdarkly-service';\nimport { Log } from '@servicetitan/log-service';\nimport { Provider } from '@servicetitan/react-ioc';\nimport { ExposedDependencies } from '@servicetitan/startup-utils';\nimport { ComponentType, FC, ReactElement, useEffect } from 'react';\nimport {\n BASENAME_TOKEN,\n Entries,\n EXPOSED_DEPENDENCIES_TOKEN,\n EXPOSED_INSTANCE_DEPENDENCIES_TOKEN,\n ExposedInstanceDependencies,\n IS_WEB_COMPONENT_TOKEN,\n IWebComponent,\n RENDER_ROOT_TOKEN,\n} from './common';\nimport { MFEDataContext } from './contexts/mfe-data-context';\nimport { MFEMetadataContext } from './contexts/mfe-metadata-context';\nimport { EVENT_BUS_TOKEN, EventBus } from './event-bus';\nimport { WEB_COMPONENT_NAME } from './globals';\nimport { HistoryManager } from './history-manager';\nimport { render } from './render';\nimport { getElementName, getLDServiceToken } from './utils';\n\nfunction createLink(url: string, onLoad: () => void) {\n const element = document.createElement('link');\n\n element.href = url;\n element.rel = 'stylesheet';\n element.crossOrigin = 'anonymous';\n element.onload = onLoad;\n element.onerror = onLoad;\n\n return element;\n}\n\nconst Placeholder: FC = () => <div style={{ display: 'none' }} />;\n\nexport interface RegisterOptions {\n legacyRoot?: boolean;\n sharedDependenciesNames?: string[];\n}\n\nexport function register(Component: ComponentType, light: boolean, options?: RegisterOptions) {\n class WebComponent extends HTMLElement implements IWebComponent {\n private root?: ShadowRoot;\n private portal?: ShadowRoot;\n private portalAnvilContainer?: HTMLDivElement;\n\n private styles: {\n total: number;\n loaded: number;\n elements: HTMLElement[];\n } = { total: 0, loaded: 0, elements: [] };\n\n private ldService?: LDService;\n private logService?: Log;\n private historyManager?: HistoryManager;\n private exposedDependencies?: ExposedDependencies;\n private exposedInstanceDependencies?: ExposedInstanceDependencies;\n private eventBus?: EventBus;\n private basename?: string;\n private onReady?: () => void;\n private onDispose?: () => void;\n private view?: ReturnType<typeof render>;\n\n connectedCallback() {\n /*\n * connectedCallback can be called when DOM element has moved\n * check that root is still connected to the DOM\n * if that's the case we don't need to reconnect MFE\n */\n if (this.root?.isConnected) {\n return;\n }\n const sharedDependenciesNames = options?.sharedDependenciesNames ?? [];\n const styleUrls = getStyleUrls(light, sharedDependenciesNames, this);\n\n this.styles = {\n total: styleUrls.length * 2,\n loaded: 0,\n elements: [],\n };\n\n this.root = this.shadowRoot ?? this.attachShadow({ mode: 'open' });\n /*\n * Portal shadow dom is created at the bottom of the body in order to be used as\n * the element for the design system components to attach modals and popups to.\n * This element is passed down the tree through context, and used within\n * the design system components.\n */\n const portalElement = document.createElement('div');\n portalElement.setAttribute(\n 'data-mfe-portal-name',\n getElementName({ WebComponent: WEB_COMPONENT_NAME! })\n );\n this.portal = document.body.appendChild(portalElement).attachShadow({ mode: 'open' });\n /*\n * Add element inside of portal so that Anvil 2 can attach modals and popups to it\n * since floating-ui does not support attaching straight to shadow dom\n */\n this.portalAnvilContainer = document.createElement('div');\n this.portal.appendChild(this.portalAnvilContainer);\n\n this.view = render(<Placeholder />, this.root, options);\n\n this.styles.elements.push(\n ...this.attachStyles(this.root, styleUrls),\n ...this.attachStyles(this.portal, styleUrls)\n );\n }\n\n disconnectedCallback() {\n if (!this.root || this.root?.isConnected) {\n return;\n }\n for (const element of this.styles.elements) {\n element.remove();\n }\n\n this.view?.unmount();\n document.body.removeChild(this.portal!.host);\n this.root = undefined;\n this.portal = undefined;\n this.portalAnvilContainer = undefined;\n\n this.onDispose?.();\n }\n\n // Observe changes to the data-mfe-data attribute so that we can re-render when it changes\n static get observedAttributes() {\n return ['data-mfe-data'];\n }\n\n attributeChangedCallback() {\n this.render();\n }\n\n provide = (entries: Entries) => {\n for (const [key, value] of Object.entries(entries)) {\n this[key as keyof IWebComponent] = value;\n }\n\n if (this.styles.loaded === this.styles.total && Object.values(entries).some(v => !!v)) {\n this.render();\n }\n };\n\n private handleLoad = () => {\n this.styles.loaded++;\n\n if (this.styles.loaded === this.styles.total) {\n this.render();\n }\n };\n\n private attachStyles = (node: ShadowRoot, urls: string[]) => {\n const elements: HTMLElement[] = [];\n\n for (const url of urls) {\n const element = createLink(url, this.handleLoad);\n node.appendChild(element);\n elements.push(element);\n }\n\n return elements;\n };\n\n private withAnvil1Providers(children: ReactElement): ReactElement {\n try {\n /**\n * Note, the webpack.IgnorePlugin must be configured to ignore this dependency.\n * @see {@link file://./../../startup/src/webpack/configs/plugins/ignore-plugin/ignore-plugin.ts}\n */\n const { DefaultPortalContext, TablePopupPropsContext } =\n require('@servicetitan/design-system') as typeof import('@servicetitan/design-system');\n return (\n <DefaultPortalContext.Provider value={this.portal as unknown as HTMLElement}>\n <TablePopupPropsContext.Provider\n value={props => ({\n ...props,\n appendTo: this.root as unknown as HTMLElement,\n })}\n >\n {children}\n </TablePopupPropsContext.Provider>\n </DefaultPortalContext.Provider>\n );\n } catch {\n return children;\n }\n }\n\n private withAnvil2Providers(children: ReactElement): ReactElement {\n try {\n /**\n * Note, the webpack.IgnorePlugin must be configured to ignore this dependency.\n * @see {@link file://./../../startup/src/webpack/configs/plugins/ignore-plugin/ignore-plugin.ts}\n */\n const { PortalProvider } =\n require('@servicetitan/anvil2') as typeof import('@servicetitan/anvil2');\n return <PortalProvider root={this.portalAnvilContainer}>{children}</PortalProvider>;\n } catch {\n return children;\n }\n }\n\n private withProviders(children: ReactElement): ReactElement {\n return this.withAnvil2Providers(this.withAnvil1Providers(children));\n }\n\n private render = () => {\n /*\n * Check for this.root first, otherwise we get error when\n * attributeChangedCallback happens on load\n */\n if (this.root) {\n const mfeData = this.dataset.mfeData\n ? /*\n * Data was stringified in order to come through the data-mfe-data attribute\n * So we must JSON.parse it here to get an object back\n */\n JSON.parse(this.dataset.mfeData)\n : /*\n * If mfeData isn't there, then the Host may not be up to date with web-components\n * and is instead passing data through separate data-attributes, so we want to\n * spread all of those instead\n */\n { ...this.dataset };\n\n const metadata = {\n shadowRoot: this.root,\n portalShadowRoot: this.portal!,\n };\n\n this.view?.rerender(\n <Provider\n singletons={[\n { provide: IS_WEB_COMPONENT_TOKEN, useValue: true },\n { provide: RENDER_ROOT_TOKEN, useValue: this.root },\n ]}\n >\n <Provider\n singletons={[\n { provide: Log, useValue: this.logService },\n {\n provide: HistoryManager,\n useValue: this.historyManager,\n },\n {\n provide: EXPOSED_DEPENDENCIES_TOKEN,\n useValue: this.exposedDependencies,\n },\n {\n provide: EXPOSED_INSTANCE_DEPENDENCIES_TOKEN,\n useValue: this.exposedInstanceDependencies,\n },\n { provide: BASENAME_TOKEN, useValue: this.basename },\n { provide: EVENT_BUS_TOKEN, useValue: this.eventBus },\n { provide: getLDServiceToken(), useValue: this.ldService },\n ].filter(\n ({ provide, useValue }) =>\n useValue !== undefined && provide !== undefined\n )}\n >\n <MFEDataContext.Provider value={{ ...mfeData }}>\n <MFEMetadataContext.Provider value={metadata}>\n {this.withProviders(<Component {...mfeData} />)}\n {this.onReady && <RenderCallback callback={this.onReady} />}\n </MFEMetadataContext.Provider>\n </MFEDataContext.Provider>\n </Provider>\n </Provider>\n );\n }\n };\n }\n\n if (!WEB_COMPONENT_NAME) {\n // eslint-disable-next-line no-console\n console.error('\"WEB_COMPONENT_NAME\" is not defined!');\n return;\n }\n\n window.customElements.define(WEB_COMPONENT_NAME, WebComponent);\n}\n\nfunction getStyleUrls(light: boolean, sharedDependenciesNames: string[], el: HTMLElement) {\n function getCssUrl(dependencyName: string, cssFileRegEx: RegExp) {\n if (light && sharedDependenciesNames.includes(dependencyName)) {\n return Array.from(document.getElementsByTagName('link')).find(\n ({ href }) => href && cssFileRegEx.test(href)\n )?.href;\n }\n }\n\n const designSystemUrl = getCssUrl(\n '@servicetitan/design-system',\n /design-system(\\..+)?\\.bundle\\.css/\n );\n const anvil2CssUrl = getCssUrl('@servicetitan/anvil2', /anvil2(\\..+)?\\.bundle\\.css/);\n\n return [\n ...(designSystemUrl ? [designSystemUrl] : []),\n ...(anvil2CssUrl ? [anvil2CssUrl] : []),\n ...(el.hasAttribute('style-urls')\n ? JSON.parse(decodeURIComponent(el.getAttribute('style-urls')!))\n : []),\n ];\n}\n\nfunction RenderCallback({ callback }: { callback: () => void }) {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(() => callback(), []);\n return null;\n}\n"],"names":["Log","Provider","useEffect","BASENAME_TOKEN","EXPOSED_DEPENDENCIES_TOKEN","EXPOSED_INSTANCE_DEPENDENCIES_TOKEN","IS_WEB_COMPONENT_TOKEN","RENDER_ROOT_TOKEN","MFEDataContext","MFEMetadataContext","EVENT_BUS_TOKEN","WEB_COMPONENT_NAME","HistoryManager","render","getElementName","getLDServiceToken","createLink","url","onLoad","element","document","createElement","href","rel","crossOrigin","onload","onerror","Placeholder","div","style","display","register","Component","light","options","WebComponent","HTMLElement","connectedCallback","root","isConnected","sharedDependenciesNames","styleUrls","getStyleUrls","styles","total","length","loaded","elements","shadowRoot","attachShadow","mode","portalElement","setAttribute","portal","body","appendChild","portalAnvilContainer","view","push","attachStyles","disconnectedCallback","remove","unmount","removeChild","host","undefined","onDispose","observedAttributes","attributeChangedCallback","withAnvil1Providers","children","DefaultPortalContext","TablePopupPropsContext","require","value","props","appendTo","withAnvil2Providers","PortalProvider","withProviders","ldService","logService","historyManager","exposedDependencies","exposedInstanceDependencies","eventBus","basename","onReady","provide","entries","key","Object","values","some","v","handleLoad","node","urls","mfeData","dataset","JSON","parse","metadata","portalShadowRoot","rerender","singletons","useValue","filter","RenderCallback","callback","console","error","window","customElements","define","el","getCssUrl","dependencyName","cssFileRegEx","includes","Array","from","getElementsByTagName","find","test","designSystemUrl","anvil2CssUrl","hasAttribute","decodeURIComponent","getAttribute"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/register.tsx"],"sourcesContent":["import { type LDService } from '@servicetitan/launchdarkly-service';\nimport { Log } from '@servicetitan/log-service';\nimport { Provider } from '@servicetitan/react-ioc';\nimport { ExposedDependencies } from '@servicetitan/startup-utils';\nimport { ComponentType, FC, ReactElement, useEffect } from 'react';\nimport {\n BASENAME_TOKEN,\n Entries,\n EXPOSED_DEPENDENCIES_TOKEN,\n EXPOSED_INSTANCE_DEPENDENCIES_TOKEN,\n ExposedInstanceDependencies,\n IS_WEB_COMPONENT_TOKEN,\n IWebComponent,\n RENDER_ROOT_TOKEN,\n} from './common';\nimport { MFEDataContext } from './contexts/mfe-data-context';\nimport { MFEMetadataContext } from './contexts/mfe-metadata-context';\nimport { EVENT_BUS_TOKEN, EventBus } from './event-bus';\nimport { WEB_COMPONENT_NAME } from './globals';\nimport { HistoryManager } from './history-manager';\nimport { render } from './render';\nimport { getElementName, getLDServiceToken } from './utils';\n\nfunction createLink(url: string, onLoad: () => void) {\n const element = document.createElement('link');\n\n element.href = url;\n element.rel = 'stylesheet';\n element.crossOrigin = 'anonymous';\n element.onload = onLoad;\n element.onerror = onLoad;\n\n return element;\n}\n\nconst Placeholder: FC = () => <div style={{ display: 'none' }} />;\n\nexport interface RegisterOptions {\n legacyRoot?: boolean;\n sharedDependenciesNames?: string[];\n}\n\nexport function register(Component: ComponentType, light: boolean, options?: RegisterOptions) {\n class WebComponent extends HTMLElement implements IWebComponent {\n private root?: ShadowRoot;\n private portal?: ShadowRoot;\n private portalAnvilContainer?: HTMLDivElement;\n\n private styles: {\n total: number;\n loaded: number;\n elements: HTMLElement[];\n } = { total: 0, loaded: 0, elements: [] };\n\n private ldService?: LDService;\n private logService?: Log;\n private historyManager?: HistoryManager;\n private exposedDependencies?: ExposedDependencies;\n private exposedInstanceDependencies?: ExposedInstanceDependencies;\n private eventBus?: EventBus;\n private basename?: string;\n private onReady?: () => void;\n private onDispose?: () => void;\n private view?: ReturnType<typeof render>;\n\n connectedCallback() {\n /*\n * connectedCallback can be called when DOM element has moved\n * check that root is still connected to the DOM\n * if that's the case we don't need to reconnect MFE\n */\n if (this.root?.isConnected) {\n return;\n }\n const sharedDependenciesNames = options?.sharedDependenciesNames ?? [];\n const styleUrls = getStyleUrls(light, sharedDependenciesNames, this);\n\n this.styles = {\n total: styleUrls.length * 2,\n loaded: 0,\n elements: [],\n };\n\n this.root = this.shadowRoot ?? this.attachShadow({ mode: 'open' });\n /*\n * Portal shadow dom is created at the bottom of the body in order to be used as\n * the element for the design system components to attach modals and popups to.\n * This element is passed down the tree through context, and used within\n * the design system components.\n */\n const portalElement = document.createElement('div');\n portalElement.setAttribute(\n 'data-mfe-portal-name',\n getElementName({ WebComponent: WEB_COMPONENT_NAME! })\n );\n this.portal = document.body.appendChild(portalElement).attachShadow({ mode: 'open' });\n /*\n * Add element inside of portal so that Anvil 2 can attach modals and popups to it\n * since floating-ui does not support attaching straight to shadow dom\n */\n this.portalAnvilContainer = document.createElement('div');\n this.portal.appendChild(this.portalAnvilContainer);\n\n this.view = render(<Placeholder />, this.root, options);\n\n this.styles.elements.push(\n ...this.attachStyles(this.root, styleUrls),\n ...this.attachStyles(this.portal, styleUrls)\n );\n }\n\n disconnectedCallback() {\n if (!this.root || this.root.isConnected) {\n return;\n }\n for (const element of this.styles.elements) {\n element.remove();\n }\n\n this.view?.unmount();\n document.body?.removeChild(this.portal!.host);\n this.root = undefined;\n this.portal = undefined;\n this.portalAnvilContainer = undefined;\n\n this.onDispose?.();\n }\n\n // Observe changes to the data-mfe-data attribute so that we can re-render when it changes\n static get observedAttributes() {\n return ['data-mfe-data'];\n }\n\n attributeChangedCallback() {\n this.render();\n }\n\n provide = (entries: Entries) => {\n for (const [key, value] of Object.entries(entries)) {\n this[key as keyof IWebComponent] = value;\n }\n\n if (this.styles.loaded === this.styles.total) {\n this.render();\n }\n };\n\n private handleLoad = () => {\n this.styles.loaded++;\n\n if (this.styles.loaded === this.styles.total) {\n this.render();\n }\n };\n\n private attachStyles = (node: ShadowRoot, urls: string[]) => {\n const elements: HTMLElement[] = [];\n\n for (const url of urls) {\n const element = createLink(url, this.handleLoad);\n node.appendChild(element);\n elements.push(element);\n }\n\n return elements;\n };\n\n private withAnvil1Providers(children: ReactElement): ReactElement {\n try {\n /**\n * Note, the webpack.IgnorePlugin must be configured to ignore this dependency.\n * @see {@link file://./../../startup/src/webpack/configs/plugins/ignore-plugin/ignore-plugin.ts}\n */\n const { DefaultPortalContext, TablePopupPropsContext } =\n require('@servicetitan/design-system') as typeof import('@servicetitan/design-system');\n return (\n <DefaultPortalContext.Provider value={this.portal as unknown as HTMLElement}>\n <TablePopupPropsContext.Provider\n value={props => ({\n ...props,\n appendTo: this.root as unknown as HTMLElement,\n })}\n >\n {children}\n </TablePopupPropsContext.Provider>\n </DefaultPortalContext.Provider>\n );\n } catch {\n return children;\n }\n }\n\n private withAnvil2Providers(children: ReactElement): ReactElement {\n try {\n /**\n * Note, the webpack.IgnorePlugin must be configured to ignore this dependency.\n * @see {@link file://./../../startup/src/webpack/configs/plugins/ignore-plugin/ignore-plugin.ts}\n */\n const { PortalProvider } =\n require('@servicetitan/anvil2') as typeof import('@servicetitan/anvil2');\n return <PortalProvider root={this.portalAnvilContainer}>{children}</PortalProvider>;\n } catch {\n return children;\n }\n }\n\n private withProviders(children: ReactElement): ReactElement {\n return this.withAnvil2Providers(this.withAnvil1Providers(children));\n }\n\n private render = () => {\n /*\n * Check for this.root first, otherwise we get error when\n * attributeChangedCallback happens on load\n */\n if (this.root) {\n const mfeData = this.dataset.mfeData\n ? /*\n * Data was stringified in order to come through the data-mfe-data attribute\n * So we must JSON.parse it here to get an object back\n */\n JSON.parse(this.dataset.mfeData)\n : /*\n * If mfeData isn't there, then the Host may not be up to date with web-components\n * and is instead passing data through separate data-attributes, so we want to\n * spread all of those instead\n */\n { ...this.dataset };\n\n const metadata = {\n shadowRoot: this.root,\n portalShadowRoot: this.portal!,\n };\n\n this.view?.rerender(\n <Provider\n singletons={[\n { provide: IS_WEB_COMPONENT_TOKEN, useValue: true },\n { provide: RENDER_ROOT_TOKEN, useValue: this.root },\n ]}\n >\n <Provider\n singletons={[\n { provide: Log, useValue: this.logService },\n {\n provide: HistoryManager,\n useValue: this.historyManager,\n },\n {\n provide: EXPOSED_DEPENDENCIES_TOKEN,\n useValue: this.exposedDependencies,\n },\n {\n provide: EXPOSED_INSTANCE_DEPENDENCIES_TOKEN,\n useValue: this.exposedInstanceDependencies,\n },\n { provide: BASENAME_TOKEN, useValue: this.basename },\n { provide: EVENT_BUS_TOKEN, useValue: this.eventBus },\n { provide: getLDServiceToken(), useValue: this.ldService },\n ].filter(\n ({ provide, useValue }) =>\n useValue !== undefined && provide !== undefined\n )}\n >\n <MFEDataContext.Provider value={{ ...mfeData }}>\n <MFEMetadataContext.Provider value={metadata}>\n {this.withProviders(<Component {...mfeData} />)}\n {this.onReady && <RenderCallback callback={this.onReady} />}\n </MFEMetadataContext.Provider>\n </MFEDataContext.Provider>\n </Provider>\n </Provider>\n );\n }\n };\n }\n\n if (!WEB_COMPONENT_NAME) {\n // eslint-disable-next-line no-console\n console.error('\"WEB_COMPONENT_NAME\" is not defined!');\n return;\n }\n\n window.customElements.define(WEB_COMPONENT_NAME, WebComponent);\n}\n\nfunction getStyleUrls(light: boolean, sharedDependenciesNames: string[], el: HTMLElement) {\n function getCssUrl(dependencyName: string, cssFileRegEx: RegExp) {\n if (light && sharedDependenciesNames.includes(dependencyName)) {\n return Array.from(document.getElementsByTagName('link')).find(\n ({ href }) => href && cssFileRegEx.test(href)\n )?.href;\n }\n }\n\n const designSystemUrl = getCssUrl(\n '@servicetitan/design-system',\n /design-system(\\..+)?\\.bundle\\.css/\n );\n const anvil2CssUrl = getCssUrl('@servicetitan/anvil2', /anvil2(\\..+)?\\.bundle\\.css/);\n\n return [\n ...(designSystemUrl ? [designSystemUrl] : []),\n ...(anvil2CssUrl ? [anvil2CssUrl] : []),\n ...(el.hasAttribute('style-urls')\n ? JSON.parse(decodeURIComponent(el.getAttribute('style-urls')!))\n : []),\n ];\n}\n\nfunction RenderCallback({ callback }: { callback: () => void }) {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(() => callback(), []);\n return null;\n}\n"],"names":["Log","Provider","useEffect","BASENAME_TOKEN","EXPOSED_DEPENDENCIES_TOKEN","EXPOSED_INSTANCE_DEPENDENCIES_TOKEN","IS_WEB_COMPONENT_TOKEN","RENDER_ROOT_TOKEN","MFEDataContext","MFEMetadataContext","EVENT_BUS_TOKEN","WEB_COMPONENT_NAME","HistoryManager","render","getElementName","getLDServiceToken","createLink","url","onLoad","element","document","createElement","href","rel","crossOrigin","onload","onerror","Placeholder","div","style","display","register","Component","light","options","WebComponent","HTMLElement","connectedCallback","root","isConnected","sharedDependenciesNames","styleUrls","getStyleUrls","styles","total","length","loaded","elements","shadowRoot","attachShadow","mode","portalElement","setAttribute","portal","body","appendChild","portalAnvilContainer","view","push","attachStyles","disconnectedCallback","remove","unmount","removeChild","host","undefined","onDispose","observedAttributes","attributeChangedCallback","withAnvil1Providers","children","DefaultPortalContext","TablePopupPropsContext","require","value","props","appendTo","withAnvil2Providers","PortalProvider","withProviders","ldService","logService","historyManager","exposedDependencies","exposedInstanceDependencies","eventBus","basename","onReady","provide","entries","key","Object","handleLoad","node","urls","mfeData","dataset","JSON","parse","metadata","portalShadowRoot","rerender","singletons","useValue","filter","RenderCallback","callback","console","error","window","customElements","define","el","getCssUrl","dependencyName","cssFileRegEx","includes","Array","from","getElementsByTagName","find","test","designSystemUrl","anvil2CssUrl","hasAttribute","decodeURIComponent","getAttribute"],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -3,7 +3,7 @@ export type JSON = JSONPrimitive | {
3
3
  [key: string | number]: JSON;
4
4
  } | JSON[];
5
5
  export type Serializable<T> = {
6
- [P in keyof T]: T[P] extends JSONPrimitive ? T[P] : T[P] extends Function | Date | Map<any, any> | Set<any> | symbol ? never : T[P] extends (infer U)[] ? Serializable<U>[] : Serializable<T[P]>;
6
+ [P in keyof T]: T[P] extends JSON ? T[P] : T[P] extends Function | Date | Map<any, any> | Set<any> | symbol ? never : T[P] extends (infer U)[] ? Serializable<U>[] : Serializable<T[P]>;
7
7
  };
8
8
  export interface Metadata {
9
9
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC;AAEzE,MAAM,MAAM,IAAI,GAAG,aAAa,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,EAAE,CAAC;AAE7E,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI;KACzB,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,aAAa,GACpC,CAAC,CAAC,CAAC,CAAC,GACJ,CAAC,CAAC,CAAC,CAAC,SAAS,QAAQ,GAAG,IAAI,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,GAC9D,KAAK,GACL,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GACtB,YAAY,CAAC,CAAC,CAAC,EAAE,GACjB,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC/B,CAAC;AAEF,MAAM,WAAW,QAAQ;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACjD,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAAC,EAAE,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACjE"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC;AAEzE,MAAM,MAAM,IAAI,GAAG,aAAa,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,EAAE,CAAC;AAE7E,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI;KACzB,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,GAC3B,CAAC,CAAC,CAAC,CAAC,GACJ,CAAC,CAAC,CAAC,CAAC,SAAS,QAAQ,GAAG,IAAI,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,GAC9D,KAAK,GACL,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GACtB,YAAY,CAAC,CAAC,CAAC,EAAE,GACjB,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC/B,CAAC;AAEF,MAAM,WAAW,QAAQ;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACjD,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAAC,EAAE,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACjE"}
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["export type JSONPrimitive = string | number | boolean | null | undefined;\n\nexport type JSON = JSONPrimitive | { [key: string | number]: JSON } | JSON[];\n\nexport type Serializable<T> = {\n [P in keyof T]: T[P] extends JSONPrimitive\n ? T[P]\n : T[P] extends Function | Date | Map<any, any> | Set<any> | symbol\n ? never\n : T[P] extends (infer U)[]\n ? Serializable<U>[]\n : Serializable<T[P]>;\n};\n\nexport interface Metadata {\n name: string;\n version?: string;\n bundledWith?: Record<string, string | undefined>;\n sharedDependencies: Record<string, string>;\n dependencies?: Record<string, string>;\n entrypoints?: Record<string, { css: string[]; js: string[] }>;\n}\n"],"names":[],"mappings":"AAcA,WAOC"}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["export type JSONPrimitive = string | number | boolean | null | undefined;\n\nexport type JSON = JSONPrimitive | { [key: string | number]: JSON } | JSON[];\n\nexport type Serializable<T> = {\n [P in keyof T]: T[P] extends JSON\n ? T[P]\n : T[P] extends Function | Date | Map<any, any> | Set<any> | symbol\n ? never\n : T[P] extends (infer U)[]\n ? Serializable<U>[]\n : Serializable<T[P]>;\n};\n\nexport interface Metadata {\n name: string;\n version?: string;\n bundledWith?: Record<string, string | undefined>;\n sharedDependencies: Record<string, string>;\n dependencies?: Record<string, string>;\n entrypoints?: Record<string, { css: string[]; js: string[] }>;\n}\n"],"names":[],"mappings":"AAcA,WAOC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@servicetitan/web-components",
3
- "version": "34.0.1",
3
+ "version": "34.1.0",
4
4
  "description": "Framework to build, register, and load Microfrontends into host applications",
5
5
  "homepage": "https://docs.st.dev/docs/frontend/uikit/web-components",
6
6
  "repository": {
@@ -16,18 +16,18 @@
16
16
  "src"
17
17
  ],
18
18
  "dependencies": {
19
- "@servicetitan/error-boundary": "34.0.1",
20
- "@servicetitan/startup-utils": "34.0.1",
19
+ "@servicetitan/error-boundary": "34.1.0",
20
+ "@servicetitan/startup-utils": "34.1.0",
21
21
  "lodash.get": "~4.4.2",
22
22
  "mitt": "~3.0.1",
23
- "semver": "~7.7.3"
23
+ "semver": "~7.7.4"
24
24
  },
25
25
  "devDependencies": {
26
- "@servicetitan/anvil2": "^2.0.1",
26
+ "@servicetitan/anvil2": "^2.1.0",
27
27
  "@servicetitan/design-system": "~14.5.3",
28
- "@servicetitan/launchdarkly-service": "34.0.1",
29
- "@servicetitan/log-service": "34.0.1",
30
- "@servicetitan/react-ioc": "34.0.1",
28
+ "@servicetitan/launchdarkly-service": "34.1.0",
29
+ "@servicetitan/log-service": "34.1.0",
30
+ "@servicetitan/react-ioc": "34.1.0",
31
31
  "@testing-library/dom": "^10.4.1",
32
32
  "@testing-library/jest-dom": "^6.9.1",
33
33
  "@testing-library/react": "^16.3.2",
@@ -45,9 +45,9 @@
45
45
  "peerDependencies": {
46
46
  "@servicetitan/anvil2": ">=1.5.0",
47
47
  "@servicetitan/design-system": ">=14.5.3",
48
- "@servicetitan/launchdarkly-service": "34.0.1",
49
- "@servicetitan/log-service": "34.0.1",
50
- "@servicetitan/react-ioc": "34.0.1",
48
+ "@servicetitan/launchdarkly-service": "34.1.0",
49
+ "@servicetitan/log-service": "34.1.0",
50
+ "@servicetitan/react-ioc": "34.1.0",
51
51
  "history": "~4.10.1",
52
52
  "react": ">=17.0.2",
53
53
  "react-dom": ">=17.0.2"
@@ -69,5 +69,5 @@
69
69
  "cli": {
70
70
  "webpack": false
71
71
  },
72
- "gitHead": "e42375d199bbc11b2f0b8881c26a8f0229446256"
72
+ "gitHead": "660a104c81cce6867a7bb3081ab3f2f0140e403a"
73
73
  }
@@ -1,7 +1,7 @@
1
1
  import { LD_SERVICE_TOKEN } from '@servicetitan/launchdarkly-service';
2
2
  import { Log } from '@servicetitan/log-service';
3
3
  import { Provider, ProviderProps } from '@servicetitan/react-ioc';
4
- import { getVersionMismatches } from '@servicetitan/startup-utils';
4
+ import { ExposedDependencies, getVersionMismatches } from '@servicetitan/startup-utils';
5
5
  import '@testing-library/jest-dom';
6
6
  import { act, render, screen, waitFor } from '@testing-library/react';
7
7
  import { FC, ReactNode, RefObject, useEffect, useRef } from 'react';
@@ -10,7 +10,6 @@ import {
10
10
  EXPOSED_DEPENDENCIES_TOKEN,
11
11
  EXPOSED_INSTANCE_DEPENDENCIES_TOKEN,
12
12
  Entries,
13
- ExposedDependencies,
14
13
  ExposedInstanceDependencies,
15
14
  } from '../common';
16
15
  import { EVENT_BUS_TOKEN } from '../event-bus';
@@ -291,7 +290,7 @@ describe('[web-components] Loader', () => {
291
290
  async function scriptLoadedSetup() {
292
291
  const result = subject();
293
292
 
294
- await waitFor(() => onloadRef !== undefined);
293
+ await waitFor(() => onloadRef !== null);
295
294
  act(() => {
296
295
  onloadRef!();
297
296
  });
@@ -1,21 +1,16 @@
1
1
  import '@testing-library/jest-dom';
2
2
  import { act, render } from '@testing-library/react';
3
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
4
- // @ts-ignore because Jest mistakenly complains that "'shadow-dom-testing-library' cannot be imported using this construct".
5
3
  import { screen } from 'shadow-dom-testing-library';
6
-
7
4
  import { expectStylesInDom, MockComponent, registerComponent } from '../__mocks__';
8
5
  import { IWebComponent } from '../common';
9
6
 
10
7
  describe('[web-components] register', () => {
11
8
  const baseComponentName = 'mock-app';
12
9
  const componentName = `${baseComponentName}-40b38a38`;
13
- const handleRef = (webComponent: IWebComponent | null) => {
14
- webComponent?.provide({
15
- onReady: jest.fn(),
16
- onDispose: jest.fn(),
17
- });
18
- };
10
+ let props: Record<string, any> | undefined;
11
+ let dataAttrs: Record<string, any> | undefined;
12
+ let onReady: (() => void) | undefined;
13
+ let onDispose: (() => void) | undefined;
19
14
  let onloadRefs: Function[];
20
15
 
21
16
  class Page {
@@ -52,12 +47,20 @@ describe('[web-components] register', () => {
52
47
  });
53
48
 
54
49
  beforeEach(() => {
50
+ props = undefined;
51
+ dataAttrs = undefined;
52
+ onReady = undefined;
53
+ onDispose = undefined;
55
54
  onloadRefs = [];
56
55
  });
57
56
 
58
- const subject = (props: Record<string, any> = {}, dataAttrs: Record<string, any> = {}) => {
57
+ const subject = () => {
59
58
  jest.spyOn(console, 'error').mockImplementation(jest.fn()); // suppress "attempt to unmount root while rendering" error
60
59
 
60
+ const handleRef = (webComponent: IWebComponent | null) => {
61
+ webComponent?.provide({ onReady, onDispose });
62
+ };
63
+
61
64
  const data = props && { 'data-mfe-data': JSON.stringify(props) };
62
65
  const Component: any = componentName;
63
66
  const renderResult = render(<Component ref={handleRef} {...data} {...dataAttrs} />);
@@ -71,14 +74,14 @@ describe('[web-components] register', () => {
71
74
  return renderResult;
72
75
  };
73
76
 
74
- test('useMFEMetadataContext exposes metadata', () => {
75
- subject();
76
-
77
+ test('exposes metadata', () => {
77
78
  const metadata = {
78
79
  shadowRoot: 'ShadowRoot',
79
80
  portalShadowRoot: 'ShadowRoot',
80
81
  };
81
82
 
83
+ subject();
84
+
82
85
  Object.entries(metadata).forEach(([name, value]) =>
83
86
  expect(
84
87
  screen.getByShadowText(`Metadata: ${name}, Value: ${JSON.stringify(value)}`)
@@ -87,19 +90,21 @@ describe('[web-components] register', () => {
87
90
  });
88
91
 
89
92
  describe('when component has style urls', () => {
90
- let styleUrls: string[];
93
+ const styleUrls = ['foo.css', 'bar.css'];
91
94
 
92
95
  beforeEach(() => {
93
- styleUrls = ['foo.css', 'bar.css'];
96
+ dataAttrs = { 'style-urls': JSON.stringify(styleUrls) };
94
97
  });
95
98
 
96
99
  test('loads the styles into the component shadow DOM', () => {
97
- subject({}, { 'style-urls': JSON.stringify(styleUrls) });
100
+ subject();
101
+
98
102
  expectStylesInDom(styleUrls, () => Page.componentShadowRoot);
99
103
  });
100
104
 
101
105
  test('loads the styles into the portal shadow DOM', () => {
102
- subject({}, { 'style-urls': JSON.stringify(styleUrls) });
106
+ subject();
107
+
103
108
  expectStylesInDom(styleUrls, () => Page.portalShadowRoot);
104
109
  });
105
110
 
@@ -119,7 +124,8 @@ describe('[web-components] register', () => {
119
124
  });
120
125
 
121
126
  test('loads the styles and design system styles into the component shadow DOM', () => {
122
- subject({}, { 'style-urls': JSON.stringify(styleUrls) });
127
+ subject();
128
+
123
129
  expectStylesInDom(
124
130
  [...styleUrls, designSystemLink.href],
125
131
  () => Page.componentShadowRoot
@@ -127,7 +133,8 @@ describe('[web-components] register', () => {
127
133
  });
128
134
 
129
135
  test('loads the styles and design system styles into the portal shadow DOM', () => {
130
- subject({}, { 'style-urls': JSON.stringify(styleUrls) });
136
+ subject();
137
+
131
138
  expectStylesInDom(
132
139
  [...styleUrls, designSystemLink.href],
133
140
  () => Page.portalShadowRoot
@@ -137,17 +144,19 @@ describe('[web-components] register', () => {
137
144
  });
138
145
 
139
146
  describe('when component has custom data-attributes', () => {
140
- const props = {
141
- string: 'foo',
142
- array: JSON.stringify(['foo', 'bar']),
143
- object: JSON.stringify({ foo: 'bar' }),
144
- objectNotStringified: { foo: 'bar' },
145
- };
147
+ beforeEach(() => {
148
+ props = {
149
+ string: 'foo',
150
+ array: JSON.stringify(['foo', 'bar']),
151
+ object: JSON.stringify({ foo: 'bar' }),
152
+ objectNotStringified: { foo: 'bar' },
153
+ };
154
+ });
146
155
 
147
156
  it('passes data attributes as props', () => {
148
- subject(props);
157
+ subject();
149
158
 
150
- Object.entries(props).forEach(([name, value]) =>
159
+ Object.entries(props!).forEach(([name, value]) =>
151
160
  expect(
152
161
  screen.getByShadowText(`Prop: ${name}, Value: ${JSON.stringify(value)}`)
153
162
  ).toBeInTheDocument()
@@ -155,9 +164,9 @@ describe('[web-components] register', () => {
155
164
  });
156
165
 
157
166
  test('useMFEDataContext exposes data attributes', () => {
158
- subject(props);
167
+ subject();
159
168
 
160
- Object.entries(props).forEach(([name, value]) =>
169
+ Object.entries(props!).forEach(([name, value]) =>
161
170
  expect(
162
171
  screen.getByShadowText(`Data: ${name}, Value: ${JSON.stringify(value)}`)
163
172
  ).toBeInTheDocument()
@@ -167,14 +176,17 @@ describe('[web-components] register', () => {
167
176
 
168
177
  test('logs an error when WEB_COMPONENT_NAME is not set', () => {
169
178
  const consoleSpy = jest.spyOn(console, 'error').mockImplementation(jest.fn());
179
+
170
180
  jest.isolateModules(() => {
171
181
  registerComponent(MockComponent, undefined);
172
182
  });
183
+
173
184
  expect(consoleSpy).toHaveBeenCalledWith('"WEB_COMPONENT_NAME" is not defined!');
174
185
  });
175
186
 
176
187
  test('configures the shadow root in PopupPropsContext', () => {
177
188
  subject();
189
+
178
190
  expect(screen.getByShadowText(/TablePopupPropsContext appendTo:/)).toHaveTextContent(
179
191
  /\[object ShadowRoot\]/
180
192
  );
@@ -185,4 +197,37 @@ describe('[web-components] register', () => {
185
197
 
186
198
  expect(Page.portalElement).toHaveAttribute('data-mfe-portal-name', baseComponentName);
187
199
  });
200
+
201
+ test('does not throw when document body is removed', () => {
202
+ const body = document.body;
203
+ const parentNode = body.parentNode!;
204
+ try {
205
+ subject();
206
+ expect(() => parentNode.removeChild(body)).not.toThrow();
207
+ } finally {
208
+ parentNode.appendChild(body);
209
+ }
210
+ });
211
+
212
+ describe('with onReady callback', () => {
213
+ beforeEach(() => (onReady = jest.fn()));
214
+
215
+ test('calls onReady', () => {
216
+ subject();
217
+
218
+ expect(onReady).toHaveBeenCalled();
219
+ });
220
+ });
221
+
222
+ describe('with onDispose callback', () => {
223
+ beforeEach(() => (onDispose = jest.fn()));
224
+
225
+ test('calls onDispose when element is removed from DOM', () => {
226
+ const { container } = subject();
227
+
228
+ container.parentNode!.removeChild(container);
229
+
230
+ expect(onDispose).toHaveBeenCalled();
231
+ });
232
+ });
188
233
  });
package/src/common.ts CHANGED
@@ -2,7 +2,6 @@ import { type LDService } from '@servicetitan/launchdarkly-service';
2
2
  import { Log } from '@servicetitan/log-service';
3
3
  import { symbolToken } from '@servicetitan/react-ioc';
4
4
  import { ExposedDependencies } from '@servicetitan/startup-utils';
5
- import { useRef } from 'react';
6
5
  import { EventBus } from './event-bus';
7
6
  import { HistoryManager } from './history-manager';
8
7
 
@@ -28,8 +27,8 @@ export interface Entries {
28
27
  exposedInstanceDependencies?: ExposedInstanceDependencies;
29
28
  eventBus?: EventBus;
30
29
  basename?: string;
31
- onReady: () => void;
32
- onDispose: () => void;
30
+ onReady?: () => void;
31
+ onDispose?: () => void;
33
32
  }
34
33
 
35
34
  export interface IWebComponent {
@@ -109,7 +108,3 @@ export async function getJson<T = any>(
109
108
 
110
109
  return { data: responseJSON, headers: response.headers, url: response.url ?? url };
111
110
  }
112
-
113
- export function useCancelation() {
114
- return useRef(new AbortController()).current;
115
- }
@@ -1,20 +1,8 @@
1
1
  import { createContext, useContext } from 'react';
2
2
 
3
- type JSONPrimitive = string | number | boolean | null | undefined;
3
+ import { JSON, Serializable } from '../types';
4
4
 
5
- // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
6
- type JSON = { [key: string]: JSONPrimitive | JSON[] | JSON };
7
-
8
- // Type complexity below is required to support Interfaces being used
9
- export type MFEContextData<T> = {
10
- [P in keyof T]: T[P] extends JSONPrimitive
11
- ? T[P]
12
- : T[P] extends (infer U)[]
13
- ? MFEContextData<U>[]
14
- : T[P] extends JSON
15
- ? MFEContextData<T[P]>
16
- : never;
17
- };
5
+ export type MFEContextData<T> = Serializable<T>;
18
6
 
19
7
  /**
20
8
  * Context used to pass data from the host to the MFEs
@@ -1,5 +1,6 @@
1
1
  import { renderHook } from '@testing-library/react';
2
2
  import { FC, PropsWithChildren } from 'react';
3
+ import { JSON } from '../../types';
3
4
  import { MFEDataContext, useMFEDataContext } from '../mfe-data-context';
4
5
 
5
6
  describe(`[web-components] ${useMFEDataContext.name}`, () => {
@@ -25,4 +26,39 @@ describe(`[web-components] ${useMFEDataContext.name}`, () => {
25
26
  expect(subject(Wrapper).result.current).toEqual({});
26
27
  });
27
28
  });
29
+
30
+ describe('type definitions', () => {
31
+ test('accepts properties typed as JSON', () => {
32
+ renderHook(() => useMFEDataContext<{ data: JSON }>());
33
+ });
34
+
35
+ test('accepts properties typed as Record<string, JSON>', () => {
36
+ renderHook(() => useMFEDataContext<{ metadata: Record<string, JSON> }>());
37
+ });
38
+
39
+ test('accepts primitive properties', () => {
40
+ renderHook(() => useMFEDataContext<{ name: string; count: number; active: boolean }>());
41
+ });
42
+
43
+ test('accepts nested objects and arrays', () => {
44
+ renderHook(() => useMFEDataContext<{ nested: { value: number }; list: string[] }>());
45
+ });
46
+
47
+ test('rejects non-serializable properties', () => {
48
+ // @ts-expect-error Type '() => void' is not assignable to type 'never'.
49
+ renderHook(() => useMFEDataContext<{ callback: () => void }>());
50
+
51
+ // @ts-expect-error Type 'Date' is not assignable to type 'never'.
52
+ renderHook(() => useMFEDataContext<{ created: Date }>());
53
+
54
+ // @ts-expect-error Type 'Map<string, any>' is not assignable to type 'never'.
55
+ renderHook(() => useMFEDataContext<{ lookup: Map<string, any> }>());
56
+
57
+ // @ts-expect-error Type 'Set<string>' is not assignable to type 'never'.
58
+ renderHook(() => useMFEDataContext<{ tags: Set<string> }>());
59
+
60
+ // @ts-expect-error Type 'symbol' is not assignable to type 'never'.
61
+ renderHook(() => useMFEDataContext<{ id: symbol }>());
62
+ });
63
+ });
28
64
  });
package/src/loader.tsx CHANGED
@@ -20,7 +20,6 @@ import {
20
20
  EXPOSED_INSTANCE_DEPENDENCIES_TOKEN,
21
21
  ExposedInstanceDependencies,
22
22
  GetJsonError,
23
- useCancelation,
24
23
  } from './common';
25
24
  import { MFEContextData } from './contexts/mfe-data-context';
26
25
  import { Delayed } from './delayed';
@@ -85,7 +84,6 @@ const UnrestrictedLoader = <T,>(props: UnrestrictedLoaderProps<T>, ref: Ref<Load
85
84
  EXPOSED_INSTANCE_DEPENDENCIES_TOKEN
86
85
  );
87
86
  const [ldService] = useOptionalDependencies(getLDServiceToken() ?? Symbol());
88
- const cancelation = useCancelation();
89
87
 
90
88
  const LoadingFallback = useMemo(() => {
91
89
  const message = `Loading${isLocalHost(src) ? ` ${src}` : ''}...`;
@@ -102,23 +100,9 @@ const UnrestrictedLoader = <T,>(props: UnrestrictedLoaderProps<T>, ref: Ref<Load
102
100
  [exposedInstanceDependencies, ldService]
103
101
  );
104
102
 
105
- const Loader = useMemo(
106
- () =>
107
- lazyLoader({
108
- basename,
109
- cache,
110
- cancelation,
111
- exposedDependencies,
112
- exposedInstanceDependencies,
113
- eventBus,
114
- fallbackSrc,
115
- isHeadless,
116
- logService,
117
- onRequestError,
118
- retries,
119
- src,
120
- }),
121
- [
103
+ const Loader = useMemo(() => {
104
+ const cancelation = new AbortController();
105
+ return lazyLoader({
122
106
  basename,
123
107
  cache,
124
108
  cancelation,
@@ -131,8 +115,20 @@ const UnrestrictedLoader = <T,>(props: UnrestrictedLoaderProps<T>, ref: Ref<Load
131
115
  onRequestError,
132
116
  retries,
133
117
  src,
134
- ]
135
- );
118
+ });
119
+ }, [
120
+ basename,
121
+ cache,
122
+ exposedDependencies,
123
+ exposedInstanceDependencies,
124
+ eventBus,
125
+ fallbackSrc,
126
+ isHeadless,
127
+ logService,
128
+ onRequestError,
129
+ retries,
130
+ src,
131
+ ]);
136
132
 
137
133
  useImperativeHandle(ref, () => eventBus, [eventBus]);
138
134
 
package/src/register.tsx CHANGED
@@ -110,7 +110,7 @@ export function register(Component: ComponentType, light: boolean, options?: Reg
110
110
  }
111
111
 
112
112
  disconnectedCallback() {
113
- if (!this.root || this.root?.isConnected) {
113
+ if (!this.root || this.root.isConnected) {
114
114
  return;
115
115
  }
116
116
  for (const element of this.styles.elements) {
@@ -118,7 +118,7 @@ export function register(Component: ComponentType, light: boolean, options?: Reg
118
118
  }
119
119
 
120
120
  this.view?.unmount();
121
- document.body.removeChild(this.portal!.host);
121
+ document.body?.removeChild(this.portal!.host);
122
122
  this.root = undefined;
123
123
  this.portal = undefined;
124
124
  this.portalAnvilContainer = undefined;
@@ -140,7 +140,7 @@ export function register(Component: ComponentType, light: boolean, options?: Reg
140
140
  this[key as keyof IWebComponent] = value;
141
141
  }
142
142
 
143
- if (this.styles.loaded === this.styles.total && Object.values(entries).some(v => !!v)) {
143
+ if (this.styles.loaded === this.styles.total) {
144
144
  this.render();
145
145
  }
146
146
  };
package/src/types.ts CHANGED
@@ -3,7 +3,7 @@ export type JSONPrimitive = string | number | boolean | null | undefined;
3
3
  export type JSON = JSONPrimitive | { [key: string | number]: JSON } | JSON[];
4
4
 
5
5
  export type Serializable<T> = {
6
- [P in keyof T]: T[P] extends JSONPrimitive
6
+ [P in keyof T]: T[P] extends JSON
7
7
  ? T[P]
8
8
  : T[P] extends Function | Date | Map<any, any> | Set<any> | symbol
9
9
  ? never