@fiction/sdk 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +6 -221
  2. package/dist/api.d.ts +23 -0
  3. package/dist/base-CEr2lLFg.js +194 -0
  4. package/dist/base-CEr2lLFg.js.map +1 -0
  5. package/dist/index-C-0XxdQQ.js +299 -0
  6. package/dist/{index-iLB4ucpG.js.map → index-C-0XxdQQ.js.map} +1 -1
  7. package/dist/index.d.ts +7 -0
  8. package/dist/sdk.css +1 -1
  9. package/dist/sdk.js +2616 -3397
  10. package/dist/sdk.js.map +1 -1
  11. package/dist/sdkClient.d.ts +666 -0
  12. package/dist/sdkStorage.d.ts +27 -0
  13. package/dist/self/ClientAudio.d.ts +75 -0
  14. package/dist/self/SelfController.d.ts +68 -0
  15. package/dist/self/constants.d.ts +29 -0
  16. package/dist/self/index.d.ts +7 -0
  17. package/dist/self/schema.d.ts +28 -0
  18. package/dist/self/ui/ElAudioVisualizer.vue.d.ts +19 -0
  19. package/dist/self/ui/ElSelfAbout.vue.d.ts +6 -0
  20. package/dist/self/ui/ElSelfChat.vue.d.ts +8 -0
  21. package/dist/self/ui/ElSelfHeader.vue.d.ts +9 -0
  22. package/dist/self/ui/ElSelfSidebar.vue.d.ts +11 -0
  23. package/dist/self/ui/ElSelfVoice.vue.d.ts +6 -0
  24. package/dist/self/ui/SelfAgent.vue.d.ts +19 -0
  25. package/dist/self/ui/SelfProvider.vue.d.ts +12 -0
  26. package/dist/self/ui/SelfWrap.vue.d.ts +142 -0
  27. package/dist/self/utils.d.ts +18 -0
  28. package/dist/self.js +4874 -0
  29. package/dist/self.js.map +1 -0
  30. package/dist/types/SDKAppType.stub.d.ts +6 -0
  31. package/package.json +25 -26
  32. package/dist/base-CWJerwpW.js +0 -299
  33. package/dist/base-CWJerwpW.js.map +0 -1
  34. package/dist/index-iLB4ucpG.js +0 -402
  35. package/dist/sdk.d.ts +0 -460
  36. package/dist/ui.d.ts +0 -19
  37. package/dist/ui.js +0 -30388
  38. package/dist/ui.js.map +0 -1
package/README.md CHANGED
@@ -1,234 +1,19 @@
1
1
  # Fiction SDK
2
2
 
3
- Vue-reactive SDK for Fiction app with full TypeScript type safety via Hono RPC.
3
+ Lightweight client library for Fiction-owned projects (app, www, widget).
4
4
 
5
- ## Features
6
-
7
- - ✅ **Fully typed Hono RPC client** - Type-safe endpoints, request bodies, response types
8
- - ✅ **Convenience auth methods** - High-level helpers for common operations
9
- - ✅ **Vue reactivity** - Reactive state management with Vue refs
10
- - ✅ **Auto user/token updates** - API responses automatically update client state
11
- - ✅ **Cookie-based auth** - Cross-domain session management
12
- - ✅ **UI components** - Import pre-built Vue components from `/ui` export
13
- - ✅ **Extends SettingsObject** - Built-in logger and proper dependency injection
14
-
15
- ## Installation
5
+ ## Development
16
6
 
17
7
  ```bash
18
- pnpm add @fiction/sdk
8
+ pnpm dev # Watch mode - rebuilds on change
9
+ pnpm build # Production build (ES modules + types)
19
10
  ```
20
11
 
21
12
  ## Usage
22
13
 
