@descope/sdk-mixins 0.14.0 → 0.15.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.
Files changed (35) hide show
  1. package/dist/cjs/mixins/loggerMixin/loggerMixin.js +8 -2
  2. package/dist/cjs/mixins/loggerMixin/loggerMixin.js.map +1 -1
  3. package/dist/cjs/mixins/staticResourcesMixin/constants.js +2 -0
  4. package/dist/cjs/mixins/staticResourcesMixin/constants.js.map +1 -1
  5. package/dist/cjs/mixins/staticResourcesMixin/staticResourcesMixin.js +46 -31
  6. package/dist/cjs/mixins/staticResourcesMixin/staticResourcesMixin.js.map +1 -1
  7. package/dist/esm/mixins/loggerMixin/loggerMixin.js +8 -2
  8. package/dist/esm/mixins/loggerMixin/loggerMixin.js.map +1 -1
  9. package/dist/esm/mixins/staticResourcesMixin/constants.js +2 -1
  10. package/dist/esm/mixins/staticResourcesMixin/constants.js.map +1 -1
  11. package/dist/esm/mixins/staticResourcesMixin/staticResourcesMixin.js +47 -32
  12. package/dist/esm/mixins/staticResourcesMixin/staticResourcesMixin.js.map +1 -1
  13. package/dist/index.d.ts +177 -151
  14. package/dist/types/mixins/configMixin/configMixin.d.ts +16 -12
  15. package/dist/types/mixins/createStateManagementMixin.d.ts +2 -2
  16. package/dist/types/mixins/createValidateAttributesMixin/createValidateAttributesMixin.d.ts +5 -5
  17. package/dist/types/mixins/cspNonceMixin.d.ts +5 -5
  18. package/dist/types/mixins/debuggerMixin/debugger-wc.d.ts +5 -5
  19. package/dist/types/mixins/debuggerMixin/debuggerMixin.d.ts +8 -8
  20. package/dist/types/mixins/descopeUiMixin/descopeUiMixin.d.ts +20 -16
  21. package/dist/types/mixins/formMixin.d.ts +2 -2
  22. package/dist/types/mixins/initElementMixin.d.ts +5 -5
  23. package/dist/types/mixins/initLifecycleMixin.d.ts +1 -1
  24. package/dist/types/mixins/injectNpmLibMixin/injectNpmLibMixin.d.ts +2 -2
  25. package/dist/types/mixins/injectStyleMixin.d.ts +5 -5
  26. package/dist/types/mixins/loggerMixin/loggerMixin.d.ts +2 -2
  27. package/dist/types/mixins/modalMixin/modalMixin.d.ts +24 -20
  28. package/dist/types/mixins/notificationsMixin/notificationsMixin.d.ts +24 -20
  29. package/dist/types/mixins/observeAttributesMixin/observeAttributesMixin.d.ts +4 -4
  30. package/dist/types/mixins/projectIdMixin.d.ts +5 -5
  31. package/dist/types/mixins/resetMixin.d.ts +6 -6
  32. package/dist/types/mixins/staticResourcesMixin/constants.d.ts +1 -0
  33. package/dist/types/mixins/staticResourcesMixin/staticResourcesMixin.d.ts +10 -8
  34. package/dist/types/mixins/themeMixin/themeMixin.d.ts +37 -29
  35. package/package.json +1 -1
@@ -4,14 +4,20 @@ var tslib = require('tslib');
4
4
  var sdkHelpers = require('@descope/sdk-helpers');
5
5
 
6
6
  const logLevels = ['error', 'warn', 'info', 'debug'];
