@esri/arcgis-rest-basemap-sessions 1.0.0 → 4.8.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.
@@ -1 +1 @@
1
- {"version":3,"file":"basemap-sessions.umd.js","sources":["../../node_modules/mitt/dist/mitt.mjs","../../src/utils/defaults.ts","../../src/utils/startNewSession.ts","../../src/utils/detemineSafetyMargin.ts","../../src/BaseSession.ts","../../src/BasemapStyleSession.ts"],"sourcesContent":["export default function(n){return{all:n=n||new Map,on:function(t,e){var i=n.get(t);i?i.push(e):n.set(t,[e])},off:function(t,e){var i=n.get(t);i&&(e?i.splice(i.indexOf(e)>>>0,1):n.set(t,[]))},emit:function(t,e){var i=n.get(t);i&&i.slice().map(function(n){n(e)}),(i=n.get(\"*\"))&&i.slice().map(function(n){n(t,e)})}}}\n//# sourceMappingURL=mitt.mjs.map\n","export const DEFAULT_START_BASEMAP_STYLE_SESSION_URL =\n \"https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/sessions/start\";\n\nexport const DEFAULT_SAFETY_MARGIN = 5 * 60; // Default to 5 minutes in seconds\n\nexport const DEFAULT_CHECK_EXPIRATION_INTERVAL = 10; // Default to 10 seconds\n\nexport const DEFAULT_DURATION = 12 * 60 * 60; // Default to 12 hours in seconds\n","import { IAuthenticationManager, request } from \"@esri/arcgis-rest-request\";\nimport { StyleFamily } from \"../types/StyleFamily.js\";\nimport { DEFAULT_DURATION } from \"./defaults.js\";\n\nexport interface IRequestNewSessionParams {\n startSessionUrl: string;\n authentication: IAuthenticationManager | string;\n styleFamily?: StyleFamily;\n duration?: number;\n}\n\nexport interface IStartSessionResponse {\n sessionToken: string;\n endTime: number;\n startTime: number;\n styleFamily: StyleFamily;\n}\n\nexport function startNewSession({\n startSessionUrl,\n authentication,\n styleFamily = \"arcgis\",\n duration = DEFAULT_DURATION\n}: IRequestNewSessionParams): Promise<IStartSessionResponse> {\n return request(startSessionUrl, {\n httpMethod: \"GET\",\n authentication: authentication,\n params: { styleFamily, durationSeconds: duration }\n });\n}\n","import { DEFAULT_SAFETY_MARGIN } from \"./defaults.js\";\n\nexport function determineSafetyMargin(\n duration: number | undefined,\n safetyMargin: number | undefined\n): number {\n if (safetyMargin) {\n return safetyMargin;\n }\n // common cases are\n // duration is 60 seconds, this will return a 1 second safety margin\n // duration is 43200 seconds, this will return a 300 second (5 minutes) safety margin\n return Math.min(Math.max(duration / 100, 1), DEFAULT_SAFETY_MARGIN);\n}\n","import mitt from \"mitt\";\n\nimport { IAuthenticationManager } from \"@esri/arcgis-rest-request\";\nimport { StyleFamily } from \"./types/StyleFamily.js\";\nimport { startNewSession } from \"./utils/startNewSession.js\";\nimport { Writable } from \"./utils/writable.js\";\nimport { determineSafetyMargin } from \"./utils/detemineSafetyMargin.js\";\nimport {\n DEFAULT_DURATION,\n DEFAULT_SAFETY_MARGIN,\n DEFAULT_CHECK_EXPIRATION_INTERVAL\n} from \"./utils/defaults.js\";\n\nexport interface IBasemapSessionParams {\n token: string;\n startSessionUrl: string;\n styleFamily: StyleFamily;\n authentication: IAuthenticationManager | string;\n expires: Date;\n startTime: Date;\n endTime: Date;\n safetyMargin?: number;\n duration?: number;\n autoRefresh?: boolean;\n}\n\nexport interface IStartSessionParams {\n styleFamily?: StyleFamily;\n authentication: IAuthenticationManager | string;\n safetyMargin?: number;\n duration?: number;\n autoRefresh?: boolean;\n\n /**\n * The URL to start the session. If not provided, it will use the default URL.\n * @private\n */\n startSessionUrl?: string;\n}\n\n/**\n * The base class for all basemap sessions. This class implements the {@linkcode IAuthenticationManager} interface and provides methods to start, refresh, and check the expiration of a session.\n * This is not intendet to be used directly, but instead is extended by other classes such as {@linkcode BasemapStyleSession} and {@linkcode StaticBasemapTilesSession}.\n *\n * @abstract\n * @implements {IAuthenticationManager}\n */\nexport abstract class BaseSession implements IAuthenticationManager {\n // the static methods for event handlers are used to provide doc via typedoc and do not need to be tested.\n /* istanbul ignore next -- @preserve */\n /**\n * Event handler for when an error occurs during session management.\n */\n static readonly error = function error(e: Error): void {}; // eslint-disable-line @typescript-eslint/no-empty-function\n\n // the static methods for event handlers are used to provide doc via typedoc and do not need to be tested.\n /* istanbul ignore next -- @preserve */\n /**\n * Event handler for when a session expires and the `token` it no longer valid.\n *\n * @event expired\n * @param e - The parameters for the expired event.\n * @param e.token - The session token that expired.\n * @param e.startTime - The start time of the session.\n * @param e.endTime - The end time of the session.\n * @param e.expires - The expiration time of the session.\n */\n static readonly expired = function expired(e: {\n token: string;\n startTime: Date;\n endTime: Date;\n expires: Date;\n }): void {}; // eslint-disable-line @typescript-eslint/no-empty-function\n\n // the static methods for event handlers are used to provide doc via typedoc and do not need to be tested.\n /* istanbul ignore next -- @preserve */\n /**\n * Event handler for when a session refreshes and a new `token` is available.\n *\n * @event refreshed\n * @param e. - The parameters for the refreshed event.\n * @param e.previous - The previous session details.\n * @param e.previous.token - The previous session token.\n * @param e.previous.startTime - The start time of the previous session.\n * @param e.previous.endTime - The end time of the previous session.\n * @param e.previous.expires - The expiration time of the previous session.\n * @param e.current - The current session details.\n * @param e.current.token - The current session token.\n * @param e.current.startTime - The start time of the current token.\n * @param e.current.endTime - The end time of the current session.\n * @param e.current.expires - The expiration time of the current token.\n */\n static readonly refreshed = function refreshed(e: {\n previous: {\n token: string;\n startTime: Date;\n endTime: Date;\n expires: Date;\n };\n current: {\n token: string;\n startTime: Date;\n endTime: Date;\n expires: Date;\n };\n }): void {}; // eslint-disable-line @typescript-eslint/no-empty-function\n\n /**\n * The portal URL that the session is associated with. This generally is not used but exists to implement the `IAuthenticationManager` interface.\n */\n readonly portal: string;\n\n /**\n * The style family of the session. This is used to determine the type of basemap styles that are available.\n */\n readonly styleFamily: StyleFamily;\n\n /**\n * The authentication manager or token used for the session.\n * This can be an instance of {@linkcode ApiKeyManager}, {@linkcode ArcGISIdentityManager}, {@linkcode ApplicationCredentialsManager} or a string token.\n */\n readonly authentication: IAuthenticationManager | string;\n\n /**\n * The expiration date of the session. This is the {@linkcode BaseSession.endTime} minus the {@linkcode BaseSession.safetyMargin}. This is used internally to determine if the session is expired.\n */\n readonly expires: Date;\n\n /**\n * The start time of the session. This is the time returned from the API when the session war started.\n */\n readonly startTime: Date;\n\n /**\n * The end time of the session. This is the time returned from the API when the session will end.\n */\n readonly endTime: Date;\n\n /**\n * The token for the session.\n */\n readonly token: string;\n\n /**\n * The URL used to start the session.\n */\n readonly startSessionUrl: string;\n\n /**\n * The safety margin in milliseconds. This subtracted from the {@linkcode BaseSession.endTime} to get the {@linkcode BaseSession.expiration}.\n */\n readonly safetyMargin: number;\n\n /**\n * The duration of the session in seconds. This is used to determine how long the session will last when the session is refreshed.\n */\n readonly duration: number;\n\n /**\n * The interval at which to check the expiration time of the session. This is always 10 seconds or 1/100th of the duration, whichever is smaller.\n */\n readonly expirationCheckInterval: number;\n\n /**\n * The ID of the timer used to check the expiration time of the session.\n */\n private expirationTimerId: any = null;\n\n /**\n * Internal instance of [`mitt`](https://github.com/developit/mitt) used for event handlers. It is recommended to use {@linkcode BasemapSession.on}, {@linkcode BasemapSession.off} or {@linkcode BasemapSession.once} instead of `emitter.`\n */\n private emitter: any;\n\n /**\n * A handler that is used to automatically refresh the session when it expires.\n */\n private autoRefreshHandler: (() => void) | null = null;\n\n /**\n * Creates a new instance of the BaseSession class. Generally you should not create an instance of this class directly, but instead use the static methods to start a session or deserialize a session.\n *\n * You may need to create an instance of this class directly if you are not using the built in deserialize method.\n *\n * @param params - The parameters for the session.\n * @param params.startSessionUrl - The URL to start the session.\n * @param params.token - The token for the session.\n * @param params.styleFamily - The style family of the session.\n * @param params.authentication - The authentication manager or token used for the session.\n * @param params.expires - The expiration date of the session.\n * @param params.startTime - The start time of the session.\n * @param params.endTime - The end time of the session.\n * @param params.safetyMargin - The safety margin in milliseconds.\n * @param params.duration - Indicates if this is a test session.\n */\n constructor(params: IBasemapSessionParams) {\n this.startSessionUrl = params.startSessionUrl;\n this.token = params.token;\n this.styleFamily = params.styleFamily || \"arcgis\";\n this.authentication = params.authentication;\n this.duration = params.duration || DEFAULT_DURATION;\n this.startTime = params.startTime;\n this.endTime = params.endTime;\n this.expires = params.expires;\n this.safetyMargin = params.safetyMargin;\n this.expirationCheckInterval =\n Math.min(this.duration / 100, DEFAULT_CHECK_EXPIRATION_INTERVAL) * 1000;\n this.emitter = mitt();\n }\n\n /**\n * Checks if the session is expired. If it is expired, it emits an \"expired\" event. The event will fire **before** the method returns true.\n *\n * @returns {boolean} - Returns true if the session is expired, otherwise false.\n */\n isSessionExpired() {\n if (this.isExpired) {\n this.emitter.emit(\"expired\", {\n token: this.token,\n startTime: this.startTime,\n endTime: this.endTime,\n expires: this.expires\n });\n }\n return this.isExpired;\n }\n\n /**\n * Starts checking the expiration time of the session. This will check the expiration time immediately and then on an interval.\n * If the session is expired, it will emit an \"expired\" event.\n */\n startCheckingExpirationTime() {\n const check = () => {\n this.isSessionExpired();\n };\n\n if (!this.expirationTimerId) {\n this.expirationTimerId = setInterval(\n check,\n // check every 10 seconds or 1/100th of the duration, whichever is smaller\n this.expirationCheckInterval\n ); // check immediatly then on an interval\n }\n\n setTimeout(() => {\n check(); // check immediately after starting the interval\n }, 10);\n\n return this.expirationTimerId; // return the timer ID so it can be stopped later\n }\n\n /**\n * Stops checking the expiration time of the session. This will clear the interval that was set by {@linkcode BaseSession.startCheckingExpirationTime}.\n */\n stopCheckingExpirationTime() {\n if (this.expirationTimerId) {\n clearInterval(this.expirationTimerId);\n this.expirationTimerId = null;\n }\n }\n\n /**\n * Indicates if the session is currently checking for expiration time.\n *\n * @returns {boolean} - Returns true if the session is checking for expiration time, otherwise false.\n */\n get checkingExpirationTime(): boolean {\n return !!this.expirationTimerId;\n }\n\n /**\n * Starts a new session using the provided parameters and returns an instance of the session class.\n *\n * @param params - The parameters for starting the session.\n * @param SessionClass - The class to use for the session.\n * @returns A promise that resolves to an instance of the session class.\n */\n protected static async startSession<T extends BaseSession>(\n {\n startSessionUrl,\n styleFamily = \"arcgis\",\n authentication,\n safetyMargin,\n duration = DEFAULT_DURATION,\n autoRefresh = true\n }: {\n startSessionUrl?: string;\n styleFamily?: StyleFamily;\n authentication: IAuthenticationManager | string;\n safetyMargin?: number;\n duration?: number;\n autoRefresh?: boolean;\n },\n SessionClass: new (params: IBasemapSessionParams) => T\n ): Promise<T> {\n const sessionResponse = await startNewSession({\n startSessionUrl,\n styleFamily,\n authentication,\n duration\n });\n const actualSafetyMargin = determineSafetyMargin(duration, safetyMargin);\n\n const session = new SessionClass({\n startSessionUrl: startSessionUrl,\n token: sessionResponse.sessionToken,\n styleFamily,\n authentication,\n safetyMargin: actualSafetyMargin,\n expires: new Date(sessionResponse.endTime - actualSafetyMargin * 1000),\n startTime: new Date(sessionResponse.startTime),\n endTime: new Date(sessionResponse.endTime),\n duration\n });\n\n session.startCheckingExpirationTime();\n\n if (autoRefresh) {\n session.startAutoRefresh();\n }\n\n return session as T;\n }\n\n /**\n * Checks if the session is expired.\n *\n */\n get isExpired(): boolean {\n return this.expires < new Date();\n }\n\n /**\n * Gets the session token. If the session is expired, it will refresh the credentials and return the new token.\n *\n * @returns A promise that resolves to the session token.\n */\n getToken(): Promise<string> {\n if (this.isExpired) {\n return this.refreshCredentials().then(() => this.token);\n }\n\n return Promise.resolve(this.token);\n }\n\n /**\n * Indicates if the session can be refreshed. This is always true for this class.\n *\n * @returns {boolean} - Always returns true.\n */\n get canRefresh(): boolean {\n return true;\n }\n\n /**\n * Indicates if the session is set to automatically refresh when it expires.\n *\n * @returns {boolean} - Returns true if auto-refresh is enabled, otherwise false.\n */\n get autoRefresh(): boolean {\n return !!this.autoRefreshHandler && !!this.expirationTimerId;\n }\n\n /**\n * Refreshes the session credentials by starting a new session.\n * This will emit a \"refreshed\" event with the previous and current session details.\n *\n * @returns A promise that resolves to the current instance of the session.\n */\n async refreshCredentials(): Promise<this> {\n // @TODO switch this to structured clone when we upgrade to Node 20+ types so we don't have to parse the dates later\n const previous = JSON.parse(\n JSON.stringify({\n token: this.token,\n startTime: this.startTime,\n endTime: this.endTime,\n expires: this.expires\n })\n );\n\n try {\n const newSession = await startNewSession({\n startSessionUrl: this.startSessionUrl,\n styleFamily: this.styleFamily,\n authentication: this.authentication,\n duration: this.duration\n });\n\n this.setToken(newSession.sessionToken);\n this.setStartTime(new Date(newSession.startTime));\n this.setEndTime(new Date(newSession.endTime));\n this.setExpires(new Date(newSession.endTime - this.safetyMargin * 1000));\n\n this.emitter.emit(\"refreshed\", {\n previous: {\n token: previous.token,\n startTime: new Date(previous.startTime),\n endTime: new Date(previous.endTime),\n expires: new Date(previous.expires)\n },\n current: {\n token: this.token,\n startTime: this.startTime,\n endTime: this.endTime,\n expires: this.expires\n }\n });\n } catch (error) {\n this.emitter.emit(\"error\", error);\n throw error;\n }\n\n return this;\n }\n /**\n * Enables auto-refresh for the session. This will automatically refresh the session when it expires.\n * It will also start checking the expiration time of the session if it is not already started via {@linkcode BaseSession.startCheckingExpirationTime}.\n */\n startAutoRefresh() {\n if (!this.expirationTimerId) {\n this.startCheckingExpirationTime();\n }\n\n this.autoRefreshHandler = () => {\n this.refreshCredentials().catch((error: Error) => {\n this.emitter.emit(\"error\", error);\n });\n };\n\n this.on(\"expired\", this.autoRefreshHandler);\n }\n\n /**\n * Disables auto-refresh for the session. This will stop automatically refreshing the session when it expires.\n * This will **not** stop checking the expiration time of the session. If you want to stop automated expiration\n * checking, call {@linkcode BaseSession.stopCheckingExpirationTime} after calling this method.\n */\n stopAutoRefresh() {\n if (this.autoRefreshHandler) {\n this.off(\"expired\", this.autoRefreshHandler);\n this.autoRefreshHandler = null;\n }\n }\n\n /**\n * A handler that listens for an eventName and returns custom handler.\n *\n * @param eventName A string of what event to listen for.\n * @param handler A function of what to do when eventName was called.\n */\n on(event: \"refreshed\", handler: typeof BaseSession.refreshed): void;\n on(event: \"expired\", handler: typeof BaseSession.expired): void;\n on(event: \"error\", handler: typeof BaseSession.error): void;\n on(\n eventName: string,\n handler:\n | typeof BaseSession.refreshed\n | typeof BaseSession.expired\n | typeof BaseSession.error\n ) {\n this.emitter.on(eventName, handler);\n this.isSessionExpired(); // check if the session is expired immediately after adding the handler\n }\n\n /**\n * A handler that listens for an event once and returns a custom handler. Events listened to with this method cannot be removed with {@linkcode BasemapSession.off}.\n *\n * @param eventName A string of what event to listen for.\n * @param handler A function of what to do when eventName was called.\n */\n once(event: \"refreshed\", handler: typeof BaseSession.refreshed): void;\n once(event: \"expired\", handler: typeof BaseSession.expired): void;\n once(event: \"error\", handler: typeof BaseSession.error): void;\n once(\n eventName: string,\n handler:\n | typeof BaseSession.refreshed\n | typeof BaseSession.expired\n | typeof BaseSession.error\n ) {\n const fn = (e: any) => {\n this.emitter.off(eventName, fn);\n handler(e);\n };\n\n this.emitter.on(eventName, fn);\n }\n\n /**\n * A handler that will remove a listener from a given event.\n *\n * @param eventName A string of what event to listen for.\n * @param handler A function of what to do when eventName was called.\n */\n off(event: \"refreshed\", handler: typeof BaseSession.refreshed): void;\n off(event: \"expired\", handler: typeof BaseSession.expired): void;\n off(event: \"error\", handler: typeof BaseSession.error): void;\n off(\n eventName: string,\n handler:\n | typeof BaseSession.refreshed\n | typeof BaseSession.expired\n | typeof BaseSession.error\n ) {\n this.emitter.off(eventName, handler);\n }\n\n /**\n * These private methods are used to set the internal state of the session.\n */\n private setToken(token: string) {\n (this as Writable<typeof this>).token = token;\n }\n private setStartTime(startTime: Date) {\n (this as Writable<typeof this>).startTime = startTime;\n }\n private setEndTime(endTime: Date) {\n (this as Writable<typeof this>).endTime = endTime;\n }\n private setExpires(expires: Date) {\n (this as Writable<typeof this>).expires = expires;\n }\n}\n","import {\n BaseSession,\n IBasemapSessionParams,\n IStartSessionParams\n} from \"./BaseSession.js\";\nimport { DEFAULT_START_BASEMAP_STYLE_SESSION_URL } from \"./utils/defaults.js\";\n\n/**\n * `BasemapStyleSession` is a class that extends {@linkcode BaseSession} to manage sessions\n * for basemap styles. It provides methods to {@linkcode BasemapStyleSession.start} a new session\n * which should be used instead of constructing a new instance directly.\n *\n * @class BasemapStyleSession\n * @extends BaseSession\n */\nexport class BasemapStyleSession extends BaseSession {\n /**\n * Creates an instance of `BasemapStyleSession`. Constructing `BasemapStyleSession` directly is discouraged.\n * Instead, use the static method {@linkcode BasemapStyleSession.start} to start a new session.\n */\n constructor(params: IBasemapSessionParams) {\n super(params);\n }\n\n /**\n * Starts a new basemap style session.\n */\n static async start(params: IStartSessionParams) {\n return BaseSession.startSession<BasemapStyleSession>(\n {\n ...params,\n startSessionUrl:\n params?.startSessionUrl || DEFAULT_START_BASEMAP_STYLE_SESSION_URL\n },\n BasemapStyleSession as new (\n params: IBasemapSessionParams\n ) => BasemapStyleSession\n );\n }\n}\n"],"names":["request"],"mappings":"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"}
1
+ {"version":3,"file":"basemap-sessions.umd.js","sources":["../../node_modules/mitt/dist/mitt.mjs","../../src/utils/defaults.ts","../../src/utils/startNewSession.ts","../../src/utils/detemineSafetyMargin.ts","../../src/BaseSession.ts","../../src/BasemapStyleSession.ts"],"sourcesContent":["export default function(n){return{all:n=n||new Map,on:function(t,e){var i=n.get(t);i?i.push(e):n.set(t,[e])},off:function(t,e){var i=n.get(t);i&&(e?i.splice(i.indexOf(e)>>>0,1):n.set(t,[]))},emit:function(t,e){var i=n.get(t);i&&i.slice().map(function(n){n(e)}),(i=n.get(\"*\"))&&i.slice().map(function(n){n(t,e)})}}}\n//# sourceMappingURL=mitt.mjs.map\n","export const DEFAULT_START_BASEMAP_STYLE_SESSION_URL =\n \"https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/sessions/start\";\n\nexport const DEFAULT_SAFETY_MARGIN = 5 * 60; // Default to 5 minutes in seconds\n\nexport const DEFAULT_CHECK_EXPIRATION_INTERVAL = 10; // Default to 10 seconds\n\nexport const DEFAULT_DURATION = 12 * 60 * 60; // Default to 12 hours in seconds\n","import { IAuthenticationManager, request } from \"@esri/arcgis-rest-request\";\nimport { StyleFamily } from \"../types/StyleFamily.js\";\nimport { DEFAULT_DURATION } from \"./defaults.js\";\n\nexport interface IRequestNewSessionParams {\n startSessionUrl: string;\n authentication: IAuthenticationManager | string;\n styleFamily?: StyleFamily;\n duration?: number;\n}\n\nexport interface IStartSessionResponse {\n sessionToken: string;\n endTime: number;\n startTime: number;\n styleFamily: StyleFamily;\n}\n\nexport function startNewSession({\n startSessionUrl,\n authentication,\n styleFamily = \"arcgis\",\n duration = DEFAULT_DURATION\n}: IRequestNewSessionParams): Promise<IStartSessionResponse> {\n return request(startSessionUrl, {\n httpMethod: \"GET\",\n authentication: authentication,\n params: { styleFamily, durationSeconds: duration }\n });\n}\n","import { DEFAULT_SAFETY_MARGIN } from \"./defaults.js\";\n\nexport function determineSafetyMargin(\n duration: number | undefined,\n safetyMargin: number | undefined\n): number {\n if (safetyMargin) {\n return safetyMargin;\n }\n\n // common cases are\n // duration is 60 seconds, this will return a 1 second safety margin\n // duration is 43200 seconds, this will return a 300 second (5 minutes) safety margin\n return Math.min(Math.max(duration / 100, 1), DEFAULT_SAFETY_MARGIN);\n}\n","import mitt from \"mitt\";\n\nimport { IAuthenticationManager } from \"@esri/arcgis-rest-request\";\nimport { StyleFamily } from \"./types/StyleFamily.js\";\nimport {\n IStartSessionResponse,\n startNewSession\n} from \"./utils/startNewSession.js\";\nimport { Writable } from \"./utils/writable.js\";\nimport { determineSafetyMargin } from \"./utils/detemineSafetyMargin.js\";\nimport {\n DEFAULT_DURATION,\n DEFAULT_CHECK_EXPIRATION_INTERVAL\n} from \"./utils/defaults.js\";\n\nexport interface IBasemapSessionParams {\n token: string;\n startSessionUrl: string;\n styleFamily: StyleFamily;\n authentication: IAuthenticationManager | string;\n expires: Date;\n startTime: Date;\n endTime: Date;\n safetyMargin?: number;\n duration?: number;\n autoRefresh?: boolean;\n}\n\nexport interface IStartSessionParams {\n styleFamily?: StyleFamily;\n authentication: IAuthenticationManager | string;\n safetyMargin?: number;\n duration?: number;\n autoRefresh?: boolean;\n\n /**\n * The URL to start the session. If not provided, it will use the default URL.\n * @private\n */\n startSessionUrl?: string;\n}\n\n/**\n * The base class for all basemap sessions. This class implements the {@linkcode @esri/arcgis-rest-request!IAuthenticationManager} interface and provides methods to start, refresh, and check the expiration of a session.\n * This is not intended to be used directly, but instead is extended by other classes such as {@linkcode BasemapStyleSession} .\n *\n * @abstract\n */\nexport abstract class BaseSession implements IAuthenticationManager {\n // the static methods for event handlers are used to provide doc via typedoc and do not need to be tested.\n /* istanbul ignore next -- @preserve */\n /**\n * Event handler for when an error occurs during session management.\n */\n static readonly error = function error(e: Error): void {};\n\n // the static methods for event handlers are used to provide doc via typedoc and do not need to be tested.\n /* istanbul ignore next -- @preserve */\n /**\n * Event handler for when the current session expires and the session token it no longer valid. This event will only fire if {@linkcode BaseSession.checkingExpirationTime}\n * is `true` which is the default. Once this event fires, {@linkcode BaseSession.checkingExpirationTime} will be set to `false` until the session is refreshed with\n * {@linkcode BaseSession.refreshCredentials}.\n *\n * @event expired\n * @param e.token - The session token that expired.\n * @param e.startTime - The start time of the session.\n * @param e.endTime - The end time of the session.\n * @param e.expires - The expiration time of the session.\n */\n static readonly expired = function expired(e: {\n token: string;\n startTime: Date;\n endTime: Date;\n expires: Date;\n }): void {};\n\n // the static methods for event handlers are used to provide doc via typedoc and do not need to be tested.\n /* istanbul ignore next -- @preserve */\n /**\n * Event handler for when a session refreshes and a new `token` is available.\n *\n * @event refreshed\n * @param e.previous - The previous session details.\n * @param e.previous.token - The previous session token.\n * @param e.previous.startTime - The start time of the previous session.\n * @param e.previous.endTime - The end time of the previous session.\n * @param e.previous.expires - The expiration time of the previous session.\n * @param e.current - The current session details.\n * @param e.current.token - The current session token.\n * @param e.current.startTime - The start time of the current token.\n * @param e.current.endTime - The end time of the current session.\n * @param e.current.expires - The expiration time of the current token.\n */\n static readonly refreshed = function refreshed(e: {\n previous: {\n token: string;\n startTime: Date;\n endTime: Date;\n expires: Date;\n };\n current: {\n token: string;\n startTime: Date;\n endTime: Date;\n expires: Date;\n };\n }): void {};\n\n /**\n * The portal URL that the session is associated with. This generally is not used but exists to implement the `IAuthenticationManager` interface.\n */\n readonly portal: string;\n\n /**\n * The style family of the session. This is used to determine the type of basemap styles that are available.\n */\n readonly styleFamily: StyleFamily;\n\n /**\n * The authentication manager or token used for the session.\n * This can be an instance of {@linkcode @esri/arcgis-rest-request!ApiKeyManager}, {@linkcode @esri/arcgis-rest-request!ArcGISIdentityManager}, {@linkcode @esri/arcgis-rest-request!ApplicationCredentialsManager} or a string token.\n */\n readonly authentication: IAuthenticationManager | string;\n\n /**\n * The expiration date of the session. This is the {@linkcode BaseSession.endTime} minus the {@linkcode BaseSession.safetyMargin}. This is used internally to determine if the session is expired.\n */\n readonly expires: Date;\n\n /**\n * The start time of the session. This is the time returned from the API when the session war started.\n */\n readonly startTime: Date;\n\n /**\n * The end time of the session. This is the time returned from the API when the session will end.\n */\n readonly endTime: Date;\n\n /**\n * The token for the session.\n */\n readonly token: string;\n\n /**\n * The URL used to start the session.\n */\n readonly startSessionUrl: string;\n\n /**\n * The safety margin in milliseconds. This subtracted from the {@linkcode BaseSession.endTime} to get the expiration time of the session.\n */\n readonly safetyMargin: number;\n\n /**\n * The duration of the session in seconds. This is used to determine how long the session will last when the session is refreshed.\n */\n readonly duration: number;\n\n /**\n * The interval at which to check the expiration time of the session. This is always 10 seconds or 1/100th of the duration, whichever is smaller.\n */\n private readonly expirationCheckInterval: number;\n\n /**\n * The ID of the timer used to check the expiration time of the session.\n */\n private expirationTimerId: any = null;\n\n /**\n * A pending session that is being refreshed. This is used to prevent multiple refreshes from happening at the same time.\n */\n private pendingSession: Promise<IStartSessionResponse> | null = null;\n\n /**\n * Internal instance of [`mitt`](https://github.com/developit/mitt) used for event handlers. It is recommended to use {@linkcode BasemapSession.on}, {@linkcode BasemapSession.off} or {@linkcode BasemapSession.once} instead of `emitter.`\n */\n private emitter: any;\n\n /**\n * A handler that is used to automatically refresh the session when it expires.\n */\n private autoRefreshHandler: (() => void) | null = null;\n\n /**\n * Creates a new instance of the BaseSession class. Generally you should not create an instance of this class directly, but instead use the static methods to start a session or deserialize a session.\n *\n * You may need to create an instance of this class directly if you are not using the built in deserialize method.\n *\n * @param params - The parameters for the session.\n * @param params.startSessionUrl - The URL to start the session.\n * @param params.token - The token for the session.\n * @param params.styleFamily - The style family of the session.\n * @param params.authentication - The authentication manager or token used for the session.\n * @param params.expires - The expiration date of the session.\n * @param params.startTime - The start time of the session.\n * @param params.endTime - The end time of the session.\n * @param params.safetyMargin - The safety margin in milliseconds.\n * @param params.duration - Indicates if this is a test session.\n */\n constructor(params: IBasemapSessionParams) {\n this.startSessionUrl = params.startSessionUrl;\n this.token = params.token;\n this.styleFamily = params.styleFamily || \"arcgis\";\n this.authentication = params.authentication;\n this.duration = params.duration || DEFAULT_DURATION;\n this.startTime = params.startTime;\n this.endTime = params.endTime;\n this.expires = params.expires;\n this.safetyMargin = params.safetyMargin;\n this.expirationCheckInterval =\n Math.min(this.duration / 100, DEFAULT_CHECK_EXPIRATION_INTERVAL) * 1000;\n this.emitter = mitt();\n }\n\n /**\n * Checks if the session is expired. If it is expired, it emits an \"expired\" event and disables expiration time checking. The event will fire **before** the method returns true.\n *\n * @returns {boolean} - Returns true if the session is expired, otherwise false.\n */\n isSessionExpired() {\n if (this.isExpired) {\n this.disableCheckingExpirationTime();\n\n this.emitter.emit(\"expired\", {\n token: this.token,\n startTime: this.startTime,\n endTime: this.endTime,\n expires: this.expires\n });\n }\n\n return this.isExpired;\n }\n\n /**\n * Starts checking the expiration time of the session. This will check the expiration time immediately and then on an interval.\n * If the session is expired, it will emit an \"expired\" event.\n */\n enableCheckingExpirationTime() {\n const check = () => {\n this.isSessionExpired();\n };\n\n if (!this.expirationTimerId) {\n this.expirationTimerId = setInterval(\n check,\n // check every 10 seconds or 1/100th of the duration, whichever is smaller\n this.expirationCheckInterval\n ); // check immediately then on an interval\n }\n\n setTimeout(() => {\n check(); // check immediately after starting the interval\n }, 10);\n\n return this.expirationTimerId; // return the timer ID so it can be stopped later\n }\n\n /**\n * Stops checking the expiration time of the session. This will clear the `setInterval()` that was started by {@linkcode BaseSession.enableCheckingExpirationTime}.\n */\n disableCheckingExpirationTime() {\n if (this.expirationTimerId) {\n clearInterval(this.expirationTimerId);\n this.expirationTimerId = null;\n }\n }\n\n /**\n * Starts a new session using the provided parameters and returns an instance of the session class.\n *\n * @param params - The parameters for starting the session.\n * @param SessionClass - The class to use for the session.\n * @returns A promise that resolves to an instance of the session class.\n */\n protected static async startSession<T extends BaseSession>(\n {\n startSessionUrl,\n styleFamily = \"arcgis\",\n authentication,\n safetyMargin,\n duration = DEFAULT_DURATION,\n autoRefresh = false\n }: {\n startSessionUrl?: string;\n styleFamily?: StyleFamily;\n authentication: IAuthenticationManager | string;\n safetyMargin?: number;\n duration?: number;\n autoRefresh?: boolean;\n },\n SessionClass: new (params: IBasemapSessionParams) => T\n ): Promise<T> {\n if (duration < 10) {\n throw new Error(\"Session duration must be at least 10 seconds.\");\n }\n\n if (duration > 43200) {\n throw new Error(\n \"Session duration cannot exceed 12 hours (43200 seconds).\"\n );\n }\n\n const sessionResponse = await startNewSession({\n startSessionUrl,\n styleFamily,\n authentication,\n duration\n });\n const actualSafetyMargin = determineSafetyMargin(duration, safetyMargin);\n\n const session = new SessionClass({\n startSessionUrl: startSessionUrl,\n token: sessionResponse.sessionToken,\n styleFamily,\n authentication,\n safetyMargin: actualSafetyMargin,\n expires: new Date(sessionResponse.endTime - actualSafetyMargin * 1000),\n startTime: new Date(sessionResponse.startTime),\n endTime: new Date(sessionResponse.endTime),\n duration\n });\n\n session.enableCheckingExpirationTime();\n\n if (autoRefresh) {\n session.enableAutoRefresh();\n }\n\n return session as T;\n }\n\n /**\n * Indicates if the session is currently checking for expiration time.\n *\n * @returns {boolean} - Returns true if the session is checking for expiration time, otherwise false.\n */\n get checkingExpirationTime(): boolean {\n return !!this.expirationTimerId;\n }\n\n /**\n * Returns the number of seconds until the session is no longer valid rounded down. If the session is expired, it will return 0.\n */\n get secondsUntilExpiration(): number {\n return Math.floor(this.millisecondsUntilExpiration / 1000);\n }\n\n /**\n * Returns the number of milliseconds until the session token is no longer valid. If the session is expired, it will return 0.\n */\n get millisecondsUntilExpiration(): number {\n if (this.isExpired) {\n return 0;\n }\n\n const now = new Date();\n const millisecondsLeft = this.endTime.getTime() - now.getTime();\n\n return millisecondsLeft;\n }\n\n /**\n * Checks if the session is expired.\n *\n */\n get isExpired(): boolean {\n return this.expires < new Date();\n }\n\n /**\n * Gets the session token. If the session is expired, it will refresh the credentials and return the new token.\n *\n * @returns A promise that resolves to the session token.\n */\n getToken(): Promise<string> {\n if (this.isExpired) {\n return this.refreshCredentials().then(() => this.token);\n }\n\n return Promise.resolve(this.token);\n }\n\n /**\n * Indicates if the session can be refreshed. This is always true for this basemap sessions.\n *\n * @returns {boolean} - Always returns true.\n */\n get canRefresh(): boolean {\n return true;\n }\n\n /**\n * Indicates if the session is set to automatically refresh when it expires.\n *\n * @returns {boolean} - Returns true if auto-refresh is enabled, otherwise false.\n */\n get autoRefresh(): boolean {\n return !!this.autoRefreshHandler && !!this.expirationTimerId;\n }\n\n /**\n * Refreshes the session credentials by starting a new session.\n * This will emit a \"refreshed\" event with the previous and current session details.\n *\n * @returns A promise that resolves to the current instance of the session.\n */\n async refreshCredentials(): Promise<this> {\n if (this.pendingSession) {\n // if there is a pending session, wait for it to resolve\n await this.pendingSession;\n return this;\n }\n\n // @TODO switch this to structured clone when we upgrade to Node 20+ types so we don't have to parse the dates later\n const previous = JSON.parse(\n JSON.stringify({\n token: this.token,\n startTime: this.startTime,\n endTime: this.endTime,\n expires: this.expires\n })\n );\n\n try {\n this.pendingSession = startNewSession({\n startSessionUrl: this.startSessionUrl,\n styleFamily: this.styleFamily,\n authentication: this.authentication,\n duration: this.duration\n });\n\n const newSession = await this.pendingSession;\n\n this.pendingSession = null; // reset the pending session\n\n this.setToken(newSession.sessionToken);\n this.setStartTime(new Date(newSession.startTime));\n this.setEndTime(new Date(newSession.endTime));\n this.setExpires(new Date(newSession.endTime - this.safetyMargin * 1000));\n\n this.enableCheckingExpirationTime(); // restart checking expiration time after refreshing credentials\n\n this.emitter.emit(\"refreshed\", {\n previous: {\n token: previous.token,\n startTime: new Date(previous.startTime),\n endTime: new Date(previous.endTime),\n expires: new Date(previous.expires)\n },\n current: {\n token: this.token,\n startTime: this.startTime,\n endTime: this.endTime,\n expires: this.expires\n }\n });\n } catch (error) {\n this.emitter.emit(\"error\", error);\n throw error;\n }\n\n return this;\n }\n /**\n * Enables auto-refresh for the session. This will automatically refresh the session when it expires.\n * It will also start checking the expiration time of the session if it is not already started via {@linkcode BaseSession.enableCheckingExpirationTime}.\n */\n enableAutoRefresh() {\n if (!this.expirationTimerId) {\n this.enableCheckingExpirationTime();\n }\n\n this.autoRefreshHandler = () => {\n this.refreshCredentials().catch((error: Error) => {\n this.emitter.emit(\"error\", error);\n });\n };\n\n this.on(\"expired\", this.autoRefreshHandler);\n }\n\n /**\n * Disables auto-refresh for the session. This will stop automatically refreshing the session when it expires.\n * This will **not** stop checking the expiration time of the session. If you want to stop automated expiration\n * checking, call {@linkcode BaseSession.disableCheckingExpirationTime} after calling this method.\n */\n disableAutoRefresh() {\n if (this.autoRefreshHandler) {\n this.off(\"expired\", this.autoRefreshHandler);\n this.autoRefreshHandler = null;\n }\n }\n\n /**\n * Removes all event listeners and disables auto-refresh and expiration time checking. This is useful for cleaning up the session when it is no longer needed or replaced with a new session.\n */\n destroy() {\n this.disableAutoRefresh();\n this.disableCheckingExpirationTime();\n this.emitter.off(\"expired\");\n this.emitter.off(\"refreshed\");\n this.emitter.off(\"error\");\n this.emitter.off(\"*\");\n }\n\n /**\n * A handler that listens for an eventName and returns custom handler.\n *\n * @param event A string of what event to listen for.\n * @param handler A function of what to do when eventName was called.\n */\n on(event: \"refreshed\", handler: typeof BaseSession.refreshed): void;\n on(event: \"expired\", handler: typeof BaseSession.expired): void;\n on(event: \"error\", handler: typeof BaseSession.error): void;\n on(\n event: string,\n handler:\n | typeof BaseSession.refreshed\n | typeof BaseSession.expired\n | typeof BaseSession.error\n ) {\n this.emitter.on(event, handler);\n this.isSessionExpired(); // check if the session is expired immediately after adding the handler\n }\n\n /**\n * A handler that listens for an event once and returns a custom handler. Events listened to with this method cannot be removed with {@linkcode BaseSession.off}.\n *\n * @param event A string of what event to listen for.\n * @param handler A function of what to do when event was called.\n */\n once(event: \"refreshed\", handler: typeof BaseSession.refreshed): void;\n once(event: \"expired\", handler: typeof BaseSession.expired): void;\n once(event: \"error\", handler: typeof BaseSession.error): void;\n once(\n event: string,\n handler:\n | typeof BaseSession.refreshed\n | typeof BaseSession.expired\n | typeof BaseSession.error\n ) {\n const fn = (e: any) => {\n this.emitter.off(event, fn);\n handler(e);\n };\n\n this.emitter.on(event, fn);\n }\n\n /**\n * A handler that will remove a listener from a given event.\n *\n * @param event A string of what event to listen for.\n * @param handler A function of what to do when event was called.\n */\n off(event: \"refreshed\", handler: typeof BaseSession.refreshed): void;\n off(event: \"expired\", handler: typeof BaseSession.expired): void;\n off(event: \"error\", handler: typeof BaseSession.error): void;\n off(\n event: string,\n handler:\n | typeof BaseSession.refreshed\n | typeof BaseSession.expired\n | typeof BaseSession.error\n ) {\n this.emitter.off(event, handler);\n }\n\n /**\n * These private methods are used to set the internal state of the session.\n */\n private setToken(token: string) {\n (this as Writable<typeof this>).token = token;\n }\n private setStartTime(startTime: Date) {\n (this as Writable<typeof this>).startTime = startTime;\n }\n private setEndTime(endTime: Date) {\n (this as Writable<typeof this>).endTime = endTime;\n }\n private setExpires(expires: Date) {\n (this as Writable<typeof this>).expires = expires;\n }\n}\n","import {\n BaseSession,\n IBasemapSessionParams,\n IStartSessionParams\n} from \"./BaseSession.js\";\nimport { DEFAULT_START_BASEMAP_STYLE_SESSION_URL } from \"./utils/defaults.js\";\n\n/**\n * `BasemapStyleSession` is a class that extends {@linkcode BaseSession} to manage sessions\n * for basemap styles. It provides methods to {@linkcode BasemapStyleSession.start} a new session\n * which should be used instead of constructing a new instance directly.\n *\n * @class BasemapStyleSession\n * @extends BaseSession\n */\nexport class BasemapStyleSession extends BaseSession {\n /**\n * Creates an instance of `BasemapStyleSession`. Constructing `BasemapStyleSession` directly is discouraged.\n * Instead, use the static method {@linkcode BasemapStyleSession.start} to start a new session.\n */\n constructor(params: IBasemapSessionParams) {\n super(params);\n }\n\n /**\n * Starts a new basemap style session.\n */\n static async start(params: IStartSessionParams) {\n return BaseSession.startSession<BasemapStyleSession>(\n {\n ...params,\n startSessionUrl:\n params?.startSessionUrl || DEFAULT_START_BASEMAP_STYLE_SESSION_URL\n },\n BasemapStyleSession as new (\n params: IBasemapSessionParams\n ) => BasemapStyleSession\n );\n }\n}\n"],"names":["request"],"mappings":"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","x_google_ignoreList":[0]}
@@ -1,12 +1,12 @@
1
1
  /* @preserve
2
- * @esri/arcgis-rest-basemap-sessions - v1.0.0 - Apache-2.0
3
- * Copyright (c) 2017-2025 Esri, Inc.
4
- * Wed Jul 30 2025 12:24:38 GMT-0700 (Pacific Daylight Time)
2
+ * @esri/arcgis-rest-basemap-sessions - v4.8.0 - Apache-2.0
3
+ * Copyright (c) 2017-2026 Esri, Inc.
4
+ * Fri Jan 16 2026 01:29:33 GMT+0000 (Coordinated Universal Time)
5
5
  */
