action-lens 1.0.18 → 1.0.20

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 CHANGED
@@ -50,22 +50,15 @@ declare class ActionLensRc {
50
50
  projectData: Project | null;
51
51
  organizationId: string | null;
52
52
  originalUserId: string | null;
53
- /** イベントバッファとコミット閾値 */
54
- private eventBuffer;
55
- private readonly flushThreshold;
56
- constructor(_userId: string | null, projectId: string | null, _db?: Firestore | null, prefix?: string);
57
- initialize(prefix: string, projectId: string, _userId: string): Promise<void>;
58
- /** バッファ内イベントをまとめて Firestore に書き込む */
59
- private flushBuffer;
60
- /** コンソール呼び出しを rrweb カスタムイベントとして記録 */
53
+ constructor(_userId: string | null, projectId: string | null, userMeta: {
54
+ name: string;
55
+ email: string;
56
+ } | null, metaData?: Record<string, any>, _db?: Firestore | null, prefix?: string);
61
57
  startConsoleRecording(): void;
62
- /** rrweb を使って画面操作をバッファ&バッチ保存 */
58
+ startTimelineRecording(): void;
63
59
  startRrwebRecordingForStore(): void;
64
- /** 録画停止とバッファフラッシュ */
65
60
  stopRrwebRecordingForStore(): void;
66
- /** セッションの endTime を更新 */
67
61
  updateActionRecordSession(): void;
68
- startTimelineRecording(): void;
69
62
  }
70
63
 
71
64
  /** Timestampの時はDateへの変更 */
package/dist/index.d.ts CHANGED
@@ -50,22 +50,15 @@ declare class ActionLensRc {
50
50
  projectData: Project | null;
51
51
  organizationId: string | null;
52
52
  originalUserId: string | null;
53
- /** イベントバッファとコミット閾値 */
54
- private eventBuffer;
55
- private readonly flushThreshold;
56
- constructor(_userId: string | null, projectId: string | null, _db?: Firestore | null, prefix?: string);
57
- initialize(prefix: string, projectId: string, _userId: string): Promise<void>;
58
- /** バッファ内イベントをまとめて Firestore に書き込む */
59
- private flushBuffer;
60
- /** コンソール呼び出しを rrweb カスタムイベントとして記録 */
53
+ constructor(_userId: string | null, projectId: string | null, userMeta: {
54
+ name: string;
55
+ email: string;
56
+ } | null, metaData?: Record<string, any>, _db?: Firestore | null, prefix?: string);
61
57
  startConsoleRecording(): void;
62
- /** rrweb を使って画面操作をバッファ&バッチ保存 */
58
+ startTimelineRecording(): void;
63
59
  startRrwebRecordingForStore(): void;
64
- /** 録画停止とバッファフラッシュ */
65
60
  stopRrwebRecordingForStore(): void;
66
- /** セッションの endTime を更新 */
67
61
  updateActionRecordSession(): void;
68
- startTimelineRecording(): void;
69
62
  }
70
63
 
71
64
  /** Timestampの時はDateへの変更 */
