@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.
- package/.prettierignore +35 -0
- package/dist/cli/scripts/release/release-file-upload.js +1 -1
- package/dist/cli/types/DatabaseTypes.d.ts +2 -2
- package/dist/components/ai/Avatar.js +4 -2
- package/dist/components/ai/EmbeddedAssistent/TTS/Player.js +1 -1
- package/dist/core/controller/AIController.js +9 -7
- package/dist/core/controller/ExerciseController.d.ts +52 -0
- package/dist/core/controller/ExerciseController.js +73 -0
- package/dist/core/core.d.ts +1 -0
- package/dist/plugin/Logger.d.ts +5 -0
- package/dist/plugin/Logger.js +56 -6
- package/dist/plugin/RimoriClient.d.ts +28 -2
- package/dist/plugin/RimoriClient.js +30 -1
- package/eslint.config.js +53 -0
- package/package.json +9 -2
- package/prettier.config.js +8 -0
- package/src/cli/scripts/release/release-file-upload.ts +1 -1
- package/src/cli/types/DatabaseTypes.ts +17 -10
- package/src/components/ai/Avatar.tsx +3 -2
- package/src/components/ai/EmbeddedAssistent/TTS/Player.ts +176 -176
- package/src/core/controller/AIController.ts +36 -34
- package/src/core/controller/ExerciseController.ts +105 -0
- package/src/core/core.ts +1 -0
- package/src/plugin/Logger.ts +59 -8
- package/src/plugin/RimoriClient.ts +40 -6
- package/dist/components/LoggerExample.d.ts +0 -6
- package/dist/components/LoggerExample.js +0 -79
- package/dist/core/controller/AudioController.d.ts +0 -0
- package/dist/core/controller/AudioController.js +0 -1
- package/dist/hooks/UseLogger.d.ts +0 -30
- package/dist/hooks/UseLogger.js +0 -122
- package/dist/plugin/LoggerExample.d.ts +0 -16
- package/dist/plugin/LoggerExample.js +0 -140
- package/dist/utils/audioFormats.d.ts +0 -26
- 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";
|
package/src/plugin/Logger.ts
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
231
|
-
|
|
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
|
|
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,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
|
-
};
|
package/dist/hooks/UseLogger.js
DELETED
|
@@ -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
|
-
};
|