6
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@esri/arcgis-rest-request")):"function"==typeof define&&define.amd?define(["exports","@esri/arcgis-rest-request"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).arcgisRest=e.arcgisRest||{},e.arcgisRest)}(this,(function(e,t){"use strict";const i="https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/sessions/start",s=43200;function r({startSessionUrl:e,authentication:i,styleFamily:s="arcgis",duration:r=43200}){return t.request(e,{httpMethod:"GET",authentication:i,params:{styleFamily:s,durationSeconds:r}})}class n{constructor(e){var t;this.expirationTimerId=null,this.autoRefreshHandler=null,this.startSessionUrl=e.startSessionUrl,this.token=e.token,this.styleFamily=e.styleFamily||"arcgis",this.authentication=e.authentication,this.duration=e.duration||s,this.startTime=e.startTime,this.endTime=e.endTime,this.expires=e.expires,this.safetyMargin=e.safetyMargin,this.expirationCheckInterval=1e3*Math.min(this.duration/100,10),this.emitter={all:t=t||new Map,on:function(e,i){var s=t.get(e);s?s.push(i):t.set(e,[i])},off:function(e,i){var s=t.get(e);s&&(i?s.splice(s.indexOf(i)>>>0,1):t.set(e,[]))},emit:function(e,i){var s=t.get(e);s&&s.slice().map((function(e){e(i)})),(s=t.get("*"))&&s.slice().map((function(t){t(e,i)}))}}}isSessionExpired(){return this.isExpired&&this.emitter.emit("expired",{token:this.token,startTime:this.startTime,endTime:this.endTime,expires:this.expires}),this.isExpired}startCheckingExpirationTime(){const e=()=>{this.isSessionExpired()};return this.expirationTimerId||(this.expirationTimerId=setInterval(e,this.expirationCheckInterval)),setTimeout((()=>{e()}),10),this.expirationTimerId}stopCheckingExpirationTime(){this.expirationTimerId&&(clearInterval(this.expirationTimerId),this.expirationTimerId=null)}get checkingExpirationTime(){return!!this.expirationTimerId}static async startSession({startSessionUrl:e,styleFamily:t="arcgis",authentication:i,safetyMargin:s,duration:n=43200,autoRefresh:a=!0},o){const h=await r({startSessionUrl:e,styleFamily:t,authentication:i,duration:n}),m=function(e,t){return t||Math.min(Math.max(e/100,1),300)}(n,s),u=new o({startSessionUrl:e,token:h.sessionToken,styleFamily:t,authentication:i,safetyMargin:m,expires:new Date(h.endTime-1e3*m),startTime:new Date(h.startTime),endTime:new Date(h.endTime),duration:n});return u.startCheckingExpirationTime(),a&&u.startAutoRefresh(),u}get isExpired(){return this.expires<new Date}getToken(){return this.isExpired?this.refreshCredentials().then((()=>this.token)):Promise.resolve(this.token)}get canRefresh(){return!0}get autoRefresh(){return!!this.autoRefreshHandler&&!!this.expirationTimerId}async refreshCredentials(){const e=JSON.parse(JSON.stringify({token:this.token,startTime:this.startTime,endTime:this.endTime,expires:this.expires}));try{const t=await r({startSessionUrl:this.startSessionUrl,styleFamily:this.styleFamily,authentication:this.authentication,duration:this.duration});this.setToken(t.sessionToken),this.setStartTime(new Date(t.startTime)),this.setEndTime(new Date(t.endTime)),this.setExpires(new Date(t.endTime-1e3*this.safetyMargin)),this.emitter.emit("refreshed",{previous:{token:e.token,startTime:new Date(e.startTime),endTime:new Date(e.endTime),expires:new Date(e.expires)},current:{token:this.token,startTime:this.startTime,endTime:this.endTime,expires:this.expires}})}catch(e){throw this.emitter.emit("error",e),e}return this}startAutoRefresh(){this.expirationTimerId||this.startCheckingExpirationTime(),this.autoRefreshHandler=()=>{this.refreshCredentials().catch((e=>{this.emitter.emit("error",e)}))},this.on("expired",this.autoRefreshHandler)}stopAutoRefresh(){this.autoRefreshHandler&&(this.off("expired",this.autoRefreshHandler),this.autoRefreshHandler=null)}on(e,t){this.emitter.on(e,t),this.isSessionExpired()}once(e,t){const i=s=>{this.emitter.off(e,i),t(s)};this.emitter.on(e,i)}off(e,t){this.emitter.off(e,t)}setToken(e){this.token=e}setStartTime(e){this.startTime=e}setEndTime(e){this.endTime=e}setExpires(e){this.expires=e}}
7
- /* istanbul ignore next -- @preserve */n.error=function(e){},
6
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@esri/arcgis-rest-request")):"function"==typeof define&&define.amd?define(["exports","@esri/arcgis-rest-request"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).arcgisRest=e.arcgisRest||{},e.arcgisRest)}(this,function(e,t){"use strict";const i="https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/sessions/start",s=43200;function n({startSessionUrl:e,authentication:i,styleFamily:s="arcgis",duration:n=43200}){return t.request(e,{httpMethod:"GET",authentication:i,params:{styleFamily:s,durationSeconds:n}})}class r{constructor(e){var t;this.expirationTimerId=null,this.pendingSession=null,this.autoRefreshHandler=null,this.startSessionUrl=e.startSessionUrl,this.token=e.token,this.styleFamily=e.styleFamily||"arcgis",this.authentication=e.authentication,this.duration=e.duration||s,this.startTime=e.startTime,this.endTime=e.endTime,this.expires=e.expires,this.safetyMargin=e.safetyMargin,this.expirationCheckInterval=1e3*Math.min(this.duration/100,10),this.emitter={all:t=t||new Map,on:function(e,i){var s=t.get(e);s?s.push(i):t.set(e,[i])},off:function(e,i){var s=t.get(e);s&&(i?s.splice(s.indexOf(i)>>>0,1):t.set(e,[]))},emit:function(e,i){var s=t.get(e);s&&s.slice().map(function(e){e(i)}),(s=t.get("*"))&&s.slice().map(function(t){t(e,i)})}}}isSessionExpired(){return this.isExpired&&(this.disableCheckingExpirationTime(),this.emitter.emit("expired",{token:this.token,startTime:this.startTime,endTime:this.endTime,expires:this.expires})),this.isExpired}enableCheckingExpirationTime(){const e=()=>{this.isSessionExpired()};return this.expirationTimerId||(this.expirationTimerId=setInterval(e,this.expirationCheckInterval)),setTimeout(()=>{e()},10),this.expirationTimerId}disableCheckingExpirationTime(){this.expirationTimerId&&(clearInterval(this.expirationTimerId),this.expirationTimerId=null)}static async startSession({startSessionUrl:e,styleFamily:t="arcgis",authentication:i,safetyMargin:s,duration:r=43200,autoRefresh:a=!1},o){if(r<10)throw new Error("Session duration must be at least 10 seconds.");if(r>43200)throw new Error("Session duration cannot exceed 12 hours (43200 seconds).");const h=await n({startSessionUrl:e,styleFamily:t,authentication:i,duration:r}),d=function(e,t){return t||Math.min(Math.max(e/100,1),300)}(r,s),m=new o({startSessionUrl:e,token:h.sessionToken,styleFamily:t,authentication:i,safetyMargin:d,expires:new Date(h.endTime-1e3*d),startTime:new Date(h.startTime),endTime:new Date(h.endTime),duration:r});return m.enableCheckingExpirationTime(),a&&m.enableAutoRefresh(),m}get checkingExpirationTime(){return!!this.expirationTimerId}get secondsUntilExpiration(){return Math.floor(this.millisecondsUntilExpiration/1e3)}get millisecondsUntilExpiration(){if(this.isExpired)return 0;const e=new Date;return this.endTime.getTime()-e.getTime()}get isExpired(){return this.expires<new Date}getToken(){return this.isExpired?this.refreshCredentials().then(()=>this.token):Promise.resolve(this.token)}get canRefresh(){return!0}get autoRefresh(){return!!this.autoRefreshHandler&&!!this.expirationTimerId}async refreshCredentials(){if(this.pendingSession)return await this.pendingSession,this;const e=JSON.parse(JSON.stringify({token:this.token,startTime:this.startTime,endTime:this.endTime,expires:this.expires}));try{this.pendingSession=n({startSessionUrl:this.startSessionUrl,styleFamily:this.styleFamily,authentication:this.authentication,duration:this.duration});const t=await this.pendingSession;this.pendingSession=null,this.setToken(t.sessionToken),this.setStartTime(new Date(t.startTime)),this.setEndTime(new Date(t.endTime)),this.setExpires(new Date(t.endTime-1e3*this.safetyMargin)),this.enableCheckingExpirationTime(),this.emitter.emit("refreshed",{previous:{token:e.token,startTime:new Date(e.startTime),endTime:new Date(e.endTime),expires:new Date(e.expires)},current:{token:this.token,startTime:this.startTime,endTime:this.endTime,expires:this.expires}})}catch(e){throw this.emitter.emit("error",e),e}return this}enableAutoRefresh(){this.expirationTimerId||this.enableCheckingExpirationTime(),this.autoRefreshHandler=()=>{this.refreshCredentials().catch(e=>{this.emitter.emit("error",e)})},this.on("expired",this.autoRefreshHandler)}disableAutoRefresh(){this.autoRefreshHandler&&(this.off("expired",this.autoRefreshHandler),this.autoRefreshHandler=null)}destroy(){this.disableAutoRefresh(),this.disableCheckingExpirationTime(),this.emitter.off("expired"),this.emitter.off("refreshed"),this.emitter.off("error"),this.emitter.off("*")}on(e,t){this.emitter.on(e,t),this.isSessionExpired()}once(e,t){const i=s=>{this.emitter.off(e,i),t(s)};this.emitter.on(e,i)}off(e,t){this.emitter.off(e,t)}setToken(e){this.token=e}setStartTime(e){this.startTime=e}setEndTime(e){this.endTime=e}setExpires(e){this.expires=e}}
7
+ /* istanbul ignore next -- @preserve */r.error=function(e){},
8
8
  /* istanbul ignore next -- @preserve */
