From f5c3b6e3d61bceba12336c0c087166e8d231935f Mon Sep 17 00:00:00 2001 From: bobrimperator Date: Sat, 28 Dec 2024 02:34:33 +0100 Subject: [PATCH] feat(ember-simple-auth): implement internal EventTarget --- packages/ember-simple-auth/package.json | 4 +- .../src/-internals/event-target.ts | 42 +++++++++++++ .../src/authenticators/base.ts | 21 +++---- .../ember-simple-auth/src/internal-session.js | 28 ++++----- .../src/session-stores/base.ts | 23 ++------ .../src/session-stores/local-storage.ts | 9 ++- .../src/session-stores/session-storage.ts | 9 ++- packages/test-app/package.json | 2 +- pnpm-lock.yaml | 59 +------------------ 9 files changed, 78 insertions(+), 119 deletions(-) create mode 100644 packages/ember-simple-auth/src/-internals/event-target.ts diff --git a/packages/ember-simple-auth/package.json b/packages/ember-simple-auth/package.json index dd86b868b..59ccaea45 100644 --- a/packages/ember-simple-auth/package.json +++ b/packages/ember-simple-auth/package.json @@ -62,8 +62,7 @@ "prettier": "3.3.3", "rollup": "4.25.0", "rollup-plugin-copy": "3.5.0", - "typescript": "^5.7.2", - "typescript-event-target": "^1.1.1" + "typescript": "^5.7.2" }, "publishConfig": { "registry": "https://registry.npmjs.org" @@ -79,7 +78,6 @@ "./initializers/ember-simple-auth.js": "./dist/_app_/initializers/ember-simple-auth.js", "./services/session.js": "./dist/_app_/services/session.js", "./session-stores/application.js": "./dist/_app_/session-stores/application.js", - "./utils/inject.js": "./dist/_app_/utils/inject.js", "./utils/is-fastboot.js": "./dist/_app_/utils/is-fastboot.js", "./utils/location.js": "./dist/_app_/utils/location.js", "./utils/objects-are-equal.js": "./dist/_app_/utils/objects-are-equal.js" diff --git a/packages/ember-simple-auth/src/-internals/event-target.ts b/packages/ember-simple-auth/src/-internals/event-target.ts new file mode 100644 index 000000000..1e38152f7 --- /dev/null +++ b/packages/ember-simple-auth/src/-internals/event-target.ts @@ -0,0 +1,42 @@ +import EmberObject from '@ember/object'; +import Evented from '@ember/object/evented'; + +export type EventListener = (event: Events[Event]) => void; + +type ValueIsEvent = { + [key in keyof T]: CustomEvent; +}; + +/** + * This module exists to act as a 'shim' between Native EventTarget API, which unfortunately can't be used due to Fastboot's node environment not providing it. + * + * It more-or-less implements the same API as an EventTarget would have but on top of Evented mixin instead. + */ +export default class EsaEventTarget> extends EmberObject.extend( + Evented +) { + addEventListener( + event: Event, + cb: EventListener + ) { + (this as any).on(event, cb); + } + + removeEventListener( + event: Event, + cb: EventListener + ) { + (this as any).off(event, cb); + } + + dispatchEvent(event: Event, value: Events[Event]['detail']) { + // let customEvent: CustomEvent; + // if (value) { + // customEvent = new CustomEvent(event, { detail: value }); + // } else { + // customEvent = new CustomEvent(event); + // } + + (this as any).trigger(event, { detail: value }); + } +} diff --git a/packages/ember-simple-auth/src/authenticators/base.ts b/packages/ember-simple-auth/src/authenticators/base.ts index c9969910b..e03df04d1 100644 --- a/packages/ember-simple-auth/src/authenticators/base.ts +++ b/packages/ember-simple-auth/src/authenticators/base.ts @@ -1,12 +1,12 @@ import EmberObject from '@ember/object'; -import { TypedEventTarget, type TypedEventListener } from 'typescript-event-target'; +import EsaEventTarget, { type EventListener } from '../-internals/event-target'; export interface AuthenticatorEvents { sessionDataUpdated: CustomEvent; sessionDataInvalidated: CustomEvent; } -class AuthenticatorEventTarget extends TypedEventTarget {} +class AuthenticatorEventTarget extends EsaEventTarget {} /** The base class for all authenticators. __This serves as a starting point for @@ -175,29 +175,22 @@ export default class EsaBaseAuthenticator extends EmberObject { on( event: Event, - cb: TypedEventListener + cb: EventListener ) { - this.authenticatorEvents.addEventListener(event, cb); + this.authenticatorEvents.addEventListener(event, cb as any); } off( event: Event, - cb: TypedEventListener + cb: EventListener ) { - this.authenticatorEvents.removeEventListener(event, cb); + this.authenticatorEvents.removeEventListener(event, cb as any); } trigger( event: Event, value: AuthenticatorEvents[Event]['detail'] ) { - let customEvent; - if (value) { - customEvent = new CustomEvent(event, { detail: value }); - } else { - customEvent = new CustomEvent(event); - } - - this.authenticatorEvents.dispatchTypedEvent(event, customEvent); + this.authenticatorEvents.dispatchEvent(event, value); } } diff --git a/packages/ember-simple-auth/src/internal-session.js b/packages/ember-simple-auth/src/internal-session.js index 66be3a705..45e832200 100644 --- a/packages/ember-simple-auth/src/internal-session.js +++ b/packages/ember-simple-auth/src/internal-session.js @@ -1,11 +1,12 @@ import { isEmpty, isNone } from '@ember/utils'; import ObjectProxy from '@ember/object/proxy'; -import { set } from '@ember/object'; +import { action, set } from '@ember/object'; import { debug, assert } from '@ember/debug'; import { getOwner, setOwner } from '@ember/application'; import { isTesting } from '@embroider/macros'; +import EsaEventTarget from './-internals/event-target'; -class SessionEventTarget extends EventTarget {} +class SessionEventTarget extends EsaEventTarget {} /** __An internal implementation of Session. Communicates with stores and emits events.__ @@ -97,7 +98,7 @@ export default ObjectProxy.extend({ let authenticator = this._lookupAuthenticator(this.authenticator); return authenticator.invalidate(this.content.authenticated, ...arguments).then( () => { - authenticator.off('sessionDataUpdated', this._onSessionDataUpdated.bind(this)); + authenticator.off('sessionDataUpdated', this._onSessionDataUpdated); this._busy = false; return this._clear(true); }, @@ -217,17 +218,17 @@ export default ObjectProxy.extend({ _bindToAuthenticatorEvents() { const authenticator = this._lookupAuthenticator(this.authenticator); - authenticator.on('sessionDataUpdated', this._onSessionDataUpdated.bind(this)); - authenticator.on('sessionDataInvalidated', this._onSessionDataInvalidated.bind(this)); + authenticator.on('sessionDataUpdated', this._onSessionDataUpdated); + authenticator.on('sessionDataInvalidated', this._onSessionDataInvalidated); }, - _onSessionDataUpdated({ detail: content }) { + _onSessionDataUpdated: action(function ({ detail: content }) { this._setup(this.authenticator, content); - }, + }), - _onSessionDataInvalidated() { + _onSessionDataInvalidated: action(function () { this._clear(true); - }, + }), _bindToStoreEvents() { this.store.on('sessionDataUpdated', ({ detail: content }) => { @@ -282,13 +283,6 @@ export default ObjectProxy.extend({ }, trigger(event, value) { - let customEvent; - if (value) { - customEvent = new CustomEvent(event, { detail: value }); - } else { - customEvent = new CustomEvent(event); - } - - this.sessionEvents.dispatchEvent(customEvent); + this.sessionEvents.dispatchEvent(event, value); }, }); diff --git a/packages/ember-simple-auth/src/session-stores/base.ts b/packages/ember-simple-auth/src/session-stores/base.ts index ad1c86d68..aa79c0429 100644 --- a/packages/ember-simple-auth/src/session-stores/base.ts +++ b/packages/ember-simple-auth/src/session-stores/base.ts @@ -1,11 +1,11 @@ import EmberObject from '@ember/object'; -import { TypedEventTarget, type TypedEventListener } from 'typescript-event-target'; +import EsaEventTarget, { type EventListener } from '../-internals/event-target'; export interface SessionEvents { sessionDataUpdated: CustomEvent; } -class SessionStoreEventTarget extends TypedEventTarget {} +class SessionStoreEventTarget extends EsaEventTarget {} /** The base class for all session stores. __This serves as a starting point for @@ -79,28 +79,15 @@ export default class EsaBaseSessionStore extends EmberObject { return Promise.reject(); } - on( - event: Event, - cb: TypedEventListener - ) { + on(event: Event, cb: EventListener) { this.sessionStoreEvents.addEventListener(event, cb); } - off( - event: Event, - cb: TypedEventListener - ) { + off(event: Event, cb: EventListener) { this.sessionStoreEvents.removeEventListener(event, cb); } trigger(event: Event, value: SessionEvents[Event]['detail']) { - let customEvent; - if (value) { - customEvent = new CustomEvent(event, { detail: value }); - } else { - customEvent = new CustomEvent(event); - } - - this.sessionStoreEvents.dispatchTypedEvent(event, customEvent); + this.sessionStoreEvents.dispatchEvent(event, value); } } diff --git a/packages/ember-simple-auth/src/session-stores/local-storage.ts b/packages/ember-simple-auth/src/session-stores/local-storage.ts index a9dae5528..9fd266496 100644 --- a/packages/ember-simple-auth/src/session-stores/local-storage.ts +++ b/packages/ember-simple-auth/src/session-stores/local-storage.ts @@ -1,8 +1,8 @@ -import { bind } from '@ember/runloop'; import { getOwner } from '@ember/application'; import BaseStore from './base'; import objectsAreEqual from '../utils/objects-are-equal'; import isFastBoot from '../utils/is-fastboot'; +import { action } from '@ember/object'; /** Session store that persists data in the browser's `localStorage`. @@ -35,7 +35,6 @@ export default class LocalStorageStore extends BaseStore { key = 'ember_simple_auth-session'; _isFastBoot: boolean = false; - _boundHandler: (e: any) => void; _lastData: Record | null = null; constructor(owner: any) { @@ -44,15 +43,14 @@ export default class LocalStorageStore extends BaseStore { this._isFastBoot = this.hasOwnProperty('_isFastBoot') ? this._isFastBoot : isFastBoot(getOwner(this)); - this._boundHandler = bind(this, this._handleStorageEvent); if (!this.get('_isFastBoot')) { - window.addEventListener('storage', this._boundHandler); + window.addEventListener('storage', this._handleStorageEvent); } } willDestroy() { if (!this.get('_isFastBoot')) { - window.removeEventListener('storage', this._boundHandler); + window.removeEventListener('storage', this._handleStorageEvent); } } @@ -104,6 +102,7 @@ export default class LocalStorageStore extends BaseStore { return Promise.resolve(); } + @action _handleStorageEvent(e: StorageEvent) { if (e.key === this.get('key')) { this.restore().then(data => { diff --git a/packages/ember-simple-auth/src/session-stores/session-storage.ts b/packages/ember-simple-auth/src/session-stores/session-storage.ts index db9aadcf7..e1478870f 100644 --- a/packages/ember-simple-auth/src/session-stores/session-storage.ts +++ b/packages/ember-simple-auth/src/session-stores/session-storage.ts @@ -1,8 +1,8 @@ -import { bind } from '@ember/runloop'; import { getOwner } from '@ember/application'; import BaseStore from './base'; import objectsAreEqual from '../utils/objects-are-equal'; import isFastBoot from '../utils/is-fastboot'; +import { action } from '@ember/object'; /** Session store that persists data in the browser's `sessionStorage`. @@ -30,7 +30,6 @@ export default class SessionStorageStore extends BaseStore { */ key = 'ember_simple_auth-session'; _isFastBoot: boolean = false; - _boundHandler: (e: any) => void; _lastData: Record | null = null; constructor(owner: any) { @@ -39,15 +38,14 @@ export default class SessionStorageStore extends BaseStore { this._isFastBoot = this.hasOwnProperty('_isFastBoot') ? this._isFastBoot : isFastBoot(getOwner(this)); - this._boundHandler = bind(this, this._handleStorageEvent); if (!this.get('_isFastBoot')) { - window.addEventListener('storage', this._boundHandler); + window.addEventListener('storage', this._handleStorageEvent); } } willDestroy() { if (!this.get('_isFastBoot')) { - window.removeEventListener('storage', bind(this, this._handleStorageEvent)); + window.removeEventListener('storage', this._handleStorageEvent); } } @@ -99,6 +97,7 @@ export default class SessionStorageStore extends BaseStore { return Promise.resolve(); } + @action _handleStorageEvent(e: StorageEvent) { if (e.key === this.get('key')) { this.restore().then(data => { diff --git a/packages/test-app/package.json b/packages/test-app/package.json index bb354e362..260239c3a 100644 --- a/packages/test-app/package.json +++ b/packages/test-app/package.json @@ -48,7 +48,7 @@ "ember-maybe-import-regenerator": "1.0.0", "ember-qunit": "7.0.0", "ember-resolver": "11.0.1", - "ember-simple-auth": "6.1.0", + "ember-simple-auth": "workspace:*", "ember-source": "5.12.0", "ember-source-channel-url": "3.0.0", "ember-try": "3.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f742fc738..e785cd53c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -322,9 +322,6 @@ importers: typescript: specifier: ^5.7.2 version: 5.7.2 - typescript-event-target: - specifier: ^1.1.1 - version: 1.1.1 packages/test-app: dependencies: @@ -426,8 +423,8 @@ importers: specifier: 11.0.1 version: 11.0.1(ember-source@5.12.0(@glimmer/component@1.1.2(@babel/core@7.26.0))(@glint/template@1.5.0)(rsvp@4.8.5)(webpack@5.96.1)) ember-simple-auth: - specifier: 6.1.0 - version: 6.1.0(@babel/core@7.26.0)(@ember/test-helpers@3.3.1(@babel/core@7.26.0)(@glint/template@1.5.0)(ember-source@5.12.0(@glimmer/component@1.1.2(@babel/core@7.26.0))(@glint/template@1.5.0)(rsvp@4.8.5)(webpack@5.96.1))(webpack@5.96.1))(@glint/template@1.5.0)(eslint@8.57.1) + specifier: workspace:* + version: link:../ember-simple-auth ember-source: specifier: 5.12.0 version: 5.12.0(@glimmer/component@1.1.2(@babel/core@7.26.0))(@glint/template@1.5.0)(rsvp@4.8.5)(webpack@5.96.1) @@ -9332,9 +9329,6 @@ packages: typedarray-to-buffer@3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} - typescript-event-target@1.1.1: - resolution: {integrity: sha512-dFSOFBKV6uwaloBCCUhxlD3Pr/P1a/tJdcmPrTXCHlEFD3faj0mztjcGn6VBAhQ0/Bdy8K3VWrrqwbt/ffsYsg==} - typescript-memoize@1.1.1: resolution: {integrity: sha512-GQ90TcKpIH4XxYTI2F98yEQYZgjNMOGPpOgdjIBhaLaWji5HPWlRnZ4AeA1hfBxtY7bCGDJsqDDHk/KaHOl5bA==} @@ -13731,26 +13725,6 @@ snapshots: dependencies: '@types/ms': 0.7.34 - '@types/ember@4.0.11': - dependencies: - '@types/ember__application': 4.0.11(@babel/core@7.26.0) - '@types/ember__array': 4.0.10(@babel/core@7.26.0) - '@types/ember__component': 4.0.22(@babel/core@7.26.0) - '@types/ember__controller': 4.0.12(@babel/core@7.26.0) - '@types/ember__debug': 4.0.8(@babel/core@7.26.0) - '@types/ember__engine': 4.0.11(@babel/core@7.26.0) - '@types/ember__error': 4.0.6 - '@types/ember__object': 4.0.12(@babel/core@7.26.0) - '@types/ember__polyfills': 4.0.6 - '@types/ember__routing': 4.0.22(@babel/core@7.26.0) - '@types/ember__runloop': 4.0.10 - '@types/ember__service': 4.0.9(@babel/core@7.26.0) - '@types/ember__string': 3.0.15 - '@types/ember__template': 4.0.7 - '@types/ember__test': 4.0.6(@babel/core@7.26.0) - '@types/ember__utils': 4.0.7 - '@types/rsvp': 4.0.9 - '@types/ember@4.0.11(@babel/core@7.26.0)': dependencies: '@types/ember__application': 4.0.11(@babel/core@7.26.0) @@ -13777,7 +13751,7 @@ snapshots: '@types/ember__application@4.0.11(@babel/core@7.26.0)': dependencies: '@glimmer/component': 1.1.2(@babel/core@7.26.0) - '@types/ember': 4.0.11 + '@types/ember': 4.0.11(@babel/core@7.26.0) '@types/ember__engine': 4.0.11(@babel/core@7.26.0) '@types/ember__object': 4.0.12(@babel/core@7.26.0) '@types/ember__owner': 4.0.9 @@ -13849,10 +13823,6 @@ snapshots: - '@babel/core' - supports-color - '@types/ember__runloop@4.0.10': - dependencies: - '@types/ember': 4.0.11 - '@types/ember__runloop@4.0.10(@babel/core@7.26.0)': dependencies: '@types/ember': 4.0.11(@babel/core@7.26.0) @@ -13878,10 +13848,6 @@ snapshots: - '@babel/core' - supports-color - '@types/ember__utils@4.0.7': - dependencies: - '@types/ember': 4.0.11 - '@types/ember__utils@4.0.7(@babel/core@7.26.0)': dependencies: '@types/ember': 4.0.11(@babel/core@7.26.0) @@ -17228,23 +17194,6 @@ snapshots: - eslint - supports-color - ember-simple-auth@6.1.0(@babel/core@7.26.0)(@ember/test-helpers@3.3.1(@babel/core@7.26.0)(@glint/template@1.5.0)(ember-source@5.12.0(@glimmer/component@1.1.2(@babel/core@7.26.0))(@glint/template@1.5.0)(rsvp@4.8.5)(webpack@5.96.1))(webpack@5.96.1))(@glint/template@1.5.0)(eslint@8.57.1): - dependencies: - '@babel/eslint-parser': 7.25.1(@babel/core@7.26.0)(eslint@8.57.1) - '@ember/test-waiters': 3.1.0 - '@embroider/addon-shim': 1.8.9 - '@embroider/macros': 1.16.6(@glint/template@1.5.0) - ember-cli-is-package-missing: 1.0.0 - ember-cookies: 1.1.2 - silent-error: 1.1.1 - optionalDependencies: - '@ember/test-helpers': 3.3.1(@babel/core@7.26.0)(@glint/template@1.5.0)(ember-source@5.12.0(@glimmer/component@1.1.2(@babel/core@7.26.0))(@glint/template@1.5.0)(rsvp@4.8.5)(webpack@5.96.1))(webpack@5.96.1) - transitivePeerDependencies: - - '@babel/core' - - '@glint/template' - - eslint - - supports-color - ember-source-channel-url@3.0.0(encoding@0.1.13): dependencies: node-fetch: 2.7.0(encoding@0.1.13) @@ -22563,8 +22512,6 @@ snapshots: dependencies: is-typedarray: 1.0.0 - typescript-event-target@1.1.1: {} - typescript-memoize@1.1.1: {} typescript@3.9.10: {}