action-lens 1.0.51 → 1.0.53

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.mjs CHANGED
@@ -312,160 +312,166 @@ import {
312
312
  doc as doc2,
313
313
  setDoc as setDoc2,
314
314
  collection as collection2,
315
- getDoc as getDoc2
315
+ getDoc as getDoc2,
316
+ getFirestore as getFirestore2,
317
+ writeBatch,
318
+ enableIndexedDbPersistence
316
319
  } from "firebase/firestore";
317
320
  import { pack } from "@rrweb/packer";
321
+ import { initializeApp as initializeApp2 } from "firebase/app";
318
322
  var ActionLensRc = class {
319
323
  sessionId = uuidv4();
320
324
  stopFnForStore = null;
321
325
  userId = null;
322
- db = db;
326
+ db;
323
327
  prefix = "";
324
328
  userData = null;
325
329
  projectId = null;
326
330
  projectData = null;
327
331
  organizationId = null;
328
332
  originalUserId = null;
329
- // 元のユーザーID(外部システムのIDなど)
330
333
  userMeta = {};
331
334
  metaData = {};
332
335
  constructor() {
336
+ const app2 = initializeApp2(firebaseConfig);
337
+ this.db = getFirestore2(app2);
338
+ enableIndexedDbPersistence(this.db).catch((err) => {
339
+ console.warn("Persistence error:", err.message);
340
+ });
341
+ }
342
+ async retryOperation(operation, maxAttempts = 3, delay = 1e3) {
343
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
344
+ try {
345
+ return await operation();
346
+ } catch (error) {
347
+ if (attempt === maxAttempts) throw error;
348
+ console.warn(`Retry ${attempt}/${maxAttempts} failed:`, error);
349
+ await new Promise((resolve) => setTimeout(resolve, delay));
350
+ }
351
+ }
352
+ throw new Error("Retry operation failed");
333
353
  }