9
- n.expired=function(e){},
9
+ r.expired=function(e){},
10
10
  /* istanbul ignore next -- @preserve */
11
- n.refreshed=function(e){};class a extends n{constructor(e){super(e)}static async start(e){return n.startSession(Object.assign(Object.assign({},e),{startSessionUrl:(null==e?void 0:e.startSessionUrl)||i}),a)}}e.BaseSession=n,e.BasemapStyleSession=a,e.DEFAULT_CHECK_EXPIRATION_INTERVAL=10,e.DEFAULT_DURATION=s,e.DEFAULT_SAFETY_MARGIN=300,e.DEFAULT_START_BASEMAP_STYLE_SESSION_URL=i,e.startNewSession=r,Object.defineProperty(e,"__esModule",{value:!0})}));
11
+ r.refreshed=function(e){};class a extends r{constructor(e){super(e)}static async start(e){return r.startSession(Object.assign(Object.assign({},e),{startSessionUrl:(null==e?void 0:e.startSessionUrl)||i}),a)}}e.BaseSession=r,e.BasemapStyleSession=a,e.DEFAULT_CHECK_EXPIRATION_INTERVAL=10,e.DEFAULT_DURATION=s,e.DEFAULT_SAFETY_MARGIN=300,e.DEFAULT_START_BASEMAP_STYLE_SESSION_URL=i,e.startNewSession=n});
12
12
  //# sourceMappingURL=basemap-sessions.umd.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"basemap-sessions.umd.min.js","sources":["../../src/utils/defaults.ts","../../src/utils/startNewSession.ts","../../src/BaseSession.ts","../../node_modules/mitt/dist/mitt.mjs","../../src/utils/detemineSafetyMargin.ts","../../src/BasemapStyleSession.ts"],"sourcesContent":["export const DEFAULT_START_BASEMAP_STYLE_SESSION_URL =\n \"https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/sessions/start\";\n\nexport const DEFAULT_SAFETY_MARGIN = 5 * 60; // Default to 5 minutes in seconds\n\nexport const DEFAULT_CHECK_EXPIRATION_INTERVAL = 10; // Default to 10 seconds\n\nexport const DEFAULT_DURATION = 12 * 60 * 60; // Default to 12 hours in seconds\n","import { IAuthenticationManager, request } from \"@esri/arcgis-rest-request\";\nimport { StyleFamily } from \"../types/StyleFamily.js\";\nimport { DEFAULT_DURATION } from \"./defaults.js\";\n\nexport interface IRequestNewSessionParams {\n startSessionUrl: string;\n authentication: IAuthenticationManager | string;\n styleFamily?: StyleFamily;\n duration?: number;\n}\n\nexport interface IStartSessionResponse {\n sessionToken: string;\n endTime: number;\n startTime: number;\n styleFamily: StyleFamily;\n}\n\nexport function startNewSession({\n startSessionUrl,\n authentication,\n styleFamily = \"arcgis\",\n duration = DEFAULT_DURATION\n}: IRequestNewSessionParams): Promise<IStartSessionResponse> {\n return request(startSessionUrl, {\n httpMethod: \"GET\",\n authentication: authentication,\n params: { styleFamily, durationSeconds: duration }\n });\n}\n","import mitt from \"mitt\";\n\nimport { IAuthenticationManager } from \"@esri/arcgis-rest-request\";\nimport { StyleFamily } from \"./types/StyleFamily.js\";\nimport { startNewSession } from \"./utils/startNewSession.js\";\nimport { Writable } from \"./utils/writable.js\";\nimport { determineSafetyMargin } from \"./utils/detemineSafetyMargin.js\";\nimport {\n DEFAULT_DURATION,\n DEFAULT_SAFETY_MARGIN,\n DEFAULT_CHECK_EXPIRATION_INTERVAL\n} from \"./utils/defaults.js\";\n\nexport interface IBasemapSessionParams {\n token: string;\n startSessionUrl: string;\n styleFamily: StyleFamily;\n authentication: IAuthenticationManager | string;\n expires: Date;\n startTime: Date;\n endTime: Date;\n safetyMargin?: number;\n duration?: number;\n autoRefresh?: boolean;\n}\n\nexport interface IStartSessionParams {\n styleFamily?: StyleFamily;\n authentication: IAuthenticationManager | string;\n safetyMargin?: number;\n duration?: number;\n autoRefresh?: boolean;\n\n /**\n * The URL to start the session. If not provided, it will use the default URL.\n * @private\n */\n startSessionUrl?: string;\n}\n\n/**\n * The base class for all basemap sessions. This class implements the {@linkcode IAuthenticationManager} interface and provides methods to start, refresh, and check the expiration of a session.\n * This is not intendet to be used directly, but instead is extended by other classes such as {@linkcode BasemapStyleSession} and {@linkcode StaticBasemapTilesSession}.\n *\n * @abstract\n * @implements {IAuthenticationManager}\n */\nexport abstract class BaseSession implements IAuthenticationManager {\n // the static methods for event handlers are used to provide doc via typedoc and do not need to be tested.\n /* istanbul ignore next -- @preserve */\n /**\n * Event handler for when an error occurs during session management.\n */\n static readonly error = function error(e: Error): void {}; // eslint-disable-line @typescript-eslint/no-empty-function\n\n // the static methods for event handlers are used to provide doc via typedoc and do not need to be tested.\n /* istanbul ignore next -- @preserve */\n /**\n * Event handler for when a session expires and the `token` it no longer valid.\n *\n * @event expired\n * @param e - The parameters for the expired event.\n * @param e.token - The session token that expired.\n * @param e.startTime - The start time of the session.\n * @param e.endTime - The end time of the session.\n * @param e.expires - The expiration time of the session.\n */\n static readonly expired = function expired(e: {\n token: string;\n startTime: Date;\n endTime: Date;\n expires: Date;\n }): void {}; // eslint-disable-line @typescript-eslint/no-empty-function\n\n // the static methods for event handlers are used to provide doc via typedoc and do not need to be tested.\n /* istanbul ignore next -- @preserve */\n /**\n * Event handler for when a session refreshes and a new `token` is available.\n *\n * @event refreshed\n * @param e. - The parameters for the refreshed event.\n * @param e.previous - The previous session details.\n * @param e.previous.token - The previous session token.\n * @param e.previous.startTime - The start time of the previous session.\n * @param e.previous.endTime - The end time of the previous session.\n * @param e.previous.expires - The expiration time of the previous session.\n * @param e.current - The current session details.\n * @param e.current.token - The current session token.\n * @param e.current.startTime - The start time of the current token.\n * @param e.current.endTime - The end time of the current session.\n * @param e.current.expires - The expiration time of the current token.\n */\n static readonly refreshed = function refreshed(e: {\n previous: {\n token: string;\n startTime: Date;\n endTime: Date;\n expires: Date;\n };\n current: {\n token: string;\n startTime: Date;\n endTime: Date;\n expires: Date;\n };\n }): void {}; // eslint-disable-line @typescript-eslint/no-empty-function\n\n /**\n * The portal URL that the session is associated with. This generally is not used but exists to implement the `IAuthenticationManager` interface.\n */\n readonly portal: string;\n\n /**\n * The style family of the session. This is used to determine the type of basemap styles that are available.\n */\n readonly styleFamily: StyleFamily;\n\n /**\n * The authentication manager or token used for the session.\n * This can be an instance of {@linkcode ApiKeyManager}, {@linkcode ArcGISIdentityManager}, {@linkcode ApplicationCredentialsManager} or a string token.\n */\n readonly authentication: IAuthenticationManager | string;\n\n /**\n * The expiration date of the session. This is the {@linkcode BaseSession.endTime} minus the {@linkcode BaseSession.safetyMargin}. This is used internally to determine if the session is expired.\n */\n readonly expires: Date;\n\n /**\n * The start time of the session. This is the time returned from the API when the session war started.\n */\n readonly startTime: Date;\n\n /**\n * The end time of the session. This is the time returned from the API when the session will end.\n */\n readonly endTime: Date;\n\n /**\n * The token for the session.\n */\n readonly token: string;\n\n /**\n * The URL used to start the session.\n */\n readonly startSessionUrl: string;\n\n /**\n * The safety margin in milliseconds. This subtracted from the {@linkcode BaseSession.endTime} to get the {@linkcode BaseSession.expiration}.\n */\n readonly safetyMargin: number;\n\n /**\n * The duration of the session in seconds. This is used to determine how long the session will last when the session is refreshed.\n */\n readonly duration: number;\n\n /**\n * The interval at which to check the expiration time of the session. This is always 10 seconds or 1/100th of the duration, whichever is smaller.\n */\n readonly expirationCheckInterval: number;\n\n /**\n * The ID of the timer used to check the expiration time of the session.\n */\n private expirationTimerId: any = null;\n\n /**\n * Internal instance of [`mitt`](https://github.com/developit/mitt) used for event handlers. It is recommended to use {@linkcode BasemapSession.on}, {@linkcode BasemapSession.off} or {@linkcode BasemapSession.once} instead of `emitter.`\n */\n private emitter: any;\n\n /**\n * A handler that is used to automatically refresh the session when it expires.\n */\n private autoRefreshHandler: (() => void) | null = null;\n\n /**\n * Creates a new instance of the BaseSession class. Generally you should not create an instance of this class directly, but instead use the static methods to start a session or deserialize a session.\n *\n * You may need to create an instance of this class directly if you are not using the built in deserialize method.\n *\n * @param params - The parameters for the session.\n * @param params.startSessionUrl - The URL to start the session.\n * @param params.token - The token for the session.\n * @param params.styleFamily - The style family of the session.\n * @param params.authentication - The authentication manager or token used for the session.\n * @param params.expires - The expiration date of the session.\n * @param params.startTime - The start time of the session.\n * @param params.endTime - The end time of the session.\n * @param params.safetyMargin - The safety margin in milliseconds.\n * @param params.duration - Indicates if this is a test session.\n */\n constructor(params: IBasemapSessionParams) {\n this.startSessionUrl = params.startSessionUrl;\n this.token = params.token;\n this.styleFamily = params.styleFamily || \"arcgis\";\n this.authentication = params.authentication;\n this.duration = params.duration || DEFAULT_DURATION;\n this.startTime = params.startTime;\n this.endTime = params.endTime;\n this.expires = params.expires;\n this.safetyMargin = params.safetyMargin;\n this.expirationCheckInterval =\n Math.min(this.duration / 100, DEFAULT_CHECK_EXPIRATION_INTERVAL) * 1000;\n this.emitter = mitt();\n }\n\n /**\n * Checks if the session is expired. If it is expired, it emits an \"expired\" event. The event will fire **before** the method returns true.\n *\n * @returns {boolean} - Returns true if the session is expired, otherwise false.\n */\n isSessionExpired() {\n if (this.isExpired) {\n this.emitter.emit(\"expired\", {\n token: this.token,\n startTime: this.startTime,\n endTime: this.endTime,\n expires: this.expires\n });\n }\n return this.isExpired;\n }\n\n /**\n * Starts checking the expiration time of the session. This will check the expiration time immediately and then on an interval.\n * If the session is expired, it will emit an \"expired\" event.\n */\n startCheckingExpirationTime() {\n const check = () => {\n this.isSessionExpired();\n };\n\n if (!this.expirationTimerId) {\n this.expirationTimerId = setInterval(\n check,\n // check every 10 seconds or 1/100th of the duration, whichever is smaller\n this.expirationCheckInterval\n ); // check immediatly then on an interval\n }\n\n setTimeout(() => {\n check(); // check immediately after starting the interval\n }, 10);\n\n return this.expirationTimerId; // return the timer ID so it can be stopped later\n }\n\n /**\n * Stops checking the expiration time of the session. This will clear the interval that was set by {@linkcode BaseSession.startCheckingExpirationTime}.\n */\n stopCheckingExpirationTime() {\n if (this.expirationTimerId) {\n clearInterval(this.expirationTimerId);\n this.expirationTimerId = null;\n }\n }\n\n /**\n * Indicates if the session is currently checking for expiration time.\n *\n * @returns {boolean} - Returns true if the session is checking for expiration time, otherwise false.\n */\n get checkingExpirationTime(): boolean {\n return !!this.expirationTimerId;\n }\n\n /**\n * Starts a new session using the provided parameters and returns an instance of the session class.\n *\n * @param params - The parameters for starting the session.\n * @param SessionClass - The class to use for the session.\n * @returns A promise that resolves to an instance of the session class.\n */\n protected static async startSession<T extends BaseSession>(\n {\n startSessionUrl,\n styleFamily = \"arcgis\",\n authentication,\n safetyMargin,\n duration = DEFAULT_DURATION,\n autoRefresh = true\n }: {\n startSessionUrl?: string;\n styleFamily?: StyleFamily;\n authentication: IAuthenticationManager | string;\n safetyMargin?: number;\n duration?: number;\n autoRefresh?: boolean;\n },\n SessionClass: new (params: IBasemapSessionParams) => T\n ): Promise<T> {\n const sessionResponse = await startNewSession({\n startSessionUrl,\n styleFamily,\n authentication,\n duration\n });\n const actualSafetyMargin = determineSafetyMargin(duration, safetyMargin);\n\n const session = new SessionClass({\n startSessionUrl: startSessionUrl,\n token: sessionResponse.sessionToken,\n styleFamily,\n authentication,\n safetyMargin: actualSafetyMargin,\n expires: new Date(sessionResponse.endTime - actualSafetyMargin * 1000),\n startTime: new Date(sessionResponse.startTime),\n endTime: new Date(sessionResponse.endTime),\n duration\n });\n\n session.startCheckingExpirationTime();\n\n if (autoRefresh) {\n session.startAutoRefresh();\n }\n\n return session as T;\n }\n\n /**\n * Checks if the session is expired.\n *\n */\n get isExpired(): boolean {\n return this.expires < new Date();\n }\n\n /**\n * Gets the session token. If the session is expired, it will refresh the credentials and return the new token.\n *\n * @returns A promise that resolves to the session token.\n */\n getToken(): Promise<string> {\n if (this.isExpired) {\n return this.refreshCredentials().then(() => this.token);\n }\n\n return Promise.resolve(this.token);\n }\n\n /**\n * Indicates if the session can be refreshed. This is always true for this class.\n *\n * @returns {boolean} - Always returns true.\n */\n get canRefresh(): boolean {\n return true;\n }\n\n /**\n * Indicates if the session is set to automatically refresh when it expires.\n *\n * @returns {boolean} - Returns true if auto-refresh is enabled, otherwise false.\n */\n get autoRefresh(): boolean {\n return !!this.autoRefreshHandler && !!this.expirationTimerId;\n }\n\n /**\n * Refreshes the session credentials by starting a new session.\n * This will emit a \"refreshed\" event with the previous and current session details.\n *\n * @returns A promise that resolves to the current instance of the session.\n */\n async refreshCredentials(): Promise<this> {\n // @TODO switch this to structured clone when we upgrade to Node 20+ types so we don't have to parse the dates later\n const previous = JSON.parse(\n JSON.stringify({\n token: this.token,\n startTime: this.startTime,\n endTime: this.endTime,\n expires: this.expires\n })\n );\n\n try {\n const newSession = await startNewSession({\n startSessionUrl: this.startSessionUrl,\n styleFamily: this.styleFamily,\n authentication: this.authentication,\n duration: this.duration\n });\n\n this.setToken(newSession.sessionToken);\n this.setStartTime(new Date(newSession.startTime));\n this.setEndTime(new Date(newSession.endTime));\n this.setExpires(new Date(newSession.endTime - this.safetyMargin * 1000));\n\n this.emitter.emit(\"refreshed\", {\n previous: {\n token: previous.token,\n startTime: new Date(previous.startTime),\n endTime: new Date(previous.endTime),\n expires: new Date(previous.expires)\n },\n current: {\n token: this.token,\n startTime: this.startTime,\n endTime: this.endTime,\n expires: this.expires\n }\n });\n } catch (error) {\n this.emitter.emit(\"error\", error);\n throw error;\n }\n\n return this;\n }\n /**\n * Enables auto-refresh for the session. This will automatically refresh the session when it expires.\n * It will also start checking the expiration time of the session if it is not already started via {@linkcode BaseSession.startCheckingExpirationTime}.\n */\n startAutoRefresh() {\n if (!this.expirationTimerId) {\n this.startCheckingExpirationTime();\n }\n\n this.autoRefreshHandler = () => {\n this.refreshCredentials().catch((error: Error) => {\n this.emitter.emit(\"error\", error);\n });\n };\n\n this.on(\"expired\", this.autoRefreshHandler);\n }\n\n /**\n * Disables auto-refresh for the session. This will stop automatically refreshing the session when it expires.\n * This will **not** stop checking the expiration time of the session. If you want to stop automated expiration\n * checking, call {@linkcode BaseSession.stopCheckingExpirationTime} after calling this method.\n */\n stopAutoRefresh() {\n if (this.autoRefreshHandler) {\n this.off(\"expired\", this.autoRefreshHandler);\n this.autoRefreshHandler = null;\n }\n }\n\n /**\n * A handler that listens for an eventName and returns custom handler.\n *\n * @param eventName A string of what event to listen for.\n * @param handler A function of what to do when eventName was called.\n */\n on(event: \"refreshed\", handler: typeof BaseSession.refreshed): void;\n on(event: \"expired\", handler: typeof BaseSession.expired): void;\n on(event: \"error\", handler: typeof BaseSession.error): void;\n on(\n eventName: string,\n handler:\n | typeof BaseSession.refreshed\n | typeof BaseSession.expired\n | typeof BaseSession.error\n ) {\n this.emitter.on(eventName, handler);\n this.isSessionExpired(); // check if the session is expired immediately after adding the handler\n }\n\n /**\n * A handler that listens for an event once and returns a custom handler. Events listened to with this method cannot be removed with {@linkcode BasemapSession.off}.\n *\n * @param eventName A string of what event to listen for.\n * @param handler A function of what to do when eventName was called.\n */\n once(event: \"refreshed\", handler: typeof BaseSession.refreshed): void;\n once(event: \"expired\", handler: typeof BaseSession.expired): void;\n once(event: \"error\", handler: typeof BaseSession.error): void;\n once(\n eventName: string,\n handler:\n | typeof BaseSession.refreshed\n | typeof BaseSession.expired\n | typeof BaseSession.error\n ) {\n const fn = (e: any) => {\n this.emitter.off(eventName, fn);\n handler(e);\n };\n\n this.emitter.on(eventName, fn);\n }\n\n /**\n * A handler that will remove a listener from a given event.\n *\n * @param eventName A string of what event to listen for.\n * @param handler A function of what to do when eventName was called.\n */\n off(event: \"refreshed\", handler: typeof BaseSession.refreshed): void;\n off(event: \"expired\", handler: typeof BaseSession.expired): void;\n off(event: \"error\", handler: typeof BaseSession.error): void;\n off(\n eventName: string,\n handler:\n | typeof BaseSession.refreshed\n | typeof BaseSession.expired\n | typeof BaseSession.error\n ) {\n this.emitter.off(eventName, handler);\n }\n\n /**\n * These private methods are used to set the internal state of the session.\n */\n private setToken(token: string) {\n (this as Writable<typeof this>).token = token;\n }\n private setStartTime(startTime: Date) {\n (this as Writable<typeof this>).startTime = startTime;\n }\n private setEndTime(endTime: Date) {\n (this as Writable<typeof this>).endTime = endTime;\n }\n private setExpires(expires: Date) {\n (this as Writable<typeof this>).expires = expires;\n }\n}\n","export default function(n){return{all:n=n||new Map,on:function(t,e){var i=n.get(t);i?i.push(e):n.set(t,[e])},off:function(t,e){var i=n.get(t);i&&(e?i.splice(i.indexOf(e)>>>0,1):n.set(t,[]))},emit:function(t,e){var i=n.get(t);i&&i.slice().map(function(n){n(e)}),(i=n.get(\"*\"))&&i.slice().map(function(n){n(t,e)})}}}\n//# sourceMappingURL=mitt.mjs.map\n","import { DEFAULT_SAFETY_MARGIN } from \"./defaults.js\";\n\nexport function determineSafetyMargin(\n duration: number | undefined,\n safetyMargin: number | undefined\n): number {\n if (safetyMargin) {\n return safetyMargin;\n }\n // common cases are\n // duration is 60 seconds, this will return a 1 second safety margin\n // duration is 43200 seconds, this will return a 300 second (5 minutes) safety margin\n return Math.min(Math.max(duration / 100, 1), DEFAULT_SAFETY_MARGIN);\n}\n","import {\n BaseSession,\n IBasemapSessionParams,\n IStartSessionParams\n} from \"./BaseSession.js\";\nimport { DEFAULT_START_BASEMAP_STYLE_SESSION_URL } from \"./utils/defaults.js\";\n\n/**\n * `BasemapStyleSession` is a class that extends {@linkcode BaseSession} to manage sessions\n * for basemap styles. It provides methods to {@linkcode BasemapStyleSession.start} a new session\n * which should be used instead of constructing a new instance directly.\n *\n * @class BasemapStyleSession\n * @extends BaseSession\n */\nexport class BasemapStyleSession extends BaseSession {\n /**\n * Creates an instance of `BasemapStyleSession`. Constructing `BasemapStyleSession` directly is discouraged.\n * Instead, use the static method {@linkcode BasemapStyleSession.start} to start a new session.\n */\n constructor(params: IBasemapSessionParams) {\n super(params);\n }\n\n /**\n * Starts a new basemap style session.\n */\n static async start(params: IStartSessionParams) {\n return BaseSession.startSession<BasemapStyleSession>(\n {\n ...params,\n startSessionUrl:\n params?.startSessionUrl || DEFAULT_START_BASEMAP_STYLE_SESSION_URL\n },\n BasemapStyleSession as new (\n params: IBasemapSessionParams\n ) => BasemapStyleSession\n );\n }\n}\n"],"names":["DEFAULT_START_BASEMAP_STYLE_SESSION_URL","DEFAULT_DURATION","startNewSession","startSessionUrl","authentication","styleFamily","duration","request","httpMethod","params","durationSeconds","BaseSession","constructor","n","this","token","startTime","endTime","expires","safetyMargin","expirationCheckInterval","Math","min","emitter","all","Map","on","t","e","i","get","push","set","off","splice","indexOf","emit","slice","map","isSessionExpired","isExpired","startCheckingExpirationTime","check","expirationTimerId","setInterval","setTimeout","stopCheckingExpirationTime","clearInterval","checkingExpirationTime","static","autoRefresh","SessionClass","sessionResponse","actualSafetyMargin","max","determineSafetyMargin","session","sessionToken","Date","startAutoRefresh","getToken","refreshCredentials","then","Promise","resolve","canRefresh","autoRefreshHandler","async","previous","JSON","parse","stringify","newSession","setToken","setStartTime","setEndTime","setExpires","current","error","catch","stopAutoRefresh","eventName","handler","once","fn","BasemapStyleSession","super","startSession"],"mappings":"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"}
