joopjs 2.0.6 → 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.
- package/.claude/skills/observables.md +28 -0
- package/.claude/skills/setup.md +14 -3
- package/.cursor/rules/joopjs.mdc +4 -5
- package/.github/copilot-instructions.md +3 -1
- package/.windsurf/rules/joopjs.md +4 -0
- package/CHANGELOG.md +31 -2
- package/README.md +19 -7
- package/ai-rules/AGENTS.md +21 -0
- package/ai-rules/GEMINI.md +17 -3
- package/dist/ai/index.js +15 -3
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/index.mjs +15 -3
- package/dist/ai/index.mjs.map +1 -1
- package/dist/analytics/index.js +10 -2
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/index.mjs +10 -2
- package/dist/analytics/index.mjs.map +1 -1
- package/dist/angular/index.d.mts +98 -27
- package/dist/angular/index.d.ts +98 -27
- package/dist/angular/index.js +44 -0
- package/dist/angular/index.js.map +1 -1
- package/dist/angular/index.mjs +39 -1
- package/dist/angular/index.mjs.map +1 -1
- package/dist/api/index.js +15 -3
- package/dist/api/index.js.map +1 -1
- package/dist/api/index.mjs +15 -3
- package/dist/api/index.mjs.map +1 -1
- package/dist/auth/index.js +15 -3
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/index.mjs +15 -3
- package/dist/auth/index.mjs.map +1 -1
- package/dist/banking/index.js +15 -3
- package/dist/banking/index.js.map +1 -1
- package/dist/banking/index.mjs +15 -3
- package/dist/banking/index.mjs.map +1 -1
- package/dist/cache/index.js +15 -3
- package/dist/cache/index.js.map +1 -1
- package/dist/cache/index.mjs +15 -3
- package/dist/cache/index.mjs.map +1 -1
- package/dist/{index-DFqEoX_l.d.ts → consent.service-CIHNtx9h.d.ts} +1 -2
- package/dist/{index-B_ksKpS1.d.mts → consent.service-DQ-JAEJx.d.mts} +1 -2
- package/dist/core/index.d.mts +34 -1
- package/dist/core/index.d.ts +34 -1
- package/dist/core/index.js +56 -5
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +54 -6
- package/dist/core/index.mjs.map +1 -1
- package/dist/deeplink/index.js +15 -3
- package/dist/deeplink/index.js.map +1 -1
- package/dist/deeplink/index.mjs +15 -3
- package/dist/deeplink/index.mjs.map +1 -1
- package/dist/device/index.js +15 -3
- package/dist/device/index.js.map +1 -1
- package/dist/device/index.mjs +15 -3
- package/dist/device/index.mjs.map +1 -1
- package/dist/forms/index.js +15 -3
- package/dist/forms/index.js.map +1 -1
- package/dist/forms/index.mjs +15 -3
- package/dist/forms/index.mjs.map +1 -1
- package/dist/i18n/index.js +15 -3
- package/dist/i18n/index.js.map +1 -1
- package/dist/i18n/index.mjs +15 -3
- package/dist/i18n/index.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +50 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +50 -8
- package/dist/index.mjs.map +1 -1
- package/dist/{joop-CA3DMeOO.d.ts → joop-Dim2yEKG.d.ts} +1 -1
- package/dist/{joop-Bx7Iwj5p.d.mts → joop-GkQw13f9.d.mts} +1 -1
- package/dist/native-bridge/index.js +10 -2
- package/dist/native-bridge/index.js.map +1 -1
- package/dist/native-bridge/index.mjs +10 -2
- package/dist/native-bridge/index.mjs.map +1 -1
- package/dist/network/index.js +15 -3
- package/dist/network/index.js.map +1 -1
- package/dist/network/index.mjs +15 -3
- package/dist/network/index.mjs.map +1 -1
- package/dist/observability/index.js +15 -3
- package/dist/observability/index.js.map +1 -1
- package/dist/observability/index.mjs +15 -3
- package/dist/observability/index.mjs.map +1 -1
- package/dist/pwa/index.js +15 -3
- package/dist/pwa/index.js.map +1 -1
- package/dist/pwa/index.mjs +15 -3
- package/dist/pwa/index.mjs.map +1 -1
- package/dist/react/index.d.mts +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +15 -3
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +15 -3
- package/dist/react/index.mjs.map +1 -1
- package/dist/router/index.js +15 -3
- package/dist/router/index.js.map +1 -1
- package/dist/router/index.mjs +15 -3
- package/dist/router/index.mjs.map +1 -1
- package/dist/security/index.js +15 -3
- package/dist/security/index.js.map +1 -1
- package/dist/security/index.mjs +15 -3
- package/dist/security/index.mjs.map +1 -1
- package/dist/session/index.js +15 -3
- package/dist/session/index.js.map +1 -1
- package/dist/session/index.mjs +15 -3
- package/dist/session/index.mjs.map +1 -1
- package/dist/state/index.js +15 -3
- package/dist/state/index.js.map +1 -1
- package/dist/state/index.mjs +15 -3
- package/dist/state/index.mjs.map +1 -1
- package/dist/storage/index.js +15 -3
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/index.mjs +15 -3
- package/dist/storage/index.mjs.map +1 -1
- package/dist/sync/index.js +15 -3
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/index.mjs +15 -3
- package/dist/sync/index.mjs.map +1 -1
- package/dist/theme/index.js +15 -3
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/index.mjs +15 -3
- package/dist/theme/index.mjs.map +1 -1
- package/dist/ui/index.js +15 -3
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/index.mjs +15 -3
- package/dist/ui/index.mjs.map +1 -1
- package/dist/utilities/index.js +46 -4
- package/dist/utilities/index.js.map +1 -1
- package/dist/utilities/index.mjs +46 -4
- package/dist/utilities/index.mjs.map +1 -1
- package/dist/vue/index.d.mts +2 -2
- package/dist/vue/index.d.ts +2 -2
- package/dist/vue/index.js +15 -3
- package/dist/vue/index.js.map +1 -1
- package/dist/vue/index.mjs +15 -3
- package/dist/vue/index.mjs.map +1 -1
- package/dist/workflow/index.js +15 -3
- package/dist/workflow/index.js.map +1 -1
- package/dist/workflow/index.mjs +15 -3
- package/dist/workflow/index.mjs.map +1 -1
- package/package.json +16 -2
package/dist/ai/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/events/index.ts","../../src/ai/ai-client.ts","../../src/ai/tool-registry.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 } from '../events';\n\nexport type JoopAiProvider = 'openai' | 'anthropic' | 'gemini' | 'ollama' | 'custom';\n\nexport interface JoopAiMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\nexport interface JoopAiConfig {\n provider: JoopAiProvider;\n apiKey?: string;\n baseUrl?: string;\n model: string;\n maxTokens?: number;\n temperature?: number;\n systemPrompt?: string;\n timeout?: number;\n}\n\nexport interface JoopAiStreamOptions {\n stream?: boolean;\n onChunk?: (token: string) => void;\n onComplete?: (full: string) => void;\n signal?: AbortSignal;\n maxTokens?: number;\n temperature?: number;\n}\n\nexport interface JoopAiUsage {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}\n\nconst PROVIDER_DEFAULTS: Record<JoopAiProvider, { baseUrl: string }> = {\n openai: { baseUrl: 'https://api.openai.com' },\n anthropic: { baseUrl: 'https://api.anthropic.com' },\n gemini: { baseUrl: 'https://generativelanguage.googleapis.com' },\n ollama: { baseUrl: 'http://localhost:11434' },\n custom: { baseUrl: '' },\n};\n\nexport class JoopAiClient {\n private _cfg: JoopAiConfig;\n private _usage$ = new JoopBehaviorSubject<JoopAiUsage>({ promptTokens: 0, completionTokens: 0, totalTokens: 0 });\n private _abort: AbortController | null = null;\n private _history: JoopAiMessage[] = [];\n\n constructor(config: JoopAiConfig) { this._cfg = config; }\n\n configure(patch: Partial<JoopAiConfig>): void { this._cfg = { ...this._cfg, ...patch }; }\n lastUsage(): JoopAiUsage { return this._usage$.getValue(); }\n usage$() { return this._usage$.asObservable(); }\n getHistory(): JoopAiMessage[] { return [...this._history]; }\n clearHistory(): void { this._history = []; }\n\n abort(): void { this._abort?.abort(); this._abort = null; }\n\n /** Approximate token count (4 chars ≈ 1 token) */\n estimateTokens(text: string): number { return Math.ceil(text.length / 4); }\n\n async complete(prompt: string, opts: JoopAiStreamOptions = {}): Promise<string> {\n return this.chat([{ role: 'user', content: prompt }], opts);\n }\n\n async chat(messages: JoopAiMessage[], opts: JoopAiStreamOptions = {}): Promise<string> {\n this._abort = new AbortController();\n const signal = opts.signal\n ? _combineSignals(opts.signal, this._abort.signal)\n : this._abort.signal;\n\n const allMessages: JoopAiMessage[] = [];\n if (this._cfg.systemPrompt) allMessages.push({ role: 'system', content: this._cfg.systemPrompt });\n allMessages.push(...this._history, ...messages);\n\n const result = opts.stream !== false\n ? await this._streamChat(allMessages, opts, signal)\n : await this._fetchChat(allMessages, opts, signal);\n\n // Append to history\n for (const m of messages) this._history.push(m);\n this._history.push({ role: 'assistant', content: result });\n\n opts.onComplete?.(result);\n return result;\n }\n\n private async _fetchChat(messages: JoopAiMessage[], opts: JoopAiStreamOptions, signal: AbortSignal): Promise<string> {\n const { url, headers, body } = this._buildRequest(messages, opts, false);\n const res = await fetch(url, { method: 'POST', headers, body: JSON.stringify(body), signal });\n if (!res.ok) throw new Error(`JoopAiClient: ${res.status} ${await res.text()}`);\n const json = await res.json();\n return this._extractContent(json);\n }\n\n private async _streamChat(messages: JoopAiMessage[], opts: JoopAiStreamOptions, signal: AbortSignal): Promise<string> {\n const { url, headers, body } = this._buildRequest(messages, opts, true);\n const res = await fetch(url, { method: 'POST', headers, body: JSON.stringify(body), signal });\n if (!res.ok) throw new Error(`JoopAiClient: ${res.status} ${await res.text()}`);\n\n const reader = res.body!.getReader();\n const decoder = new TextDecoder();\n let full = '';\n let buf = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buf += decoder.decode(value, { stream: true });\n const lines = buf.split('\\n');\n buf = lines.pop() ?? '';\n for (const line of lines) {\n const token = this._parseStreamLine(line.trim());\n if (token) { full += token; opts.onChunk?.(token); }\n }\n }\n return full;\n }\n\n private _buildRequest(messages: JoopAiMessage[], opts: JoopAiStreamOptions, stream: boolean): { url: string; headers: Record<string, string>; body: unknown } {\n const { provider, apiKey, model, maxTokens, temperature } = this._cfg;\n const baseUrl = this._cfg.baseUrl ?? PROVIDER_DEFAULTS[provider].baseUrl;\n const mt = opts.maxTokens ?? maxTokens ?? 1024;\n const temp = opts.temperature ?? temperature ?? 0.7;\n\n switch (provider) {\n case 'openai':\n case 'custom':\n return {\n url: `${baseUrl}/v1/chat/completions`,\n headers: { 'Content-Type': 'application/json', ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}) },\n body: { model, messages, stream, max_tokens: mt, temperature: temp },\n };\n case 'anthropic':\n return {\n url: `${baseUrl}/v1/messages`,\n headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey ?? '', 'anthropic-version': '2023-06-01' },\n body: {\n model, stream, max_tokens: mt, temperature: temp,\n system: messages.find(m => m.role === 'system')?.content,\n messages: messages.filter(m => m.role !== 'system'),\n },\n };\n case 'gemini': {\n const contents = messages.filter(m => m.role !== 'system').map(m => ({ role: m.role === 'assistant' ? 'model' : 'user', parts: [{ text: m.content }] }));\n const path = stream ? 'streamGenerateContent?alt=sse' : 'generateContent';\n return {\n url: `${baseUrl}/v1beta/models/${model}:${path}${apiKey ? `&key=${apiKey}` : ''}`,\n headers: { 'Content-Type': 'application/json' },\n body: { contents, generationConfig: { maxOutputTokens: mt, temperature: temp } },\n };\n }\n case 'ollama':\n return {\n url: `${baseUrl}/api/chat`,\n headers: { 'Content-Type': 'application/json' },\n body: { model, messages, stream, options: { num_predict: mt, temperature: temp } },\n };\n }\n }\n\n private _parseStreamLine(line: string): string {\n if (!line.startsWith('data: ') && !line.startsWith('{')) return '';\n const raw = line.startsWith('data: ') ? line.slice(6) : line;\n if (raw === '[DONE]') return '';\n try {\n const json = JSON.parse(raw);\n // OpenAI\n const oaChoice = json?.choices?.[0];\n if (oaChoice?.delta?.content) return oaChoice.delta.content;\n // Anthropic\n if (json?.type === 'content_block_delta') return json?.delta?.text ?? '';\n // Gemini\n const gmPart = json?.candidates?.[0]?.content?.parts?.[0];\n if (gmPart?.text) return gmPart.text;\n // Ollama\n if (json?.message?.content) return json.message.content;\n } catch {}\n return '';\n }\n\n private _extractContent(json: unknown): string {\n const j = json as Record<string, unknown>;\n // OpenAI\n const oa = (j?.choices as Array<{message:{content:string}}>)?.[0]?.message?.content;\n if (oa) return oa;\n // Anthropic\n const an = (j?.content as Array<{text:string}>)?.[0]?.text;\n if (an) return an;\n // Gemini\n const gm = ((j?.candidates as Array<{content:{parts:Array<{text:string}>}}>)?.[0]?.content?.parts)?.[0]?.text;\n if (gm) return gm;\n // Ollama\n const ol = (j?.message as {content:string})?.content;\n if (ol) return ol;\n return '';\n }\n}\n\nfunction _combineSignals(...signals: AbortSignal[]): AbortSignal {\n const ctrl = new AbortController();\n for (const s of signals) s.addEventListener('abort', () => ctrl.abort(), { once: true });\n return ctrl.signal;\n}\n","export interface JoopToolParameter {\n type: 'string' | 'number' | 'boolean' | 'object' | 'array';\n description?: string;\n enum?: unknown[];\n items?: JoopToolParameter;\n properties?: Record<string, JoopToolParameter>;\n required?: string[];\n}\n\nexport interface JoopToolDefinition {\n name: string;\n description: string;\n parameters: Record<string, JoopToolParameter>;\n required?: string[];\n handler: (args: Record<string, unknown>) => Promise<unknown>;\n}\n\nexport interface JoopToolCall {\n name: string;\n arguments: string | Record<string, unknown>;\n}\n\nexport interface JoopToolResult {\n name: string;\n result: unknown;\n error?: string;\n durationMs: number;\n}\n\nexport class JoopToolRegistry {\n private _tools = new Map<string, JoopToolDefinition>();\n\n register(tool: JoopToolDefinition): void {\n if (this._tools.has(tool.name)) throw new Error(`Tool '${tool.name}' already registered. Use update() to replace.`);\n this._tools.set(tool.name, tool);\n }\n\n update(tool: JoopToolDefinition): void { this._tools.set(tool.name, tool); }\n unregister(name: string): void { this._tools.delete(name); }\n has(name: string): boolean { return this._tools.has(name); }\n list(): string[] { return Array.from(this._tools.keys()); }\n get(name: string): JoopToolDefinition | undefined { return this._tools.get(name); }\n clear(): void { this._tools.clear(); }\n\n async dispatch(call: JoopToolCall): Promise<JoopToolResult> {\n const tool = this._tools.get(call.name);\n if (!tool) return { name: call.name, result: null, error: `Unknown tool: ${call.name}`, durationMs: 0 };\n\n const args = typeof call.arguments === 'string' ? JSON.parse(call.arguments) : call.arguments;\n const t0 = Date.now();\n try {\n const result = await tool.handler(args as Record<string, unknown>);\n return { name: call.name, result, durationMs: Date.now() - t0 };\n } catch (e) {\n return { name: call.name, result: null, error: String(e), durationMs: Date.now() - t0 };\n }\n }\n\n /** Dispatch multiple tool calls in parallel */\n async dispatchAll(calls: JoopToolCall[]): Promise<JoopToolResult[]> {\n return Promise.all(calls.map(c => this.dispatch(c)));\n }\n\n /** Format for OpenAI function-calling */\n toOpenAiFormat(): object[] {\n return Array.from(this._tools.values()).map(t => ({\n type: 'function',\n function: {\n name: t.name,\n description: t.description,\n parameters: {\n type: 'object',\n properties: t.parameters,\n required: t.required ?? [],\n },\n },\n }));\n }\n\n /** Format for Anthropic tool-use */\n toAnthropicFormat(): object[] {\n return Array.from(this._tools.values()).map(t => ({\n name: t.name,\n description: t.description,\n input_schema: {\n type: 'object',\n properties: t.parameters,\n required: t.required ?? [],\n },\n }));\n }\n\n /** Format for Google Gemini function declarations */\n toGeminiFormat(): object[] {\n return [{\n function_declarations: Array.from(this._tools.values()).map(t => ({\n name: t.name,\n description: t.description,\n parameters: { type: 'object', properties: t.parameters, required: t.required ?? [] },\n })),\n }];\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/events/index.ts","../../src/ai/ai-client.ts","../../src/ai/tool-registry.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 } from '../events';\n\nexport type JoopAiProvider = 'openai' | 'anthropic' | 'gemini' | 'ollama' | 'custom';\n\nexport interface JoopAiMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\nexport interface JoopAiConfig {\n provider: JoopAiProvider;\n apiKey?: string;\n baseUrl?: string;\n model: string;\n maxTokens?: number;\n temperature?: number;\n systemPrompt?: string;\n timeout?: number;\n}\n\nexport interface JoopAiStreamOptions {\n stream?: boolean;\n onChunk?: (token: string) => void;\n onComplete?: (full: string) => void;\n signal?: AbortSignal;\n maxTokens?: number;\n temperature?: number;\n}\n\nexport interface JoopAiUsage {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n}\n\nconst PROVIDER_DEFAULTS: Record<JoopAiProvider, { baseUrl: string }> = {\n openai: { baseUrl: 'https://api.openai.com' },\n anthropic: { baseUrl: 'https://api.anthropic.com' },\n gemini: { baseUrl: 'https://generativelanguage.googleapis.com' },\n ollama: { baseUrl: 'http://localhost:11434' },\n custom: { baseUrl: '' },\n};\n\nexport class JoopAiClient {\n private _cfg: JoopAiConfig;\n private _usage$ = new JoopBehaviorSubject<JoopAiUsage>({ promptTokens: 0, completionTokens: 0, totalTokens: 0 });\n private _abort: AbortController | null = null;\n private _history: JoopAiMessage[] = [];\n\n constructor(config: JoopAiConfig) { this._cfg = config; }\n\n configure(patch: Partial<JoopAiConfig>): void { this._cfg = { ...this._cfg, ...patch }; }\n lastUsage(): JoopAiUsage { return this._usage$.getValue(); }\n usage$() { return this._usage$.asObservable(); }\n getHistory(): JoopAiMessage[] { return [...this._history]; }\n clearHistory(): void { this._history = []; }\n\n abort(): void { this._abort?.abort(); this._abort = null; }\n\n /** Approximate token count (4 chars ≈ 1 token) */\n estimateTokens(text: string): number { return Math.ceil(text.length / 4); }\n\n async complete(prompt: string, opts: JoopAiStreamOptions = {}): Promise<string> {\n return this.chat([{ role: 'user', content: prompt }], opts);\n }\n\n async chat(messages: JoopAiMessage[], opts: JoopAiStreamOptions = {}): Promise<string> {\n this._abort = new AbortController();\n const signal = opts.signal\n ? _combineSignals(opts.signal, this._abort.signal)\n : this._abort.signal;\n\n const allMessages: JoopAiMessage[] = [];\n if (this._cfg.systemPrompt) allMessages.push({ role: 'system', content: this._cfg.systemPrompt });\n allMessages.push(...this._history, ...messages);\n\n const result = opts.stream !== false\n ? await this._streamChat(allMessages, opts, signal)\n : await this._fetchChat(allMessages, opts, signal);\n\n // Append to history\n for (const m of messages) this._history.push(m);\n this._history.push({ role: 'assistant', content: result });\n\n opts.onComplete?.(result);\n return result;\n }\n\n private async _fetchChat(messages: JoopAiMessage[], opts: JoopAiStreamOptions, signal: AbortSignal): Promise<string> {\n const { url, headers, body } = this._buildRequest(messages, opts, false);\n const res = await fetch(url, { method: 'POST', headers, body: JSON.stringify(body), signal });\n if (!res.ok) throw new Error(`JoopAiClient: ${res.status} ${await res.text()}`);\n const json = await res.json();\n return this._extractContent(json);\n }\n\n private async _streamChat(messages: JoopAiMessage[], opts: JoopAiStreamOptions, signal: AbortSignal): Promise<string> {\n const { url, headers, body } = this._buildRequest(messages, opts, true);\n const res = await fetch(url, { method: 'POST', headers, body: JSON.stringify(body), signal });\n if (!res.ok) throw new Error(`JoopAiClient: ${res.status} ${await res.text()}`);\n\n const reader = res.body!.getReader();\n const decoder = new TextDecoder();\n let full = '';\n let buf = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buf += decoder.decode(value, { stream: true });\n const lines = buf.split('\\n');\n buf = lines.pop() ?? '';\n for (const line of lines) {\n const token = this._parseStreamLine(line.trim());\n if (token) { full += token; opts.onChunk?.(token); }\n }\n }\n return full;\n }\n\n private _buildRequest(messages: JoopAiMessage[], opts: JoopAiStreamOptions, stream: boolean): { url: string; headers: Record<string, string>; body: unknown } {\n const { provider, apiKey, model, maxTokens, temperature } = this._cfg;\n const baseUrl = this._cfg.baseUrl ?? PROVIDER_DEFAULTS[provider].baseUrl;\n const mt = opts.maxTokens ?? maxTokens ?? 1024;\n const temp = opts.temperature ?? temperature ?? 0.7;\n\n switch (provider) {\n case 'openai':\n case 'custom':\n return {\n url: `${baseUrl}/v1/chat/completions`,\n headers: { 'Content-Type': 'application/json', ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}) },\n body: { model, messages, stream, max_tokens: mt, temperature: temp },\n };\n case 'anthropic':\n return {\n url: `${baseUrl}/v1/messages`,\n headers: { 'Content-Type': 'application/json', 'x-api-key': apiKey ?? '', 'anthropic-version': '2023-06-01' },\n body: {\n model, stream, max_tokens: mt, temperature: temp,\n system: messages.find(m => m.role === 'system')?.content,\n messages: messages.filter(m => m.role !== 'system'),\n },\n };\n case 'gemini': {\n const contents = messages.filter(m => m.role !== 'system').map(m => ({ role: m.role === 'assistant' ? 'model' : 'user', parts: [{ text: m.content }] }));\n const path = stream ? 'streamGenerateContent?alt=sse' : 'generateContent';\n return {\n url: `${baseUrl}/v1beta/models/${model}:${path}${apiKey ? `&key=${apiKey}` : ''}`,\n headers: { 'Content-Type': 'application/json' },\n body: { contents, generationConfig: { maxOutputTokens: mt, temperature: temp } },\n };\n }\n case 'ollama':\n return {\n url: `${baseUrl}/api/chat`,\n headers: { 'Content-Type': 'application/json' },\n body: { model, messages, stream, options: { num_predict: mt, temperature: temp } },\n };\n }\n }\n\n private _parseStreamLine(line: string): string {\n if (!line.startsWith('data: ') && !line.startsWith('{')) return '';\n const raw = line.startsWith('data: ') ? line.slice(6) : line;\n if (raw === '[DONE]') return '';\n try {\n const json = JSON.parse(raw);\n // OpenAI\n const oaChoice = json?.choices?.[0];\n if (oaChoice?.delta?.content) return oaChoice.delta.content;\n // Anthropic\n if (json?.type === 'content_block_delta') return json?.delta?.text ?? '';\n // Gemini\n const gmPart = json?.candidates?.[0]?.content?.parts?.[0];\n if (gmPart?.text) return gmPart.text;\n // Ollama\n if (json?.message?.content) return json.message.content;\n } catch {}\n return '';\n }\n\n private _extractContent(json: unknown): string {\n const j = json as Record<string, unknown>;\n // OpenAI\n const oa = (j?.choices as Array<{message:{content:string}}>)?.[0]?.message?.content;\n if (oa) return oa;\n // Anthropic\n const an = (j?.content as Array<{text:string}>)?.[0]?.text;\n if (an) return an;\n // Gemini\n const gm = ((j?.candidates as Array<{content:{parts:Array<{text:string}>}}>)?.[0]?.content?.parts)?.[0]?.text;\n if (gm) return gm;\n // Ollama\n const ol = (j?.message as {content:string})?.content;\n if (ol) return ol;\n return '';\n }\n}\n\nfunction _combineSignals(...signals: AbortSignal[]): AbortSignal {\n const ctrl = new AbortController();\n for (const s of signals) s.addEventListener('abort', () => ctrl.abort(), { once: true });\n return ctrl.signal;\n}\n","export interface JoopToolParameter {\n type: 'string' | 'number' | 'boolean' | 'object' | 'array';\n description?: string;\n enum?: unknown[];\n items?: JoopToolParameter;\n properties?: Record<string, JoopToolParameter>;\n required?: string[];\n}\n\nexport interface JoopToolDefinition {\n name: string;\n description: string;\n parameters: Record<string, JoopToolParameter>;\n required?: string[];\n handler: (args: Record<string, unknown>) => Promise<unknown>;\n}\n\nexport interface JoopToolCall {\n name: string;\n arguments: string | Record<string, unknown>;\n}\n\nexport interface JoopToolResult {\n name: string;\n result: unknown;\n error?: string;\n durationMs: number;\n}\n\nexport class JoopToolRegistry {\n private _tools = new Map<string, JoopToolDefinition>();\n\n register(tool: JoopToolDefinition): void {\n if (this._tools.has(tool.name)) throw new Error(`Tool '${tool.name}' already registered. Use update() to replace.`);\n this._tools.set(tool.name, tool);\n }\n\n update(tool: JoopToolDefinition): void { this._tools.set(tool.name, tool); }\n unregister(name: string): void { this._tools.delete(name); }\n has(name: string): boolean { return this._tools.has(name); }\n list(): string[] { return Array.from(this._tools.keys()); }\n get(name: string): JoopToolDefinition | undefined { return this._tools.get(name); }\n clear(): void { this._tools.clear(); }\n\n async dispatch(call: JoopToolCall): Promise<JoopToolResult> {\n const tool = this._tools.get(call.name);\n if (!tool) return { name: call.name, result: null, error: `Unknown tool: ${call.name}`, durationMs: 0 };\n\n const args = typeof call.arguments === 'string' ? JSON.parse(call.arguments) : call.arguments;\n const t0 = Date.now();\n try {\n const result = await tool.handler(args as Record<string, unknown>);\n return { name: call.name, result, durationMs: Date.now() - t0 };\n } catch (e) {\n return { name: call.name, result: null, error: String(e), durationMs: Date.now() - t0 };\n }\n }\n\n /** Dispatch multiple tool calls in parallel */\n async dispatchAll(calls: JoopToolCall[]): Promise<JoopToolResult[]> {\n return Promise.all(calls.map(c => this.dispatch(c)));\n }\n\n /** Format for OpenAI function-calling */\n toOpenAiFormat(): object[] {\n return Array.from(this._tools.values()).map(t => ({\n type: 'function',\n function: {\n name: t.name,\n description: t.description,\n parameters: {\n type: 'object',\n properties: t.parameters,\n required: t.required ?? [],\n },\n },\n }));\n }\n\n /** Format for Anthropic tool-use */\n toAnthropicFormat(): object[] {\n return Array.from(this._tools.values()).map(t => ({\n name: t.name,\n description: t.description,\n input_schema: {\n type: 'object',\n properties: t.parameters,\n required: t.required ?? [],\n },\n }));\n }\n\n /** Format for Google Gemini function declarations */\n toGeminiFormat(): object[] {\n return [{\n function_declarations: Array.from(this._tools.values()).map(t => ({\n name: t.name,\n description: t.description,\n parameters: { type: 'object', properties: t.parameters, required: t.required ?? [] },\n })),\n }];\n }\n}\n"]}
|
package/dist/analytics/index.js
CHANGED
|
@@ -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
|
-
|
|
14
|
-
|
|
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() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/events/index.ts","../../src/analytics/analytics.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 { JoopSubject } from '../events';\n\nexport interface JoopAnalyticsEvent {\n name: string;\n properties?: Record<string, unknown>;\n timestamp: number;\n sessionId?: string;\n userId?: string;\n}\n\nexport interface JoopAnalyticsAdapter {\n name: string;\n track?(event: JoopAnalyticsEvent): void;\n page?(name: string, properties?: Record<string, unknown>): void;\n identify?(userId: string, traits?: Record<string, unknown>): void;\n}\n\nexport class JoopAnalyticsService {\n private _adapters: JoopAnalyticsAdapter[] = [];\n private _context: Record<string, unknown> = {};\n private _userId = '';\n private _sessionId = '';\n private _event$ = new JoopSubject<JoopAnalyticsEvent>();\n private _queue: JoopAnalyticsEvent[] = [];\n private _enabled = true;\n\n addAdapter(adapter: JoopAnalyticsAdapter): void {\n if (!this._adapters.find(a => a.name === adapter.name)) {\n this._adapters.push(adapter);\n // drain queued events to new adapter\n for (const ev of this._queue) adapter.track?.(ev);\n }\n }\n\n removeAdapter(name: string): void {\n this._adapters = this._adapters.filter(a => a.name !== name);\n }\n\n enable(): void { this._enabled = true; }\n disable(): void { this._enabled = false; }\n\n setContext(ctx: Record<string, unknown>): void {\n this._context = { ...this._context, ...ctx };\n }\n\n setUser(userId: string, traits?: Record<string, unknown>): void {\n this._userId = userId;\n this._adapters.forEach(a => a.identify?.(userId, traits));\n }\n\n setSession(sessionId: string): void { this._sessionId = sessionId; }\n\n track(name: string, properties?: Record<string, unknown>): void {\n if (!this._enabled) return;\n const event: JoopAnalyticsEvent = {\n name,\n properties: { ...this._context, ...properties },\n timestamp: Date.now(),\n userId: this._userId || undefined,\n sessionId: this._sessionId || undefined,\n };\n this._event$.next(event);\n if (this._adapters.length === 0) { this._queue.push(event); return; }\n this._adapters.forEach(a => { try { a.track?.(event); } catch { /* isolate adapter errors */ } });\n }\n\n page(name: string, properties?: Record<string, unknown>): void {\n if (!this._enabled) return;\n const merged = { ...this._context, ...properties };\n this._adapters.forEach(a => { try { a.page?.(name, merged); } catch { /* */ } });\n this.track(`page:${name}`, merged);\n }\n\n identify(userId: string, traits?: Record<string, unknown>): void {\n this.setUser(userId, traits);\n }\n\n /** Subscribe to all tracked events (useful for debugging) */\n events$() { return this._event$.asObservable(); }\n\n /** Flush the pre-adapter queue (e.g. after lazy-loading analytics) */\n flush(): void {\n for (const ev of this._queue) {\n this._adapters.forEach(a => { try { a.track?.(ev); } catch { /* */ } });\n }\n this._queue = [];\n }\n\n getQueueSize(): number { return this._queue.length; }\n}\n\n// ── Built-in console adapter (for development) ────────────────────────────\nexport const consoleAnalyticsAdapter: JoopAnalyticsAdapter = {\n name: 'console',\n track: (e) => console.log(`[analytics:track] ${e.name}`, e.properties),\n page: (name) => console.log(`[analytics:page] ${name}`),\n identify: (id) => console.log(`[analytics:identify] ${id}`),\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/events/index.ts","../../src/analytics/analytics.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 { JoopSubject } from '../events';\n\nexport interface JoopAnalyticsEvent {\n name: string;\n properties?: Record<string, unknown>;\n timestamp: number;\n sessionId?: string;\n userId?: string;\n}\n\nexport interface JoopAnalyticsAdapter {\n name: string;\n track?(event: JoopAnalyticsEvent): void;\n page?(name: string, properties?: Record<string, unknown>): void;\n identify?(userId: string, traits?: Record<string, unknown>): void;\n}\n\nexport class JoopAnalyticsService {\n private _adapters: JoopAnalyticsAdapter[] = [];\n private _context: Record<string, unknown> = {};\n private _userId = '';\n private _sessionId = '';\n private _event$ = new JoopSubject<JoopAnalyticsEvent>();\n private _queue: JoopAnalyticsEvent[] = [];\n private _enabled = true;\n\n addAdapter(adapter: JoopAnalyticsAdapter): void {\n if (!this._adapters.find(a => a.name === adapter.name)) {\n this._adapters.push(adapter);\n // drain queued events to new adapter\n for (const ev of this._queue) adapter.track?.(ev);\n }\n }\n\n removeAdapter(name: string): void {\n this._adapters = this._adapters.filter(a => a.name !== name);\n }\n\n enable(): void { this._enabled = true; }\n disable(): void { this._enabled = false; }\n\n setContext(ctx: Record<string, unknown>): void {\n this._context = { ...this._context, ...ctx };\n }\n\n setUser(userId: string, traits?: Record<string, unknown>): void {\n this._userId = userId;\n this._adapters.forEach(a => a.identify?.(userId, traits));\n }\n\n setSession(sessionId: string): void { this._sessionId = sessionId; }\n\n track(name: string, properties?: Record<string, unknown>): void {\n if (!this._enabled) return;\n const event: JoopAnalyticsEvent = {\n name,\n properties: { ...this._context, ...properties },\n timestamp: Date.now(),\n userId: this._userId || undefined,\n sessionId: this._sessionId || undefined,\n };\n this._event$.next(event);\n if (this._adapters.length === 0) { this._queue.push(event); return; }\n this._adapters.forEach(a => { try { a.track?.(event); } catch { /* isolate adapter errors */ } });\n }\n\n page(name: string, properties?: Record<string, unknown>): void {\n if (!this._enabled) return;\n const merged = { ...this._context, ...properties };\n this._adapters.forEach(a => { try { a.page?.(name, merged); } catch { /* */ } });\n this.track(`page:${name}`, merged);\n }\n\n identify(userId: string, traits?: Record<string, unknown>): void {\n this.setUser(userId, traits);\n }\n\n /** Subscribe to all tracked events (useful for debugging) */\n events$() { return this._event$.asObservable(); }\n\n /** Flush the pre-adapter queue (e.g. after lazy-loading analytics) */\n flush(): void {\n for (const ev of this._queue) {\n this._adapters.forEach(a => { try { a.track?.(ev); } catch { /* */ } });\n }\n this._queue = [];\n }\n\n getQueueSize(): number { return this._queue.length; }\n}\n\n// ── Built-in console adapter (for development) ────────────────────────────\nexport const consoleAnalyticsAdapter: JoopAnalyticsAdapter = {\n name: 'console',\n track: (e) => console.log(`[analytics:track] ${e.name}`, e.properties),\n page: (name) => console.log(`[analytics:page] ${name}`),\n identify: (id) => console.log(`[analytics:identify] ${id}`),\n};\n"]}
|
package/dist/analytics/index.mjs
CHANGED
|
@@ -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
|
-
|
|
12
|
-
|
|
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() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/events/index.ts","../../src/analytics/analytics.service.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 } from '../events';\n\nexport interface JoopAnalyticsEvent {\n name: string;\n properties?: Record<string, unknown>;\n timestamp: number;\n sessionId?: string;\n userId?: string;\n}\n\nexport interface JoopAnalyticsAdapter {\n name: string;\n track?(event: JoopAnalyticsEvent): void;\n page?(name: string, properties?: Record<string, unknown>): void;\n identify?(userId: string, traits?: Record<string, unknown>): void;\n}\n\nexport class JoopAnalyticsService {\n private _adapters: JoopAnalyticsAdapter[] = [];\n private _context: Record<string, unknown> = {};\n private _userId = '';\n private _sessionId = '';\n private _event$ = new JoopSubject<JoopAnalyticsEvent>();\n private _queue: JoopAnalyticsEvent[] = [];\n private _enabled = true;\n\n addAdapter(adapter: JoopAnalyticsAdapter): void {\n if (!this._adapters.find(a => a.name === adapter.name)) {\n this._adapters.push(adapter);\n // drain queued events to new adapter\n for (const ev of this._queue) adapter.track?.(ev);\n }\n }\n\n removeAdapter(name: string): void {\n this._adapters = this._adapters.filter(a => a.name !== name);\n }\n\n enable(): void { this._enabled = true; }\n disable(): void { this._enabled = false; }\n\n setContext(ctx: Record<string, unknown>): void {\n this._context = { ...this._context, ...ctx };\n }\n\n setUser(userId: string, traits?: Record<string, unknown>): void {\n this._userId = userId;\n this._adapters.forEach(a => a.identify?.(userId, traits));\n }\n\n setSession(sessionId: string): void { this._sessionId = sessionId; }\n\n track(name: string, properties?: Record<string, unknown>): void {\n if (!this._enabled) return;\n const event: JoopAnalyticsEvent = {\n name,\n properties: { ...this._context, ...properties },\n timestamp: Date.now(),\n userId: this._userId || undefined,\n sessionId: this._sessionId || undefined,\n };\n this._event$.next(event);\n if (this._adapters.length === 0) { this._queue.push(event); return; }\n this._adapters.forEach(a => { try { a.track?.(event); } catch { /* isolate adapter errors */ } });\n }\n\n page(name: string, properties?: Record<string, unknown>): void {\n if (!this._enabled) return;\n const merged = { ...this._context, ...properties };\n this._adapters.forEach(a => { try { a.page?.(name, merged); } catch { /* */ } });\n this.track(`page:${name}`, merged);\n }\n\n identify(userId: string, traits?: Record<string, unknown>): void {\n this.setUser(userId, traits);\n }\n\n /** Subscribe to all tracked events (useful for debugging) */\n events$() { return this._event$.asObservable(); }\n\n /** Flush the pre-adapter queue (e.g. after lazy-loading analytics) */\n flush(): void {\n for (const ev of this._queue) {\n this._adapters.forEach(a => { try { a.track?.(ev); } catch { /* */ } });\n }\n this._queue = [];\n }\n\n getQueueSize(): number { return this._queue.length; }\n}\n\n// ── Built-in console adapter (for development) ────────────────────────────\nexport const consoleAnalyticsAdapter: JoopAnalyticsAdapter = {\n name: 'console',\n track: (e) => console.log(`[analytics:track] ${e.name}`, e.properties),\n page: (name) => console.log(`[analytics:page] ${name}`),\n identify: (id) => console.log(`[analytics:identify] ${id}`),\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/events/index.ts","../../src/analytics/analytics.service.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 } from '../events';\n\nexport interface JoopAnalyticsEvent {\n name: string;\n properties?: Record<string, unknown>;\n timestamp: number;\n sessionId?: string;\n userId?: string;\n}\n\nexport interface JoopAnalyticsAdapter {\n name: string;\n track?(event: JoopAnalyticsEvent): void;\n page?(name: string, properties?: Record<string, unknown>): void;\n identify?(userId: string, traits?: Record<string, unknown>): void;\n}\n\nexport class JoopAnalyticsService {\n private _adapters: JoopAnalyticsAdapter[] = [];\n private _context: Record<string, unknown> = {};\n private _userId = '';\n private _sessionId = '';\n private _event$ = new JoopSubject<JoopAnalyticsEvent>();\n private _queue: JoopAnalyticsEvent[] = [];\n private _enabled = true;\n\n addAdapter(adapter: JoopAnalyticsAdapter): void {\n if (!this._adapters.find(a => a.name === adapter.name)) {\n this._adapters.push(adapter);\n // drain queued events to new adapter\n for (const ev of this._queue) adapter.track?.(ev);\n }\n }\n\n removeAdapter(name: string): void {\n this._adapters = this._adapters.filter(a => a.name !== name);\n }\n\n enable(): void { this._enabled = true; }\n disable(): void { this._enabled = false; }\n\n setContext(ctx: Record<string, unknown>): void {\n this._context = { ...this._context, ...ctx };\n }\n\n setUser(userId: string, traits?: Record<string, unknown>): void {\n this._userId = userId;\n this._adapters.forEach(a => a.identify?.(userId, traits));\n }\n\n setSession(sessionId: string): void { this._sessionId = sessionId; }\n\n track(name: string, properties?: Record<string, unknown>): void {\n if (!this._enabled) return;\n const event: JoopAnalyticsEvent = {\n name,\n properties: { ...this._context, ...properties },\n timestamp: Date.now(),\n userId: this._userId || undefined,\n sessionId: this._sessionId || undefined,\n };\n this._event$.next(event);\n if (this._adapters.length === 0) { this._queue.push(event); return; }\n this._adapters.forEach(a => { try { a.track?.(event); } catch { /* isolate adapter errors */ } });\n }\n\n page(name: string, properties?: Record<string, unknown>): void {\n if (!this._enabled) return;\n const merged = { ...this._context, ...properties };\n this._adapters.forEach(a => { try { a.page?.(name, merged); } catch { /* */ } });\n this.track(`page:${name}`, merged);\n }\n\n identify(userId: string, traits?: Record<string, unknown>): void {\n this.setUser(userId, traits);\n }\n\n /** Subscribe to all tracked events (useful for debugging) */\n events$() { return this._event$.asObservable(); }\n\n /** Flush the pre-adapter queue (e.g. after lazy-loading analytics) */\n flush(): void {\n for (const ev of this._queue) {\n this._adapters.forEach(a => { try { a.track?.(ev); } catch { /* */ } });\n }\n this._queue = [];\n }\n\n getQueueSize(): number { return this._queue.length; }\n}\n\n// ── Built-in console adapter (for development) ────────────────────────────\nexport const consoleAnalyticsAdapter: JoopAnalyticsAdapter = {\n name: 'console',\n track: (e) => console.log(`[analytics:track] ${e.name}`, e.properties),\n page: (name) => console.log(`[analytics:page] ${name}`),\n identify: (id) => console.log(`[analytics:identify] ${id}`),\n};\n"]}
|
package/dist/angular/index.d.mts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as _angular_router from '@angular/router';
|
|
2
|
+
import { InjectionToken, Injector, DestroyRef, Signal, Provider } from '@angular/core';
|
|
3
|
+
import { HttpInterceptorFn } from '@angular/common/http';
|
|
4
|
+
import { J as JoopInstance } from '../joop-GkQw13f9.mjs';
|
|
2
5
|
import { J as JoopObservable } from '../index-Dz0gOur2.mjs';
|
|
3
6
|
import '../config.service-Cz4QQLlf.mjs';
|
|
4
7
|
import '../config.models-Cqg04fAQ.mjs';
|
|
5
|
-
import '../
|
|
8
|
+
import '../consent.service-DQ-JAEJx.mjs';
|
|
6
9
|
import '../data-storage.service-LvhGRCmw.mjs';
|
|
7
10
|
import '../index-CqDKWTUP.mjs';
|
|
8
11
|
import '../auth.service-DNVB-L4U.mjs';
|
|
@@ -40,50 +43,48 @@ import '../state/index.mjs';
|
|
|
40
43
|
import '../sync-engine-DZqyKHkK.mjs';
|
|
41
44
|
import '../workflow/index.mjs';
|
|
42
45
|
|
|
43
|
-
/**
|
|
44
|
-
* joopjs/angular — Angular integration
|
|
45
|
-
*
|
|
46
|
-
* @angular/core 17+ is a required peer dependency.
|
|
47
|
-
*
|
|
48
|
-
* Standalone (recommended):
|
|
49
|
-
* bootstrapApplication(AppComponent, {
|
|
50
|
-
* providers: [provideJoop(joopInstance)]
|
|
51
|
-
* });
|
|
52
|
-
*
|
|
53
|
-
* NgModule (legacy):
|
|
54
|
-
* @NgModule({ imports: [JoopModule.forRoot(joopInstance)] })
|
|
55
|
-
*
|
|
56
|
-
* Inject anywhere:
|
|
57
|
-
* constructor(@Inject(JOOP) private joop: JoopInstance) {}
|
|
58
|
-
*
|
|
59
|
-
* RxJS bridge:
|
|
60
|
-
* readonly theme$ = fromJoop(this.joop.theme.active$());
|
|
61
|
-
*/
|
|
62
|
-
|
|
63
46
|
/**
|
|
64
47
|
* InjectionToken for the JoopInstance.
|
|
65
48
|
* Angular's DI accepts any object as a token — use this with @Inject(JOOP).
|
|
66
49
|
*
|
|
67
|
-
* Example with @angular/core InjectionToken (recommended):
|
|
68
|
-
* import { InjectionToken } from '@angular/core';
|
|
69
|
-
* const JOOP = new InjectionToken<JoopInstance>('JoopInstance');
|
|
70
|
-
*
|
|
71
50
|
* The string form below works for both class-based and object-literal tokens.
|
|
51
|
+
*
|
|
52
|
+
* @deprecated Use the typed {@link JOOP_INSTANCE} token with `inject(JOOP_INSTANCE)`
|
|
53
|
+
* (or {@link injectJoop}) instead — it gives full type inference. The string tokens
|
|
54
|
+
* remain functional but will be removed in a future major.
|
|
72
55
|
*/
|
|
73
56
|
declare const JOOP: "JOOP_INSTANCE";
|
|
57
|
+
/**
|
|
58
|
+
* Per-service string tokens.
|
|
59
|
+
* @deprecated Inject {@link JOOP_INSTANCE} (or call {@link injectJoop}) and read the
|
|
60
|
+
* service off it (e.g. `injectJoop().auth`). Removed in a future major.
|
|
61
|
+
*/
|
|
74
62
|
declare const JOOP_AUTH: "JOOP_AUTH";
|
|
63
|
+
/** @deprecated Inject {@link JOOP_INSTANCE} and read `.theme`. */
|
|
75
64
|
declare const JOOP_THEME: "JOOP_THEME";
|
|
65
|
+
/** @deprecated Inject {@link JOOP_INSTANCE} and read `.i18n`. */
|
|
76
66
|
declare const JOOP_I18N: "JOOP_I18N";
|
|
67
|
+
/** @deprecated Inject {@link JOOP_INSTANCE} and read `.http`. */
|
|
77
68
|
declare const JOOP_HTTP: "JOOP_HTTP";
|
|
69
|
+
/** @deprecated Inject {@link JOOP_INSTANCE} and read `.loader`. */
|
|
78
70
|
declare const JOOP_LOADER: "JOOP_LOADER";
|
|
71
|
+
/** @deprecated Inject {@link JOOP_INSTANCE} and read `.alert`. */
|
|
79
72
|
declare const JOOP_ALERT: "JOOP_ALERT";
|
|
73
|
+
/** @deprecated Inject {@link JOOP_INSTANCE} and read `.router`. */
|
|
80
74
|
declare const JOOP_ROUTER: "JOOP_ROUTER";
|
|
75
|
+
/** @deprecated Inject {@link JOOP_INSTANCE} and read `.analytics`. */
|
|
81
76
|
declare const JOOP_ANALYTICS: "JOOP_ANALYTICS";
|
|
77
|
+
/** @deprecated Inject {@link JOOP_INSTANCE} and read `.featureFlags`. */
|
|
82
78
|
declare const JOOP_FEATURE_FLAGS: "JOOP_FEATURE_FLAGS";
|
|
79
|
+
/** @deprecated Inject {@link JOOP_INSTANCE} and read `.auditLog`. */
|
|
83
80
|
declare const JOOP_AUDIT_LOG: "JOOP_AUDIT_LOG";
|
|
81
|
+
/** @deprecated Inject {@link JOOP_INSTANCE} and read `.store`. */
|
|
84
82
|
declare const JOOP_STORE: "JOOP_STORE";
|
|
83
|
+
/** @deprecated Inject {@link JOOP_INSTANCE} and read `.keyVault`. */
|
|
85
84
|
declare const JOOP_KEY_VAULT: "JOOP_KEY_VAULT";
|
|
85
|
+
/** @deprecated Inject {@link JOOP_INSTANCE} and read `.network`. */
|
|
86
86
|
declare const JOOP_NETWORK: "JOOP_NETWORK";
|
|
87
|
+
/** @deprecated Inject {@link JOOP_INSTANCE} and read `.lifecycle`. */
|
|
87
88
|
declare const JOOP_LIFECYCLE: "JOOP_LIFECYCLE";
|
|
88
89
|
interface JoopProvider {
|
|
89
90
|
provide: string;
|
|
@@ -94,6 +95,9 @@ interface JoopProvider {
|
|
|
94
95
|
* Use with bootstrapApplication() or provideEnvironmentInitializer().
|
|
95
96
|
*
|
|
96
97
|
* providers: [...provideJoop(await createJoop(config))]
|
|
98
|
+
*
|
|
99
|
+
* @deprecated Use {@link provideJoopAngular} — it registers the typed
|
|
100
|
+
* {@link JOOP_INSTANCE} token (plus these legacy string tokens for compatibility).
|
|
97
101
|
*/
|
|
98
102
|
declare function provideJoop(instance: JoopInstance): JoopProvider[];
|
|
99
103
|
/**
|
|
@@ -106,6 +110,9 @@ declare function provideJoop(instance: JoopInstance): JoopProvider[];
|
|
|
106
110
|
* directly in your app's providers:
|
|
107
111
|
*
|
|
108
112
|
* @NgModule({ providers: JoopModule.forRoot(instance) })
|
|
113
|
+
*
|
|
114
|
+
* @deprecated Standalone APIs are preferred. Use `provideJoopAngular(instance)` in
|
|
115
|
+
* your `ApplicationConfig`/bootstrap providers instead.
|
|
109
116
|
*/
|
|
110
117
|
declare const JoopModule: {
|
|
111
118
|
readonly forRoot: (instance: JoopInstance) => {
|
|
@@ -119,6 +126,9 @@ declare const JoopModule: {
|
|
|
119
126
|
*
|
|
120
127
|
* readonly loading$ = fromJoop(this.joop.loader.isLoading$());
|
|
121
128
|
* readonly theme$ = fromJoop(this.joop.theme.active$());
|
|
129
|
+
*
|
|
130
|
+
* @deprecated For Angular 17+ prefer {@link joopSignal} (signals over Observables).
|
|
131
|
+
* Use `fromJoop` only when an RxJS stream is specifically required.
|
|
122
132
|
*/
|
|
123
133
|
declare function fromJoop<T>(joopObs: JoopObservable<T>): RxJSLike<T>;
|
|
124
134
|
/**
|
|
@@ -144,5 +154,66 @@ interface RxJSLike<T> {
|
|
|
144
154
|
* readonly theme$ = zonedFromJoop(this.joop.theme.active$());
|
|
145
155
|
*/
|
|
146
156
|
declare function createZonedFromJoop(zoneRun: <T>(fn: () => T) => T): <T>(obs: JoopObservable<T>) => RxJSLike<T>;
|
|
157
|
+
/**
|
|
158
|
+
* Typed InjectionToken for the JoopInstance. Prefer this over the string `JOOP`
|
|
159
|
+
* token — it gives full type inference at the injection site.
|
|
160
|
+
*
|
|
161
|
+
* private joop = inject(JOOP_INSTANCE); // typed as JoopInstance
|
|
162
|
+
*/
|
|
163
|
+
declare const JOOP_INSTANCE: InjectionToken<JoopInstance>;
|
|
164
|
+
/**
|
|
165
|
+
* Angular providers for the JoopInstance keyed by the typed token (and the
|
|
166
|
+
* legacy string tokens, so existing @Inject(JOOP_*) sites keep working).
|
|
167
|
+
*
|
|
168
|
+
* bootstrapApplication(AppComponent, {
|
|
169
|
+
* providers: [...provideJoopAngular(await createJoop(config))],
|
|
170
|
+
* });
|
|
171
|
+
*/
|
|
172
|
+
declare function provideJoopAngular(instance: JoopInstance): Provider[];
|
|
173
|
+
/** Convenience for `inject(JOOP_INSTANCE)` — must run in an injection context. */
|
|
174
|
+
declare function injectJoop(): JoopInstance;
|
|
175
|
+
interface JoopSignalOptions {
|
|
176
|
+
/** Injector to resolve DestroyRef from when called outside an injection context. */
|
|
177
|
+
injector?: Injector;
|
|
178
|
+
/** Explicit teardown ref — bypasses DestroyRef resolution (handy in tests). */
|
|
179
|
+
destroyRef?: Pick<DestroyRef, 'onDestroy'>;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Bridges a JoopObservable into an Angular signal. The signal seeds with the
|
|
183
|
+
* observable's current value (for JoopBehaviorSubject-backed streams) and
|
|
184
|
+
* updates on every emission. The subscription is torn down automatically via
|
|
185
|
+
* DestroyRef when the owning component/service is destroyed.
|
|
186
|
+
*
|
|
187
|
+
* readonly balance = joopSignal(this.joop.wallet.balance$());
|
|
188
|
+
* // template: {{ balance() }}
|
|
189
|
+
*
|
|
190
|
+
* Call from an injection context (field initializer / constructor), or pass an
|
|
191
|
+
* `injector`/`destroyRef` explicitly.
|
|
192
|
+
*/
|
|
193
|
+
declare function joopSignal<T>(source: JoopObservable<T>, options?: JoopSignalOptions): Signal<T | undefined>;
|
|
194
|
+
interface JoopAuthGuardOptions {
|
|
195
|
+
/** Where to redirect when not authenticated. Default: '/login'. */
|
|
196
|
+
redirectTo?: string;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Functional CanActivateFn backed by JoopAuthService. Returns true when logged
|
|
200
|
+
* in, otherwise a UrlTree redirecting to `redirectTo`.
|
|
201
|
+
*
|
|
202
|
+
* { path: 'account', canActivate: [joopAuthGuard()], component: AccountComponent }
|
|
203
|
+
*/
|
|
204
|
+
declare function joopAuthGuard(options?: JoopAuthGuardOptions): () => true | _angular_router.UrlTree;
|
|
205
|
+
interface JoopAuthInterceptorOptions {
|
|
206
|
+
/** Header name. Default: 'Authorization'. */
|
|
207
|
+
header?: string;
|
|
208
|
+
/** Token scheme prefix. Default: 'Bearer'. Pass '' for a bare token. */
|
|
209
|
+
scheme?: string;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Functional HttpInterceptorFn that attaches the current access token from
|
|
213
|
+
* JoopTokenService to outgoing requests.
|
|
214
|
+
*
|
|
215
|
+
* provideHttpClient(withInterceptors([joopAuthInterceptor()]))
|
|
216
|
+
*/
|
|
217
|
+
declare function joopAuthInterceptor(options?: JoopAuthInterceptorOptions): HttpInterceptorFn;
|
|
147
218
|
|
|
148
|
-
export { JOOP, JOOP_ALERT, JOOP_ANALYTICS, JOOP_AUDIT_LOG, JOOP_AUTH, JOOP_FEATURE_FLAGS, JOOP_HTTP, JOOP_I18N, JOOP_KEY_VAULT, JOOP_LIFECYCLE, JOOP_LOADER, JOOP_NETWORK, JOOP_ROUTER, JOOP_STORE, JOOP_THEME, JoopModule, type JoopProvider, type RxJSLike, createZonedFromJoop, fromJoop, provideJoop, toJoop };
|
|
219
|
+
export { JOOP, JOOP_ALERT, JOOP_ANALYTICS, JOOP_AUDIT_LOG, JOOP_AUTH, JOOP_FEATURE_FLAGS, JOOP_HTTP, JOOP_I18N, JOOP_INSTANCE, JOOP_KEY_VAULT, JOOP_LIFECYCLE, JOOP_LOADER, JOOP_NETWORK, JOOP_ROUTER, JOOP_STORE, JOOP_THEME, type JoopAuthGuardOptions, type JoopAuthInterceptorOptions, JoopModule, type JoopProvider, type JoopSignalOptions, type RxJSLike, createZonedFromJoop, fromJoop, injectJoop, joopAuthGuard, joopAuthInterceptor, joopSignal, provideJoop, provideJoopAngular, toJoop };
|