action-lens 1.0.101 → 1.0.103
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/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +135 -76
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +135 -76
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/player.ts","../src/utils/index.ts","../src/record.ts"],"sourcesContent":["export * from \"./player\";\nexport * from \"./record\";\nimport \"./style.css\";\n","import {\n doc,\n collection,\n setDoc,\n addDoc,\n where,\n query,\n getDocs,\n orderBy,\n Firestore,\n getDoc,\n limit,\n} from \"firebase/firestore\";\nimport {\n ActionRecord,\n ActionRecordSession,\n AuthUser,\n Project,\n Session,\n User,\n} from \"@ism-tech/actionlens-type\";\nimport { Replayer } from \"rrweb\";\nimport { db } from \"./utils\"; // dbのインポートパスを適宜変更してください\n\nimport { unpack } from \"@rrweb/packer\";\n\nexport class ActionLensPlayer {\n replayer: Replayer | null = null;\n overlayContainer: HTMLElement | null = null;\n playerStatus: \"playing\" | \"paused\" | \"stopped\" = \"stopped\";\n targetDivId: string;\n db: Firestore;\n prefix: string;\n userId: string | null = null;\n projectId: string | null = null;\n currentTime: number = 0; // 現在の再生時間\n recordTime: number = 0; // レコードの時間\n totalTime: number = 0; // 再生中の時間を保持するための変数\n user: AuthUser | null = null; // ユーザーデータを保持するための変数\n private setIntervalId: NodeJS.Timeout | null = null; // setTimeoutのIDを保持するための変数\n width: number = 0; // プレイヤーの幅\n height: number = 0; // プレイヤーの高さ\n sessions: (ActionRecordSession & { userData: User<\"customer\"> })[] = []; // セッションのリスト\n currentUrl: string | null = null; // 現在のURLを保持するための変数\n startTime: number = 0; // セッションの開始時間\n sessionInfo: ActionRecordSession | null = null; // セッション情報を保持するための変数\n constructor(\n userId: string,\n targetDivId: string,\n\n _db: Firestore = db,\n prefix: string = \"\"\n ) {\n // 初期化処理が必要であればここに記述\n this.userId = userId;\n this.targetDivId = targetDivId;\n this.db = _db;\n this.prefix = prefix;\n this.initialize(userId);\n }\n\n async initialize(userId: string) {\n const user = await getDoc(doc(this.db, `${this.prefix}authUser`, userId));\n if (!user.exists()) {\n throw new Error(`User with ID ${userId} does not exist.`);\n }\n const userData = user.data() as AuthUser;\n this.user = userData; // ユーザーデータを保持\n this.projectId = userData.projectIds?.[0] || \"\"; // プロジェクトIDを取得\n if (!this.projectId) {\n throw new Error(`Project ID for user ${userId} does not exist.`);\n }\n }\n\n async replayRrwebSession(sessionId: string): Promise<any[]> {\n try {\n // 1. Firestoreからデータを取得\n\n const q = query(\n collection(this.db, `${this.prefix}ActionRecord`),\n where(\"sessionId\", \"==\", sessionId),\n orderBy(\"timeStamp\", \"asc\")\n );\n\n const querySnapshot = await getDocs(q);\n const events = querySnapshot.docs.flatMap((doc) => {\n const data = doc.data() as ActionRecord;\n return data.rrwebRecord\n ? JSON.parse(data.rrwebRecord)\n : data.rrwebRecords\n ? data.rrwebRecords?.map((r) => JSON.parse(r)) || []\n : [];\n });\n\n if (events.length === 0) {\n console.warn(\n `セッションID ${sessionId} のデータが見つかりませんでした。`\n );\n return [];\n }\n\n const targetDiv = document.getElementById(this.targetDivId);\n if (!targetDiv) {\n throw new Error(\n `ID ${this.targetDivId} のdiv要素が見つかりませんでした。`\n );\n }\n\n // クラスを追加\n targetDiv.classList.add(\"replayer-container\");\n\n // 3. Replayerを初期化\n this.replayer = new Replayer(events, {\n unpackFn: unpack,\n root: targetDiv,\n UNSAFE_replayCanvas: false,\n props: {\n autoPlay: true,\n speed: 1,\n mouseTail: true,\n },\n className: \"_replayer-canvas\",\n } as any);\n\n this.width = this.replayer.wrapper.clientWidth;\n this.height = this.replayer.wrapper.clientHeight;\n\n // 4. カスタムイベントのリスナーを追加\n this.replayer.on(\"custom-event\", (event: any) => {\n this.handleCustomEvent(event);\n });\n\n this.replayer.on(\"finish\", () => {\n this.replayer?.pause(0);\n this.playerStatus = \"stopped\";\n this.currentTime = this.replayer?.getCurrentTime() || 0;\n this.endTimeoutTimeline();\n });\n this.replayer.on(\"event-cast\", (event: any) => {\n console.log(\"Event cast:\", event);\n if (event.type === 4 && event.data.href) {\n this.currentUrl = event.data.href;\n }\n });\n this.replayer.on(\"resize\", (e) => {\n const { width, height } = e as { width: number; height: number };\n\n this.width = width;\n this.height = height;\n });\n\n const { totalTime } = this.replayer.getMetaData();\n this.totalTime = totalTime;\n\n // iframeのスタイルを調整\n const iframes = targetDiv.querySelectorAll(\"iframe\");\n iframes.forEach((iframe) => {\n (iframe as HTMLElement).style.transform = \"translate(-50%, -50%)\";\n (iframe as HTMLElement).style.position = \"absolute\";\n (iframe as HTMLElement).style.left = \"50%\";\n (iframe as HTMLElement).style.top = \"50%\";\n });\n // replayer-mouse-tailにposition: absolute; を追加\n const mouseTailElements = document.querySelectorAll(\n \".replayer-mouse-tail\"\n );\n mouseTailElements.forEach((element) => {\n (element as HTMLElement).style.position = \"absolute\";\n (element as HTMLElement).style.left = \"50%\";\n (element as HTMLElement).style.top = \"50%\";\n (element as HTMLElement).style.transform = \"translate(-50%, -50%)\";\n (element as HTMLElement).style.zIndex = \"1000\"; // z-indexを追加\n });\n\n // 5. 再生開始\n\n this.replayer.play();\n this.playerStatus = \"playing\";\n\n this.setTimeoutTimeline();\n return events.map((e) => unpack(e));\n } catch (error) {\n console.error(\"再生エラー:\", error);\n throw error;\n }\n }\n\n // カスタムイベントを処理\n private handleCustomEvent(event: any) {\n if (!event.data || !event.data.type) return;\n\n const { timestamp } = event;\n const timeString = new Date(timestamp).toISOString();\n\n switch (event.data.type) {\n case \"console\":\n const { method, args } = event.data;\n this.displayEvent(\n `[${timeString}] Console ${method}: ${args.join(\", \")}`,\n \"console\"\n );\n\n break;\n case \"navigation\":\n const { url } = event.data;\n this.currentUrl = url;\n this.displayEvent(`[${timeString}] Navigation to ${url}`, \"navigation\");\n break;\n case \"performance\":\n const { name, entryType, duration } = event.data;\n this.displayEvent(\n `[${timeString}] Performance ${entryType}: ${name} (${duration}ms)`,\n \"performance\"\n );\n break;\n default:\n }\n }\n\n // イベントをオーバーレイに表示\n private displayEvent(message: string, eventType: string) {\n if (!this.overlayContainer) return;\n\n const eventDiv = document.createElement(\"div\");\n eventDiv.style.padding = \"5px\";\n eventDiv.style.borderBottom = \"1px solid rgba(255, 255, 255, 0.2)\";\n\n // イベントタイプに応じた色\n const colors: { [key: string]: string } = {\n console: \"#00cc00\",\n navigation: \"#3399ff\",\n performance: \"#ff9900\",\n };\n eventDiv.style.color = colors[eventType] || \"white\";\n\n eventDiv.innerText = message;\n this.overlayContainer.appendChild(eventDiv);\n\n // 最新のイベントが表示されるようスクロール\n this.overlayContainer.scrollTop = this.overlayContainer.scrollHeight;\n\n // 5秒後にフェードアウト\n setTimeout(() => {\n eventDiv.style.transition = \"opacity 1s\";\n eventDiv.style.opacity = \"0\";\n setTimeout(() => eventDiv.remove(), 1000);\n }, 5000);\n }\n setReplayTime(time: number) {\n if (this.replayer) {\n this.replayer.pause(time);\n this.currentTime = time;\n this.playerStatus = \"stopped\";\n }\n }\n\n setTimeoutTimeline() {\n this.setIntervalId = setInterval(() => {\n this.currentTime = this.replayer?.getCurrentTime() || 0;\n this.recordTime =\n Number(this.replayer?.getMetaData()?.startTime) + this.currentTime;\n }, 10);\n }\n endTimeoutTimeline() {\n if (this.setIntervalId) {\n clearTimeout(this.setIntervalId);\n this.setIntervalId = null;\n }\n }\n\n // 再生を停止\n stopReplay() {\n this.endTimeoutTimeline();\n if (this.replayer) {\n this.replayer.pause();\n this.playerStatus = \"stopped\";\n this.currentTime = this.replayer?.getCurrentTime() || 0;\n }\n }\n restartReplay() {\n this.setTimeoutTimeline();\n if (this.replayer) {\n const offset = this.replayer.getCurrentTime();\n\n this.replayer.play(offset);\n this.playerStatus = \"playing\";\n this.currentTime = this.replayer?.getCurrentTime() || 0;\n }\n }\n getCurrentTime() {\n if (this.replayer) {\n return this.replayer.getCurrentTime();\n }\n return 0;\n }\n\n resetReplayer() {\n this.endTimeoutTimeline();\n this.playerStatus = \"stopped\";\n this.currentTime = 0;\n\n if (this.replayer) {\n this.replayer.pause();\n this.replayer.destroy();\n this.replayer = null;\n }\n if (this.overlayContainer) {\n this.overlayContainer.remove();\n this.overlayContainer = null;\n }\n }\n async fetchProjectList() {\n try {\n if (!this.userId) {\n console.warn(\"User ID is not initialized.\");\n return [];\n }\n if (!this.user) {\n this.user = (\n await getDoc(doc(this.db, `${this.prefix}authUser`, this.userId))\n ).data() as AuthUser | null;\n if (!this.user) {\n console.warn(`User with ID ${this.userId} does not exist.`);\n\n return [];\n }\n }\n console.log(\"fetchProjectList\", this.user);\n const projectIds = this.user.projectIds || [];\n if (projectIds.length === 0) {\n console.warn(\"No project IDs found for the user.\");\n return [];\n }\n const promise = projectIds.flatMap(async (projectId) => {\n const projectDoc = await getDoc(\n doc(this.db, `${this.prefix}project`, projectId)\n );\n if (!projectDoc.exists()) {\n console.warn(`Project with ID ${projectId} does not exist.`);\n return null;\n }\n return projectDoc.data() as Project;\n });\n const projectPromises: (Project | null)[] = await Promise.all(promise);\n return projectPromises.filter((project) => project !== null);\n } catch (e) {\n console.error(\"プロジェクトリストの取得エラー:\", e);\n throw e;\n }\n }\n\n async fetchSessionList(projectId: string, limitNum: number = 20) {\n try {\n const q = query(\n collection(this.db, `${this.prefix}ActionRecordSession`),\n where(\"projectId\", \"==\", projectId),\n where(\"recordTime\", \">=\", 10),\n orderBy(\"startTime\", \"desc\"),\n limit(limitNum)\n );\n const usersStore: { [userId: string]: User<\"customer\"> } = {};\n\n const querySnapshot = await getDocs(q);\n const promise = querySnapshot.docs.map(async (_doc) => {\n const data = _doc.data() as ActionRecordSession;\n if (!usersStore[data.userId]) {\n usersStore[data.userId] = (\n await getDoc(doc(this.db, `${this.prefix}user`, data.userId))\n ).data() as User<\"customer\">;\n }\n\n return { ...data, userData: usersStore[data.userId] };\n });\n const sessions: (ActionRecordSession & { userData: User<\"customer\"> })[] =\n await Promise.all(promise);\n console.log(sessions);\n this.sessions = sessions;\n return sessions;\n } catch (error) {\n console.error(\"セッションリストの取得エラー:\", error);\n throw error;\n }\n }\n}\n","import { initializeApp } from \"firebase/app\";\nimport { getFirestore } from \"firebase/firestore\";\n\nexport const firebaseConfig = {\n apiKey: \"AIzaSyCxreoOZivnjFIh2mJ6WXjS3ieQ11wsDW8\",\n authDomain: \"actionlens-b14ae.firebaseapp.com\",\n projectId: \"actionlens-b14ae\",\n storageBucket: \"actionlens-b14ae.firebasestorage.app\",\n messagingSenderId: \"36086339210\",\n appId: \"1:36086339210:web:36e16e8778aadd8c58ff73\",\n};\n\n// Initialize Firebase\nexport const app = initializeApp(firebaseConfig);\n\nexport const db = getFirestore(app);\n","import { v4 as uuidv4 } from \"uuid\";\nimport { record, Replayer } from \"rrweb\";\nimport {\n Firestore,\n doc,\n setDoc,\n collection,\n getDoc,\n getFirestore,\n updateDoc,\n} from \"firebase/firestore\";\nimport {\n ActionRecord,\n ActionRecordSession,\n Project,\n User,\n} from \"@ism-tech/actionlens-type\";\nimport { db, app } from \"./utils/index\";\nimport { pack } from \"@rrweb/packer\";\nimport { httpsCallable, getFunctions } from \"firebase/functions\";\n\nconst functions = getFunctions(app);\n\nconst setSessionDetail = httpsCallable(functions, \"setSessionDetail\");\nexport class ActionLensRc {\n sessionId: string = uuidv4();\n stopFnForStore: any = null;\n userId: string | null = \"anonymous\"; // ユーザーIDはプロジェクトIDと組み合わせて一意にする\n db: Firestore | null = null;\n prefix: string = \"\";\n userData: User<\"customer\"> | null = null;\n projectId: string | null = null;\n projectData: Project | null = null;\n organizationId: string | null = null;\n originalUserId: string | null = null; // 元のユーザーID(外部システムのIDなど)\n userMeta: { name?: string; email?: string } = {};\n metaData: Record<string, any> = {};\n\n constructor() {\n this.db = db; // Firestoreの初期化\n }\n\n async init(\n projectId: string | null,\n _db: Firestore | null = null,\n prefix: string = \"\"\n ) {\n try {\n if (!projectId) {\n console.error(\"projectIdがNULLです\");\n return;\n }\n this.projectId = projectId;\n\n this.prefix = prefix;\n\n if (!this.db && _db) {\n console.error(\"Firestoreが初期化されていません\");\n this.db = _db;\n }\n if (!this.db) {\n console.error(\"Firestoreが初期化されていません\");\n return;\n }\n\n if (!this.projectId) {\n console.error(\"projectIdが設定されていません\");\n return;\n }\n const _doc = await getDoc(\n doc(collection(this.db, `${this.prefix}project`), this.projectId)\n );\n this.projectData = _doc.data() as Project;\n const projectData = this.projectData;\n this.organizationId = projectData?.organizationId || \"\";\n\n if (!this.projectData) {\n await setDoc(\n doc(collection(this.db, `${this.prefix}project`), this.projectId),\n {\n id: this.projectId,\n name: this.projectId,\n organizationId: \"\",\n isActivate: false, // デフォルトでアクティブに設定\n createAt: new Date(),\n updateAt: new Date(),\n createdBy: this.originalUserId,\n updatedBy: this.originalUserId,\n } as Project,\n { merge: true }\n );\n\n console.warn(\"プロジェクトが存在しません\");\n return;\n }\n if (!this.projectData?.isActivate) {\n console.warn(\"プロジェクトは非アクティブです。録画を開始できません。\");\n return;\n }\n\n await this.startRrwebRecordingForStore();\n\n // this.startTimelineRecording();\n return;\n } catch (error) {\n console.error(\"初期化中にエラーが発生しました:\", error);\n return;\n }\n }\n\n async setUser(\n _userId: string | null,\n userMeta: { name: string; email: string },\n metaData: Record<string, any> = {}\n ) {\n if (!this.db) {\n console.error(\"Firestoreが初期化されていません\");\n return;\n }\n if (!this.projectData) {\n console.error(\"プロジェクトデータが設定されていません\");\n return;\n }\n this.originalUserId = _userId; // 元のユーザーIDを保存\n this.userMeta = userMeta;\n this.metaData = metaData;\n\n if (!_userId) {\n console.error(\"userIdがNULLです\");\n return;\n }\n\n this.userId = this.projectData.id + \"-\" + this.originalUserId;\n this.prefix = this.prefix;\n this.projectId = this.projectId;\n const user = await getDoc(\n doc(collection(this.db, `${this.prefix}user`), this.userId)\n );\n\n if (!this.db) {\n console.error(\"Firestoreが初期化されていません\");\n return;\n }\n\n const userData = user.data() as User<\"customer\">;\n\n if (!userData?.id || !user.exists()) {\n await setDoc(\n doc(\n collection(this.db, `${this.prefix}user`),\n this.projectData.id + \"-\" + this.originalUserId\n ),\n {\n ...(this.userMeta || {}),\n metaData: this.metaData,\n id: this.userId,\n originalUserId: this.originalUserId,\n type: \"customer\",\n organizationId: this.projectData?.organizationId || \"\",\n projectIds: [this.projectId],\n createAt: new Date(),\n updateAt: new Date(),\n createdBy: this.userId,\n updatedBy: this.userId,\n hidden: false,\n hiddenBy: \"\",\n } as User<\"customer\">,\n { merge: true }\n );\n this.userData = {\n ...(this.userMeta || {}),\n metaData: this.metaData,\n id: this.userId,\n originalUserId: this.originalUserId,\n type: \"customer\",\n organizationId: this.projectData?.organizationId || \"\",\n projectIds: [this.projectId],\n createAt: new Date(),\n updateAt: new Date(),\n createdBy: this.userId,\n updatedBy: this.userId,\n hidden: false,\n hiddenBy: \"\",\n } as User<\"customer\">;\n } else {\n this.userData = user.data() as User<\"customer\">;\n\n if (!this.userData?.projectIds?.includes(this.projectId || \"\")) {\n await setDoc(\n doc(\n collection(this.db, `${this.prefix}user`),\n this.projectData.id + \"-\" + this.originalUserId\n ),\n {\n projectIds: [...(this.userData?.projectIds || []), this.projectId],\n updateAt: new Date(),\n updatedBy: this.userId,\n } as Partial<User<\"customer\">>,\n { merge: true }\n );\n }\n\n if (this.userData?.organizationId !== this.projectData.organizationId) {\n await setDoc(\n doc(\n collection(this.db, `${this.prefix}user`),\n this.projectData.id + \"-\" + this.originalUserId\n ),\n {\n organizationId: this.projectData.organizationId\n ? this.projectData.organizationId\n : this.userData?.organizationId,\n updateAt: new Date(),\n updatedBy: this.userId,\n } as Partial<User<\"customer\">>,\n { merge: true }\n );\n }\n }\n const ActionRecordSessionRef = doc(\n collection(this.db, `${this.prefix}ActionRecordSession`),\n this.sessionId\n );\n await setDoc(\n ActionRecordSessionRef,\n {\n userId: this.projectData.id + \"-\" + this.originalUserId,\n originalUserId: this.originalUserId,\n userName: this.userMeta.name || \"anonymous\",\n userEmail: this.userMeta.email || \"\",\n userMeta: this.userMeta,\n updatedBy: this.userId,\n } as Partial<ActionRecordSession>,\n { merge: true }\n );\n return;\n }\n\n // コンソールログをキャプチャ\n startConsoleRecording() {\n try {\n const originalConsole = { ...console };\n const consoleMethods = [\n \"log\",\n \"info\",\n \"warn\",\n \"error\",\n \"debug\",\n \"trace\",\n \"navigation\",\n ] as const;\n\n consoleMethods.forEach((method) => {\n // 型安全なオーバーライド\n (console as any)[method] = (...args: any[]) => {\n // 元のメソッドを呼び出し\n (originalConsole as any)[method](...args);\n // ファイル名も取得\n const fileName =\n new Error().stack?.split(\"\\n\")[2]?.trim() || \"unknown\";\n record.addCustomEvent(\"console\", { method, args, fileName });\n };\n });\n } catch (error) {\n console.error(\"コンソール録画エラー:\", error);\n throw error;\n }\n }\n\n // タイムライン(ナビゲーションとパフォーマンス)をキャプチャ\n startTimelineRecording() {\n try {\n const userId = this.userId || \"unknown\";\n const sessionId = this.sessionId;\n const db = this.db;\n const prefix = this.prefix;\n // ナビゲーション履歴(popstateイベント)\n window.addEventListener(\"popstate\", (event) => {\n if (!db) {\n console.error(\"Firestoreが初期化されていません\");\n return;\n }\n\n record.addCustomEvent(\"navigation\", {\n url: window.location.href,\n state: event.state,\n });\n });\n\n // パフォーマンスエントリ\n if (window.performance) {\n const observer = new PerformanceObserver((list) => {\n for (const entry of list.getEntries()) {\n if (entry.entryType === \"resource\") {\n const resourceEntry = entry as PerformanceResourceTiming;\n // 新規追加: XHR/Fetch以外(CSS, JS, images, fontsなど)のみ記録\n // initiatorTypeでフィルタリング(XHR: \"xmlhttprequest\", Fetch: \"fetch\")\n if (\n resourceEntry.initiatorType !== \"xmlhttprequest\" &&\n resourceEntry.initiatorType !== \"fetch\"\n ) {\n record.addCustomEvent(\"network_resource\", {\n name: resourceEntry.name,\n entryType: resourceEntry.entryType,\n initiatorType: resourceEntry.initiatorType, // css, script, img, font など\n nextHopProtocol: resourceEntry.nextHopProtocol,\n encodedBodySize: resourceEntry.encodedBodySize,\n decodedBodySize: resourceEntry.decodedBodySize,\n transferSize: resourceEntry.transferSize,\n duration: resourceEntry.duration,\n startTime: resourceEntry.startTime,\n fetchStart: resourceEntry.fetchStart,\n domainLookupStart: resourceEntry.domainLookupStart,\n domainLookupEnd: resourceEntry.domainLookupEnd,\n connectStart: resourceEntry.connectStart,\n connectEnd: resourceEntry.connectEnd,\n secureConnectionStart: resourceEntry.secureConnectionStart,\n requestStart: resourceEntry.requestStart,\n responseStart: resourceEntry.responseStart,\n responseEnd: resourceEntry.responseEnd,\n workerStart: resourceEntry.workerStart,\n redirectStart: resourceEntry.redirectStart,\n redirectEnd: resourceEntry.redirectEnd,\n // responseStatus is experimental, may not be available\n responseStatus:\n (resourceEntry as any).responseStatus || undefined,\n serverTiming: resourceEntry.serverTiming,\n });\n }\n } else {\n record.addCustomEvent(\"performance\", {\n name: entry.name,\n entryType: entry.entryType,\n startTime: entry.startTime,\n duration: entry.duration,\n });\n }\n }\n });\n\n observer.observe({ entryTypes: [\"resource\", \"navigation\", \"paint\"] });\n }\n } catch (error) {\n console.error(\"タイムライン録画エラー:\", error);\n throw error;\n }\n }\n\n // ネットワークリクエストをキャプチャ(新規追加)\n startNetworkRecording() {\n try {\n const shouldIgnoreNetwork = (url: string) => {\n try {\n const parsed = new URL(url, window.location.href);\n const host = parsed.hostname;\n if (!host) return false;\n if (host.endsWith(\"firebaseio.com\")) return true;\n return (\n host === \"firestore.googleapis.com\" ||\n host === \"firebasestorage.googleapis.com\" ||\n host === \"firebaseinstallations.googleapis.com\" ||\n host === \"identitytoolkit.googleapis.com\" ||\n host === \"securetoken.googleapis.com\" ||\n host === \"firebaseappcheck.googleapis.com\" ||\n host === \"firebaseremoteconfig.googleapis.com\" ||\n host === \"firebasedynamiclinks.googleapis.com\"\n );\n } catch {\n return false;\n }\n };\n\n // fetch APIをフック\n const originalFetch = window.fetch;\n window.fetch = (...args: Parameters<typeof fetch>) => {\n const startTime = Date.now();\n let input = args[0];\n let init = args[1] as RequestInit | undefined;\n\n let urlStr: string;\n let method: string = \"GET\";\n let requestBody: BodyInit | null | undefined;\n\n if (input instanceof Request) {\n urlStr = input.url;\n method = input.method;\n requestBody = input.body;\n } else {\n urlStr = input instanceof URL ? input.href : input.toString();\n method = init?.method || \"GET\";\n requestBody = init?.body;\n }\n\n if (shouldIgnoreNetwork(urlStr)) {\n return originalFetch(...args);\n }\n\n // リクエストをrrwebのカスタムイベントとして記録\n record.addCustomEvent(\"network_request\", {\n type: \"fetch\",\n method,\n url: urlStr,\n requestBody,\n startTime,\n status: \"pending\", // 初期状態は保留中\n });\n\n return originalFetch(...args)\n .then((response) => {\n const endTime = Date.now();\n const duration = endTime - startTime;\n\n // レスポンスを記録(ボディは非同期で読むため、cloneして扱う)\n const clonedResponse = response.clone();\n clonedResponse\n .text()\n .then((responseBody) => {\n record.addCustomEvent(\"network_response\", {\n type: \"fetch\",\n url: urlStr,\n status: response.status,\n statusText: response.statusText,\n responseBody,\n duration,\n endTime,\n });\n })\n .catch((err) => {\n console.error(\n \"ネットワークレスポンスボディ読み込みエラー:\",\n err\n );\n });\n\n return response;\n })\n .catch((error) => {\n const endTime = Date.now();\n const duration = endTime - startTime;\n\n record.addCustomEvent(\"network_error\", {\n type: \"fetch\",\n url: urlStr,\n error: error.message,\n duration,\n endTime,\n });\n\n throw error;\n });\n };\n\n // XMLHttpRequestをフック\n const OriginalXMLHttpRequest = window.XMLHttpRequest;\n class HookedXMLHttpRequest extends OriginalXMLHttpRequest {\n private _method?: string;\n private _url?: string;\n private _startTime?: number;\n private _skipRecord?: boolean;\n\n static readonly UNSENT = 0;\n static readonly OPENED = 1;\n static readonly HEADERS_RECEIVED = 2;\n static readonly LOADING = 3;\n static readonly DONE = 4;\n\n open(\n method: string,\n url: string | URL,\n async = true,\n username: string | null = null,\n password: string | null = null\n ) {\n this._method = method;\n this._url = url.toString();\n this._startTime = Date.now();\n this._skipRecord = shouldIgnoreNetwork(this._url);\n if (!this._skipRecord) {\n // リクエストを記録\n record.addCustomEvent(\"network_request\", {\n type: \"xhr\",\n method,\n url: this._url,\n startTime: this._startTime,\n status: \"pending\", // 初期状態は保留中\n });\n }\n return super.open(method, url, async, username, password);\n }\n\n send(body?: any) {\n if (this._skipRecord) {\n return super.send(body);\n }\n this.addEventListener(\"load\", () => {\n const endTime = Date.now();\n const duration = endTime - (this._startTime || 0);\n\n record.addCustomEvent(\"network_response\", {\n type: \"xhr\",\n url: this._url,\n status: this.status,\n statusText: this.statusText,\n responseBody: this.responseText,\n duration,\n endTime,\n });\n });\n\n this.addEventListener(\"error\", () => {\n const endTime = Date.now();\n const duration = endTime - (this._startTime || 0);\n\n record.addCustomEvent(\"network_error\", {\n type: \"xhr\",\n url: this._url,\n error: \"XHR error\",\n duration,\n endTime,\n });\n });\n\n return super.send(body);\n }\n }\n window.XMLHttpRequest = HookedXMLHttpRequest;\n\n // WebSocketをフック\n const OriginalWebSocket = window.WebSocket;\n window.WebSocket = class HookedWebSocket extends OriginalWebSocket {\n private _skipRecord: boolean;\n\n constructor(url: string | URL, protocols?: string | string[]) {\n super(url, protocols);\n const wsUrl = url.toString();\n this._skipRecord = shouldIgnoreNetwork(wsUrl);\n if (!this._skipRecord) {\n record.addCustomEvent(\"network_websocket_open\", {\n type: \"websocket\",\n url: wsUrl,\n startTime: Date.now(),\n });\n\n this.addEventListener(\"message\", (event) => {\n record.addCustomEvent(\"network_websocket_message\", {\n type: \"websocket\",\n url: wsUrl,\n data: event.data,\n time: Date.now(),\n });\n });\n\n this.addEventListener(\"close\", (event) => {\n record.addCustomEvent(\"network_websocket_close\", {\n type: \"websocket\",\n url: wsUrl,\n code: event.code,\n reason: event.reason,\n endTime: Date.now(),\n });\n });\n\n this.addEventListener(\"error\", (event) => {\n record.addCustomEvent(\"network_websocket_error\", {\n type: \"websocket\",\n url: wsUrl,\n error: \"WebSocket error\",\n time: Date.now(),\n });\n });\n }\n }\n\n send(data: any) {\n if (!this._skipRecord) {\n record.addCustomEvent(\"network_websocket_send\", {\n type: \"websocket\",\n url: this.url,\n data,\n time: Date.now(),\n });\n }\n return super.send(data);\n }\n };\n } catch (error) {\n console.error(\"ネットワーク録画エラー:\", error);\n throw error;\n }\n }\n\n async startRrwebRecordingForStore() {\n try {\n if (this.stopFnForStore) return;\n\n const _sessionId = this.sessionId;\n const userId = this.userId || \"anonymous\";\n const originalUserId = this.originalUserId || \"\";\n const _db = this.db;\n const prefix = this.prefix;\n let rrwebRecords: string[] = [];\n let pinTime = new Date().getTime();\n if (!this.db || !_db) {\n console.error(\"Firestoreが初期化されていません\");\n return;\n }\n // rrwebの録画を開始\n // このセッションの開始時間を記録\n const ActionRecordSessionRef = doc(\n collection(this.db, `${prefix}ActionRecordSession`),\n _sessionId\n );\n await setDoc(ActionRecordSessionRef, {\n id: _sessionId,\n startTime: new Date(),\n endTime: new Date(),\n recordTime: 0, // 初期値は0\n userId,\n projectId: this.projectId || \"\",\n organizationId: this.projectData?.organizationId || \"\",\n createAt: new Date(),\n updateAt: new Date(),\n createdBy: userId,\n updatedBy: userId,\n });\n try {\n console.log(\"setSessionDetail関数を呼び出します\", this.sessionId);\n await setSessionDetail({ sessionId: this.sessionId });\n } catch (error) {\n console.error(\"setSessionDetail関数の呼び出しに失敗:\", error);\n }\n const docRef = doc(\n collection(this.db, \"ActionRecordSession\"),\n this.sessionId\n );\n await getDoc(docRef)\n .then(async (doc) => {\n if (doc.exists()) {\n const data = doc.data() as ActionRecordSession;\n const ipAddress = data?.ipAddress || \"\";\n const placeData = await getPlaceFromIp(ipAddress);\n\n await updateDoc(docRef, { place: placeData });\n }\n })\n .catch((error) => {\n console.error(\"IPアドレスの取得に失敗:\", error);\n });\n\n this.stopFnForStore = record({\n packFn: pack,\n collectFonts: false,\n inlineImages: false,\n checkoutEveryNth: 2000,\n sampling: {\n canvas: 2000,\n mousemove: 200,\n // mousemoveCallback: 1000,\n },\n\n emit: async (event) => {\n try {\n const deffTime = new Date().getTime() - pinTime;\n rrwebRecords.push(JSON.stringify(event));\n\n if (\n rrwebRecords.length >= 200 ||\n (deffTime >= 10000 && rrwebRecords.length > 0)\n ) {\n pinTime = new Date().getTime(); // リセット\n const record: ActionRecord = {\n id: \"\",\n timeStamp: new Date(),\n userId,\n originalUserId,\n type: \"rrweb\",\n sessionId: _sessionId,\n rrwebRecords: rrwebRecords,\n createAt: new Date(),\n updateAt: new Date(),\n hidden: false,\n createdBy: userId,\n updatedBy: userId,\n hiddenBy: \"\",\n };\n rrwebRecords = []; // リセット\n const newDocRef = doc(collection(_db, `${prefix}ActionRecord`));\n record.id = newDocRef.id; // 新しいIDを生成\n\n await setDoc(newDocRef, record);\n // 送信後にリセット\n }\n } catch (error) {\n console.error(\"rrwebイベント保存エラー:\", error);\n throw error;\n }\n },\n recordCanvas: false,\n });\n this.startConsoleRecording();\n this.startTimelineRecording();\n this.startNetworkRecording(); // ネットワーク録画を追加で開始\n } catch (error) {\n console.error(\"rrweb録画エラー:\", error);\n throw error;\n }\n }\n\n stopRrwebRecordingForStore() {\n try {\n if (this.stopFnForStore) {\n this.stopFnForStore();\n this.stopFnForStore = null;\n }\n } catch (error) {\n console.error(\"rrweb録画停止エラー:\", error);\n throw error;\n }\n }\n async updateActionRecordSession() {\n try {\n if (!this.db || !this.sessionId || !this.userId) {\n console.error(\n \"Firestoreが初期化されていません、またはsessionId、userIdが設定されていません\"\n );\n return;\n }\n const ActionRecordSessionRef = doc(\n collection(this.db, `${this.prefix}ActionRecordSession`),\n this.sessionId\n );\n await setDoc(\n ActionRecordSessionRef,\n {\n endTime: new Date(),\n updateAt: new Date(),\n updatedBy: this.userId,\n },\n { merge: true }\n ).catch((error) => {\n console.error(\"Error updating ActionRecordSession: \", error);\n });\n } catch (error) {\n console.error(\"ActionRecordSession更新エラー:\", error);\n throw error;\n }\n }\n}\n\nexport const ActionLens = new ActionLensRc();\n\nconst getPlaceFromIp = async (ip: string) => {\n try {\n const response = await fetch(`https://ipapi.co/${ip}/json/`);\n if (!response.ok) {\n throw new Error(`IP情報取得エラー: ${response.statusText}`);\n }\n const data = await response.json();\n return {\n city: data.city,\n region: data.region,\n country: data.country_name,\n latitude: data.latitude,\n longitude: data.longitude,\n };\n } catch (error) {\n console.error(\"IP情報取得エラー:\", error);\n return null;\n }\n};\n"],"mappings":"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","names":["import_firestore","doc","import_rrweb","import_firestore","import_packer","uuidv4","db","doc","record"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/player.ts","../src/utils/index.ts","../src/record.ts"],"sourcesContent":["export * from \"./player\";\nexport * from \"./record\";\nimport \"./style.css\";\n","import {\n doc,\n collection,\n setDoc,\n addDoc,\n where,\n query,\n getDocs,\n orderBy,\n Firestore,\n getDoc,\n limit,\n} from \"firebase/firestore\";\nimport {\n ActionRecord,\n ActionRecordSession,\n AuthUser,\n Project,\n Session,\n User,\n} from \"@ism-tech/actionlens-type\";\nimport { Replayer } from \"rrweb\";\nimport { db } from \"./utils\"; // dbのインポートパスを適宜変更してください\n\nimport { unpack } from \"@rrweb/packer\";\n\nexport class ActionLensPlayer {\n replayer: Replayer | null = null;\n overlayContainer: HTMLElement | null = null;\n playerStatus: \"playing\" | \"paused\" | \"stopped\" = \"stopped\";\n targetDivId: string;\n db: Firestore;\n prefix: string;\n userId: string | null = null;\n projectId: string | null = null;\n currentTime: number = 0; // 現在の再生時間\n recordTime: number = 0; // レコードの時間\n totalTime: number = 0; // 再生中の時間を保持するための変数\n user: AuthUser | null = null; // ユーザーデータを保持するための変数\n private setIntervalId: NodeJS.Timeout | null = null; // setTimeoutのIDを保持するための変数\n width: number = 0; // プレイヤーの幅\n height: number = 0; // プレイヤーの高さ\n sessions: (ActionRecordSession & { userData: User<\"customer\"> })[] = []; // セッションのリスト\n currentUrl: string | null = null; // 現在のURLを保持するための変数\n startTime: number = 0; // セッションの開始時間\n sessionInfo: ActionRecordSession | null = null; // セッション情報を保持するための変数\n constructor(\n userId: string,\n targetDivId: string,\n\n _db: Firestore = db,\n prefix: string = \"\"\n ) {\n // 初期化処理が必要であればここに記述\n this.userId = userId;\n this.targetDivId = targetDivId;\n this.db = _db;\n this.prefix = prefix;\n this.initialize(userId);\n }\n\n async initialize(userId: string) {\n const user = await getDoc(doc(this.db, `${this.prefix}authUser`, userId));\n if (!user.exists()) {\n throw new Error(`User with ID ${userId} does not exist.`);\n }\n const userData = user.data() as AuthUser;\n this.user = userData; // ユーザーデータを保持\n this.projectId = userData.projectIds?.[0] || \"\"; // プロジェクトIDを取得\n if (!this.projectId) {\n throw new Error(`Project ID for user ${userId} does not exist.`);\n }\n }\n\n async replayRrwebSession(sessionId: string): Promise<any[]> {\n try {\n // 1. Firestoreからデータを取得\n\n const q = query(\n collection(this.db, `${this.prefix}ActionRecord`),\n where(\"sessionId\", \"==\", sessionId),\n orderBy(\"timeStamp\", \"asc\")\n );\n\n const querySnapshot = await getDocs(q);\n const events = querySnapshot.docs.flatMap((doc) => {\n const data = doc.data() as ActionRecord;\n return data.rrwebRecord\n ? JSON.parse(data.rrwebRecord)\n : data.rrwebRecords\n ? data.rrwebRecords?.map((r) => JSON.parse(r)) || []\n : [];\n });\n\n if (events.length === 0) {\n console.warn(\n `セッションID ${sessionId} のデータが見つかりませんでした。`\n );\n return [];\n }\n\n const targetDiv = document.getElementById(this.targetDivId);\n if (!targetDiv) {\n throw new Error(\n `ID ${this.targetDivId} のdiv要素が見つかりませんでした。`\n );\n }\n\n // クラスを追加\n targetDiv.classList.add(\"replayer-container\");\n\n // 3. Replayerを初期化\n this.replayer = new Replayer(events, {\n unpackFn: unpack,\n root: targetDiv,\n UNSAFE_replayCanvas: false,\n props: {\n autoPlay: true,\n speed: 1,\n mouseTail: true,\n },\n className: \"_replayer-canvas\",\n } as any);\n\n this.width = this.replayer.wrapper.clientWidth;\n this.height = this.replayer.wrapper.clientHeight;\n\n // 4. カスタムイベントのリスナーを追加\n this.replayer.on(\"custom-event\", (event: any) => {\n this.handleCustomEvent(event);\n });\n\n this.replayer.on(\"finish\", () => {\n this.replayer?.pause(0);\n this.playerStatus = \"stopped\";\n this.currentTime = this.replayer?.getCurrentTime() || 0;\n this.endTimeoutTimeline();\n });\n this.replayer.on(\"event-cast\", (event: any) => {\n console.log(\"Event cast:\", event);\n if (event.type === 4 && event.data.href) {\n this.currentUrl = event.data.href;\n }\n });\n this.replayer.on(\"resize\", (e) => {\n const { width, height } = e as { width: number; height: number };\n\n this.width = width;\n this.height = height;\n });\n\n const { totalTime } = this.replayer.getMetaData();\n this.totalTime = totalTime;\n\n // iframeのスタイルを調整\n const iframes = targetDiv.querySelectorAll(\"iframe\");\n iframes.forEach((iframe) => {\n (iframe as HTMLElement).style.transform = \"translate(-50%, -50%)\";\n (iframe as HTMLElement).style.position = \"absolute\";\n (iframe as HTMLElement).style.left = \"50%\";\n (iframe as HTMLElement).style.top = \"50%\";\n });\n // replayer-mouse-tailにposition: absolute; を追加\n const mouseTailElements = document.querySelectorAll(\n \".replayer-mouse-tail\"\n );\n mouseTailElements.forEach((element) => {\n (element as HTMLElement).style.position = \"absolute\";\n (element as HTMLElement).style.left = \"50%\";\n (element as HTMLElement).style.top = \"50%\";\n (element as HTMLElement).style.transform = \"translate(-50%, -50%)\";\n (element as HTMLElement).style.zIndex = \"1000\"; // z-indexを追加\n });\n\n // 5. 再生開始\n\n this.replayer.play();\n this.playerStatus = \"playing\";\n\n this.setTimeoutTimeline();\n return events.map((e) => unpack(e));\n } catch (error) {\n console.error(\"再生エラー:\", error);\n throw error;\n }\n }\n\n // カスタムイベントを処理\n private handleCustomEvent(event: any) {\n if (!event.data || !event.data.type) return;\n\n const { timestamp } = event;\n const timeString = new Date(timestamp).toISOString();\n\n switch (event.data.type) {\n case \"console\":\n const { method, args } = event.data;\n this.displayEvent(\n `[${timeString}] Console ${method}: ${args.join(\", \")}`,\n \"console\"\n );\n\n break;\n case \"navigation\":\n const { url } = event.data;\n this.currentUrl = url;\n this.displayEvent(`[${timeString}] Navigation to ${url}`, \"navigation\");\n break;\n case \"performance\":\n const { name, entryType, duration } = event.data;\n this.displayEvent(\n `[${timeString}] Performance ${entryType}: ${name} (${duration}ms)`,\n \"performance\"\n );\n break;\n default:\n }\n }\n\n // イベントをオーバーレイに表示\n private displayEvent(message: string, eventType: string) {\n if (!this.overlayContainer) return;\n\n const eventDiv = document.createElement(\"div\");\n eventDiv.style.padding = \"5px\";\n eventDiv.style.borderBottom = \"1px solid rgba(255, 255, 255, 0.2)\";\n\n // イベントタイプに応じた色\n const colors: { [key: string]: string } = {\n console: \"#00cc00\",\n navigation: \"#3399ff\",\n performance: \"#ff9900\",\n };\n eventDiv.style.color = colors[eventType] || \"white\";\n\n eventDiv.innerText = message;\n this.overlayContainer.appendChild(eventDiv);\n\n // 最新のイベントが表示されるようスクロール\n this.overlayContainer.scrollTop = this.overlayContainer.scrollHeight;\n\n // 5秒後にフェードアウト\n setTimeout(() => {\n eventDiv.style.transition = \"opacity 1s\";\n eventDiv.style.opacity = \"0\";\n setTimeout(() => eventDiv.remove(), 1000);\n }, 5000);\n }\n setReplayTime(time: number) {\n if (this.replayer) {\n this.replayer.pause(time);\n this.currentTime = time;\n this.playerStatus = \"stopped\";\n }\n }\n\n setTimeoutTimeline() {\n this.setIntervalId = setInterval(() => {\n this.currentTime = this.replayer?.getCurrentTime() || 0;\n this.recordTime =\n Number(this.replayer?.getMetaData()?.startTime) + this.currentTime;\n }, 10);\n }\n endTimeoutTimeline() {\n if (this.setIntervalId) {\n clearTimeout(this.setIntervalId);\n this.setIntervalId = null;\n }\n }\n\n // 再生を停止\n stopReplay() {\n this.endTimeoutTimeline();\n if (this.replayer) {\n this.replayer.pause();\n this.playerStatus = \"stopped\";\n this.currentTime = this.replayer?.getCurrentTime() || 0;\n }\n }\n restartReplay() {\n this.setTimeoutTimeline();\n if (this.replayer) {\n const offset = this.replayer.getCurrentTime();\n\n this.replayer.play(offset);\n this.playerStatus = \"playing\";\n this.currentTime = this.replayer?.getCurrentTime() || 0;\n }\n }\n getCurrentTime() {\n if (this.replayer) {\n return this.replayer.getCurrentTime();\n }\n return 0;\n }\n\n resetReplayer() {\n this.endTimeoutTimeline();\n this.playerStatus = \"stopped\";\n this.currentTime = 0;\n\n if (this.replayer) {\n this.replayer.pause();\n this.replayer.destroy();\n this.replayer = null;\n }\n if (this.overlayContainer) {\n this.overlayContainer.remove();\n this.overlayContainer = null;\n }\n }\n async fetchProjectList() {\n try {\n if (!this.userId) {\n console.warn(\"User ID is not initialized.\");\n return [];\n }\n if (!this.user) {\n this.user = (\n await getDoc(doc(this.db, `${this.prefix}authUser`, this.userId))\n ).data() as AuthUser | null;\n if (!this.user) {\n console.warn(`User with ID ${this.userId} does not exist.`);\n\n return [];\n }\n }\n console.log(\"fetchProjectList\", this.user);\n const projectIds = this.user.projectIds || [];\n if (projectIds.length === 0) {\n console.warn(\"No project IDs found for the user.\");\n return [];\n }\n const promise = projectIds.flatMap(async (projectId) => {\n const projectDoc = await getDoc(\n doc(this.db, `${this.prefix}project`, projectId)\n );\n if (!projectDoc.exists()) {\n console.warn(`Project with ID ${projectId} does not exist.`);\n return null;\n }\n return projectDoc.data() as Project;\n });\n const projectPromises: (Project | null)[] = await Promise.all(promise);\n return projectPromises.filter((project) => project !== null);\n } catch (e) {\n console.error(\"プロジェクトリストの取得エラー:\", e);\n throw e;\n }\n }\n\n async fetchSessionList(projectId: string, limitNum: number = 20) {\n try {\n const q = query(\n collection(this.db, `${this.prefix}ActionRecordSession`),\n where(\"projectId\", \"==\", projectId),\n where(\"recordTime\", \">=\", 10),\n orderBy(\"startTime\", \"desc\"),\n limit(limitNum)\n );\n const usersStore: { [userId: string]: User<\"customer\"> } = {};\n\n const querySnapshot = await getDocs(q);\n const promise = querySnapshot.docs.map(async (_doc) => {\n const data = _doc.data() as ActionRecordSession;\n if (!usersStore[data.userId]) {\n usersStore[data.userId] = (\n await getDoc(doc(this.db, `${this.prefix}user`, data.userId))\n ).data() as User<\"customer\">;\n }\n\n return { ...data, userData: usersStore[data.userId] };\n });\n const sessions: (ActionRecordSession & { userData: User<\"customer\"> })[] =\n await Promise.all(promise);\n console.log(sessions);\n this.sessions = sessions;\n return sessions;\n } catch (error) {\n console.error(\"セッションリストの取得エラー:\", error);\n throw error;\n }\n }\n}\n","import { initializeApp } from \"firebase/app\";\nimport { getFirestore } from \"firebase/firestore\";\n\nexport const firebaseConfig = {\n apiKey: \"AIzaSyCxreoOZivnjFIh2mJ6WXjS3ieQ11wsDW8\",\n authDomain: \"actionlens-b14ae.firebaseapp.com\",\n projectId: \"actionlens-b14ae\",\n storageBucket: \"actionlens-b14ae.firebasestorage.app\",\n messagingSenderId: \"36086339210\",\n appId: \"1:36086339210:web:36e16e8778aadd8c58ff73\",\n};\n\n// Initialize Firebase\nexport const app = initializeApp(firebaseConfig);\n\nexport const db = getFirestore(app);\n","import { v4 as uuidv4 } from \"uuid\";\nimport { record, Replayer } from \"rrweb\";\nimport {\n Firestore,\n doc,\n setDoc,\n collection,\n getDoc,\n getFirestore,\n updateDoc,\n} from \"firebase/firestore\";\nimport {\n ActionRecord,\n ActionRecordSession,\n Project,\n User,\n} from \"@ism-tech/actionlens-type\";\nimport { db, app } from \"./utils/index\";\nimport { pack } from \"@rrweb/packer\";\nimport { httpsCallable, getFunctions } from \"firebase/functions\";\n\nconst functions = getFunctions(app);\n\nconst setSessionDetail = httpsCallable(functions, \"setSessionDetail\");\nexport class ActionLensRc {\n sessionId: string = uuidv4();\n stopFnForStore: any = null;\n userId: string | null = \"anonymous\"; // ユーザーIDはプロジェクトIDと組み合わせて一意にする\n db: Firestore | null = null;\n prefix: string = \"\";\n userData: User<\"customer\"> | null = null;\n projectId: string | null = null;\n projectData: Project | null = null;\n organizationId: string | null = null;\n originalUserId: string | null = null; // 元のユーザーID(外部システムのIDなど)\n userMeta: { name?: string; email?: string } = {};\n metaData: Record<string, any> = {};\n isRecordingPaused: boolean = false;\n isSessionInitialized: boolean = false;\n areAuxRecordersStarted: boolean = false;\n\n constructor() {\n this.db = db; // Firestoreの初期化\n }\n\n async init(\n projectId: string | null,\n _db: Firestore | null = null,\n prefix: string = \"\"\n ) {\n try {\n if (!projectId) {\n console.error(\"projectIdがNULLです\");\n return;\n }\n this.projectId = projectId;\n\n this.prefix = prefix;\n\n if (!this.db && _db) {\n console.error(\"Firestoreが初期化されていません\");\n this.db = _db;\n }\n if (!this.db) {\n console.error(\"Firestoreが初期化されていません\");\n return;\n }\n\n if (!this.projectId) {\n console.error(\"projectIdが設定されていません\");\n return;\n }\n const _doc = await getDoc(\n doc(collection(this.db, `${this.prefix}project`), this.projectId)\n );\n this.projectData = _doc.data() as Project;\n const projectData = this.projectData;\n this.organizationId = projectData?.organizationId || \"\";\n\n if (!this.projectData) {\n await setDoc(\n doc(collection(this.db, `${this.prefix}project`), this.projectId),\n {\n id: this.projectId,\n name: this.projectId,\n organizationId: \"\",\n isActivate: false, // デフォルトでアクティブに設定\n createAt: new Date(),\n updateAt: new Date(),\n createdBy: this.originalUserId,\n updatedBy: this.originalUserId,\n } as Project,\n { merge: true }\n );\n\n console.warn(\"プロジェクトが存在しません\");\n return;\n }\n if (!this.projectData?.isActivate) {\n console.warn(\"プロジェクトは非アクティブです。録画を開始できません。\");\n return;\n }\n\n await this.startRrwebRecordingForStore();\n\n // this.startTimelineRecording();\n return;\n } catch (error) {\n console.error(\"初期化中にエラーが発生しました:\", error);\n return;\n }\n }\n\n async setUser(\n _userId: string | null,\n userMeta: { name: string; email: string },\n metaData: Record<string, any> = {}\n ) {\n if (!this.db) {\n console.error(\"Firestoreが初期化されていません\");\n return;\n }\n if (!this.projectData) {\n console.error(\"プロジェクトデータが設定されていません\");\n return;\n }\n this.originalUserId = _userId; // 元のユーザーIDを保存\n this.userMeta = userMeta;\n this.metaData = metaData;\n\n if (!_userId) {\n console.error(\"userIdがNULLです\");\n return;\n }\n\n this.userId = this.projectData.id + \"-\" + this.originalUserId;\n this.prefix = this.prefix;\n this.projectId = this.projectId;\n const user = await getDoc(\n doc(collection(this.db, `${this.prefix}user`), this.userId)\n );\n\n if (!this.db) {\n console.error(\"Firestoreが初期化されていません\");\n return;\n }\n\n const userData = user.data() as User<\"customer\">;\n\n if (!userData?.id || !user.exists()) {\n await setDoc(\n doc(\n collection(this.db, `${this.prefix}user`),\n this.projectData.id + \"-\" + this.originalUserId\n ),\n {\n ...(this.userMeta || {}),\n metaData: this.metaData,\n id: this.userId,\n originalUserId: this.originalUserId,\n type: \"customer\",\n organizationId: this.projectData?.organizationId || \"\",\n projectIds: [this.projectId],\n createAt: new Date(),\n updateAt: new Date(),\n createdBy: this.userId,\n updatedBy: this.userId,\n hidden: false,\n hiddenBy: \"\",\n } as User<\"customer\">,\n { merge: true }\n );\n this.userData = {\n ...(this.userMeta || {}),\n metaData: this.metaData,\n id: this.userId,\n originalUserId: this.originalUserId,\n type: \"customer\",\n organizationId: this.projectData?.organizationId || \"\",\n projectIds: [this.projectId],\n createAt: new Date(),\n updateAt: new Date(),\n createdBy: this.userId,\n updatedBy: this.userId,\n hidden: false,\n hiddenBy: \"\",\n } as User<\"customer\">;\n } else {\n this.userData = user.data() as User<\"customer\">;\n\n if (!this.userData?.projectIds?.includes(this.projectId || \"\")) {\n await setDoc(\n doc(\n collection(this.db, `${this.prefix}user`),\n this.projectData.id + \"-\" + this.originalUserId\n ),\n {\n projectIds: [...(this.userData?.projectIds || []), this.projectId],\n updateAt: new Date(),\n updatedBy: this.userId,\n } as Partial<User<\"customer\">>,\n { merge: true }\n );\n }\n\n if (this.userData?.organizationId !== this.projectData.organizationId) {\n await setDoc(\n doc(\n collection(this.db, `${this.prefix}user`),\n this.projectData.id + \"-\" + this.originalUserId\n ),\n {\n organizationId: this.projectData.organizationId\n ? this.projectData.organizationId\n : this.userData?.organizationId,\n updateAt: new Date(),\n updatedBy: this.userId,\n } as Partial<User<\"customer\">>,\n { merge: true }\n );\n }\n }\n const ActionRecordSessionRef = doc(\n collection(this.db, `${this.prefix}ActionRecordSession`),\n this.sessionId\n );\n await setDoc(\n ActionRecordSessionRef,\n {\n userId: this.projectData.id + \"-\" + this.originalUserId,\n originalUserId: this.originalUserId,\n userName: this.userMeta.name || \"anonymous\",\n userEmail: this.userMeta.email || \"\",\n userMeta: this.userMeta,\n updatedBy: this.userId,\n } as Partial<ActionRecordSession>,\n { merge: true }\n );\n return;\n }\n\n private shouldRecordCustomEvents() {\n return !this.isRecordingPaused && !!this.stopFnForStore;\n }\n\n // コンソールログをキャプチャ\n startConsoleRecording() {\n try {\n const originalConsole = { ...console };\n const consoleMethods = [\n \"log\",\n \"info\",\n \"warn\",\n \"error\",\n \"debug\",\n \"trace\",\n \"navigation\",\n ] as const;\n\n consoleMethods.forEach((method) => {\n // 型安全なオーバーライド\n (console as any)[method] = (...args: any[]) => {\n // 元のメソッドを呼び出し\n (originalConsole as any)[method](...args);\n if (!this.shouldRecordCustomEvents()) return;\n // ファイル名も取得\n const fileName =\n new Error().stack?.split(\"\\n\")[2]?.trim() || \"unknown\";\n record.addCustomEvent(\"console\", { method, args, fileName });\n };\n });\n } catch (error) {\n console.error(\"コンソール録画エラー:\", error);\n throw error;\n }\n }\n\n // タイムライン(ナビゲーションとパフォーマンス)をキャプチャ\n startTimelineRecording() {\n try {\n const userId = this.userId || \"unknown\";\n const sessionId = this.sessionId;\n const db = this.db;\n const prefix = this.prefix;\n // ナビゲーション履歴(popstateイベント)\n window.addEventListener(\"popstate\", (event) => {\n if (!db) {\n console.error(\"Firestoreが初期化されていません\");\n return;\n }\n if (!this.shouldRecordCustomEvents()) return;\n\n record.addCustomEvent(\"navigation\", {\n url: window.location.href,\n state: event.state,\n });\n });\n\n // パフォーマンスエントリ\n if (window.performance) {\n const observer = new PerformanceObserver((list) => {\n if (!this.shouldRecordCustomEvents()) return;\n for (const entry of list.getEntries()) {\n if (entry.entryType === \"resource\") {\n const resourceEntry = entry as PerformanceResourceTiming;\n // 新規追加: XHR/Fetch以外(CSS, JS, images, fontsなど)のみ記録\n // initiatorTypeでフィルタリング(XHR: \"xmlhttprequest\", Fetch: \"fetch\")\n if (\n resourceEntry.initiatorType !== \"xmlhttprequest\" &&\n resourceEntry.initiatorType !== \"fetch\"\n ) {\n record.addCustomEvent(\"network_resource\", {\n name: resourceEntry.name,\n entryType: resourceEntry.entryType,\n initiatorType: resourceEntry.initiatorType, // css, script, img, font など\n nextHopProtocol: resourceEntry.nextHopProtocol,\n encodedBodySize: resourceEntry.encodedBodySize,\n decodedBodySize: resourceEntry.decodedBodySize,\n transferSize: resourceEntry.transferSize,\n duration: resourceEntry.duration,\n startTime: resourceEntry.startTime,\n fetchStart: resourceEntry.fetchStart,\n domainLookupStart: resourceEntry.domainLookupStart,\n domainLookupEnd: resourceEntry.domainLookupEnd,\n connectStart: resourceEntry.connectStart,\n connectEnd: resourceEntry.connectEnd,\n secureConnectionStart: resourceEntry.secureConnectionStart,\n requestStart: resourceEntry.requestStart,\n responseStart: resourceEntry.responseStart,\n responseEnd: resourceEntry.responseEnd,\n workerStart: resourceEntry.workerStart,\n redirectStart: resourceEntry.redirectStart,\n redirectEnd: resourceEntry.redirectEnd,\n // responseStatus is experimental, may not be available\n responseStatus:\n (resourceEntry as any).responseStatus || undefined,\n serverTiming: resourceEntry.serverTiming,\n });\n }\n } else {\n record.addCustomEvent(\"performance\", {\n name: entry.name,\n entryType: entry.entryType,\n startTime: entry.startTime,\n duration: entry.duration,\n });\n }\n }\n });\n\n observer.observe({ entryTypes: [\"resource\", \"navigation\", \"paint\"] });\n }\n } catch (error) {\n console.error(\"タイムライン録画エラー:\", error);\n throw error;\n }\n }\n\n // ネットワークリクエストをキャプチャ(新規追加)\n startNetworkRecording() {\n try {\n const shouldRecordCustomEvents = () => this.shouldRecordCustomEvents();\n const shouldIgnoreNetwork = (url: string) => {\n try {\n const parsed = new URL(url, window.location.href);\n const host = parsed.hostname;\n if (!host) return false;\n if (host.endsWith(\"firebaseio.com\")) return true;\n return (\n host === \"firestore.googleapis.com\" ||\n host === \"firebasestorage.googleapis.com\" ||\n host === \"firebaseinstallations.googleapis.com\" ||\n host === \"identitytoolkit.googleapis.com\" ||\n host === \"securetoken.googleapis.com\" ||\n host === \"firebaseappcheck.googleapis.com\" ||\n host === \"firebaseremoteconfig.googleapis.com\" ||\n host === \"firebasedynamiclinks.googleapis.com\"\n );\n } catch {\n return false;\n }\n };\n\n // fetch APIをフック\n const originalFetch = window.fetch;\n window.fetch = (...args: Parameters<typeof fetch>) => {\n const startTime = Date.now();\n let input = args[0];\n let init = args[1] as RequestInit | undefined;\n\n let urlStr: string;\n let method: string = \"GET\";\n let requestBody: BodyInit | null | undefined;\n\n if (input instanceof Request) {\n urlStr = input.url;\n method = input.method;\n requestBody = input.body;\n } else {\n urlStr = input instanceof URL ? input.href : input.toString();\n method = init?.method || \"GET\";\n requestBody = init?.body;\n }\n\n if (shouldIgnoreNetwork(urlStr) || !shouldRecordCustomEvents()) {\n return originalFetch(...args);\n }\n\n // リクエストをrrwebのカスタムイベントとして記録\n record.addCustomEvent(\"network_request\", {\n type: \"fetch\",\n method,\n url: urlStr,\n requestBody,\n startTime,\n status: \"pending\", // 初期状態は保留中\n });\n\n return originalFetch(...args)\n .then((response) => {\n if (!shouldRecordCustomEvents()) {\n return response;\n }\n const endTime = Date.now();\n const duration = endTime - startTime;\n\n // レスポンスを記録(ボディは非同期で読むため、cloneして扱う)\n const clonedResponse = response.clone();\n clonedResponse\n .text()\n .then((responseBody) => {\n record.addCustomEvent(\"network_response\", {\n type: \"fetch\",\n url: urlStr,\n status: response.status,\n statusText: response.statusText,\n responseBody,\n duration,\n endTime,\n });\n })\n .catch((err) => {\n console.error(\n \"ネットワークレスポンスボディ読み込みエラー:\",\n err\n );\n });\n\n return response;\n })\n .catch((error) => {\n if (!shouldRecordCustomEvents()) {\n throw error;\n }\n const endTime = Date.now();\n const duration = endTime - startTime;\n\n record.addCustomEvent(\"network_error\", {\n type: \"fetch\",\n url: urlStr,\n error: error.message,\n duration,\n endTime,\n });\n\n throw error;\n });\n };\n\n // XMLHttpRequestをフック\n const OriginalXMLHttpRequest = window.XMLHttpRequest;\n class HookedXMLHttpRequest extends OriginalXMLHttpRequest {\n private _method?: string;\n private _url?: string;\n private _startTime?: number;\n private _skipRecord?: boolean;\n\n static readonly UNSENT = 0;\n static readonly OPENED = 1;\n static readonly HEADERS_RECEIVED = 2;\n static readonly LOADING = 3;\n static readonly DONE = 4;\n\n open(\n method: string,\n url: string | URL,\n async = true,\n username: string | null = null,\n password: string | null = null\n ) {\n this._method = method;\n this._url = url.toString();\n this._startTime = Date.now();\n this._skipRecord =\n shouldIgnoreNetwork(this._url) || !shouldRecordCustomEvents();\n if (!this._skipRecord) {\n // リクエストを記録\n record.addCustomEvent(\"network_request\", {\n type: \"xhr\",\n method,\n url: this._url,\n startTime: this._startTime,\n status: \"pending\", // 初期状態は保留中\n });\n }\n return super.open(method, url, async, username, password);\n }\n\n send(body?: any) {\n if (this._skipRecord) {\n return super.send(body);\n }\n this.addEventListener(\"load\", () => {\n if (!shouldRecordCustomEvents()) return;\n const endTime = Date.now();\n const duration = endTime - (this._startTime || 0);\n\n record.addCustomEvent(\"network_response\", {\n type: \"xhr\",\n url: this._url,\n status: this.status,\n statusText: this.statusText,\n responseBody: this.responseText,\n duration,\n endTime,\n });\n });\n\n this.addEventListener(\"error\", () => {\n if (!shouldRecordCustomEvents()) return;\n const endTime = Date.now();\n const duration = endTime - (this._startTime || 0);\n\n record.addCustomEvent(\"network_error\", {\n type: \"xhr\",\n url: this._url,\n error: \"XHR error\",\n duration,\n endTime,\n });\n });\n\n return super.send(body);\n }\n }\n window.XMLHttpRequest = HookedXMLHttpRequest;\n\n // WebSocketをフック\n const OriginalWebSocket = window.WebSocket;\n window.WebSocket = class HookedWebSocket extends OriginalWebSocket {\n private _skipRecord: boolean;\n\n constructor(url: string | URL, protocols?: string | string[]) {\n super(url, protocols);\n const wsUrl = url.toString();\n this._skipRecord = shouldIgnoreNetwork(wsUrl);\n if (this._skipRecord) return;\n if (shouldRecordCustomEvents()) {\n record.addCustomEvent(\"network_websocket_open\", {\n type: \"websocket\",\n url: wsUrl,\n startTime: Date.now(),\n });\n }\n\n this.addEventListener(\"message\", (event) => {\n if (!shouldRecordCustomEvents()) return;\n record.addCustomEvent(\"network_websocket_message\", {\n type: \"websocket\",\n url: wsUrl,\n data: event.data,\n time: Date.now(),\n });\n });\n\n this.addEventListener(\"close\", (event) => {\n if (!shouldRecordCustomEvents()) return;\n record.addCustomEvent(\"network_websocket_close\", {\n type: \"websocket\",\n url: wsUrl,\n code: event.code,\n reason: event.reason,\n endTime: Date.now(),\n });\n });\n\n this.addEventListener(\"error\", (event) => {\n if (!shouldRecordCustomEvents()) return;\n record.addCustomEvent(\"network_websocket_error\", {\n type: \"websocket\",\n url: wsUrl,\n error: \"WebSocket error\",\n time: Date.now(),\n });\n });\n }\n\n send(data: any) {\n if (this._skipRecord || !shouldRecordCustomEvents()) {\n return super.send(data);\n }\n record.addCustomEvent(\"network_websocket_send\", {\n type: \"websocket\",\n url: this.url,\n data,\n time: Date.now(),\n });\n return super.send(data);\n }\n };\n } catch (error) {\n console.error(\"ネットワーク録画エラー:\", error);\n throw error;\n }\n }\n\n async startRrwebRecordingForStore() {\n try {\n if (this.stopFnForStore) return;\n\n const _sessionId = this.sessionId;\n const userId = this.userId || \"anonymous\";\n const originalUserId = this.originalUserId || \"\";\n const _db = this.db;\n const prefix = this.prefix;\n let rrwebRecords: string[] = [];\n let pinTime = new Date().getTime();\n if (!this.db || !_db) {\n console.error(\"Firestoreが初期化されていません\");\n return;\n }\n if (!this.isSessionInitialized) {\n // rrwebの録画を開始\n // このセッションの開始時間を記録\n const ActionRecordSessionRef = doc(\n collection(this.db, `${prefix}ActionRecordSession`),\n _sessionId\n );\n await setDoc(ActionRecordSessionRef, {\n id: _sessionId,\n startTime: new Date(),\n endTime: new Date(),\n recordTime: 0, // 初期値は0\n userId,\n projectId: this.projectId || \"\",\n organizationId: this.projectData?.organizationId || \"\",\n createAt: new Date(),\n updateAt: new Date(),\n createdBy: userId,\n updatedBy: userId,\n });\n this.isSessionInitialized = true;\n try {\n console.log(\"setSessionDetail関数を呼び出します\", this.sessionId);\n await setSessionDetail({ sessionId: this.sessionId });\n } catch (error) {\n console.error(\"setSessionDetail関数の呼び出しに失敗:\", error);\n }\n const docRef = doc(\n collection(this.db, \"ActionRecordSession\"),\n this.sessionId\n );\n await getDoc(docRef)\n .then(async (doc) => {\n if (doc.exists()) {\n const data = doc.data() as ActionRecordSession;\n const ipAddress = data?.ipAddress || \"\";\n const placeData = await getPlaceFromIp(ipAddress);\n\n await updateDoc(docRef, { place: placeData });\n }\n })\n .catch((error) => {\n console.error(\"IPアドレスの取得に失敗:\", error);\n });\n }\n\n this.stopFnForStore = record({\n packFn: pack,\n collectFonts: false,\n inlineImages: false,\n checkoutEveryNth: 4000,\n slimDOMOptions: {\n script: true,\n comment: true,\n headFavicon: true,\n headWhitespace: true,\n },\n sampling: {\n canvas: 5000,\n mousemove: 500,\n // mousemoveCallback: 1000,\n },\n\n emit: async (event) => {\n try {\n const deffTime = new Date().getTime() - pinTime;\n rrwebRecords.push(JSON.stringify(event));\n\n if (\n rrwebRecords.length >= 200 ||\n (deffTime >= 10000 && rrwebRecords.length > 0)\n ) {\n pinTime = new Date().getTime(); // リセット\n const record: ActionRecord = {\n id: \"\",\n timeStamp: new Date(),\n userId,\n originalUserId,\n type: \"rrweb\",\n sessionId: _sessionId,\n rrwebRecords: rrwebRecords,\n createAt: new Date(),\n updateAt: new Date(),\n hidden: false,\n createdBy: userId,\n updatedBy: userId,\n hiddenBy: \"\",\n };\n rrwebRecords = []; // リセット\n const newDocRef = doc(collection(_db, `${prefix}ActionRecord`));\n record.id = newDocRef.id; // 新しいIDを生成\n\n await setDoc(newDocRef, record);\n // 送信後にリセット\n }\n } catch (error) {\n console.error(\"rrwebイベント保存エラー:\", error);\n throw error;\n }\n },\n recordCanvas: false,\n });\n this.isRecordingPaused = false;\n if (!this.areAuxRecordersStarted) {\n this.startConsoleRecording();\n this.startTimelineRecording();\n this.startNetworkRecording(); // ネットワーク録画を追加で開始\n this.areAuxRecordersStarted = true;\n }\n } catch (error) {\n console.error(\"rrweb録画エラー:\", error);\n throw error;\n }\n }\n\n pauseRrwebRecordingForStore() {\n try {\n this.isRecordingPaused = true;\n if (this.stopFnForStore) {\n this.stopFnForStore();\n this.stopFnForStore = null;\n }\n } catch (error) {\n console.error(\"rrweb録画一時停止エラー:\", error);\n throw error;\n }\n }\n\n async resumeRrwebRecordingForStore() {\n try {\n if (this.stopFnForStore) return;\n this.isRecordingPaused = false;\n await this.startRrwebRecordingForStore();\n } catch (error) {\n console.error(\"rrweb録画再開エラー:\", error);\n throw error;\n }\n }\n\n stopRrwebRecordingForStore() {\n try {\n if (this.stopFnForStore) {\n this.stopFnForStore();\n this.stopFnForStore = null;\n }\n this.isRecordingPaused = false;\n } catch (error) {\n console.error(\"rrweb録画停止エラー:\", error);\n throw error;\n }\n }\n async updateActionRecordSession() {\n try {\n if (!this.db || !this.sessionId || !this.userId) {\n console.error(\n \"Firestoreが初期化されていません、またはsessionId、userIdが設定されていません\"\n );\n return;\n }\n const ActionRecordSessionRef = doc(\n collection(this.db, `${this.prefix}ActionRecordSession`),\n this.sessionId\n );\n await setDoc(\n ActionRecordSessionRef,\n {\n endTime: new Date(),\n updateAt: new Date(),\n updatedBy: this.userId,\n },\n { merge: true }\n ).catch((error) => {\n console.error(\"Error updating ActionRecordSession: \", error);\n });\n } catch (error) {\n console.error(\"ActionRecordSession更新エラー:\", error);\n throw error;\n }\n }\n}\n\nexport const ActionLens = new ActionLensRc();\n\nconst getPlaceFromIp = async (ip: string) => {\n try {\n const response = await fetch(`https://ipapi.co/${ip}/json/`);\n if (!response.ok) {\n throw new Error(`IP情報取得エラー: ${response.statusText}`);\n }\n const data = await response.json();\n return {\n city: data.city,\n region: data.region,\n country: data.country_name,\n latitude: data.latitude,\n longitude: data.longitude,\n };\n } catch (error) {\n console.error(\"IP情報取得エラー:\", error);\n return null;\n }\n};\n"],"mappings":"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","names":["import_firestore","doc","import_rrweb","import_firestore","import_packer","uuidv4","db","doc","record"]}
|
package/dist/index.mjs
CHANGED
|
@@ -363,6 +363,9 @@ var ActionLensRc = class {
|
|
|
363
363
|
// 元のユーザーID(外部システムのIDなど)
|
|
364
364
|
userMeta = {};
|
|
365
365
|
metaData = {};
|
|
366
|
+
isRecordingPaused = false;
|
|
367
|
+
isSessionInitialized = false;
|
|
368
|
+
areAuxRecordersStarted = false;
|
|
366
369
|
constructor() {
|
|
367
370
|
this.db = db;
|
|
368
371
|
}
|
|
@@ -536,6 +539,9 @@ var ActionLensRc = class {
|
|
|
536
539
|
);
|
|
537
540
|
return;
|
|
538
541
|
}
|
|
542
|
+
shouldRecordCustomEvents() {
|
|
543
|
+
return !this.isRecordingPaused && !!this.stopFnForStore;
|
|
544
|
+
}
|
|
539
545
|
// コンソールログをキャプチャ
|
|
540
546
|
startConsoleRecording() {
|
|
541
547
|
try {
|
|
@@ -552,6 +558,7 @@ var ActionLensRc = class {
|
|
|
552
558
|
consoleMethods.forEach((method) => {
|
|
553
559
|
console[method] = (...args) => {
|
|
554
560
|
originalConsole[method](...args);
|
|
561
|
+
if (!this.shouldRecordCustomEvents()) return;
|
|
555
562
|
const fileName = new Error().stack?.split("\n")[2]?.trim() || "unknown";
|
|
556
563
|
record.addCustomEvent("console", { method, args, fileName });
|
|
557
564
|
};
|
|
@@ -573,6 +580,7 @@ var ActionLensRc = class {
|
|
|
573
580
|
console.error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
|
|
574
581
|
return;
|
|
575
582
|
}
|
|
583
|
+
if (!this.shouldRecordCustomEvents()) return;
|
|
576
584
|
record.addCustomEvent("navigation", {
|
|
577
585
|
url: window.location.href,
|
|
578
586
|
state: event.state
|
|
@@ -580,6 +588,7 @@ var ActionLensRc = class {
|
|
|
580
588
|
});
|
|
581
589
|
if (window.performance) {
|
|
582
590
|
const observer = new PerformanceObserver((list) => {
|
|
591
|
+
if (!this.shouldRecordCustomEvents()) return;
|
|
583
592
|
for (const entry of list.getEntries()) {
|
|
584
593
|
if (entry.entryType === "resource") {
|
|
585
594
|
const resourceEntry = entry;
|
|
@@ -632,6 +641,7 @@ var ActionLensRc = class {
|
|
|
632
641
|
// ネットワークリクエストをキャプチャ(新規追加)
|
|
633
642
|
startNetworkRecording() {
|
|
634
643
|
try {
|
|
644
|
+
const shouldRecordCustomEvents = () => this.shouldRecordCustomEvents();
|
|
635
645
|
const shouldIgnoreNetwork = (url) => {
|
|
636
646
|
try {
|
|
637
647
|
const parsed = new URL(url, window.location.href);
|
|
@@ -660,7 +670,7 @@ var ActionLensRc = class {
|
|
|
660
670
|
method = init?.method || "GET";
|
|
661
671
|
requestBody = init?.body;
|
|
662
672
|
}
|
|
663
|
-
if (shouldIgnoreNetwork(urlStr)) {
|
|
673
|
+
if (shouldIgnoreNetwork(urlStr) || !shouldRecordCustomEvents()) {
|
|
664
674
|
return originalFetch(...args);
|
|
665
675
|
}
|
|
666
676
|
record.addCustomEvent("network_request", {
|
|
@@ -673,6 +683,9 @@ var ActionLensRc = class {
|
|
|
673
683
|
// 初期状態は保留中
|
|
674
684
|
});
|
|
675
685
|
return originalFetch(...args).then((response) => {
|
|
686
|
+
if (!shouldRecordCustomEvents()) {
|
|
687
|
+
return response;
|
|
688
|
+
}
|
|
676
689
|
const endTime = Date.now();
|
|
677
690
|
const duration = endTime - startTime;
|
|
678
691
|
const clonedResponse = response.clone();
|
|
@@ -694,6 +707,9 @@ var ActionLensRc = class {
|
|
|
694
707
|
});
|
|
695
708
|
return response;
|
|
696
709
|
}).catch((error) => {
|
|
710
|
+
if (!shouldRecordCustomEvents()) {
|
|
711
|
+
throw error;
|
|
712
|
+
}
|
|
697
713
|
const endTime = Date.now();
|
|
698
714
|
const duration = endTime - startTime;
|
|
699
715
|
record.addCustomEvent("network_error", {
|
|
@@ -721,7 +737,7 @@ var ActionLensRc = class {
|
|
|
721
737
|
this._method = method;
|
|
722
738
|
this._url = url.toString();
|
|
723
739
|
this._startTime = Date.now();
|
|
724
|
-
this._skipRecord = shouldIgnoreNetwork(this._url);
|
|
740
|
+
this._skipRecord = shouldIgnoreNetwork(this._url) || !shouldRecordCustomEvents();
|
|
725
741
|
if (!this._skipRecord) {
|
|
726
742
|
record.addCustomEvent("network_request", {
|
|
727
743
|
type: "xhr",
|
|
@@ -739,6 +755,7 @@ var ActionLensRc = class {
|
|
|
739
755
|
return super.send(body);
|
|
740
756
|
}
|
|
741
757
|
this.addEventListener("load", () => {
|
|
758
|
+
if (!shouldRecordCustomEvents()) return;
|
|
742
759
|
const endTime = Date.now();
|
|
743
760
|
const duration = endTime - (this._startTime || 0);
|
|
744
761
|
record.addCustomEvent("network_response", {
|
|
@@ -752,6 +769,7 @@ var ActionLensRc = class {
|
|
|
752
769
|
});
|
|
753
770
|
});
|
|
754
771
|
this.addEventListener("error", () => {
|
|
772
|
+
if (!shouldRecordCustomEvents()) return;
|
|
755
773
|
const endTime = Date.now();
|
|
756
774
|
const duration = endTime - (this._startTime || 0);
|
|
757
775
|
record.addCustomEvent("network_error", {
|
|
@@ -773,48 +791,53 @@ var ActionLensRc = class {
|
|
|
773
791
|
super(url, protocols);
|
|
774
792
|
const wsUrl = url.toString();
|
|
775
793
|
this._skipRecord = shouldIgnoreNetwork(wsUrl);
|
|
776
|
-
if (
|
|
794
|
+
if (this._skipRecord) return;
|
|
795
|
+
if (shouldRecordCustomEvents()) {
|
|
777
796
|
record.addCustomEvent("network_websocket_open", {
|
|
778
797
|
type: "websocket",
|
|
779
798
|
url: wsUrl,
|
|
780
799
|
startTime: Date.now()
|
|
781
800
|
});
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
this.addEventListener("close", (event) => {
|
|
791
|
-
record.addCustomEvent("network_websocket_close", {
|
|
792
|
-
type: "websocket",
|
|
793
|
-
url: wsUrl,
|
|
794
|
-
code: event.code,
|
|
795
|
-
reason: event.reason,
|
|
796
|
-
endTime: Date.now()
|
|
797
|
-
});
|
|
801
|
+
}
|
|
802
|
+
this.addEventListener("message", (event) => {
|
|
803
|
+
if (!shouldRecordCustomEvents()) return;
|
|
804
|
+
record.addCustomEvent("network_websocket_message", {
|
|
805
|
+
type: "websocket",
|
|
806
|
+
url: wsUrl,
|
|
807
|
+
data: event.data,
|
|
808
|
+
time: Date.now()
|
|
798
809
|
});
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
810
|
+
});
|
|
811
|
+
this.addEventListener("close", (event) => {
|
|
812
|
+
if (!shouldRecordCustomEvents()) return;
|
|
813
|
+
record.addCustomEvent("network_websocket_close", {
|
|
814
|
+
type: "websocket",
|
|
815
|
+
url: wsUrl,
|
|
816
|
+
code: event.code,
|
|
817
|
+
reason: event.reason,
|
|
818
|
+
endTime: Date.now()
|
|
806
819
|
});
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
record.addCustomEvent("network_websocket_send", {
|
|
820
|
+
});
|
|
821
|
+
this.addEventListener("error", (event) => {
|
|
822
|
+
if (!shouldRecordCustomEvents()) return;
|
|
823
|
+
record.addCustomEvent("network_websocket_error", {
|
|
812
824
|
type: "websocket",
|
|
813
|
-
url:
|
|
814
|
-
|
|
825
|
+
url: wsUrl,
|
|
826
|
+
error: "WebSocket error",
|
|
815
827
|
time: Date.now()
|
|
816
828
|
});
|
|
829
|
+
});
|
|
830
|
+
}
|
|
831
|
+
send(data) {
|
|
832
|
+
if (this._skipRecord || !shouldRecordCustomEvents()) {
|
|
833
|
+
return super.send(data);
|
|
817
834
|
}
|
|
835
|
+
record.addCustomEvent("network_websocket_send", {
|
|
836
|
+
type: "websocket",
|
|
837
|
+
url: this.url,
|
|
838
|
+
data,
|
|
839
|
+
time: Date.now()
|
|
840
|
+
});
|
|
818
841
|
return super.send(data);
|
|
819
842
|
}
|
|
820
843
|
};
|
|
@@ -837,52 +860,61 @@ var ActionLensRc = class {
|
|
|
837
860
|
console.error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
|
|
838
861
|
return;
|
|
839
862
|
}
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
collection2(this.db, "ActionRecordSession"),
|
|
866
|
-
this.sessionId
|
|
867
|
-
);
|
|
868
|
-
await getDoc2(docRef).then(async (doc3) => {
|
|
869
|
-
if (doc3.exists()) {
|
|
870
|
-
const data = doc3.data();
|
|
871
|
-
const ipAddress = data?.ipAddress || "";
|
|
872
|
-
const placeData = await getPlaceFromIp(ipAddress);
|
|
873
|
-
await updateDoc(docRef, { place: placeData });
|
|
863
|
+
if (!this.isSessionInitialized) {
|
|
864
|
+
const ActionRecordSessionRef = doc2(
|
|
865
|
+
collection2(this.db, `${prefix}ActionRecordSession`),
|
|
866
|
+
_sessionId
|
|
867
|
+
);
|
|
868
|
+
await setDoc2(ActionRecordSessionRef, {
|
|
869
|
+
id: _sessionId,
|
|
870
|
+
startTime: /* @__PURE__ */ new Date(),
|
|
871
|
+
endTime: /* @__PURE__ */ new Date(),
|
|
872
|
+
recordTime: 0,
|
|
873
|
+
// 初期値は0
|
|
874
|
+
userId,
|
|
875
|
+
projectId: this.projectId || "",
|
|
876
|
+
organizationId: this.projectData?.organizationId || "",
|
|
877
|
+
createAt: /* @__PURE__ */ new Date(),
|
|
878
|
+
updateAt: /* @__PURE__ */ new Date(),
|
|
879
|
+
createdBy: userId,
|
|
880
|
+
updatedBy: userId
|
|
881
|
+
});
|
|
882
|
+
this.isSessionInitialized = true;
|
|
883
|
+
try {
|
|
884
|
+
console.log("setSessionDetail\u95A2\u6570\u3092\u547C\u3073\u51FA\u3057\u307E\u3059", this.sessionId);
|
|
885
|
+
await setSessionDetail({ sessionId: this.sessionId });
|
|
886
|
+
} catch (error) {
|
|
887
|
+
console.error("setSessionDetail\u95A2\u6570\u306E\u547C\u3073\u51FA\u3057\u306B\u5931\u6557:", error);
|
|
874
888
|
}
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
889
|
+
const docRef = doc2(
|
|
890
|
+
collection2(this.db, "ActionRecordSession"),
|
|
891
|
+
this.sessionId
|
|
892
|
+
);
|
|
893
|
+
await getDoc2(docRef).then(async (doc3) => {
|
|
894
|
+
if (doc3.exists()) {
|
|
895
|
+
const data = doc3.data();
|
|
896
|
+
const ipAddress = data?.ipAddress || "";
|
|
897
|
+
const placeData = await getPlaceFromIp(ipAddress);
|
|
898
|
+
await updateDoc(docRef, { place: placeData });
|
|
899
|
+
}
|
|
900
|
+
}).catch((error) => {
|
|
901
|
+
console.error("IP\u30A2\u30C9\u30EC\u30B9\u306E\u53D6\u5F97\u306B\u5931\u6557:", error);
|
|
902
|
+
});
|
|
903
|
+
}
|
|
878
904
|
this.stopFnForStore = record({
|
|
879
905
|
packFn: pack,
|
|
880
906
|
collectFonts: false,
|
|
881
907
|
inlineImages: false,
|
|
882
|
-
checkoutEveryNth:
|
|
908
|
+
checkoutEveryNth: 4e3,
|
|
909
|
+
slimDOMOptions: {
|
|
910
|
+
script: true,
|
|
911
|
+
comment: true,
|
|
912
|
+
headFavicon: true,
|
|
913
|
+
headWhitespace: true
|
|
914
|
+
},
|
|
883
915
|
sampling: {
|
|
884
|
-
canvas:
|
|
885
|
-
mousemove:
|
|
916
|
+
canvas: 5e3,
|
|
917
|
+
mousemove: 500
|
|
886
918
|
// mousemoveCallback: 1000,
|
|
887
919
|
},
|
|
888
920
|
emit: async (event) => {
|
|
@@ -918,20 +950,47 @@ var ActionLensRc = class {
|
|
|
918
950
|
},
|
|
919
951
|
recordCanvas: false
|
|
920
952
|
});
|
|
921
|
-
this.
|
|
922
|
-
this.
|
|
923
|
-
|
|
953
|
+
this.isRecordingPaused = false;
|
|
954
|
+
if (!this.areAuxRecordersStarted) {
|
|
955
|
+
this.startConsoleRecording();
|
|
956
|
+
this.startTimelineRecording();
|
|
957
|
+
this.startNetworkRecording();
|
|
958
|
+
this.areAuxRecordersStarted = true;
|
|
959
|
+
}
|
|
924
960
|
} catch (error) {
|
|
925
961
|
console.error("rrweb\u9332\u753B\u30A8\u30E9\u30FC:", error);
|
|
926
962
|
throw error;
|
|
927
963
|
}
|
|
928
964
|
}
|
|
965
|
+
pauseRrwebRecordingForStore() {
|
|
966
|
+
try {
|
|
967
|
+
this.isRecordingPaused = true;
|
|
968
|
+
if (this.stopFnForStore) {
|
|
969
|
+
this.stopFnForStore();
|
|
970
|
+
this.stopFnForStore = null;
|
|
971
|
+
}
|
|
972
|
+
} catch (error) {
|
|
973
|
+
console.error("rrweb\u9332\u753B\u4E00\u6642\u505C\u6B62\u30A8\u30E9\u30FC:", error);
|
|
974
|
+
throw error;
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
async resumeRrwebRecordingForStore() {
|
|
978
|
+
try {
|
|
979
|
+
if (this.stopFnForStore) return;
|
|
980
|
+
this.isRecordingPaused = false;
|
|
981
|
+
await this.startRrwebRecordingForStore();
|
|
982
|
+
} catch (error) {
|
|
983
|
+
console.error("rrweb\u9332\u753B\u518D\u958B\u30A8\u30E9\u30FC:", error);
|
|
984
|
+
throw error;
|
|
985
|
+
}
|
|
986
|
+
}
|
|
929
987
|
stopRrwebRecordingForStore() {
|
|
930
988
|
try {
|
|
931
989
|
if (this.stopFnForStore) {
|
|
932
990
|
this.stopFnForStore();
|
|
933
991
|
this.stopFnForStore = null;
|
|
934
992
|
}
|
|
993
|
+
this.isRecordingPaused = false;
|
|
935
994
|
} catch (error) {
|
|
936
995
|
console.error("rrweb\u9332\u753B\u505C\u6B62\u30A8\u30E9\u30FC:", error);
|
|
937
996
|
throw error;
|