1
+ {"version":3,"file":"basemap-sessions.umd.min.js","sources":["../../src/utils/defaults.ts","../../src/utils/startNewSession.ts","../../src/BaseSession.ts","../../node_modules/mitt/dist/mitt.mjs","../../src/utils/detemineSafetyMargin.ts","../../src/BasemapStyleSession.ts"],"sourcesContent":["export const DEFAULT_START_BASEMAP_STYLE_SESSION_URL =\n \"https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/sessions/start\";\n\nexport const DEFAULT_SAFETY_MARGIN = 5 * 60; // Default to 5 minutes in seconds\n\nexport const DEFAULT_CHECK_EXPIRATION_INTERVAL = 10; // Default to 10 seconds\n\nexport const DEFAULT_DURATION = 12 * 60 * 60; // Default to 12 hours in seconds\n","import { IAuthenticationManager, request } from \"@esri/arcgis-rest-request\";\nimport { StyleFamily } from \"../types/StyleFamily.js\";\nimport { DEFAULT_DURATION } from \"./defaults.js\";\n\nexport interface IRequestNewSessionParams {\n startSessionUrl: string;\n authentication: IAuthenticationManager | string;\n styleFamily?: StyleFamily;\n duration?: number;\n}\n\nexport interface IStartSessionResponse {\n sessionToken: string;\n endTime: number;\n startTime: number;\n styleFamily: StyleFamily;\n}\n\nexport function startNewSession({\n startSessionUrl,\n authentication,\n styleFamily = \"arcgis\",\n duration = DEFAULT_DURATION\n}: IRequestNewSessionParams): Promise<IStartSessionResponse> {\n return request(startSessionUrl, {\n httpMethod: \"GET\",\n authentication: authentication,\n params: { styleFamily, durationSeconds: duration }\n });\n}\n","import mitt from \"mitt\";\n\nimport { IAuthenticationManager } from \"@esri/arcgis-rest-request\";\nimport { StyleFamily } from \"./types/StyleFamily.js\";\nimport {\n IStartSessionResponse,\n startNewSession\n} from \"./utils/startNewSession.js\";\nimport { Writable } from \"./utils/writable.js\";\nimport { determineSafetyMargin } from \"./utils/detemineSafetyMargin.js\";\nimport {\n DEFAULT_DURATION,\n DEFAULT_CHECK_EXPIRATION_INTERVAL\n} from \"./utils/defaults.js\";\n\nexport interface IBasemapSessionParams {\n token: string;\n startSessionUrl: string;\n styleFamily: StyleFamily;\n authentication: IAuthenticationManager | string;\n expires: Date;\n startTime: Date;\n endTime: Date;\n safetyMargin?: number;\n duration?: number;\n autoRefresh?: boolean;\n}\n\nexport interface IStartSessionParams {\n styleFamily?: StyleFamily;\n authentication: IAuthenticationManager | string;\n safetyMargin?: number;\n duration?: number;\n autoRefresh?: boolean;\n\n /**\n * The URL to start the session. If not provided, it will use the default URL.\n * @private\n */\n startSessionUrl?: string;\n}\n\n/**\n * The base class for all basemap sessions. This class implements the {@linkcode @esri/arcgis-rest-request!IAuthenticationManager} interface and provides methods to start, refresh, and check the expiration of a session.\n * This is not intended to be used directly, but instead is extended by other classes such as {@linkcode BasemapStyleSession} .\n *\n * @abstract\n */\nexport abstract class BaseSession implements IAuthenticationManager {\n // the static methods for event handlers are used to provide doc via typedoc and do not need to be tested.\n /* istanbul ignore next -- @preserve */\n /**\n * Event handler for when an error occurs during session management.\n */\n static readonly error = function error(e: Error): void {};\n\n // the static methods for event handlers are used to provide doc via typedoc and do not need to be tested.\n /* istanbul ignore next -- @preserve */\n /**\n * Event handler for when the current session expires and the session token it no longer valid. This event will only fire if {@linkcode BaseSession.checkingExpirationTime}\n * is `true` which is the default. Once this event fires, {@linkcode BaseSession.checkingExpirationTime} will be set to `false` until the session is refreshed with\n * {@linkcode BaseSession.refreshCredentials}.\n *\n * @event expired\n * @param e.token - The session token that expired.\n * @param e.startTime - The start time of the session.\n * @param e.endTime - The end time of the session.\n * @param e.expires - The expiration time of the session.\n */\n static readonly expired = function expired(e: {\n token: string;\n startTime: Date;\n endTime: Date;\n expires: Date;\n }): void {};\n\n // the static methods for event handlers are used to provide doc via typedoc and do not need to be tested.\n /* istanbul ignore next -- @preserve */\n /**\n * Event handler for when a session refreshes and a new `token` is available.\n *\n * @event refreshed\n * @param e.previous - The previous session details.\n * @param e.previous.token - The previous session token.\n * @param e.previous.startTime - The start time of the previous session.\n * @param e.previous.endTime - The end time of the previous session.\n * @param e.previous.expires - The expiration time of the previous session.\n * @param e.current - The current session details.\n * @param e.current.token - The current session token.\n * @param e.current.startTime - The start time of the current token.\n * @param e.current.endTime - The end time of the current session.\n * @param e.current.expires - The expiration time of the current token.\n */\n static readonly refreshed = function refreshed(e: {\n previous: {\n token: string;\n startTime: Date;\n endTime: Date;\n expires: Date;\n };\n current: {\n token: string;\n startTime: Date;\n endTime: Date;\n expires: Date;\n };\n }): void {};\n\n /**\n * The portal URL that the session is associated with. This generally is not used but exists to implement the `IAuthenticationManager` interface.\n */\n readonly portal: string;\n\n /**\n * The style family of the session. This is used to determine the type of basemap styles that are available.\n */\n readonly styleFamily: StyleFamily;\n\n /**\n * The authentication manager or token used for the session.\n * This can be an instance of {@linkcode @esri/arcgis-rest-request!ApiKeyManager}, {@linkcode @esri/arcgis-rest-request!ArcGISIdentityManager}, {@linkcode @esri/arcgis-rest-request!ApplicationCredentialsManager} or a string token.\n */\n readonly authentication: IAuthenticationManager | string;\n\n /**\n * The expiration date of the session. This is the {@linkcode BaseSession.endTime} minus the {@linkcode BaseSession.safetyMargin}. This is used internally to determine if the session is expired.\n */\n readonly expires: Date;\n\n /**\n * The start time of the session. This is the time returned from the API when the session war started.\n */\n readonly startTime: Date;\n\n /**\n * The end time of the session. This is the time returned from the API when the session will end.\n */\n readonly endTime: Date;\n\n /**\n * The token for the session.\n */\n readonly token: string;\n\n /**\n * The URL used to start the session.\n */\n readonly startSessionUrl: string;\n\n /**\n * The safety margin in milliseconds. This subtracted from the {@linkcode BaseSession.endTime} to get the expiration time of the session.\n */\n readonly safetyMargin: number;\n\n /**\n * The duration of the session in seconds. This is used to determine how long the session will last when the session is refreshed.\n */\n readonly duration: number;\n\n /**\n * The interval at which to check the expiration time of the session. This is always 10 seconds or 1/100th of the duration, whichever is smaller.\n */\n private readonly expirationCheckInterval: number;\n\n /**\n * The ID of the timer used to check the expiration time of the session.\n */\n private expirationTimerId: any = null;\n\n /**\n * A pending session that is being refreshed. This is used to prevent multiple refreshes from happening at the same time.\n */\n private pendingSession: Promise<IStartSessionResponse> | null = null;\n\n /**\n * Internal instance of [`mitt`](https://github.com/developit/mitt) used for event handlers. It is recommended to use {@linkcode BasemapSession.on}, {@linkcode BasemapSession.off} or {@linkcode BasemapSession.once} instead of `emitter.`\n */\n private emitter: any;\n\n /**\n * A handler that is used to automatically refresh the session when it expires.\n */\n private autoRefreshHandler: (() => void) | null = null;\n\n /**\n * Creates a new instance of the BaseSession class. Generally you should not create an instance of this class directly, but instead use the static methods to start a session or deserialize a session.\n *\n * You may need to create an instance of this class directly if you are not using the built in deserialize method.\n *\n * @param params - The parameters for the session.\n * @param params.startSessionUrl - The URL to start the session.\n * @param params.token - The token for the session.\n * @param params.styleFamily - The style family of the session.\n * @param params.authentication - The authentication manager or token used for the session.\n * @param params.expires - The expiration date of the session.\n * @param params.startTime - The start time of the session.\n * @param params.endTime - The end time of the session.\n * @param params.safetyMargin - The safety margin in milliseconds.\n * @param params.duration - Indicates if this is a test session.\n */\n constructor(params: IBasemapSessionParams) {\n this.startSessionUrl = params.startSessionUrl;\n this.token = params.token;\n this.styleFamily = params.styleFamily || \"arcgis\";\n this.authentication = params.authentication;\n this.duration = params.duration || DEFAULT_DURATION;\n this.startTime = params.startTime;\n this.endTime = params.endTime;\n this.expires = params.expires;\n this.safetyMargin = params.safetyMargin;\n this.expirationCheckInterval =\n Math.min(this.duration / 100, DEFAULT_CHECK_EXPIRATION_INTERVAL) * 1000;\n this.emitter = mitt();\n }\n\n /**\n * Checks if the session is expired. If it is expired, it emits an \"expired\" event and disables expiration time checking. The event will fire **before** the method returns true.\n *\n * @returns {boolean} - Returns true if the session is expired, otherwise false.\n */\n isSessionExpired() {\n if (this.isExpired) {\n this.disableCheckingExpirationTime();\n\n this.emitter.emit(\"expired\", {\n token: this.token,\n startTime: this.startTime,\n endTime: this.endTime,\n expires: this.expires\n });\n }\n\n return this.isExpired;\n }\n\n /**\n * Starts checking the expiration time of the session. This will check the expiration time immediately and then on an interval.\n * If the session is expired, it will emit an \"expired\" event.\n */\n enableCheckingExpirationTime() {\n const check = () => {\n this.isSessionExpired();\n };\n\n if (!this.expirationTimerId) {\n this.expirationTimerId = setInterval(\n check,\n // check every 10 seconds or 1/100th of the duration, whichever is smaller\n this.expirationCheckInterval\n ); // check immediately then on an interval\n }\n\n setTimeout(() => {\n check(); // check immediately after starting the interval\n }, 10);\n\n return this.expirationTimerId; // return the timer ID so it can be stopped later\n }\n\n /**\n * Stops checking the expiration time of the session. This will clear the `setInterval()` that was started by {@linkcode BaseSession.enableCheckingExpirationTime}.\n */\n disableCheckingExpirationTime() {\n if (this.expirationTimerId) {\n clearInterval(this.expirationTimerId);\n this.expirationTimerId = null;\n }\n }\n\n /**\n * Starts a new session using the provided parameters and returns an instance of the session class.\n *\n * @param params - The parameters for starting the session.\n * @param SessionClass - The class to use for the session.\n * @returns A promise that resolves to an instance of the session class.\n */\n protected static async startSession<T extends BaseSession>(\n {\n startSessionUrl,\n styleFamily = \"arcgis\",\n authentication,\n safetyMargin,\n duration = DEFAULT_DURATION,\n autoRefresh = false\n }: {\n startSessionUrl?: string;\n styleFamily?: StyleFamily;\n authentication: IAuthenticationManager | string;\n safetyMargin?: number;\n duration?: number;\n autoRefresh?: boolean;\n },\n SessionClass: new (params: IBasemapSessionParams) => T\n ): Promise<T> {\n if (duration < 10) {\n throw new Error(\"Session duration must be at least 10 seconds.\");\n }\n\n if (duration > 43200) {\n throw new Error(\n \"Session duration cannot exceed 12 hours (43200 seconds).\"\n );\n }\n\n const sessionResponse = await startNewSession({\n startSessionUrl,\n styleFamily,\n authentication,\n duration\n });\n const actualSafetyMargin = determineSafetyMargin(duration, safetyMargin);\n\n const session = new SessionClass({\n startSessionUrl: startSessionUrl,\n token: sessionResponse.sessionToken,\n styleFamily,\n authentication,\n safetyMargin: actualSafetyMargin,\n expires: new Date(sessionResponse.endTime - actualSafetyMargin * 1000),\n startTime: new Date(sessionResponse.startTime),\n endTime: new Date(sessionResponse.endTime),\n duration\n });\n\n session.enableCheckingExpirationTime();\n\n if (autoRefresh) {\n session.enableAutoRefresh();\n }\n\n return session as T;\n }\n\n /**\n * Indicates if the session is currently checking for expiration time.\n *\n * @returns {boolean} - Returns true if the session is checking for expiration time, otherwise false.\n */\n get checkingExpirationTime(): boolean {\n return !!this.expirationTimerId;\n }\n\n /**\n * Returns the number of seconds until the session is no longer valid rounded down. If the session is expired, it will return 0.\n */\n get secondsUntilExpiration(): number {\n return Math.floor(this.millisecondsUntilExpiration / 1000);\n }\n\n /**\n * Returns the number of milliseconds until the session token is no longer valid. If the session is expired, it will return 0.\n */\n get millisecondsUntilExpiration(): number {\n if (this.isExpired) {\n return 0;\n }\n\n const now = new Date();\n const millisecondsLeft = this.endTime.getTime() - now.getTime();\n\n return millisecondsLeft;\n }\n\n /**\n * Checks if the session is expired.\n *\n */\n get isExpired(): boolean {\n return this.expires < new Date();\n }\n\n /**\n * Gets the session token. If the session is expired, it will refresh the credentials and return the new token.\n *\n * @returns A promise that resolves to the session token.\n */\n getToken(): Promise<string> {\n if (this.isExpired) {\n return this.refreshCredentials().then(() => this.token);\n }\n\n return Promise.resolve(this.token);\n }\n\n /**\n * Indicates if the session can be refreshed. This is always true for this basemap sessions.\n *\n * @returns {boolean} - Always returns true.\n */\n get canRefresh(): boolean {\n return true;\n }\n\n /**\n * Indicates if the session is set to automatically refresh when it expires.\n *\n * @returns {boolean} - Returns true if auto-refresh is enabled, otherwise false.\n */\n get autoRefresh(): boolean {\n return !!this.autoRefreshHandler && !!this.expirationTimerId;\n }\n\n /**\n * Refreshes the session credentials by starting a new session.\n * This will emit a \"refreshed\" event with the previous and current session details.\n *\n * @returns A promise that resolves to the current instance of the session.\n */\n async refreshCredentials(): Promise<this> {\n if (this.pendingSession) {\n // if there is a pending session, wait for it to resolve\n await this.pendingSession;\n return this;\n }\n\n // @TODO switch this to structured clone when we upgrade to Node 20+ types so we don't have to parse the dates later\n const previous = JSON.parse(\n JSON.stringify({\n token: this.token,\n startTime: this.startTime,\n endTime: this.endTime,\n expires: this.expires\n })\n );\n\n try {\n this.pendingSession = startNewSession({\n startSessionUrl: this.startSessionUrl,\n styleFamily: this.styleFamily,\n authentication: this.authentication,\n duration: this.duration\n });\n\n const newSession = await this.pendingSession;\n\n this.pendingSession = null; // reset the pending session\n\n this.setToken(newSession.sessionToken);\n this.setStartTime(new Date(newSession.startTime));\n this.setEndTime(new Date(newSession.endTime));\n this.setExpires(new Date(newSession.endTime - this.safetyMargin * 1000));\n\n this.enableCheckingExpirationTime(); // restart checking expiration time after refreshing credentials\n\n this.emitter.emit(\"refreshed\", {\n previous: {\n token: previous.token,\n startTime: new Date(previous.startTime),\n endTime: new Date(previous.endTime),\n expires: new Date(previous.expires)\n },\n current: {\n token: this.token,\n startTime: this.startTime,\n endTime: this.endTime,\n expires: this.expires\n }\n });\n } catch (error) {\n this.emitter.emit(\"error\", error);\n throw error;\n }\n\n return this;\n }\n /**\n * Enables auto-refresh for the session. This will automatically refresh the session when it expires.\n * It will also start checking the expiration time of the session if it is not already started via {@linkcode BaseSession.enableCheckingExpirationTime}.\n */\n enableAutoRefresh() {\n if (!this.expirationTimerId) {\n this.enableCheckingExpirationTime();\n }\n\n this.autoRefreshHandler = () => {\n this.refreshCredentials().catch((error: Error) => {\n this.emitter.emit(\"error\", error);\n });\n };\n\n this.on(\"expired\", this.autoRefreshHandler);\n }\n\n /**\n * Disables auto-refresh for the session. This will stop automatically refreshing the session when it expires.\n * This will **not** stop checking the expiration time of the session. If you want to stop automated expiration\n * checking, call {@linkcode BaseSession.disableCheckingExpirationTime} after calling this method.\n */\n disableAutoRefresh() {\n if (this.autoRefreshHandler) {\n this.off(\"expired\", this.autoRefreshHandler);\n this.autoRefreshHandler = null;\n }\n }\n\n /**\n * Removes all event listeners and disables auto-refresh and expiration time checking. This is useful for cleaning up the session when it is no longer needed or replaced with a new session.\n */\n destroy() {\n this.disableAutoRefresh();\n this.disableCheckingExpirationTime();\n this.emitter.off(\"expired\");\n this.emitter.off(\"refreshed\");\n this.emitter.off(\"error\");\n this.emitter.off(\"*\");\n }\n\n /**\n * A handler that listens for an eventName and returns custom handler.\n *\n * @param event A string of what event to listen for.\n * @param handler A function of what to do when eventName was called.\n */\n on(event: \"refreshed\", handler: typeof BaseSession.refreshed): void;\n on(event: \"expired\", handler: typeof BaseSession.expired): void;\n on(event: \"error\", handler: typeof BaseSession.error): void;\n on(\n event: string,\n handler:\n | typeof BaseSession.refreshed\n | typeof BaseSession.expired\n | typeof BaseSession.error\n ) {\n this.emitter.on(event, handler);\n this.isSessionExpired(); // check if the session is expired immediately after adding the handler\n }\n\n /**\n * A handler that listens for an event once and returns a custom handler. Events listened to with this method cannot be removed with {@linkcode BaseSession.off}.\n *\n * @param event A string of what event to listen for.\n * @param handler A function of what to do when event was called.\n */\n once(event: \"refreshed\", handler: typeof BaseSession.refreshed): void;\n once(event: \"expired\", handler: typeof BaseSession.expired): void;\n once(event: \"error\", handler: typeof BaseSession.error): void;\n once(\n event: string,\n handler:\n | typeof BaseSession.refreshed\n | typeof BaseSession.expired\n | typeof BaseSession.error\n ) {\n const fn = (e: any) => {\n this.emitter.off(event, fn);\n handler(e);\n };\n\n this.emitter.on(event, fn);\n }\n\n /**\n * A handler that will remove a listener from a given event.\n *\n * @param event A string of what event to listen for.\n * @param handler A function of what to do when event was called.\n */\n off(event: \"refreshed\", handler: typeof BaseSession.refreshed): void;\n off(event: \"expired\", handler: typeof BaseSession.expired): void;\n off(event: \"error\", handler: typeof BaseSession.error): void;\n off(\n event: string,\n handler:\n | typeof BaseSession.refreshed\n | typeof BaseSession.expired\n | typeof BaseSession.error\n ) {\n this.emitter.off(event, handler);\n }\n\n /**\n * These private methods are used to set the internal state of the session.\n */\n private setToken(token: string) {\n (this as Writable<typeof this>).token = token;\n }\n private setStartTime(startTime: Date) {\n (this as Writable<typeof this>).startTime = startTime;\n }\n private setEndTime(endTime: Date) {\n (this as Writable<typeof this>).endTime = endTime;\n }\n private setExpires(expires: Date) {\n (this as Writable<typeof this>).expires = expires;\n }\n}\n","export default function(n){return{all:n=n||new Map,on:function(t,e){var i=n.get(t);i?i.push(e):n.set(t,[e])},off:function(t,e){var i=n.get(t);i&&(e?i.splice(i.indexOf(e)>>>0,1):n.set(t,[]))},emit:function(t,e){var i=n.get(t);i&&i.slice().map(function(n){n(e)}),(i=n.get(\"*\"))&&i.slice().map(function(n){n(t,e)})}}}\n//# sourceMappingURL=mitt.mjs.map\n","import { DEFAULT_SAFETY_MARGIN } from \"./defaults.js\";\n\nexport function determineSafetyMargin(\n duration: number | undefined,\n safetyMargin: number | undefined\n): number {\n if (safetyMargin) {\n return safetyMargin;\n }\n\n // common cases are\n // duration is 60 seconds, this will return a 1 second safety margin\n // duration is 43200 seconds, this will return a 300 second (5 minutes) safety margin\n return Math.min(Math.max(duration / 100, 1), DEFAULT_SAFETY_MARGIN);\n}\n","import {\n BaseSession,\n IBasemapSessionParams,\n IStartSessionParams\n} from \"./BaseSession.js\";\nimport { DEFAULT_START_BASEMAP_STYLE_SESSION_URL } from \"./utils/defaults.js\";\n\n/**\n * `BasemapStyleSession` is a class that extends {@linkcode BaseSession} to manage sessions\n * for basemap styles. It provides methods to {@linkcode BasemapStyleSession.start} a new session\n * which should be used instead of constructing a new instance directly.\n *\n * @class BasemapStyleSession\n * @extends BaseSession\n */\nexport class BasemapStyleSession extends BaseSession {\n /**\n * Creates an instance of `BasemapStyleSession`. Constructing `BasemapStyleSession` directly is discouraged.\n * Instead, use the static method {@linkcode BasemapStyleSession.start} to start a new session.\n */\n constructor(params: IBasemapSessionParams) {\n super(params);\n }\n\n /**\n * Starts a new basemap style session.\n */\n static async start(params: IStartSessionParams) {\n return BaseSession.startSession<BasemapStyleSession>(\n {\n ...params,\n startSessionUrl:\n params?.startSessionUrl || DEFAULT_START_BASEMAP_STYLE_SESSION_URL\n },\n BasemapStyleSession as new (\n params: IBasemapSessionParams\n ) => BasemapStyleSession\n );\n }\n}\n"],"names":["DEFAULT_START_BASEMAP_STYLE_SESSION_URL","DEFAULT_DURATION","startNewSession","startSessionUrl","authentication","styleFamily","duration","request","httpMethod","params","durationSeconds","BaseSession","constructor","n","this","expirationTimerId","pendingSession","autoRefreshHandler","token","startTime","endTime","expires","safetyMargin","expirationCheckInterval","Math","min","emitter","all","Map","on","t","e","i","get","push","set","off","splice","indexOf","emit","slice","map","isSessionExpired","isExpired","disableCheckingExpirationTime","enableCheckingExpirationTime","check","setInterval","setTimeout","clearInterval","startSession","autoRefresh","SessionClass","Error","sessionResponse","actualSafetyMargin","max","determineSafetyMargin","session","sessionToken","Date","enableAutoRefresh","checkingExpirationTime","secondsUntilExpiration","floor","millisecondsUntilExpiration","now","getTime","getToken","refreshCredentials","then","Promise","resolve","canRefresh","previous","JSON","parse","stringify","newSession","setToken","setStartTime","setEndTime","setExpires","current","error","catch","disableAutoRefresh","destroy","event","handler","once","fn","expired","refreshed","BasemapStyleSession","super","start","Object","assign"],"mappings":"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","x_google_ignoreList":[3]}
@@ -6,11 +6,10 @@ const startNewSession_js_1 = require("./utils/startNewSession.js");
6
6
  const detemineSafetyMargin_js_1 = require("./utils/detemineSafetyMargin.js");
