UNPKG

subsiphon

Version:
1 lines 9.86 kB
{"version":3,"file":"index.esm.mjs","sources":["../src/subsiphon.ts","../src/siphon.pipe.ts","../src/siphon.decorator.ts"],"sourcesContent":["import { Subscription } from \"rxjs\";\n\nexport class SubSiphon {\n private subs: Record<PropertyKey, Subscription> = {};\n private index: number = 0;\n\n constructor() {\n return new Proxy(this, {\n set(self: SubSiphon, prop: PropertyKey, sub: any): boolean {\n if (prop in self) {\n if (prop === \"add\") {\n self.add = sub;\n return true;\n }\n console.error(\n `Attempted to add Subscription value to SubSiphon class methods: ${String(prop)} =`,\n sub,\n );\n return false;\n }\n if (!(sub instanceof Subscription)) {\n console.error(`Attempted to add non-Subscription value to SubSiphon: ${String(prop)} =`, sub);\n return false;\n }\n if (prop in self.subs) {\n self.subs[prop].unsubscribe();\n delete self.subs[prop];\n }\n self.subs[prop] = sub;\n\n return true;\n },\n get(self: SubSiphon, prop: PropertyKey): any {\n if (prop in self) {\n return (self as any)[prop];\n }\n if (self.subs.hasOwnProperty(prop)) {\n return self.subs[prop];\n }\n return undefined;\n },\n has: (self: SubSiphon, prop: PropertyKey): boolean => prop in self.subs,\n deleteProperty: (self: SubSiphon, prop: PropertyKey): boolean => {\n if (self.subs[prop]) {\n self.subs[prop].unsubscribe();\n delete self.subs[prop];\n }\n return true;\n },\n ownKeys: (self: SubSiphon): ArrayLike<string | symbol> => Object.keys(self.subs),\n getOwnPropertyDescriptor(self: SubSiphon, prop: PropertyKey) {\n if (prop in self.subs) {\n return {\n configurable: true,\n enumerable: true,\n writable: true,\n value: self.subs[prop],\n };\n }\n return undefined;\n },\n }) as SubSiphon & Record<PropertyKey, Subscription>;\n }\n\n public set add(sub: Subscription) {\n let index = this.index;\n while (index in this.subs) {\n index += 1;\n }\n this.index = index;\n this.subs[index] = sub;\n }\n\n public unsubscribe(): void {\n for (const key in this.subs) {\n this.subs[key].unsubscribe();\n }\n }\n\n public destroy(): void {\n for (const key in this.subs) {\n this.subs[key].unsubscribe();\n delete this.subs[key];\n }\n }\n}\n\nexport function createSubSiphon(): SubSiphon & Record<PropertyKey, Subscription> {\n return new SubSiphon() as any;\n}\n","import { MonoTypeOperatorFunction, Subject, takeUntil } from 'rxjs';\n\nconst destroySubjects = new WeakMap<object, Subject<void>>();\n\nexport function siphon<T>(instance: object): MonoTypeOperatorFunction<T> {\n if (!destroySubjects.has(instance)) {\n const destroy$ = new Subject<void>();\n destroySubjects.set(instance, destroy$);\n\n const originalDestroy = (instance as any).ngOnDestroy;\n\n (instance as any).ngOnDestroy = function () {\n destroy$.next();\n destroy$.complete();\n destroySubjects.delete(instance);\n if (typeof originalDestroy === 'function') {\n originalDestroy.apply(this);\n }\n };\n }\n\n return takeUntil<T>(destroySubjects.get(instance)!);\n}","import { Unsubscribable } from \"rxjs\";\n\nexport interface SiphonOptions {\n include?: string[];\n exclude?: string[];\n log?: boolean;\n}\n\nconst isUnsubscribable = (value: any): value is Unsubscribable => value && typeof value.unsubscribe === \"function\";\n\nconst tryUnsubscribe = (value: any, key: string, options: SiphonOptions): void => {\n if (isUnsubscribable(value)) {\n try {\n value.unsubscribe();\n if (options.log) {\n console.debug(`[Siphon] Unsubscribed: ${key}`);\n }\n } catch (err) {\n console.error(`[Siphon] Error unsubscribing ${key}`, err);\n }\n } else if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n const item = value[i];\n if (isUnsubscribable(item)) {\n try {\n item.unsubscribe();\n if (options.log) {\n console.debug(`[Siphon] Unsubscribed: ${key}[${i}]`);\n }\n } catch (err) {\n console.error(`[Siphon] Error unsubscribing ${key}[${i}]`, err);\n }\n } else if (options.log) {\n console.warn(`[Siphon] Skipped non-unsubscribable item in ${key}[${i}]`);\n }\n }\n } else if (options.log) {\n console.warn(`[Siphon] ${key} is not unsubscribable`);\n }\n};\n\nexport function Siphon(options: SiphonOptions = {}): ClassDecorator {\n return function (target: any) {\n const originalDestroy = target.prototype.ngOnDestroy;\n\n target.prototype.ngOnDestroy = function () {\n const instance = this;\n const allKeys = Object.keys(instance);\n const keysToCheck = options.include\n ? options.include\n : allKeys.filter((key) => !options.exclude?.includes(key));\n\n for (const key of keysToCheck) {\n if (!allKeys.includes(key)) {\n console.warn(`[Siphon] Property \"${key}\" does not exist on instance.`);\n continue;\n }\n\n tryUnsubscribe(instance[key], key, options);\n }\n\n if (typeof originalDestroy === \"function\") {\n originalDestroy.apply(this);\n }\n };\n };\n}\n"],"names":["SubSiphon","this","subs","index","Proxy","set","self","prop","sub","add","console","error","String","Subscription","unsubscribe","get","hasOwnProperty","has","deleteProperty","ownKeys","Object","keys","getOwnPropertyDescriptor","configurable","enumerable","writable","value","_proto","prototype","key","destroy","createSubSiphon","destroySubjects","WeakMap","siphon","instance","destroy$","Subject","originalDestroy","ngOnDestroy","next","complete","apply","takeUntil","isUnsubscribable","tryUnsubscribe","options","log","debug","err","Array","isArray","i","length","item","warn","Siphon","target","_step","allKeys","keysToCheck","include","filter","_options$exclude","exclude","includes","_iterator","_createForOfIteratorHelperLoose","done"],"mappings":"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"}