@rimori/client 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/.prettierignore +35 -0
  2. package/dist/cli/scripts/release/release-file-upload.js +1 -1
  3. package/dist/cli/types/DatabaseTypes.d.ts +2 -2
  4. package/dist/components/ai/Avatar.js +4 -2
  5. package/dist/components/ai/EmbeddedAssistent/TTS/Player.js +1 -1
  6. package/dist/core/controller/AIController.js +9 -7
  7. package/dist/core/controller/ExerciseController.d.ts +52 -0
  8. package/dist/core/controller/ExerciseController.js +73 -0
  9. package/dist/core/core.d.ts +1 -0
  10. package/dist/plugin/Logger.d.ts +5 -0
  11. package/dist/plugin/Logger.js +56 -6
  12. package/dist/plugin/RimoriClient.d.ts +28 -2
  13. package/dist/plugin/RimoriClient.js +30 -1
  14. package/eslint.config.js +53 -0
  15. package/package.json +9 -2
  16. package/prettier.config.js +8 -0
  17. package/src/cli/scripts/release/release-file-upload.ts +1 -1
  18. package/src/cli/types/DatabaseTypes.ts +17 -10
  19. package/src/components/ai/Avatar.tsx +3 -2
  20. package/src/components/ai/EmbeddedAssistent/TTS/Player.ts +176 -176
  21. package/src/core/controller/AIController.ts +36 -34
  22. package/src/core/controller/ExerciseController.ts +105 -0
  23. package/src/core/core.ts +1 -0
  24. package/src/plugin/Logger.ts +59 -8
  25. package/src/plugin/RimoriClient.ts +40 -6
  26. package/dist/components/LoggerExample.d.ts +0 -6
  27. package/dist/components/LoggerExample.js +0 -79
  28. package/dist/core/controller/AudioController.d.ts +0 -0
  29. package/dist/core/controller/AudioController.js +0 -1
  30. package/dist/hooks/UseLogger.d.ts +0 -30
  31. package/dist/hooks/UseLogger.js +0 -122
  32. package/dist/plugin/LoggerExample.d.ts +0 -16
  33. package/dist/plugin/LoggerExample.js +0 -140
  34. package/dist/utils/audioFormats.d.ts +0 -26
  35. package/dist/utils/audioFormats.js +0 -67
