joopjs 2.0.5 → 2.1.0

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.
Files changed (146) hide show
  1. package/.claude/skills/auth.md +235 -0
  2. package/.claude/skills/banking.md +377 -0
  3. package/.claude/skills/encryption.md +265 -0
  4. package/.claude/skills/finance.md +248 -0
  5. package/.claude/skills/observables.md +270 -0
  6. package/.claude/skills/security.md +240 -0
  7. package/.claude/skills/setup.md +196 -0
  8. package/.cursor/rules/joopjs.mdc +150 -0
  9. package/.github/copilot-instructions.md +143 -0
  10. package/.windsurf/rules/joopjs.md +226 -0
  11. package/CHANGELOG.md +81 -0
  12. package/README.md +47 -7
  13. package/ai-rules/AGENTS.md +241 -0
  14. package/ai-rules/GEMINI.md +183 -0
  15. package/dist/ai/index.js +15 -3
  16. package/dist/ai/index.js.map +1 -1
  17. package/dist/ai/index.mjs +15 -3
  18. package/dist/ai/index.mjs.map +1 -1
  19. package/dist/analytics/index.js +10 -2
  20. package/dist/analytics/index.js.map +1 -1
  21. package/dist/analytics/index.mjs +10 -2
  22. package/dist/analytics/index.mjs.map +1 -1
  23. package/dist/angular/index.d.mts +98 -27
  24. package/dist/angular/index.d.ts +98 -27
  25. package/dist/angular/index.js +44 -0
  26. package/dist/angular/index.js.map +1 -1
  27. package/dist/angular/index.mjs +39 -1
  28. package/dist/angular/index.mjs.map +1 -1
  29. package/dist/api/index.js +15 -3
  30. package/dist/api/index.js.map +1 -1
  31. package/dist/api/index.mjs +15 -3
  32. package/dist/api/index.mjs.map +1 -1
  33. package/dist/auth/index.js +15 -3
  34. package/dist/auth/index.js.map +1 -1
  35. package/dist/auth/index.mjs +15 -3
  36. package/dist/auth/index.mjs.map +1 -1
  37. package/dist/banking/index.js +15 -3
  38. package/dist/banking/index.js.map +1 -1
  39. package/dist/banking/index.mjs +15 -3
  40. package/dist/banking/index.mjs.map +1 -1
  41. package/dist/cache/index.js +15 -3
  42. package/dist/cache/index.js.map +1 -1
  43. package/dist/cache/index.mjs +15 -3
  44. package/dist/cache/index.mjs.map +1 -1
  45. package/dist/{index-DFqEoX_l.d.ts → consent.service-CIHNtx9h.d.ts} +1 -2
  46. package/dist/{index-B_ksKpS1.d.mts → consent.service-DQ-JAEJx.d.mts} +1 -2
  47. package/dist/core/index.d.mts +34 -1
  48. package/dist/core/index.d.ts +34 -1
  49. package/dist/core/index.js +56 -5
  50. package/dist/core/index.js.map +1 -1
  51. package/dist/core/index.mjs +54 -6
  52. package/dist/core/index.mjs.map +1 -1
  53. package/dist/deeplink/index.js +15 -3
  54. package/dist/deeplink/index.js.map +1 -1
  55. package/dist/deeplink/index.mjs +15 -3
  56. package/dist/deeplink/index.mjs.map +1 -1
  57. package/dist/device/index.js +15 -3
  58. package/dist/device/index.js.map +1 -1
  59. package/dist/device/index.mjs +15 -3
  60. package/dist/device/index.mjs.map +1 -1
  61. package/dist/forms/index.js +15 -3
  62. package/dist/forms/index.js.map +1 -1
  63. package/dist/forms/index.mjs +15 -3
  64. package/dist/forms/index.mjs.map +1 -1
  65. package/dist/i18n/index.js +15 -3
  66. package/dist/i18n/index.js.map +1 -1
  67. package/dist/i18n/index.mjs +15 -3
  68. package/dist/i18n/index.mjs.map +1 -1
  69. package/dist/index.d.mts +2 -2
  70. package/dist/index.d.ts +2 -2
  71. package/dist/index.js +50 -8
  72. package/dist/index.js.map +1 -1
  73. package/dist/index.mjs +50 -8
  74. package/dist/index.mjs.map +1 -1
  75. package/dist/{joop-CA3DMeOO.d.ts → joop-Dim2yEKG.d.ts} +1 -1
  76. package/dist/{joop-Bx7Iwj5p.d.mts → joop-GkQw13f9.d.mts} +1 -1
  77. package/dist/native-bridge/index.js +10 -2
  78. package/dist/native-bridge/index.js.map +1 -1
  79. package/dist/native-bridge/index.mjs +10 -2
  80. package/dist/native-bridge/index.mjs.map +1 -1
  81. package/dist/network/index.js +15 -3
  82. package/dist/network/index.js.map +1 -1
  83. package/dist/network/index.mjs +15 -3
  84. package/dist/network/index.mjs.map +1 -1
  85. package/dist/observability/index.js +15 -3
  86. package/dist/observability/index.js.map +1 -1
  87. package/dist/observability/index.mjs +15 -3
  88. package/dist/observability/index.mjs.map +1 -1
  89. package/dist/pwa/index.js +15 -3
  90. package/dist/pwa/index.js.map +1 -1
  91. package/dist/pwa/index.mjs +15 -3
  92. package/dist/pwa/index.mjs.map +1 -1
  93. package/dist/react/index.d.mts +2 -2
  94. package/dist/react/index.d.ts +2 -2
  95. package/dist/react/index.js +15 -3
  96. package/dist/react/index.js.map +1 -1
  97. package/dist/react/index.mjs +15 -3
  98. package/dist/react/index.mjs.map +1 -1
  99. package/dist/router/index.js +15 -3
  100. package/dist/router/index.js.map +1 -1
  101. package/dist/router/index.mjs +15 -3
  102. package/dist/router/index.mjs.map +1 -1
  103. package/dist/security/index.js +15 -3
  104. package/dist/security/index.js.map +1 -1
  105. package/dist/security/index.mjs +15 -3
  106. package/dist/security/index.mjs.map +1 -1
  107. package/dist/session/index.js +15 -3
  108. package/dist/session/index.js.map +1 -1
  109. package/dist/session/index.mjs +15 -3
  110. package/dist/session/index.mjs.map +1 -1
  111. package/dist/state/index.js +15 -3
  112. package/dist/state/index.js.map +1 -1
  113. package/dist/state/index.mjs +15 -3
  114. package/dist/state/index.mjs.map +1 -1
  115. package/dist/storage/index.js +15 -3
  116. package/dist/storage/index.js.map +1 -1
  117. package/dist/storage/index.mjs +15 -3
  118. package/dist/storage/index.mjs.map +1 -1
  119. package/dist/sync/index.js +15 -3
  120. package/dist/sync/index.js.map +1 -1
  121. package/dist/sync/index.mjs +15 -3
  122. package/dist/sync/index.mjs.map +1 -1
  123. package/dist/theme/index.js +15 -3
  124. package/dist/theme/index.js.map +1 -1
  125. package/dist/theme/index.mjs +15 -3
  126. package/dist/theme/index.mjs.map +1 -1
  127. package/dist/ui/index.js +15 -3
  128. package/dist/ui/index.js.map +1 -1
  129. package/dist/ui/index.mjs +15 -3
  130. package/dist/ui/index.mjs.map +1 -1
  131. package/dist/utilities/index.js +46 -4
  132. package/dist/utilities/index.js.map +1 -1
  133. package/dist/utilities/index.mjs +46 -4
  134. package/dist/utilities/index.mjs.map +1 -1
  135. package/dist/vue/index.d.mts +2 -2
  136. package/dist/vue/index.d.ts +2 -2
  137. package/dist/vue/index.js +15 -3
  138. package/dist/vue/index.js.map +1 -1
  139. package/dist/vue/index.mjs +15 -3
  140. package/dist/vue/index.mjs.map +1 -1
  141. package/dist/workflow/index.js +15 -3
  142. package/dist/workflow/index.js.map +1 -1
  143. package/dist/workflow/index.mjs +15 -3
  144. package/dist/workflow/index.mjs.map +1 -1
  145. package/package.json +96 -32
  146. package/scripts/setup-ai.mjs +133 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/storage/scope-map.service.ts","../../src/events/index.ts","../../src/storage/data-storage.service.ts","../../src/storage/indexed-db.service.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { JoopScopeType } from '../enums';\n\n/**\n * Four-scope in-memory store.\n *\n * | Scope | Lifetime |\n * |---------|--------------------------------|\n * | app | Entire app session |\n * | page | Current page / flow |\n * | screen | Current screen / component |\n * | session | Browser session (survives nav) |\n */\nexport class JoopScopeMapService {\n private _appMap: Record<string, any> = {};\n private _pageMap: Record<string, any> = {};\n private _screenMap: Record<string, any> = {};\n private _sessionMap: Record<string, any> = {};\n\n getMap(scope: JoopScopeType): Record<string, any> {\n switch (scope) {\n case JoopScopeType.App: return this._appMap;\n case JoopScopeType.Page: return this._pageMap;\n case JoopScopeType.Screen: return this._screenMap;\n case JoopScopeType.Session: return this._sessionMap;\n }\n }\n\n clearScreen(): void { this._screenMap = {}; }\n clearPage(): void { this._pageMap = {}; }\n clearSession(): void { this._sessionMap = {}; }\n clearApp(): void { this._appMap = {}; }\n\n clearAll(): void {\n this._appMap = {};\n this._pageMap = {};\n this._screenMap = {};\n this._sessionMap = {};\n }\n}\n","export type Unsubscribe = () => void;\nexport type Listener<T> = (value: T) => void;\n\n/**\n * Lightweight pub/sub subject — emits to all current subscribers.\n * Replaces RxJS Subject without pulling in the full RxJS dependency.\n */\nexport class JoopSubject<T> {\n private _listeners: Listener<T>[] = [];\n\n subscribe(listener: Listener<T>): Unsubscribe {\n this._listeners.push(listener);\n return () => {\n this._listeners = this._listeners.filter(l => l !== listener);\n };\n }\n\n next(value: T): void {\n for (const listener of this._listeners) {\n listener(value);\n }\n }\n\n asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Stateful subject — replays the current value to any new subscriber immediately.\n * Replaces RxJS BehaviorSubject.\n */\nexport class JoopBehaviorSubject<T> extends JoopSubject<T> {\n private _value: T;\n\n constructor(initialValue: T) {\n super();\n this._value = initialValue;\n }\n\n getValue(): T {\n return this._value;\n }\n\n override next(value: T): void {\n this._value = value;\n super.next(value);\n }\n\n override subscribe(listener: Listener<T>): Unsubscribe {\n listener(this._value);\n return super.subscribe(listener);\n }\n\n override asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Read-only observable handle returned from asObservable().\n */\nexport class JoopObservable<T> {\n constructor(private _subscribeFn: (listener: Listener<T>) => Unsubscribe) {}\n\n subscribe(listener: Listener<T>): Unsubscribe {\n return this._subscribeFn(listener);\n }\n\n /** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */\n getOnce(): T | undefined {\n let result: T | undefined;\n const unsub = this.subscribe(v => { result = v; });\n unsub();\n return result;\n }\n}\n","import { JoopBehaviorSubject, JoopObservable } from '../events';\nimport { JoopScopeType } from '../enums';\nimport { JoopScopeMapService } from './scope-map.service';\n\nexport class JoopDataStorage {\n private _menuSubject = new JoopBehaviorSubject<{ menuObj: any[] } | null>(null);\n\n constructor(private readonly _scopeMap: JoopScopeMapService) {}\n\n /** Store a value in the given scope under the given key. */\n set(scope: JoopScopeType, key: string, value: any): void {\n const map = this._scopeMap.getMap(scope);\n map[key] = value;\n }\n\n /** Retrieve a typed value from the given scope. Returns null if not found. */\n get<T>(scope: JoopScopeType, key: string): T | null {\n return this._scopeMap.getMap(scope)[key] ?? null;\n }\n\n /** Remove a single key from the given scope. */\n remove(scope: JoopScopeType, key: string): void {\n delete this._scopeMap.getMap(scope)[key];\n }\n\n /** Retrieve the entire map for a scope (reference, not clone). */\n getScope<T extends Record<string, any>>(scope: JoopScopeType): T {\n return this._scopeMap.getMap(scope) as T;\n }\n\n setMenuData(data: { menuObj: any[] }): void {\n this._menuSubject.next(data);\n }\n\n clearMenuData(): void {\n this._menuSubject.next(null);\n }\n\n menuData$(): JoopObservable<{ menuObj: any[] } | null> {\n return this._menuSubject.asObservable();\n }\n\n getMenuData(): { menuObj: any[] } | null {\n return this._menuSubject.getValue();\n }\n}\n","import { JoopBehaviorSubject } from '../events';\n\nexport interface JoopIdbStoreSchema {\n name: string;\n keyPath?: string;\n autoIncrement?: boolean;\n indexes?: Array<{ name: string; keyPath: string | string[]; unique?: boolean }>;\n}\n\nexport interface JoopIdbConfig {\n name: string;\n version: number;\n stores: JoopIdbStoreSchema[];\n}\n\nexport class JoopIndexedDbService {\n private _db: IDBDatabase | null = null;\n private _ready$ = new JoopBehaviorSubject<boolean>(false);\n\n async open(config: JoopIdbConfig): Promise<void> {\n return new Promise((resolve, reject) => {\n const req = indexedDB.open(config.name, config.version);\n req.onupgradeneeded = (e) => {\n const db = (e.target as IDBOpenDBRequest).result;\n for (const store of config.stores) {\n if (!db.objectStoreNames.contains(store.name)) {\n const os = db.createObjectStore(store.name, { keyPath: store.keyPath, autoIncrement: store.autoIncrement });\n for (const idx of store.indexes ?? []) os.createIndex(idx.name, idx.keyPath, { unique: idx.unique ?? false });\n }\n }\n };\n req.onsuccess = (e) => { this._db = (e.target as IDBOpenDBRequest).result; this._ready$.next(true); resolve(); };\n req.onerror = () => reject(req.error);\n });\n }\n\n close(): void { this._db?.close(); this._db = null; this._ready$.next(false); }\n isOpen(): boolean { return this._db !== null; }\n ready$() { return this._ready$.asObservable(); }\n\n private _store(storeName: string, mode: IDBTransactionMode): IDBObjectStore {\n if (!this._db) throw new Error('JoopIndexedDb: not open');\n return this._db.transaction(storeName, mode).objectStore(storeName);\n }\n\n async get<T>(store: string, key: IDBValidKey): Promise<T | null> {\n return new Promise((res, rej) => {\n const req = this._store(store, 'readonly').get(key);\n req.onsuccess = () => res((req.result as T) ?? null);\n req.onerror = () => rej(req.error);\n });\n }\n\n async set(store: string, value: unknown, key?: IDBValidKey): Promise<IDBValidKey> {\n return new Promise((res, rej) => {\n const req = key !== undefined ? this._store(store, 'readwrite').put(value, key) : this._store(store, 'readwrite').put(value);\n req.onsuccess = () => res(req.result);\n req.onerror = () => rej(req.error);\n });\n }\n\n async delete(store: string, key: IDBValidKey): Promise<void> {\n return new Promise((res, rej) => {\n const req = this._store(store, 'readwrite').delete(key);\n req.onsuccess = () => res();\n req.onerror = () => rej(req.error);\n });\n }\n\n async getAll<T>(store: string): Promise<T[]> {\n return new Promise((res, rej) => {\n const req = this._store(store, 'readonly').getAll();\n req.onsuccess = () => res(req.result as T[]);\n req.onerror = () => rej(req.error);\n });\n }\n\n async getAllKeys(store: string): Promise<IDBValidKey[]> {\n return new Promise((res, rej) => {\n const req = this._store(store, 'readonly').getAllKeys();\n req.onsuccess = () => res(req.result);\n req.onerror = () => rej(req.error);\n });\n }\n\n async query<T>(store: string, indexName: string, range: IDBKeyRange): Promise<T[]> {\n return new Promise((res, rej) => {\n const req = this._store(store, 'readonly').index(indexName).getAll(range);\n req.onsuccess = () => res(req.result as T[]);\n req.onerror = () => rej(req.error);\n });\n }\n\n async count(store: string, range?: IDBKeyRange): Promise<number> {\n return new Promise((res, rej) => {\n const req = range ? this._store(store, 'readonly').count(range) : this._store(store, 'readonly').count();\n req.onsuccess = () => res(req.result);\n req.onerror = () => rej(req.error);\n });\n }\n\n async clear(store: string): Promise<void> {\n return new Promise((res, rej) => {\n const req = this._store(store, 'readwrite').clear();\n req.onsuccess = () => res();\n req.onerror = () => rej(req.error);\n });\n }\n\n async bulkSet(store: string, items: unknown[]): Promise<void> {\n if (!this._db) throw new Error('JoopIndexedDb: not open');\n return new Promise((res, rej) => {\n const tx = this._db!.transaction(store, 'readwrite');\n const os = tx.objectStore(store);\n for (const item of items) os.put(item);\n tx.oncomplete = () => res();\n tx.onerror = () => rej(tx.error);\n });\n }\n\n async deleteDatabase(name: string): Promise<void> {\n this.close();\n return new Promise((res, rej) => {\n const req = indexedDB.deleteDatabase(name);\n req.onsuccess = () => res();\n req.onerror = () => rej(req.error);\n });\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/storage/scope-map.service.ts","../../src/events/index.ts","../../src/storage/data-storage.service.ts","../../src/storage/indexed-db.service.ts"],"names":[],"mappings":";AAYO,IAAM,sBAAN,MAA0B;AAAA,EACvB,UAA+B,EAAC;AAAA,EAChC,WAAgC,EAAC;AAAA,EACjC,aAAkC,EAAC;AAAA,EACnC,cAAmC,EAAC;AAAA,EAE5C,OAAO,KAAA,EAA2C;AAChD,IAAA,QAAQ,KAAA;AAAO,MACb,KAAA,KAAA;AAA4B,QAAA,OAAO,IAAA,CAAK,OAAA;AAAA,MACxC,KAAA,MAAA;AAA4B,QAAA,OAAO,IAAA,CAAK,QAAA;AAAA,MACxC,KAAA,QAAA;AAA4B,QAAA,OAAO,IAAA,CAAK,UAAA;AAAA,MACxC,KAAA,SAAA;AAA4B,QAAA,OAAO,IAAA,CAAK,WAAA;AAAA;AAC1C,EACF;AAAA,EAEA,WAAA,GAAqB;AAAE,IAAA,IAAA,CAAK,aAAa,EAAC;AAAA,EAAG;AAAA,EAC7C,SAAA,GAAqB;AAAE,IAAA,IAAA,CAAK,WAAW,EAAC;AAAA,EAAG;AAAA,EAC3C,YAAA,GAAqB;AAAE,IAAA,IAAA,CAAK,cAAc,EAAC;AAAA,EAAG;AAAA,EAC9C,QAAA,GAAqB;AAAE,IAAA,IAAA,CAAK,UAAU,EAAC;AAAA,EAAG;AAAA,EAE1C,QAAA,GAAiB;AACf,IAAA,IAAA,CAAK,UAAU,EAAC;AAChB,IAAA,IAAA,CAAK,WAAW,EAAC;AACjB,IAAA,IAAA,CAAK,aAAa,EAAC;AACnB,IAAA,IAAA,CAAK,cAAc,EAAC;AAAA,EACtB;AACF;;;AC9BA,IAAI,gBAAA,GAA6C,CAAC,KAAA,KAAU;AAE1D,EAAA,OAAA,CAAQ,KAAA,CAAM,wDAAwD,KAAK,CAAA;AAC7E,CAAA;AAWO,IAAM,cAAN,MAAqB;AAAA,EAClB,aAA4B,EAAC;AAAA,EAErC,UAAU,QAAA,EAAoC;AAC5C,IAAA,IAAA,CAAK,UAAA,CAAW,KAAK,QAAQ,CAAA;AAC7B,IAAA,OAAO,MAAM;AACX,MAAA,IAAA,CAAK,aAAa,IAAA,CAAK,UAAA,CAAW,MAAA,CAAO,CAAA,CAAA,KAAK,MAAM,QAAQ,CAAA;AAAA,IAC9D,CAAA;AAAA,EACF;AAAA,EAEA,KAAK,KAAA,EAAgB;AAInB,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,UAAA,CAAW,KAAA,EAAM;AACxC,IAAA,KAAA,MAAW,YAAY,SAAA,EAAW;AAChC,MAAA,IAAI;AACF,QAAA,QAAA,CAAS,KAAK,CAAA;AAAA,MAChB,SAAS,KAAA,EAAO;AACd,QAAA,gBAAA,CAAiB,KAAK,CAAA;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAAA,GAAkC;AAChC,IAAA,OAAO,IAAI,cAAA,CAAkB,CAAA,QAAA,KAAY,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AAAA,EACnE;AACF,CAAA;AAMO,IAAM,mBAAA,GAAN,cAAqC,WAAA,CAAe;AAAA,EACjD,MAAA;AAAA,EAER,YAAY,YAAA,EAAiB;AAC3B,IAAA,KAAA,EAAM;AACN,IAAA,IAAA,CAAK,MAAA,GAAS,YAAA;AAAA,EAChB;AAAA,EAEA,QAAA,GAAc;AACZ,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EAES,KAAK,KAAA,EAAgB;AAC5B,IAAA,IAAA,CAAK,MAAA,GAAS,KAAA;AACd,IAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAAA,EAClB;AAAA,EAES,UAAU,QAAA,EAAoC;AACrD,IAAA,IAAI;AACF,MAAA,QAAA,CAAS,KAAK,MAAM,CAAA;AAAA,IACtB,SAAS,KAAA,EAAO;AACd,MAAA,gBAAA,CAAiB,KAAK,CAAA;AAAA,IACxB;AACA,IAAA,OAAO,KAAA,CAAM,UAAU,QAAQ,CAAA;AAAA,EACjC;AAAA,EAES,YAAA,GAAkC;AACzC,IAAA,OAAO,IAAI,cAAA,CAAkB,CAAA,QAAA,KAAY,IAAA,CAAK,SAAA,CAAU,QAAQ,CAAC,CAAA;AAAA,EACnE;AACF,CAAA;AAKO,IAAM,iBAAN,MAAwB;AAAA,EAC7B,YAAoB,YAAA,EAAsD;AAAtD,IAAA,IAAA,CAAA,YAAA,GAAA,YAAA;AAAA,EAAuD;AAAA,EAAvD,YAAA;AAAA,EAEpB,UAAU,QAAA,EAAoC;AAC5C,IAAA,OAAO,IAAA,CAAK,aAAa,QAAQ,CAAA;AAAA,EACnC;AAAA;AAAA,EAGA,OAAA,GAAyB;AACvB,IAAA,IAAI,MAAA;AACJ,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,SAAA,CAAU,CAAA,CAAA,KAAK;AAAE,MAAA,MAAA,GAAS,CAAA;AAAA,IAAG,CAAC,CAAA;AACjD,IAAA,KAAA,EAAM;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF,CAAA;;;ACnGO,IAAM,kBAAN,MAAsB;AAAA,EAG3B,YAA6B,SAAA,EAAgC;AAAhC,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AAAA,EAAiC;AAAA,EAAjC,SAAA;AAAA,EAFrB,YAAA,GAAe,IAAI,mBAAA,CAA+C,IAAI,CAAA;AAAA;AAAA,EAK9E,GAAA,CAAI,KAAA,EAAsB,GAAA,EAAa,KAAA,EAAkB;AACvD,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,KAAK,CAAA;AACvC,IAAA,GAAA,CAAI,GAAG,CAAA,GAAI,KAAA;AAAA,EACb;AAAA;AAAA,EAGA,GAAA,CAAO,OAAsB,GAAA,EAAuB;AAClD,IAAA,OAAO,KAAK,SAAA,CAAU,MAAA,CAAO,KAAK,CAAA,CAAE,GAAG,CAAA,IAAK,IAAA;AAAA,EAC9C;AAAA;AAAA,EAGA,MAAA,CAAO,OAAsB,GAAA,EAAmB;AAC9C,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,KAAK,EAAE,GAAG,CAAA;AAAA,EACzC;AAAA;AAAA,EAGA,SAAwC,KAAA,EAAyB;AAC/D,IAAA,OAAO,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,KAAK,CAAA;AAAA,EACpC;AAAA,EAEA,YAAY,IAAA,EAAgC;AAC1C,IAAA,IAAA,CAAK,YAAA,CAAa,KAAK,IAAI,CAAA;AAAA,EAC7B;AAAA,EAEA,aAAA,GAAsB;AACpB,IAAA,IAAA,CAAK,YAAA,CAAa,KAAK,IAAI,CAAA;AAAA,EAC7B;AAAA,EAEA,SAAA,GAAuD;AACrD,IAAA,OAAO,IAAA,CAAK,aAAa,YAAA,EAAa;AAAA,EACxC;AAAA,EAEA,WAAA,GAAyC;AACvC,IAAA,OAAO,IAAA,CAAK,aAAa,QAAA,EAAS;AAAA,EACpC;AACF;;;AC9BO,IAAM,uBAAN,MAA2B;AAAA,EACxB,GAAA,GAA0B,IAAA;AAAA,EAC1B,OAAA,GAAU,IAAI,mBAAA,CAA6B,KAAK,CAAA;AAAA,EAExD,MAAM,KAAK,MAAA,EAAsC;AAC/C,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,MAAA,MAAM,MAAM,SAAA,CAAU,IAAA,CAAK,MAAA,CAAO,IAAA,EAAM,OAAO,OAAO,CAAA;AACtD,MAAA,GAAA,CAAI,eAAA,GAAkB,CAAC,CAAA,KAAM;AAC3B,QAAA,MAAM,EAAA,GAAM,EAAE,MAAA,CAA4B,MAAA;AAC1C,QAAA,KAAA,MAAW,KAAA,IAAS,OAAO,MAAA,EAAQ;AACjC,UAAA,IAAI,CAAC,EAAA,CAAG,gBAAA,CAAiB,QAAA,CAAS,KAAA,CAAM,IAAI,CAAA,EAAG;AAC7C,YAAA,MAAM,EAAA,GAAK,EAAA,CAAG,iBAAA,CAAkB,KAAA,CAAM,IAAA,EAAM,EAAE,OAAA,EAAS,KAAA,CAAM,OAAA,EAAS,aAAA,EAAe,KAAA,CAAM,aAAA,EAAe,CAAA;AAC1G,YAAA,KAAA,MAAW,OAAO,KAAA,CAAM,OAAA,IAAW,EAAC,KAAM,WAAA,CAAY,GAAA,CAAI,IAAA,EAAM,GAAA,CAAI,SAAS,EAAE,MAAA,EAAQ,GAAA,CAAI,MAAA,IAAU,OAAO,CAAA;AAAA,UAC9G;AAAA,QACF;AAAA,MACF,CAAA;AACA,MAAA,GAAA,CAAI,SAAA,GAAY,CAAC,CAAA,KAAM;AAAE,QAAA,IAAA,CAAK,GAAA,GAAO,EAAE,MAAA,CAA4B,MAAA;AAAQ,QAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAG,QAAA,OAAA,EAAQ;AAAA,MAAG,CAAA;AAC/G,MAAA,GAAA,CAAI,OAAA,GAAU,MAAM,MAAA,CAAO,GAAA,CAAI,KAAK,CAAA;AAAA,IACtC,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,KAAA,GAAc;AAAE,IAAA,IAAA,CAAK,KAAK,KAAA,EAAM;AAAG,IAAA,IAAA,CAAK,GAAA,GAAM,IAAA;AAAM,IAAA,IAAA,CAAK,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,EAAG;AAAA,EAC9E,MAAA,GAAkB;AAAE,IAAA,OAAO,KAAK,GAAA,KAAQ,IAAA;AAAA,EAAM;AAAA,EAC9C,MAAA,GAAS;AAAE,IAAA,OAAO,IAAA,CAAK,QAAQ,YAAA,EAAa;AAAA,EAAG;AAAA,EAEvC,MAAA,CAAO,WAAmB,IAAA,EAA0C;AAC1E,IAAA,IAAI,CAAC,IAAA,CAAK,GAAA,EAAK,MAAM,IAAI,MAAM,yBAAyB,CAAA;AACxD,IAAA,OAAO,KAAK,GAAA,CAAI,WAAA,CAAY,WAAW,IAAI,CAAA,CAAE,YAAY,SAAS,CAAA;AAAA,EACpE;AAAA,EAEA,MAAM,GAAA,CAAO,KAAA,EAAe,GAAA,EAAqC;AAC/D,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,GAAA,EAAK,GAAA,KAAQ;AAC/B,MAAA,MAAM,MAAM,IAAA,CAAK,MAAA,CAAO,OAAO,UAAU,CAAA,CAAE,IAAI,GAAG,CAAA;AAClD,MAAA,GAAA,CAAI,SAAA,GAAY,MAAM,GAAA,CAAK,GAAA,CAAI,UAAgB,IAAI,CAAA;AACnD,MAAA,GAAA,CAAI,OAAA,GAAU,MAAM,GAAA,CAAI,GAAA,CAAI,KAAK,CAAA;AAAA,IACnC,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,GAAA,CAAI,KAAA,EAAe,KAAA,EAAgB,GAAA,EAAyC;AAChF,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,GAAA,EAAK,GAAA,KAAQ;AAC/B,MAAA,MAAM,MAAM,GAAA,KAAQ,MAAA,GAAY,KAAK,MAAA,CAAO,KAAA,EAAO,WAAW,CAAA,CAAE,GAAA,CAAI,KAAA,EAAO,GAAG,IAAI,IAAA,CAAK,MAAA,CAAO,OAAO,WAAW,CAAA,CAAE,IAAI,KAAK,CAAA;AAC3H,MAAA,GAAA,CAAI,SAAA,GAAY,MAAM,GAAA,CAAI,GAAA,CAAI,MAAM,CAAA;AACpC,MAAA,GAAA,CAAI,OAAA,GAAU,MAAM,GAAA,CAAI,GAAA,CAAI,KAAK,CAAA;AAAA,IACnC,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,MAAA,CAAO,KAAA,EAAe,GAAA,EAAiC;AAC3D,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,GAAA,EAAK,GAAA,KAAQ;AAC/B,MAAA,MAAM,MAAM,IAAA,CAAK,MAAA,CAAO,OAAO,WAAW,CAAA,CAAE,OAAO,GAAG,CAAA;AACtD,MAAA,GAAA,CAAI,SAAA,GAAY,MAAM,GAAA,EAAI;AAC1B,MAAA,GAAA,CAAI,OAAA,GAAU,MAAM,GAAA,CAAI,GAAA,CAAI,KAAK,CAAA;AAAA,IACnC,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,OAAU,KAAA,EAA6B;AAC3C,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,GAAA,EAAK,GAAA,KAAQ;AAC/B,MAAA,MAAM,MAAM,IAAA,CAAK,MAAA,CAAO,KAAA,EAAO,UAAU,EAAE,MAAA,EAAO;AAClD,MAAA,GAAA,CAAI,SAAA,GAAY,MAAM,GAAA,CAAI,GAAA,CAAI,MAAa,CAAA;AAC3C,MAAA,GAAA,CAAI,OAAA,GAAU,MAAM,GAAA,CAAI,GAAA,CAAI,KAAK,CAAA;AAAA,IACnC,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,WAAW,KAAA,EAAuC;AACtD,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,GAAA,EAAK,GAAA,KAAQ;AAC/B,MAAA,MAAM,MAAM,IAAA,CAAK,MAAA,CAAO,KAAA,EAAO,UAAU,EAAE,UAAA,EAAW;AACtD,MAAA,GAAA,CAAI,SAAA,GAAY,MAAM,GAAA,CAAI,GAAA,CAAI,MAAM,CAAA;AACpC,MAAA,GAAA,CAAI,OAAA,GAAU,MAAM,GAAA,CAAI,GAAA,CAAI,KAAK,CAAA;AAAA,IACnC,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,KAAA,CAAS,KAAA,EAAe,SAAA,EAAmB,KAAA,EAAkC;AACjF,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,GAAA,EAAK,GAAA,KAAQ;AAC/B,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,CAAO,KAAA,EAAO,UAAU,EAAE,KAAA,CAAM,SAAS,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA;AACxE,MAAA,GAAA,CAAI,SAAA,GAAY,MAAM,GAAA,CAAI,GAAA,CAAI,MAAa,CAAA;AAC3C,MAAA,GAAA,CAAI,OAAA,GAAU,MAAM,GAAA,CAAI,GAAA,CAAI,KAAK,CAAA;AAAA,IACnC,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,KAAA,CAAM,KAAA,EAAe,KAAA,EAAsC;AAC/D,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,GAAA,EAAK,GAAA,KAAQ;AAC/B,MAAA,MAAM,GAAA,GAAM,KAAA,GAAQ,IAAA,CAAK,MAAA,CAAO,OAAO,UAAU,CAAA,CAAE,KAAA,CAAM,KAAK,IAAI,IAAA,CAAK,MAAA,CAAO,KAAA,EAAO,UAAU,EAAE,KAAA,EAAM;AACvG,MAAA,GAAA,CAAI,SAAA,GAAY,MAAM,GAAA,CAAI,GAAA,CAAI,MAAM,CAAA;AACpC,MAAA,GAAA,CAAI,OAAA,GAAU,MAAM,GAAA,CAAI,GAAA,CAAI,KAAK,CAAA;AAAA,IACnC,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,MAAM,KAAA,EAA8B;AACxC,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,GAAA,EAAK,GAAA,KAAQ;AAC/B,MAAA,MAAM,MAAM,IAAA,CAAK,MAAA,CAAO,KAAA,EAAO,WAAW,EAAE,KAAA,EAAM;AAClD,MAAA,GAAA,CAAI,SAAA,GAAY,MAAM,GAAA,EAAI;AAC1B,MAAA,GAAA,CAAI,OAAA,GAAU,MAAM,GAAA,CAAI,GAAA,CAAI,KAAK,CAAA;AAAA,IACnC,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,OAAA,CAAQ,KAAA,EAAe,KAAA,EAAiC;AAC5D,IAAA,IAAI,CAAC,IAAA,CAAK,GAAA,EAAK,MAAM,IAAI,MAAM,yBAAyB,CAAA;AACxD,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,GAAA,EAAK,GAAA,KAAQ;AAC/B,MAAA,MAAM,EAAA,GAAK,IAAA,CAAK,GAAA,CAAK,WAAA,CAAY,OAAO,WAAW,CAAA;AACnD,MAAA,MAAM,EAAA,GAAK,EAAA,CAAG,WAAA,CAAY,KAAK,CAAA;AAC/B,MAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,EAAO,EAAA,CAAG,GAAA,CAAI,IAAI,CAAA;AACrC,MAAA,EAAA,CAAG,UAAA,GAAa,MAAM,GAAA,EAAI;AAC1B,MAAA,EAAA,CAAG,OAAA,GAAU,MAAM,GAAA,CAAI,EAAA,CAAG,KAAK,CAAA;AAAA,IACjC,CAAC,CAAA;AAAA,EACH;AAAA,EAEA,MAAM,eAAe,IAAA,EAA6B;AAChD,IAAA,IAAA,CAAK,KAAA,EAAM;AACX,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,GAAA,EAAK,GAAA,KAAQ;AAC/B,MAAA,MAAM,GAAA,GAAM,SAAA,CAAU,cAAA,CAAe,IAAI,CAAA;AACzC,MAAA,GAAA,CAAI,SAAA,GAAY,MAAM,GAAA,EAAI;AAC1B,MAAA,GAAA,CAAI,OAAA,GAAU,MAAM,GAAA,CAAI,GAAA,CAAI,KAAK,CAAA;AAAA,IACnC,CAAC,CAAA;AAAA,EACH;AACF","file":"index.mjs","sourcesContent":["import { JoopScopeType } from '../enums';\n\n/**\n * Four-scope in-memory store.\n *\n * | Scope | Lifetime |\n * |---------|--------------------------------|\n * | app | Entire app session |\n * | page | Current page / flow |\n * | screen | Current screen / component |\n * | session | Browser session (survives nav) |\n */\nexport class JoopScopeMapService {\n private _appMap: Record<string, any> = {};\n private _pageMap: Record<string, any> = {};\n private _screenMap: Record<string, any> = {};\n private _sessionMap: Record<string, any> = {};\n\n getMap(scope: JoopScopeType): Record<string, any> {\n switch (scope) {\n case JoopScopeType.App: return this._appMap;\n case JoopScopeType.Page: return this._pageMap;\n case JoopScopeType.Screen: return this._screenMap;\n case JoopScopeType.Session: return this._sessionMap;\n }\n }\n\n clearScreen(): void { this._screenMap = {}; }\n clearPage(): void { this._pageMap = {}; }\n clearSession(): void { this._sessionMap = {}; }\n clearApp(): void { this._appMap = {}; }\n\n clearAll(): void {\n this._appMap = {};\n this._pageMap = {};\n this._screenMap = {};\n this._sessionMap = {};\n }\n}\n","export type Unsubscribe = () => void;\nexport type Listener<T> = (value: T) => void;\n\n/**\n * Reports a subscriber that threw during emission, without aborting delivery\n * to the remaining subscribers. Defaults to console.error; override to route\n * to your own logger (e.g. in a banking app where dropped events matter).\n */\nlet _onListenerError: (error: unknown) => void = (error) => {\n // eslint-disable-next-line no-console\n console.error('[joopjs] a subject subscriber threw during emission:', error);\n};\n\n/** Override how subscriber errors are reported during emission. */\nexport function setSubjectErrorHandler(handler: (error: unknown) => void): void {\n _onListenerError = handler;\n}\n\n/**\n * Lightweight pub/sub subject — emits to all current subscribers.\n * Replaces RxJS Subject without pulling in the full RxJS dependency.\n */\nexport class JoopSubject<T> {\n private _listeners: Listener<T>[] = [];\n\n subscribe(listener: Listener<T>): Unsubscribe {\n this._listeners.push(listener);\n return () => {\n this._listeners = this._listeners.filter(l => l !== listener);\n };\n }\n\n next(value: T): void {\n // Snapshot so a subscribe()/unsubscribe() triggered by a listener can't\n // disturb this emission, and isolate each listener so one that throws\n // doesn't deprive later subscribers of the value.\n const listeners = this._listeners.slice();\n for (const listener of listeners) {\n try {\n listener(value);\n } catch (error) {\n _onListenerError(error);\n }\n }\n }\n\n asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Stateful subject — replays the current value to any new subscriber immediately.\n * Replaces RxJS BehaviorSubject.\n */\nexport class JoopBehaviorSubject<T> extends JoopSubject<T> {\n private _value: T;\n\n constructor(initialValue: T) {\n super();\n this._value = initialValue;\n }\n\n getValue(): T {\n return this._value;\n }\n\n override next(value: T): void {\n this._value = value;\n super.next(value);\n }\n\n override subscribe(listener: Listener<T>): Unsubscribe {\n try {\n listener(this._value);\n } catch (error) {\n _onListenerError(error);\n }\n return super.subscribe(listener);\n }\n\n override asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Read-only observable handle returned from asObservable().\n */\nexport class JoopObservable<T> {\n constructor(private _subscribeFn: (listener: Listener<T>) => Unsubscribe) {}\n\n subscribe(listener: Listener<T>): Unsubscribe {\n return this._subscribeFn(listener);\n }\n\n /** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */\n getOnce(): T | undefined {\n let result: T | undefined;\n const unsub = this.subscribe(v => { result = v; });\n unsub();\n return result;\n }\n}\n","import { JoopBehaviorSubject, JoopObservable } from '../events';\nimport { JoopScopeType } from '../enums';\nimport { JoopScopeMapService } from './scope-map.service';\n\nexport class JoopDataStorage {\n private _menuSubject = new JoopBehaviorSubject<{ menuObj: any[] } | null>(null);\n\n constructor(private readonly _scopeMap: JoopScopeMapService) {}\n\n /** Store a value in the given scope under the given key. */\n set(scope: JoopScopeType, key: string, value: any): void {\n const map = this._scopeMap.getMap(scope);\n map[key] = value;\n }\n\n /** Retrieve a typed value from the given scope. Returns null if not found. */\n get<T>(scope: JoopScopeType, key: string): T | null {\n return this._scopeMap.getMap(scope)[key] ?? null;\n }\n\n /** Remove a single key from the given scope. */\n remove(scope: JoopScopeType, key: string): void {\n delete this._scopeMap.getMap(scope)[key];\n }\n\n /** Retrieve the entire map for a scope (reference, not clone). */\n getScope<T extends Record<string, any>>(scope: JoopScopeType): T {\n return this._scopeMap.getMap(scope) as T;\n }\n\n setMenuData(data: { menuObj: any[] }): void {\n this._menuSubject.next(data);\n }\n\n clearMenuData(): void {\n this._menuSubject.next(null);\n }\n\n menuData$(): JoopObservable<{ menuObj: any[] } | null> {\n return this._menuSubject.asObservable();\n }\n\n getMenuData(): { menuObj: any[] } | null {\n return this._menuSubject.getValue();\n }\n}\n","import { JoopBehaviorSubject } from '../events';\n\nexport interface JoopIdbStoreSchema {\n name: string;\n keyPath?: string;\n autoIncrement?: boolean;\n indexes?: Array<{ name: string; keyPath: string | string[]; unique?: boolean }>;\n}\n\nexport interface JoopIdbConfig {\n name: string;\n version: number;\n stores: JoopIdbStoreSchema[];\n}\n\nexport class JoopIndexedDbService {\n private _db: IDBDatabase | null = null;\n private _ready$ = new JoopBehaviorSubject<boolean>(false);\n\n async open(config: JoopIdbConfig): Promise<void> {\n return new Promise((resolve, reject) => {\n const req = indexedDB.open(config.name, config.version);\n req.onupgradeneeded = (e) => {\n const db = (e.target as IDBOpenDBRequest).result;\n for (const store of config.stores) {\n if (!db.objectStoreNames.contains(store.name)) {\n const os = db.createObjectStore(store.name, { keyPath: store.keyPath, autoIncrement: store.autoIncrement });\n for (const idx of store.indexes ?? []) os.createIndex(idx.name, idx.keyPath, { unique: idx.unique ?? false });\n }\n }\n };\n req.onsuccess = (e) => { this._db = (e.target as IDBOpenDBRequest).result; this._ready$.next(true); resolve(); };\n req.onerror = () => reject(req.error);\n });\n }\n\n close(): void { this._db?.close(); this._db = null; this._ready$.next(false); }\n isOpen(): boolean { return this._db !== null; }\n ready$() { return this._ready$.asObservable(); }\n\n private _store(storeName: string, mode: IDBTransactionMode): IDBObjectStore {\n if (!this._db) throw new Error('JoopIndexedDb: not open');\n return this._db.transaction(storeName, mode).objectStore(storeName);\n }\n\n async get<T>(store: string, key: IDBValidKey): Promise<T | null> {\n return new Promise((res, rej) => {\n const req = this._store(store, 'readonly').get(key);\n req.onsuccess = () => res((req.result as T) ?? null);\n req.onerror = () => rej(req.error);\n });\n }\n\n async set(store: string, value: unknown, key?: IDBValidKey): Promise<IDBValidKey> {\n return new Promise((res, rej) => {\n const req = key !== undefined ? this._store(store, 'readwrite').put(value, key) : this._store(store, 'readwrite').put(value);\n req.onsuccess = () => res(req.result);\n req.onerror = () => rej(req.error);\n });\n }\n\n async delete(store: string, key: IDBValidKey): Promise<void> {\n return new Promise((res, rej) => {\n const req = this._store(store, 'readwrite').delete(key);\n req.onsuccess = () => res();\n req.onerror = () => rej(req.error);\n });\n }\n\n async getAll<T>(store: string): Promise<T[]> {\n return new Promise((res, rej) => {\n const req = this._store(store, 'readonly').getAll();\n req.onsuccess = () => res(req.result as T[]);\n req.onerror = () => rej(req.error);\n });\n }\n\n async getAllKeys(store: string): Promise<IDBValidKey[]> {\n return new Promise((res, rej) => {\n const req = this._store(store, 'readonly').getAllKeys();\n req.onsuccess = () => res(req.result);\n req.onerror = () => rej(req.error);\n });\n }\n\n async query<T>(store: string, indexName: string, range: IDBKeyRange): Promise<T[]> {\n return new Promise((res, rej) => {\n const req = this._store(store, 'readonly').index(indexName).getAll(range);\n req.onsuccess = () => res(req.result as T[]);\n req.onerror = () => rej(req.error);\n });\n }\n\n async count(store: string, range?: IDBKeyRange): Promise<number> {\n return new Promise((res, rej) => {\n const req = range ? this._store(store, 'readonly').count(range) : this._store(store, 'readonly').count();\n req.onsuccess = () => res(req.result);\n req.onerror = () => rej(req.error);\n });\n }\n\n async clear(store: string): Promise<void> {\n return new Promise((res, rej) => {\n const req = this._store(store, 'readwrite').clear();\n req.onsuccess = () => res();\n req.onerror = () => rej(req.error);\n });\n }\n\n async bulkSet(store: string, items: unknown[]): Promise<void> {\n if (!this._db) throw new Error('JoopIndexedDb: not open');\n return new Promise((res, rej) => {\n const tx = this._db!.transaction(store, 'readwrite');\n const os = tx.objectStore(store);\n for (const item of items) os.put(item);\n tx.oncomplete = () => res();\n tx.onerror = () => rej(tx.error);\n });\n }\n\n async deleteDatabase(name: string): Promise<void> {\n this.close();\n return new Promise((res, rej) => {\n const req = indexedDB.deleteDatabase(name);\n req.onsuccess = () => res();\n req.onerror = () => rej(req.error);\n });\n }\n}\n"]}
@@ -1,6 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  // src/events/index.ts
4
+ var _onListenerError = (error) => {
5
+ console.error("[joopjs] a subject subscriber threw during emission:", error);
6
+ };
4
7
  var JoopSubject = class {
5
8
  _listeners = [];
6
9
  subscribe(listener) {
@@ -10,8 +13,13 @@ var JoopSubject = class {
10
13
  };
11
14
  }
12
15
  next(value) {
13
- for (const listener of this._listeners) {
14
- listener(value);
16
+ const listeners = this._listeners.slice();
17
+ for (const listener of listeners) {
18
+ try {
19
+ listener(value);
20
+ } catch (error) {
21
+ _onListenerError(error);
22
+ }
15
23
  }
16
24
  }
17
25
  asObservable() {
@@ -32,7 +40,11 @@ var JoopBehaviorSubject = class extends JoopSubject {
32
40
  super.next(value);
33
41
  }
34
42
  subscribe(listener) {
35
- listener(this._value);
43
+ try {
44
+ listener(this._value);
45
+ } catch (error) {
46
+ _onListenerError(error);
47
+ }
36
48
  return super.subscribe(listener);
37
49
  }
38
50
  asObservable() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/events/index.ts","../../src/sync/sync-engine.ts","../../src/sync/crdt.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export type Unsubscribe = () => void;\nexport type Listener<T> = (value: T) => void;\n\n/**\n * Lightweight pub/sub subject — emits to all current subscribers.\n * Replaces RxJS Subject without pulling in the full RxJS dependency.\n */\nexport class JoopSubject<T> {\n private _listeners: Listener<T>[] = [];\n\n subscribe(listener: Listener<T>): Unsubscribe {\n this._listeners.push(listener);\n return () => {\n this._listeners = this._listeners.filter(l => l !== listener);\n };\n }\n\n next(value: T): void {\n for (const listener of this._listeners) {\n listener(value);\n }\n }\n\n asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Stateful subject — replays the current value to any new subscriber immediately.\n * Replaces RxJS BehaviorSubject.\n */\nexport class JoopBehaviorSubject<T> extends JoopSubject<T> {\n private _value: T;\n\n constructor(initialValue: T) {\n super();\n this._value = initialValue;\n }\n\n getValue(): T {\n return this._value;\n }\n\n override next(value: T): void {\n this._value = value;\n super.next(value);\n }\n\n override subscribe(listener: Listener<T>): Unsubscribe {\n listener(this._value);\n return super.subscribe(listener);\n }\n\n override asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Read-only observable handle returned from asObservable().\n */\nexport class JoopObservable<T> {\n constructor(private _subscribeFn: (listener: Listener<T>) => Unsubscribe) {}\n\n subscribe(listener: Listener<T>): Unsubscribe {\n return this._subscribeFn(listener);\n }\n\n /** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */\n getOnce(): T | undefined {\n let result: T | undefined;\n const unsub = this.subscribe(v => { result = v; });\n unsub();\n return result;\n }\n}\n","import { JoopBehaviorSubject, JoopSubject } from '../events';\n\nexport type JoopSyncConflictStrategy = 'local-wins' | 'remote-wins' | 'merge';\n\nexport interface JoopSyncConfig {\n syncUrl: string;\n headers?: Record<string, string>;\n retryMs?: number;\n maxRetries?: number;\n conflictStrategy?: JoopSyncConflictStrategy;\n batchSize?: number;\n}\n\nexport interface JoopMutation {\n id: string;\n type: string;\n payload: unknown;\n status: 'pending' | 'syncing' | 'synced' | 'failed';\n timestamp: number;\n retries: number;\n}\n\nexport interface JoopSyncConflict {\n id: string;\n mutationId: string;\n local: unknown;\n remote: unknown;\n resolvedAt?: number;\n resolution?: 'local' | 'remote' | 'merged';\n}\n\nexport interface JoopSyncStatus {\n online: boolean;\n pendingCount: number;\n syncedCount: number;\n failedCount: number;\n lastSyncAt: number | null;\n syncing: boolean;\n}\n\nexport class JoopSyncEngine {\n private _cfg: JoopSyncConfig | null = null;\n private _mutations: JoopMutation[] = [];\n private _conflicts: JoopSyncConflict[] = [];\n private _syncing = false;\n private _syncedCount = 0;\n private _lastSyncAt: number | null = null;\n private _online = typeof navigator !== 'undefined' ? navigator.onLine : true;\n private _status$ = new JoopBehaviorSubject<JoopSyncStatus>(this._buildStatus());\n private _conflict$ = new JoopSubject<JoopSyncConflict>();\n private _onlineHandlers: Array<() => void> = [];\n\n configure(config: JoopSyncConfig): void {\n this._cfg = config;\n if (typeof window !== 'undefined') {\n const onOnline = () => { this._online = true; this._updateStatus(); this.sync(); };\n const onOffline = () => { this._online = false; this._updateStatus(); };\n window.addEventListener('online', onOnline);\n window.addEventListener('offline', onOffline);\n this._onlineHandlers.push(\n () => window.removeEventListener('online', onOnline),\n () => window.removeEventListener('offline', onOffline),\n );\n }\n }\n\n destroy(): void { for (const rm of this._onlineHandlers) rm(); this._onlineHandlers = []; }\n\n mutate(type: string, payload: unknown): JoopMutation {\n const m: JoopMutation = { id: _uid(), type, payload, status: 'pending', timestamp: Date.now(), retries: 0 };\n this._mutations.push(m);\n this._updateStatus();\n if (this._online && !this._syncing) this.sync();\n return m;\n }\n\n pending(): JoopMutation[] { return this._mutations.filter(m => m.status === 'pending' || m.status === 'failed'); }\n conflicts(): JoopSyncConflict[] { return [...this._conflicts]; }\n status$() { return this._status$.asObservable(); }\n conflict$() { return this._conflict$.asObservable(); }\n\n async sync(): Promise<void> {\n if (!this._cfg || this._syncing || !this._online) return;\n const pending = this.pending();\n if (pending.length === 0) return;\n\n this._syncing = true;\n this._updateStatus();\n\n const { syncUrl, headers = {}, maxRetries = 3, batchSize = 50 } = this._cfg;\n const batch = pending.slice(0, batchSize);\n\n try {\n for (const m of batch) m.status = 'syncing';\n const res = await fetch(syncUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify({ mutations: batch.map(m => ({ id: m.id, type: m.type, payload: m.payload, timestamp: m.timestamp })) }),\n });\n\n if (!res.ok) throw new Error(`Sync failed: ${res.status}`);\n const data = (await res.json()) as { results: Array<{ id: string; status: 'ok' | 'conflict'; remote?: unknown }> };\n\n for (const result of data.results ?? []) {\n const m = this._mutations.find(x => x.id === result.id);\n if (!m) continue;\n if (result.status === 'ok') {\n m.status = 'synced'; this._syncedCount++;\n } else if (result.status === 'conflict') {\n m.status = 'failed';\n const conflict: JoopSyncConflict = { id: _uid(), mutationId: m.id, local: m.payload, remote: result.remote };\n this._conflicts.push(conflict);\n this._conflict$.next(conflict);\n }\n }\n } catch {\n for (const m of batch) {\n m.retries++; m.status = m.retries >= maxRetries ? 'failed' : 'pending';\n }\n } finally {\n this._syncing = false;\n this._lastSyncAt = Date.now();\n this._updateStatus();\n }\n }\n\n resolve(conflictId: string, strategy: 'local' | 'remote' | 'merge', mergeFn?: (local: unknown, remote: unknown) => unknown): void {\n const conflict = this._conflicts.find(c => c.id === conflictId);\n if (!conflict) return;\n const m = this._mutations.find(x => x.id === conflict.mutationId);\n if (m) {\n if (strategy === 'remote') m.payload = conflict.remote;\n else if (strategy === 'merge' && mergeFn) m.payload = mergeFn(conflict.local, conflict.remote);\n m.status = 'pending'; m.retries = 0;\n }\n conflict.resolvedAt = Date.now();\n conflict.resolution = strategy === 'merge' ? 'merged' : strategy;\n this._conflicts = this._conflicts.filter(c => c.id !== conflictId);\n if (this._online) this.sync();\n }\n\n clearSynced(): void { this._mutations = this._mutations.filter(m => m.status !== 'synced'); this._updateStatus(); }\n\n private _buildStatus(): JoopSyncStatus {\n return {\n online: this._online,\n pendingCount: this._mutations.filter(m => m.status === 'pending').length,\n syncedCount: this._syncedCount,\n failedCount: this._mutations.filter(m => m.status === 'failed').length,\n lastSyncAt: this._lastSyncAt,\n syncing: this._syncing,\n };\n }\n\n private _updateStatus(): void { this._status$.next(this._buildStatus()); }\n}\n\nfunction _uid(): string { return `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`; }\n","// ─── G-Counter (grow-only) ───────────────────────────────────────────────────\n\nexport class CRDTCounter {\n private _inc: Record<string, number> = {};\n private _dec: Record<string, number> = {};\n\n increment(nodeId: string, by = 1): void { this._inc[nodeId] = (this._inc[nodeId] ?? 0) + by; }\n decrement(nodeId: string, by = 1): void { this._dec[nodeId] = (this._dec[nodeId] ?? 0) + by; }\n\n value(): number {\n const inc = Object.values(this._inc).reduce((s, v) => s + v, 0);\n const dec = Object.values(this._dec).reduce((s, v) => s + v, 0);\n return inc - dec;\n }\n\n merge(remote: CRDTCounter): void {\n for (const [id, v] of Object.entries(remote._inc)) this._inc[id] = Math.max(this._inc[id] ?? 0, v);\n for (const [id, v] of Object.entries(remote._dec)) this._dec[id] = Math.max(this._dec[id] ?? 0, v);\n }\n\n state(): { inc: Record<string, number>; dec: Record<string, number> } { return { inc: { ...this._inc }, dec: { ...this._dec } }; }\n\n static fromState(s: { inc: Record<string, number>; dec: Record<string, number> }): CRDTCounter {\n const c = new CRDTCounter(); c._inc = { ...s.inc }; c._dec = { ...s.dec }; return c;\n }\n}\n\n// ─── Add-Wins Set ────────────────────────────────────────────────────────────\n\nexport class CRDTSet<T> {\n private _added = new Map<string, T>();\n private _removed = new Set<string>();\n\n add(uniqueId: string, item: T): void { this._added.set(uniqueId, item); this._removed.delete(uniqueId); }\n remove(uniqueId: string): void { this._removed.add(uniqueId); }\n has(uniqueId: string): boolean { return this._added.has(uniqueId) && !this._removed.has(uniqueId); }\n values(): T[] { return Array.from(this._added.entries()).filter(([id]) => !this._removed.has(id)).map(([, v]) => v); }\n size(): number { return this.values().length; }\n\n merge(remote: CRDTSet<T>): void {\n for (const [id, item] of remote._added) if (!this._added.has(id)) this._added.set(id, item);\n for (const id of remote._removed) this._removed.add(id);\n }\n\n state(): { added: [string, T][]; removed: string[] } {\n return { added: Array.from(this._added.entries()), removed: Array.from(this._removed) };\n }\n}\n\n// ─── LWW Register (Last-Write-Wins) ─────────────────────────────────────────\n\nexport class CRDTRegister<T> {\n private _value: T;\n private _timestamp: number;\n private _nodeId: string;\n\n constructor(initial: T, nodeId = 'default', timestamp = 0) {\n this._value = initial; this._timestamp = timestamp; this._nodeId = nodeId;\n }\n\n set(value: T, nodeId: string, timestamp?: number): void {\n const ts = timestamp ?? Date.now();\n if (ts > this._timestamp || (ts === this._timestamp && nodeId > this._nodeId)) {\n this._value = value; this._timestamp = ts; this._nodeId = nodeId;\n }\n }\n\n get(): T { return this._value; }\n timestamp(): number { return this._timestamp; }\n\n merge(remote: CRDTRegister<T>): void {\n this.set(remote._value, remote._nodeId, remote._timestamp);\n }\n\n state(): { value: T; timestamp: number; nodeId: string } {\n return { value: this._value, timestamp: this._timestamp, nodeId: this._nodeId };\n }\n}\n\n// ─── CRDT Text (basic sequence CRDT — simplified RGA) ────────────────────────\n\ninterface _Char {\n id: string; // nodeId:seqNo\n char: string;\n after: string | null; // id of predecessor (null = beginning)\n deleted: boolean;\n}\n\nexport class CRDTText {\n private _chars: _Char[] = [];\n private _index = new Map<string, _Char>();\n\n insert(after: string | null, char: string, nodeId: string, seq: number): string {\n const id = `${nodeId}:${seq}`;\n const c: _Char = { id, char, after, deleted: false };\n const pos = after === null ? 0 : this._chars.findIndex(ch => ch.id === after) + 1;\n this._chars.splice(pos, 0, c);\n this._index.set(id, c);\n return id;\n }\n\n delete(id: string): void {\n const c = this._index.get(id);\n if (c) c.deleted = true;\n }\n\n toString(): string { return this._chars.filter(c => !c.deleted).map(c => c.char).join(''); }\n length(): number { return this._chars.filter(c => !c.deleted).length; }\n\n merge(remote: CRDTText): void {\n for (const rc of remote._chars) {\n if (!this._index.has(rc.id)) {\n const c: _Char = { ...rc };\n const pos = rc.after === null ? 0 : this._chars.findIndex(ch => ch.id === rc.after) + 1;\n this._chars.splice(pos, 0, c);\n this._index.set(c.id, c);\n } else if (rc.deleted) {\n const existing = this._index.get(rc.id)!;\n existing.deleted = true;\n }\n }\n }\n\n state(): _Char[] { return this._chars.map(c => ({ ...c })); }\n}\n\n// ─── Merge helper ────────────────────────────────────────────────────────────\n\nexport function mergeCRDT<T extends { merge(remote: T): void }>(local: T, remote: T): T {\n local.merge(remote);\n return local;\n}\n"]}
1
+ {"version":3,"sources":["../../src/events/index.ts","../../src/sync/sync-engine.ts","../../src/sync/crdt.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export type Unsubscribe = () => void;\nexport type Listener<T> = (value: T) => void;\n\n/**\n * Reports a subscriber that threw during emission, without aborting delivery\n * to the remaining subscribers. Defaults to console.error; override to route\n * to your own logger (e.g. in a banking app where dropped events matter).\n */\nlet _onListenerError: (error: unknown) => void = (error) => {\n // eslint-disable-next-line no-console\n console.error('[joopjs] a subject subscriber threw during emission:', error);\n};\n\n/** Override how subscriber errors are reported during emission. */\nexport function setSubjectErrorHandler(handler: (error: unknown) => void): void {\n _onListenerError = handler;\n}\n\n/**\n * Lightweight pub/sub subject — emits to all current subscribers.\n * Replaces RxJS Subject without pulling in the full RxJS dependency.\n */\nexport class JoopSubject<T> {\n private _listeners: Listener<T>[] = [];\n\n subscribe(listener: Listener<T>): Unsubscribe {\n this._listeners.push(listener);\n return () => {\n this._listeners = this._listeners.filter(l => l !== listener);\n };\n }\n\n next(value: T): void {\n // Snapshot so a subscribe()/unsubscribe() triggered by a listener can't\n // disturb this emission, and isolate each listener so one that throws\n // doesn't deprive later subscribers of the value.\n const listeners = this._listeners.slice();\n for (const listener of listeners) {\n try {\n listener(value);\n } catch (error) {\n _onListenerError(error);\n }\n }\n }\n\n asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Stateful subject — replays the current value to any new subscriber immediately.\n * Replaces RxJS BehaviorSubject.\n */\nexport class JoopBehaviorSubject<T> extends JoopSubject<T> {\n private _value: T;\n\n constructor(initialValue: T) {\n super();\n this._value = initialValue;\n }\n\n getValue(): T {\n return this._value;\n }\n\n override next(value: T): void {\n this._value = value;\n super.next(value);\n }\n\n override subscribe(listener: Listener<T>): Unsubscribe {\n try {\n listener(this._value);\n } catch (error) {\n _onListenerError(error);\n }\n return super.subscribe(listener);\n }\n\n override asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Read-only observable handle returned from asObservable().\n */\nexport class JoopObservable<T> {\n constructor(private _subscribeFn: (listener: Listener<T>) => Unsubscribe) {}\n\n subscribe(listener: Listener<T>): Unsubscribe {\n return this._subscribeFn(listener);\n }\n\n /** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */\n getOnce(): T | undefined {\n let result: T | undefined;\n const unsub = this.subscribe(v => { result = v; });\n unsub();\n return result;\n }\n}\n","import { JoopBehaviorSubject, JoopSubject } from '../events';\n\nexport type JoopSyncConflictStrategy = 'local-wins' | 'remote-wins' | 'merge';\n\nexport interface JoopSyncConfig {\n syncUrl: string;\n headers?: Record<string, string>;\n retryMs?: number;\n maxRetries?: number;\n conflictStrategy?: JoopSyncConflictStrategy;\n batchSize?: number;\n}\n\nexport interface JoopMutation {\n id: string;\n type: string;\n payload: unknown;\n status: 'pending' | 'syncing' | 'synced' | 'failed';\n timestamp: number;\n retries: number;\n}\n\nexport interface JoopSyncConflict {\n id: string;\n mutationId: string;\n local: unknown;\n remote: unknown;\n resolvedAt?: number;\n resolution?: 'local' | 'remote' | 'merged';\n}\n\nexport interface JoopSyncStatus {\n online: boolean;\n pendingCount: number;\n syncedCount: number;\n failedCount: number;\n lastSyncAt: number | null;\n syncing: boolean;\n}\n\nexport class JoopSyncEngine {\n private _cfg: JoopSyncConfig | null = null;\n private _mutations: JoopMutation[] = [];\n private _conflicts: JoopSyncConflict[] = [];\n private _syncing = false;\n private _syncedCount = 0;\n private _lastSyncAt: number | null = null;\n private _online = typeof navigator !== 'undefined' ? navigator.onLine : true;\n private _status$ = new JoopBehaviorSubject<JoopSyncStatus>(this._buildStatus());\n private _conflict$ = new JoopSubject<JoopSyncConflict>();\n private _onlineHandlers: Array<() => void> = [];\n\n configure(config: JoopSyncConfig): void {\n this._cfg = config;\n if (typeof window !== 'undefined') {\n const onOnline = () => { this._online = true; this._updateStatus(); this.sync(); };\n const onOffline = () => { this._online = false; this._updateStatus(); };\n window.addEventListener('online', onOnline);\n window.addEventListener('offline', onOffline);\n this._onlineHandlers.push(\n () => window.removeEventListener('online', onOnline),\n () => window.removeEventListener('offline', onOffline),\n );\n }\n }\n\n destroy(): void { for (const rm of this._onlineHandlers) rm(); this._onlineHandlers = []; }\n\n mutate(type: string, payload: unknown): JoopMutation {\n const m: JoopMutation = { id: _uid(), type, payload, status: 'pending', timestamp: Date.now(), retries: 0 };\n this._mutations.push(m);\n this._updateStatus();\n if (this._online && !this._syncing) this.sync();\n return m;\n }\n\n pending(): JoopMutation[] { return this._mutations.filter(m => m.status === 'pending' || m.status === 'failed'); }\n conflicts(): JoopSyncConflict[] { return [...this._conflicts]; }\n status$() { return this._status$.asObservable(); }\n conflict$() { return this._conflict$.asObservable(); }\n\n async sync(): Promise<void> {\n if (!this._cfg || this._syncing || !this._online) return;\n const pending = this.pending();\n if (pending.length === 0) return;\n\n this._syncing = true;\n this._updateStatus();\n\n const { syncUrl, headers = {}, maxRetries = 3, batchSize = 50 } = this._cfg;\n const batch = pending.slice(0, batchSize);\n\n try {\n for (const m of batch) m.status = 'syncing';\n const res = await fetch(syncUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify({ mutations: batch.map(m => ({ id: m.id, type: m.type, payload: m.payload, timestamp: m.timestamp })) }),\n });\n\n if (!res.ok) throw new Error(`Sync failed: ${res.status}`);\n const data = (await res.json()) as { results: Array<{ id: string; status: 'ok' | 'conflict'; remote?: unknown }> };\n\n for (const result of data.results ?? []) {\n const m = this._mutations.find(x => x.id === result.id);\n if (!m) continue;\n if (result.status === 'ok') {\n m.status = 'synced'; this._syncedCount++;\n } else if (result.status === 'conflict') {\n m.status = 'failed';\n const conflict: JoopSyncConflict = { id: _uid(), mutationId: m.id, local: m.payload, remote: result.remote };\n this._conflicts.push(conflict);\n this._conflict$.next(conflict);\n }\n }\n } catch {\n for (const m of batch) {\n m.retries++; m.status = m.retries >= maxRetries ? 'failed' : 'pending';\n }\n } finally {\n this._syncing = false;\n this._lastSyncAt = Date.now();\n this._updateStatus();\n }\n }\n\n resolve(conflictId: string, strategy: 'local' | 'remote' | 'merge', mergeFn?: (local: unknown, remote: unknown) => unknown): void {\n const conflict = this._conflicts.find(c => c.id === conflictId);\n if (!conflict) return;\n const m = this._mutations.find(x => x.id === conflict.mutationId);\n if (m) {\n if (strategy === 'remote') m.payload = conflict.remote;\n else if (strategy === 'merge' && mergeFn) m.payload = mergeFn(conflict.local, conflict.remote);\n m.status = 'pending'; m.retries = 0;\n }\n conflict.resolvedAt = Date.now();\n conflict.resolution = strategy === 'merge' ? 'merged' : strategy;\n this._conflicts = this._conflicts.filter(c => c.id !== conflictId);\n if (this._online) this.sync();\n }\n\n clearSynced(): void { this._mutations = this._mutations.filter(m => m.status !== 'synced'); this._updateStatus(); }\n\n private _buildStatus(): JoopSyncStatus {\n return {\n online: this._online,\n pendingCount: this._mutations.filter(m => m.status === 'pending').length,\n syncedCount: this._syncedCount,\n failedCount: this._mutations.filter(m => m.status === 'failed').length,\n lastSyncAt: this._lastSyncAt,\n syncing: this._syncing,\n };\n }\n\n private _updateStatus(): void { this._status$.next(this._buildStatus()); }\n}\n\nfunction _uid(): string { return `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`; }\n","// ─── G-Counter (grow-only) ───────────────────────────────────────────────────\n\nexport class CRDTCounter {\n private _inc: Record<string, number> = {};\n private _dec: Record<string, number> = {};\n\n increment(nodeId: string, by = 1): void { this._inc[nodeId] = (this._inc[nodeId] ?? 0) + by; }\n decrement(nodeId: string, by = 1): void { this._dec[nodeId] = (this._dec[nodeId] ?? 0) + by; }\n\n value(): number {\n const inc = Object.values(this._inc).reduce((s, v) => s + v, 0);\n const dec = Object.values(this._dec).reduce((s, v) => s + v, 0);\n return inc - dec;\n }\n\n merge(remote: CRDTCounter): void {\n for (const [id, v] of Object.entries(remote._inc)) this._inc[id] = Math.max(this._inc[id] ?? 0, v);\n for (const [id, v] of Object.entries(remote._dec)) this._dec[id] = Math.max(this._dec[id] ?? 0, v);\n }\n\n state(): { inc: Record<string, number>; dec: Record<string, number> } { return { inc: { ...this._inc }, dec: { ...this._dec } }; }\n\n static fromState(s: { inc: Record<string, number>; dec: Record<string, number> }): CRDTCounter {\n const c = new CRDTCounter(); c._inc = { ...s.inc }; c._dec = { ...s.dec }; return c;\n }\n}\n\n// ─── Add-Wins Set ────────────────────────────────────────────────────────────\n\nexport class CRDTSet<T> {\n private _added = new Map<string, T>();\n private _removed = new Set<string>();\n\n add(uniqueId: string, item: T): void { this._added.set(uniqueId, item); this._removed.delete(uniqueId); }\n remove(uniqueId: string): void { this._removed.add(uniqueId); }\n has(uniqueId: string): boolean { return this._added.has(uniqueId) && !this._removed.has(uniqueId); }\n values(): T[] { return Array.from(this._added.entries()).filter(([id]) => !this._removed.has(id)).map(([, v]) => v); }\n size(): number { return this.values().length; }\n\n merge(remote: CRDTSet<T>): void {\n for (const [id, item] of remote._added) if (!this._added.has(id)) this._added.set(id, item);\n for (const id of remote._removed) this._removed.add(id);\n }\n\n state(): { added: [string, T][]; removed: string[] } {\n return { added: Array.from(this._added.entries()), removed: Array.from(this._removed) };\n }\n}\n\n// ─── LWW Register (Last-Write-Wins) ─────────────────────────────────────────\n\nexport class CRDTRegister<T> {\n private _value: T;\n private _timestamp: number;\n private _nodeId: string;\n\n constructor(initial: T, nodeId = 'default', timestamp = 0) {\n this._value = initial; this._timestamp = timestamp; this._nodeId = nodeId;\n }\n\n set(value: T, nodeId: string, timestamp?: number): void {\n const ts = timestamp ?? Date.now();\n if (ts > this._timestamp || (ts === this._timestamp && nodeId > this._nodeId)) {\n this._value = value; this._timestamp = ts; this._nodeId = nodeId;\n }\n }\n\n get(): T { return this._value; }\n timestamp(): number { return this._timestamp; }\n\n merge(remote: CRDTRegister<T>): void {\n this.set(remote._value, remote._nodeId, remote._timestamp);\n }\n\n state(): { value: T; timestamp: number; nodeId: string } {\n return { value: this._value, timestamp: this._timestamp, nodeId: this._nodeId };\n }\n}\n\n// ─── CRDT Text (basic sequence CRDT — simplified RGA) ────────────────────────\n\ninterface _Char {\n id: string; // nodeId:seqNo\n char: string;\n after: string | null; // id of predecessor (null = beginning)\n deleted: boolean;\n}\n\nexport class CRDTText {\n private _chars: _Char[] = [];\n private _index = new Map<string, _Char>();\n\n insert(after: string | null, char: string, nodeId: string, seq: number): string {\n const id = `${nodeId}:${seq}`;\n const c: _Char = { id, char, after, deleted: false };\n const pos = after === null ? 0 : this._chars.findIndex(ch => ch.id === after) + 1;\n this._chars.splice(pos, 0, c);\n this._index.set(id, c);\n return id;\n }\n\n delete(id: string): void {\n const c = this._index.get(id);\n if (c) c.deleted = true;\n }\n\n toString(): string { return this._chars.filter(c => !c.deleted).map(c => c.char).join(''); }\n length(): number { return this._chars.filter(c => !c.deleted).length; }\n\n merge(remote: CRDTText): void {\n for (const rc of remote._chars) {\n if (!this._index.has(rc.id)) {\n const c: _Char = { ...rc };\n const pos = rc.after === null ? 0 : this._chars.findIndex(ch => ch.id === rc.after) + 1;\n this._chars.splice(pos, 0, c);\n this._index.set(c.id, c);\n } else if (rc.deleted) {\n const existing = this._index.get(rc.id)!;\n existing.deleted = true;\n }\n }\n }\n\n state(): _Char[] { return this._chars.map(c => ({ ...c })); }\n}\n\n// ─── Merge helper ────────────────────────────────────────────────────────────\n\nexport function mergeCRDT<T extends { merge(remote: T): void }>(local: T, remote: T): T {\n local.merge(remote);\n return local;\n}\n"]}
@@ -1,4 +1,7 @@
1
1
  // src/events/index.ts
2
+ var _onListenerError = (error) => {
3
+ console.error("[joopjs] a subject subscriber threw during emission:", error);
4
+ };
2
5
  var JoopSubject = class {
3
6
  _listeners = [];
4
7
  subscribe(listener) {
@@ -8,8 +11,13 @@ var JoopSubject = class {
8
11
  };
9
12
  }
10
13
  next(value) {
11
- for (const listener of this._listeners) {
12
- listener(value);
14
+ const listeners = this._listeners.slice();
15
+ for (const listener of listeners) {
16
+ try {
17
+ listener(value);
18
+ } catch (error) {
19
+ _onListenerError(error);
20
+ }
13
21
  }
14
22
  }
15
23
  asObservable() {
@@ -30,7 +38,11 @@ var JoopBehaviorSubject = class extends JoopSubject {
30
38
  super.next(value);
31
39
  }
32
40
  subscribe(listener) {
33
- listener(this._value);
41
+ try {
42
+ listener(this._value);
43
+ } catch (error) {
44
+ _onListenerError(error);
45
+ }
34
46
  return super.subscribe(listener);
35
47
  }
36
48
  asObservable() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/events/index.ts","../../src/sync/sync-engine.ts","../../src/sync/crdt.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["export type Unsubscribe = () => void;\nexport type Listener<T> = (value: T) => void;\n\n/**\n * Lightweight pub/sub subject — emits to all current subscribers.\n * Replaces RxJS Subject without pulling in the full RxJS dependency.\n */\nexport class JoopSubject<T> {\n private _listeners: Listener<T>[] = [];\n\n subscribe(listener: Listener<T>): Unsubscribe {\n this._listeners.push(listener);\n return () => {\n this._listeners = this._listeners.filter(l => l !== listener);\n };\n }\n\n next(value: T): void {\n for (const listener of this._listeners) {\n listener(value);\n }\n }\n\n asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Stateful subject — replays the current value to any new subscriber immediately.\n * Replaces RxJS BehaviorSubject.\n */\nexport class JoopBehaviorSubject<T> extends JoopSubject<T> {\n private _value: T;\n\n constructor(initialValue: T) {\n super();\n this._value = initialValue;\n }\n\n getValue(): T {\n return this._value;\n }\n\n override next(value: T): void {\n this._value = value;\n super.next(value);\n }\n\n override subscribe(listener: Listener<T>): Unsubscribe {\n listener(this._value);\n return super.subscribe(listener);\n }\n\n override asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Read-only observable handle returned from asObservable().\n */\nexport class JoopObservable<T> {\n constructor(private _subscribeFn: (listener: Listener<T>) => Unsubscribe) {}\n\n subscribe(listener: Listener<T>): Unsubscribe {\n return this._subscribeFn(listener);\n }\n\n /** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */\n getOnce(): T | undefined {\n let result: T | undefined;\n const unsub = this.subscribe(v => { result = v; });\n unsub();\n return result;\n }\n}\n","import { JoopBehaviorSubject, JoopSubject } from '../events';\n\nexport type JoopSyncConflictStrategy = 'local-wins' | 'remote-wins' | 'merge';\n\nexport interface JoopSyncConfig {\n syncUrl: string;\n headers?: Record<string, string>;\n retryMs?: number;\n maxRetries?: number;\n conflictStrategy?: JoopSyncConflictStrategy;\n batchSize?: number;\n}\n\nexport interface JoopMutation {\n id: string;\n type: string;\n payload: unknown;\n status: 'pending' | 'syncing' | 'synced' | 'failed';\n timestamp: number;\n retries: number;\n}\n\nexport interface JoopSyncConflict {\n id: string;\n mutationId: string;\n local: unknown;\n remote: unknown;\n resolvedAt?: number;\n resolution?: 'local' | 'remote' | 'merged';\n}\n\nexport interface JoopSyncStatus {\n online: boolean;\n pendingCount: number;\n syncedCount: number;\n failedCount: number;\n lastSyncAt: number | null;\n syncing: boolean;\n}\n\nexport class JoopSyncEngine {\n private _cfg: JoopSyncConfig | null = null;\n private _mutations: JoopMutation[] = [];\n private _conflicts: JoopSyncConflict[] = [];\n private _syncing = false;\n private _syncedCount = 0;\n private _lastSyncAt: number | null = null;\n private _online = typeof navigator !== 'undefined' ? navigator.onLine : true;\n private _status$ = new JoopBehaviorSubject<JoopSyncStatus>(this._buildStatus());\n private _conflict$ = new JoopSubject<JoopSyncConflict>();\n private _onlineHandlers: Array<() => void> = [];\n\n configure(config: JoopSyncConfig): void {\n this._cfg = config;\n if (typeof window !== 'undefined') {\n const onOnline = () => { this._online = true; this._updateStatus(); this.sync(); };\n const onOffline = () => { this._online = false; this._updateStatus(); };\n window.addEventListener('online', onOnline);\n window.addEventListener('offline', onOffline);\n this._onlineHandlers.push(\n () => window.removeEventListener('online', onOnline),\n () => window.removeEventListener('offline', onOffline),\n );\n }\n }\n\n destroy(): void { for (const rm of this._onlineHandlers) rm(); this._onlineHandlers = []; }\n\n mutate(type: string, payload: unknown): JoopMutation {\n const m: JoopMutation = { id: _uid(), type, payload, status: 'pending', timestamp: Date.now(), retries: 0 };\n this._mutations.push(m);\n this._updateStatus();\n if (this._online && !this._syncing) this.sync();\n return m;\n }\n\n pending(): JoopMutation[] { return this._mutations.filter(m => m.status === 'pending' || m.status === 'failed'); }\n conflicts(): JoopSyncConflict[] { return [...this._conflicts]; }\n status$() { return this._status$.asObservable(); }\n conflict$() { return this._conflict$.asObservable(); }\n\n async sync(): Promise<void> {\n if (!this._cfg || this._syncing || !this._online) return;\n const pending = this.pending();\n if (pending.length === 0) return;\n\n this._syncing = true;\n this._updateStatus();\n\n const { syncUrl, headers = {}, maxRetries = 3, batchSize = 50 } = this._cfg;\n const batch = pending.slice(0, batchSize);\n\n try {\n for (const m of batch) m.status = 'syncing';\n const res = await fetch(syncUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify({ mutations: batch.map(m => ({ id: m.id, type: m.type, payload: m.payload, timestamp: m.timestamp })) }),\n });\n\n if (!res.ok) throw new Error(`Sync failed: ${res.status}`);\n const data = (await res.json()) as { results: Array<{ id: string; status: 'ok' | 'conflict'; remote?: unknown }> };\n\n for (const result of data.results ?? []) {\n const m = this._mutations.find(x => x.id === result.id);\n if (!m) continue;\n if (result.status === 'ok') {\n m.status = 'synced'; this._syncedCount++;\n } else if (result.status === 'conflict') {\n m.status = 'failed';\n const conflict: JoopSyncConflict = { id: _uid(), mutationId: m.id, local: m.payload, remote: result.remote };\n this._conflicts.push(conflict);\n this._conflict$.next(conflict);\n }\n }\n } catch {\n for (const m of batch) {\n m.retries++; m.status = m.retries >= maxRetries ? 'failed' : 'pending';\n }\n } finally {\n this._syncing = false;\n this._lastSyncAt = Date.now();\n this._updateStatus();\n }\n }\n\n resolve(conflictId: string, strategy: 'local' | 'remote' | 'merge', mergeFn?: (local: unknown, remote: unknown) => unknown): void {\n const conflict = this._conflicts.find(c => c.id === conflictId);\n if (!conflict) return;\n const m = this._mutations.find(x => x.id === conflict.mutationId);\n if (m) {\n if (strategy === 'remote') m.payload = conflict.remote;\n else if (strategy === 'merge' && mergeFn) m.payload = mergeFn(conflict.local, conflict.remote);\n m.status = 'pending'; m.retries = 0;\n }\n conflict.resolvedAt = Date.now();\n conflict.resolution = strategy === 'merge' ? 'merged' : strategy;\n this._conflicts = this._conflicts.filter(c => c.id !== conflictId);\n if (this._online) this.sync();\n }\n\n clearSynced(): void { this._mutations = this._mutations.filter(m => m.status !== 'synced'); this._updateStatus(); }\n\n private _buildStatus(): JoopSyncStatus {\n return {\n online: this._online,\n pendingCount: this._mutations.filter(m => m.status === 'pending').length,\n syncedCount: this._syncedCount,\n failedCount: this._mutations.filter(m => m.status === 'failed').length,\n lastSyncAt: this._lastSyncAt,\n syncing: this._syncing,\n };\n }\n\n private _updateStatus(): void { this._status$.next(this._buildStatus()); }\n}\n\nfunction _uid(): string { return `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`; }\n","// ─── G-Counter (grow-only) ───────────────────────────────────────────────────\n\nexport class CRDTCounter {\n private _inc: Record<string, number> = {};\n private _dec: Record<string, number> = {};\n\n increment(nodeId: string, by = 1): void { this._inc[nodeId] = (this._inc[nodeId] ?? 0) + by; }\n decrement(nodeId: string, by = 1): void { this._dec[nodeId] = (this._dec[nodeId] ?? 0) + by; }\n\n value(): number {\n const inc = Object.values(this._inc).reduce((s, v) => s + v, 0);\n const dec = Object.values(this._dec).reduce((s, v) => s + v, 0);\n return inc - dec;\n }\n\n merge(remote: CRDTCounter): void {\n for (const [id, v] of Object.entries(remote._inc)) this._inc[id] = Math.max(this._inc[id] ?? 0, v);\n for (const [id, v] of Object.entries(remote._dec)) this._dec[id] = Math.max(this._dec[id] ?? 0, v);\n }\n\n state(): { inc: Record<string, number>; dec: Record<string, number> } { return { inc: { ...this._inc }, dec: { ...this._dec } }; }\n\n static fromState(s: { inc: Record<string, number>; dec: Record<string, number> }): CRDTCounter {\n const c = new CRDTCounter(); c._inc = { ...s.inc }; c._dec = { ...s.dec }; return c;\n }\n}\n\n// ─── Add-Wins Set ────────────────────────────────────────────────────────────\n\nexport class CRDTSet<T> {\n private _added = new Map<string, T>();\n private _removed = new Set<string>();\n\n add(uniqueId: string, item: T): void { this._added.set(uniqueId, item); this._removed.delete(uniqueId); }\n remove(uniqueId: string): void { this._removed.add(uniqueId); }\n has(uniqueId: string): boolean { return this._added.has(uniqueId) && !this._removed.has(uniqueId); }\n values(): T[] { return Array.from(this._added.entries()).filter(([id]) => !this._removed.has(id)).map(([, v]) => v); }\n size(): number { return this.values().length; }\n\n merge(remote: CRDTSet<T>): void {\n for (const [id, item] of remote._added) if (!this._added.has(id)) this._added.set(id, item);\n for (const id of remote._removed) this._removed.add(id);\n }\n\n state(): { added: [string, T][]; removed: string[] } {\n return { added: Array.from(this._added.entries()), removed: Array.from(this._removed) };\n }\n}\n\n// ─── LWW Register (Last-Write-Wins) ─────────────────────────────────────────\n\nexport class CRDTRegister<T> {\n private _value: T;\n private _timestamp: number;\n private _nodeId: string;\n\n constructor(initial: T, nodeId = 'default', timestamp = 0) {\n this._value = initial; this._timestamp = timestamp; this._nodeId = nodeId;\n }\n\n set(value: T, nodeId: string, timestamp?: number): void {\n const ts = timestamp ?? Date.now();\n if (ts > this._timestamp || (ts === this._timestamp && nodeId > this._nodeId)) {\n this._value = value; this._timestamp = ts; this._nodeId = nodeId;\n }\n }\n\n get(): T { return this._value; }\n timestamp(): number { return this._timestamp; }\n\n merge(remote: CRDTRegister<T>): void {\n this.set(remote._value, remote._nodeId, remote._timestamp);\n }\n\n state(): { value: T; timestamp: number; nodeId: string } {\n return { value: this._value, timestamp: this._timestamp, nodeId: this._nodeId };\n }\n}\n\n// ─── CRDT Text (basic sequence CRDT — simplified RGA) ────────────────────────\n\ninterface _Char {\n id: string; // nodeId:seqNo\n char: string;\n after: string | null; // id of predecessor (null = beginning)\n deleted: boolean;\n}\n\nexport class CRDTText {\n private _chars: _Char[] = [];\n private _index = new Map<string, _Char>();\n\n insert(after: string | null, char: string, nodeId: string, seq: number): string {\n const id = `${nodeId}:${seq}`;\n const c: _Char = { id, char, after, deleted: false };\n const pos = after === null ? 0 : this._chars.findIndex(ch => ch.id === after) + 1;\n this._chars.splice(pos, 0, c);\n this._index.set(id, c);\n return id;\n }\n\n delete(id: string): void {\n const c = this._index.get(id);\n if (c) c.deleted = true;\n }\n\n toString(): string { return this._chars.filter(c => !c.deleted).map(c => c.char).join(''); }\n length(): number { return this._chars.filter(c => !c.deleted).length; }\n\n merge(remote: CRDTText): void {\n for (const rc of remote._chars) {\n if (!this._index.has(rc.id)) {\n const c: _Char = { ...rc };\n const pos = rc.after === null ? 0 : this._chars.findIndex(ch => ch.id === rc.after) + 1;\n this._chars.splice(pos, 0, c);\n this._index.set(c.id, c);\n } else if (rc.deleted) {\n const existing = this._index.get(rc.id)!;\n existing.deleted = true;\n }\n }\n }\n\n state(): _Char[] { return this._chars.map(c => ({ ...c })); }\n}\n\n// ─── Merge helper ────────────────────────────────────────────────────────────\n\nexport function mergeCRDT<T extends { merge(remote: T): void }>(local: T, remote: T): T {\n local.merge(remote);\n return local;\n}\n"]}
1
+ {"version":3,"sources":["../../src/events/index.ts","../../src/sync/sync-engine.ts","../../src/sync/crdt.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["export type Unsubscribe = () => void;\nexport type Listener<T> = (value: T) => void;\n\n/**\n * Reports a subscriber that threw during emission, without aborting delivery\n * to the remaining subscribers. Defaults to console.error; override to route\n * to your own logger (e.g. in a banking app where dropped events matter).\n */\nlet _onListenerError: (error: unknown) => void = (error) => {\n // eslint-disable-next-line no-console\n console.error('[joopjs] a subject subscriber threw during emission:', error);\n};\n\n/** Override how subscriber errors are reported during emission. */\nexport function setSubjectErrorHandler(handler: (error: unknown) => void): void {\n _onListenerError = handler;\n}\n\n/**\n * Lightweight pub/sub subject — emits to all current subscribers.\n * Replaces RxJS Subject without pulling in the full RxJS dependency.\n */\nexport class JoopSubject<T> {\n private _listeners: Listener<T>[] = [];\n\n subscribe(listener: Listener<T>): Unsubscribe {\n this._listeners.push(listener);\n return () => {\n this._listeners = this._listeners.filter(l => l !== listener);\n };\n }\n\n next(value: T): void {\n // Snapshot so a subscribe()/unsubscribe() triggered by a listener can't\n // disturb this emission, and isolate each listener so one that throws\n // doesn't deprive later subscribers of the value.\n const listeners = this._listeners.slice();\n for (const listener of listeners) {\n try {\n listener(value);\n } catch (error) {\n _onListenerError(error);\n }\n }\n }\n\n asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Stateful subject — replays the current value to any new subscriber immediately.\n * Replaces RxJS BehaviorSubject.\n */\nexport class JoopBehaviorSubject<T> extends JoopSubject<T> {\n private _value: T;\n\n constructor(initialValue: T) {\n super();\n this._value = initialValue;\n }\n\n getValue(): T {\n return this._value;\n }\n\n override next(value: T): void {\n this._value = value;\n super.next(value);\n }\n\n override subscribe(listener: Listener<T>): Unsubscribe {\n try {\n listener(this._value);\n } catch (error) {\n _onListenerError(error);\n }\n return super.subscribe(listener);\n }\n\n override asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Read-only observable handle returned from asObservable().\n */\nexport class JoopObservable<T> {\n constructor(private _subscribeFn: (listener: Listener<T>) => Unsubscribe) {}\n\n subscribe(listener: Listener<T>): Unsubscribe {\n return this._subscribeFn(listener);\n }\n\n /** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */\n getOnce(): T | undefined {\n let result: T | undefined;\n const unsub = this.subscribe(v => { result = v; });\n unsub();\n return result;\n }\n}\n","import { JoopBehaviorSubject, JoopSubject } from '../events';\n\nexport type JoopSyncConflictStrategy = 'local-wins' | 'remote-wins' | 'merge';\n\nexport interface JoopSyncConfig {\n syncUrl: string;\n headers?: Record<string, string>;\n retryMs?: number;\n maxRetries?: number;\n conflictStrategy?: JoopSyncConflictStrategy;\n batchSize?: number;\n}\n\nexport interface JoopMutation {\n id: string;\n type: string;\n payload: unknown;\n status: 'pending' | 'syncing' | 'synced' | 'failed';\n timestamp: number;\n retries: number;\n}\n\nexport interface JoopSyncConflict {\n id: string;\n mutationId: string;\n local: unknown;\n remote: unknown;\n resolvedAt?: number;\n resolution?: 'local' | 'remote' | 'merged';\n}\n\nexport interface JoopSyncStatus {\n online: boolean;\n pendingCount: number;\n syncedCount: number;\n failedCount: number;\n lastSyncAt: number | null;\n syncing: boolean;\n}\n\nexport class JoopSyncEngine {\n private _cfg: JoopSyncConfig | null = null;\n private _mutations: JoopMutation[] = [];\n private _conflicts: JoopSyncConflict[] = [];\n private _syncing = false;\n private _syncedCount = 0;\n private _lastSyncAt: number | null = null;\n private _online = typeof navigator !== 'undefined' ? navigator.onLine : true;\n private _status$ = new JoopBehaviorSubject<JoopSyncStatus>(this._buildStatus());\n private _conflict$ = new JoopSubject<JoopSyncConflict>();\n private _onlineHandlers: Array<() => void> = [];\n\n configure(config: JoopSyncConfig): void {\n this._cfg = config;\n if (typeof window !== 'undefined') {\n const onOnline = () => { this._online = true; this._updateStatus(); this.sync(); };\n const onOffline = () => { this._online = false; this._updateStatus(); };\n window.addEventListener('online', onOnline);\n window.addEventListener('offline', onOffline);\n this._onlineHandlers.push(\n () => window.removeEventListener('online', onOnline),\n () => window.removeEventListener('offline', onOffline),\n );\n }\n }\n\n destroy(): void { for (const rm of this._onlineHandlers) rm(); this._onlineHandlers = []; }\n\n mutate(type: string, payload: unknown): JoopMutation {\n const m: JoopMutation = { id: _uid(), type, payload, status: 'pending', timestamp: Date.now(), retries: 0 };\n this._mutations.push(m);\n this._updateStatus();\n if (this._online && !this._syncing) this.sync();\n return m;\n }\n\n pending(): JoopMutation[] { return this._mutations.filter(m => m.status === 'pending' || m.status === 'failed'); }\n conflicts(): JoopSyncConflict[] { return [...this._conflicts]; }\n status$() { return this._status$.asObservable(); }\n conflict$() { return this._conflict$.asObservable(); }\n\n async sync(): Promise<void> {\n if (!this._cfg || this._syncing || !this._online) return;\n const pending = this.pending();\n if (pending.length === 0) return;\n\n this._syncing = true;\n this._updateStatus();\n\n const { syncUrl, headers = {}, maxRetries = 3, batchSize = 50 } = this._cfg;\n const batch = pending.slice(0, batchSize);\n\n try {\n for (const m of batch) m.status = 'syncing';\n const res = await fetch(syncUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify({ mutations: batch.map(m => ({ id: m.id, type: m.type, payload: m.payload, timestamp: m.timestamp })) }),\n });\n\n if (!res.ok) throw new Error(`Sync failed: ${res.status}`);\n const data = (await res.json()) as { results: Array<{ id: string; status: 'ok' | 'conflict'; remote?: unknown }> };\n\n for (const result of data.results ?? []) {\n const m = this._mutations.find(x => x.id === result.id);\n if (!m) continue;\n if (result.status === 'ok') {\n m.status = 'synced'; this._syncedCount++;\n } else if (result.status === 'conflict') {\n m.status = 'failed';\n const conflict: JoopSyncConflict = { id: _uid(), mutationId: m.id, local: m.payload, remote: result.remote };\n this._conflicts.push(conflict);\n this._conflict$.next(conflict);\n }\n }\n } catch {\n for (const m of batch) {\n m.retries++; m.status = m.retries >= maxRetries ? 'failed' : 'pending';\n }\n } finally {\n this._syncing = false;\n this._lastSyncAt = Date.now();\n this._updateStatus();\n }\n }\n\n resolve(conflictId: string, strategy: 'local' | 'remote' | 'merge', mergeFn?: (local: unknown, remote: unknown) => unknown): void {\n const conflict = this._conflicts.find(c => c.id === conflictId);\n if (!conflict) return;\n const m = this._mutations.find(x => x.id === conflict.mutationId);\n if (m) {\n if (strategy === 'remote') m.payload = conflict.remote;\n else if (strategy === 'merge' && mergeFn) m.payload = mergeFn(conflict.local, conflict.remote);\n m.status = 'pending'; m.retries = 0;\n }\n conflict.resolvedAt = Date.now();\n conflict.resolution = strategy === 'merge' ? 'merged' : strategy;\n this._conflicts = this._conflicts.filter(c => c.id !== conflictId);\n if (this._online) this.sync();\n }\n\n clearSynced(): void { this._mutations = this._mutations.filter(m => m.status !== 'synced'); this._updateStatus(); }\n\n private _buildStatus(): JoopSyncStatus {\n return {\n online: this._online,\n pendingCount: this._mutations.filter(m => m.status === 'pending').length,\n syncedCount: this._syncedCount,\n failedCount: this._mutations.filter(m => m.status === 'failed').length,\n lastSyncAt: this._lastSyncAt,\n syncing: this._syncing,\n };\n }\n\n private _updateStatus(): void { this._status$.next(this._buildStatus()); }\n}\n\nfunction _uid(): string { return `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`; }\n","// ─── G-Counter (grow-only) ───────────────────────────────────────────────────\n\nexport class CRDTCounter {\n private _inc: Record<string, number> = {};\n private _dec: Record<string, number> = {};\n\n increment(nodeId: string, by = 1): void { this._inc[nodeId] = (this._inc[nodeId] ?? 0) + by; }\n decrement(nodeId: string, by = 1): void { this._dec[nodeId] = (this._dec[nodeId] ?? 0) + by; }\n\n value(): number {\n const inc = Object.values(this._inc).reduce((s, v) => s + v, 0);\n const dec = Object.values(this._dec).reduce((s, v) => s + v, 0);\n return inc - dec;\n }\n\n merge(remote: CRDTCounter): void {\n for (const [id, v] of Object.entries(remote._inc)) this._inc[id] = Math.max(this._inc[id] ?? 0, v);\n for (const [id, v] of Object.entries(remote._dec)) this._dec[id] = Math.max(this._dec[id] ?? 0, v);\n }\n\n state(): { inc: Record<string, number>; dec: Record<string, number> } { return { inc: { ...this._inc }, dec: { ...this._dec } }; }\n\n static fromState(s: { inc: Record<string, number>; dec: Record<string, number> }): CRDTCounter {\n const c = new CRDTCounter(); c._inc = { ...s.inc }; c._dec = { ...s.dec }; return c;\n }\n}\n\n// ─── Add-Wins Set ────────────────────────────────────────────────────────────\n\nexport class CRDTSet<T> {\n private _added = new Map<string, T>();\n private _removed = new Set<string>();\n\n add(uniqueId: string, item: T): void { this._added.set(uniqueId, item); this._removed.delete(uniqueId); }\n remove(uniqueId: string): void { this._removed.add(uniqueId); }\n has(uniqueId: string): boolean { return this._added.has(uniqueId) && !this._removed.has(uniqueId); }\n values(): T[] { return Array.from(this._added.entries()).filter(([id]) => !this._removed.has(id)).map(([, v]) => v); }\n size(): number { return this.values().length; }\n\n merge(remote: CRDTSet<T>): void {\n for (const [id, item] of remote._added) if (!this._added.has(id)) this._added.set(id, item);\n for (const id of remote._removed) this._removed.add(id);\n }\n\n state(): { added: [string, T][]; removed: string[] } {\n return { added: Array.from(this._added.entries()), removed: Array.from(this._removed) };\n }\n}\n\n// ─── LWW Register (Last-Write-Wins) ─────────────────────────────────────────\n\nexport class CRDTRegister<T> {\n private _value: T;\n private _timestamp: number;\n private _nodeId: string;\n\n constructor(initial: T, nodeId = 'default', timestamp = 0) {\n this._value = initial; this._timestamp = timestamp; this._nodeId = nodeId;\n }\n\n set(value: T, nodeId: string, timestamp?: number): void {\n const ts = timestamp ?? Date.now();\n if (ts > this._timestamp || (ts === this._timestamp && nodeId > this._nodeId)) {\n this._value = value; this._timestamp = ts; this._nodeId = nodeId;\n }\n }\n\n get(): T { return this._value; }\n timestamp(): number { return this._timestamp; }\n\n merge(remote: CRDTRegister<T>): void {\n this.set(remote._value, remote._nodeId, remote._timestamp);\n }\n\n state(): { value: T; timestamp: number; nodeId: string } {\n return { value: this._value, timestamp: this._timestamp, nodeId: this._nodeId };\n }\n}\n\n// ─── CRDT Text (basic sequence CRDT — simplified RGA) ────────────────────────\n\ninterface _Char {\n id: string; // nodeId:seqNo\n char: string;\n after: string | null; // id of predecessor (null = beginning)\n deleted: boolean;\n}\n\nexport class CRDTText {\n private _chars: _Char[] = [];\n private _index = new Map<string, _Char>();\n\n insert(after: string | null, char: string, nodeId: string, seq: number): string {\n const id = `${nodeId}:${seq}`;\n const c: _Char = { id, char, after, deleted: false };\n const pos = after === null ? 0 : this._chars.findIndex(ch => ch.id === after) + 1;\n this._chars.splice(pos, 0, c);\n this._index.set(id, c);\n return id;\n }\n\n delete(id: string): void {\n const c = this._index.get(id);\n if (c) c.deleted = true;\n }\n\n toString(): string { return this._chars.filter(c => !c.deleted).map(c => c.char).join(''); }\n length(): number { return this._chars.filter(c => !c.deleted).length; }\n\n merge(remote: CRDTText): void {\n for (const rc of remote._chars) {\n if (!this._index.has(rc.id)) {\n const c: _Char = { ...rc };\n const pos = rc.after === null ? 0 : this._chars.findIndex(ch => ch.id === rc.after) + 1;\n this._chars.splice(pos, 0, c);\n this._index.set(c.id, c);\n } else if (rc.deleted) {\n const existing = this._index.get(rc.id)!;\n existing.deleted = true;\n }\n }\n }\n\n state(): _Char[] { return this._chars.map(c => ({ ...c })); }\n}\n\n// ─── Merge helper ────────────────────────────────────────────────────────────\n\nexport function mergeCRDT<T extends { merge(remote: T): void }>(local: T, remote: T): T {\n local.merge(remote);\n return local;\n}\n"]}
@@ -1,6 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  // src/events/index.ts
4
+ var _onListenerError = (error) => {
5
+ console.error("[joopjs] a subject subscriber threw during emission:", error);
6
+ };
4
7
  var JoopSubject = class {
5
8
  _listeners = [];
6
9
  subscribe(listener) {
@@ -10,8 +13,13 @@ var JoopSubject = class {
10
13
  };
11
14
  }
12
15
  next(value) {
13
- for (const listener of this._listeners) {
14
- listener(value);
16
+ const listeners = this._listeners.slice();
17
+ for (const listener of listeners) {
18
+ try {
19
+ listener(value);
20
+ } catch (error) {
21
+ _onListenerError(error);
22
+ }
15
23
  }
16
24
  }
17
25
  asObservable() {
@@ -32,7 +40,11 @@ var JoopBehaviorSubject = class extends JoopSubject {
32
40
  super.next(value);
33
41
  }
34
42
  subscribe(listener) {
35
- listener(this._value);
43
+ try {
44
+ listener(this._value);
45
+ } catch (error) {
46
+ _onListenerError(error);
47
+ }
36
48
  return super.subscribe(listener);
37
49
  }
38
50
  asObservable() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/events/index.ts","../../src/theme/theme.service.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export type Unsubscribe = () => void;\nexport type Listener<T> = (value: T) => void;\n\n/**\n * Lightweight pub/sub subject — emits to all current subscribers.\n * Replaces RxJS Subject without pulling in the full RxJS dependency.\n */\nexport class JoopSubject<T> {\n private _listeners: Listener<T>[] = [];\n\n subscribe(listener: Listener<T>): Unsubscribe {\n this._listeners.push(listener);\n return () => {\n this._listeners = this._listeners.filter(l => l !== listener);\n };\n }\n\n next(value: T): void {\n for (const listener of this._listeners) {\n listener(value);\n }\n }\n\n asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Stateful subject — replays the current value to any new subscriber immediately.\n * Replaces RxJS BehaviorSubject.\n */\nexport class JoopBehaviorSubject<T> extends JoopSubject<T> {\n private _value: T;\n\n constructor(initialValue: T) {\n super();\n this._value = initialValue;\n }\n\n getValue(): T {\n return this._value;\n }\n\n override next(value: T): void {\n this._value = value;\n super.next(value);\n }\n\n override subscribe(listener: Listener<T>): Unsubscribe {\n listener(this._value);\n return super.subscribe(listener);\n }\n\n override asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Read-only observable handle returned from asObservable().\n */\nexport class JoopObservable<T> {\n constructor(private _subscribeFn: (listener: Listener<T>) => Unsubscribe) {}\n\n subscribe(listener: Listener<T>): Unsubscribe {\n return this._subscribeFn(listener);\n }\n\n /** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */\n getOnce(): T | undefined {\n let result: T | undefined;\n const unsub = this.subscribe(v => { result = v; });\n unsub();\n return result;\n }\n}\n","import { JoopBehaviorSubject } from '../events';\n\nexport interface JoopThemeColor {\n name: string;\n value: string;\n contrastText?: string;\n}\n\nexport interface JoopThemePalette {\n name: string;\n prefix: string;\n contrastPrefix?: string;\n baseColor?: string;\n colors: JoopThemeColor[];\n}\n\nexport interface JoopTheme {\n id: number;\n themeName: string;\n palettes: JoopThemePalette[];\n isDefault?: boolean;\n fontFamily?: string;\n fontSize?: string;\n}\n\nexport interface JoopThemeInfo {\n id: number;\n themeName: string;\n primary: string;\n}\n\nconst STYLE_TAG_ID = '__joop_theme__';\n\nexport class JoopThemeService {\n private _themes: JoopTheme[] = [];\n private _active$ = new JoopBehaviorSubject<string>('');\n private _id$ = new JoopBehaviorSubject<number>(0);\n\n async load(themesOrUrl: JoopTheme[] | string): Promise<JoopTheme[]> {\n if (Array.isArray(themesOrUrl)) {\n this._themes = themesOrUrl;\n } else {\n const res = await fetch(themesOrUrl);\n this._themes = await res.json();\n }\n return this._themes;\n }\n\n getAll(): JoopTheme[] { return this._themes; }\n\n getDefault(): JoopTheme | undefined {\n return this._themes.find(t => t.isDefault) ?? this._themes[0];\n }\n\n getByName(name: string): JoopTheme | undefined {\n return this._themes.find(t => t.themeName === name);\n }\n\n getById(id: number): JoopTheme | undefined {\n return this._themes.find(t => t.id === id);\n }\n\n getMapped(): JoopThemeInfo[] {\n return this._themes.map(t => ({\n id: t.id,\n themeName: t.themeName,\n primary: t.palettes.find(p => p.name === 'Primary')?.baseColor ?? '',\n }));\n }\n\n /** Inject a theme's palette as CSS custom properties on :root */\n apply(theme: JoopTheme | string): void {\n const resolved = typeof theme === 'string' ? this.getByName(theme) : theme;\n if (!resolved) return;\n\n const vars = this._buildCssVars(resolved);\n this._injectStyles(vars);\n this._active$.next(resolved.themeName);\n this._id$.next(resolved.id);\n }\n\n applyById(id: number): void {\n const theme = this.getById(id);\n if (theme) this.apply(theme);\n }\n\n applyDefault(): void {\n const theme = this.getDefault();\n if (theme) this.apply(theme);\n }\n\n /** Apply arbitrary CSS custom properties to :root */\n applyVars(vars: Record<string, string>): void {\n const css = Object.entries(vars).map(([k, v]) => ` ${k}: ${v};`).join('\\n');\n this._injectStyles(`\\n${css}\\n`);\n }\n\n getActiveName(): string { return this._active$.getValue(); }\n getActiveId(): number { return this._id$.getValue(); }\n active$() { return this._active$.asObservable(); }\n activeId$() { return this._id$.asObservable(); }\n\n clearStyles(): void {\n document.getElementById(STYLE_TAG_ID)?.remove();\n }\n\n private _buildCssVars(theme: JoopTheme): string {\n const lines: string[] = [];\n for (const palette of theme.palettes) {\n const p = palette.prefix ?? palette.name.toLowerCase().slice(0, 2);\n if (palette.baseColor) {\n lines.push(` --joop-${p}: ${palette.baseColor};`);\n }\n for (const color of palette.colors) {\n lines.push(` --joop-${p}-${color.name}: ${color.value};`);\n if (color.contrastText) {\n const cp = palette.contrastPrefix ?? `${p}-c`;\n lines.push(` --joop-${cp}-${color.name}: ${color.contrastText};`);\n }\n }\n }\n if (theme.fontFamily) lines.push(` --joop-font-family: ${theme.fontFamily};`);\n if (theme.fontSize) lines.push(` --joop-font-size: ${theme.fontSize};`);\n return lines.join('\\n');\n }\n\n private _injectStyles(vars: string): void {\n if (typeof document === 'undefined') return;\n let tag = document.getElementById(STYLE_TAG_ID) as HTMLStyleElement | null;\n if (!tag) {\n tag = document.createElement('style');\n tag.id = STYLE_TAG_ID;\n document.head.appendChild(tag);\n }\n tag.textContent = `:root {\\n${vars}\\n}`;\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/events/index.ts","../../src/theme/theme.service.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export type Unsubscribe = () => void;\nexport type Listener<T> = (value: T) => void;\n\n/**\n * Reports a subscriber that threw during emission, without aborting delivery\n * to the remaining subscribers. Defaults to console.error; override to route\n * to your own logger (e.g. in a banking app where dropped events matter).\n */\nlet _onListenerError: (error: unknown) => void = (error) => {\n // eslint-disable-next-line no-console\n console.error('[joopjs] a subject subscriber threw during emission:', error);\n};\n\n/** Override how subscriber errors are reported during emission. */\nexport function setSubjectErrorHandler(handler: (error: unknown) => void): void {\n _onListenerError = handler;\n}\n\n/**\n * Lightweight pub/sub subject — emits to all current subscribers.\n * Replaces RxJS Subject without pulling in the full RxJS dependency.\n */\nexport class JoopSubject<T> {\n private _listeners: Listener<T>[] = [];\n\n subscribe(listener: Listener<T>): Unsubscribe {\n this._listeners.push(listener);\n return () => {\n this._listeners = this._listeners.filter(l => l !== listener);\n };\n }\n\n next(value: T): void {\n // Snapshot so a subscribe()/unsubscribe() triggered by a listener can't\n // disturb this emission, and isolate each listener so one that throws\n // doesn't deprive later subscribers of the value.\n const listeners = this._listeners.slice();\n for (const listener of listeners) {\n try {\n listener(value);\n } catch (error) {\n _onListenerError(error);\n }\n }\n }\n\n asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Stateful subject — replays the current value to any new subscriber immediately.\n * Replaces RxJS BehaviorSubject.\n */\nexport class JoopBehaviorSubject<T> extends JoopSubject<T> {\n private _value: T;\n\n constructor(initialValue: T) {\n super();\n this._value = initialValue;\n }\n\n getValue(): T {\n return this._value;\n }\n\n override next(value: T): void {\n this._value = value;\n super.next(value);\n }\n\n override subscribe(listener: Listener<T>): Unsubscribe {\n try {\n listener(this._value);\n } catch (error) {\n _onListenerError(error);\n }\n return super.subscribe(listener);\n }\n\n override asObservable(): JoopObservable<T> {\n return new JoopObservable<T>(listener => this.subscribe(listener));\n }\n}\n\n/**\n * Read-only observable handle returned from asObservable().\n */\nexport class JoopObservable<T> {\n constructor(private _subscribeFn: (listener: Listener<T>) => Unsubscribe) {}\n\n subscribe(listener: Listener<T>): Unsubscribe {\n return this._subscribeFn(listener);\n }\n\n /** Returns the current value without subscribing (only meaningful for BehaviorSubject-backed observables). */\n getOnce(): T | undefined {\n let result: T | undefined;\n const unsub = this.subscribe(v => { result = v; });\n unsub();\n return result;\n }\n}\n","import { JoopBehaviorSubject } from '../events';\n\nexport interface JoopThemeColor {\n name: string;\n value: string;\n contrastText?: string;\n}\n\nexport interface JoopThemePalette {\n name: string;\n prefix: string;\n contrastPrefix?: string;\n baseColor?: string;\n colors: JoopThemeColor[];\n}\n\nexport interface JoopTheme {\n id: number;\n themeName: string;\n palettes: JoopThemePalette[];\n isDefault?: boolean;\n fontFamily?: string;\n fontSize?: string;\n}\n\nexport interface JoopThemeInfo {\n id: number;\n themeName: string;\n primary: string;\n}\n\nconst STYLE_TAG_ID = '__joop_theme__';\n\nexport class JoopThemeService {\n private _themes: JoopTheme[] = [];\n private _active$ = new JoopBehaviorSubject<string>('');\n private _id$ = new JoopBehaviorSubject<number>(0);\n\n async load(themesOrUrl: JoopTheme[] | string): Promise<JoopTheme[]> {\n if (Array.isArray(themesOrUrl)) {\n this._themes = themesOrUrl;\n } else {\n const res = await fetch(themesOrUrl);\n this._themes = await res.json();\n }\n return this._themes;\n }\n\n getAll(): JoopTheme[] { return this._themes; }\n\n getDefault(): JoopTheme | undefined {\n return this._themes.find(t => t.isDefault) ?? this._themes[0];\n }\n\n getByName(name: string): JoopTheme | undefined {\n return this._themes.find(t => t.themeName === name);\n }\n\n getById(id: number): JoopTheme | undefined {\n return this._themes.find(t => t.id === id);\n }\n\n getMapped(): JoopThemeInfo[] {\n return this._themes.map(t => ({\n id: t.id,\n themeName: t.themeName,\n primary: t.palettes.find(p => p.name === 'Primary')?.baseColor ?? '',\n }));\n }\n\n /** Inject a theme's palette as CSS custom properties on :root */\n apply(theme: JoopTheme | string): void {\n const resolved = typeof theme === 'string' ? this.getByName(theme) : theme;\n if (!resolved) return;\n\n const vars = this._buildCssVars(resolved);\n this._injectStyles(vars);\n this._active$.next(resolved.themeName);\n this._id$.next(resolved.id);\n }\n\n applyById(id: number): void {\n const theme = this.getById(id);\n if (theme) this.apply(theme);\n }\n\n applyDefault(): void {\n const theme = this.getDefault();\n if (theme) this.apply(theme);\n }\n\n /** Apply arbitrary CSS custom properties to :root */\n applyVars(vars: Record<string, string>): void {\n const css = Object.entries(vars).map(([k, v]) => ` ${k}: ${v};`).join('\\n');\n this._injectStyles(`\\n${css}\\n`);\n }\n\n getActiveName(): string { return this._active$.getValue(); }\n getActiveId(): number { return this._id$.getValue(); }\n active$() { return this._active$.asObservable(); }\n activeId$() { return this._id$.asObservable(); }\n\n clearStyles(): void {\n document.getElementById(STYLE_TAG_ID)?.remove();\n }\n\n private _buildCssVars(theme: JoopTheme): string {\n const lines: string[] = [];\n for (const palette of theme.palettes) {\n const p = palette.prefix ?? palette.name.toLowerCase().slice(0, 2);\n if (palette.baseColor) {\n lines.push(` --joop-${p}: ${palette.baseColor};`);\n }\n for (const color of palette.colors) {\n lines.push(` --joop-${p}-${color.name}: ${color.value};`);\n if (color.contrastText) {\n const cp = palette.contrastPrefix ?? `${p}-c`;\n lines.push(` --joop-${cp}-${color.name}: ${color.contrastText};`);\n }\n }\n }\n if (theme.fontFamily) lines.push(` --joop-font-family: ${theme.fontFamily};`);\n if (theme.fontSize) lines.push(` --joop-font-size: ${theme.fontSize};`);\n return lines.join('\\n');\n }\n\n private _injectStyles(vars: string): void {\n if (typeof document === 'undefined') return;\n let tag = document.getElementById(STYLE_TAG_ID) as HTMLStyleElement | null;\n if (!tag) {\n tag = document.createElement('style');\n tag.id = STYLE_TAG_ID;\n document.head.appendChild(tag);\n }\n tag.textContent = `:root {\\n${vars}\\n}`;\n }\n}\n"]}
@@ -1,4 +1,7 @@
1
1
  // src/events/index.ts
2
+ var _onListenerError = (error) => {
3
+ console.error("[joopjs] a subject subscriber threw during emission:", error);
4
+ };
2
5
  var JoopSubject = class {
3
6
  _listeners = [];
4
7
  subscribe(listener) {
@@ -8,8 +11,13 @@ var JoopSubject = class {
8
11
  };
9
12
  }
10
13
  next(value) {
11
- for (const listener of this._listeners) {
12
- listener(value);
14
+ const listeners = this._listeners.slice();
15
+ for (const listener of listeners) {
16
+ try {
17
+ listener(value);
18
+ } catch (error) {
19
+ _onListenerError(error);
20
+ }
13
21
  }
14
22
  }
15
23
  asObservable() {
@@ -30,7 +38,11 @@ var JoopBehaviorSubject = class extends JoopSubject {
30
38
  super.next(value);
31
39
  }
32
40
  subscribe(listener) {
33
- listener(this._value);
41
+ try {
42
+ listener(this._value);
43
+ } catch (error) {
44
+ _onListenerError(error);
45
+ }
34
46
  return super.subscribe(listener);
35
47
  }
36
48
  asObservable() {