UNPKG

@furystack/shades

Version:

Google Authentication Provider for FuryStack

118 lines 6.16 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { Injectable } from '@furystack/inject'; import { deserializeQueryString as defaultDeserializeQueryString, serializeToQueryString as defaultSerializeToQueryString, } from '@furystack/rest'; import { ObservableValue } from '@furystack/utils'; let LocationService = class LocationService { serializeToQueryString; deserializeQueryString; constructor(serializeToQueryString = defaultSerializeToQueryString, deserializeQueryString = defaultDeserializeQueryString) { this.serializeToQueryString = serializeToQueryString; this.deserializeQueryString = deserializeQueryString; window.addEventListener('popstate', this.popStateListener); window.addEventListener('hashchange', this.hashChangeListener); this.onDeserializedLocationSearchChanged = new ObservableValue(this.deserializeQueryString(location.search)); this.originalPushState = window.history.pushState.bind(window.history); window.history.pushState = ((...args) => { this.originalPushState(...args); this.updateState(); }).bind(this); this.originalReplaceState = window.history.replaceState.bind(window.history); window.history.replaceState = ((...args) => { this.originalReplaceState(...args); this.updateState(); }).bind(this); } originalPushState; originalReplaceState; [Symbol.dispose]() { window.removeEventListener('popstate', this.popStateListener); window.removeEventListener('hashchange', this.hashChangeListener); this.onLocationPathChanged[Symbol.dispose](); this.onLocationSearchChanged[Symbol.dispose](); this.onDeserializedLocationSearchChanged[Symbol.dispose](); this.locationDeserializerObserver[Symbol.dispose](); window.history.pushState = this.originalPushState; window.history.replaceState = this.originalReplaceState; } /** * Observable value that will be updated when the location pathname (e.g. /page/1) changes */ onLocationPathChanged = new ObservableValue(new URL(location.href).pathname); /** * Observable value that will be updated when the location hash (e.g. #hash) changes */ onLocationHashChanged = new ObservableValue(location.hash.replace('#', '')); /** * Observable value that will be updated when the location search (e.g. ?search=1) changes */ onLocationSearchChanged = new ObservableValue(location.search); onDeserializedLocationSearchChanged; locationDeserializerObserver = this.onLocationSearchChanged.subscribe((search) => { this.onDeserializedLocationSearchChanged.setValue(this.deserializeQueryString(search)); }); updateState = (() => { this.onLocationPathChanged.setValue(location.pathname); this.onLocationHashChanged.setValue(location.hash.replace('#', '')); this.onLocationSearchChanged.setValue(location.search); }).bind(this); searchParamObservables = new Map(); /** * * @param key The search param key (e.g. ?search=1 -> search) * @param defaultValue The default value if not provided * @returns An observable with the current value (or default value) of the search param */ useSearchParam(key, defaultValue) { const existing = this.searchParamObservables.get(key); if (!existing) { const currentDeserialized = this.onDeserializedLocationSearchChanged.getValue(); const actualValue = Object.prototype.hasOwnProperty.call(currentDeserialized, key) ? currentDeserialized[key] : defaultValue; const newObservable = new ObservableValue(actualValue); this.searchParamObservables.set(key, newObservable); newObservable.subscribe((value) => { const currentQueryStringObject = this.onDeserializedLocationSearchChanged.getValue(); if (currentQueryStringObject[key] !== value) { const params = this.serializeToQueryString({ ...currentQueryStringObject, [key]: value }); const newUrl = `${location.pathname}?${params}`; history.pushState({}, '', newUrl); } }); this.onDeserializedLocationSearchChanged.subscribe((search) => { const value = search[key] ?? defaultValue; this.searchParamObservables.get(key)?.setValue(value); }); return newObservable; } return existing; } popStateListener = (_ev) => { this.updateState(); }; hashChangeListener = ((_ev) => { this.updateState(); }).bind(this); }; LocationService = __decorate([ Injectable({ lifetime: 'singleton' }), __metadata("design:paramtypes", [Object, Object]) ], LocationService); export { LocationService }; export const useCustomSearchStateSerializer = (injector, serialize, deserialize) => { if (injector.cachedSingletons.has(LocationService)) { throw new Error('useCustomSearchStateSerializer must be called before the LocationService is instantiated'); } const locationService = new LocationService(serialize, deserialize); injector.setExplicitInstance(locationService, LocationService); }; //# sourceMappingURL=location-service.js.map