7
7
  const defaults_js_1 = require("./utils/defaults.js");
8
8
  /**
9
- * The base class for all basemap sessions. This class implements the {@linkcode IAuthenticationManager} interface and provides methods to start, refresh, and check the expiration of a session.
10
- * This is not intendet to be used directly, but instead is extended by other classes such as {@linkcode BasemapStyleSession} and {@linkcode StaticBasemapTilesSession}.
9
+ * The base class for all basemap sessions. This class implements the {@linkcode @esri/arcgis-rest-request!IAuthenticationManager} interface and provides methods to start, refresh, and check the expiration of a session.
10
+ * This is not intended to be used directly, but instead is extended by other classes such as {@linkcode BasemapStyleSession} .
11
11
  *
12
12
  * @abstract
13
- * @implements {IAuthenticationManager}
14
13
  */
15
14
  class BaseSession {
16
15
  /**
@@ -34,6 +33,10 @@ class BaseSession {
34
33
  * The ID of the timer used to check the expiration time of the session.
35
34
  */
36
35
  this.expirationTimerId = null;
36
+ /**
37
+ * A pending session that is being refreshed. This is used to prevent multiple refreshes from happening at the same time.
38
+ */
39
+ this.pendingSession = null;
37
40
  /**
38
41
  * A handler that is used to automatically refresh the session when it expires.
39
42
  */
@@ -52,12 +55,13 @@ class BaseSession {
52
55
  this.emitter = (0, mitt_1.default)();
53
56
  }
54
57
  /**
55
- * Checks if the session is expired. If it is expired, it emits an "expired" event. The event will fire **before** the method returns true.
58
+ * Checks if the session is expired. If it is expired, it emits an "expired" event and disables expiration time checking. The event will fire **before** the method returns true.
56
59
  *
57
60
  * @returns {boolean} - Returns true if the session is expired, otherwise false.
58
61
  */
59
62
  isSessionExpired() {
60
63
  if (this.isExpired) {
64
+ this.disableCheckingExpirationTime();
61
65
  this.emitter.emit("expired", {
62
66
  token: this.token,
63
67
  startTime: this.startTime,
@@ -71,14 +75,14 @@ class BaseSession {
71
75
  * Starts checking the expiration time of the session. This will check the expiration time immediately and then on an interval.
72
76
  * If the session is expired, it will emit an "expired" event.
73
77
  */
74
- startCheckingExpirationTime() {
78
+ enableCheckingExpirationTime() {
75
79
  const check = () => {
76
80
  this.isSessionExpired();
77
81
  };
78
82
  if (!this.expirationTimerId) {
79
83
  this.expirationTimerId = setInterval(check,
80
84
  // check every 10 seconds or 1/100th of the duration, whichever is smaller
81
- this.expirationCheckInterval); // check immediatly then on an interval
85
+ this.expirationCheckInterval); // check immediately then on an interval
82
86
  }
83
87
  setTimeout(() => {
84
88
  check(); // check immediately after starting the interval
@@ -86,22 +90,14 @@ class BaseSession {
86
90
  return this.expirationTimerId; // return the timer ID so it can be stopped later
87
91
  }
88
92
  /**
89
- * Stops checking the expiration time of the session. This will clear the interval that was set by {@linkcode BaseSession.startCheckingExpirationTime}.
93
+ * Stops checking the expiration time of the session. This will clear the `setInterval()` that was started by {@linkcode BaseSession.enableCheckingExpirationTime}.
90
94
  */
91
- stopCheckingExpirationTime() {
95
+ disableCheckingExpirationTime() {
92
96
  if (this.expirationTimerId) {
93
97
  clearInterval(this.expirationTimerId);
94
98
  this.expirationTimerId = null;
95
99
  }
96
100
  }
97
- /**
98
- * Indicates if the session is currently checking for expiration time.
99
- *
100
- * @returns {boolean} - Returns true if the session is checking for expiration time, otherwise false.
101
- */
102
- get checkingExpirationTime() {
103
- return !!this.expirationTimerId;
104
- }
105
101
  /**
106
102
  * Starts a new session using the provided parameters and returns an instance of the session class.
107
103
  *
@@ -109,7 +105,13 @@ class BaseSession {
109
105
  * @param SessionClass - The class to use for the session.
110
106
  * @returns A promise that resolves to an instance of the session class.
111
107
  */
112
- static async startSession({ startSessionUrl, styleFamily = "arcgis", authentication, safetyMargin, duration = defaults_js_1.DEFAULT_DURATION, autoRefresh = true }, SessionClass) {
108
+ static async startSession({ startSessionUrl, styleFamily = "arcgis", authentication, safetyMargin, duration = defaults_js_1.DEFAULT_DURATION, autoRefresh = false }, SessionClass) {
109
+ if (duration < 10) {
110
+ throw new Error("Session duration must be at least 10 seconds.");
111
+ }
112
+ if (duration > 43200) {
113
+ throw new Error("Session duration cannot exceed 12 hours (43200 seconds).");
114
+ }
113
115
  const sessionResponse = await (0, startNewSession_js_1.startNewSession)({
114
116
  startSessionUrl,
115
117
  styleFamily,
@@ -128,12 +130,37 @@ class BaseSession {
128
130
  endTime: new Date(sessionResponse.endTime),
129
131
  duration
130
132
  });
131
- session.startCheckingExpirationTime();
133
+ session.enableCheckingExpirationTime();
132
134
  if (autoRefresh) {
133
- session.startAutoRefresh();
135
+ session.enableAutoRefresh();
134
136
  }
135
137
  return session;
136
138
  }
139
+ /**
140
+ * Indicates if the session is currently checking for expiration time.
141
+ *
142
+ * @returns {boolean} - Returns true if the session is checking for expiration time, otherwise false.
143
+ */
144
+ get checkingExpirationTime() {
145
+ return !!this.expirationTimerId;
146
+ }
147
+ /**
148
+ * Returns the number of seconds until the session is no longer valid rounded down. If the session is expired, it will return 0.
149
+ */
150
+ get secondsUntilExpiration() {
151
+ return Math.floor(this.millisecondsUntilExpiration / 1000);
152
+ }
153
+ /**
154
+ * Returns the number of milliseconds until the session token is no longer valid. If the session is expired, it will return 0.
155
+ */
156
+ get millisecondsUntilExpiration() {
157
+ if (this.isExpired) {
158
+ return 0;
159
+ }
160
+ const now = new Date();
161
+ const millisecondsLeft = this.endTime.getTime() - now.getTime();
162
+ return millisecondsLeft;
163
+ }
137
164
  /**
138
165
  * Checks if the session is expired.
139
166
  *
@@ -153,7 +180,7 @@ class BaseSession {
153
180
  return Promise.resolve(this.token);
154
181
  }
155
182
  /**
156
- * Indicates if the session can be refreshed. This is always true for this class.
183
+ * Indicates if the session can be refreshed. This is always true for this basemap sessions.
157
184
  *
158
185
  * @returns {boolean} - Always returns true.
159
186
  */
@@ -175,6 +202,11 @@ class BaseSession {
175
202
  * @returns A promise that resolves to the current instance of the session.
176
203
  */
177
204
  async refreshCredentials() {
205
+ if (this.pendingSession) {
206
+ // if there is a pending session, wait for it to resolve
207
+ await this.pendingSession;
208
+ return this;
209
+ }
178
210
  // @TODO switch this to structured clone when we upgrade to Node 20+ types so we don't have to parse the dates later
179
211
  const previous = JSON.parse(JSON.stringify({
180
212
  token: this.token,
@@ -183,16 +215,19 @@ class BaseSession {
183
215
  expires: this.expires
184
216
  }));
185
217
  try {
186
- const newSession = await (0, startNewSession_js_1.startNewSession)({
218
+ this.pendingSession = (0, startNewSession_js_1.startNewSession)({
187
219
  startSessionUrl: this.startSessionUrl,
188
220
  styleFamily: this.styleFamily,
189
221
  authentication: this.authentication,
190
222
  duration: this.duration
191
223
  });
224
+ const newSession = await this.pendingSession;
225
+ this.pendingSession = null; // reset the pending session
192
226
  this.setToken(newSession.sessionToken);
193
227
  this.setStartTime(new Date(newSession.startTime));
194
228
  this.setEndTime(new Date(newSession.endTime));
195
229
  this.setExpires(new Date(newSession.endTime - this.safetyMargin * 1000));
230
+ this.enableCheckingExpirationTime(); // restart checking expiration time after refreshing credentials
196
231
  this.emitter.emit("refreshed", {
197
232
  previous: {
198
233
  token: previous.token,
@@ -216,11 +251,11 @@ class BaseSession {
216
251
  }
217
252
  /**
218
253
  * Enables auto-refresh for the session. This will automatically refresh the session when it expires.
219
- * It will also start checking the expiration time of the session if it is not already started via {@linkcode BaseSession.startCheckingExpirationTime}.
254
+ * It will also start checking the expiration time of the session if it is not already started via {@linkcode BaseSession.enableCheckingExpirationTime}.
220
255
  */
221
- startAutoRefresh() {
256
+ enableAutoRefresh() {
222
257
  if (!this.expirationTimerId) {
223
- this.startCheckingExpirationTime();
258
+ this.enableCheckingExpirationTime();
224
259
  }
225
260
  this.autoRefreshHandler = () => {
226
261
  this.refreshCredentials().catch((error) => {
@@ -232,27 +267,38 @@ class BaseSession {
232
267
  /**
233
268
  * Disables auto-refresh for the session. This will stop automatically refreshing the session when it expires.
234
269
  * This will **not** stop checking the expiration time of the session. If you want to stop automated expiration
235
- * checking, call {@linkcode BaseSession.stopCheckingExpirationTime} after calling this method.
270
+ * checking, call {@linkcode BaseSession.disableCheckingExpirationTime} after calling this method.
236
271
  */
237
- stopAutoRefresh() {
272
+ disableAutoRefresh() {
238
273
  if (this.autoRefreshHandler) {
239
274
  this.off("expired", this.autoRefreshHandler);
240
275
  this.autoRefreshHandler = null;
241
276
  }
242
277
  }
243
- on(eventName, handler) {
244
- this.emitter.on(eventName, handler);
278
+ /**
279
+ * Removes all event listeners and disables auto-refresh and expiration time checking. This is useful for cleaning up the session when it is no longer needed or replaced with a new session.
280
+ */
281
+ destroy() {
282
+ this.disableAutoRefresh();
283
+ this.disableCheckingExpirationTime();
284
+ this.emitter.off("expired");
285
+ this.emitter.off("refreshed");
286
+ this.emitter.off("error");
287
+ this.emitter.off("*");
288
+ }
289
+ on(event, handler) {
290
+ this.emitter.on(event, handler);
245
291
  this.isSessionExpired(); // check if the session is expired immediately after adding the handler
246
292
  }
247
- once(eventName, handler) {
293
+ once(event, handler) {
248
294
  const fn = (e) => {
249
- this.emitter.off(eventName, fn);
295
+ this.emitter.off(event, fn);
250
296
  handler(e);
251
297
  };
252
- this.emitter.on(eventName, fn);
298
+ this.emitter.on(event, fn);
253
299
  }
254
- off(eventName, handler) {
255
- this.emitter.off(eventName, handler);
300
+ off(event, handler) {
301
+ this.emitter.off(event, handler);
256
302
  }
257
303
  /**
258
304
  * These private methods are used to set the internal state of the session.
@@ -276,27 +322,27 @@ exports.BaseSession = BaseSession;
276
322
  /**
277
323
  * Event handler for when an error occurs during session management.
278
324
  */
279
- BaseSession.error = function error(e) { }; // eslint-disable-line @typescript-eslint/no-empty-function
325
+ BaseSession.error = function error(e) { };
280
326
  // the static methods for event handlers are used to provide doc via typedoc and do not need to be tested.
281
327
  /* istanbul ignore next -- @preserve */
282
328
  /**
283
- * Event handler for when a session expires and the `token` it no longer valid.
329
+ * Event handler for when the current session expires and the session token it no longer valid. This event will only fire if {@linkcode BaseSession.checkingExpirationTime}
330
+ * is `true` which is the default. Once this event fires, {@linkcode BaseSession.checkingExpirationTime} will be set to `false` until the session is refreshed with
331
+ * {@linkcode BaseSession.refreshCredentials}.
284
332
  *
285
333
  * @event expired
286
- * @param e - The parameters for the expired event.
287
334
  * @param e.token - The session token that expired.
288
335
  * @param e.startTime - The start time of the session.
289
336
  * @param e.endTime - The end time of the session.
290
337
  * @param e.expires - The expiration time of the session.
291
338
  */
292
- BaseSession.expired = function expired(e) { }; // eslint-disable-line @typescript-eslint/no-empty-function
339
+ BaseSession.expired = function expired(e) { };
293
340
  // the static methods for event handlers are used to provide doc via typedoc and do not need to be tested.
294
341
  /* istanbul ignore next -- @preserve */
295
342
  /**
296
343
  * Event handler for when a session refreshes and a new `token` is available.
297
344
  *
298
345
  * @event refreshed
299
- * @param e. - The parameters for the refreshed event.
300
346
  * @param e.previous - The previous session details.
301
347
  * @param e.previous.token - The previous session token.
302
348
  * @param e.previous.startTime - The start time of the previous session.
@@ -308,5 +354,5 @@ BaseSession.expired = function expired(e) { }; // eslint-disable-line @typescrip
308
354
  * @param e.current.endTime - The end time of the current session.
309
355
  * @param e.current.expires - The expiration time of the current token.
310
356
  */
311
- BaseSession.refreshed = function refreshed(e) { }; // eslint-disable-line @typescript-eslint/no-empty-function
357
+ BaseSession.refreshed = function refreshed(e) { };
312
358
  //# sourceMappingURL=BaseSession.js.map