package/dist/index.js CHANGED
@@ -290,136 +290,213 @@ var ActionLensRc = class {
290
290
  projectData = null;
291
291
  organizationId = null;
292
292
  originalUserId = null;
293
- /** イベントバッファとコミット閾値 */
294
- eventBuffer = [];
295
- flushThreshold = 50;
296
- constructor(_userId, projectId, _db = null, prefix = "") {
297
- if (!!this.originalUserId) {
298
- console.warn("ActionLensRc\u306F\u4E00\u5EA6\u3060\u3051\u521D\u671F\u5316\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
299
- return;
293
+ // 元のユーザーID(外部システムのIDなど)
294
+ constructor(_userId, projectId, userMeta, metaData = {}, _db = null, prefix = "") {
295
+ try {
296
+ this.originalUserId = _userId;
297
+ console.log("ActionLensRc\u958B\u59CB");
298
+ if (!projectId) {
299
+ console.error("projectId\u304CNULL\u3067\u3059");
300
+ throw new Error("projectId\u304CNULL\u3067\u3059");
301
+ }
302
+ if (!_userId) {
303
+ console.error("userId\u304CNULL\u3067\u3059");
304
+ throw new Error("userId\u304CNULL\u3067\u3059");
305
+ }
306
+ if (!_db) {
307
+ this.db = db;
308
+ } else {
309
+ this.db = _db;
310
+ }
311
+ (0, import_firestore3.getDoc)((0, import_firestore3.doc)((0, import_firestore3.collection)(this.db, `${prefix}project`), projectId)).then(async (_doc) => {
312
+ this.projectData = _doc.data();
313
+ const projectData = this.projectData;
314
+ this.organizationId = projectData?.organizationId || null;
315
+ if (!_db) {
316
+ this.db = db;
317
+ } else {
318
+ this.db = _db;
319
+ }
320
+ if (!this.projectData) {
321
+ await (0, import_firestore3.setDoc)(
322
+ (0, import_firestore3.doc)((0, import_firestore3.collection)(this.db, `${prefix}project`), projectId),
323
+ {
324
+ id: projectId,
325
+ name: projectId,
326
+ organizationId: "",
327
+ isActivate: false,
328
+ // デフォルトでアクティブに設定
329
+ createAt: /* @__PURE__ */ new Date(),
330
+ updateAt: /* @__PURE__ */ new Date(),
331
+ createdBy: _userId,
332
+ updatedBy: _userId
333
+ },
334
+ { merge: true }
335
+ );
336
+ throw new Error("\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u304C\u5B58\u5728\u3057\u307E\u305B\u3093");
337
+ }
338
+ if (!this.projectData.isActivate) {
339
+ console.warn(
340
+ "\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306F\u975E\u30A2\u30AF\u30C6\u30A3\u30D6\u3067\u3059\u3002\u9332\u753B\u3092\u958B\u59CB\u3067\u304D\u307E\u305B\u3093\u3002"
341
+ );
342
+ throw new Error(
343
+ "\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306F\u975E\u30A2\u30AF\u30C6\u30A3\u30D6\u3067\u3059\u3002\u9332\u753B\u3092\u958B\u59CB\u3067\u304D\u307E\u305B\u3093\u3002"
344
+ );
345
+ }
346
+ (0, import_firestore3.getDoc)((0, import_firestore3.doc)((0, import_firestore3.collection)(this.db, `${prefix}user`), _userId)).then(async (_doc2) => {
347
+ if (!this.db) {
348
+ console.error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
349
+ throw new Error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
350
+ }
351
+ this.userId = projectData.organizationId + "-" + _userId;
352
+ const userData = _doc2.data();
353
+ if (!_doc2.exists || !userData.organizationId || !userData.projectIds || !userData.type) {
354
+ await (0, import_firestore3.setDoc)(
355
+ (0, import_firestore3.doc)(
356
+ (0, import_firestore3.collection)(this.db, `${prefix}user`),
357
+ projectData.organizationId + "-" + _userId
358
+ ),
359
+ {
360
+ ...userMeta || {},
361
+ metaData,
362
+ id: projectData.organizationId + "-" + _userId,
363
+ originalUserId: _userId,
364
+ type: "customer",
365
+ organizationId: projectData.organizationId,
366
+ projectIds: [projectId],
367
+ createAt: /* @__PURE__ */ new Date(),
368
+ updateAt: /* @__PURE__ */ new Date(),
369
+ createdBy: _userId,
370
+ updatedBy: _userId,
371
+ hidden: false,
372
+ hiddenBy: ""
373
+ },
374
+ { merge: true }
375
+ ).catch((error) => {
376
+ console.error("Error creating document: ", error);
377
+ throw new Error("\u30E6\u30FC\u30B6\u30FC\u306E\u4F5C\u6210\u306B\u5931\u6557\u3057\u307E\u3057\u305F");
378
+ });
379
+ this.userData = _doc2.data();
380
+ } else {
381
+ this.userData = _doc2.data();
382
+ if (!this.userData?.projectIds?.includes(projectId)) {
383
+ await (0, import_firestore3.setDoc)(
384
+ (0, import_firestore3.doc)(
385
+ (0, import_firestore3.collection)(this.db, `${prefix}user`),
386
+ projectData.organizationId + "-" + _userId
387
+ ),
388
+ {
389
+ projectIds: [
390
+ ...this.userData?.projectIds || [],
391
+ projectId
392
+ ],
393
+ updateAt: /* @__PURE__ */ new Date(),
394
+ updatedBy: this.userId
395
+ },
396
+ { merge: true }
397
+ ).catch((error) => {
398
+ console.error("Error updating document: ", error);
399
+ throw new Error(
400
+ "\u30E6\u30FC\u30B6\u30FC\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8ID\u306E\u66F4\u65B0\u306B\u5931\u6557\u3057\u307E\u3057\u305F"
401
+ );
402
+ });
403
+ }
404
+ if (this.userData?.organizationId !== projectData.organizationId) {
405
+ await (0, import_firestore3.setDoc)(
406
+ (0, import_firestore3.doc)(
407
+ (0, import_firestore3.collection)(this.db, `${prefix}user`),
408
+ projectData.organizationId + "-" + _userId
409
+ ),
410
+ {
411
+ organizationId: this.userData?.organizationId ? this.userData?.organizationId : projectData.organizationId,
412
+ updateAt: /* @__PURE__ */ new Date(),
413
+ updatedBy: this.userId
414
+ },
415
+ { merge: true }
416
+ ).catch((error) => {
417
+ console.error("Error updating document: ", error);
418
+ throw new Error("\u30E6\u30FC\u30B6\u30FC\u306E\u7D44\u7E54ID\u306E\u66F4\u65B0\u306B\u5931\u6557\u3057\u307E\u3057\u305F");
419
+ });
420
+ }
421
+ }
422
+ this.prefix = prefix;
423
+ this.projectId = projectId;
424
+ this.startRrwebRecordingForStore();
425
+ }).catch((error) => {
426
+ console.error("\u30E6\u30FC\u30B6\u30FC\u30C7\u30FC\u30BF\u306E\u53D6\u5F97\u30A8\u30E9\u30FC:", error);
427
+ throw new Error("\u30E6\u30FC\u30B6\u30FC\u30C7\u30FC\u30BF\u306E\u53D6\u5F97\u306B\u5931\u6557\u3057\u307E\u3057\u305F");
428
+ });
429
+ }).catch((error) => {
430
+ console.error("\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u30C7\u30FC\u30BF\u306E\u53D6\u5F97\u30A8\u30E9\u30FC:", error);
431
+ throw new Error("\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u30C7\u30FC\u30BF\u306E\u53D6\u5F97\u306B\u5931\u6557\u3057\u307E\u3057\u305F");
432
+ });
433
+ } catch (error) {
434
+ console.error("\u521D\u671F\u5316\u30A8\u30E9\u30FC:", error);
435
+ throw error;
300
436
  }
301
- this.originalUserId = _userId;
302
- this.db = _db || db;
303
- this.initialize(prefix, projectId, _userId);
304
437
  }
305
- async initialize(prefix, projectId, _userId) {
306
- if (!this.db) {
307
- this.db = db;
308
- }
309
- const _proj = await (0, import_firestore3.getDoc)(
310
- (0, import_firestore3.doc)((0, import_firestore3.collection)(this.db, `${prefix}project`), projectId)
311
- );
312
- this.projectData = _proj.data();
313
- this.organizationId = this.projectData?.organizationId || null;
314
- if (!this.db) {
315
- this.db = db;
316
- }
317
- const _usr = await (0, import_firestore3.getDoc)(
318
- (0, import_firestore3.doc)((0, import_firestore3.collection)(this.db, `${prefix}user`), _userId)
319
- );
320
- this.userId = `${this.organizationId}-${_userId}`;
321
- this.prefix = prefix;
322
- this.projectId = projectId;
323
- this.startRrwebRecordingForStore();
324
- this.startConsoleRecording();
325
- }
326
- /** バッファ内イベントをまとめて Firestore に書き込む */
327
- flushBuffer() {
328
- if (!this.db || this.eventBuffer.length === 0) return;
329
- const batch = (0, import_firestore3.writeBatch)(this.db);
330
- this.eventBuffer.forEach((rec) => {
331
- const ref = (0, import_firestore3.doc)((0, import_firestore3.collection)(this.db, `${this.prefix}ActionRecord`));
332
- batch.set(ref, rec);
333
- });
334
- batch.commit().catch((e) => console.error("Batch commit error:", e));
335
- this.eventBuffer = [];
336
- }
337
- /** コンソール呼び出しを rrweb カスタムイベントとして記録 */
438
+ // コンソールログをキャプチャ
338
439
  startConsoleRecording() {
339
- const methods = ["log", "info", "warn", "error", "debug", "trace"];
340
- const original = {};
341
- methods.forEach((m) => {
342
- original[m] = console[m].bind(console);
343
- console[m] = (...args) => {
344
- original[m](...args);
345
- import_rrweb2.record.addCustomEvent("console", { method: m, args });
346
- this.updateActionRecordSession();
347
- };
348
- });
349
- }
350
- /** rrweb を使って画面操作をバッファ&バッチ保存 */
351
- startRrwebRecordingForStore() {
352
- if (this.stopFnForStore) return;
353
- const userId = this.userId || "unknown";
354
- const originalUserId = this.originalUserId || "";
355
- const sessionId = this.sessionId;
356
- const db2 = this.db;
357
- const prefix = this.prefix;
358
- (0, import_firestore3.setDoc)((0, import_firestore3.doc)((0, import_firestore3.collection)(db2, `${prefix}ActionRecordSession`), sessionId), {
359
- id: sessionId,
360
- startTime: /* @__PURE__ */ new Date(),
361
- endTime: null,
362
- userId,
363
- projectId: this.projectId,
364
- organizationId: this.projectData?.organizationId || null,
365
- createAt: /* @__PURE__ */ new Date(),
366
- updateAt: /* @__PURE__ */ new Date(),
367
- createdBy: userId,
368
- updatedBy: userId
369
- }).catch((e) => console.error(e));
370
- this.stopFnForStore = (0, import_rrweb2.record)({
371
- collectFonts: true,
372
- inlineImages: false,
373
- sampling: { canvas: 500, mousemove: 500, scroll: 500 },
374
- emit: (event) => {
375
- const rec = {
376
- id: (0, import_firestore3.doc)((0, import_firestore3.collection)(db2, `${prefix}ActionRecord`)).id,
377
- timeStamp: /* @__PURE__ */ new Date(),
378
- userId,
379
- originalUserId,
380
- sessionId,
381
- type: "rrweb",
382
- rrwebRecord: JSON.stringify(event),
383
- createAt: /* @__PURE__ */ new Date(),
384
- updateAt: /* @__PURE__ */ new Date(),
385
- hidden: false,
386
- createdBy: userId,
387
- updatedBy: userId,
388
- hiddenBy: ""
440
+ try {
441
+ const originalConsole = { ...console };
442
+ const consoleMethods = [
443
+ "log",
444
+ "info",
445
+ "warn",
446
+ "error",
447
+ "debug",
448
+ "trace",
449
+ "assert",
450
+ "clear",
451
+ "context",
452
+ "count",
453
+ "countReset",
454
+ "createTask",
455
+ "debug",
456
+ "dir",
457
+ "dirxml",
458
+ "error",
459
+ "group",
460
+ "groupCollapsed",
461
+ "groupEnd",
462
+ "memory",
463
+ "profile",
464
+ "profileEnd",
465
+ "table",
466
+ "time",
467
+ "timeEnd",
468
+ "timeLog",
469
+ "timeStamp"
470
+ ];
471
+ const db2 = this.db;
472
+ const _updateActionRecordSession = () => this.updateActionRecordSession();
473
+ consoleMethods.forEach((method) => {
474
+ console[method] = (...args) => {
475
+ originalConsole[method](...args);
476
+ if (!db2) {
477
+ console.error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
478
+ return;
479
+ }
480
+ const consoleEvent = {
481
+ type: "custom-event",
482
+ data: {
483
+ type: "console",
484
+ method,
485
+ args: args.map(
486
+ (arg) => typeof arg === "object" ? JSON.stringify(arg) : arg
487
+ )
488
+ },
489
+ timestamp: Date.now()
490
+ };
491
+ import_rrweb2.record.addCustomEvent("console", { method: "log", args });
492
+ _updateActionRecordSession();
389
493
  };
390
- this.eventBuffer.push(rec);
391
- (0, import_firestore3.setDoc)(
392
- (0, import_firestore3.doc)((0, import_firestore3.collection)(db2, `${prefix}ActionRecordSession`), sessionId),
393
- { endTime: /* @__PURE__ */ new Date(), updateAt: /* @__PURE__ */ new Date(), updatedBy: userId },
394
- { merge: true }
395
- ).catch((e) => console.error(e));
396
- },
397
- recordCanvas: false
398
- });
399
- setInterval(() => {
400
- this.flushBuffer();
401
- }, 5e3);
402
- }
403
- /** 録画停止とバッファフラッシュ */
404
- stopRrwebRecordingForStore() {
405
- if (this.stopFnForStore) {
406
- this.stopFnForStore();
407
- this.stopFnForStore = null;
408
- this.flushBuffer();
494
+ });
495
+ } catch (error) {
496
+ console.error("\u30B3\u30F3\u30BD\u30FC\u30EB\u9332\u753B\u30A8\u30E9\u30FC:", error);
497
+ throw error;
409
498
  }
410
499
  }
411
- /** セッションの endTime を更新 */
412
- updateActionRecordSession() {
413
- if (!this.db || !this.sessionId || !this.userId) return;
414
- (0, import_firestore3.setDoc)(
415
- (0, import_firestore3.doc)(
416
- (0, import_firestore3.collection)(this.db, `${this.prefix}ActionRecordSession`),
417
- this.sessionId
418
- ),
419
- { endTime: /* @__PURE__ */ new Date(), updateAt: /* @__PURE__ */ new Date(), updatedBy: this.userId },
420
- { merge: true }
421
- ).catch((e) => console.error(e));
422
- }
423
500
  // タイムライン(ナビゲーションとパフォーマンス)をキャプチャ
424
501
  startTimelineRecording() {
425
502
  try {
@@ -509,6 +586,110 @@ var ActionLensRc = class {
509
586
  throw error;
510
587
  }
511
588
  }
589
+ startRrwebRecordingForStore() {
590
+ try {
591
+ if (this.stopFnForStore) return;
592
+ const _sessionId = this.sessionId;
593
+ const userId = this.userId || "unknown";
594
+ const originalUserId = this.originalUserId || "";
595
+ const db2 = this.db;
596
+ const prefix = this.prefix;
597
+ if (!db2) {
598
+ console.error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
599
+ return;
600
+ }
601
+ const ActionRecordSessionRef = (0, import_firestore3.doc)(
602
+ (0, import_firestore3.collection)(db2, `${prefix}ActionRecordSession`),
603
+ _sessionId
604
+ );
605
+ (0, import_firestore3.setDoc)(ActionRecordSessionRef, {
606
+ id: _sessionId,
607
+ startTime: /* @__PURE__ */ new Date(),
608
+ endTime: null,
609
+ userId,
610
+ projectId: this.projectId || null,
611
+ organizationId: this.projectData?.organizationId || null,
612
+ createAt: /* @__PURE__ */ new Date(),
613
+ updateAt: /* @__PURE__ */ new Date(),
614
+ createdBy: userId,
615
+ updatedBy: userId
616
+ });
617
+ const _updateActionRecordSession = () => this.updateActionRecordSession();
618
+ this.stopFnForStore = (0, import_rrweb2.record)({
619
+ collectFonts: true,
620
+ inlineImages: true,
621
+ sampling: {
622
+ canvas: 50,
623
+ mousemove: true
624
+ },
625
+ emit(event) {
626
+ const newDocRef = (0, import_firestore3.doc)((0, import_firestore3.collection)(db2, `${prefix}ActionRecord`));
627
+ const record2 = {
628
+ id: newDocRef.id,
629
+ timeStamp: /* @__PURE__ */ new Date(),
630
+ userId,
631
+ originalUserId,
632
+ type: "rrweb",
633
+ sessionId: _sessionId,
634
+ rrwebRecord: JSON.stringify(event),
635
+ createAt: /* @__PURE__ */ new Date(),
636
+ updateAt: /* @__PURE__ */ new Date(),
637
+ hidden: false,
638
+ createdBy: userId,
639
+ updatedBy: userId,
640
+ hiddenBy: ""
641
+ };
642
+ (0, import_firestore3.setDoc)(newDocRef, record2).catch((error) => {
643
+ console.error("Error saving rrweb event: ", error);
644
+ });
645
+ _updateActionRecordSession();
646
+ },
647
+ recordCanvas: false
648
+ });
649
+ } catch (error) {
650
+ console.error("rrweb\u9332\u753B\u30A8\u30E9\u30FC:", error);
651
+ throw error;
652
+ }
653
+ }
654
+ stopRrwebRecordingForStore() {
655
+ try {
656
+ if (this.stopFnForStore) {
657
+ this.stopFnForStore();
658
+ this.stopFnForStore = null;
659
+ }
660
+ } catch (error) {
661
+ console.error("rrweb\u9332\u753B\u505C\u6B62\u30A8\u30E9\u30FC:", error);
662
+ throw error;
663
+ }
664
+ }
665
+ updateActionRecordSession() {
666
+ try {
667
+ if (!this.db || !this.sessionId || !this.userId) {
668
+ console.error(
669
+ "Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3001\u307E\u305F\u306FsessionId\u3001userId\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093"
670
+ );
671
+ return;
672
+ }
673
+ const ActionRecordSessionRef = (0, import_firestore3.doc)(
674
+ (0, import_firestore3.collection)(this.db, `${this.prefix}ActionRecordSession`),
675
+ this.sessionId
676
+ );
677
+ (0, import_firestore3.setDoc)(
678
+ ActionRecordSessionRef,
679
+ {
680
+ endTime: /* @__PURE__ */ new Date(),
681
+ updateAt: /* @__PURE__ */ new Date(),
682
+ updatedBy: this.userId
683
+ },
684
+ { merge: true }
685
+ ).catch((error) => {
686
+ console.error("Error updating ActionRecordSession: ", error);
687
+ });
688
+ } catch (error) {
689
+ console.error("ActionRecordSession\u66F4\u65B0\u30A8\u30E9\u30FC:", error);
690
+ throw error;
691
+ }
692
+ }
512
693
  };
513
694
 
514
695
  // src/utils/date.ts