@@ -0,0 +1,105 @@
1
+ import { SupabaseClient } from "@supabase/supabase-js";
2
+ import { PluginController } from "../../plugin/PluginController";
3
+
4
+ export type TriggerAction = { action_key: string } & Record<string, string | number | boolean>;
5
+
6
+ export interface CreateExerciseParams {
7
+ plugin_id: string;
8
+ start_date: string;
9
+ end_date: string;
10
+ trigger_action: TriggerAction;
11
+ name: string;
12
+ description: string;
13
+ estimated_duration: number;
14
+ }
15
+
16
+ export interface Exercise {
17
+ id: string;
18
+ plugin_id: string;
19
+ start_date: string;
20
+ end_date: string;
21
+ trigger_action: TriggerAction;
22
+ name: string;
23
+ description: string;
24
+ estimated_duration: number;
25
+ created_at?: string;
26
+ updated_at?: string;
27
+ }
28
+
29
+ export class ExerciseController {
30
+ private supabase: SupabaseClient;
31
+ private pluginController: PluginController;
32
+
33
+ constructor(supabase: SupabaseClient, pluginController: PluginController) {
34
+ this.supabase = supabase;
35
+ this.pluginController = pluginController;
36
+ }
37
+
38
+ /**
39
+ * Fetches weekly exercises from the weekly_exercises view.
40
+ * Shows exercises for the current week that haven't expired.
41
+ * @returns Array of exercise objects.
42
+ */
43
+ public async viewWeeklyExercises(): Promise<Exercise[]> {
44
+ const { data, error } = await this.supabase.from('weekly_exercises').select('*');
45
+
46
+ if (error) {
47
+ throw new Error(`Failed to fetch weekly exercises: ${error.message}`);
48
+ }
49
+
50
+ return data || [];
51
+ }
52
+
53
+ /**
54
+ * Creates a new exercise via the backend API.
55
+ * @param params Exercise creation parameters.
56
+ * @returns Created exercise object.
57
+ */
58
+ public async addExercise(params: CreateExerciseParams): Promise<Exercise> {
59
+ const token = await this.pluginController.getToken();
60
+ const response = await fetch(
61
+ `${this.pluginController.getBackendUrl()}/exercises`,
62
+ {
63
+ method: 'POST',
64
+ headers: {
65
+ 'Content-Type': 'application/json',
66
+ 'Authorization': `Bearer ${token}`,
67
+ },
68
+ body: JSON.stringify(params),
69
+ }
70
+ );
71
+
72
+ if (!response.ok) {
73
+ const errorText = await response.text();
74
+ throw new Error(`Failed to create exercise: ${errorText}`);
75
+ }
76
+
77
+ return await response.json();
78
+ }
79
+
80
+ /**
81
+ * Deletes an exercise via the backend API.
82
+ * @param id The exercise ID to delete.
83
+ * @returns Success status.
84
+ */
85
+ public async deleteExercise(id: string): Promise<{ success: boolean; message: string }> {
86
+ const token = await this.pluginController.getToken();
87
+ const response = await fetch(
88
+ `${this.pluginController.getBackendUrl()}/exercises/${id}`,
89
+ {
90
+ method: 'DELETE',
91
+ headers: {
92
+ 'Authorization': `Bearer ${token}`,
93
+ },
94
+ }
95
+ );
96
+
97
+ if (!response.ok) {
98
+ const errorText = await response.text();
99
+ throw new Error(`Failed to delete exercise: ${errorText}`);
100
+ }
101
+
102
+ return await response.json();
103
+ }
104
+ }
105
+
package/src/core/core.ts CHANGED
@@ -9,6 +9,7 @@ export * from "../worker/WorkerSetup";
9
9
  export { EventBusMessage } from "../fromRimori/EventBus";
10
10
  export { Buddy, UserInfo } from "./controller/SettingsController";
11
11
  export { SharedContent } from "./controller/SharedContentController";
12
+ export { Exercise, TriggerAction } from "./controller/ExerciseController";
12
13
  export { Message, OnLLMResponse, ToolInvocation } from "./controller/AIController";
13
14
  export { MacroAccomplishmentPayload, MicroAccomplishmentPayload } from "../plugin/AccomplishmentHandler";
14
15
  export { Tool } from "../fromRimori/PluginTypes";
