feat: add solid-js support

This commit is contained in:
2025-03-01 23:22:02 +08:00
parent 3aabcd6442
commit dff1e1f9a6
11 changed files with 533 additions and 64 deletions

131
src/features/core.ts Normal file
View File

@@ -0,0 +1,131 @@
import type { HttpFeature } from '@ngify/http';
import type { Provider } from '@outposts/injection-js';
import { DOCUMENT } from '../dom';
import { provideHttpClient } from '../http';
import {
AbstractRouter,
VanillaHistoryRouter,
VanillaLocationRouter,
} from '../router';
import { AbstractSecurityStorage } from '../storage/abstract-security-storage';
import { DefaultLocalStorageService } from '../storage/default-localstorage.service';
import { DefaultSessionStorageService } from '../storage/default-sessionstorage.service';
import { PLATFORM_ID } from '../utils/platform-provider/platform.provider';
/**
* A feature to be used with `provideAuth`.
*/
export interface AuthFeature {
ɵproviders: Provider[];
}
export interface BrowserPlatformFeatureOptions {
enabled?: boolean;
}
export function withBrowserPlatform({
enabled = true,
}: BrowserPlatformFeatureOptions = {}): AuthFeature {
return {
ɵproviders: enabled
? [
{
provide: DOCUMENT,
useFactory: () => document,
},
{
provide: PLATFORM_ID,
useValue: 'browser',
},
]
: [],
};
}
export interface HttpClientFeatureOptions {
enabled?: boolean;
features?: HttpFeature[];
}
export function withHttpClient({
features,
enabled = true,
}: HttpClientFeatureOptions = {}): AuthFeature {
return {
ɵproviders: enabled ? provideHttpClient(features) : [],
};
}
export type SecurityStorageType = 'session-storage' | 'local-storage';
export interface SecurityStorageFeatureOptions {
enabled?: boolean;
type?: SecurityStorageType;
}
export function withSecurityStorage({
enabled = true,
type = 'session-storage',
}: SecurityStorageFeatureOptions = {}): AuthFeature {
return {
ɵproviders: enabled
? [
type === 'session-storage'
? {
provide: AbstractSecurityStorage,
useClass: DefaultLocalStorageService,
}
: {
provide: AbstractSecurityStorage,
useClass: DefaultSessionStorageService,
},
]
: [],
};
}
export type VanillaRouterType = 'location' | 'history';
export interface VanillaRouterFeatureOptions {
enabled?: boolean;
type?: VanillaRouterType;
}
export function withVanillaRouter({
enabled = true,
type = 'history',
}: VanillaRouterFeatureOptions = {}): AuthFeature {
return {
ɵproviders: enabled
? [
type === 'location'
? {
provide: AbstractRouter,
useClass: VanillaLocationRouter,
}
: {
provide: AbstractRouter,
useClass: VanillaHistoryRouter,
},
]
: [],
};
}
export interface DefaultFeaturesOptions {
browserPlatform?: BrowserPlatformFeatureOptions;
securityStorage?: SecurityStorageFeatureOptions;
router?: VanillaRouterFeatureOptions;
httpClient?: HttpClientFeatureOptions;
}
export function withDefaultFeatures(
options: DefaultFeaturesOptions = {}
): AuthFeature[] {
return [
withBrowserPlatform(options.browserPlatform),
withSecurityStorage(options.securityStorage),
withHttpClient(options.httpClient),
withVanillaRouter(options.router),
].filter(Boolean) as AuthFeature[];
}

8
src/features/index.ts Normal file
View File

@@ -0,0 +1,8 @@
export type * from './core';
export * from './core';
export {
CHECK_AUTH_RESULT_EVENT,
withCheckAuthResultEvent,
type CheckAuthResultEventType,
type WithCheckAuthResultEventProps,
} from './with-check-auth-result-event';

View File

@@ -0,0 +1,45 @@
import { InjectionToken, inject } from '@outposts/injection-js';
import { type Observable, filter, shareReplay } from 'rxjs';
import { EventTypes } from '../public-events/event-types';
import { PublicEventsService } from '../public-events/public-events.service';
import type { AuthFeature } from './core';
export type CheckAuthResultEventType =
| { type: EventTypes.CheckingAuthFinished }
| {
type: EventTypes.CheckingAuthFinishedWithError;
value: string;
};
export const CHECK_AUTH_RESULT_EVENT = new InjectionToken<
Observable<CheckAuthResultEventType>
>('CHECK_AUTH_RESULT_EVENT');
export interface WithCheckAuthResultEventProps {
shareReplayCount?: number;
}
export function withCheckAuthResultEvent({
shareReplayCount = 1,
}: WithCheckAuthResultEventProps = {}): AuthFeature {
return {
ɵproviders: [
{
provide: CHECK_AUTH_RESULT_EVENT,
useFactory: () => {
const publishEventService = inject(PublicEventsService);
return publishEventService.registerForEvents().pipe(
filter(
(e) =>
e.type === EventTypes.CheckingAuthFinishedWithError ||
e.type === EventTypes.CheckingAuthFinished
),
shareReplay(shareReplayCount)
);
},
deps: [PublicEventsService],
},
],
};
}