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,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/deeplink/deeplink.service.ts","../../src/deeplink/deeplink-router.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 { JoopSubject, JoopBehaviorSubject } from '../events';\n\nexport interface JoopDeeplinkData {\n module: string;\n data?: string;\n timestamp: number;\n}\n\nconst STORAGE_KEY = '__joop_deeplink__';\n\nexport class JoopDeeplinkService {\n private _close$ = new JoopSubject<boolean>();\n private _incoming$ = new JoopSubject<JoopDeeplinkData>();\n private _module$ = new JoopBehaviorSubject<string>('');\n private _unlisten: (() => void) | null = null;\n\n getModule(): string { return this._module$.getValue(); }\n module$() { return this._module$.asObservable(); }\n close$() { return this._close$.asObservable(); }\n incoming$() { return this._incoming$.asObservable(); }\n\n /**\n * Set the deeplink module + data, broadcast via localStorage, then signal tab close.\n * Returns a Promise that resolves when the current tab is done.\n */\n setModule(module: string, data?: string): Promise<JoopDeeplinkData> {\n const payload: JoopDeeplinkData = { module, data, timestamp: Date.now() };\n this._module$.next(module);\n\n if (typeof localStorage !== 'undefined') {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(payload));\n // remove immediately so storage event fires on every call\n localStorage.removeItem(STORAGE_KEY);\n }\n\n this._close$.next(true);\n\n return new Promise(resolve => {\n const unsub = this._incoming$.subscribe(d => {\n unsub();\n resolve(d);\n });\n setTimeout(() => { unsub(); resolve(payload); }, 2000);\n });\n }\n\n /**\n * Start listening for deeplink data from another tab via storage events.\n * Returns a cleanup function.\n */\n startListening(storageKey = STORAGE_KEY): () => void {\n if (typeof window === 'undefined') return () => {};\n const handler = (event: StorageEvent) => {\n if (event.key !== storageKey || !event.newValue) return;\n try {\n const data: JoopDeeplinkData = JSON.parse(event.newValue);\n this._module$.next(data.module);\n this._incoming$.next(data);\n } catch { /* ignore */ }\n };\n window.addEventListener('storage', handler);\n this._unlisten = () => window.removeEventListener('storage', handler);\n return this._unlisten;\n }\n\n stopListening(): void {\n this._unlisten?.();\n this._unlisten = null;\n }\n\n /** Signal this tab should close (without deeplink) */\n requestClose(): void { this._close$.next(false); }\n\n /** Read deeplink payload written by another tab on this page load */\n readIncoming(storageKey = STORAGE_KEY): JoopDeeplinkData | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n const raw = localStorage.getItem(storageKey);\n return raw ? JSON.parse(raw) : null;\n } catch { return null; }\n }\n\n clearStored(storageKey = STORAGE_KEY): void {\n if (typeof localStorage !== 'undefined') localStorage.removeItem(storageKey);\n }\n}\n","// URL-pattern deeplink router — distinct from the cross-tab JoopDeeplinkService.\n// Handles incoming URLs with :param and *wildcard patterns.\n\nexport interface JoopRouteParams {\n params: Record<string, string>;\n query: Record<string, string>;\n hash: string;\n url: string;\n pattern: string;\n}\n\nexport type JoopRouteHandler = (match: JoopRouteParams) => void | Promise<void>;\n\ninterface RegisteredRoute {\n pattern: string;\n regex: RegExp;\n keys: string[];\n handler: JoopRouteHandler;\n priority: number;\n}\n\nfunction _compilePattern(pattern: string): { regex: RegExp; keys: string[] } {\n const keys: string[] = [];\n const escaped = pattern\n .replace(/\\//g, '\\\\/')\n .replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, (_, key) => { keys.push(key); return '([^/]+)'; })\n .replace(/\\*/g, '(.*)');\n return { regex: new RegExp(`^${escaped}$`), keys };\n}\n\nfunction _parseQuery(search: string): Record<string, string> {\n const params: Record<string, string> = {};\n if (!search) return params;\n new URLSearchParams(search.startsWith('?') ? search.slice(1) : search)\n .forEach((v, k) => { params[k] = v; });\n return params;\n}\n\nexport class JoopDeeplinkRouter {\n private _routes: RegisteredRoute[] = [];\n private _fallback: JoopRouteHandler | null = null;\n private _history: string[] = [];\n private _maxHistory = 50;\n\n /** Register a URL-pattern handler. Returns an unsubscribe function. */\n on(pattern: string, handler: JoopRouteHandler, priority = 0): () => void {\n const { regex, keys } = _compilePattern(pattern);\n const route: RegisteredRoute = { pattern, regex, keys, handler, priority };\n this._routes.push(route);\n this._routes.sort((a, b) => b.priority - a.priority);\n return () => { this._routes = this._routes.filter(r => r !== route); };\n }\n\n /** Register a fallback handler for unmatched URLs. */\n fallback(handler: JoopRouteHandler): void {\n this._fallback = handler;\n }\n\n /** Dispatch a URL, return true if a handler matched. */\n async dispatch(url: string): Promise<boolean> {\n this._history.push(url);\n if (this._history.length > this._maxHistory) this._history.shift();\n\n let path: string, search: string, hash: string;\n try {\n const parsed = new URL(url, 'http://x');\n path = parsed.pathname;\n search = parsed.search;\n hash = parsed.hash;\n } catch {\n path = url; search = ''; hash = '';\n }\n\n for (const route of this._routes) {\n const match = route.regex.exec(path);\n if (!match) continue;\n const params: Record<string, string> = {};\n route.keys.forEach((k, i) => { params[k] = decodeURIComponent(match[i + 1] ?? ''); });\n await route.handler({ params, query: _parseQuery(search), hash, url, pattern: route.pattern });\n return true;\n }\n\n if (this._fallback) {\n await this._fallback({ params: {}, query: _parseQuery(search), hash, url, pattern: '' });\n }\n return false;\n }\n\n /** Parse a URL into parts without dispatching. */\n parse(url: string): Omit<JoopRouteParams, 'pattern'> & { matchedPattern: string | null } {\n let path: string, search: string, hash: string;\n try {\n const p = new URL(url, 'http://x');\n path = p.pathname; search = p.search; hash = p.hash;\n } catch { path = url; search = ''; hash = ''; }\n\n for (const route of this._routes) {\n const match = route.regex.exec(path);\n if (!match) continue;\n const params: Record<string, string> = {};\n route.keys.forEach((k, i) => { params[k] = decodeURIComponent(match[i + 1] ?? ''); });\n return { params, query: _parseQuery(search), hash, url, matchedPattern: route.pattern };\n }\n return { params: {}, query: _parseQuery(search), hash, url, matchedPattern: null };\n }\n\n /** Build a URL from a pattern and param values. */\n buildUrl(pattern: string, params: Record<string, string> = {}, query: Record<string, string> = {}): string {\n let path = pattern;\n for (const [k, v] of Object.entries(params)) {\n path = path.replace(`:${k}`, encodeURIComponent(v));\n }\n const qs = new URLSearchParams(query).toString();\n return qs ? `${path}?${qs}` : path;\n }\n\n /** List all registered patterns. */\n routes(): string[] {\n return this._routes.map(r => r.pattern);\n }\n\n /** Navigation history (last N dispatched URLs). */\n history(): readonly string[] {\n return this._history;\n }\n\n /** Remove all registered handlers. */\n clear(): void {\n this._routes = [];\n this._fallback = null;\n }\n\n /** Dispatch the current window.location.href. */\n dispatchCurrent(): Promise<boolean> {\n if (typeof window === 'undefined') return Promise.resolve(false);\n return this.dispatch(window.location.href);\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/events/index.ts","../../src/deeplink/deeplink.service.ts","../../src/deeplink/deeplink-router.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 { JoopSubject, JoopBehaviorSubject } from '../events';\n\nexport interface JoopDeeplinkData {\n module: string;\n data?: string;\n timestamp: number;\n}\n\nconst STORAGE_KEY = '__joop_deeplink__';\n\nexport class JoopDeeplinkService {\n private _close$ = new JoopSubject<boolean>();\n private _incoming$ = new JoopSubject<JoopDeeplinkData>();\n private _module$ = new JoopBehaviorSubject<string>('');\n private _unlisten: (() => void) | null = null;\n\n getModule(): string { return this._module$.getValue(); }\n module$() { return this._module$.asObservable(); }\n close$() { return this._close$.asObservable(); }\n incoming$() { return this._incoming$.asObservable(); }\n\n /**\n * Set the deeplink module + data, broadcast via localStorage, then signal tab close.\n * Returns a Promise that resolves when the current tab is done.\n */\n setModule(module: string, data?: string): Promise<JoopDeeplinkData> {\n const payload: JoopDeeplinkData = { module, data, timestamp: Date.now() };\n this._module$.next(module);\n\n if (typeof localStorage !== 'undefined') {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(payload));\n // remove immediately so storage event fires on every call\n localStorage.removeItem(STORAGE_KEY);\n }\n\n this._close$.next(true);\n\n return new Promise(resolve => {\n const unsub = this._incoming$.subscribe(d => {\n unsub();\n resolve(d);\n });\n setTimeout(() => { unsub(); resolve(payload); }, 2000);\n });\n }\n\n /**\n * Start listening for deeplink data from another tab via storage events.\n * Returns a cleanup function.\n */\n startListening(storageKey = STORAGE_KEY): () => void {\n if (typeof window === 'undefined') return () => {};\n const handler = (event: StorageEvent) => {\n if (event.key !== storageKey || !event.newValue) return;\n try {\n const data: JoopDeeplinkData = JSON.parse(event.newValue);\n this._module$.next(data.module);\n this._incoming$.next(data);\n } catch { /* ignore */ }\n };\n window.addEventListener('storage', handler);\n this._unlisten = () => window.removeEventListener('storage', handler);\n return this._unlisten;\n }\n\n stopListening(): void {\n this._unlisten?.();\n this._unlisten = null;\n }\n\n /** Signal this tab should close (without deeplink) */\n requestClose(): void { this._close$.next(false); }\n\n /** Read deeplink payload written by another tab on this page load */\n readIncoming(storageKey = STORAGE_KEY): JoopDeeplinkData | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n const raw = localStorage.getItem(storageKey);\n return raw ? JSON.parse(raw) : null;\n } catch { return null; }\n }\n\n clearStored(storageKey = STORAGE_KEY): void {\n if (typeof localStorage !== 'undefined') localStorage.removeItem(storageKey);\n }\n}\n","// URL-pattern deeplink router — distinct from the cross-tab JoopDeeplinkService.\n// Handles incoming URLs with :param and *wildcard patterns.\n\nexport interface JoopRouteParams {\n params: Record<string, string>;\n query: Record<string, string>;\n hash: string;\n url: string;\n pattern: string;\n}\n\nexport type JoopRouteHandler = (match: JoopRouteParams) => void | Promise<void>;\n\ninterface RegisteredRoute {\n pattern: string;\n regex: RegExp;\n keys: string[];\n handler: JoopRouteHandler;\n priority: number;\n}\n\nfunction _compilePattern(pattern: string): { regex: RegExp; keys: string[] } {\n const keys: string[] = [];\n const escaped = pattern\n .replace(/\\//g, '\\\\/')\n .replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, (_, key) => { keys.push(key); return '([^/]+)'; })\n .replace(/\\*/g, '(.*)');\n return { regex: new RegExp(`^${escaped}$`), keys };\n}\n\nfunction _parseQuery(search: string): Record<string, string> {\n const params: Record<string, string> = {};\n if (!search) return params;\n new URLSearchParams(search.startsWith('?') ? search.slice(1) : search)\n .forEach((v, k) => { params[k] = v; });\n return params;\n}\n\nexport class JoopDeeplinkRouter {\n private _routes: RegisteredRoute[] = [];\n private _fallback: JoopRouteHandler | null = null;\n private _history: string[] = [];\n private _maxHistory = 50;\n\n /** Register a URL-pattern handler. Returns an unsubscribe function. */\n on(pattern: string, handler: JoopRouteHandler, priority = 0): () => void {\n const { regex, keys } = _compilePattern(pattern);\n const route: RegisteredRoute = { pattern, regex, keys, handler, priority };\n this._routes.push(route);\n this._routes.sort((a, b) => b.priority - a.priority);\n return () => { this._routes = this._routes.filter(r => r !== route); };\n }\n\n /** Register a fallback handler for unmatched URLs. */\n fallback(handler: JoopRouteHandler): void {\n this._fallback = handler;\n }\n\n /** Dispatch a URL, return true if a handler matched. */\n async dispatch(url: string): Promise<boolean> {\n this._history.push(url);\n if (this._history.length > this._maxHistory) this._history.shift();\n\n let path: string, search: string, hash: string;\n try {\n const parsed = new URL(url, 'http://x');\n path = parsed.pathname;\n search = parsed.search;\n hash = parsed.hash;\n } catch {\n path = url; search = ''; hash = '';\n }\n\n for (const route of this._routes) {\n const match = route.regex.exec(path);\n if (!match) continue;\n const params: Record<string, string> = {};\n route.keys.forEach((k, i) => { params[k] = decodeURIComponent(match[i + 1] ?? ''); });\n await route.handler({ params, query: _parseQuery(search), hash, url, pattern: route.pattern });\n return true;\n }\n\n if (this._fallback) {\n await this._fallback({ params: {}, query: _parseQuery(search), hash, url, pattern: '' });\n }\n return false;\n }\n\n /** Parse a URL into parts without dispatching. */\n parse(url: string): Omit<JoopRouteParams, 'pattern'> & { matchedPattern: string | null } {\n let path: string, search: string, hash: string;\n try {\n const p = new URL(url, 'http://x');\n path = p.pathname; search = p.search; hash = p.hash;\n } catch { path = url; search = ''; hash = ''; }\n\n for (const route of this._routes) {\n const match = route.regex.exec(path);\n if (!match) continue;\n const params: Record<string, string> = {};\n route.keys.forEach((k, i) => { params[k] = decodeURIComponent(match[i + 1] ?? ''); });\n return { params, query: _parseQuery(search), hash, url, matchedPattern: route.pattern };\n }\n return { params: {}, query: _parseQuery(search), hash, url, matchedPattern: null };\n }\n\n /** Build a URL from a pattern and param values. */\n buildUrl(pattern: string, params: Record<string, string> = {}, query: Record<string, string> = {}): string {\n let path = pattern;\n for (const [k, v] of Object.entries(params)) {\n path = path.replace(`:${k}`, encodeURIComponent(v));\n }\n const qs = new URLSearchParams(query).toString();\n return qs ? `${path}?${qs}` : path;\n }\n\n /** List all registered patterns. */\n routes(): string[] {\n return this._routes.map(r => r.pattern);\n }\n\n /** Navigation history (last N dispatched URLs). */\n history(): readonly string[] {\n return this._history;\n }\n\n /** Remove all registered handlers. */\n clear(): void {\n this._routes = [];\n this._fallback = null;\n }\n\n /** Dispatch the current window.location.href. */\n dispatchCurrent(): Promise<boolean> {\n if (typeof window === 'undefined') return Promise.resolve(false);\n return this.dispatch(window.location.href);\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() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/events/index.ts","../../src/deeplink/deeplink.service.ts","../../src/deeplink/deeplink-router.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 { JoopSubject, JoopBehaviorSubject } from '../events';\n\nexport interface JoopDeeplinkData {\n module: string;\n data?: string;\n timestamp: number;\n}\n\nconst STORAGE_KEY = '__joop_deeplink__';\n\nexport class JoopDeeplinkService {\n private _close$ = new JoopSubject<boolean>();\n private _incoming$ = new JoopSubject<JoopDeeplinkData>();\n private _module$ = new JoopBehaviorSubject<string>('');\n private _unlisten: (() => void) | null = null;\n\n getModule(): string { return this._module$.getValue(); }\n module$() { return this._module$.asObservable(); }\n close$() { return this._close$.asObservable(); }\n incoming$() { return this._incoming$.asObservable(); }\n\n /**\n * Set the deeplink module + data, broadcast via localStorage, then signal tab close.\n * Returns a Promise that resolves when the current tab is done.\n */\n setModule(module: string, data?: string): Promise<JoopDeeplinkData> {\n const payload: JoopDeeplinkData = { module, data, timestamp: Date.now() };\n this._module$.next(module);\n\n if (typeof localStorage !== 'undefined') {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(payload));\n // remove immediately so storage event fires on every call\n localStorage.removeItem(STORAGE_KEY);\n }\n\n this._close$.next(true);\n\n return new Promise(resolve => {\n const unsub = this._incoming$.subscribe(d => {\n unsub();\n resolve(d);\n });\n setTimeout(() => { unsub(); resolve(payload); }, 2000);\n });\n }\n\n /**\n * Start listening for deeplink data from another tab via storage events.\n * Returns a cleanup function.\n */\n startListening(storageKey = STORAGE_KEY): () => void {\n if (typeof window === 'undefined') return () => {};\n const handler = (event: StorageEvent) => {\n if (event.key !== storageKey || !event.newValue) return;\n try {\n const data: JoopDeeplinkData = JSON.parse(event.newValue);\n this._module$.next(data.module);\n this._incoming$.next(data);\n } catch { /* ignore */ }\n };\n window.addEventListener('storage', handler);\n this._unlisten = () => window.removeEventListener('storage', handler);\n return this._unlisten;\n }\n\n stopListening(): void {\n this._unlisten?.();\n this._unlisten = null;\n }\n\n /** Signal this tab should close (without deeplink) */\n requestClose(): void { this._close$.next(false); }\n\n /** Read deeplink payload written by another tab on this page load */\n readIncoming(storageKey = STORAGE_KEY): JoopDeeplinkData | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n const raw = localStorage.getItem(storageKey);\n return raw ? JSON.parse(raw) : null;\n } catch { return null; }\n }\n\n clearStored(storageKey = STORAGE_KEY): void {\n if (typeof localStorage !== 'undefined') localStorage.removeItem(storageKey);\n }\n}\n","// URL-pattern deeplink router — distinct from the cross-tab JoopDeeplinkService.\n// Handles incoming URLs with :param and *wildcard patterns.\n\nexport interface JoopRouteParams {\n params: Record<string, string>;\n query: Record<string, string>;\n hash: string;\n url: string;\n pattern: string;\n}\n\nexport type JoopRouteHandler = (match: JoopRouteParams) => void | Promise<void>;\n\ninterface RegisteredRoute {\n pattern: string;\n regex: RegExp;\n keys: string[];\n handler: JoopRouteHandler;\n priority: number;\n}\n\nfunction _compilePattern(pattern: string): { regex: RegExp; keys: string[] } {\n const keys: string[] = [];\n const escaped = pattern\n .replace(/\\//g, '\\\\/')\n .replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, (_, key) => { keys.push(key); return '([^/]+)'; })\n .replace(/\\*/g, '(.*)');\n return { regex: new RegExp(`^${escaped}$`), keys };\n}\n\nfunction _parseQuery(search: string): Record<string, string> {\n const params: Record<string, string> = {};\n if (!search) return params;\n new URLSearchParams(search.startsWith('?') ? search.slice(1) : search)\n .forEach((v, k) => { params[k] = v; });\n return params;\n}\n\nexport class JoopDeeplinkRouter {\n private _routes: RegisteredRoute[] = [];\n private _fallback: JoopRouteHandler | null = null;\n private _history: string[] = [];\n private _maxHistory = 50;\n\n /** Register a URL-pattern handler. Returns an unsubscribe function. */\n on(pattern: string, handler: JoopRouteHandler, priority = 0): () => void {\n const { regex, keys } = _compilePattern(pattern);\n const route: RegisteredRoute = { pattern, regex, keys, handler, priority };\n this._routes.push(route);\n this._routes.sort((a, b) => b.priority - a.priority);\n return () => { this._routes = this._routes.filter(r => r !== route); };\n }\n\n /** Register a fallback handler for unmatched URLs. */\n fallback(handler: JoopRouteHandler): void {\n this._fallback = handler;\n }\n\n /** Dispatch a URL, return true if a handler matched. */\n async dispatch(url: string): Promise<boolean> {\n this._history.push(url);\n if (this._history.length > this._maxHistory) this._history.shift();\n\n let path: string, search: string, hash: string;\n try {\n const parsed = new URL(url, 'http://x');\n path = parsed.pathname;\n search = parsed.search;\n hash = parsed.hash;\n } catch {\n path = url; search = ''; hash = '';\n }\n\n for (const route of this._routes) {\n const match = route.regex.exec(path);\n if (!match) continue;\n const params: Record<string, string> = {};\n route.keys.forEach((k, i) => { params[k] = decodeURIComponent(match[i + 1] ?? ''); });\n await route.handler({ params, query: _parseQuery(search), hash, url, pattern: route.pattern });\n return true;\n }\n\n if (this._fallback) {\n await this._fallback({ params: {}, query: _parseQuery(search), hash, url, pattern: '' });\n }\n return false;\n }\n\n /** Parse a URL into parts without dispatching. */\n parse(url: string): Omit<JoopRouteParams, 'pattern'> & { matchedPattern: string | null } {\n let path: string, search: string, hash: string;\n try {\n const p = new URL(url, 'http://x');\n path = p.pathname; search = p.search; hash = p.hash;\n } catch { path = url; search = ''; hash = ''; }\n\n for (const route of this._routes) {\n const match = route.regex.exec(path);\n if (!match) continue;\n const params: Record<string, string> = {};\n route.keys.forEach((k, i) => { params[k] = decodeURIComponent(match[i + 1] ?? ''); });\n return { params, query: _parseQuery(search), hash, url, matchedPattern: route.pattern };\n }\n return { params: {}, query: _parseQuery(search), hash, url, matchedPattern: null };\n }\n\n /** Build a URL from a pattern and param values. */\n buildUrl(pattern: string, params: Record<string, string> = {}, query: Record<string, string> = {}): string {\n let path = pattern;\n for (const [k, v] of Object.entries(params)) {\n path = path.replace(`:${k}`, encodeURIComponent(v));\n }\n const qs = new URLSearchParams(query).toString();\n return qs ? `${path}?${qs}` : path;\n }\n\n /** List all registered patterns. */\n routes(): string[] {\n return this._routes.map(r => r.pattern);\n }\n\n /** Navigation history (last N dispatched URLs). */\n history(): readonly string[] {\n return this._history;\n }\n\n /** Remove all registered handlers. */\n clear(): void {\n this._routes = [];\n this._fallback = null;\n }\n\n /** Dispatch the current window.location.href. */\n dispatchCurrent(): Promise<boolean> {\n if (typeof window === 'undefined') return Promise.resolve(false);\n return this.dispatch(window.location.href);\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/events/index.ts","../../src/deeplink/deeplink.service.ts","../../src/deeplink/deeplink-router.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 { JoopSubject, JoopBehaviorSubject } from '../events';\n\nexport interface JoopDeeplinkData {\n module: string;\n data?: string;\n timestamp: number;\n}\n\nconst STORAGE_KEY = '__joop_deeplink__';\n\nexport class JoopDeeplinkService {\n private _close$ = new JoopSubject<boolean>();\n private _incoming$ = new JoopSubject<JoopDeeplinkData>();\n private _module$ = new JoopBehaviorSubject<string>('');\n private _unlisten: (() => void) | null = null;\n\n getModule(): string { return this._module$.getValue(); }\n module$() { return this._module$.asObservable(); }\n close$() { return this._close$.asObservable(); }\n incoming$() { return this._incoming$.asObservable(); }\n\n /**\n * Set the deeplink module + data, broadcast via localStorage, then signal tab close.\n * Returns a Promise that resolves when the current tab is done.\n */\n setModule(module: string, data?: string): Promise<JoopDeeplinkData> {\n const payload: JoopDeeplinkData = { module, data, timestamp: Date.now() };\n this._module$.next(module);\n\n if (typeof localStorage !== 'undefined') {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(payload));\n // remove immediately so storage event fires on every call\n localStorage.removeItem(STORAGE_KEY);\n }\n\n this._close$.next(true);\n\n return new Promise(resolve => {\n const unsub = this._incoming$.subscribe(d => {\n unsub();\n resolve(d);\n });\n setTimeout(() => { unsub(); resolve(payload); }, 2000);\n });\n }\n\n /**\n * Start listening for deeplink data from another tab via storage events.\n * Returns a cleanup function.\n */\n startListening(storageKey = STORAGE_KEY): () => void {\n if (typeof window === 'undefined') return () => {};\n const handler = (event: StorageEvent) => {\n if (event.key !== storageKey || !event.newValue) return;\n try {\n const data: JoopDeeplinkData = JSON.parse(event.newValue);\n this._module$.next(data.module);\n this._incoming$.next(data);\n } catch { /* ignore */ }\n };\n window.addEventListener('storage', handler);\n this._unlisten = () => window.removeEventListener('storage', handler);\n return this._unlisten;\n }\n\n stopListening(): void {\n this._unlisten?.();\n this._unlisten = null;\n }\n\n /** Signal this tab should close (without deeplink) */\n requestClose(): void { this._close$.next(false); }\n\n /** Read deeplink payload written by another tab on this page load */\n readIncoming(storageKey = STORAGE_KEY): JoopDeeplinkData | null {\n if (typeof localStorage === 'undefined') return null;\n try {\n const raw = localStorage.getItem(storageKey);\n return raw ? JSON.parse(raw) : null;\n } catch { return null; }\n }\n\n clearStored(storageKey = STORAGE_KEY): void {\n if (typeof localStorage !== 'undefined') localStorage.removeItem(storageKey);\n }\n}\n","// URL-pattern deeplink router — distinct from the cross-tab JoopDeeplinkService.\n// Handles incoming URLs with :param and *wildcard patterns.\n\nexport interface JoopRouteParams {\n params: Record<string, string>;\n query: Record<string, string>;\n hash: string;\n url: string;\n pattern: string;\n}\n\nexport type JoopRouteHandler = (match: JoopRouteParams) => void | Promise<void>;\n\ninterface RegisteredRoute {\n pattern: string;\n regex: RegExp;\n keys: string[];\n handler: JoopRouteHandler;\n priority: number;\n}\n\nfunction _compilePattern(pattern: string): { regex: RegExp; keys: string[] } {\n const keys: string[] = [];\n const escaped = pattern\n .replace(/\\//g, '\\\\/')\n .replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, (_, key) => { keys.push(key); return '([^/]+)'; })\n .replace(/\\*/g, '(.*)');\n return { regex: new RegExp(`^${escaped}$`), keys };\n}\n\nfunction _parseQuery(search: string): Record<string, string> {\n const params: Record<string, string> = {};\n if (!search) return params;\n new URLSearchParams(search.startsWith('?') ? search.slice(1) : search)\n .forEach((v, k) => { params[k] = v; });\n return params;\n}\n\nexport class JoopDeeplinkRouter {\n private _routes: RegisteredRoute[] = [];\n private _fallback: JoopRouteHandler | null = null;\n private _history: string[] = [];\n private _maxHistory = 50;\n\n /** Register a URL-pattern handler. Returns an unsubscribe function. */\n on(pattern: string, handler: JoopRouteHandler, priority = 0): () => void {\n const { regex, keys } = _compilePattern(pattern);\n const route: RegisteredRoute = { pattern, regex, keys, handler, priority };\n this._routes.push(route);\n this._routes.sort((a, b) => b.priority - a.priority);\n return () => { this._routes = this._routes.filter(r => r !== route); };\n }\n\n /** Register a fallback handler for unmatched URLs. */\n fallback(handler: JoopRouteHandler): void {\n this._fallback = handler;\n }\n\n /** Dispatch a URL, return true if a handler matched. */\n async dispatch(url: string): Promise<boolean> {\n this._history.push(url);\n if (this._history.length > this._maxHistory) this._history.shift();\n\n let path: string, search: string, hash: string;\n try {\n const parsed = new URL(url, 'http://x');\n path = parsed.pathname;\n search = parsed.search;\n hash = parsed.hash;\n } catch {\n path = url; search = ''; hash = '';\n }\n\n for (const route of this._routes) {\n const match = route.regex.exec(path);\n if (!match) continue;\n const params: Record<string, string> = {};\n route.keys.forEach((k, i) => { params[k] = decodeURIComponent(match[i + 1] ?? ''); });\n await route.handler({ params, query: _parseQuery(search), hash, url, pattern: route.pattern });\n return true;\n }\n\n if (this._fallback) {\n await this._fallback({ params: {}, query: _parseQuery(search), hash, url, pattern: '' });\n }\n return false;\n }\n\n /** Parse a URL into parts without dispatching. */\n parse(url: string): Omit<JoopRouteParams, 'pattern'> & { matchedPattern: string | null } {\n let path: string, search: string, hash: string;\n try {\n const p = new URL(url, 'http://x');\n path = p.pathname; search = p.search; hash = p.hash;\n } catch { path = url; search = ''; hash = ''; }\n\n for (const route of this._routes) {\n const match = route.regex.exec(path);\n if (!match) continue;\n const params: Record<string, string> = {};\n route.keys.forEach((k, i) => { params[k] = decodeURIComponent(match[i + 1] ?? ''); });\n return { params, query: _parseQuery(search), hash, url, matchedPattern: route.pattern };\n }\n return { params: {}, query: _parseQuery(search), hash, url, matchedPattern: null };\n }\n\n /** Build a URL from a pattern and param values. */\n buildUrl(pattern: string, params: Record<string, string> = {}, query: Record<string, string> = {}): string {\n let path = pattern;\n for (const [k, v] of Object.entries(params)) {\n path = path.replace(`:${k}`, encodeURIComponent(v));\n }\n const qs = new URLSearchParams(query).toString();\n return qs ? `${path}?${qs}` : path;\n }\n\n /** List all registered patterns. */\n routes(): string[] {\n return this._routes.map(r => r.pattern);\n }\n\n /** Navigation history (last N dispatched URLs). */\n history(): readonly string[] {\n return this._history;\n }\n\n /** Remove all registered handlers. */\n clear(): void {\n this._routes = [];\n this._fallback = null;\n }\n\n /** Dispatch the current window.location.href. */\n dispatchCurrent(): Promise<boolean> {\n if (typeof window === 'undefined') return Promise.resolve(false);\n return this.dispatch(window.location.href);\n }\n}\n"]}
@@ -482,6 +482,9 @@ function _urlBase64ToUint8(base64String) {
482
482
  }
483
483
 
484
484
  // src/events/index.ts
485
+ var _onListenerError = (error) => {
486
+ console.error("[joopjs] a subject subscriber threw during emission:", error);
487
+ };
485
488
  var JoopSubject = class {
486
489
  _listeners = [];
487
490
  subscribe(listener) {
@@ -491,8 +494,13 @@ var JoopSubject = class {
491
494
  };
492
495
  }
493
496
  next(value) {
494
- for (const listener of this._listeners) {
495
- listener(value);
497
+ const listeners = this._listeners.slice();
498
+ for (const listener of listeners) {
499
+ try {
500
+ listener(value);
501
+ } catch (error) {
502
+ _onListenerError(error);
503
+ }
496
504
  }
497
505
  }
498
506
  asObservable() {
@@ -513,7 +521,11 @@ var JoopBehaviorSubject = class extends JoopSubject {
513
521
  super.next(value);
514
522
  }
515
523
  subscribe(listener) {
516
- listener(this._value);
524
+ try {
525
+ listener(this._value);
526
+ } catch (error) {
527
+ _onListenerError(error);
528
+ }
517
529
  return super.subscribe(listener);
518
530
  }
519
531
  asObservable() {