@@ -167,35 +167,81 @@ export class Logger {
167
167
  private overrideConsoleMethods(): void {
168
168
  // Override console.log
169
169
  console.log = (...args: any[]) => {
170
- this.originalConsole.log(...args);
170
+ const { location, style } = this.getCallerLocation();
171
+ this.originalConsole.log(location, style, ...args);
171
172
  this.handleConsoleCall('info', args);
172
173
  };
173
174
 
174
175
  // Override console.info
175
176
  console.info = (...args: any[]) => {
176
- this.originalConsole.info(...args);
177
+ const { location, style } = this.getCallerLocation();
178
+ this.originalConsole.info(location, style, ...args);
177
179
  this.handleConsoleCall('info', args);
178
180
  };
179
181
 
180
182
  // Override console.warn
181
183
  console.warn = (...args: any[]) => {
182
- this.originalConsole.warn(...args);
184
+ const { location, style } = this.getCallerLocation();
185
+ this.originalConsole.warn(location, style, ...args);
183
186
  this.handleConsoleCall('warn', args);
184
187
  };
185
188
 
186
189
  // Override console.error
187
190
  console.error = (...args: any[]) => {
188
- this.originalConsole.error(...args);
191
+ const { location, style } = this.getCallerLocation();
192
+ this.originalConsole.error(location, style, ...args);
189
193
  this.handleConsoleCall('error', args);
190
194
  };
191
195
 
192
196
  // Override console.debug
193
197
  console.debug = (...args: any[]) => {
194
- this.originalConsole.debug(...args);
198
+ const { location, style } = this.getCallerLocation();
199
+ this.originalConsole.debug(location, style, ...args);
195
200
  this.handleConsoleCall('debug', args);
196
201
  };
197
202
  }
198
203
 
204
+ /**
205
+ * Get caller information from stack trace.
206
+ * @returns Object with location string and CSS style, or empty values for production
207
+ */
208
+ private getCallerLocation(): { location: string; style: string } {
209
+ const emptyResult = { location: "", style: "" };
210
+ const style = "color: #0063A2; font-weight: bold;";
211
+
212
+ if (this.isProduction) return emptyResult;
213
+
214
+ try {
215
+ const stack = new Error().stack;
216
+ if (!stack) return emptyResult;
217
+
218
+ const stackLines = stack.split('\n');
219
+ // Skip the first 3 lines: Error, getCallerLocation, overrideConsoleMethods wrapper
220
+ const callerLine = stackLines[3];
221
+
222
+ if (!callerLine) return emptyResult;
223
+
224
+ // Extract file name and line number from stack trace
225
+ // Format: "at functionName (file:line:column)" or "at file:line:column"
226
+ const match = callerLine.match(/(?:at\s+.*?\s+\()?([^/\\(]+\.(?:ts|tsx|js|jsx)):(\d+):(\d+)\)?/);
227
+
228
+ if (match) {
229
+ const [, fileName, lineNumber] = match;
230
+ return { style, location: `%c[${fileName}:${lineNumber}]` };
231
+ }
232
+
233
+ // Fallback: try to extract just the file name
234
+ const simpleMatch = callerLine.match(/([^/\\]+\.(?:ts|tsx|js|jsx))/);
235
+ if (simpleMatch) {
236
+ return { style, location: `%c[${simpleMatch[1]}]` };
237
+ }
238
+
239
+ return emptyResult;
240
+ } catch (error) {
241
+ return emptyResult;
242
+ }
243
+ }
244
+
199
245
  /**
200
246
  * Track mouse position for screenshot context.
201
247
  */
@@ -226,9 +272,14 @@ export class Logger {
226
272
  }
227
273
 
228
274
  // Convert console arguments to message and data
229
- const message = args.map(arg =>
230
- typeof arg === 'object' ? JSON.stringify(arg) : String(arg)
231
- ).join(' ');
275
+ const message = args.map(arg => {
276
+ if (typeof arg !== "object") return arg;
277
+ try {
278
+ return JSON.stringify(arg);
279
+ } catch (error: any) {
280
+ return "Error adding object to log: " + error.message + " " + String(arg);
281
+ }
282
+ }).join(' ');
232
283
 
233
284
  const data = args.length > 1 ? args.slice(1) : undefined;
234
285
 
@@ -6,16 +6,18 @@ import { generateObject, ObjectRequest } from "../core/controller/ObjectControll
6
6
  import { SettingsController, UserInfo } from "../core/controller/SettingsController";
7
7
  import { SharedContent, SharedContentController, SharedContentFilter, SharedContentObjectRequest } from "../core/controller/SharedContentController";
8
8
  import { getSTTResponse, getTTSResponse } from "../core/controller/VoiceController";
9
+ import { ExerciseController, CreateExerciseParams } from "../core/controller/ExerciseController";
9
10
  import { EventBus, EventBusMessage, EventHandler, EventPayload } from "../fromRimori/EventBus";
10
11
  import { ActivePlugin, MainPanelAction, Plugin, Tool } from "../fromRimori/PluginTypes";
11
12
  import { AccomplishmentHandler, AccomplishmentPayload } from "./AccomplishmentHandler";
12
13
  import { PluginController, RimoriInfo } from "./PluginController";
14
+ import { ClientServerOptions } from "@supabase/postgrest-js/dist/cjs/types/common/common";
13
15
 
14
16
 
15
17
  interface Db {
16
18
  from: {
17
- <TableName extends string & keyof GenericSchema['Tables'], Table extends GenericSchema['Tables'][TableName]>(relation: TableName): PostgrestQueryBuilder<GenericSchema, Table, TableName>;
18
- <ViewName extends string & keyof GenericSchema['Views'], View extends GenericSchema['Views'][ViewName]>(relation: ViewName): PostgrestQueryBuilder<GenericSchema, View, ViewName>;
19
+ <TableName extends string & keyof GenericSchema['Tables'], Table extends GenericSchema['Tables'][TableName]>(relation: TableName): PostgrestQueryBuilder<ClientServerOptions, GenericSchema, Table, TableName>;
20
+ <ViewName extends string & keyof GenericSchema['Views'], View extends GenericSchema['Views'][ViewName]>(relation: ViewName): PostgrestQueryBuilder<ClientServerOptions, GenericSchema, View, ViewName>;
19
21
  };
20
22
  // storage: SupabaseClient["storage"];
21
23
 
@@ -72,6 +74,7 @@ export class RimoriClient {
72
74
  private pluginController: PluginController;
73
75
  private settingsController: SettingsController;
74
76
  private sharedContentController: SharedContentController;
77
+ private exerciseController: ExerciseController;
75
78
  private accomplishmentHandler: AccomplishmentHandler;
76
79
  private rimoriInfo: RimoriInfo;
77
80
  public plugin: PluginInterface;
@@ -83,16 +86,18 @@ export class RimoriClient {
83
86
  this.pluginController = pluginController;
84
87
  this.settingsController = new SettingsController(supabase, info.pluginId);
85
88
  this.sharedContentController = new SharedContentController(this.superbase, this);
89
+ this.exerciseController = new ExerciseController(supabase, pluginController);
86
90
  this.accomplishmentHandler = new AccomplishmentHandler(info.pluginId);
87
91
 
88
92
  this.from = this.from.bind(this);
93
+ this.getTableName = this.getTableName.bind(this);
89
94
 
90
95
  this.db = {
91
96
  from: this.from,
92
97
  // storage: this.superbase.storage,
93
98
  // functions: this.superbase.functions,
94
99
  tablePrefix: info.tablePrefix,
95
- getTableName: this.getTableName.bind(this),
100
+ getTableName: this.getTableName,
96
101
  }
97
102
  this.plugin = {
98
103
  pluginId: info.pluginId,
@@ -225,12 +230,12 @@ export class RimoriClient {
225
230
  private from<
226
231
  TableName extends string & keyof GenericSchema['Tables'],
227
232
  Table extends GenericSchema['Tables'][TableName]
228
- >(relation: TableName): PostgrestQueryBuilder<GenericSchema, Table, TableName>
233
+ >(relation: TableName): PostgrestQueryBuilder<ClientServerOptions, GenericSchema, Table, TableName>
229
234
  private from<
230
235
  ViewName extends string & keyof GenericSchema['Views'],
231
236
  View extends GenericSchema['Views'][ViewName]
232
- >(relation: ViewName): PostgrestQueryBuilder<GenericSchema, View, ViewName>
233
- private from(relation: string): PostgrestQueryBuilder<GenericSchema, any, any> {
237
+ >(relation: ViewName): PostgrestQueryBuilder<ClientServerOptions, GenericSchema, View, ViewName>
238
+ private from(relation: string): PostgrestQueryBuilder<ClientServerOptions, GenericSchema, any, any> {
234
239
  return this.superbase.from(this.getTableName(relation));
235
240
  }
236
241
 
@@ -376,4 +381,33 @@ export class RimoriClient {
376
381
  }
377
382
  }
378
383
  }
384
+
385
+ public exercise = {
386
+ /**
387
+ * Fetches weekly exercises from the weekly_exercises view.
388
+ * Shows exercises for the current week that haven't expired.
389
+ * @returns Array of exercise objects.
390
+ */
391
+ view: async () => {
392
+ return this.exerciseController.viewWeeklyExercises();
393
+ },
394
+
395
+ /**
396
+ * Creates a new exercise via the backend API.
397
+ * @param params Exercise creation parameters.
398
+ * @returns Created exercise object.
399
+ */
400
+ add: async (params: CreateExerciseParams) => {
401
+ return this.exerciseController.addExercise(params);
402
+ },
403
+
404
+ /**
405
+ * Deletes an exercise via the backend API.
406
+ * @param id The exercise ID to delete.
407
+ * @returns Success status.
408
+ */
409
+ delete: async (id: string) => {
410
+ return this.exerciseController.deleteExercise(id);
411
+ },
412
+ }
379
413
  }
@@ -1,6 +0,0 @@
1
- import React from 'react';
2
- /**
3
- * Example component demonstrating Logger usage in a React component.
4
- * Shows how console methods are automatically captured by the Logger.
5
- */
6
- export declare const LoggerExample: React.FC;
@@ -1,79 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
- import { useState } from 'react';
12
- import { useLogging, useLogger } from '../hooks/UseLogger';
13
- /**
14
- * Example component demonstrating Logger usage in a React component.
15
- * Shows how console methods are automatically captured by the Logger.
16
- */
17
- export const LoggerExample = () => {
18
- const [logMessage, setLogMessage] = useState('Hello from Logger Example');
19
- const [logData, setLogData] = useState('{"key": "value"}');
20
- // Initialize the logger - this overrides console methods globally
21
- const logger = useLogger(process.env.NODE_ENV === 'production');
22
- // Get logging utilities
23
- const { sendAllLogs, getStats, clearLogs, exportLogs, sendLogsByLevel } = useLogging(process.env.NODE_ENV === 'production');
24
- const handleConsoleLog = () => {
25
- // This will be automatically captured by the Logger
26
- console.log(logMessage, logData ? JSON.parse(logData) : '');
27
- };
28
- const handleConsoleInfo = () => {
29
- // This will be automatically captured by the Logger
30
- console.info(logMessage, logData ? JSON.parse(logData) : '');
31
- };
32
- const handleConsoleWarn = () => {
33
- // This will be automatically captured by the Logger and include screenshot + mouse position
34
- console.warn(logMessage, logData ? JSON.parse(logData) : '');
35
- };
36
- const handleConsoleError = () => {
37
- // This will be automatically captured by the Logger and include screenshot + mouse position
38
- console.error(logMessage, logData ? JSON.parse(logData) : '');
39
- };
40
- const handleConsoleDebug = () => {
41
- // This will be automatically captured by the Logger
42
- console.debug(logMessage, logData ? JSON.parse(logData) : '');
43
- };
44
- const handleSendLogs = () => __awaiter(void 0, void 0, void 0, function* () {
45
- yield sendAllLogs();
46
- alert('Logs sent to Rimori!');
47
- });
48
- const handleGetStats = () => {
49
- const stats = getStats();
50
- alert(`Log Statistics:\nTotal: ${stats.total}\nDebug: ${stats.byLevel.debug}\nInfo: ${stats.byLevel.info}\nWarn: ${stats.byLevel.warn}\nError: ${stats.byLevel.error}`);
51
- };
52
- const handleClearLogs = () => {
53
- clearLogs();
54
- alert('Logs cleared!');
55
- };
56
- const handleExportLogs = () => {
57
- const exportedLogs = exportLogs();
58
- const blob = new Blob([exportedLogs], { type: 'application/json' });
59
- const url = URL.createObjectURL(blob);
60
- const a = document.createElement('a');
61
- a.href = url;
62
- a.download = 'rimori-logs.json';
63
- a.click();
64
- URL.revokeObjectURL(url);
65
- };
66
- const handleSendErrorLogs = () => __awaiter(void 0, void 0, void 0, function* () {
67
- yield sendLogsByLevel('error');
68
- alert('Error logs sent to Rimori!');
69
- });
70
- const handleTriggerError = () => {
71
- // This will trigger an unhandled error that the logger will catch via console.error override
72
- throw new Error('This is a test error for the logger');
73
- };
74
- const handleTriggerPromiseRejection = () => {
75
- // This will trigger an unhandled promise rejection that the logger will catch
76
- Promise.reject(new Error('This is a test promise rejection'));
77
- };
78
- return (_jsxs("div", { style: { padding: '20px', maxWidth: '800px' }, children: [_jsx("h2", { children: "Logger Example - Console Override Demo" }), _jsxs("div", { style: { marginBottom: '20px', padding: '15px', backgroundColor: '#e3f2fd', borderRadius: '5px' }, children: [_jsx("h4", { children: "\uD83C\uDFAF Key Feature: Console Methods Override" }), _jsxs("p", { children: ["The Logger automatically overrides ", _jsx("code", { children: "console.log" }), ", ", _jsx("code", { children: "console.info" }), ",", _jsx("code", { children: "console.warn" }), ", ", _jsx("code", { children: "console.error" }), ", and ", _jsx("code", { children: "console.debug" }), " globally. All console calls are automatically captured and stored with context information."] })] }), _jsx("div", { style: { marginBottom: '20px' }, children: _jsxs("label", { children: ["Log Message:", _jsx("input", { type: "text", value: logMessage, onChange: (e) => setLogMessage(e.target.value), placeholder: "Enter log message", style: { width: '100%', marginTop: '5px' } })] }) }), _jsx("div", { style: { marginBottom: '20px' }, children: _jsxs("label", { children: ["Log Data (JSON):", _jsx("textarea", { value: logData, onChange: (e) => setLogData(e.target.value), placeholder: '{"key": "value"}', style: { width: '100%', height: '60px', marginTop: '5px' } })] }) }), _jsxs("div", { style: { marginBottom: '20px' }, children: [_jsx("h3", { children: "Console Method Calls (Automatically Captured)" }), _jsx("button", { onClick: handleConsoleLog, style: { margin: '5px' }, children: "console.log()" }), _jsx("button", { onClick: handleConsoleInfo, style: { margin: '5px' }, children: "console.info()" }), _jsx("button", { onClick: handleConsoleWarn, style: { margin: '5px', backgroundColor: '#ff9800' }, children: "console.warn() \uD83D\uDCF8" }), _jsx("button", { onClick: handleConsoleError, style: { margin: '5px', backgroundColor: '#f44336' }, children: "console.error() \uD83D\uDCF8" }), _jsx("button", { onClick: handleConsoleDebug, style: { margin: '5px' }, children: "console.debug()" })] }), _jsxs("div", { style: { marginBottom: '20px' }, children: [_jsx("h3", { children: "Log Management" }), _jsx("button", { onClick: handleSendLogs, style: { margin: '5px' }, children: "Send All Logs to Rimori" }), _jsx("button", { onClick: handleSendErrorLogs, style: { margin: '5px', backgroundColor: '#f44336' }, children: "Send Error Logs Only" }), _jsx("button", { onClick: handleGetStats, style: { margin: '5px' }, children: "Get Log Statistics" }), _jsx("button", { onClick: handleClearLogs, style: { margin: '5px' }, children: "Clear Logs" }), _jsx("button", { onClick: handleExportLogs, style: { margin: '5px' }, children: "Export Logs (JSON)" })] }), _jsxs("div", { style: { marginBottom: '20px' }, children: [_jsx("h3", { children: "Test Error Handling" }), _jsx("button", { onClick: handleTriggerError, style: { margin: '5px', backgroundColor: '#ff6b6b' }, children: "Trigger Unhandled Error" }), _jsx("button", { onClick: handleTriggerPromiseRejection, style: { margin: '5px', backgroundColor: '#ff6b6b' }, children: "Trigger Promise Rejection" })] }), _jsxs("div", { style: { marginTop: '30px', padding: '15px', backgroundColor: '#f5f5f5', borderRadius: '5px' }, children: [_jsx("h4", { children: "\uD83D\uDCCB How It Works:" }), _jsxs("ul", { children: [_jsxs("li", { children: [_jsx("strong", { children: "Automatic Capture:" }), " All console calls are automatically captured by the Logger"] }), _jsxs("li", { children: [_jsx("strong", { children: "No Manual Logging:" }), " Just use ", _jsx("code", { children: "console.log()" }), " as usual - no need to call Logger methods"] }), _jsxs("li", { children: [_jsx("strong", { children: "Production Filtering:" }), " In production, only warnings and errors show in console, but all are stored"] }), _jsxs("li", { children: [_jsx("strong", { children: "Screenshot Capture:" }), " Errors and warnings automatically capture screenshots + mouse position"] }), _jsxs("li", { children: [_jsx("strong", { children: "Browser Context:" }), " Each log includes URL, user agent, screen resolution, etc."] }), _jsxs("li", { children: [_jsx("strong", { children: "Rimori Integration:" }), " Logs can be sent to Rimori for centralized logging"] })] }), _jsx("h4", { children: "\uD83C\uDFAF Screenshot & Mouse Position:" }), _jsxs("p", { children: ["When you call ", _jsx("code", { children: "console.warn()" }), " or ", _jsx("code", { children: "console.error()" }), ", the Logger automatically:"] }), _jsxs("ul", { children: [_jsx("li", { children: "Captures a screenshot of the current page (if html2canvas is available)" }), _jsx("li", { children: "Records the current mouse position (x, y coordinates)" }), _jsx("li", { children: "Includes timestamp for both screenshot and mouse position" })] })] }), _jsxs("div", { style: { marginTop: '20px', padding: '15px', backgroundColor: '#fff3e0', borderRadius: '5px' }, children: [_jsx("h4", { children: "\uD83D\uDD27 Setup Required:" }), _jsx("p", { children: "To enable screenshot capture, include html2canvas in your plugin:" }), _jsx("pre", { style: { backgroundColor: '#f5f5f5', padding: '10px', borderRadius: '3px' }, children: `<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>` })] })] }));
79
- };
File without changes
@@ -1 +0,0 @@
1
- "use strict";
@@ -1,30 +0,0 @@
1
- import { Logger } from '../plugin/Logger';
2
- /**
3
- * Hook for initializing the Logger singleton with automatic Rimori client integration.
4
- * This hook should be called once at the top level of your plugin.
5
- * @param isProduction - Whether the environment is production
6
- * @returns Logger instance
7
- */
8
- export declare function useLogger(isProduction: boolean): Logger;
9
- /**
10
- * Hook that provides a logger with automatic Rimori client integration.
11
- * This hook should be used after the plugin is fully initialized.
12
- * @param isProduction - Whether the environment is production
13
- * @returns Logger instance with Rimori client set
14
- */
15
- export declare function useLoggerWithRimori(isProduction: boolean): Logger;
16
- /**
17
- * Hook for managing logs with simplified interface.
18
- * Since console methods are overridden globally, this provides utility functions for log management.
19
- * @param isProduction - Whether the environment is production
20
- * @returns Object with log management methods
21
- */
22
- export declare function useLogging(isProduction: boolean): {
23
- sendAllLogs: () => any;
24
- sendRecentLogs: (count: number) => any;
25
- sendLogsByLevel: (level: "debug" | "info" | "warn" | "error") => any;
26
- getStats: () => any;
27
- exportLogs: () => any;
28
- clearLogs: () => any;
29
- restoreConsole: () => any;
30
- };
@@ -1,122 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { useEffect, useRef } from 'react';
11
- import { Logger } from '../plugin/Logger';
12
- import { usePlugin } from './UseChatHook';
13
- /**
14
- * Hook for initializing the Logger singleton with automatic Rimori client integration.
15
- * This hook should be called once at the top level of your plugin.
16
- * @param isProduction - Whether the environment is production
17
- * @returns Logger instance
18
- */
19
- export function useLogger(isProduction) {
20
- const { event } = usePlugin();
21
- const loggerRef = useRef(null);
22
- useEffect(() => {
23
- // Initialize logger if not already done
24
- if (!loggerRef.current) {
25
- loggerRef.current = Logger.getInstance(isProduction);
26
- }
27
- // Set up automatic log transmission on certain events
28
- const handleBeforeUnload = () => {
29
- if (loggerRef.current) {
30
- // Send recent logs before page unload
31
- loggerRef.current.sendRecentLogs(50);
32
- }
33
- };
34
- const handleError = (event) => {
35
- // The logger will automatically capture this via console.error override
36
- console.error('Unhandled error', {
37
- message: event.message,
38
- filename: event.filename,
39
- lineno: event.lineno,
40
- colno: event.colno,
41
- error: event.error
42
- });
43
- };
44
- const handleUnhandledRejection = (event) => {
45
- // The logger will automatically capture this via console.error override
46
- console.error('Unhandled promise rejection', {
47
- reason: event.reason
48
- });
49
- };
50
- // Add event listeners
51
- window.addEventListener('beforeunload', handleBeforeUnload);
52
- window.addEventListener('error', handleError);
53
- window.addEventListener('unhandledrejection', handleUnhandledRejection);
54
- // Cleanup
55
- return () => {
56
- window.removeEventListener('beforeunload', handleBeforeUnload);
57
- window.removeEventListener('error', handleError);
58
- window.removeEventListener('unhandledrejection', handleUnhandledRejection);
59
- };
60
- }, [isProduction]);
61
- // Return a proxy that ensures the logger is available
62
- return new Proxy({}, {
63
- get(target, prop) {
64
- if (!loggerRef.current) {
65
- throw new Error('Logger not initialized');
66
- }
67
- return loggerRef.current[prop];
68
- }
69
- });
70
- }
71
- /**
72
- * Hook that provides a logger with automatic Rimori client integration.
73
- * This hook should be used after the plugin is fully initialized.
74
- * @param isProduction - Whether the environment is production
75
- * @returns Logger instance with Rimori client set
76
- */
77
- export function useLoggerWithRimori(isProduction) {
78
- const logger = useLogger(isProduction);
79
- const { event } = usePlugin();
80
- useEffect(() => {
81
- // Set up Rimori client integration when the hook is used
82
- const setupRimoriIntegration = () => __awaiter(this, void 0, void 0, function* () {
83
- try {
84
- // Get the plugin ID from the event bus context
85
- // This is a simplified approach - in practice, you'd get this from your plugin context
86
- const pluginId = 'your-plugin-id'; // This should come from your plugin configuration
87
- // Set up a listener for log transmission
88
- event.on('global.logger.sendLogs', (data) => __awaiter(this, void 0, void 0, function* () {
89
- if (data.pluginId === pluginId) {
90
- yield logger.sendAllLogs();
91
- }
92
- }));
93
- }
94
- catch (error) {
95
- console.warn('Failed to set up Logger with Rimori integration:', error);
96
- }
97
- });
98
- setupRimoriIntegration();
99
- }, [event, logger]);
100
- return logger;
101
- }
102
- /**
103
- * Hook for managing logs with simplified interface.
104
- * Since console methods are overridden globally, this provides utility functions for log management.
105
- * @param isProduction - Whether the environment is production
106
- * @returns Object with log management methods
107
- */
108
- export function useLogging(isProduction) {
109
- const logger = useLogger(isProduction);
110
- return {
111
- // Log management
112
- sendAllLogs: () => logger.sendAllLogs(),
113
- sendRecentLogs: (count) => logger.sendRecentLogs(count),
114
- sendLogsByLevel: (level) => logger.sendLogsByLevel(level),
115
- // Statistics and export
116
- getStats: () => logger.getStats(),
117
- exportLogs: () => logger.exportLogs(),
118
- clearLogs: () => logger.clearLogs(),
119
- // Console restoration (use with caution)
120
- restoreConsole: () => logger.restoreConsole()
121
- };
122
- }
@@ -1,16 +0,0 @@
1
- /**
2
- * Example of how to integrate the Logger into a plugin's main entry point.
3
- * This shows the complete setup process.
4
- */
5
- export declare function initializePluginWithLogger(): Promise<void>;
6
- export declare function exampleComponentUsage(): {
7
- handleUserAction: () => void;
8
- handleApiError: (error: Error) => void;
9
- handleDeprecatedFeature: () => void;
10
- };
11
- export declare function exampleLogManagement(): {
12
- sendLogsToRimori: () => Promise<void>;
13
- getLogStatistics: () => any;
14
- exportLogsForDebugging: () => void;
15
- clearOldLogs: () => void;
16
- };