23
- ### Quick Start with Convenience Methods
24
-
25
14
  ```typescript
26
15
  import { FictionSDK } from '@fiction/sdk'
27
-
28
- const sdk = new FictionSDK({
29
- isDev: true,
30
- apiBase: 'http://localhost:5555'
31
- })
32
-
33
- // Simple auth methods
34
- await sdk.sendCode('user@example.com')
35
- await sdk.verifyCode('user@example.com', '123456')
36
- await sdk.login('user@example.com', 'password')
37
- await sdk.logout()
38
-
39
- // Reactive state
40
- console.log(sdk.activeUser.value) // Current user
41
- console.log(sdk.loading.value) // Loading state
42
- console.log(sdk.error.value) // Error message
43
- ```
44
-
45
- ### Fully Typed API Access
46
-
47
- When you have access to the app's server types, you get full type safety:
48
-
49
- ```typescript
50
- import { FictionSDK } from '@fiction/sdk'
51
- import type { AppType } from '@/modules/main/server'
52
-
53
- // Create SDK with app types for full type safety
54
- const sdk = new FictionSDK<AppType>({
55
- isDev: true,
56
- apiBase: 'http://localhost:5555'
57
- })
58
-
59
- // Now sdk.apiClient is fully typed with all endpoints!
60
- // Autocomplete, type checking, compile-time errors
61
-
62
- // Example: Type-safe auth endpoint
63
- const response = await sdk.apiClient.api.auth['send-code'].$post({
64
- json: { email: 'user@example.com' }
65
- })
66
-
67
- const data = await response.json()
68
- // data is fully typed based on the endpoint's response schema
69
- ```
70
-
71
- ### Reactive State
72
-
73
- The SDK exposes Vue refs for reactive state management:
74
-
75
- ```typescript
76
- // Reactive user state
77
- sdk.activeUser.value // EnrichedUser | undefined
78
- sdk.token.value // string | null
79
- sdk.loading.value // boolean
80
- sdk.error.value // string | null
81
-
82
- // Watch for changes
83
- watch(sdk.activeUser, (user) => {
84
- console.log('User changed:', user)
85
- })
86
- ```
87
-
88
- ### UI Components
89
-
90
- Import pre-built Vue components for rapid integration:
91
-
92
- ```typescript
93
- // Import UI components from /ui export
94
- import { SelfAgent, TestButton } from '@fiction/sdk/ui'
95
-
96
- // Use in your Vue app
97
- <template>
98
- <SelfAgent
99
- :self="selfData"
100
- context="website"
101
- @close="handleClose"
102
- />
103
-
104
- <TestButton
105
- label="Click me"
106
- @click="handleClick"
107
- />
108
- </template>
109
- ```
110
-
111
- **Available Components:**
112
- - `SelfAgent` - Full digital self agent interface with chat, voice, and profile
113
- - `TestButton` - Simple test button component (for validation)
114
-
115
- ### Advanced: Direct Typed API Access
116
-
117
- Use the typed Hono RPC client directly for custom endpoints:
118
-
119
- ```typescript
120
- // Type-safe login
121
- const loginResponse = await sdk.apiClient.api.auth.login.$post({
122
- json: { email: 'user@example.com', password: 'secret' }
123
- })
124
-
125
- // Type-safe user fetch
126
- const userResponse = await sdk.apiClient.api.auth.me.$get()
127
-
128
- // Type-safe self access
129
- const selfResponse = await sdk.apiClient.api.self['by-handle'].$get({
130
- query: { handle: 'andrew' }
131
- })
132
-
133
- // All responses are fully typed based on endpoint schemas
134
- const data = await loginResponse.json()
135
- ```
136
-
137
- ## API Reference
138
-
139
- ### FictionSDK Class
140
-
141
- ```typescript
142
- class FictionSDK<TAppType extends Hono = any> extends SettingsObject<FictionSDKSettings>
143
- ```
144
-
145
- #### Constructor
146
-
147
- ```typescript
148
- new FictionSDK<TAppType>(settings?: FictionSDKSettings)
149
- ```
150
-
151
- **Settings:**
152
- - `apiBase?: string` - API base URL (default: auto-detected)
153
- - `isDev?: boolean` - Development mode (default: auto-detected from hostname)
154
-
155
- #### Properties
156
-
157
- - `apiClient: ReturnType<typeof createApiClient<TAppType>>` - Typed Hono RPC client
158
- - `activeUser: Ref<EnrichedUser | undefined>` - Current authenticated user
159
- - `token: Ref<string | null>` - Authentication token
160
- - `loading: Ref<boolean>` - Loading state
161
- - `error: Ref<string | null>` - Error message
162
- - `logger: ReturnType<typeof createLogger>` - Logger instance (from SettingsObject)
163
- - `initialized: Promise<EnrichedUser | undefined>` - Promise that resolves when user loads
164
-
165
- #### Methods
166
-
167
- **Convenience Auth Methods:**
168
- - `sendCode(email: string): Promise<void>` - Send verification code to email
169
- - `verifyCode(email: string, code: string): Promise<void>` - Verify code and login
170
- - `login(email: string, password: string): Promise<void>` - Login with password
171
- - `logout(): Promise<void>` - Logout and clear session
172
- - `getCurrentUser(): Promise<EnrichedUser | undefined>` - Fetch current user from server
173
-
174
- **Utility Methods:**
175
- - `processApiResponse(response: ApiResponse<any>): void` - Process API response for auto state updates
176
- - `clearSession(): void` - Clear all user data and tokens
177
-
178
- ### createApiClient Function
179
-
180
- ```typescript
181
- function createApiClient<TAppType extends Hono = any>(
182
- settings: ApiClientSettings,
183
- responseHandler?: (response: any) => void
184
- ): ReturnType<typeof hc<TAppType>>
185
- ```
186
-
187
- Creates a fully typed Hono RPC client with optional response interceptor.
188
-
189
- **Example:**
190
- ```typescript
191
- import type { AppType } from '@/modules/main/server'
192
-
193
- const client = createApiClient<AppType>(
194
- { isDev: true },
195
- (response) => {
196
- // Handle ApiResponse with user/token updates
197
- console.log('API response:', response)
198
- }
199
- )
200
-
201
- // Fully typed endpoint calls
202
- const response = await client.api.auth['send-code'].$post({
203
- json: { email: 'user@example.com' }
204
- })
16
+ import { SelfAgent } from '@fiction/sdk/self'
205
17
  ```