7
+ const defaultLogger = {
8
+ error: console.error.bind(console, '[Descope]'),
9
+ warn: console.warn.bind(console, '[Descope]'),
10
+ info: console.info.bind(console, '[Descope]'),
11
+ debug: console.debug.bind(console, '[Descope]'),
12
+ };
7
13
  const loggerMixin = sdkHelpers.createSingletonMixin((superclass) => { var _LoggerMixinClass_instances, _LoggerMixinClass_logger, _LoggerMixinClass_wrapLogger, _a; return _a = class LoggerMixinClass extends superclass {
8
14
  constructor() {
9
15
  super(...arguments);
10
16
  _LoggerMixinClass_instances.add(this);
11
- _LoggerMixinClass_logger.set(this, tslib.__classPrivateFieldGet(this, _LoggerMixinClass_instances, "m", _LoggerMixinClass_wrapLogger).call(this, console));
17
+ _LoggerMixinClass_logger.set(this, tslib.__classPrivateFieldGet(this, _LoggerMixinClass_instances, "m", _LoggerMixinClass_wrapLogger).call(this, defaultLogger));
12
18
  }
13
19
  set logger(logger) {
14
- tslib.__classPrivateFieldSet(this, _LoggerMixinClass_logger, tslib.__classPrivateFieldGet(this, _LoggerMixinClass_instances, "m", _LoggerMixinClass_wrapLogger).call(this, logger || console), "f");
20
+ tslib.__classPrivateFieldSet(this, _LoggerMixinClass_logger, tslib.__classPrivateFieldGet(this, _LoggerMixinClass_instances, "m", _LoggerMixinClass_wrapLogger).call(this, logger || defaultLogger), "f");
15
21
  }
16
22
  get logger() {
17
23
  return tslib.__classPrivateFieldGet(this, _LoggerMixinClass_logger, "f");
@@ -1 +1 @@
1
- {"version":3,"file":"loggerMixin.js","sources":["../../../../src/mixins/loggerMixin/loggerMixin.ts"],"sourcesContent":["import { createSingletonMixin } from '@descope/sdk-helpers';\nimport { Logger } from './types';\n\nconst logLevels = ['error', 'warn', 'info', 'debug'] as const;\n\nexport type LogLevel = (typeof logLevels)[number];\n\nexport const loggerMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) =>\n class LoggerMixinClass extends superclass {\n #logger: Logger = this.#wrapLogger(console);\n\n #wrapLogger(logger: Partial<Logger>) {\n return logLevels.reduce((acc, logLevel) => {\n acc[logLevel] = (...args: any[]) => {\n this.onLogEvent(logLevel, args);\n logger[logLevel]?.(...args);\n };\n\n return acc;\n }, {}) as Logger;\n }\n\n set logger(logger: Partial<Logger> | undefined) {\n this.#logger = this.#wrapLogger(logger || console);\n }\n\n get logger(): Logger {\n return this.#logger;\n }\n\n // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars\n onLogEvent(logLevel: LogLevel, data: any[]) {}\n },\n);\n"],"names":["createSingletonMixin","__classPrivateFieldGet","__classPrivateFieldSet"],"mappings":";;;;;AAGA,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAIvD,MAAM,WAAW,GAAGA,+BAAoB,CAC7C,CAAqC,UAAa,KAAI,EAAA,IAAA,2BAAA,EAAA,wBAAA,EAAA,4BAAA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,GACpD,MAAM,gBAAiB,SAAQ,UAAU,CAAA;AAAzC,QAAA,WAAA,GAAA;;;YACE,wBAAkB,CAAA,GAAA,CAAA,IAAA,EAAAC,4BAAA,CAAA,IAAI,EAAY,2BAAA,EAAA,GAAA,EAAA,4BAAA,CAAA,CAAA,IAAA,CAAhB,IAAI,EAAa,OAAO,CAAC,CAAC,CAAA;SAuB7C;QAVC,IAAI,MAAM,CAAC,MAAmC,EAAA;AAC5C,YAAAC,4BAAA,CAAA,IAAI,EAAA,wBAAA,EAAWD,4BAAA,CAAA,IAAI,EAAY,2BAAA,EAAA,GAAA,EAAA,4BAAA,CAAA,CAAA,IAAA,CAAhB,IAAI,EAAa,MAAM,IAAI,OAAO,CAAC,MAAA,CAAC;SACpD;AAED,QAAA,IAAI,MAAM,GAAA;YACR,OAAOA,4BAAA,CAAA,IAAI,EAAA,wBAAA,EAAA,GAAA,CAAQ,CAAC;SACrB;;AAGD,QAAA,UAAU,CAAC,QAAkB,EAAE,IAAW,KAAI;AAC/C,KAAA;;;yEArBa,MAAuB,EAAA;QACjC,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,QAAQ,KAAI;YACxC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAW,KAAI;;AACjC,gBAAA,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;gBAChC,CAAA,EAAA,GAAA,MAAM,CAAC,QAAQ,CAAC,uDAAG,GAAG,IAAI,CAAC,CAAC;AAC9B,aAAC,CAAC;AAEF,YAAA,OAAO,GAAG,CAAC;SACZ,EAAE,EAAE,CAAW,CAAC;KAClB;AAYF,IAAA,EAAA,CAAA,EAAA;;;;"}
1
+ {"version":3,"file":"loggerMixin.js","sources":["../../../../src/mixins/loggerMixin/loggerMixin.ts"],"sourcesContent":["/* eslint-disable import/exports-last, no-console */\nimport { createSingletonMixin } from '@descope/sdk-helpers';\nimport { Logger } from './types';\n\nconst logLevels = ['error', 'warn', 'info', 'debug'] as const;\n\nexport type LogLevel = (typeof logLevels)[number];\n\nconst defaultLogger: Logger = {\n error: console.error.bind(console, '[Descope]'),\n warn: console.warn.bind(console, '[Descope]'),\n info: console.info.bind(console, '[Descope]'),\n debug: console.debug.bind(console, '[Descope]'),\n};\n\nexport const loggerMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) =>\n class LoggerMixinClass extends superclass {\n #logger: Logger = this.#wrapLogger(defaultLogger);\n\n #wrapLogger(logger: Partial<Logger>) {\n return logLevels.reduce((acc, logLevel) => {\n acc[logLevel] = (...args: any[]) => {\n this.onLogEvent(logLevel, args);\n logger[logLevel]?.(...args);\n };\n\n return acc;\n }, {}) as Logger;\n }\n\n set logger(logger: Partial<Logger> | undefined) {\n this.#logger = this.#wrapLogger(logger || defaultLogger);\n }\n\n get logger(): Logger {\n return this.#logger;\n }\n\n // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars\n onLogEvent(logLevel: LogLevel, data: any[]) {}\n },\n);\n"],"names":["createSingletonMixin","__classPrivateFieldGet","__classPrivateFieldSet"],"mappings":";;;;;AAIA,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAI9D,MAAM,aAAa,GAAW;IAC5B,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC;IAC/C,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC;IAC7C,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC;IAC7C,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC;CAChD,CAAC;AAEK,MAAM,WAAW,GAAGA,+BAAoB,CAC7C,CAAqC,UAAa,KAAI,EAAA,IAAA,2BAAA,EAAA,wBAAA,EAAA,4BAAA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,GACpD,MAAM,gBAAiB,SAAQ,UAAU,CAAA;AAAzC,QAAA,WAAA,GAAA;;;YACE,wBAAkB,CAAA,GAAA,CAAA,IAAA,EAAAC,4BAAA,CAAA,IAAI,EAAY,2BAAA,EAAA,GAAA,EAAA,4BAAA,CAAA,CAAA,IAAA,CAAhB,IAAI,EAAa,aAAa,CAAC,CAAC,CAAA;SAuBnD;QAVC,IAAI,MAAM,CAAC,MAAmC,EAAA;AAC5C,YAAAC,4BAAA,CAAA,IAAI,EAAA,wBAAA,EAAWD,4BAAA,CAAA,IAAI,EAAY,2BAAA,EAAA,GAAA,EAAA,4BAAA,CAAA,CAAA,IAAA,CAAhB,IAAI,EAAa,MAAM,IAAI,aAAa,CAAC,MAAA,CAAC;SAC1D;AAED,QAAA,IAAI,MAAM,GAAA;YACR,OAAOA,4BAAA,CAAA,IAAI,EAAA,wBAAA,EAAA,GAAA,CAAQ,CAAC;SACrB;;AAGD,QAAA,UAAU,CAAC,QAAkB,EAAE,IAAW,KAAI;AAC/C,KAAA;;;yEArBa,MAAuB,EAAA;QACjC,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,QAAQ,KAAI;YACxC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAW,KAAI;;AACjC,gBAAA,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;gBAChC,CAAA,EAAA,GAAA,MAAM,CAAC,QAAQ,CAAC,uDAAG,GAAG,IAAI,CAAC,CAAC;AAC9B,aAAC,CAAC;AAEF,YAAA,OAAO,GAAG,CAAC;SACZ,EAAE,EAAE,CAAW,CAAC;KAClB;AAYF,IAAA,EAAA,CAAA,EAAA;;;;"}
@@ -4,10 +4,12 @@ var constants = require('../../constants.js');
4
4
 
5
5
  const BASE_CONTENT_URL_KEY = 'base.content.url';
6
6
  const BASE_CONTENT_URL = 'https://static.descope.com/pages';
7
+ const BASE_CONTENT_URL_FALLBACK = 'https://static2.descope.com/pages';
7
8
  const OVERRIDE_CONTENT_URL = (constants.IS_LOCAL_STORAGE && localStorage.getItem(BASE_CONTENT_URL_KEY)) || '';
8
9
  const ASSETS_FOLDER = 'v2-beta';
9
10
 
10
11
  exports.ASSETS_FOLDER = ASSETS_FOLDER;
11
12
  exports.BASE_CONTENT_URL = BASE_CONTENT_URL;
13
+ exports.BASE_CONTENT_URL_FALLBACK = BASE_CONTENT_URL_FALLBACK;
12
14
  exports.OVERRIDE_CONTENT_URL = OVERRIDE_CONTENT_URL;
13
15
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sources":["../../../../src/mixins/staticResourcesMixin/constants.ts"],"sourcesContent":["import { IS_LOCAL_STORAGE } from '../../constants';\n\nconst BASE_CONTENT_URL_KEY = 'base.content.url';\n\nexport const BASE_CONTENT_URL = 'https://static.descope.com/pages';\n\nexport const OVERRIDE_CONTENT_URL =\n (IS_LOCAL_STORAGE && localStorage.getItem(BASE_CONTENT_URL_KEY)) || '';\n\nexport const ASSETS_FOLDER = 'v2-beta';\nexport const PREV_VER_ASSETS_FOLDER = 'v2-alpha';\n"],"names":["IS_LOCAL_STORAGE"],"mappings":";;;;AAEA,MAAM,oBAAoB,GAAG,kBAAkB,CAAC;AAEzC,MAAM,gBAAgB,GAAG,mCAAmC;AAEtD,MAAA,oBAAoB,GAC/B,CAACA,0BAAgB,IAAI,YAAY,CAAC,OAAO,CAAC,oBAAoB,CAAC,KAAK,GAAG;AAElE,MAAM,aAAa,GAAG;;;;;;"}
1
+ {"version":3,"file":"constants.js","sources":["../../../../src/mixins/staticResourcesMixin/constants.ts"],"sourcesContent":["import { IS_LOCAL_STORAGE } from '../../constants';\n\nconst BASE_CONTENT_URL_KEY = 'base.content.url';\n\nexport const BASE_CONTENT_URL = 'https://static.descope.com/pages';\nexport const BASE_CONTENT_URL_FALLBACK = 'https://static2.descope.com/pages';\n\nexport const OVERRIDE_CONTENT_URL =\n (IS_LOCAL_STORAGE && localStorage.getItem(BASE_CONTENT_URL_KEY)) || '';\n\nexport const ASSETS_FOLDER = 'v2-beta';\nexport const PREV_VER_ASSETS_FOLDER = 'v2-alpha';\n"],"names":["IS_LOCAL_STORAGE"],"mappings":";;;;AAEA,MAAM,oBAAoB,GAAG,kBAAkB,CAAC;AAEzC,MAAM,gBAAgB,GAAG,mCAAmC;AAC5D,MAAM,yBAAyB,GAAG,oCAAoC;AAEhE,MAAA,oBAAoB,GAC/B,CAACA,0BAAgB,IAAI,YAAY,CAAC,OAAO,CAAC,oBAAoB,CAAC,KAAK,GAAG;AAElE,MAAM,aAAa,GAAG;;;;;;;"}
@@ -16,31 +16,35 @@ function getResourceUrl({ projectId, filename, assetsFolder = constants.ASSETS_F
16
16
  return url;
17
17
  }
18
18
  const staticResourcesMixin = sdkHelpers.createSingletonMixin((superclass) => {
19
- var _StaticResourcesMixinClass_instances, _StaticResourcesMixinClass_lastBaseUrl, _StaticResourcesMixinClass_workingBaseUrl, _StaticResourcesMixinClass_getResourceUrls, _a;
19
+ var _StaticResourcesMixinClass_instances, _StaticResourcesMixinClass_lastBaseUrl, _StaticResourcesMixinClass_workingBaseUrl, _StaticResourcesMixinClass_failedUrls, _StaticResourcesMixinClass_getResourceUrls, _StaticResourcesMixinClass_createResourceUrl, _a;
20
20
  const BaseClass = sdkHelpers.compose(loggerMixin.loggerMixin, projectIdMixin.projectIdMixin, baseUrlMixin.baseUrlMixin)(superclass);
21
21
  // the logic should be as following:
22
- // if there is a local storage override, use it
23
- // otherwise, if there is a base-static-url attribute, use it
24
- // otherwise, try to use base-url, and check if it's working
25
- // if it's working, use it
26
- // if not, use the default content url
22
+ // 1. if there is a local storage override, use it
23
+ // 2. otherwise, if there is a base-static-url attribute, use it
24
+ // 3. otherwise, try to use base-url
25
+ // 4. otherwise, try to use default content url (BASE_CONTENT_URL)
26
+ // 5. otherwise, try to use the fallback content url (BASE_CONTENT_URL_FALLBACK)
27
+ // For steps 3-5: if the url is valid, keep using it, and if not, don't try it anymore
27
28
  return _a = class StaticResourcesMixinClass extends BaseClass {
28
29
  constructor() {
29
30
  super(...arguments);
30
31
  _StaticResourcesMixinClass_instances.add(this);
31
32
  _StaticResourcesMixinClass_lastBaseUrl.set(this, void 0);
32
33
  _StaticResourcesMixinClass_workingBaseUrl.set(this, void 0);
34
+ _StaticResourcesMixinClass_failedUrls.set(this, new Set());
33
35
  }
34
36
  async fetchStaticResource(filename, format) {
35
37
  const resourceUrls = tslib.__classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_getResourceUrls).call(this, filename);
36
- // if there are multiple resource urls, it means that there are fallbacks,
37
- // if one of the options (which is not the last) is working, we want to keep using it by updating the workingBaseUrl
38
+ // Cache the working URL and mark failed URLs
38
39
  const onSuccess = !Array.isArray(resourceUrls)
39
40
  ? null
40
41
  : (index) => {
41
- if (index !== resourceUrls.length - 1) {
42
- const { baseUrl } = resourceUrls[index];
43
- tslib.__classPrivateFieldSet(this, _StaticResourcesMixinClass_workingBaseUrl, baseUrl, "f");
42
+ const { baseUrl } = resourceUrls[index];
43
+ tslib.__classPrivateFieldSet(this, _StaticResourcesMixinClass_workingBaseUrl, baseUrl, "f");
44
+ // Mark all URLs before this one as failed
45
+ for (let i = 0; i < index; i++) {
46
+ const failedUrl = resourceUrls[i].baseUrl;
47
+ tslib.__classPrivateFieldGet(this, _StaticResourcesMixinClass_failedUrls, "f").add(failedUrl);
44
48
  }
45
49
  };
46
50
  try {
@@ -60,38 +64,49 @@ const staticResourcesMixin = sdkHelpers.createSingletonMixin((superclass) => {
60
64
  },
61
65
  _StaticResourcesMixinClass_lastBaseUrl = new WeakMap(),
62
66
  _StaticResourcesMixinClass_workingBaseUrl = new WeakMap(),
67
+ _StaticResourcesMixinClass_failedUrls = new WeakMap(),
63
68
  _StaticResourcesMixinClass_instances = new WeakSet(),
64
69
  _StaticResourcesMixinClass_getResourceUrls = function _StaticResourcesMixinClass_getResourceUrls(filename) {
65
70
  const overrideUrl = constants.OVERRIDE_CONTENT_URL || this.baseStaticUrl;
71
+ // Steps 1-2: Override URL or base-static-url takes precedence
66
72
  if (overrideUrl) {
67
- return getResourceUrl({
68
- projectId: this.projectId,
69
- filename,
70
- baseUrl: overrideUrl,
71
- });
73
+ return tslib.__classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_createResourceUrl).call(this, filename, overrideUrl);
72
74
  }
73
- const isBaseUrlUpdated = tslib.__classPrivateFieldGet(this, _StaticResourcesMixinClass_lastBaseUrl, "f") !== this.baseUrl;
74
- const shouldFallbackFetch = isBaseUrlUpdated && !!this.baseUrl;
75
- // if the base url has changed, reset the working base url
76
- if (isBaseUrlUpdated) {
75
+ // Reset state if base-url changed
76
+ if (tslib.__classPrivateFieldGet(this, _StaticResourcesMixinClass_lastBaseUrl, "f") !== this.baseUrl) {
77
77
  tslib.__classPrivateFieldSet(this, _StaticResourcesMixinClass_lastBaseUrl, this.baseUrl, "f");
78
78
  tslib.__classPrivateFieldSet(this, _StaticResourcesMixinClass_workingBaseUrl, undefined, "f");
79
+ tslib.__classPrivateFieldGet(this, _StaticResourcesMixinClass_failedUrls, "f").clear();
79
80
  }
80
- const resourceUrl = getResourceUrl({
81
- projectId: this.projectId,
82
- filename,
83
- baseUrl: tslib.__classPrivateFieldGet(this, _StaticResourcesMixinClass_workingBaseUrl, "f"),
84
- });
85
- // if there is no reason to check the baseUrl, generate the resource url according to the priority
86
- if (!shouldFallbackFetch) {
87
- return resourceUrl;
81
+ // Build URL list based on cached state or fallback chain
82
+ const urls = [];
83
+ if (tslib.__classPrivateFieldGet(this, _StaticResourcesMixinClass_workingBaseUrl, "f")) {
84
+ // Use cached working URL
85
+ urls.push(tslib.__classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_createResourceUrl).call(this, filename, tslib.__classPrivateFieldGet(this, _StaticResourcesMixinClass_workingBaseUrl, "f")));
86
+ // Add fallback only for BASE_CONTENT_URL (for resilience)
87
+ if (tslib.__classPrivateFieldGet(this, _StaticResourcesMixinClass_workingBaseUrl, "f") === constants.BASE_CONTENT_URL) {
88
+ urls.push(tslib.__classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_createResourceUrl).call(this, filename, constants.BASE_CONTENT_URL_FALLBACK));
89
+ }
88
90
  }
89
- const resourceUrlFromBaseUrl = getResourceUrl({
91
+ else {
92
+ // Build fallback chain: try URLs that haven't failed yet
93
+ const baseUrlWithPages = this.baseUrl + '/pages';
94
+ if (this.baseUrl && !tslib.__classPrivateFieldGet(this, _StaticResourcesMixinClass_failedUrls, "f").has(baseUrlWithPages)) {
95
+ urls.push(tslib.__classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_createResourceUrl).call(this, filename, baseUrlWithPages));
96
+ }
97
+ if (!tslib.__classPrivateFieldGet(this, _StaticResourcesMixinClass_failedUrls, "f").has(constants.BASE_CONTENT_URL)) {
98
+ urls.push(tslib.__classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_createResourceUrl).call(this, filename, constants.BASE_CONTENT_URL));
99
+ }
100
+ urls.push(tslib.__classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_createResourceUrl).call(this, filename, constants.BASE_CONTENT_URL_FALLBACK));
101
+ }
102
+ return urls.length === 1 ? urls[0] : urls;
103
+ },
104
+ _StaticResourcesMixinClass_createResourceUrl = function _StaticResourcesMixinClass_createResourceUrl(filename, baseUrl) {
105
+ return getResourceUrl({
90
106
  projectId: this.projectId,
91
107
  filename,
92
- baseUrl: this.baseUrl + '/pages',
108
+ baseUrl,
93
109
  });
94
- return [resourceUrlFromBaseUrl, resourceUrl];
95
110
  },
96
111
  _a;
97
112
  });
@@ -1 +1 @@
1
- {"version":3,"file":"staticResourcesMixin.js","sources":["../../../../src/mixins/staticResourcesMixin/staticResourcesMixin.ts"],"sourcesContent":["import { pathJoin, compose, createSingletonMixin } from '@descope/sdk-helpers';\nimport { loggerMixin } from '../loggerMixin';\nimport {\n ASSETS_FOLDER,\n BASE_CONTENT_URL,\n OVERRIDE_CONTENT_URL,\n} from './constants';\nimport { projectIdMixin } from '../projectIdMixin';\nimport { baseUrlMixin } from '../baseUrlMixin';\nimport { fetchWithFallbacks } from './fetchWithFallbacks';\n\ntype Format = 'text' | 'json';\n\ntype CustomUrl = URL & { baseUrl: string };\n\nexport function getResourceUrl({\n projectId,\n filename,\n assetsFolder = ASSETS_FOLDER,\n baseUrl = BASE_CONTENT_URL,\n}: {\n projectId: string;\n filename: string;\n assetsFolder?: string;\n baseUrl?: string;\n}) {\n const url: CustomUrl = new URL(baseUrl) as any;\n url.pathname = pathJoin(url.pathname, projectId, assetsFolder, filename);\n // we want to keep the baseUrl so we can use it later\n url.baseUrl = baseUrl;\n\n return url;\n}\n\nexport const staticResourcesMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) => {\n const BaseClass = compose(\n loggerMixin,\n projectIdMixin,\n baseUrlMixin,\n )(superclass);\n\n // the logic should be as following:\n // if there is a local storage override, use it\n // otherwise, if there is a base-static-url attribute, use it\n // otherwise, try to use base-url, and check if it's working\n // if it's working, use it\n // if not, use the default content url\n return class StaticResourcesMixinClass extends BaseClass {\n #lastBaseUrl?: string;\n #workingBaseUrl?: string;\n\n #getResourceUrls(filename: string): CustomUrl[] | CustomUrl {\n const overrideUrl = OVERRIDE_CONTENT_URL || this.baseStaticUrl;\n\n if (overrideUrl) {\n return getResourceUrl({\n projectId: this.projectId,\n filename,\n baseUrl: overrideUrl,\n });\n }\n\n const isBaseUrlUpdated = this.#lastBaseUrl !== this.baseUrl;\n const shouldFallbackFetch = isBaseUrlUpdated && !!this.baseUrl;\n\n // if the base url has changed, reset the working base url\n if (isBaseUrlUpdated) {\n this.#lastBaseUrl = this.baseUrl;\n this.#workingBaseUrl = undefined;\n }\n\n const resourceUrl = getResourceUrl({\n projectId: this.projectId,\n filename,\n baseUrl: this.#workingBaseUrl,\n });\n\n // if there is no reason to check the baseUrl, generate the resource url according to the priority\n if (!shouldFallbackFetch) {\n return resourceUrl;\n }\n\n const resourceUrlFromBaseUrl = getResourceUrl({\n projectId: this.projectId,\n filename,\n baseUrl: this.baseUrl + '/pages',\n });\n\n return [resourceUrlFromBaseUrl, resourceUrl];\n }\n\n async fetchStaticResource<F extends Format>(\n filename: string,\n format: F,\n ): Promise<{\n body: F extends 'json' ? Record<string, any> : string;\n headers: Record<string, string>;\n }> {\n const resourceUrls = this.#getResourceUrls(filename);\n\n // if there are multiple resource urls, it means that there are fallbacks,\n // if one of the options (which is not the last) is working, we want to keep using it by updating the workingBaseUrl\n const onSuccess = !Array.isArray(resourceUrls)\n ? null\n : (index: number) => {\n if (index !== resourceUrls.length - 1) {\n const { baseUrl } = resourceUrls[index];\n this.#workingBaseUrl = baseUrl;\n }\n };\n\n try {\n const res = await fetchWithFallbacks(\n resourceUrls,\n { cache: 'default' },\n { logger: this.logger, onSuccess },\n );\n\n return {\n body: await res[format](),\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (e) {\n this.logger.error(e.message);\n }\n }\n\n get baseStaticUrl() {\n return this.getAttribute('base-static-url') || '';\n }\n };\n },\n);\n"],"names":["ASSETS_FOLDER","BASE_CONTENT_URL","pathJoin","createSingletonMixin","compose","loggerMixin","projectIdMixin","baseUrlMixin","__classPrivateFieldGet","__classPrivateFieldSet","fetchWithFallbacks","OVERRIDE_CONTENT_URL"],"mappings":"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"}
1
+ {"version":3,"file":"staticResourcesMixin.js","sources":["../../../../src/mixins/staticResourcesMixin/staticResourcesMixin.ts"],"sourcesContent":["import { pathJoin, compose, createSingletonMixin } from '@descope/sdk-helpers';\nimport { loggerMixin } from '../loggerMixin';\nimport {\n ASSETS_FOLDER,\n BASE_CONTENT_URL,\n BASE_CONTENT_URL_FALLBACK,\n OVERRIDE_CONTENT_URL,\n} from './constants';\nimport { projectIdMixin } from '../projectIdMixin';\nimport { baseUrlMixin } from '../baseUrlMixin';\nimport { fetchWithFallbacks } from './fetchWithFallbacks';\n\ntype Format = 'text' | 'json';\n\ntype CustomUrl = URL & { baseUrl: string };\n\nexport function getResourceUrl({\n projectId,\n filename,\n assetsFolder = ASSETS_FOLDER,\n baseUrl = BASE_CONTENT_URL,\n}: {\n projectId: string;\n filename: string;\n assetsFolder?: string;\n baseUrl?: string;\n}) {\n const url: CustomUrl = new URL(baseUrl) as any;\n url.pathname = pathJoin(url.pathname, projectId, assetsFolder, filename);\n // we want to keep the baseUrl so we can use it later\n url.baseUrl = baseUrl;\n\n return url;\n}\n\nexport const staticResourcesMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) => {\n const BaseClass = compose(\n loggerMixin,\n projectIdMixin,\n baseUrlMixin,\n )(superclass);\n\n // the logic should be as following:\n // 1. if there is a local storage override, use it\n // 2. otherwise, if there is a base-static-url attribute, use it\n // 3. otherwise, try to use base-url\n // 4. otherwise, try to use default content url (BASE_CONTENT_URL)\n // 5. otherwise, try to use the fallback content url (BASE_CONTENT_URL_FALLBACK)\n // For steps 3-5: if the url is valid, keep using it, and if not, don't try it anymore\n return class StaticResourcesMixinClass extends BaseClass {\n #lastBaseUrl?: string;\n #workingBaseUrl?: string;\n #failedUrls = new Set<string>();\n\n #getResourceUrls(filename: string): CustomUrl[] | CustomUrl {\n const overrideUrl = OVERRIDE_CONTENT_URL || this.baseStaticUrl;\n\n // Steps 1-2: Override URL or base-static-url takes precedence\n if (overrideUrl) {\n return this.#createResourceUrl(filename, overrideUrl);\n }\n\n // Reset state if base-url changed\n if (this.#lastBaseUrl !== this.baseUrl) {\n this.#lastBaseUrl = this.baseUrl;\n this.#workingBaseUrl = undefined;\n this.#failedUrls.clear();\n }\n\n // Build URL list based on cached state or fallback chain\n const urls: CustomUrl[] = [];\n\n if (this.#workingBaseUrl) {\n // Use cached working URL\n urls.push(this.#createResourceUrl(filename, this.#workingBaseUrl));\n // Add fallback only for BASE_CONTENT_URL (for resilience)\n if (this.#workingBaseUrl === BASE_CONTENT_URL) {\n urls.push(\n this.#createResourceUrl(filename, BASE_CONTENT_URL_FALLBACK),\n );\n }\n } else {\n // Build fallback chain: try URLs that haven't failed yet\n const baseUrlWithPages = this.baseUrl + '/pages';\n if (this.baseUrl && !this.#failedUrls.has(baseUrlWithPages)) {\n urls.push(this.#createResourceUrl(filename, baseUrlWithPages));\n }\n if (!this.#failedUrls.has(BASE_CONTENT_URL)) {\n urls.push(this.#createResourceUrl(filename, BASE_CONTENT_URL));\n }\n urls.push(\n this.#createResourceUrl(filename, BASE_CONTENT_URL_FALLBACK),\n );\n }\n\n return urls.length === 1 ? urls[0] : urls;\n }\n\n #createResourceUrl(filename: string, baseUrl: string): CustomUrl {\n return getResourceUrl({\n projectId: this.projectId,\n filename,\n baseUrl,\n });\n }\n\n async fetchStaticResource<F extends Format>(\n filename: string,\n format: F,\n ): Promise<{\n body: F extends 'json' ? Record<string, any> : string;\n headers: Record<string, string>;\n }> {\n const resourceUrls = this.#getResourceUrls(filename);\n\n // Cache the working URL and mark failed URLs\n const onSuccess = !Array.isArray(resourceUrls)\n ? null\n : (index: number) => {\n const { baseUrl } = resourceUrls[index];\n this.#workingBaseUrl = baseUrl;\n\n // Mark all URLs before this one as failed\n for (let i = 0; i < index; i++) {\n const failedUrl = resourceUrls[i].baseUrl;\n this.#failedUrls.add(failedUrl);\n }\n };\n\n try {\n const res = await fetchWithFallbacks(\n resourceUrls,\n { cache: 'default' },\n { logger: this.logger, onSuccess },\n );\n\n return {\n body: await res[format](),\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (e) {\n this.logger.error(e.message);\n }\n }\n\n get baseStaticUrl() {\n return this.getAttribute('base-static-url') || '';\n }\n };\n },\n);\n"],"names":["ASSETS_FOLDER","BASE_CONTENT_URL","pathJoin","createSingletonMixin","compose","loggerMixin","projectIdMixin","baseUrlMixin","__classPrivateFieldGet","__classPrivateFieldSet","fetchWithFallbacks","OVERRIDE_CONTENT_URL","BASE_CONTENT_URL_FALLBACK"],"mappings":"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"}
@@ -2,14 +2,20 @@ import { __classPrivateFieldGet, __classPrivateFieldSet } from 'tslib';
2
2
  import { createSingletonMixin } from '@descope/sdk-helpers';
3
3
 
4
4
  const logLevels = ['error', 'warn', 'info', 'debug'];
5
+ const defaultLogger = {
6
+ error: console.error.bind(console, '[Descope]'),
7
+ warn: console.warn.bind(console, '[Descope]'),
8
+ info: console.info.bind(console, '[Descope]'),
9
+ debug: console.debug.bind(console, '[Descope]'),
10
+ };
5
11
  const loggerMixin = createSingletonMixin((superclass) => { var _LoggerMixinClass_instances, _LoggerMixinClass_logger, _LoggerMixinClass_wrapLogger, _a; return _a = class LoggerMixinClass extends superclass {
6
12
  constructor() {
7
13
  super(...arguments);
8
14
  _LoggerMixinClass_instances.add(this);
9
- _LoggerMixinClass_logger.set(this, __classPrivateFieldGet(this, _LoggerMixinClass_instances, "m", _LoggerMixinClass_wrapLogger).call(this, console));
15
+ _LoggerMixinClass_logger.set(this, __classPrivateFieldGet(this, _LoggerMixinClass_instances, "m", _LoggerMixinClass_wrapLogger).call(this, defaultLogger));
10
16
  }
11
17
  set logger(logger) {
12
- __classPrivateFieldSet(this, _LoggerMixinClass_logger, __classPrivateFieldGet(this, _LoggerMixinClass_instances, "m", _LoggerMixinClass_wrapLogger).call(this, logger || console), "f");
18
+ __classPrivateFieldSet(this, _LoggerMixinClass_logger, __classPrivateFieldGet(this, _LoggerMixinClass_instances, "m", _LoggerMixinClass_wrapLogger).call(this, logger || defaultLogger), "f");
13
19
  }
14
20
  get logger() {
15
21
  return __classPrivateFieldGet(this, _LoggerMixinClass_logger, "f");
@@ -1 +1 @@
1
- {"version":3,"file":"loggerMixin.js","sources":["../../../../src/mixins/loggerMixin/loggerMixin.ts"],"sourcesContent":["import { createSingletonMixin } from '@descope/sdk-helpers';\nimport { Logger } from './types';\n\nconst logLevels = ['error', 'warn', 'info', 'debug'] as const;\n\nexport type LogLevel = (typeof logLevels)[number];\n\nexport const loggerMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) =>\n class LoggerMixinClass extends superclass {\n #logger: Logger = this.#wrapLogger(console);\n\n #wrapLogger(logger: Partial<Logger>) {\n return logLevels.reduce((acc, logLevel) => {\n acc[logLevel] = (...args: any[]) => {\n this.onLogEvent(logLevel, args);\n logger[logLevel]?.(...args);\n };\n\n return acc;\n }, {}) as Logger;\n }\n\n set logger(logger: Partial<Logger> | undefined) {\n this.#logger = this.#wrapLogger(logger || console);\n }\n\n get logger(): Logger {\n return this.#logger;\n }\n\n // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars\n onLogEvent(logLevel: LogLevel, data: any[]) {}\n },\n);\n"],"names":[],"mappings":";;;AAGA,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAIvD,MAAM,WAAW,GAAG,oBAAoB,CAC7C,CAAqC,UAAa,KAAI,EAAA,IAAA,2BAAA,EAAA,wBAAA,EAAA,4BAAA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,GACpD,MAAM,gBAAiB,SAAQ,UAAU,CAAA;AAAzC,QAAA,WAAA,GAAA;;;YACE,wBAAkB,CAAA,GAAA,CAAA,IAAA,EAAA,sBAAA,CAAA,IAAI,EAAY,2BAAA,EAAA,GAAA,EAAA,4BAAA,CAAA,CAAA,IAAA,CAAhB,IAAI,EAAa,OAAO,CAAC,CAAC,CAAA;SAuB7C;QAVC,IAAI,MAAM,CAAC,MAAmC,EAAA;AAC5C,YAAA,sBAAA,CAAA,IAAI,EAAA,wBAAA,EAAW,sBAAA,CAAA,IAAI,EAAY,2BAAA,EAAA,GAAA,EAAA,4BAAA,CAAA,CAAA,IAAA,CAAhB,IAAI,EAAa,MAAM,IAAI,OAAO,CAAC,MAAA,CAAC;SACpD;AAED,QAAA,IAAI,MAAM,GAAA;YACR,OAAO,sBAAA,CAAA,IAAI,EAAA,wBAAA,EAAA,GAAA,CAAQ,CAAC;SACrB;;AAGD,QAAA,UAAU,CAAC,QAAkB,EAAE,IAAW,KAAI;AAC/C,KAAA;;;yEArBa,MAAuB,EAAA;QACjC,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,QAAQ,KAAI;YACxC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAW,KAAI;;AACjC,gBAAA,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;gBAChC,CAAA,EAAA,GAAA,MAAM,CAAC,QAAQ,CAAC,uDAAG,GAAG,IAAI,CAAC,CAAC;AAC9B,aAAC,CAAC;AAEF,YAAA,OAAO,GAAG,CAAC;SACZ,EAAE,EAAE,CAAW,CAAC;KAClB;AAYF,IAAA,EAAA,CAAA,EAAA;;;;"}
1
+ {"version":3,"file":"loggerMixin.js","sources":["../../../../src/mixins/loggerMixin/loggerMixin.ts"],"sourcesContent":["/* eslint-disable import/exports-last, no-console */\nimport { createSingletonMixin } from '@descope/sdk-helpers';\nimport { Logger } from './types';\n\nconst logLevels = ['error', 'warn', 'info', 'debug'] as const;\n\nexport type LogLevel = (typeof logLevels)[number];\n\nconst defaultLogger: Logger = {\n error: console.error.bind(console, '[Descope]'),\n warn: console.warn.bind(console, '[Descope]'),\n info: console.info.bind(console, '[Descope]'),\n debug: console.debug.bind(console, '[Descope]'),\n};\n\nexport const loggerMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) =>\n class LoggerMixinClass extends superclass {\n #logger: Logger = this.#wrapLogger(defaultLogger);\n\n #wrapLogger(logger: Partial<Logger>) {\n return logLevels.reduce((acc, logLevel) => {\n acc[logLevel] = (...args: any[]) => {\n this.onLogEvent(logLevel, args);\n logger[logLevel]?.(...args);\n };\n\n return acc;\n }, {}) as Logger;\n }\n\n set logger(logger: Partial<Logger> | undefined) {\n this.#logger = this.#wrapLogger(logger || defaultLogger);\n }\n\n get logger(): Logger {\n return this.#logger;\n }\n\n // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars\n onLogEvent(logLevel: LogLevel, data: any[]) {}\n },\n);\n"],"names":[],"mappings":";;;AAIA,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAI9D,MAAM,aAAa,GAAW;IAC5B,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC;IAC/C,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC;IAC7C,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC;IAC7C,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC;CAChD,CAAC;AAEK,MAAM,WAAW,GAAG,oBAAoB,CAC7C,CAAqC,UAAa,KAAI,EAAA,IAAA,2BAAA,EAAA,wBAAA,EAAA,4BAAA,EAAA,EAAA,CAAA,CAAA,OAAA,EAAA,GACpD,MAAM,gBAAiB,SAAQ,UAAU,CAAA;AAAzC,QAAA,WAAA,GAAA;;;YACE,wBAAkB,CAAA,GAAA,CAAA,IAAA,EAAA,sBAAA,CAAA,IAAI,EAAY,2BAAA,EAAA,GAAA,EAAA,4BAAA,CAAA,CAAA,IAAA,CAAhB,IAAI,EAAa,aAAa,CAAC,CAAC,CAAA;SAuBnD;QAVC,IAAI,MAAM,CAAC,MAAmC,EAAA;AAC5C,YAAA,sBAAA,CAAA,IAAI,EAAA,wBAAA,EAAW,sBAAA,CAAA,IAAI,EAAY,2BAAA,EAAA,GAAA,EAAA,4BAAA,CAAA,CAAA,IAAA,CAAhB,IAAI,EAAa,MAAM,IAAI,aAAa,CAAC,MAAA,CAAC;SAC1D;AAED,QAAA,IAAI,MAAM,GAAA;YACR,OAAO,sBAAA,CAAA,IAAI,EAAA,wBAAA,EAAA,GAAA,CAAQ,CAAC;SACrB;;AAGD,QAAA,UAAU,CAAC,QAAkB,EAAE,IAAW,KAAI;AAC/C,KAAA;;;yEArBa,MAAuB,EAAA;QACjC,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,QAAQ,KAAI;YACxC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAW,KAAI;;AACjC,gBAAA,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;gBAChC,CAAA,EAAA,GAAA,MAAM,CAAC,QAAQ,CAAC,uDAAG,GAAG,IAAI,CAAC,CAAC;AAC9B,aAAC,CAAC;AAEF,YAAA,OAAO,GAAG,CAAC;SACZ,EAAE,EAAE,CAAW,CAAC;KAClB;AAYF,IAAA,EAAA,CAAA,EAAA;;;;"}
@@ -2,8 +2,9 @@ import { IS_LOCAL_STORAGE } from '../../constants.js';
2
2
 
3
3
  const BASE_CONTENT_URL_KEY = 'base.content.url';
4
4
  const BASE_CONTENT_URL = 'https://static.descope.com/pages';
5
+ const BASE_CONTENT_URL_FALLBACK = 'https://static2.descope.com/pages';
5
6
  const OVERRIDE_CONTENT_URL = (IS_LOCAL_STORAGE && localStorage.getItem(BASE_CONTENT_URL_KEY)) || '';
6
7
  const ASSETS_FOLDER = 'v2-beta';
7
8
 
8
- export { ASSETS_FOLDER, BASE_CONTENT_URL, OVERRIDE_CONTENT_URL };
9
+ export { ASSETS_FOLDER, BASE_CONTENT_URL, BASE_CONTENT_URL_FALLBACK, OVERRIDE_CONTENT_URL };
9
10
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sources":["../../../../src/mixins/staticResourcesMixin/constants.ts"],"sourcesContent":["import { IS_LOCAL_STORAGE } from '../../constants';\n\nconst BASE_CONTENT_URL_KEY = 'base.content.url';\n\nexport const BASE_CONTENT_URL = 'https://static.descope.com/pages';\n\nexport const OVERRIDE_CONTENT_URL =\n (IS_LOCAL_STORAGE && localStorage.getItem(BASE_CONTENT_URL_KEY)) || '';\n\nexport const ASSETS_FOLDER = 'v2-beta';\nexport const PREV_VER_ASSETS_FOLDER = 'v2-alpha';\n"],"names":[],"mappings":";;AAEA,MAAM,oBAAoB,GAAG,kBAAkB,CAAC;AAEzC,MAAM,gBAAgB,GAAG,mCAAmC;AAEtD,MAAA,oBAAoB,GAC/B,CAAC,gBAAgB,IAAI,YAAY,CAAC,OAAO,CAAC,oBAAoB,CAAC,KAAK,GAAG;AAElE,MAAM,aAAa,GAAG;;;;"}
1
+ {"version":3,"file":"constants.js","sources":["../../../../src/mixins/staticResourcesMixin/constants.ts"],"sourcesContent":["import { IS_LOCAL_STORAGE } from '../../constants';\n\nconst BASE_CONTENT_URL_KEY = 'base.content.url';\n\nexport const BASE_CONTENT_URL = 'https://static.descope.com/pages';\nexport const BASE_CONTENT_URL_FALLBACK = 'https://static2.descope.com/pages';\n\nexport const OVERRIDE_CONTENT_URL =\n (IS_LOCAL_STORAGE && localStorage.getItem(BASE_CONTENT_URL_KEY)) || '';\n\nexport const ASSETS_FOLDER = 'v2-beta';\nexport const PREV_VER_ASSETS_FOLDER = 'v2-alpha';\n"],"names":[],"mappings":";;AAEA,MAAM,oBAAoB,GAAG,kBAAkB,CAAC;AAEzC,MAAM,gBAAgB,GAAG,mCAAmC;AAC5D,MAAM,yBAAyB,GAAG,oCAAoC;AAEhE,MAAA,oBAAoB,GAC/B,CAAC,gBAAgB,IAAI,YAAY,CAAC,OAAO,CAAC,oBAAoB,CAAC,KAAK,GAAG;AAElE,MAAM,aAAa,GAAG;;;;"}
@@ -1,7 +1,7 @@
1
1
  import { __classPrivateFieldGet, __classPrivateFieldSet } from 'tslib';
2
2
  import { createSingletonMixin, compose, pathJoin } from '@descope/sdk-helpers';
3
3
  import { loggerMixin } from '../loggerMixin/loggerMixin.js';
4
- import { ASSETS_FOLDER, BASE_CONTENT_URL, OVERRIDE_CONTENT_URL } from './constants.js';
4
+ import { ASSETS_FOLDER, BASE_CONTENT_URL, OVERRIDE_CONTENT_URL, BASE_CONTENT_URL_FALLBACK } from './constants.js';
5
5
  import { projectIdMixin } from '../projectIdMixin.js';
6
6
  import { baseUrlMixin } from '../baseUrlMixin.js';
7
7
  import { fetchWithFallbacks } from './fetchWithFallbacks.js';
@@ -14,31 +14,35 @@ function getResourceUrl({ projectId, filename, assetsFolder = ASSETS_FOLDER, bas
14
14
  return url;
15
15
  }
16
16
  const staticResourcesMixin = createSingletonMixin((superclass) => {
17
- var _StaticResourcesMixinClass_instances, _StaticResourcesMixinClass_lastBaseUrl, _StaticResourcesMixinClass_workingBaseUrl, _StaticResourcesMixinClass_getResourceUrls, _a;
17
+ var _StaticResourcesMixinClass_instances, _StaticResourcesMixinClass_lastBaseUrl, _StaticResourcesMixinClass_workingBaseUrl, _StaticResourcesMixinClass_failedUrls, _StaticResourcesMixinClass_getResourceUrls, _StaticResourcesMixinClass_createResourceUrl, _a;
18
18
  const BaseClass = compose(loggerMixin, projectIdMixin, baseUrlMixin)(superclass);
19
19
  // the logic should be as following:
20
- // if there is a local storage override, use it
21
- // otherwise, if there is a base-static-url attribute, use it
22
- // otherwise, try to use base-url, and check if it's working
23
- // if it's working, use it
24
- // if not, use the default content url
20
+ // 1. if there is a local storage override, use it
21
+ // 2. otherwise, if there is a base-static-url attribute, use it
22
+ // 3. otherwise, try to use base-url
23
+ // 4. otherwise, try to use default content url (BASE_CONTENT_URL)
24
+ // 5. otherwise, try to use the fallback content url (BASE_CONTENT_URL_FALLBACK)
25
+ // For steps 3-5: if the url is valid, keep using it, and if not, don't try it anymore
25
26
  return _a = class StaticResourcesMixinClass extends BaseClass {
26
27
  constructor() {
27
28
  super(...arguments);
28
29
  _StaticResourcesMixinClass_instances.add(this);
29
30
  _StaticResourcesMixinClass_lastBaseUrl.set(this, void 0);
30
31
  _StaticResourcesMixinClass_workingBaseUrl.set(this, void 0);
32
+ _StaticResourcesMixinClass_failedUrls.set(this, new Set());
31
33
  }
32
34
  async fetchStaticResource(filename, format) {
33
35
  const resourceUrls = __classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_getResourceUrls).call(this, filename);
34
- // if there are multiple resource urls, it means that there are fallbacks,
35
- // if one of the options (which is not the last) is working, we want to keep using it by updating the workingBaseUrl
36
+ // Cache the working URL and mark failed URLs
36
37
  const onSuccess = !Array.isArray(resourceUrls)
37
38
  ? null
38
39
  : (index) => {
39
- if (index !== resourceUrls.length - 1) {
40
- const { baseUrl } = resourceUrls[index];
41
- __classPrivateFieldSet(this, _StaticResourcesMixinClass_workingBaseUrl, baseUrl, "f");
40
+ const { baseUrl } = resourceUrls[index];
41
+ __classPrivateFieldSet(this, _StaticResourcesMixinClass_workingBaseUrl, baseUrl, "f");
42
+ // Mark all URLs before this one as failed
43
+ for (let i = 0; i < index; i++) {
44
+ const failedUrl = resourceUrls[i].baseUrl;
45
+ __classPrivateFieldGet(this, _StaticResourcesMixinClass_failedUrls, "f").add(failedUrl);
42
46
  }
43
47
  };
44
48
  try {
@@ -58,38 +62,49 @@ const staticResourcesMixin = createSingletonMixin((superclass) => {
58
62
  },
59
63
  _StaticResourcesMixinClass_lastBaseUrl = new WeakMap(),
60
64
  _StaticResourcesMixinClass_workingBaseUrl = new WeakMap(),
65
+ _StaticResourcesMixinClass_failedUrls = new WeakMap(),
61
66
  _StaticResourcesMixinClass_instances = new WeakSet(),
62
67
  _StaticResourcesMixinClass_getResourceUrls = function _StaticResourcesMixinClass_getResourceUrls(filename) {
63
68
  const overrideUrl = OVERRIDE_CONTENT_URL || this.baseStaticUrl;
69
+ // Steps 1-2: Override URL or base-static-url takes precedence
64
70
  if (overrideUrl) {
65
- return getResourceUrl({
66
- projectId: this.projectId,
67
- filename,
68
- baseUrl: overrideUrl,
69
- });
71
+ return __classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_createResourceUrl).call(this, filename, overrideUrl);
70
72
  }
71
- const isBaseUrlUpdated = __classPrivateFieldGet(this, _StaticResourcesMixinClass_lastBaseUrl, "f") !== this.baseUrl;
72
- const shouldFallbackFetch = isBaseUrlUpdated && !!this.baseUrl;
73
- // if the base url has changed, reset the working base url
74
- if (isBaseUrlUpdated) {
73
+ // Reset state if base-url changed
74
+ if (__classPrivateFieldGet(this, _StaticResourcesMixinClass_lastBaseUrl, "f") !== this.baseUrl) {
75
75
  __classPrivateFieldSet(this, _StaticResourcesMixinClass_lastBaseUrl, this.baseUrl, "f");
76
76
  __classPrivateFieldSet(this, _StaticResourcesMixinClass_workingBaseUrl, undefined, "f");
77
+ __classPrivateFieldGet(this, _StaticResourcesMixinClass_failedUrls, "f").clear();
77
78
  }
78
- const resourceUrl = getResourceUrl({
79
- projectId: this.projectId,
80
- filename,
81
- baseUrl: __classPrivateFieldGet(this, _StaticResourcesMixinClass_workingBaseUrl, "f"),
82
- });
83
- // if there is no reason to check the baseUrl, generate the resource url according to the priority
84
- if (!shouldFallbackFetch) {
85
- return resourceUrl;
79
+ // Build URL list based on cached state or fallback chain
80
+ const urls = [];
81
+ if (__classPrivateFieldGet(this, _StaticResourcesMixinClass_workingBaseUrl, "f")) {
82
+ // Use cached working URL
83
+ urls.push(__classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_createResourceUrl).call(this, filename, __classPrivateFieldGet(this, _StaticResourcesMixinClass_workingBaseUrl, "f")));
84
+ // Add fallback only for BASE_CONTENT_URL (for resilience)
85
+ if (__classPrivateFieldGet(this, _StaticResourcesMixinClass_workingBaseUrl, "f") === BASE_CONTENT_URL) {
86
+ urls.push(__classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_createResourceUrl).call(this, filename, BASE_CONTENT_URL_FALLBACK));
87
+ }
86
88
  }
87
- const resourceUrlFromBaseUrl = getResourceUrl({
89
+ else {
90
+ // Build fallback chain: try URLs that haven't failed yet
91
+ const baseUrlWithPages = this.baseUrl + '/pages';
92
+ if (this.baseUrl && !__classPrivateFieldGet(this, _StaticResourcesMixinClass_failedUrls, "f").has(baseUrlWithPages)) {
93
+ urls.push(__classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_createResourceUrl).call(this, filename, baseUrlWithPages));
94
+ }
95
+ if (!__classPrivateFieldGet(this, _StaticResourcesMixinClass_failedUrls, "f").has(BASE_CONTENT_URL)) {
96
+ urls.push(__classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_createResourceUrl).call(this, filename, BASE_CONTENT_URL));
97
+ }
98
+ urls.push(__classPrivateFieldGet(this, _StaticResourcesMixinClass_instances, "m", _StaticResourcesMixinClass_createResourceUrl).call(this, filename, BASE_CONTENT_URL_FALLBACK));
99
+ }
100
+ return urls.length === 1 ? urls[0] : urls;
101
+ },
102
+ _StaticResourcesMixinClass_createResourceUrl = function _StaticResourcesMixinClass_createResourceUrl(filename, baseUrl) {
103
+ return getResourceUrl({
88
104
  projectId: this.projectId,
89
105
  filename,
90
- baseUrl: this.baseUrl + '/pages',
106
+ baseUrl,
91
107
  });
92
- return [resourceUrlFromBaseUrl, resourceUrl];
93
108
  },
94
109
  _a;
95
110
  });
@@ -1 +1 @@
1
- {"version":3,"file":"staticResourcesMixin.js","sources":["../../../../src/mixins/staticResourcesMixin/staticResourcesMixin.ts"],"sourcesContent":["import { pathJoin, compose, createSingletonMixin } from '@descope/sdk-helpers';\nimport { loggerMixin } from '../loggerMixin';\nimport {\n ASSETS_FOLDER,\n BASE_CONTENT_URL,\n OVERRIDE_CONTENT_URL,\n} from './constants';\nimport { projectIdMixin } from '../projectIdMixin';\nimport { baseUrlMixin } from '../baseUrlMixin';\nimport { fetchWithFallbacks } from './fetchWithFallbacks';\n\ntype Format = 'text' | 'json';\n\ntype CustomUrl = URL & { baseUrl: string };\n\nexport function getResourceUrl({\n projectId,\n filename,\n assetsFolder = ASSETS_FOLDER,\n baseUrl = BASE_CONTENT_URL,\n}: {\n projectId: string;\n filename: string;\n assetsFolder?: string;\n baseUrl?: string;\n}) {\n const url: CustomUrl = new URL(baseUrl) as any;\n url.pathname = pathJoin(url.pathname, projectId, assetsFolder, filename);\n // we want to keep the baseUrl so we can use it later\n url.baseUrl = baseUrl;\n\n return url;\n}\n\nexport const staticResourcesMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) => {\n const BaseClass = compose(\n loggerMixin,\n projectIdMixin,\n baseUrlMixin,\n )(superclass);\n\n // the logic should be as following:\n // if there is a local storage override, use it\n // otherwise, if there is a base-static-url attribute, use it\n // otherwise, try to use base-url, and check if it's working\n // if it's working, use it\n // if not, use the default content url\n return class StaticResourcesMixinClass extends BaseClass {\n #lastBaseUrl?: string;\n #workingBaseUrl?: string;\n\n #getResourceUrls(filename: string): CustomUrl[] | CustomUrl {\n const overrideUrl = OVERRIDE_CONTENT_URL || this.baseStaticUrl;\n\n if (overrideUrl) {\n return getResourceUrl({\n projectId: this.projectId,\n filename,\n baseUrl: overrideUrl,\n });\n }\n\n const isBaseUrlUpdated = this.#lastBaseUrl !== this.baseUrl;\n const shouldFallbackFetch = isBaseUrlUpdated && !!this.baseUrl;\n\n // if the base url has changed, reset the working base url\n if (isBaseUrlUpdated) {\n this.#lastBaseUrl = this.baseUrl;\n this.#workingBaseUrl = undefined;\n }\n\n const resourceUrl = getResourceUrl({\n projectId: this.projectId,\n filename,\n baseUrl: this.#workingBaseUrl,\n });\n\n // if there is no reason to check the baseUrl, generate the resource url according to the priority\n if (!shouldFallbackFetch) {\n return resourceUrl;\n }\n\n const resourceUrlFromBaseUrl = getResourceUrl({\n projectId: this.projectId,\n filename,\n baseUrl: this.baseUrl + '/pages',\n });\n\n return [resourceUrlFromBaseUrl, resourceUrl];\n }\n\n async fetchStaticResource<F extends Format>(\n filename: string,\n format: F,\n ): Promise<{\n body: F extends 'json' ? Record<string, any> : string;\n headers: Record<string, string>;\n }> {\n const resourceUrls = this.#getResourceUrls(filename);\n\n // if there are multiple resource urls, it means that there are fallbacks,\n // if one of the options (which is not the last) is working, we want to keep using it by updating the workingBaseUrl\n const onSuccess = !Array.isArray(resourceUrls)\n ? null\n : (index: number) => {\n if (index !== resourceUrls.length - 1) {\n const { baseUrl } = resourceUrls[index];\n this.#workingBaseUrl = baseUrl;\n }\n };\n\n try {\n const res = await fetchWithFallbacks(\n resourceUrls,\n { cache: 'default' },\n { logger: this.logger, onSuccess },\n );\n\n return {\n body: await res[format](),\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (e) {\n this.logger.error(e.message);\n }\n }\n\n get baseStaticUrl() {\n return this.getAttribute('base-static-url') || '';\n }\n };\n },\n);\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"staticResourcesMixin.js","sources":["../../../../src/mixins/staticResourcesMixin/staticResourcesMixin.ts"],"sourcesContent":["import { pathJoin, compose, createSingletonMixin } from '@descope/sdk-helpers';\nimport { loggerMixin } from '../loggerMixin';\nimport {\n ASSETS_FOLDER,\n BASE_CONTENT_URL,\n BASE_CONTENT_URL_FALLBACK,\n OVERRIDE_CONTENT_URL,\n} from './constants';\nimport { projectIdMixin } from '../projectIdMixin';\nimport { baseUrlMixin } from '../baseUrlMixin';\nimport { fetchWithFallbacks } from './fetchWithFallbacks';\n\ntype Format = 'text' | 'json';\n\ntype CustomUrl = URL & { baseUrl: string };\n\nexport function getResourceUrl({\n projectId,\n filename,\n assetsFolder = ASSETS_FOLDER,\n baseUrl = BASE_CONTENT_URL,\n}: {\n projectId: string;\n filename: string;\n assetsFolder?: string;\n baseUrl?: string;\n}) {\n const url: CustomUrl = new URL(baseUrl) as any;\n url.pathname = pathJoin(url.pathname, projectId, assetsFolder, filename);\n // we want to keep the baseUrl so we can use it later\n url.baseUrl = baseUrl;\n\n return url;\n}\n\nexport const staticResourcesMixin = createSingletonMixin(\n <T extends CustomElementConstructor>(superclass: T) => {\n const BaseClass = compose(\n loggerMixin,\n projectIdMixin,\n baseUrlMixin,\n )(superclass);\n\n // the logic should be as following:\n // 1. if there is a local storage override, use it\n // 2. otherwise, if there is a base-static-url attribute, use it\n // 3. otherwise, try to use base-url\n // 4. otherwise, try to use default content url (BASE_CONTENT_URL)\n // 5. otherwise, try to use the fallback content url (BASE_CONTENT_URL_FALLBACK)\n // For steps 3-5: if the url is valid, keep using it, and if not, don't try it anymore\n return class StaticResourcesMixinClass extends BaseClass {\n #lastBaseUrl?: string;\n #workingBaseUrl?: string;\n #failedUrls = new Set<string>();\n\n #getResourceUrls(filename: string): CustomUrl[] | CustomUrl {\n const overrideUrl = OVERRIDE_CONTENT_URL || this.baseStaticUrl;\n\n // Steps 1-2: Override URL or base-static-url takes precedence\n if (overrideUrl) {\n return this.#createResourceUrl(filename, overrideUrl);\n }\n\n // Reset state if base-url changed\n if (this.#lastBaseUrl !== this.baseUrl) {\n this.#lastBaseUrl = this.baseUrl;\n this.#workingBaseUrl = undefined;\n this.#failedUrls.clear();\n }\n\n // Build URL list based on cached state or fallback chain\n const urls: CustomUrl[] = [];\n\n if (this.#workingBaseUrl) {\n // Use cached working URL\n urls.push(this.#createResourceUrl(filename, this.#workingBaseUrl));\n // Add fallback only for BASE_CONTENT_URL (for resilience)\n if (this.#workingBaseUrl === BASE_CONTENT_URL) {\n urls.push(\n this.#createResourceUrl(filename, BASE_CONTENT_URL_FALLBACK),\n );\n }\n } else {\n // Build fallback chain: try URLs that haven't failed yet\n const baseUrlWithPages = this.baseUrl + '/pages';\n if (this.baseUrl && !this.#failedUrls.has(baseUrlWithPages)) {\n urls.push(this.#createResourceUrl(filename, baseUrlWithPages));\n }\n if (!this.#failedUrls.has(BASE_CONTENT_URL)) {\n urls.push(this.#createResourceUrl(filename, BASE_CONTENT_URL));\n }\n urls.push(\n this.#createResourceUrl(filename, BASE_CONTENT_URL_FALLBACK),\n );\n }\n\n return urls.length === 1 ? urls[0] : urls;\n }\n\n #createResourceUrl(filename: string, baseUrl: string): CustomUrl {\n return getResourceUrl({\n projectId: this.projectId,\n filename,\n baseUrl,\n });\n }\n\n async fetchStaticResource<F extends Format>(\n filename: string,\n format: F,\n ): Promise<{\n body: F extends 'json' ? Record<string, any> : string;\n headers: Record<string, string>;\n }> {\n const resourceUrls = this.#getResourceUrls(filename);\n\n // Cache the working URL and mark failed URLs\n const onSuccess = !Array.isArray(resourceUrls)\n ? null\n : (index: number) => {\n const { baseUrl } = resourceUrls[index];\n this.#workingBaseUrl = baseUrl;\n\n // Mark all URLs before this one as failed\n for (let i = 0; i < index; i++) {\n const failedUrl = resourceUrls[i].baseUrl;\n this.#failedUrls.add(failedUrl);\n }\n };\n\n try {\n const res = await fetchWithFallbacks(\n resourceUrls,\n { cache: 'default' },\n { logger: this.logger, onSuccess },\n );\n\n return {\n body: await res[format](),\n headers: Object.fromEntries(res.headers.entries()),\n };\n } catch (e) {\n this.logger.error(e.message);\n }\n }\n\n get baseStaticUrl() {\n return this.getAttribute('base-static-url') || '';\n }\n };\n },\n);\n"],"names":[],"mappings":"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"}