@flurryx/rx 0.8.1 → 0.8.2
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.
- package/dist/index.cjs +5 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +8 -6
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -192,7 +192,6 @@ function syncToKeyedStore(store, storeKey, resourceKey, options = {
|
|
|
192
192
|
// src/decorators/skip-if-cached.ts
|
|
193
193
|
var import_rxjs3 = require("rxjs");
|
|
194
194
|
var import_core2 = require("@flurryx/core");
|
|
195
|
-
var import_core3 = require("@flurryx/core");
|
|
196
195
|
var cacheState = /* @__PURE__ */ new WeakMap();
|
|
197
196
|
function getStoreKeyMap(store, key) {
|
|
198
197
|
let storeMap = cacheState.get(store);
|
|
@@ -224,7 +223,7 @@ function deriveResourceKey(args) {
|
|
|
224
223
|
return void 0;
|
|
225
224
|
}
|
|
226
225
|
function isExpired(timestamp, timeoutMs, now) {
|
|
227
|
-
if (timeoutMs ===
|
|
226
|
+
if (timeoutMs === import_core2.CACHE_NO_TIMEOUT) {
|
|
228
227
|
return false;
|
|
229
228
|
}
|
|
230
229
|
if (timestamp === void 0) {
|
|
@@ -304,8 +303,9 @@ function handleKeyedCache(store, storeKey, context, timeoutMs, now, returnObserv
|
|
|
304
303
|
}
|
|
305
304
|
return { hit: false };
|
|
306
305
|
}
|
|
307
|
-
function handleNonKeyedCache(store, storeKey, context, timeoutMs, now, returnObservable,
|
|
306
|
+
function handleNonKeyedCache(store, storeKey, context, timeoutMs, now, returnObservable, extra) {
|
|
308
307
|
const { nonKeyedCacheEntry, runtimeCacheKey } = context;
|
|
308
|
+
const { currentState, argsString, storeSignal } = extra;
|
|
309
309
|
if (returnObservable && nonKeyedCacheEntry?.args === argsString && nonKeyedCacheEntry.inflight$) {
|
|
310
310
|
return { hit: true, value: nonKeyedCacheEntry.inflight$ };
|
|
311
311
|
}
|
|
@@ -346,7 +346,7 @@ function createCachedObservable(result, store, storeKey, runtimeCacheKey, argsSt
|
|
|
346
346
|
(0, import_rxjs3.shareReplay)({ bufferSize: 1, refCount: true })
|
|
347
347
|
);
|
|
348
348
|
}
|
|
349
|
-
function SkipIfCached(storeKey, storeGetter, returnObservable = false, timeoutMs =
|
|
349
|
+
function SkipIfCached(storeKey, storeGetter, returnObservable = false, timeoutMs = import_core2.DEFAULT_CACHE_TTL_MS) {
|
|
350
350
|
return function(_target, _propertyKey, descriptor) {
|
|
351
351
|
const originalMethod = descriptor.value;
|
|
352
352
|
descriptor.value = function(...args) {
|
|
@@ -383,9 +383,7 @@ function SkipIfCached(storeKey, storeGetter, returnObservable = false, timeoutMs
|
|
|
383
383
|
timeoutMs,
|
|
384
384
|
now,
|
|
385
385
|
returnObservable,
|
|
386
|
-
currentState,
|
|
387
|
-
argsString,
|
|
388
|
-
storeSignal
|
|
386
|
+
{ currentState, argsString, storeSignal }
|
|
389
387
|
);
|
|
390
388
|
}
|
|
391
389
|
if (cacheHit.hit) {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/operators/sync-to-store.ts","../src/error/error-normalizer.ts","../src/operators/sync-to-keyed-store.ts","../src/decorators/skip-if-cached.ts","../src/decorators/loading.ts"],"sourcesContent":["export {\n syncToStore,\n type SyncToStoreOptions,\n} from './operators/sync-to-store';\nexport {\n syncToKeyedStore,\n type SyncToKeyedStoreOptions,\n} from './operators/sync-to-keyed-store';\nexport { SkipIfCached } from './decorators/skip-if-cached';\nexport { Loading } from './decorators/loading';\nexport {\n defaultErrorNormalizer,\n type ErrorNormalizer,\n} from './error/error-normalizer';\n","import { finalize, Observable, take, tap } from \"rxjs\";\nimport type { BaseStore, IStore } from \"@flurryx/store\";\nimport type { ResourceState } from \"@flurryx/core\";\nimport {\n defaultErrorNormalizer,\n type ErrorNormalizer,\n} from \"../error/error-normalizer\";\n\nexport interface SyncToStoreOptions {\n completeOnFirstEmission?: boolean;\n callbackAfterComplete?: () => void;\n errorNormalizer?: ErrorNormalizer;\n}\n\ninterface SyncToStoreRuntimeStore {\n update(key: PropertyKey, newState: unknown): void;\n}\n\nexport function syncToStore<\n TEnum extends Record<string, string | number>,\n TData extends { [K in keyof TEnum]: ResourceState<unknown> },\n K extends keyof TData,\n>(\n store: BaseStore<TEnum, TData>,\n key: K,\n options?: SyncToStoreOptions\n): <R>(source: Observable<R>) => Observable<R>;\n\nexport function syncToStore<\n TData extends { [K in keyof TData]: ResourceState<unknown> },\n K extends keyof TData,\n>(\n store: IStore<TData>,\n key: K,\n options?: SyncToStoreOptions\n): <R>(source: Observable<R>) => Observable<R>;\n\nexport function syncToStore(\n store: unknown,\n key: PropertyKey,\n options: SyncToStoreOptions = { completeOnFirstEmission: true }\n) {\n const normalizeError = options.errorNormalizer ?? defaultErrorNormalizer;\n const syncStore = store as SyncToStoreRuntimeStore;\n\n return <R>(source: Observable<R>) => {\n let pipeline = source.pipe(\n tap({\n next: (data: R) => {\n syncStore.update(key, {\n data,\n isLoading: false,\n status: \"Success\",\n errors: undefined,\n });\n },\n error: (error: unknown) => {\n syncStore.update(key, {\n data: undefined,\n isLoading: false,\n status: \"Error\",\n errors: normalizeError(error),\n });\n },\n })\n );\n\n if (options.completeOnFirstEmission) {\n pipeline = pipeline.pipe(take(1));\n }\n\n if (options.callbackAfterComplete) {\n pipeline = pipeline.pipe(finalize(options.callbackAfterComplete));\n }\n\n return pipeline;\n };\n}\n","import type { ResourceErrors } from '@flurryx/core';\n\nexport type ErrorNormalizer = (error: unknown) => ResourceErrors;\n\nexport function defaultErrorNormalizer(error: unknown): ResourceErrors {\n if (\n typeof error === 'object' &&\n error !== null &&\n 'error' in error &&\n typeof (error as Record<string, unknown>).error === 'object'\n ) {\n const inner = (error as { error: Record<string, unknown> }).error;\n if (inner && Array.isArray(inner.errors)) {\n return inner.errors as ResourceErrors;\n }\n }\n\n if (\n typeof error === 'object' &&\n error !== null &&\n 'status' in error &&\n 'message' in error\n ) {\n const typed = error as { status: number; message: string };\n return [\n {\n code: String(typed.status),\n message: typed.message,\n },\n ];\n }\n\n if (error instanceof Error) {\n return [\n {\n code: 'UNKNOWN',\n message: error.message,\n },\n ];\n }\n\n return [\n {\n code: 'UNKNOWN',\n message: String(error),\n },\n ];\n}\n","import { finalize, Observable, take, tap } from \"rxjs\";\nimport type { BaseStore, IStore } from \"@flurryx/store\";\nimport {\n createKeyedResourceData,\n isAnyKeyLoading,\n type KeyedResourceData,\n type KeyedResourceKey,\n type ResourceErrors,\n type ResourceState,\n type ResourceStatus,\n} from \"@flurryx/core\";\nimport {\n defaultErrorNormalizer,\n type ErrorNormalizer,\n} from \"../error/error-normalizer\";\nimport type { SyncToStoreOptions } from \"./sync-to-store\";\n\ninterface SyncToKeyedStoreRuntimeStore {\n get(key: PropertyKey): () => ResourceState<unknown>;\n update(key: PropertyKey, newState: unknown): void;\n}\n\nexport interface SyncToKeyedStoreOptions<R, TValue> extends SyncToStoreOptions {\n mapResponse?: (response: R) => TValue;\n errorNormalizer?: ErrorNormalizer;\n}\n\nfunction withoutKey<TKey extends KeyedResourceKey, TValue>(\n record: Partial<Record<TKey, TValue>>,\n key: TKey\n): Partial<Record<TKey, TValue>> {\n const next: Partial<Record<TKey, TValue>> = {\n ...record,\n };\n delete next[key];\n return next;\n}\n\nexport function syncToKeyedStore<\n TEnum extends Record<string, string | number>,\n TData extends { [K in keyof TEnum]: ResourceState<unknown> },\n TStoreKey extends keyof TData,\n TKey extends KeyedResourceKey,\n TValue,\n R = TValue\n>(\n store: BaseStore<TEnum, TData>,\n storeKey: TStoreKey,\n resourceKey: TKey,\n options?: SyncToKeyedStoreOptions<R, TValue>\n): (source: Observable<R>) => Observable<R>;\n\nexport function syncToKeyedStore<\n TData extends { [K in keyof TData]: ResourceState<unknown> },\n TStoreKey extends keyof TData,\n TKey extends KeyedResourceKey,\n TValue,\n R = TValue\n>(\n store: IStore<TData>,\n storeKey: TStoreKey,\n resourceKey: TKey,\n options?: SyncToKeyedStoreOptions<R, TValue>\n): (source: Observable<R>) => Observable<R>;\n\nexport function syncToKeyedStore(\n store: unknown,\n storeKey: PropertyKey,\n resourceKey: KeyedResourceKey,\n options: SyncToKeyedStoreOptions<unknown, unknown> = {\n completeOnFirstEmission: true,\n }\n) {\n const { completeOnFirstEmission, callbackAfterComplete, mapResponse } =\n options;\n const normalizeError = options.errorNormalizer ?? defaultErrorNormalizer;\n const syncStore = store as SyncToKeyedStoreRuntimeStore;\n\n return (source: Observable<unknown>) => {\n let pipeline = source.pipe(\n tap({\n next: (response: unknown) => {\n const value = mapResponse\n ? mapResponse(response)\n : response;\n\n const storeSignal = syncStore.get(storeKey);\n const state = storeSignal();\n const data =\n (state.data as\n | KeyedResourceData<KeyedResourceKey, unknown>\n | undefined) ??\n createKeyedResourceData<KeyedResourceKey, unknown>();\n\n const nextIsLoading = {\n ...data.isLoading,\n [resourceKey]: false,\n } as Partial<Record<KeyedResourceKey, boolean>>;\n\n const nextStatus: Partial<Record<KeyedResourceKey, ResourceStatus>> = {\n ...data.status,\n [resourceKey]: \"Success\" as ResourceStatus,\n };\n\n const nextData: KeyedResourceData<KeyedResourceKey, unknown> = {\n ...data,\n entities: {\n ...data.entities,\n [resourceKey]: value,\n } as Partial<Record<KeyedResourceKey, unknown>>,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: withoutKey(data.errors, resourceKey),\n };\n\n syncStore.update(storeKey, {\n data: nextData,\n isLoading: isAnyKeyLoading(nextIsLoading),\n status: undefined,\n errors: undefined,\n });\n },\n error: (error: unknown) => {\n const storeSignal = syncStore.get(storeKey);\n const state = storeSignal();\n const data =\n (state.data as\n | KeyedResourceData<KeyedResourceKey, unknown>\n | undefined) ??\n createKeyedResourceData<KeyedResourceKey, unknown>();\n\n const nextIsLoading = {\n ...data.isLoading,\n [resourceKey]: false,\n } as Partial<Record<KeyedResourceKey, boolean>>;\n\n const nextStatus: Partial<Record<KeyedResourceKey, ResourceStatus>> = {\n ...data.status,\n [resourceKey]: \"Error\" as ResourceStatus,\n };\n\n const nextErrors: Partial<Record<KeyedResourceKey, ResourceErrors>> = {\n ...data.errors,\n [resourceKey]: normalizeError(error),\n };\n\n const nextData: KeyedResourceData<KeyedResourceKey, unknown> = {\n ...data,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n syncStore.update(storeKey, {\n data: nextData,\n isLoading: isAnyKeyLoading(nextIsLoading),\n status: undefined,\n errors: undefined,\n });\n },\n })\n );\n\n if (completeOnFirstEmission) {\n pipeline = pipeline.pipe(take(1));\n }\n\n if (callbackAfterComplete) {\n pipeline = pipeline.pipe(finalize(callbackAfterComplete));\n }\n\n return pipeline;\n };\n}\n","import type { Signal } from \"@angular/core\";\nimport { finalize, Observable, of, shareReplay, tap } from \"rxjs\";\nimport type { ResourceState, StoreEnum, KeyedResourceKey } from \"@flurryx/core\";\nimport { isKeyedResourceData } from \"@flurryx/core\";\nimport { CACHE_NO_TIMEOUT, DEFAULT_CACHE_TTL_MS } from \"@flurryx/core\";\n\ntype StoreWithSignal<TKey extends StoreEnum> = {\n get: (key: TKey) => Signal<ResourceState<unknown>> | undefined;\n};\n\ninterface CacheEntry {\n timestamp: number;\n args: string;\n inflight$?: Observable<unknown>;\n}\n\nconst cacheState = new WeakMap<\n object,\n Map<StoreEnum, Map<string, CacheEntry>>\n>();\n\nfunction getStoreKeyMap(\n store: object,\n key: StoreEnum\n): Map<string, CacheEntry> {\n let storeMap = cacheState.get(store);\n if (!storeMap) {\n storeMap = new Map();\n cacheState.set(store, storeMap);\n }\n\n let keyMap = storeMap.get(key);\n if (!keyMap) {\n keyMap = new Map();\n storeMap.set(key, keyMap);\n }\n\n return keyMap;\n}\n\nfunction getCacheEntry(\n store: object,\n key: StoreEnum,\n cacheKey: string\n): CacheEntry | undefined {\n return getStoreKeyMap(store, key).get(cacheKey);\n}\n\nfunction setCacheEntry(\n store: object,\n key: StoreEnum,\n cacheKey: string,\n entry: CacheEntry\n): void {\n getStoreKeyMap(store, key).set(cacheKey, entry);\n}\n\nfunction clearCacheEntry(\n store: object,\n key: StoreEnum,\n cacheKey: string\n): void {\n getStoreKeyMap(store, key).delete(cacheKey);\n}\n\nfunction deriveResourceKey(args: unknown[]): KeyedResourceKey | undefined {\n const key = args[0];\n if (typeof key === \"string\" || typeof key === \"number\") {\n return key;\n }\n return undefined;\n}\n\nfunction isExpired(\n timestamp: number | undefined,\n timeoutMs: number,\n now: number\n): boolean {\n if (timeoutMs === CACHE_NO_TIMEOUT) {\n return false;\n }\n if (timestamp === undefined) {\n return false;\n }\n return now - timestamp >= timeoutMs;\n}\n\ninterface StoreContext {\n store: object;\n storeSignal: Signal<ResourceState<unknown>>;\n currentState: ResourceState<unknown>;\n}\n\nfunction getStoreContext<TTarget, TKey extends StoreEnum>(\n instance: TTarget,\n storeKey: TKey,\n getStore: (i: TTarget) => StoreWithSignal<TKey> | undefined\n): StoreContext | undefined {\n const store = getStore(instance);\n if (!store) {\n return undefined;\n }\n\n const storeSignal = store.get(storeKey);\n if (!storeSignal) {\n return undefined;\n }\n\n const currentState = storeSignal();\n if (currentState === null || currentState === undefined) {\n return undefined;\n }\n\n return { store, storeSignal, currentState };\n}\n\ninterface CacheContext {\n isKeyedCall: boolean;\n resourceKey: KeyedResourceKey | undefined;\n keyedData: ReturnType<typeof isKeyedResourceData> extends true\n ? { entities: object; isLoading: object; status: object; errors: object }\n : undefined;\n runtimeCacheKey: string;\n keyedCacheEntry: CacheEntry | undefined;\n nonKeyedCacheEntry: CacheEntry | undefined;\n}\n\nfunction getCacheContext(\n store: object,\n storeKey: StoreEnum,\n args: unknown[],\n argsString: string,\n currentState: ResourceState<unknown>\n): CacheContext {\n const keyedData = isKeyedResourceData(currentState.data)\n ? currentState.data\n : undefined;\n const resourceKey = keyedData ? deriveResourceKey(args) : undefined;\n const isKeyedCall = keyedData !== undefined && resourceKey !== undefined;\n\n const keyedCacheKey = argsString;\n const nonKeyedCacheKey = \"__single__\";\n const runtimeCacheKey = isKeyedCall ? keyedCacheKey : nonKeyedCacheKey;\n\n const keyedCacheEntry = getCacheEntry(store, storeKey, keyedCacheKey);\n const nonKeyedCacheEntry = getCacheEntry(store, storeKey, nonKeyedCacheKey);\n\n return {\n isKeyedCall,\n resourceKey,\n keyedData: keyedData as CacheContext[\"keyedData\"],\n runtimeCacheKey,\n keyedCacheEntry,\n nonKeyedCacheEntry,\n };\n}\n\nfunction handleCacheErrors(\n store: object,\n storeKey: StoreEnum,\n context: CacheContext,\n currentState: ResourceState<unknown>\n): void {\n if (!context.keyedData && currentState.status === \"Error\") {\n clearCacheEntry(store, storeKey, \"__single__\");\n }\n if (context.keyedData && context.resourceKey !== undefined) {\n const status = (\n context.keyedData as {\n status: Partial<Record<KeyedResourceKey, string>>;\n }\n ).status[context.resourceKey];\n if (status === \"Error\") {\n clearCacheEntry(store, storeKey, context.runtimeCacheKey);\n }\n }\n}\n\ninterface CacheHitResult {\n hit: boolean;\n value?: Observable<unknown>;\n}\n\nfunction handleKeyedCache(\n store: object,\n storeKey: StoreEnum,\n context: CacheContext,\n timeoutMs: number,\n now: number,\n returnObservable: boolean\n): CacheHitResult {\n const { keyedData, resourceKey, keyedCacheEntry, runtimeCacheKey } = context;\n\n if (!keyedData || resourceKey === undefined) {\n return { hit: false };\n }\n\n const typed = keyedData as {\n status: Partial<Record<KeyedResourceKey, string>>;\n entities: Partial<Record<KeyedResourceKey, unknown>>;\n isLoading: Partial<Record<KeyedResourceKey, boolean>>;\n };\n\n const status = typed.status[resourceKey];\n const entity = typed.entities[resourceKey];\n const loading = typed.isLoading[resourceKey] === true;\n\n const expired = isExpired(keyedCacheEntry?.timestamp, timeoutMs, now);\n if (expired) {\n clearCacheEntry(store, storeKey, runtimeCacheKey);\n }\n\n if (!expired && status === \"Success\" && entity !== undefined) {\n if (returnObservable) {\n return { hit: true, value: of(entity) };\n }\n return { hit: true };\n }\n\n if (returnObservable) {\n if (keyedCacheEntry?.inflight$) {\n return { hit: true, value: keyedCacheEntry.inflight$ };\n }\n } else if (loading) {\n return { hit: true };\n }\n\n return { hit: false };\n}\n\nfunction handleNonKeyedCache(\n store: object,\n storeKey: StoreEnum,\n context: CacheContext,\n timeoutMs: number,\n now: number,\n returnObservable: boolean,\n currentState: ResourceState<unknown>,\n argsString: string,\n storeSignal: Signal<ResourceState<unknown>>\n): CacheHitResult {\n const { nonKeyedCacheEntry, runtimeCacheKey } = context;\n\n if (\n returnObservable &&\n nonKeyedCacheEntry?.args === argsString &&\n nonKeyedCacheEntry.inflight$\n ) {\n return { hit: true, value: nonKeyedCacheEntry.inflight$ };\n }\n\n const hasValidCacheState =\n currentState?.status === \"Success\" || currentState?.isLoading === true;\n\n if (\n nonKeyedCacheEntry &&\n isExpired(nonKeyedCacheEntry.timestamp, timeoutMs, now)\n ) {\n clearCacheEntry(store, storeKey, runtimeCacheKey);\n } else if (nonKeyedCacheEntry?.args === argsString && hasValidCacheState) {\n if (returnObservable) {\n if (nonKeyedCacheEntry.inflight$) {\n return { hit: true, value: nonKeyedCacheEntry.inflight$ };\n }\n return { hit: true, value: of(storeSignal().data) };\n }\n return { hit: true };\n }\n\n return { hit: false };\n}\n\nfunction createCachedObservable(\n result: Observable<unknown>,\n store: object,\n storeKey: StoreEnum,\n runtimeCacheKey: string,\n argsString: string\n): Observable<unknown> {\n return result.pipe(\n tap({\n next: () => {\n setCacheEntry(store, storeKey, runtimeCacheKey, {\n timestamp: Date.now(),\n args: argsString,\n });\n },\n error: () => {\n clearCacheEntry(store, storeKey, runtimeCacheKey);\n },\n }),\n finalize(() => {\n const entry = getCacheEntry(store, storeKey, runtimeCacheKey);\n if (entry?.inflight$) {\n const { inflight$: _inflight$, ...rest } = entry;\n setCacheEntry(store, storeKey, runtimeCacheKey, rest);\n }\n }),\n shareReplay({ bufferSize: 1, refCount: true })\n );\n}\n\nexport function SkipIfCached<TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: {\n store: StoreWithSignal<TKey>;\n }) => StoreWithSignal<TKey> | undefined,\n returnObservable?: boolean,\n timeoutMs?: number\n): MethodDecorator;\nexport function SkipIfCached<TTarget, TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: TTarget) => StoreWithSignal<TKey> | undefined,\n returnObservable?: boolean,\n timeoutMs?: number\n): MethodDecorator;\nexport function SkipIfCached<TTarget, TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: TTarget) => StoreWithSignal<TKey> | undefined,\n returnObservable = false,\n timeoutMs = DEFAULT_CACHE_TTL_MS\n): MethodDecorator {\n return function (\n _target: unknown,\n _propertyKey: string | symbol,\n descriptor: PropertyDescriptor\n ) {\n const originalMethod = descriptor.value as (\n this: TTarget,\n ...args: unknown[]\n ) => unknown;\n\n descriptor.value = function (this: TTarget, ...args: unknown[]) {\n const storeContext = getStoreContext(this, storeKey, storeGetter);\n if (!storeContext) {\n return originalMethod.apply(this, args);\n }\n const { store, storeSignal, currentState } = storeContext;\n\n const argsString = JSON.stringify(args);\n const now = Date.now();\n const cacheContext = getCacheContext(\n store,\n storeKey,\n args,\n argsString,\n currentState\n );\n\n handleCacheErrors(store, storeKey, cacheContext, currentState);\n\n let cacheHit: CacheHitResult;\n\n if (cacheContext.isKeyedCall) {\n cacheHit = handleKeyedCache(\n store,\n storeKey,\n cacheContext,\n timeoutMs,\n now,\n returnObservable\n );\n } else {\n cacheHit = handleNonKeyedCache(\n store,\n storeKey,\n cacheContext,\n timeoutMs,\n now,\n returnObservable,\n currentState,\n argsString,\n storeSignal\n );\n }\n\n if (cacheHit.hit) {\n return cacheHit.value;\n }\n\n const result = originalMethod.apply(this, args);\n\n if (!returnObservable) {\n setCacheEntry(store, storeKey, cacheContext.runtimeCacheKey, {\n timestamp: now,\n args: argsString,\n });\n return result;\n }\n\n const inflight$ = createCachedObservable(\n result as Observable<unknown>,\n store,\n storeKey,\n cacheContext.runtimeCacheKey,\n argsString\n );\n\n setCacheEntry(store, storeKey, cacheContext.runtimeCacheKey, {\n timestamp: now,\n args: argsString,\n inflight$,\n });\n\n return inflight$;\n };\n\n return descriptor;\n };\n}\n","import type { StoreEnum, KeyedResourceKey } from '@flurryx/core';\n\ntype StoreWithLoading<TKey extends StoreEnum> = {\n startLoading: (key: TKey) => void;\n};\n\nexport function Loading<TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: {\n store: StoreWithLoading<TKey>;\n }) => StoreWithLoading<TKey>\n): MethodDecorator;\nexport function Loading<TTarget, TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: TTarget) => StoreWithLoading<TKey>\n): MethodDecorator;\nexport function Loading<TTarget, TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: TTarget) => StoreWithLoading<TKey>\n) {\n return function (\n _target: unknown,\n _propertyKey: string | symbol,\n descriptor: PropertyDescriptor\n ) {\n const originalMethod = descriptor.value as (\n this: unknown,\n ...args: unknown[]\n ) => unknown;\n\n descriptor.value = function (this: TTarget, ...args: unknown[]) {\n const store = storeGetter(this);\n\n const resourceKey = args[0];\n const canKey =\n typeof resourceKey === 'string' || typeof resourceKey === 'number';\n const hasKeyed =\n typeof store === 'object' &&\n store !== null &&\n 'startKeyedLoading' in store &&\n typeof (store as { startKeyedLoading?: unknown }).startKeyedLoading ===\n 'function';\n\n if (canKey && hasKeyed) {\n (\n store as unknown as {\n startKeyedLoading: (\n key: TKey,\n resourceKey: KeyedResourceKey\n ) => void;\n }\n ).startKeyedLoading(storeKey, resourceKey as KeyedResourceKey);\n } else {\n store?.startLoading(storeKey);\n }\n return originalMethod.apply(this, args);\n };\n\n return descriptor;\n };\n}\n"],"mappings":"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","names":["import_rxjs","import_rxjs","import_core"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/operators/sync-to-store.ts","../src/error/error-normalizer.ts","../src/operators/sync-to-keyed-store.ts","../src/decorators/skip-if-cached.ts","../src/decorators/loading.ts"],"sourcesContent":["export {\n syncToStore,\n type SyncToStoreOptions,\n} from './operators/sync-to-store';\nexport {\n syncToKeyedStore,\n type SyncToKeyedStoreOptions,\n} from './operators/sync-to-keyed-store';\nexport { SkipIfCached } from './decorators/skip-if-cached';\nexport { Loading } from './decorators/loading';\nexport {\n defaultErrorNormalizer,\n type ErrorNormalizer,\n} from './error/error-normalizer';\n","import { finalize, Observable, take, tap } from \"rxjs\";\nimport type { BaseStore, IStore } from \"@flurryx/store\";\nimport type { ResourceState } from \"@flurryx/core\";\nimport {\n defaultErrorNormalizer,\n type ErrorNormalizer,\n} from \"../error/error-normalizer\";\n\nexport interface SyncToStoreOptions {\n completeOnFirstEmission?: boolean;\n callbackAfterComplete?: () => void;\n errorNormalizer?: ErrorNormalizer;\n}\n\ninterface SyncToStoreRuntimeStore {\n update(key: PropertyKey, newState: unknown): void;\n}\n\nexport function syncToStore<\n TEnum extends Record<string, string | number>,\n TData extends { [K in keyof TEnum]: ResourceState<unknown> },\n K extends keyof TData,\n>(\n store: BaseStore<TEnum, TData>,\n key: K,\n options?: SyncToStoreOptions\n): <R>(source: Observable<R>) => Observable<R>;\n\nexport function syncToStore<\n TData extends { [K in keyof TData]: ResourceState<unknown> },\n K extends keyof TData,\n>(\n store: IStore<TData>,\n key: K,\n options?: SyncToStoreOptions\n): <R>(source: Observable<R>) => Observable<R>;\n\nexport function syncToStore(\n store: unknown,\n key: PropertyKey,\n options: SyncToStoreOptions = { completeOnFirstEmission: true }\n) {\n const normalizeError = options.errorNormalizer ?? defaultErrorNormalizer;\n const syncStore = store as SyncToStoreRuntimeStore;\n\n return <R>(source: Observable<R>) => {\n let pipeline = source.pipe(\n tap({\n next: (data: R) => {\n syncStore.update(key, {\n data,\n isLoading: false,\n status: \"Success\",\n errors: undefined,\n });\n },\n error: (error: unknown) => {\n syncStore.update(key, {\n data: undefined,\n isLoading: false,\n status: \"Error\",\n errors: normalizeError(error),\n });\n },\n })\n );\n\n if (options.completeOnFirstEmission) {\n pipeline = pipeline.pipe(take(1));\n }\n\n if (options.callbackAfterComplete) {\n pipeline = pipeline.pipe(finalize(options.callbackAfterComplete));\n }\n\n return pipeline;\n };\n}\n","import type { ResourceErrors } from '@flurryx/core';\n\nexport type ErrorNormalizer = (error: unknown) => ResourceErrors;\n\nexport function defaultErrorNormalizer(error: unknown): ResourceErrors {\n if (\n typeof error === 'object' &&\n error !== null &&\n 'error' in error &&\n typeof (error as Record<string, unknown>).error === 'object'\n ) {\n const inner = (error as { error: Record<string, unknown> }).error;\n if (inner && Array.isArray(inner.errors)) {\n return inner.errors as ResourceErrors;\n }\n }\n\n if (\n typeof error === 'object' &&\n error !== null &&\n 'status' in error &&\n 'message' in error\n ) {\n const typed = error as { status: number; message: string };\n return [\n {\n code: String(typed.status),\n message: typed.message,\n },\n ];\n }\n\n if (error instanceof Error) {\n return [\n {\n code: 'UNKNOWN',\n message: error.message,\n },\n ];\n }\n\n return [\n {\n code: 'UNKNOWN',\n message: String(error),\n },\n ];\n}\n","import { finalize, Observable, take, tap } from \"rxjs\";\nimport type { BaseStore, IStore } from \"@flurryx/store\";\nimport {\n createKeyedResourceData,\n isAnyKeyLoading,\n type KeyedResourceData,\n type KeyedResourceKey,\n type ResourceErrors,\n type ResourceState,\n type ResourceStatus,\n} from \"@flurryx/core\";\nimport {\n defaultErrorNormalizer,\n type ErrorNormalizer,\n} from \"../error/error-normalizer\";\nimport type { SyncToStoreOptions } from \"./sync-to-store\";\n\ninterface SyncToKeyedStoreRuntimeStore {\n get(key: PropertyKey): () => ResourceState<unknown>;\n update(key: PropertyKey, newState: unknown): void;\n}\n\nexport interface SyncToKeyedStoreOptions<R, TValue> extends SyncToStoreOptions {\n mapResponse?: (response: R) => TValue;\n errorNormalizer?: ErrorNormalizer;\n}\n\nfunction withoutKey<TKey extends KeyedResourceKey, TValue>(\n record: Partial<Record<TKey, TValue>>,\n key: TKey\n): Partial<Record<TKey, TValue>> {\n const next: Partial<Record<TKey, TValue>> = {\n ...record,\n };\n delete next[key];\n return next;\n}\n\nexport function syncToKeyedStore<\n TEnum extends Record<string, string | number>,\n TData extends { [K in keyof TEnum]: ResourceState<unknown> },\n TStoreKey extends keyof TData,\n TKey extends KeyedResourceKey,\n TValue,\n R = TValue\n>(\n store: BaseStore<TEnum, TData>,\n storeKey: TStoreKey,\n resourceKey: TKey,\n options?: SyncToKeyedStoreOptions<R, TValue>\n): (source: Observable<R>) => Observable<R>;\n\nexport function syncToKeyedStore<\n TData extends { [K in keyof TData]: ResourceState<unknown> },\n TStoreKey extends keyof TData,\n TKey extends KeyedResourceKey,\n TValue,\n R = TValue\n>(\n store: IStore<TData>,\n storeKey: TStoreKey,\n resourceKey: TKey,\n options?: SyncToKeyedStoreOptions<R, TValue>\n): (source: Observable<R>) => Observable<R>;\n\nexport function syncToKeyedStore(\n store: unknown,\n storeKey: PropertyKey,\n resourceKey: KeyedResourceKey,\n options: SyncToKeyedStoreOptions<unknown, unknown> = {\n completeOnFirstEmission: true,\n }\n) {\n const { completeOnFirstEmission, callbackAfterComplete, mapResponse } =\n options;\n const normalizeError = options.errorNormalizer ?? defaultErrorNormalizer;\n const syncStore = store as SyncToKeyedStoreRuntimeStore;\n\n return (source: Observable<unknown>) => {\n let pipeline = source.pipe(\n tap({\n next: (response: unknown) => {\n const value = mapResponse\n ? mapResponse(response)\n : response;\n\n const storeSignal = syncStore.get(storeKey);\n const state = storeSignal();\n const data =\n (state.data as\n | KeyedResourceData<KeyedResourceKey, unknown>\n | undefined) ??\n createKeyedResourceData<KeyedResourceKey, unknown>();\n\n const nextIsLoading = {\n ...data.isLoading,\n [resourceKey]: false,\n } as Partial<Record<KeyedResourceKey, boolean>>;\n\n const nextStatus: Partial<Record<KeyedResourceKey, ResourceStatus>> = {\n ...data.status,\n [resourceKey]: \"Success\" as ResourceStatus,\n };\n\n const nextData: KeyedResourceData<KeyedResourceKey, unknown> = {\n ...data,\n entities: {\n ...data.entities,\n [resourceKey]: value,\n } as Partial<Record<KeyedResourceKey, unknown>>,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: withoutKey(data.errors, resourceKey),\n };\n\n syncStore.update(storeKey, {\n data: nextData,\n isLoading: isAnyKeyLoading(nextIsLoading),\n status: undefined,\n errors: undefined,\n });\n },\n error: (error: unknown) => {\n const storeSignal = syncStore.get(storeKey);\n const state = storeSignal();\n const data =\n (state.data as\n | KeyedResourceData<KeyedResourceKey, unknown>\n | undefined) ??\n createKeyedResourceData<KeyedResourceKey, unknown>();\n\n const nextIsLoading = {\n ...data.isLoading,\n [resourceKey]: false,\n } as Partial<Record<KeyedResourceKey, boolean>>;\n\n const nextStatus: Partial<Record<KeyedResourceKey, ResourceStatus>> = {\n ...data.status,\n [resourceKey]: \"Error\" as ResourceStatus,\n };\n\n const nextErrors: Partial<Record<KeyedResourceKey, ResourceErrors>> = {\n ...data.errors,\n [resourceKey]: normalizeError(error),\n };\n\n const nextData: KeyedResourceData<KeyedResourceKey, unknown> = {\n ...data,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n syncStore.update(storeKey, {\n data: nextData,\n isLoading: isAnyKeyLoading(nextIsLoading),\n status: undefined,\n errors: undefined,\n });\n },\n })\n );\n\n if (completeOnFirstEmission) {\n pipeline = pipeline.pipe(take(1));\n }\n\n if (callbackAfterComplete) {\n pipeline = pipeline.pipe(finalize(callbackAfterComplete));\n }\n\n return pipeline;\n };\n}\n","import type { Signal } from \"@angular/core\";\nimport { finalize, Observable, of, shareReplay, tap } from \"rxjs\";\nimport {\n isKeyedResourceData,\n CACHE_NO_TIMEOUT,\n DEFAULT_CACHE_TTL_MS,\n} from \"@flurryx/core\";\nimport type { ResourceState, StoreEnum, KeyedResourceKey } from \"@flurryx/core\";\n\ntype StoreWithSignal<TKey extends StoreEnum> = {\n get: (key: TKey) => Signal<ResourceState<unknown>> | undefined;\n};\n\ninterface CacheEntry {\n timestamp: number;\n args: string;\n inflight$?: Observable<unknown>;\n}\n\nconst cacheState = new WeakMap<\n object,\n Map<StoreEnum, Map<string, CacheEntry>>\n>();\n\nfunction getStoreKeyMap(\n store: object,\n key: StoreEnum\n): Map<string, CacheEntry> {\n let storeMap = cacheState.get(store);\n if (!storeMap) {\n storeMap = new Map();\n cacheState.set(store, storeMap);\n }\n\n let keyMap = storeMap.get(key);\n if (!keyMap) {\n keyMap = new Map();\n storeMap.set(key, keyMap);\n }\n\n return keyMap;\n}\n\nfunction getCacheEntry(\n store: object,\n key: StoreEnum,\n cacheKey: string\n): CacheEntry | undefined {\n return getStoreKeyMap(store, key).get(cacheKey);\n}\n\nfunction setCacheEntry(\n store: object,\n key: StoreEnum,\n cacheKey: string,\n entry: CacheEntry\n): void {\n getStoreKeyMap(store, key).set(cacheKey, entry);\n}\n\nfunction clearCacheEntry(\n store: object,\n key: StoreEnum,\n cacheKey: string\n): void {\n getStoreKeyMap(store, key).delete(cacheKey);\n}\n\nfunction deriveResourceKey(args: unknown[]): KeyedResourceKey | undefined {\n const key = args[0];\n if (typeof key === \"string\" || typeof key === \"number\") {\n return key;\n }\n return undefined;\n}\n\nfunction isExpired(\n timestamp: number | undefined,\n timeoutMs: number,\n now: number\n): boolean {\n if (timeoutMs === CACHE_NO_TIMEOUT) {\n return false;\n }\n if (timestamp === undefined) {\n return false;\n }\n return now - timestamp >= timeoutMs;\n}\n\ninterface StoreContext {\n store: object;\n storeSignal: Signal<ResourceState<unknown>>;\n currentState: ResourceState<unknown>;\n}\n\nfunction getStoreContext<TTarget, TKey extends StoreEnum>(\n instance: TTarget,\n storeKey: TKey,\n getStore: (i: TTarget) => StoreWithSignal<TKey> | undefined\n): StoreContext | undefined {\n const store = getStore(instance);\n if (!store) {\n return undefined;\n }\n\n const storeSignal = store.get(storeKey);\n if (!storeSignal) {\n return undefined;\n }\n\n const currentState = storeSignal();\n if (currentState === null || currentState === undefined) {\n return undefined;\n }\n\n return { store, storeSignal, currentState };\n}\n\ninterface CacheContext {\n isKeyedCall: boolean;\n resourceKey: KeyedResourceKey | undefined;\n keyedData: ReturnType<typeof isKeyedResourceData> extends true\n ? { entities: object; isLoading: object; status: object; errors: object }\n : undefined;\n runtimeCacheKey: string;\n keyedCacheEntry: CacheEntry | undefined;\n nonKeyedCacheEntry: CacheEntry | undefined;\n}\n\nfunction getCacheContext(\n store: object,\n storeKey: StoreEnum,\n args: unknown[],\n argsString: string,\n currentState: ResourceState<unknown>\n): CacheContext {\n const keyedData = isKeyedResourceData(currentState.data)\n ? currentState.data\n : undefined;\n const resourceKey = keyedData ? deriveResourceKey(args) : undefined;\n const isKeyedCall = keyedData !== undefined && resourceKey !== undefined;\n\n const keyedCacheKey = argsString;\n const nonKeyedCacheKey = \"__single__\";\n const runtimeCacheKey = isKeyedCall ? keyedCacheKey : nonKeyedCacheKey;\n\n const keyedCacheEntry = getCacheEntry(store, storeKey, keyedCacheKey);\n const nonKeyedCacheEntry = getCacheEntry(store, storeKey, nonKeyedCacheKey);\n\n return {\n isKeyedCall,\n resourceKey,\n keyedData: keyedData as CacheContext[\"keyedData\"],\n runtimeCacheKey,\n keyedCacheEntry,\n nonKeyedCacheEntry,\n };\n}\n\nfunction handleCacheErrors(\n store: object,\n storeKey: StoreEnum,\n context: CacheContext,\n currentState: ResourceState<unknown>\n): void {\n if (!context.keyedData && currentState.status === \"Error\") {\n clearCacheEntry(store, storeKey, \"__single__\");\n }\n if (context.keyedData && context.resourceKey !== undefined) {\n const status = (\n context.keyedData as {\n status: Partial<Record<KeyedResourceKey, string>>;\n }\n ).status[context.resourceKey];\n if (status === \"Error\") {\n clearCacheEntry(store, storeKey, context.runtimeCacheKey);\n }\n }\n}\n\ninterface CacheHitResult {\n hit: boolean;\n value?: Observable<unknown>;\n}\n\nfunction handleKeyedCache(\n store: object,\n storeKey: StoreEnum,\n context: CacheContext,\n timeoutMs: number,\n now: number,\n returnObservable: boolean\n): CacheHitResult {\n const { keyedData, resourceKey, keyedCacheEntry, runtimeCacheKey } = context;\n\n if (!keyedData || resourceKey === undefined) {\n return { hit: false };\n }\n\n const typed = keyedData as {\n status: Partial<Record<KeyedResourceKey, string>>;\n entities: Partial<Record<KeyedResourceKey, unknown>>;\n isLoading: Partial<Record<KeyedResourceKey, boolean>>;\n };\n\n const status = typed.status[resourceKey];\n const entity = typed.entities[resourceKey];\n const loading = typed.isLoading[resourceKey] === true;\n\n const expired = isExpired(keyedCacheEntry?.timestamp, timeoutMs, now);\n if (expired) {\n clearCacheEntry(store, storeKey, runtimeCacheKey);\n }\n\n if (!expired && status === \"Success\" && entity !== undefined) {\n if (returnObservable) {\n return { hit: true, value: of(entity) };\n }\n return { hit: true };\n }\n\n if (returnObservable) {\n if (keyedCacheEntry?.inflight$) {\n return { hit: true, value: keyedCacheEntry.inflight$ };\n }\n } else if (loading) {\n return { hit: true };\n }\n\n return { hit: false };\n}\n\ninterface NonKeyedCacheExtra {\n readonly currentState: ResourceState<unknown>;\n readonly argsString: string;\n readonly storeSignal: Signal<ResourceState<unknown>>;\n}\n\nfunction handleNonKeyedCache(\n store: object,\n storeKey: StoreEnum,\n context: CacheContext,\n timeoutMs: number,\n now: number,\n returnObservable: boolean,\n extra: NonKeyedCacheExtra\n): CacheHitResult {\n const { nonKeyedCacheEntry, runtimeCacheKey } = context;\n const { currentState, argsString, storeSignal } = extra;\n\n if (\n returnObservable &&\n nonKeyedCacheEntry?.args === argsString &&\n nonKeyedCacheEntry.inflight$\n ) {\n return { hit: true, value: nonKeyedCacheEntry.inflight$ };\n }\n\n const hasValidCacheState =\n currentState?.status === \"Success\" || currentState?.isLoading === true;\n\n if (\n nonKeyedCacheEntry &&\n isExpired(nonKeyedCacheEntry.timestamp, timeoutMs, now)\n ) {\n clearCacheEntry(store, storeKey, runtimeCacheKey);\n } else if (nonKeyedCacheEntry?.args === argsString && hasValidCacheState) {\n if (returnObservable) {\n if (nonKeyedCacheEntry.inflight$) {\n return { hit: true, value: nonKeyedCacheEntry.inflight$ };\n }\n return { hit: true, value: of(storeSignal().data) };\n }\n return { hit: true };\n }\n\n return { hit: false };\n}\n\nfunction createCachedObservable(\n result: Observable<unknown>,\n store: object,\n storeKey: StoreEnum,\n runtimeCacheKey: string,\n argsString: string\n): Observable<unknown> {\n return result.pipe(\n tap({\n next: () => {\n setCacheEntry(store, storeKey, runtimeCacheKey, {\n timestamp: Date.now(),\n args: argsString,\n });\n },\n error: () => {\n clearCacheEntry(store, storeKey, runtimeCacheKey);\n },\n }),\n finalize(() => {\n const entry = getCacheEntry(store, storeKey, runtimeCacheKey);\n if (entry?.inflight$) {\n const { inflight$: _inflight$, ...rest } = entry;\n setCacheEntry(store, storeKey, runtimeCacheKey, rest);\n }\n }),\n shareReplay({ bufferSize: 1, refCount: true })\n );\n}\n\nexport function SkipIfCached<TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: {\n store: StoreWithSignal<TKey>;\n }) => StoreWithSignal<TKey> | undefined,\n returnObservable?: boolean,\n timeoutMs?: number\n): MethodDecorator;\nexport function SkipIfCached<TTarget, TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: TTarget) => StoreWithSignal<TKey> | undefined,\n returnObservable?: boolean,\n timeoutMs?: number\n): MethodDecorator;\nexport function SkipIfCached<TTarget, TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: TTarget) => StoreWithSignal<TKey> | undefined,\n returnObservable = false,\n timeoutMs = DEFAULT_CACHE_TTL_MS\n): MethodDecorator {\n return function (\n _target: unknown,\n _propertyKey: string | symbol,\n descriptor: PropertyDescriptor\n ) {\n const originalMethod = descriptor.value as (\n this: TTarget,\n ...args: unknown[]\n ) => unknown;\n\n descriptor.value = function (this: TTarget, ...args: unknown[]) {\n const storeContext = getStoreContext(this, storeKey, storeGetter);\n if (!storeContext) {\n return originalMethod.apply(this, args);\n }\n const { store, storeSignal, currentState } = storeContext;\n\n const argsString = JSON.stringify(args);\n const now = Date.now();\n const cacheContext = getCacheContext(\n store,\n storeKey,\n args,\n argsString,\n currentState\n );\n\n handleCacheErrors(store, storeKey, cacheContext, currentState);\n\n let cacheHit: CacheHitResult;\n\n if (cacheContext.isKeyedCall) {\n cacheHit = handleKeyedCache(\n store,\n storeKey,\n cacheContext,\n timeoutMs,\n now,\n returnObservable\n );\n } else {\n cacheHit = handleNonKeyedCache(\n store,\n storeKey,\n cacheContext,\n timeoutMs,\n now,\n returnObservable,\n { currentState, argsString, storeSignal }\n );\n }\n\n if (cacheHit.hit) {\n return cacheHit.value;\n }\n\n const result = originalMethod.apply(this, args);\n\n if (!returnObservable) {\n setCacheEntry(store, storeKey, cacheContext.runtimeCacheKey, {\n timestamp: now,\n args: argsString,\n });\n return result;\n }\n\n const inflight$ = createCachedObservable(\n result as Observable<unknown>,\n store,\n storeKey,\n cacheContext.runtimeCacheKey,\n argsString\n );\n\n setCacheEntry(store, storeKey, cacheContext.runtimeCacheKey, {\n timestamp: now,\n args: argsString,\n inflight$,\n });\n\n return inflight$;\n };\n\n return descriptor;\n };\n}\n","import type { StoreEnum, KeyedResourceKey } from '@flurryx/core';\n\ntype StoreWithLoading<TKey extends StoreEnum> = {\n startLoading: (key: TKey) => void;\n};\n\nexport function Loading<TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: {\n store: StoreWithLoading<TKey>;\n }) => StoreWithLoading<TKey>\n): MethodDecorator;\nexport function Loading<TTarget, TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: TTarget) => StoreWithLoading<TKey>\n): MethodDecorator;\nexport function Loading<TTarget, TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: TTarget) => StoreWithLoading<TKey>\n) {\n return function (\n _target: unknown,\n _propertyKey: string | symbol,\n descriptor: PropertyDescriptor\n ) {\n const originalMethod = descriptor.value as (\n this: unknown,\n ...args: unknown[]\n ) => unknown;\n\n descriptor.value = function (this: TTarget, ...args: unknown[]) {\n const store = storeGetter(this);\n\n const resourceKey = args[0];\n const canKey =\n typeof resourceKey === 'string' || typeof resourceKey === 'number';\n const hasKeyed =\n typeof store === 'object' &&\n store !== null &&\n 'startKeyedLoading' in store &&\n typeof (store as { startKeyedLoading?: unknown }).startKeyedLoading ===\n 'function';\n\n if (canKey && hasKeyed) {\n (\n store as unknown as {\n startKeyedLoading: (\n key: TKey,\n resourceKey: KeyedResourceKey\n ) => void;\n }\n ).startKeyedLoading(storeKey, resourceKey as KeyedResourceKey);\n } else {\n store?.startLoading(storeKey);\n }\n return originalMethod.apply(this, args);\n };\n\n return descriptor;\n };\n}\n"],"mappings":"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","names":["import_rxjs","import_rxjs","import_core"]}
|
package/dist/index.js
CHANGED
|
@@ -164,8 +164,11 @@ function syncToKeyedStore(store, storeKey, resourceKey, options = {
|
|
|
164
164
|
|
|
165
165
|
// src/decorators/skip-if-cached.ts
|
|
166
166
|
import { finalize as finalize3, of, shareReplay, tap as tap3 } from "rxjs";
|
|
167
|
-
import {
|
|
168
|
-
|
|
167
|
+
import {
|
|
168
|
+
isKeyedResourceData,
|
|
169
|
+
CACHE_NO_TIMEOUT,
|
|
170
|
+
DEFAULT_CACHE_TTL_MS
|
|
171
|
+
} from "@flurryx/core";
|
|
169
172
|
var cacheState = /* @__PURE__ */ new WeakMap();
|
|
170
173
|
function getStoreKeyMap(store, key) {
|
|
171
174
|
let storeMap = cacheState.get(store);
|
|
@@ -277,8 +280,9 @@ function handleKeyedCache(store, storeKey, context, timeoutMs, now, returnObserv
|
|
|
277
280
|
}
|
|
278
281
|
return { hit: false };
|
|
279
282
|
}
|
|
280
|
-
function handleNonKeyedCache(store, storeKey, context, timeoutMs, now, returnObservable,
|
|
283
|
+
function handleNonKeyedCache(store, storeKey, context, timeoutMs, now, returnObservable, extra) {
|
|
281
284
|
const { nonKeyedCacheEntry, runtimeCacheKey } = context;
|
|
285
|
+
const { currentState, argsString, storeSignal } = extra;
|
|
282
286
|
if (returnObservable && nonKeyedCacheEntry?.args === argsString && nonKeyedCacheEntry.inflight$) {
|
|
283
287
|
return { hit: true, value: nonKeyedCacheEntry.inflight$ };
|
|
284
288
|
}
|
|
@@ -356,9 +360,7 @@ function SkipIfCached(storeKey, storeGetter, returnObservable = false, timeoutMs
|
|
|
356
360
|
timeoutMs,
|
|
357
361
|
now,
|
|
358
362
|
returnObservable,
|
|
359
|
-
currentState,
|
|
360
|
-
argsString,
|
|
361
|
-
storeSignal
|
|
363
|
+
{ currentState, argsString, storeSignal }
|
|
362
364
|
);
|
|
363
365
|
}
|
|
364
366
|
if (cacheHit.hit) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/operators/sync-to-store.ts","../src/error/error-normalizer.ts","../src/operators/sync-to-keyed-store.ts","../src/decorators/skip-if-cached.ts","../src/decorators/loading.ts"],"sourcesContent":["import { finalize, Observable, take, tap } from \"rxjs\";\nimport type { BaseStore, IStore } from \"@flurryx/store\";\nimport type { ResourceState } from \"@flurryx/core\";\nimport {\n defaultErrorNormalizer,\n type ErrorNormalizer,\n} from \"../error/error-normalizer\";\n\nexport interface SyncToStoreOptions {\n completeOnFirstEmission?: boolean;\n callbackAfterComplete?: () => void;\n errorNormalizer?: ErrorNormalizer;\n}\n\ninterface SyncToStoreRuntimeStore {\n update(key: PropertyKey, newState: unknown): void;\n}\n\nexport function syncToStore<\n TEnum extends Record<string, string | number>,\n TData extends { [K in keyof TEnum]: ResourceState<unknown> },\n K extends keyof TData,\n>(\n store: BaseStore<TEnum, TData>,\n key: K,\n options?: SyncToStoreOptions\n): <R>(source: Observable<R>) => Observable<R>;\n\nexport function syncToStore<\n TData extends { [K in keyof TData]: ResourceState<unknown> },\n K extends keyof TData,\n>(\n store: IStore<TData>,\n key: K,\n options?: SyncToStoreOptions\n): <R>(source: Observable<R>) => Observable<R>;\n\nexport function syncToStore(\n store: unknown,\n key: PropertyKey,\n options: SyncToStoreOptions = { completeOnFirstEmission: true }\n) {\n const normalizeError = options.errorNormalizer ?? defaultErrorNormalizer;\n const syncStore = store as SyncToStoreRuntimeStore;\n\n return <R>(source: Observable<R>) => {\n let pipeline = source.pipe(\n tap({\n next: (data: R) => {\n syncStore.update(key, {\n data,\n isLoading: false,\n status: \"Success\",\n errors: undefined,\n });\n },\n error: (error: unknown) => {\n syncStore.update(key, {\n data: undefined,\n isLoading: false,\n status: \"Error\",\n errors: normalizeError(error),\n });\n },\n })\n );\n\n if (options.completeOnFirstEmission) {\n pipeline = pipeline.pipe(take(1));\n }\n\n if (options.callbackAfterComplete) {\n pipeline = pipeline.pipe(finalize(options.callbackAfterComplete));\n }\n\n return pipeline;\n };\n}\n","import type { ResourceErrors } from '@flurryx/core';\n\nexport type ErrorNormalizer = (error: unknown) => ResourceErrors;\n\nexport function defaultErrorNormalizer(error: unknown): ResourceErrors {\n if (\n typeof error === 'object' &&\n error !== null &&\n 'error' in error &&\n typeof (error as Record<string, unknown>).error === 'object'\n ) {\n const inner = (error as { error: Record<string, unknown> }).error;\n if (inner && Array.isArray(inner.errors)) {\n return inner.errors as ResourceErrors;\n }\n }\n\n if (\n typeof error === 'object' &&\n error !== null &&\n 'status' in error &&\n 'message' in error\n ) {\n const typed = error as { status: number; message: string };\n return [\n {\n code: String(typed.status),\n message: typed.message,\n },\n ];\n }\n\n if (error instanceof Error) {\n return [\n {\n code: 'UNKNOWN',\n message: error.message,\n },\n ];\n }\n\n return [\n {\n code: 'UNKNOWN',\n message: String(error),\n },\n ];\n}\n","import { finalize, Observable, take, tap } from \"rxjs\";\nimport type { BaseStore, IStore } from \"@flurryx/store\";\nimport {\n createKeyedResourceData,\n isAnyKeyLoading,\n type KeyedResourceData,\n type KeyedResourceKey,\n type ResourceErrors,\n type ResourceState,\n type ResourceStatus,\n} from \"@flurryx/core\";\nimport {\n defaultErrorNormalizer,\n type ErrorNormalizer,\n} from \"../error/error-normalizer\";\nimport type { SyncToStoreOptions } from \"./sync-to-store\";\n\ninterface SyncToKeyedStoreRuntimeStore {\n get(key: PropertyKey): () => ResourceState<unknown>;\n update(key: PropertyKey, newState: unknown): void;\n}\n\nexport interface SyncToKeyedStoreOptions<R, TValue> extends SyncToStoreOptions {\n mapResponse?: (response: R) => TValue;\n errorNormalizer?: ErrorNormalizer;\n}\n\nfunction withoutKey<TKey extends KeyedResourceKey, TValue>(\n record: Partial<Record<TKey, TValue>>,\n key: TKey\n): Partial<Record<TKey, TValue>> {\n const next: Partial<Record<TKey, TValue>> = {\n ...record,\n };\n delete next[key];\n return next;\n}\n\nexport function syncToKeyedStore<\n TEnum extends Record<string, string | number>,\n TData extends { [K in keyof TEnum]: ResourceState<unknown> },\n TStoreKey extends keyof TData,\n TKey extends KeyedResourceKey,\n TValue,\n R = TValue\n>(\n store: BaseStore<TEnum, TData>,\n storeKey: TStoreKey,\n resourceKey: TKey,\n options?: SyncToKeyedStoreOptions<R, TValue>\n): (source: Observable<R>) => Observable<R>;\n\nexport function syncToKeyedStore<\n TData extends { [K in keyof TData]: ResourceState<unknown> },\n TStoreKey extends keyof TData,\n TKey extends KeyedResourceKey,\n TValue,\n R = TValue\n>(\n store: IStore<TData>,\n storeKey: TStoreKey,\n resourceKey: TKey,\n options?: SyncToKeyedStoreOptions<R, TValue>\n): (source: Observable<R>) => Observable<R>;\n\nexport function syncToKeyedStore(\n store: unknown,\n storeKey: PropertyKey,\n resourceKey: KeyedResourceKey,\n options: SyncToKeyedStoreOptions<unknown, unknown> = {\n completeOnFirstEmission: true,\n }\n) {\n const { completeOnFirstEmission, callbackAfterComplete, mapResponse } =\n options;\n const normalizeError = options.errorNormalizer ?? defaultErrorNormalizer;\n const syncStore = store as SyncToKeyedStoreRuntimeStore;\n\n return (source: Observable<unknown>) => {\n let pipeline = source.pipe(\n tap({\n next: (response: unknown) => {\n const value = mapResponse\n ? mapResponse(response)\n : response;\n\n const storeSignal = syncStore.get(storeKey);\n const state = storeSignal();\n const data =\n (state.data as\n | KeyedResourceData<KeyedResourceKey, unknown>\n | undefined) ??\n createKeyedResourceData<KeyedResourceKey, unknown>();\n\n const nextIsLoading = {\n ...data.isLoading,\n [resourceKey]: false,\n } as Partial<Record<KeyedResourceKey, boolean>>;\n\n const nextStatus: Partial<Record<KeyedResourceKey, ResourceStatus>> = {\n ...data.status,\n [resourceKey]: \"Success\" as ResourceStatus,\n };\n\n const nextData: KeyedResourceData<KeyedResourceKey, unknown> = {\n ...data,\n entities: {\n ...data.entities,\n [resourceKey]: value,\n } as Partial<Record<KeyedResourceKey, unknown>>,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: withoutKey(data.errors, resourceKey),\n };\n\n syncStore.update(storeKey, {\n data: nextData,\n isLoading: isAnyKeyLoading(nextIsLoading),\n status: undefined,\n errors: undefined,\n });\n },\n error: (error: unknown) => {\n const storeSignal = syncStore.get(storeKey);\n const state = storeSignal();\n const data =\n (state.data as\n | KeyedResourceData<KeyedResourceKey, unknown>\n | undefined) ??\n createKeyedResourceData<KeyedResourceKey, unknown>();\n\n const nextIsLoading = {\n ...data.isLoading,\n [resourceKey]: false,\n } as Partial<Record<KeyedResourceKey, boolean>>;\n\n const nextStatus: Partial<Record<KeyedResourceKey, ResourceStatus>> = {\n ...data.status,\n [resourceKey]: \"Error\" as ResourceStatus,\n };\n\n const nextErrors: Partial<Record<KeyedResourceKey, ResourceErrors>> = {\n ...data.errors,\n [resourceKey]: normalizeError(error),\n };\n\n const nextData: KeyedResourceData<KeyedResourceKey, unknown> = {\n ...data,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n syncStore.update(storeKey, {\n data: nextData,\n isLoading: isAnyKeyLoading(nextIsLoading),\n status: undefined,\n errors: undefined,\n });\n },\n })\n );\n\n if (completeOnFirstEmission) {\n pipeline = pipeline.pipe(take(1));\n }\n\n if (callbackAfterComplete) {\n pipeline = pipeline.pipe(finalize(callbackAfterComplete));\n }\n\n return pipeline;\n };\n}\n","import type { Signal } from \"@angular/core\";\nimport { finalize, Observable, of, shareReplay, tap } from \"rxjs\";\nimport type { ResourceState, StoreEnum, KeyedResourceKey } from \"@flurryx/core\";\nimport { isKeyedResourceData } from \"@flurryx/core\";\nimport { CACHE_NO_TIMEOUT, DEFAULT_CACHE_TTL_MS } from \"@flurryx/core\";\n\ntype StoreWithSignal<TKey extends StoreEnum> = {\n get: (key: TKey) => Signal<ResourceState<unknown>> | undefined;\n};\n\ninterface CacheEntry {\n timestamp: number;\n args: string;\n inflight$?: Observable<unknown>;\n}\n\nconst cacheState = new WeakMap<\n object,\n Map<StoreEnum, Map<string, CacheEntry>>\n>();\n\nfunction getStoreKeyMap(\n store: object,\n key: StoreEnum\n): Map<string, CacheEntry> {\n let storeMap = cacheState.get(store);\n if (!storeMap) {\n storeMap = new Map();\n cacheState.set(store, storeMap);\n }\n\n let keyMap = storeMap.get(key);\n if (!keyMap) {\n keyMap = new Map();\n storeMap.set(key, keyMap);\n }\n\n return keyMap;\n}\n\nfunction getCacheEntry(\n store: object,\n key: StoreEnum,\n cacheKey: string\n): CacheEntry | undefined {\n return getStoreKeyMap(store, key).get(cacheKey);\n}\n\nfunction setCacheEntry(\n store: object,\n key: StoreEnum,\n cacheKey: string,\n entry: CacheEntry\n): void {\n getStoreKeyMap(store, key).set(cacheKey, entry);\n}\n\nfunction clearCacheEntry(\n store: object,\n key: StoreEnum,\n cacheKey: string\n): void {\n getStoreKeyMap(store, key).delete(cacheKey);\n}\n\nfunction deriveResourceKey(args: unknown[]): KeyedResourceKey | undefined {\n const key = args[0];\n if (typeof key === \"string\" || typeof key === \"number\") {\n return key;\n }\n return undefined;\n}\n\nfunction isExpired(\n timestamp: number | undefined,\n timeoutMs: number,\n now: number\n): boolean {\n if (timeoutMs === CACHE_NO_TIMEOUT) {\n return false;\n }\n if (timestamp === undefined) {\n return false;\n }\n return now - timestamp >= timeoutMs;\n}\n\ninterface StoreContext {\n store: object;\n storeSignal: Signal<ResourceState<unknown>>;\n currentState: ResourceState<unknown>;\n}\n\nfunction getStoreContext<TTarget, TKey extends StoreEnum>(\n instance: TTarget,\n storeKey: TKey,\n getStore: (i: TTarget) => StoreWithSignal<TKey> | undefined\n): StoreContext | undefined {\n const store = getStore(instance);\n if (!store) {\n return undefined;\n }\n\n const storeSignal = store.get(storeKey);\n if (!storeSignal) {\n return undefined;\n }\n\n const currentState = storeSignal();\n if (currentState === null || currentState === undefined) {\n return undefined;\n }\n\n return { store, storeSignal, currentState };\n}\n\ninterface CacheContext {\n isKeyedCall: boolean;\n resourceKey: KeyedResourceKey | undefined;\n keyedData: ReturnType<typeof isKeyedResourceData> extends true\n ? { entities: object; isLoading: object; status: object; errors: object }\n : undefined;\n runtimeCacheKey: string;\n keyedCacheEntry: CacheEntry | undefined;\n nonKeyedCacheEntry: CacheEntry | undefined;\n}\n\nfunction getCacheContext(\n store: object,\n storeKey: StoreEnum,\n args: unknown[],\n argsString: string,\n currentState: ResourceState<unknown>\n): CacheContext {\n const keyedData = isKeyedResourceData(currentState.data)\n ? currentState.data\n : undefined;\n const resourceKey = keyedData ? deriveResourceKey(args) : undefined;\n const isKeyedCall = keyedData !== undefined && resourceKey !== undefined;\n\n const keyedCacheKey = argsString;\n const nonKeyedCacheKey = \"__single__\";\n const runtimeCacheKey = isKeyedCall ? keyedCacheKey : nonKeyedCacheKey;\n\n const keyedCacheEntry = getCacheEntry(store, storeKey, keyedCacheKey);\n const nonKeyedCacheEntry = getCacheEntry(store, storeKey, nonKeyedCacheKey);\n\n return {\n isKeyedCall,\n resourceKey,\n keyedData: keyedData as CacheContext[\"keyedData\"],\n runtimeCacheKey,\n keyedCacheEntry,\n nonKeyedCacheEntry,\n };\n}\n\nfunction handleCacheErrors(\n store: object,\n storeKey: StoreEnum,\n context: CacheContext,\n currentState: ResourceState<unknown>\n): void {\n if (!context.keyedData && currentState.status === \"Error\") {\n clearCacheEntry(store, storeKey, \"__single__\");\n }\n if (context.keyedData && context.resourceKey !== undefined) {\n const status = (\n context.keyedData as {\n status: Partial<Record<KeyedResourceKey, string>>;\n }\n ).status[context.resourceKey];\n if (status === \"Error\") {\n clearCacheEntry(store, storeKey, context.runtimeCacheKey);\n }\n }\n}\n\ninterface CacheHitResult {\n hit: boolean;\n value?: Observable<unknown>;\n}\n\nfunction handleKeyedCache(\n store: object,\n storeKey: StoreEnum,\n context: CacheContext,\n timeoutMs: number,\n now: number,\n returnObservable: boolean\n): CacheHitResult {\n const { keyedData, resourceKey, keyedCacheEntry, runtimeCacheKey } = context;\n\n if (!keyedData || resourceKey === undefined) {\n return { hit: false };\n }\n\n const typed = keyedData as {\n status: Partial<Record<KeyedResourceKey, string>>;\n entities: Partial<Record<KeyedResourceKey, unknown>>;\n isLoading: Partial<Record<KeyedResourceKey, boolean>>;\n };\n\n const status = typed.status[resourceKey];\n const entity = typed.entities[resourceKey];\n const loading = typed.isLoading[resourceKey] === true;\n\n const expired = isExpired(keyedCacheEntry?.timestamp, timeoutMs, now);\n if (expired) {\n clearCacheEntry(store, storeKey, runtimeCacheKey);\n }\n\n if (!expired && status === \"Success\" && entity !== undefined) {\n if (returnObservable) {\n return { hit: true, value: of(entity) };\n }\n return { hit: true };\n }\n\n if (returnObservable) {\n if (keyedCacheEntry?.inflight$) {\n return { hit: true, value: keyedCacheEntry.inflight$ };\n }\n } else if (loading) {\n return { hit: true };\n }\n\n return { hit: false };\n}\n\nfunction handleNonKeyedCache(\n store: object,\n storeKey: StoreEnum,\n context: CacheContext,\n timeoutMs: number,\n now: number,\n returnObservable: boolean,\n currentState: ResourceState<unknown>,\n argsString: string,\n storeSignal: Signal<ResourceState<unknown>>\n): CacheHitResult {\n const { nonKeyedCacheEntry, runtimeCacheKey } = context;\n\n if (\n returnObservable &&\n nonKeyedCacheEntry?.args === argsString &&\n nonKeyedCacheEntry.inflight$\n ) {\n return { hit: true, value: nonKeyedCacheEntry.inflight$ };\n }\n\n const hasValidCacheState =\n currentState?.status === \"Success\" || currentState?.isLoading === true;\n\n if (\n nonKeyedCacheEntry &&\n isExpired(nonKeyedCacheEntry.timestamp, timeoutMs, now)\n ) {\n clearCacheEntry(store, storeKey, runtimeCacheKey);\n } else if (nonKeyedCacheEntry?.args === argsString && hasValidCacheState) {\n if (returnObservable) {\n if (nonKeyedCacheEntry.inflight$) {\n return { hit: true, value: nonKeyedCacheEntry.inflight$ };\n }\n return { hit: true, value: of(storeSignal().data) };\n }\n return { hit: true };\n }\n\n return { hit: false };\n}\n\nfunction createCachedObservable(\n result: Observable<unknown>,\n store: object,\n storeKey: StoreEnum,\n runtimeCacheKey: string,\n argsString: string\n): Observable<unknown> {\n return result.pipe(\n tap({\n next: () => {\n setCacheEntry(store, storeKey, runtimeCacheKey, {\n timestamp: Date.now(),\n args: argsString,\n });\n },\n error: () => {\n clearCacheEntry(store, storeKey, runtimeCacheKey);\n },\n }),\n finalize(() => {\n const entry = getCacheEntry(store, storeKey, runtimeCacheKey);\n if (entry?.inflight$) {\n const { inflight$: _inflight$, ...rest } = entry;\n setCacheEntry(store, storeKey, runtimeCacheKey, rest);\n }\n }),\n shareReplay({ bufferSize: 1, refCount: true })\n );\n}\n\nexport function SkipIfCached<TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: {\n store: StoreWithSignal<TKey>;\n }) => StoreWithSignal<TKey> | undefined,\n returnObservable?: boolean,\n timeoutMs?: number\n): MethodDecorator;\nexport function SkipIfCached<TTarget, TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: TTarget) => StoreWithSignal<TKey> | undefined,\n returnObservable?: boolean,\n timeoutMs?: number\n): MethodDecorator;\nexport function SkipIfCached<TTarget, TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: TTarget) => StoreWithSignal<TKey> | undefined,\n returnObservable = false,\n timeoutMs = DEFAULT_CACHE_TTL_MS\n): MethodDecorator {\n return function (\n _target: unknown,\n _propertyKey: string | symbol,\n descriptor: PropertyDescriptor\n ) {\n const originalMethod = descriptor.value as (\n this: TTarget,\n ...args: unknown[]\n ) => unknown;\n\n descriptor.value = function (this: TTarget, ...args: unknown[]) {\n const storeContext = getStoreContext(this, storeKey, storeGetter);\n if (!storeContext) {\n return originalMethod.apply(this, args);\n }\n const { store, storeSignal, currentState } = storeContext;\n\n const argsString = JSON.stringify(args);\n const now = Date.now();\n const cacheContext = getCacheContext(\n store,\n storeKey,\n args,\n argsString,\n currentState\n );\n\n handleCacheErrors(store, storeKey, cacheContext, currentState);\n\n let cacheHit: CacheHitResult;\n\n if (cacheContext.isKeyedCall) {\n cacheHit = handleKeyedCache(\n store,\n storeKey,\n cacheContext,\n timeoutMs,\n now,\n returnObservable\n );\n } else {\n cacheHit = handleNonKeyedCache(\n store,\n storeKey,\n cacheContext,\n timeoutMs,\n now,\n returnObservable,\n currentState,\n argsString,\n storeSignal\n );\n }\n\n if (cacheHit.hit) {\n return cacheHit.value;\n }\n\n const result = originalMethod.apply(this, args);\n\n if (!returnObservable) {\n setCacheEntry(store, storeKey, cacheContext.runtimeCacheKey, {\n timestamp: now,\n args: argsString,\n });\n return result;\n }\n\n const inflight$ = createCachedObservable(\n result as Observable<unknown>,\n store,\n storeKey,\n cacheContext.runtimeCacheKey,\n argsString\n );\n\n setCacheEntry(store, storeKey, cacheContext.runtimeCacheKey, {\n timestamp: now,\n args: argsString,\n inflight$,\n });\n\n return inflight$;\n };\n\n return descriptor;\n };\n}\n","import type { StoreEnum, KeyedResourceKey } from '@flurryx/core';\n\ntype StoreWithLoading<TKey extends StoreEnum> = {\n startLoading: (key: TKey) => void;\n};\n\nexport function Loading<TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: {\n store: StoreWithLoading<TKey>;\n }) => StoreWithLoading<TKey>\n): MethodDecorator;\nexport function Loading<TTarget, TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: TTarget) => StoreWithLoading<TKey>\n): MethodDecorator;\nexport function Loading<TTarget, TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: TTarget) => StoreWithLoading<TKey>\n) {\n return function (\n _target: unknown,\n _propertyKey: string | symbol,\n descriptor: PropertyDescriptor\n ) {\n const originalMethod = descriptor.value as (\n this: unknown,\n ...args: unknown[]\n ) => unknown;\n\n descriptor.value = function (this: TTarget, ...args: unknown[]) {\n const store = storeGetter(this);\n\n const resourceKey = args[0];\n const canKey =\n typeof resourceKey === 'string' || typeof resourceKey === 'number';\n const hasKeyed =\n typeof store === 'object' &&\n store !== null &&\n 'startKeyedLoading' in store &&\n typeof (store as { startKeyedLoading?: unknown }).startKeyedLoading ===\n 'function';\n\n if (canKey && hasKeyed) {\n (\n store as unknown as {\n startKeyedLoading: (\n key: TKey,\n resourceKey: KeyedResourceKey\n ) => void;\n }\n ).startKeyedLoading(storeKey, resourceKey as KeyedResourceKey);\n } else {\n store?.startLoading(storeKey);\n }\n return originalMethod.apply(this, args);\n };\n\n return descriptor;\n };\n}\n"],"mappings":"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","names":["finalize","take","tap","tap","take","finalize","finalize","tap"]}
|
|
1
|
+
{"version":3,"sources":["../src/operators/sync-to-store.ts","../src/error/error-normalizer.ts","../src/operators/sync-to-keyed-store.ts","../src/decorators/skip-if-cached.ts","../src/decorators/loading.ts"],"sourcesContent":["import { finalize, Observable, take, tap } from \"rxjs\";\nimport type { BaseStore, IStore } from \"@flurryx/store\";\nimport type { ResourceState } from \"@flurryx/core\";\nimport {\n defaultErrorNormalizer,\n type ErrorNormalizer,\n} from \"../error/error-normalizer\";\n\nexport interface SyncToStoreOptions {\n completeOnFirstEmission?: boolean;\n callbackAfterComplete?: () => void;\n errorNormalizer?: ErrorNormalizer;\n}\n\ninterface SyncToStoreRuntimeStore {\n update(key: PropertyKey, newState: unknown): void;\n}\n\nexport function syncToStore<\n TEnum extends Record<string, string | number>,\n TData extends { [K in keyof TEnum]: ResourceState<unknown> },\n K extends keyof TData,\n>(\n store: BaseStore<TEnum, TData>,\n key: K,\n options?: SyncToStoreOptions\n): <R>(source: Observable<R>) => Observable<R>;\n\nexport function syncToStore<\n TData extends { [K in keyof TData]: ResourceState<unknown> },\n K extends keyof TData,\n>(\n store: IStore<TData>,\n key: K,\n options?: SyncToStoreOptions\n): <R>(source: Observable<R>) => Observable<R>;\n\nexport function syncToStore(\n store: unknown,\n key: PropertyKey,\n options: SyncToStoreOptions = { completeOnFirstEmission: true }\n) {\n const normalizeError = options.errorNormalizer ?? defaultErrorNormalizer;\n const syncStore = store as SyncToStoreRuntimeStore;\n\n return <R>(source: Observable<R>) => {\n let pipeline = source.pipe(\n tap({\n next: (data: R) => {\n syncStore.update(key, {\n data,\n isLoading: false,\n status: \"Success\",\n errors: undefined,\n });\n },\n error: (error: unknown) => {\n syncStore.update(key, {\n data: undefined,\n isLoading: false,\n status: \"Error\",\n errors: normalizeError(error),\n });\n },\n })\n );\n\n if (options.completeOnFirstEmission) {\n pipeline = pipeline.pipe(take(1));\n }\n\n if (options.callbackAfterComplete) {\n pipeline = pipeline.pipe(finalize(options.callbackAfterComplete));\n }\n\n return pipeline;\n };\n}\n","import type { ResourceErrors } from '@flurryx/core';\n\nexport type ErrorNormalizer = (error: unknown) => ResourceErrors;\n\nexport function defaultErrorNormalizer(error: unknown): ResourceErrors {\n if (\n typeof error === 'object' &&\n error !== null &&\n 'error' in error &&\n typeof (error as Record<string, unknown>).error === 'object'\n ) {\n const inner = (error as { error: Record<string, unknown> }).error;\n if (inner && Array.isArray(inner.errors)) {\n return inner.errors as ResourceErrors;\n }\n }\n\n if (\n typeof error === 'object' &&\n error !== null &&\n 'status' in error &&\n 'message' in error\n ) {\n const typed = error as { status: number; message: string };\n return [\n {\n code: String(typed.status),\n message: typed.message,\n },\n ];\n }\n\n if (error instanceof Error) {\n return [\n {\n code: 'UNKNOWN',\n message: error.message,\n },\n ];\n }\n\n return [\n {\n code: 'UNKNOWN',\n message: String(error),\n },\n ];\n}\n","import { finalize, Observable, take, tap } from \"rxjs\";\nimport type { BaseStore, IStore } from \"@flurryx/store\";\nimport {\n createKeyedResourceData,\n isAnyKeyLoading,\n type KeyedResourceData,\n type KeyedResourceKey,\n type ResourceErrors,\n type ResourceState,\n type ResourceStatus,\n} from \"@flurryx/core\";\nimport {\n defaultErrorNormalizer,\n type ErrorNormalizer,\n} from \"../error/error-normalizer\";\nimport type { SyncToStoreOptions } from \"./sync-to-store\";\n\ninterface SyncToKeyedStoreRuntimeStore {\n get(key: PropertyKey): () => ResourceState<unknown>;\n update(key: PropertyKey, newState: unknown): void;\n}\n\nexport interface SyncToKeyedStoreOptions<R, TValue> extends SyncToStoreOptions {\n mapResponse?: (response: R) => TValue;\n errorNormalizer?: ErrorNormalizer;\n}\n\nfunction withoutKey<TKey extends KeyedResourceKey, TValue>(\n record: Partial<Record<TKey, TValue>>,\n key: TKey\n): Partial<Record<TKey, TValue>> {\n const next: Partial<Record<TKey, TValue>> = {\n ...record,\n };\n delete next[key];\n return next;\n}\n\nexport function syncToKeyedStore<\n TEnum extends Record<string, string | number>,\n TData extends { [K in keyof TEnum]: ResourceState<unknown> },\n TStoreKey extends keyof TData,\n TKey extends KeyedResourceKey,\n TValue,\n R = TValue\n>(\n store: BaseStore<TEnum, TData>,\n storeKey: TStoreKey,\n resourceKey: TKey,\n options?: SyncToKeyedStoreOptions<R, TValue>\n): (source: Observable<R>) => Observable<R>;\n\nexport function syncToKeyedStore<\n TData extends { [K in keyof TData]: ResourceState<unknown> },\n TStoreKey extends keyof TData,\n TKey extends KeyedResourceKey,\n TValue,\n R = TValue\n>(\n store: IStore<TData>,\n storeKey: TStoreKey,\n resourceKey: TKey,\n options?: SyncToKeyedStoreOptions<R, TValue>\n): (source: Observable<R>) => Observable<R>;\n\nexport function syncToKeyedStore(\n store: unknown,\n storeKey: PropertyKey,\n resourceKey: KeyedResourceKey,\n options: SyncToKeyedStoreOptions<unknown, unknown> = {\n completeOnFirstEmission: true,\n }\n) {\n const { completeOnFirstEmission, callbackAfterComplete, mapResponse } =\n options;\n const normalizeError = options.errorNormalizer ?? defaultErrorNormalizer;\n const syncStore = store as SyncToKeyedStoreRuntimeStore;\n\n return (source: Observable<unknown>) => {\n let pipeline = source.pipe(\n tap({\n next: (response: unknown) => {\n const value = mapResponse\n ? mapResponse(response)\n : response;\n\n const storeSignal = syncStore.get(storeKey);\n const state = storeSignal();\n const data =\n (state.data as\n | KeyedResourceData<KeyedResourceKey, unknown>\n | undefined) ??\n createKeyedResourceData<KeyedResourceKey, unknown>();\n\n const nextIsLoading = {\n ...data.isLoading,\n [resourceKey]: false,\n } as Partial<Record<KeyedResourceKey, boolean>>;\n\n const nextStatus: Partial<Record<KeyedResourceKey, ResourceStatus>> = {\n ...data.status,\n [resourceKey]: \"Success\" as ResourceStatus,\n };\n\n const nextData: KeyedResourceData<KeyedResourceKey, unknown> = {\n ...data,\n entities: {\n ...data.entities,\n [resourceKey]: value,\n } as Partial<Record<KeyedResourceKey, unknown>>,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: withoutKey(data.errors, resourceKey),\n };\n\n syncStore.update(storeKey, {\n data: nextData,\n isLoading: isAnyKeyLoading(nextIsLoading),\n status: undefined,\n errors: undefined,\n });\n },\n error: (error: unknown) => {\n const storeSignal = syncStore.get(storeKey);\n const state = storeSignal();\n const data =\n (state.data as\n | KeyedResourceData<KeyedResourceKey, unknown>\n | undefined) ??\n createKeyedResourceData<KeyedResourceKey, unknown>();\n\n const nextIsLoading = {\n ...data.isLoading,\n [resourceKey]: false,\n } as Partial<Record<KeyedResourceKey, boolean>>;\n\n const nextStatus: Partial<Record<KeyedResourceKey, ResourceStatus>> = {\n ...data.status,\n [resourceKey]: \"Error\" as ResourceStatus,\n };\n\n const nextErrors: Partial<Record<KeyedResourceKey, ResourceErrors>> = {\n ...data.errors,\n [resourceKey]: normalizeError(error),\n };\n\n const nextData: KeyedResourceData<KeyedResourceKey, unknown> = {\n ...data,\n isLoading: nextIsLoading,\n status: nextStatus,\n errors: nextErrors,\n };\n\n syncStore.update(storeKey, {\n data: nextData,\n isLoading: isAnyKeyLoading(nextIsLoading),\n status: undefined,\n errors: undefined,\n });\n },\n })\n );\n\n if (completeOnFirstEmission) {\n pipeline = pipeline.pipe(take(1));\n }\n\n if (callbackAfterComplete) {\n pipeline = pipeline.pipe(finalize(callbackAfterComplete));\n }\n\n return pipeline;\n };\n}\n","import type { Signal } from \"@angular/core\";\nimport { finalize, Observable, of, shareReplay, tap } from \"rxjs\";\nimport {\n isKeyedResourceData,\n CACHE_NO_TIMEOUT,\n DEFAULT_CACHE_TTL_MS,\n} from \"@flurryx/core\";\nimport type { ResourceState, StoreEnum, KeyedResourceKey } from \"@flurryx/core\";\n\ntype StoreWithSignal<TKey extends StoreEnum> = {\n get: (key: TKey) => Signal<ResourceState<unknown>> | undefined;\n};\n\ninterface CacheEntry {\n timestamp: number;\n args: string;\n inflight$?: Observable<unknown>;\n}\n\nconst cacheState = new WeakMap<\n object,\n Map<StoreEnum, Map<string, CacheEntry>>\n>();\n\nfunction getStoreKeyMap(\n store: object,\n key: StoreEnum\n): Map<string, CacheEntry> {\n let storeMap = cacheState.get(store);\n if (!storeMap) {\n storeMap = new Map();\n cacheState.set(store, storeMap);\n }\n\n let keyMap = storeMap.get(key);\n if (!keyMap) {\n keyMap = new Map();\n storeMap.set(key, keyMap);\n }\n\n return keyMap;\n}\n\nfunction getCacheEntry(\n store: object,\n key: StoreEnum,\n cacheKey: string\n): CacheEntry | undefined {\n return getStoreKeyMap(store, key).get(cacheKey);\n}\n\nfunction setCacheEntry(\n store: object,\n key: StoreEnum,\n cacheKey: string,\n entry: CacheEntry\n): void {\n getStoreKeyMap(store, key).set(cacheKey, entry);\n}\n\nfunction clearCacheEntry(\n store: object,\n key: StoreEnum,\n cacheKey: string\n): void {\n getStoreKeyMap(store, key).delete(cacheKey);\n}\n\nfunction deriveResourceKey(args: unknown[]): KeyedResourceKey | undefined {\n const key = args[0];\n if (typeof key === \"string\" || typeof key === \"number\") {\n return key;\n }\n return undefined;\n}\n\nfunction isExpired(\n timestamp: number | undefined,\n timeoutMs: number,\n now: number\n): boolean {\n if (timeoutMs === CACHE_NO_TIMEOUT) {\n return false;\n }\n if (timestamp === undefined) {\n return false;\n }\n return now - timestamp >= timeoutMs;\n}\n\ninterface StoreContext {\n store: object;\n storeSignal: Signal<ResourceState<unknown>>;\n currentState: ResourceState<unknown>;\n}\n\nfunction getStoreContext<TTarget, TKey extends StoreEnum>(\n instance: TTarget,\n storeKey: TKey,\n getStore: (i: TTarget) => StoreWithSignal<TKey> | undefined\n): StoreContext | undefined {\n const store = getStore(instance);\n if (!store) {\n return undefined;\n }\n\n const storeSignal = store.get(storeKey);\n if (!storeSignal) {\n return undefined;\n }\n\n const currentState = storeSignal();\n if (currentState === null || currentState === undefined) {\n return undefined;\n }\n\n return { store, storeSignal, currentState };\n}\n\ninterface CacheContext {\n isKeyedCall: boolean;\n resourceKey: KeyedResourceKey | undefined;\n keyedData: ReturnType<typeof isKeyedResourceData> extends true\n ? { entities: object; isLoading: object; status: object; errors: object }\n : undefined;\n runtimeCacheKey: string;\n keyedCacheEntry: CacheEntry | undefined;\n nonKeyedCacheEntry: CacheEntry | undefined;\n}\n\nfunction getCacheContext(\n store: object,\n storeKey: StoreEnum,\n args: unknown[],\n argsString: string,\n currentState: ResourceState<unknown>\n): CacheContext {\n const keyedData = isKeyedResourceData(currentState.data)\n ? currentState.data\n : undefined;\n const resourceKey = keyedData ? deriveResourceKey(args) : undefined;\n const isKeyedCall = keyedData !== undefined && resourceKey !== undefined;\n\n const keyedCacheKey = argsString;\n const nonKeyedCacheKey = \"__single__\";\n const runtimeCacheKey = isKeyedCall ? keyedCacheKey : nonKeyedCacheKey;\n\n const keyedCacheEntry = getCacheEntry(store, storeKey, keyedCacheKey);\n const nonKeyedCacheEntry = getCacheEntry(store, storeKey, nonKeyedCacheKey);\n\n return {\n isKeyedCall,\n resourceKey,\n keyedData: keyedData as CacheContext[\"keyedData\"],\n runtimeCacheKey,\n keyedCacheEntry,\n nonKeyedCacheEntry,\n };\n}\n\nfunction handleCacheErrors(\n store: object,\n storeKey: StoreEnum,\n context: CacheContext,\n currentState: ResourceState<unknown>\n): void {\n if (!context.keyedData && currentState.status === \"Error\") {\n clearCacheEntry(store, storeKey, \"__single__\");\n }\n if (context.keyedData && context.resourceKey !== undefined) {\n const status = (\n context.keyedData as {\n status: Partial<Record<KeyedResourceKey, string>>;\n }\n ).status[context.resourceKey];\n if (status === \"Error\") {\n clearCacheEntry(store, storeKey, context.runtimeCacheKey);\n }\n }\n}\n\ninterface CacheHitResult {\n hit: boolean;\n value?: Observable<unknown>;\n}\n\nfunction handleKeyedCache(\n store: object,\n storeKey: StoreEnum,\n context: CacheContext,\n timeoutMs: number,\n now: number,\n returnObservable: boolean\n): CacheHitResult {\n const { keyedData, resourceKey, keyedCacheEntry, runtimeCacheKey } = context;\n\n if (!keyedData || resourceKey === undefined) {\n return { hit: false };\n }\n\n const typed = keyedData as {\n status: Partial<Record<KeyedResourceKey, string>>;\n entities: Partial<Record<KeyedResourceKey, unknown>>;\n isLoading: Partial<Record<KeyedResourceKey, boolean>>;\n };\n\n const status = typed.status[resourceKey];\n const entity = typed.entities[resourceKey];\n const loading = typed.isLoading[resourceKey] === true;\n\n const expired = isExpired(keyedCacheEntry?.timestamp, timeoutMs, now);\n if (expired) {\n clearCacheEntry(store, storeKey, runtimeCacheKey);\n }\n\n if (!expired && status === \"Success\" && entity !== undefined) {\n if (returnObservable) {\n return { hit: true, value: of(entity) };\n }\n return { hit: true };\n }\n\n if (returnObservable) {\n if (keyedCacheEntry?.inflight$) {\n return { hit: true, value: keyedCacheEntry.inflight$ };\n }\n } else if (loading) {\n return { hit: true };\n }\n\n return { hit: false };\n}\n\ninterface NonKeyedCacheExtra {\n readonly currentState: ResourceState<unknown>;\n readonly argsString: string;\n readonly storeSignal: Signal<ResourceState<unknown>>;\n}\n\nfunction handleNonKeyedCache(\n store: object,\n storeKey: StoreEnum,\n context: CacheContext,\n timeoutMs: number,\n now: number,\n returnObservable: boolean,\n extra: NonKeyedCacheExtra\n): CacheHitResult {\n const { nonKeyedCacheEntry, runtimeCacheKey } = context;\n const { currentState, argsString, storeSignal } = extra;\n\n if (\n returnObservable &&\n nonKeyedCacheEntry?.args === argsString &&\n nonKeyedCacheEntry.inflight$\n ) {\n return { hit: true, value: nonKeyedCacheEntry.inflight$ };\n }\n\n const hasValidCacheState =\n currentState?.status === \"Success\" || currentState?.isLoading === true;\n\n if (\n nonKeyedCacheEntry &&\n isExpired(nonKeyedCacheEntry.timestamp, timeoutMs, now)\n ) {\n clearCacheEntry(store, storeKey, runtimeCacheKey);\n } else if (nonKeyedCacheEntry?.args === argsString && hasValidCacheState) {\n if (returnObservable) {\n if (nonKeyedCacheEntry.inflight$) {\n return { hit: true, value: nonKeyedCacheEntry.inflight$ };\n }\n return { hit: true, value: of(storeSignal().data) };\n }\n return { hit: true };\n }\n\n return { hit: false };\n}\n\nfunction createCachedObservable(\n result: Observable<unknown>,\n store: object,\n storeKey: StoreEnum,\n runtimeCacheKey: string,\n argsString: string\n): Observable<unknown> {\n return result.pipe(\n tap({\n next: () => {\n setCacheEntry(store, storeKey, runtimeCacheKey, {\n timestamp: Date.now(),\n args: argsString,\n });\n },\n error: () => {\n clearCacheEntry(store, storeKey, runtimeCacheKey);\n },\n }),\n finalize(() => {\n const entry = getCacheEntry(store, storeKey, runtimeCacheKey);\n if (entry?.inflight$) {\n const { inflight$: _inflight$, ...rest } = entry;\n setCacheEntry(store, storeKey, runtimeCacheKey, rest);\n }\n }),\n shareReplay({ bufferSize: 1, refCount: true })\n );\n}\n\nexport function SkipIfCached<TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: {\n store: StoreWithSignal<TKey>;\n }) => StoreWithSignal<TKey> | undefined,\n returnObservable?: boolean,\n timeoutMs?: number\n): MethodDecorator;\nexport function SkipIfCached<TTarget, TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: TTarget) => StoreWithSignal<TKey> | undefined,\n returnObservable?: boolean,\n timeoutMs?: number\n): MethodDecorator;\nexport function SkipIfCached<TTarget, TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: TTarget) => StoreWithSignal<TKey> | undefined,\n returnObservable = false,\n timeoutMs = DEFAULT_CACHE_TTL_MS\n): MethodDecorator {\n return function (\n _target: unknown,\n _propertyKey: string | symbol,\n descriptor: PropertyDescriptor\n ) {\n const originalMethod = descriptor.value as (\n this: TTarget,\n ...args: unknown[]\n ) => unknown;\n\n descriptor.value = function (this: TTarget, ...args: unknown[]) {\n const storeContext = getStoreContext(this, storeKey, storeGetter);\n if (!storeContext) {\n return originalMethod.apply(this, args);\n }\n const { store, storeSignal, currentState } = storeContext;\n\n const argsString = JSON.stringify(args);\n const now = Date.now();\n const cacheContext = getCacheContext(\n store,\n storeKey,\n args,\n argsString,\n currentState\n );\n\n handleCacheErrors(store, storeKey, cacheContext, currentState);\n\n let cacheHit: CacheHitResult;\n\n if (cacheContext.isKeyedCall) {\n cacheHit = handleKeyedCache(\n store,\n storeKey,\n cacheContext,\n timeoutMs,\n now,\n returnObservable\n );\n } else {\n cacheHit = handleNonKeyedCache(\n store,\n storeKey,\n cacheContext,\n timeoutMs,\n now,\n returnObservable,\n { currentState, argsString, storeSignal }\n );\n }\n\n if (cacheHit.hit) {\n return cacheHit.value;\n }\n\n const result = originalMethod.apply(this, args);\n\n if (!returnObservable) {\n setCacheEntry(store, storeKey, cacheContext.runtimeCacheKey, {\n timestamp: now,\n args: argsString,\n });\n return result;\n }\n\n const inflight$ = createCachedObservable(\n result as Observable<unknown>,\n store,\n storeKey,\n cacheContext.runtimeCacheKey,\n argsString\n );\n\n setCacheEntry(store, storeKey, cacheContext.runtimeCacheKey, {\n timestamp: now,\n args: argsString,\n inflight$,\n });\n\n return inflight$;\n };\n\n return descriptor;\n };\n}\n","import type { StoreEnum, KeyedResourceKey } from '@flurryx/core';\n\ntype StoreWithLoading<TKey extends StoreEnum> = {\n startLoading: (key: TKey) => void;\n};\n\nexport function Loading<TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: {\n store: StoreWithLoading<TKey>;\n }) => StoreWithLoading<TKey>\n): MethodDecorator;\nexport function Loading<TTarget, TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: TTarget) => StoreWithLoading<TKey>\n): MethodDecorator;\nexport function Loading<TTarget, TKey extends StoreEnum>(\n storeKey: TKey,\n storeGetter: (instance: TTarget) => StoreWithLoading<TKey>\n) {\n return function (\n _target: unknown,\n _propertyKey: string | symbol,\n descriptor: PropertyDescriptor\n ) {\n const originalMethod = descriptor.value as (\n this: unknown,\n ...args: unknown[]\n ) => unknown;\n\n descriptor.value = function (this: TTarget, ...args: unknown[]) {\n const store = storeGetter(this);\n\n const resourceKey = args[0];\n const canKey =\n typeof resourceKey === 'string' || typeof resourceKey === 'number';\n const hasKeyed =\n typeof store === 'object' &&\n store !== null &&\n 'startKeyedLoading' in store &&\n typeof (store as { startKeyedLoading?: unknown }).startKeyedLoading ===\n 'function';\n\n if (canKey && hasKeyed) {\n (\n store as unknown as {\n startKeyedLoading: (\n key: TKey,\n resourceKey: KeyedResourceKey\n ) => void;\n }\n ).startKeyedLoading(storeKey, resourceKey as KeyedResourceKey);\n } else {\n store?.startLoading(storeKey);\n }\n return originalMethod.apply(this, args);\n };\n\n return descriptor;\n };\n}\n"],"mappings":"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","names":["finalize","take","tap","tap","take","finalize","finalize","tap"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flurryx/rx",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "RxJS operators and decorators for flurryx stores",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"sideEffects": false,
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@flurryx/core": "0.8.0",
|
|
42
|
-
"@flurryx/store": "0.8.
|
|
42
|
+
"@flurryx/store": "0.8.2"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"@angular/core": ">=17.0.0",
|