334
354
  async init(_userId, projectId, userMeta, metaData = {}, _db = null, prefix = "") {
335
355
  try {
356
+ if (_db) {
357
+ this.db = _db;
358
+ }
359
+ if (!this.db) {
360
+ throw new Error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
361
+ }
336
362
  this.originalUserId = _userId;
337
363
  console.log("ActionLensRc\u958B\u59CB");
338
- if (!projectId) {
339
- console.error("projectId\u304CNULL\u3067\u3059");
340
- throw new Error("projectId\u304CNULL\u3067\u3059");
341
- }
342
364
  this.projectId = projectId;
343
365
  this.prefix = prefix;
344
366
  this.userMeta = userMeta;
345
367
  this.metaData = metaData;
346
368
  if (!_userId) {
347
- console.error("userId\u304CNULL\u3067\u3059");
348
369
  throw new Error("userId\u304CNULL\u3067\u3059");
349
370
  }
350
- if (!this.db && _db) {
351
- console.error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
352
- this.db = _db;
353
- }
354
- if (!this.db) {
355
- console.error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
356
- throw new Error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
357
- }
358
371
  if (!this.projectId) {
359
- console.error("projectId\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
360
- throw new Error("projectId\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
372
+ throw new Error("projectId\u304CNULL\u3067\u3059");
361
373
  }
362
- const _doc = await getDoc2(
363
- doc2(collection2(this.db, `${this.prefix}project`), this.projectId)
374
+ const projectDocRef = doc2(
375
+ collection2(this.db, `${this.prefix}project`),
376
+ this.projectId
364
377
  );
365
- this.projectData = _doc.data();
366
- const projectData = this.projectData;
367
- this.organizationId = projectData?.organizationId || "";
378
+ const projectDoc = await this.retryOperation(() => getDoc2(projectDocRef));
379
+ this.projectData = projectDoc.exists() ? projectDoc.data() : null;
368
380
  if (!this.projectData) {
369
- await setDoc2(
370
- doc2(collection2(this.db, `${this.prefix}project`), this.projectId),
371
- {
372
- id: this.projectId,
373
- name: this.projectId,
374
- organizationId: "",
375
- isActivate: false,
376
- // デフォルトでアクティブに設定
377
- createAt: /* @__PURE__ */ new Date(),
378
- updateAt: /* @__PURE__ */ new Date(),
379
- createdBy: this.originalUserId,
380
- updatedBy: this.originalUserId
381
- },
382
- { merge: true }
381
+ await this.retryOperation(
382
+ () => setDoc2(
383
+ projectDocRef,
384
+ {
385
+ id: this.projectId,
386
+ name: this.projectId,
387
+ organizationId: "",
388
+ isActivate: false,
389
+ createAt: /* @__PURE__ */ new Date(),
390
+ updateAt: /* @__PURE__ */ new Date(),
391
+ createdBy: this.originalUserId,
392
+ updatedBy: this.originalUserId
393
+ },
394
+ { merge: true }
395
+ )
383
396
  );
384
397
  throw new Error("\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u304C\u5B58\u5728\u3057\u307E\u305B\u3093");
385
398
  }
386
- if (!this.projectData?.isActivate) {
387
- console.warn("\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");
399
+ if (!this.projectData.isActivate) {
388
400
  throw new Error(
389
401
  "\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"
390
402
  );
391
403
  }
392
- this.userId = projectData.organizationId + "-" + this.originalUserId;
393
- this.prefix = this.prefix;
394
- this.projectId = this.projectId;
395
- const user = await getDoc2(
396
- doc2(collection2(this.db, `${this.prefix}user`), this.userId)
404
+ this.organizationId = this.projectData.organizationId || "";
405
+ this.userId = `${this.projectData.organizationId}-${this.originalUserId}`;
406
+ const userDocRef = doc2(
407
+ collection2(this.db, `${this.prefix}user`),
408
+ this.userId
397
409
  );
398
- if (!this.db) {
399
- console.error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
400
- throw new Error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
401
- }
402
- const userData = user.data();
403
- if (!userData.id || !user.exists()) {
404
- await setDoc2(
405
- doc2(
406
- collection2(this.db, `${this.prefix}user`),
407
- projectData.organizationId + "-" + this.originalUserId
408
- ),
409
- {
410
- ...this.userMeta || {},
411
- metaData: this.metaData,
412
- id: this.userId,
413
- originalUserId: this.originalUserId,
414
- type: "customer",
415
- organizationId: projectData?.organizationId || "",
416
- projectIds: [this.projectId],
417
- createAt: /* @__PURE__ */ new Date(),
418
- updateAt: /* @__PURE__ */ new Date(),
419
- createdBy: this.userId,
420
- updatedBy: this.userId,
421
- hidden: false,
422
- hiddenBy: ""
423
- },
424
- { merge: true }
425
- );
426
- this.userData = user.data();
427
- } else {
428
- this.userData = user.data();
429
- if (!this.userData?.projectIds?.includes(this.projectId || "")) {
430
- await setDoc2(
431
- doc2(
432
- collection2(this.db, `${this.prefix}user`),
433
- projectData.organizationId + "-" + this.originalUserId
434
- ),
410
+ const userDoc = await this.retryOperation(() => getDoc2(userDocRef));
411
+ this.userData = userDoc.exists() ? userDoc.data() : null;
412
+ if (!this.userData || !userDoc.exists()) {
413
+ await this.retryOperation(
414
+ () => setDoc2(
415
+ userDocRef,
435
416
  {
436
- projectIds: [
437
- ...this.userData?.projectIds || [],
438
- this.projectId
439
- ],
417
+ ...this.userMeta,
418
+ metaData: this.metaData,
419
+ id: this.userId,
420
+ originalUserId: this.originalUserId,
421
+ type: "customer",
422
+ organizationId: this.projectData?.organizationId || "",
423
+ projectIds: [this.projectId],
424
+ createAt: /* @__PURE__ */ new Date(),
440
425
  updateAt: /* @__PURE__ */ new Date(),
441
- updatedBy: this.userId
426
+ createdBy: this.userId,
427
+ updatedBy: this.userId,
428
+ hidden: false,
429
+ hiddenBy: ""
442
430
  },
443
431
  { merge: true }
432
+ )
433
+ );
434
+ const updatedUserDoc = await this.retryOperation(
435
+ () => getDoc2(userDocRef)
436
+ );
437
+ this.userData = updatedUserDoc.data();
438
+ } else {
439
+ if (!this.userData.projectIds?.includes(this.projectId)) {
440
+ await this.retryOperation(
441
+ () => setDoc2(
442
+ userDocRef,
443
+ {
444
+ projectIds: [
445
+ ...this.userData?.projectIds || [],
446
+ this.projectId
447
+ ],
448
+ updateAt: /* @__PURE__ */ new Date(),
449
+ updatedBy: this.userId
450
+ },
451
+ { merge: true }
452
+ )
444
453
  );
445
454
  }
446
- if (this.userData?.organizationId !== projectData.organizationId) {
447
- await setDoc2(
448
- doc2(
449
- collection2(this.db, `${this.prefix}user`),
450
- projectData.organizationId + "-" + this.originalUserId
451
- ),
452
- {
453
- organizationId: projectData.organizationId ? projectData.organizationId : this.userData?.organizationId,
454
- updateAt: /* @__PURE__ */ new Date(),
455
- updatedBy: this.userId
456
- },
457
- { merge: true }
455
+ if (this.userData.organizationId !== this.projectData.organizationId) {
456
+ await this.retryOperation(
457
+ () => setDoc2(
458
+ userDocRef,
459
+ {
460
+ organizationId: this.projectData?.organizationId || this.userData?.organizationId,
461
+ updateAt: /* @__PURE__ */ new Date(),
462
+ updatedBy: this.userId
463
+ },
464
+ { merge: true }
465
+ )
458
466
  );
459
467
  }
460
468
  }
461
469
  await this.startRrwebRecordingForStore();
462
- return;
463
470
  } catch (error) {
464
471
  console.error("\u521D\u671F\u5316\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F:", error);
465
472
  throw error;
466
473
  }
467
474
  }
468
- // コンソールログをキャプチャ
469
475
  startConsoleRecording() {
470
476
  try {
471
477
  const originalConsole = { ...console };
@@ -475,33 +481,19 @@ var ActionLensRc = class {
475
481
  "warn",
476
482
  "error",
477
483
  "debug",
478
- "trace",
479
- "assert",
480
- "clear",
481
- "context",
482
- "count",
483
- "countReset",
484
- "createTask",
485
- "debug",
486
- "dir",
487
- "dirxml",
488
- "error",
489
- "group",
490
- "groupCollapsed",
491
- "groupEnd",
492
- "memory",
493
- "profile",
494
- "profileEnd",
495
- "table",
496
- "time",
497
- "timeEnd",
498
- "timeLog",
499
- "timeStamp"
484
+ "trace"
500
485
  ];
501
486
  consoleMethods.forEach((method) => {
502
487
  console[method] = (...args) => {
503
- originalConsole[method](...args);
504
- record.addCustomEvent("console", { method: "log", args });
488
+ try {
489
+ originalConsole[method](...args);
490
+ record.addCustomEvent("console", { method, args });
491
+ } catch (error) {
492
+ originalConsole.error(
493
+ "\u30B3\u30F3\u30BD\u30FC\u30EB\u30A4\u30D9\u30F3\u30C8\u8A18\u9332\u30A8\u30E9\u30FC:",
494
+ error
495
+ );
496
+ }
505
497
  };
506
498
  });
507
499
  } catch (error) {
@@ -509,32 +501,39 @@ var ActionLensRc = class {
509
501
  throw error;
510
502
  }
511
503
  }
512
- // タイムライン(ナビゲーションとパフォーマンス)をキャプチャ
513
504
  startTimelineRecording() {
514
505
  try {
515
506
  const userId = this.userId || "unknown";
516
507
  const sessionId = this.sessionId;
517
508
  const db2 = this.db;
518
509
  const prefix = this.prefix;
510
+ if (!db2) {
511
+ console.error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
512
+ return;
513
+ }
519
514
  window.addEventListener("popstate", (event) => {
520
- if (!db2) {
521
- console.error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
522
- return;
515
+ try {
516
+ record.addCustomEvent("navigation", {
517
+ url: window.location.href,
518
+ state: event.state
519
+ });
520
+ } catch (error) {
521
+ console.error("\u30CA\u30D3\u30B2\u30FC\u30B7\u30E7\u30F3\u30A4\u30D9\u30F3\u30C8\u8A18\u9332\u30A8\u30E9\u30FC:", error);
523
522
  }
524
- record.addCustomEvent("navigation", {
525
- url: window.location.href,
526
- state: event.state
527
- });
528
523
  });
529
524
  if (window.performance) {
530
525
  const observer = new PerformanceObserver((list) => {
531
526
  for (const entry of list.getEntries()) {
532
- record.addCustomEvent("performance", {
533
- name: entry.name,
534
- entryType: entry.entryType,
535
- startTime: entry.startTime,
536
- duration: entry.duration
537
- });
527
+ try {
528
+ record.addCustomEvent("performance", {
529
+ name: entry.name,
530
+ entryType: entry.entryType,
531
+ startTime: entry.startTime,
532
+ duration: entry.duration
533
+ });
534
+ } catch (error) {
535
+ console.error("\u30D1\u30D5\u30A9\u30FC\u30DE\u30F3\u30B9\u30A4\u30D9\u30F3\u30C8\u8A18\u9332\u30A8\u30E9\u30FC:", error);
536
+ }
538
537
  }
539
538
  });
540
539
  observer.observe({ entryTypes: ["resource", "navigation", "paint"] });
@@ -553,26 +552,27 @@ var ActionLensRc = class {
553
552
  const db2 = this.db;
554
553
  const prefix = this.prefix;
555
554
  if (!db2) {
556
- console.error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
557
- return;
555
+ throw new Error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
558
556
  }
559
557
  const ActionRecordSessionRef = doc2(
560
558
  collection2(db2, `${prefix}ActionRecordSession`),
561
559
  _sessionId
562
560
  );
563
- await setDoc2(ActionRecordSessionRef, {
564
- id: _sessionId,
565
- startTime: /* @__PURE__ */ new Date(),
566
- endTime: /* @__PURE__ */ new Date(),
567
- userId,
568
- projectId: this.projectId || "",
569
- organizationId: this.projectData?.organizationId || "",
570
- createAt: /* @__PURE__ */ new Date(),
571
- updateAt: /* @__PURE__ */ new Date(),
572
- createdBy: userId,
573
- updatedBy: userId
574
- });
575
- const _updateActionRecordSession = async () => await this.updateActionRecordSession();
561
+ await this.retryOperation(
562
+ () => setDoc2(ActionRecordSessionRef, {
563
+ id: _sessionId,
564
+ startTime: /* @__PURE__ */ new Date(),
565
+ endTime: /* @__PURE__ */ new Date(),
566
+ userId,
567
+ projectId: this.projectId || "",
568
+ organizationId: this.projectData?.organizationId || "",
569
+ createAt: /* @__PURE__ */ new Date(),
570
+ updateAt: /* @__PURE__ */ new Date(),
571
+ createdBy: userId,
572
+ updatedBy: userId
573
+ }).then(() => console.log(`ActionRecordSession created: ${_sessionId}`))
574
+ );
575
+ const events = [];
576
576
  this.stopFnForStore = record({
577
577
  packFn: pack,
578
578
  collectFonts: true,
@@ -600,18 +600,38 @@ var ActionLensRc = class {
600
600
  updatedBy: userId,
601
601
  hiddenBy: ""
602
602
  };
603
- await setDoc2(newDocRef, record2);
604
- await _updateActionRecordSession();
603
+ events.push(record2);
604
+ if (events.length >= 10) {
605
+ const batch = writeBatch(db2);
606
+ events.forEach((evt) => {
607
+ const docRef = doc2(
608
+ collection2(db2, `${prefix}ActionRecord`),
609
+ evt.id
610
+ );
611
+ batch.set(docRef, evt);
612
+ });
613
+ await this.retryOperation(
614
+ () => batch.commit().then(
615
+ () => console.log(
616
+ `Batch write completed for ${events.length} events`
617
+ )
618
+ )
619
+ );
620
+ events.length = 0;
621
+ await this.updateActionRecordSession();
622
+ }
605
623
  } catch (error) {
606
- console.error("rrweb\u30A4\u30D9\u30F3\u30C8\u4FDD\u5B58\u30A8\u30E9\u30FC:", error);
607
- throw error;
624
+ console.error(
625
+ `rrweb\u30A4\u30D9\u30F3\u30C8\u4FDD\u5B58\u30A8\u30E9\u30FC (sessionId: ${_sessionId}):`,
626
+ error
627
+ );
608
628
  }
609
629
  },
610
630
  recordCanvas: false
611
631
  });
612
632
  this.startConsoleRecording();
613
633
  } catch (error) {
614
- console.error("rrweb\u9332\u753B\u30A8\u30E9\u30FC:", error);
634
+ console.error(`rrweb\u9332\u753B\u30A8\u30E9\u30FC (sessionId: ${this.sessionId}):`, error);
615
635
  throw error;
616
636
  }
617
637
  }
@@ -620,6 +640,7 @@ var ActionLensRc = class {
620
640
  if (this.stopFnForStore) {
621
641
  this.stopFnForStore();
622
642
  this.stopFnForStore = null;
643
+ console.log("rrweb\u9332\u753B\u3092\u505C\u6B62\u3057\u307E\u3057\u305F");
623
644
  }
624
645
  } catch (error) {
625
646
  console.error("rrweb\u9332\u753B\u505C\u6B62\u30A8\u30E9\u30FC:", error);
@@ -638,19 +659,24 @@ var ActionLensRc = class {
638
659
  collection2(this.db, `${this.prefix}ActionRecordSession`),
639
660
  this.sessionId
640
661
  );
641
- await setDoc2(
642
- ActionRecordSessionRef,
643
- {
644
- endTime: /* @__PURE__ */ new Date(),
645
- updateAt: /* @__PURE__ */ new Date(),
646
- updatedBy: this.userId
647
- },
648
- { merge: true }
649
- ).catch((error) => {
650
- console.error("Error updating ActionRecordSession: ", error);
651
- });
662
+ await this.retryOperation(
663
+ () => setDoc2(
664
+ ActionRecordSessionRef,
665
+ {
666
+ endTime: /* @__PURE__ */ new Date(),
667
+ updateAt: /* @__PURE__ */ new Date(),
668
+ updatedBy: this.userId
669
+ },
670
+ { merge: true }
671
+ ).then(
672
+ () => console.log(`ActionRecordSession updated: ${this.sessionId}`)
673
+ )
674
+ );
652
675
  } catch (error) {
653
- console.error("ActionRecordSession\u66F4\u65B0\u30A8\u30E9\u30FC:", error);
676
+ console.error(
677
+ `ActionRecordSession\u66F4\u65B0\u30A8\u30E9\u30FC (sessionId: ${this.sessionId}):`,
678
+ error
679
+ );
654
680
  throw error;
655
681
  }
656
682
  }