206
18
 
207
- ## Bundle Size
208
-
209
- - **ES Module**: 140KB uncompressed, 27KB gzipped
210
- - **UMD**: 161KB uncompressed, 51KB gzipped
211
- - **TypeScript declarations**: Included
212
-
213
- ## Development
214
-
215
- ```bash
216
- # Install dependencies
217
- pnpm install
218
-
219
- # Build
220
- pnpm run build
221
-
222
- # Type check
223
- pnpm run typecheck
224
-
225
- # Run tests
226
- pnpm run test
227
-
228
- # Watch mode
229
- pnpm run test:watch
230
- ```
231
-
232
- ## License
233
-
234
- MIT
19
+ **Build required before typecheck** - Widget/www import from `dist/`, not source.
package/dist/api.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ import { Hono } from 'hono';
2
+ import { hc } from 'hono/client';
3
+ export interface ApiClientSettings {
4
+ isDev: boolean;
5
+ apiBase?: string;
6
+ [key: string]: unknown;
7
+ }
8
+ /**
9
+ * Create fully typed Hono RPC client for Fiction SDK
10
+ *
11
+ * @template TAppType - The Hono app type from the server (enables full type safety)
12
+ * @param settings - Configuration for API base URL and environment
13
+ * @param responseHandler - Optional handler to process ApiResponse for auto user/token updates
14
+ * @returns Typed Hono client with response interceptor
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * import type { SDKAppType } from '@/modules/main/server'
19
+ * const client = createApiClient<SDKAppType>({ isDev: true })
20
+ * const response = await client.api.auth['check-email'].$post({ json: { email } })
21
+ * ```
22
+ */
23
+ export declare function createApiClient<TAppType extends Hono = any>(settings: ApiClientSettings, responseHandler?: (response: any) => void): ReturnType<typeof hc<TAppType>>;
@@ -0,0 +1,194 @@
1
+ var E = Object.defineProperty;
2
+ var D = (l, e, o) => e in l ? E(l, e, { enumerable: !0, configurable: !0, writable: !0, value: o }) : l[e] = o;
3
+ var i = (l, e) => E(l, "name", { value: e, configurable: !0 });
4
+ var h = (l, e, o) => D(l, typeof e != "symbol" ? e + "" : e, o);
5
+ const p = globalThis.process, f = typeof window < "u", y = typeof p < "u" && !f, d = f ? typeof window < "u" && window.location && !window.location.hostname.includes("localhost") : y && typeof p < "u" && p.env?.NODE_ENV === "production", k = !d, v = {
6
+ error: { priority: 50, color: "#FF0000", nodeColor: "\x1B[31m" },
7
+ warn: { priority: 40, color: "#FFA500", nodeColor: "\x1B[33m" },
8
+ info: { priority: 30, color: "#00ABFF", nodeColor: "\x1B[36m" },
9
+ debug: { priority: 20, color: "#00BD0C", nodeColor: "\x1B[32m" },
10
+ trace: { priority: 10, color: "#5233FF", nodeColor: "\x1B[35m" }
11
+ }, N = ["password", "token", "secret", "apikey", "api_key", "authorization", "cookie"], m = class m {
12
+ constructor(e = {}, o) {
13
+ h(this, "settings");
14
+ h(this, "enabledInBrowser", !1);
15
+ h(this, "context");
16
+ this.context = o, this.settings = {
17
+ enabled: e.enabled ?? !0,
18
+ minLevel: e.minLevel ?? this.getDefaultLevel(),
19
+ timestamps: e.timestamps ?? !0
20
+ }, f && this.initBrowserLogging();
21
+ }
22
+ getDefaultLevel() {
23
+ if (y && typeof p < "u" && p.env?.LOG_LEVEL)
24
+ return p.env.LOG_LEVEL;
25
+ if (f && typeof localStorage < "u") {
26
+ const e = localStorage.getItem("FICTION_LOG_LEVEL");
27
+ if (e)
28
+ return e;
29
+ }
30
+ return d ? "info" : "debug";
31
+ }
32
+ initBrowserLogging() {
33
+ if (!f)
34
+ return;
35
+ const o = localStorage.getItem("FICTION_LOG") === "true", t = window.location?.hostname || "";
36
+ this.enabledInBrowser = k || o || t === "localhost" || t.includes("127.0.0.1"), d && !o && !m.hasShownHelp && (console.log(
37
+ "%cFiction WWW Logger (disabled in production)",
38
+ "color: #888; font-size: 12px"
39
+ ), console.log(
40
+ '%cTo enable: localStorage.setItem("FICTION_LOG", "true")',
41
+ "color: #888; font-size: 11px"
42
+ ), m.hasShownHelp = !0);
43
+ }
44
+ shouldLog(e) {
45
+ if (!this.settings.enabled || f && !this.enabledInBrowser)
46
+ return !1;
47
+ const o = v[e].priority, t = v[this.settings.minLevel].priority;
48
+ return o >= t;
49
+ }
50
+ formatTimestamp() {
51
+ return (/* @__PURE__ */ new Date()).toLocaleTimeString("en-GB", {
52
+ hour12: !1,
53
+ hour: "2-digit",
54
+ minute: "2-digit",
55
+ second: "2-digit"
56
+ });
57
+ }
58
+ formatISOTimestamp() {
59
+ return (/* @__PURE__ */ new Date()).toISOString();
60
+ }
61
+ redactSensitive(e) {
62
+ if (typeof e != "object" || e === null)
63
+ return e;
64
+ if (Array.isArray(e))
65
+ return e.map((t) => this.redactSensitive(t));
66
+ const o = {};
67
+ for (const [t, r] of Object.entries(e)) {
68
+ const s = t.toLowerCase();
69
+ N.some((n) => s.includes(n)) ? o[t] = "[REDACTED]" : typeof r == "object" && r !== null ? o[t] = this.redactSensitive(r) : o[t] = r;
70
+ }
71
+ return o;
72
+ }
73
+ formatData(e, o = 3, t = 0) {
74
+ if (t >= o)
75
+ return "[Max Depth]";
76
+ if (e == null)
77
+ return e;
78
+ if (e instanceof Error)
79
+ return {
80
+ name: e.name,
81
+ message: e.message,
82
+ stack: d ? e.stack?.split(`
83
+ `).slice(0, 3).join(`
84
+ `) : e.stack,
85
+ ...e
86
+ // Include any additional error properties
87
+ };
88
+ if (e instanceof Date)
89
+ return e.toISOString();
90
+ if (typeof e != "object")
91
+ return e;
92
+ if (Array.isArray(e))
93
+ return e.length > 20 && d ? `Array(${e.length}) [${e.slice(0, 3).map((r) => this.formatData(r, o, t + 1)).join(", ")}, ...]` : e.map((r) => this.formatData(r, o, t + 1));
94
+ try {
95
+ const r = {}, s = Object.entries(e), n = d ? 50 : 200;
96
+ for (const [g, u] of s.slice(0, n))
97
+ r[g] = this.formatData(u, o, t + 1);
98
+ return s.length > n && (r["..."] = `${s.length - n} more properties`), this.redactSensitive(r);
99
+ } catch {
100
+ return "[Unserializable]";
101
+ }
102
+ }
103
+ logToBrowser(e) {
104
+ if (!f || !this.shouldLog(e.level))
105
+ return;
106
+ const { level: o, description: t, context: r, data: s, error: n } = e, g = v[o], a = `[${r || this.context || "www"}] ${o.toUpperCase()}:`, w = `color: ${g.color}; font-weight: bold;`;
107
+ s !== void 0 ? console[o](`%c${a}`, w, t, this.formatData(s)) : console[o](`%c${a}`, w, t), n && (n instanceof Error ? console.error(n) : console.error("Error details:", n));
108
+ }
109
+ async logToNode(e) {
110
+ if (!y || !this.shouldLog(e.level))
111
+ return;
112
+ const { level: o, description: t, context: r, data: s, error: n } = e, g = r || this.context || "www";
113
+ if (d) {
114
+ const u = {
115
+ timestamp: this.formatISOTimestamp(),
116
+ level: o.toUpperCase()
117
+ };
118
+ s && (u.data = this.formatData(s)), n && (u.error = this.formatData(n)), console[o](`${u.timestamp} ${u.level} [${g}] ${t}`, s || n ? JSON.stringify({ data: s, error: n }) : "");
119
+ } else
120
+ try {
121
+ const a = (await import("./index-C-0XxdQQ.js").catch(() => null))?.default, w = v[o], $ = this.formatTimestamp();
122
+ if (a) {
123
+ const C = a.dim, b = a.hex(w.color), I = C(`${$} `), T = b(`${o.toUpperCase()} `), B = b(`(${g}): `), O = `${I}${T}${B}${t}`;
124
+ console[o](O), s !== void 0 && console.log(JSON.stringify(this.formatData(s), null, 2)), n && (n instanceof Error && a ? (console.error(a.red("Error:"), n.message), n.stack && console.error(a.gray(n.stack))) : console.error("Error:", n));
125
+ } else
126
+ console[o](`${$} ${o.toUpperCase()} (${g}): ${t}`), s !== void 0 && console.log(JSON.stringify(this.formatData(s), null, 2)), n && console.error("Error:", n);
127
+ } catch {
128
+ console[o](`${this.formatTimestamp()} ${o.toUpperCase()} (${g}): ${t}`), s !== void 0 && console.log(JSON.stringify(this.formatData(s), null, 2)), n && console.error("Error:", n);
129
+ }
130
+ }
131
+ log(e) {
132
+ f ? this.logToBrowser(e) : y && this.logToNode(e).catch(console.error);
133
+ }
134
+ error(e, o) {
135
+ this.log({ level: "error", description: e, data: o, context: this.context });
136
+ }
137
+ warn(e, o) {
138
+ this.log({ level: "warn", description: e, data: o, context: this.context });
139
+ }
140
+ info(e, o) {
141
+ this.log({ level: "info", description: e, data: o, context: this.context });
142
+ }
143
+ debug(e, o) {
144
+ this.log({ level: "debug", description: e, data: o, context: this.context });
145
+ }
146
+ trace(e, o) {
147
+ this.log({ level: "trace", description: e, data: o, context: this.context });
148
+ }
149
+ isEnabled() {
150
+ return f ? this.enabledInBrowser : !0;
151
+ }
152
+ setLevel(e) {
153
+ this.settings.minLevel = e;
154
+ }
155
+ createContextLogger(e) {
156
+ const o = new m(this.settings, e);
157
+ return {
158
+ error: /* @__PURE__ */ i((t, r) => o.error(t, r), "error"),
159
+ warn: /* @__PURE__ */ i((t, r) => o.warn(t, r), "warn"),
160
+ info: /* @__PURE__ */ i((t, r) => o.info(t, r), "info"),
161
+ debug: /* @__PURE__ */ i((t, r) => o.debug(t, r), "debug"),
162
+ trace: /* @__PURE__ */ i((t, r) => o.trace(t, r), "trace"),
163
+ isEnabled: /* @__PURE__ */ i(() => o.isEnabled(), "isEnabled"),
164
+ setLevel: /* @__PURE__ */ i((t) => o.setLevel(t), "setLevel")
165
+ };
166
+ }
167
+ };
168
+ i(m, "Logger"), h(m, "hasShownHelp", !1);
169
+ let x = m;
170
+ function F(l) {
171
+ return new x({}, l).createContextLogger(l);
172
+ }
173
+ i(F, "createLogger");
174
+ const c = new x();
175
+ c.error.bind(c);
176
+ c.warn.bind(c);
177
+ c.info.bind(c);
178
+ c.debug.bind(c);
179
+ c.trace.bind(c);
180
+ const L = class L {
181
+ constructor(e, o) {
182
+ h(this, "name");
183
+ h(this, "settings");
184
+ h(this, "logger");
185
+ this.name = e, this.settings = o, this.logger = F(e);
186
+ }
187
+ };
188
+ i(L, "SettingsObject");
189
+ let S = L;
190
+ export {
191
+ S,
192
+ F as c
193
+ };
194
+ //# sourceMappingURL=base-CEr2lLFg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-CEr2lLFg.js","sources":["../../utils/logger.ts","../../utils/base.ts"],"sourcesContent":["/* eslint-disable no-console */\n\n// Use globalThis.process instead of node:process import for browser compatibility\n// Safe because we always check `typeof process !== 'undefined'` before accessing properties\n// eslint-disable-next-line node/prefer-global/process\nconst process = (globalThis as any).process\n\ntype LogLevel = 'error' | 'warn' | 'info' | 'debug' | 'trace'\ntype LogData = Record<string, unknown> | unknown\n\nexport interface LogHelper {\n error: (description: string, data?: LogData) => void\n warn: (description: string, data?: LogData) => void\n info: (description: string, data?: LogData) => void\n debug: (description: string, data?: LogData) => void\n trace: (description: string, data?: LogData) => void\n isEnabled?: () => boolean\n setLevel?: (level: LogLevel) => void\n}\n\ninterface LoggerConfig {\n level: LogLevel\n context?: string\n description?: string\n data?: LogData\n error?: Error | unknown\n timestamp?: boolean\n}\n\ninterface LogSettings {\n enabled?: boolean\n minLevel?: LogLevel\n timestamps?: boolean\n}\n\n// Universal environment detection\nconst isBrowser = typeof window !== 'undefined'\nconst isNode = typeof process !== 'undefined' && !isBrowser\nconst isProd = isBrowser\n ? (typeof window !== 'undefined' && window.location && !window.location.hostname.includes('localhost'))\n : (isNode && typeof process !== 'undefined' && process.env?.NODE_ENV === 'production')\nconst isDev = !isProd\n\n// Log level configuration\nconst logLevels: Record<LogLevel, { priority: number, color: string, nodeColor?: string }> = {\n error: { priority: 50, color: '#FF0000', nodeColor: '\\x1B[31m' },\n warn: { priority: 40, color: '#FFA500', nodeColor: '\\x1B[33m' },\n info: { priority: 30, color: '#00ABFF', nodeColor: '\\x1B[36m' },\n debug: { priority: 20, color: '#00BD0C', nodeColor: '\\x1B[32m' },\n trace: { priority: 10, color: '#5233FF', nodeColor: '\\x1B[35m' },\n}\n\n// Sensitive keys to redact\nconst SENSITIVE_KEYS = ['password', 'token', 'secret', 'apikey', 'api_key', 'authorization', 'cookie']\n\nexport class Logger {\n private settings: Required<LogSettings>\n private enabledInBrowser: boolean = false\n private context?: string\n private static hasShownHelp = false\n\n constructor(settings: LogSettings = {}, context?: string) {\n this.context = context\n this.settings = {\n enabled: settings.enabled ?? true,\n minLevel: settings.minLevel ?? this.getDefaultLevel(),\n timestamps: settings.timestamps ?? true,\n }\n\n if (isBrowser) {\n this.initBrowserLogging()\n }\n }\n\n private getDefaultLevel(): LogLevel {\n // Check environment variable first\n if (isNode && typeof process !== 'undefined' && process.env?.LOG_LEVEL) {\n return process.env.LOG_LEVEL as LogLevel\n }\n\n // Check localStorage in browser\n if (isBrowser && typeof localStorage !== 'undefined') {\n const level = localStorage.getItem('FICTION_LOG_LEVEL')\n if (level)\n return level as LogLevel\n }\n\n // Default: info in production, debug in development\n return isProd ? 'info' : 'debug'\n }\n\n private initBrowserLogging(): void {\n if (!isBrowser)\n return\n\n const logKey = 'FICTION_LOG'\n const enabled = localStorage.getItem(logKey) === 'true'\n const hostname = window.location?.hostname || ''\n\n // Enable in dev, or if explicitly enabled via localStorage\n this.enabledInBrowser = isDev || enabled || hostname === 'localhost' || hostname.includes('127.0.0.1')\n\n // Show help message once in production\n if (isProd && !enabled && !Logger.hasShownHelp) {\n console.log(\n '%cFiction WWW Logger (disabled in production)',\n 'color: #888; font-size: 12px',\n )\n console.log(\n '%cTo enable: localStorage.setItem(\"FICTION_LOG\", \"true\")',\n 'color: #888; font-size: 11px',\n )\n Logger.hasShownHelp = true\n }\n }\n\n private shouldLog(level: LogLevel): boolean {\n if (!this.settings.enabled)\n return false\n\n // In browser, check if enabled\n if (isBrowser && !this.enabledInBrowser)\n return false\n\n const currentPriority = logLevels[level].priority\n const minPriority = logLevels[this.settings.minLevel].priority\n\n return currentPriority >= minPriority\n }\n\n private formatTimestamp(): string {\n return new Date().toLocaleTimeString('en-GB', {\n hour12: false,\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n })\n }\n\n private formatISOTimestamp(): string {\n return new Date().toISOString()\n }\n\n private redactSensitive(obj: any): any {\n if (typeof obj !== 'object' || obj === null)\n return obj\n\n if (Array.isArray(obj)) {\n return obj.map((item) => this.redactSensitive(item))\n }\n\n const result: any = {}\n for (const [key, value] of Object.entries(obj)) {\n const lowerKey = key.toLowerCase()\n if (SENSITIVE_KEYS.some((sensitive) => lowerKey.includes(sensitive))) {\n result[key] = '[REDACTED]'\n } else if (typeof value === 'object' && value !== null) {\n result[key] = this.redactSensitive(value)\n } else {\n result[key] = value\n }\n }\n return result\n }\n\n private formatData(data: unknown, maxDepth: number = 3, currentDepth: number = 0): unknown {\n if (currentDepth >= maxDepth) {\n return '[Max Depth]'\n }\n\n if (data === null || data === undefined) {\n return data\n }\n\n // Handle Error objects specially\n if (data instanceof Error) {\n return {\n name: data.name,\n message: data.message,\n stack: isProd ? data.stack?.split('\\n').slice(0, 3).join('\\n') : data.stack,\n ...(data as any), // Include any additional error properties\n }\n }\n\n if (data instanceof Date) {\n return data.toISOString()\n }\n\n if (typeof data !== 'object') {\n return data\n }\n\n if (Array.isArray(data)) {\n if (data.length > 20 && isProd) {\n return `Array(${data.length}) [${data.slice(0, 3).map((item) =>\n this.formatData(item, maxDepth, currentDepth + 1)).join(', ')}, ...]`\n }\n return data.map((item) => this.formatData(item, maxDepth, currentDepth + 1))\n }\n\n // Handle regular objects\n try {\n const formatted: Record<string, unknown> = {}\n const entries = Object.entries(data)\n const maxProperties = isProd ? 50 : 200\n\n for (const [key, value] of entries.slice(0, maxProperties)) {\n formatted[key] = this.formatData(value, maxDepth, currentDepth + 1)\n }\n\n if (entries.length > maxProperties) {\n formatted['...'] = `${entries.length - maxProperties} more properties`\n }\n\n return this.redactSensitive(formatted)\n } catch {\n return '[Unserializable]'\n }\n }\n\n private logToBrowser(config: LoggerConfig): void {\n if (!isBrowser || !this.shouldLog(config.level))\n return\n\n const { level, description, context, data, error } = config\n const levelConfig = logLevels[level]\n const ctx = context || this.context || 'www'\n\n // Format for browser console\n const prefix = `[${ctx}] ${level.toUpperCase()}:`\n const style = `color: ${levelConfig.color}; font-weight: bold;`\n\n // Log main message\n if (data !== undefined) {\n console[level](`%c${prefix}`, style, description, this.formatData(data))\n } else {\n console[level](`%c${prefix}`, style, description)\n }\n\n // Log error details if present\n if (error) {\n if (error instanceof Error) {\n console.error(error)\n } else {\n console.error('Error details:', error)\n }\n }\n }\n\n private async logToNode(config: LoggerConfig): Promise<void> {\n if (!isNode || !this.shouldLog(config.level))\n return\n\n const { level, description, context, data, error } = config\n const ctx = context || this.context || 'www'\n\n if (isProd) {\n // Production: Single-line JSON format for log aggregation\n const logEntry: any = {\n timestamp: this.formatISOTimestamp(),\n level: level.toUpperCase(),\n context: ctx,\n message: description,\n }\n if (data) {\n logEntry.data = this.formatData(data)\n }\n if (error) {\n logEntry.error = this.formatData(error)\n }\n\n console[level](`${logEntry.timestamp} ${logEntry.level} [${ctx}] ${description}`, data || error ? JSON.stringify({ data, error }) : '')\n } else {\n // Development: Pretty-printed format\n try {\n // Dynamic import for Node-only dependencies\n const chalkModule = await import('chalk').catch(() => null)\n const chalk = chalkModule?.default\n\n const levelConfig = logLevels[level]\n const timestamp = this.formatTimestamp()\n\n if (chalk) {\n const dim = chalk.dim\n const colored = chalk.hex(levelConfig.color)\n\n const logTimestamp = dim(`${timestamp} `)\n const logLevel = colored(`${level.toUpperCase()} `)\n const logContext = colored(`(${ctx}): `)\n const logMessage = `${logTimestamp}${logLevel}${logContext}${description}`\n\n console[level](logMessage)\n\n // Log data if present\n if (data !== undefined) {\n console.log(JSON.stringify(this.formatData(data), null, 2))\n }\n\n // Log error if present\n if (error) {\n if (error instanceof Error && chalk) {\n console.error(chalk.red('Error:'), error.message)\n if (error.stack) {\n console.error(chalk.gray(error.stack))\n }\n } else {\n console.error('Error:', error)\n }\n }\n } else {\n // Fallback without chalk\n console[level](`${timestamp} ${level.toUpperCase()} (${ctx}): ${description}`)\n if (data !== undefined) {\n console.log(JSON.stringify(this.formatData(data), null, 2))\n }\n if (error) {\n console.error('Error:', error)\n }\n }\n } catch {\n // Fallback if dynamic imports fail\n console[level](`${this.formatTimestamp()} ${level.toUpperCase()} (${ctx}): ${description}`)\n if (data !== undefined) {\n console.log(JSON.stringify(this.formatData(data), null, 2))\n }\n if (error) {\n console.error('Error:', error)\n }\n }\n }\n }\n\n private log(config: LoggerConfig): void {\n if (isBrowser) {\n this.logToBrowser(config)\n } else if (isNode) {\n // Use promise but don't await (fire and forget)\n this.logToNode(config).catch(console.error)\n }\n }\n\n error(description: string, data?: LogData): void {\n this.log({ level: 'error', description, data, context: this.context })\n }\n\n warn(description: string, data?: LogData): void {\n this.log({ level: 'warn', description, data, context: this.context })\n }\n\n info(description: string, data?: LogData): void {\n this.log({ level: 'info', description, data, context: this.context })\n }\n\n debug(description: string, data?: LogData): void {\n this.log({ level: 'debug', description, data, context: this.context })\n }\n\n trace(description: string, data?: LogData): void {\n this.log({ level: 'trace', description, data, context: this.context })\n }\n\n isEnabled(): boolean {\n if (isBrowser) {\n return this.enabledInBrowser\n }\n return true // Always enabled in Node\n }\n\n setLevel(level: LogLevel): void {\n this.settings.minLevel = level\n }\n\n createContextLogger(context: string): LogHelper {\n const contextualLogger = new Logger(this.settings, context)\n\n return {\n error: (description: string, data?: LogData) => contextualLogger.error(description, data),\n warn: (description: string, data?: LogData) => contextualLogger.warn(description, data),\n info: (description: string, data?: LogData) => contextualLogger.info(description, data),\n debug: (description: string, data?: LogData) => contextualLogger.debug(description, data),\n trace: (description: string, data?: LogData) => contextualLogger.trace(description, data),\n isEnabled: () => contextualLogger.isEnabled(),\n setLevel: (level: LogLevel) => contextualLogger.setLevel(level),\n }\n }\n}\n\n// Factory function - main export\nexport function createLogger(context: string): LogHelper {\n return new Logger({}, context).createContextLogger(context)\n}\n\n// Default logger instance for convenience\nexport const logger = new Logger()\n\n// Convenience exports\nexport const error = logger.error.bind(logger)\nexport const warn = logger.warn.bind(logger)\nexport const info = logger.info.bind(logger)\nexport const debug = logger.debug.bind(logger)\nexport const trace = logger.trace.bind(logger)\n","import { createLogger } from './logger'\n\nexport type SettingsObjectSettings = {\n [key: string]: unknown\n}\n\n/**\n * Base class for objects with settings and contextual logging.\n * Services use this.logger.error(message, { data }) pattern directly.\n */\nexport abstract class SettingsObject<T extends SettingsObjectSettings = SettingsObjectSettings> {\n name: string\n settings: T\n logger: ReturnType<typeof createLogger>\n\n constructor(name: string, settings: T) {\n this.name = name\n this.settings = settings\n this.logger = createLogger(name)\n }\n}\n"],"names":["process","isBrowser","isNode","isProd","isDev","logLevels","SENSITIVE_KEYS","_Logger","settings","context","__publicField","level","enabled","hostname","currentPriority","minPriority","obj","item","result","key","value","lowerKey","sensitive","data","maxDepth","currentDepth","formatted","entries","maxProperties","config","description","error","levelConfig","prefix","style","ctx","logEntry","chalk","timestamp","dim","colored","logTimestamp","logLevel","logContext","logMessage","contextualLogger","__name","Logger","createLogger","logger","_SettingsObject","name","SettingsObject"],"mappings":"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"}