action-lens 1.0.52 → 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 };
@@ -479,8 +485,15 @@ var ActionLensRc = class {
479
485
  ];
480
486
  consoleMethods.forEach((method) => {
481
487
  console[method] = (...args) => {
482
- originalConsole[method](...args);
483
- 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
+ }
484
497
  };
485
498
  });
486
499
  } catch (error) {
@@ -488,32 +501,39 @@ var ActionLensRc = class {
488
501
  throw error;
489
502
  }
490
503
  }
491
- // タイムライン(ナビゲーションとパフォーマンス)をキャプチャ
492
504
  startTimelineRecording() {
493
505
  try {
494
506
  const userId = this.userId || "unknown";
495
507
  const sessionId = this.sessionId;
496
508
  const db2 = this.db;
497
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
+ }
498
514
  window.addEventListener("popstate", (event) => {
499
- if (!db2) {
500
- console.error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
501
- 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);
502
522
  }
503
- record.addCustomEvent("navigation", {
504
- url: window.location.href,
505
- state: event.state
506
- });
507
523
  });
508
524
  if (window.performance) {
509
525
  const observer = new PerformanceObserver((list) => {
510
526
  for (const entry of list.getEntries()) {
511
- record.addCustomEvent("performance", {
512
- name: entry.name,
513
- entryType: entry.entryType,
514
- startTime: entry.startTime,
515
- duration: entry.duration
516
- });
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
+ }
517
537
  }
518
538
  });
519
539
  observer.observe({ entryTypes: ["resource", "navigation", "paint"] });
@@ -532,26 +552,27 @@ var ActionLensRc = class {
532
552
  const db2 = this.db;
533
553
  const prefix = this.prefix;
534
554
  if (!db2) {
535
- console.error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
536
- return;
555
+ throw new Error("Firestore\u304C\u521D\u671F\u5316\u3055\u308C\u3066\u3044\u307E\u305B\u3093");
537
556
  }
538
557
  const ActionRecordSessionRef = doc2(
539
558
  collection2(db2, `${prefix}ActionRecordSession`),
540
559
  _sessionId
541
560
  );
542
- await setDoc2(ActionRecordSessionRef, {
543
- id: _sessionId,
544
- startTime: /* @__PURE__ */ new Date(),
545
- endTime: /* @__PURE__ */ new Date(),
546
- userId,
547
- projectId: this.projectId || "",
548
- organizationId: this.projectData?.organizationId || "",
549
- createAt: /* @__PURE__ */ new Date(),
550
- updateAt: /* @__PURE__ */ new Date(),
551
- createdBy: userId,
552
- updatedBy: userId
553
- });
554
- 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 = [];
555
576
  this.stopFnForStore = record({
556
577
  packFn: pack,
557
578
  collectFonts: true,
@@ -579,18 +600,38 @@ var ActionLensRc = class {
579
600
  updatedBy: userId,
580
601
  hiddenBy: ""
581
602
  };
582
- await setDoc2(newDocRef, record2);
583
- 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
+ }
584
623
  } catch (error) {
585
- console.error("rrweb\u30A4\u30D9\u30F3\u30C8\u4FDD\u5B58\u30A8\u30E9\u30FC:", error);
586
- throw error;
624
+ console.error(
625
+ `rrweb\u30A4\u30D9\u30F3\u30C8\u4FDD\u5B58\u30A8\u30E9\u30FC (sessionId: ${_sessionId}):`,
626
+ error
627
+ );
587
628
  }
588
629
  },
589
630
  recordCanvas: false
590
631
  });
591
632
  this.startConsoleRecording();
592
633
  } catch (error) {
593
- console.error("rrweb\u9332\u753B\u30A8\u30E9\u30FC:", error);
634
+ console.error(`rrweb\u9332\u753B\u30A8\u30E9\u30FC (sessionId: ${this.sessionId}):`, error);
594
635
  throw error;
595
636
  }
596
637
  }
@@ -599,6 +640,7 @@ var ActionLensRc = class {
599
640
  if (this.stopFnForStore) {
600
641
  this.stopFnForStore();
601
642
  this.stopFnForStore = null;
643
+ console.log("rrweb\u9332\u753B\u3092\u505C\u6B62\u3057\u307E\u3057\u305F");
602
644
  }
603
645
  } catch (error) {
604
646
  console.error("rrweb\u9332\u753B\u505C\u6B62\u30A8\u30E9\u30FC:", error);
@@ -617,19 +659,24 @@ var ActionLensRc = class {
617
659
  collection2(this.db, `${this.prefix}ActionRecordSession`),
618
660
  this.sessionId
619
661
  );
620
- await setDoc2(
621
- ActionRecordSessionRef,
622
- {
623
- endTime: /* @__PURE__ */ new Date(),
624
- updateAt: /* @__PURE__ */ new Date(),
625
- updatedBy: this.userId
626
- },
627
- { merge: true }
628
- ).catch((error) => {
629
- console.error("Error updating ActionRecordSession: ", error);
630
- });
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
+ );
631
675
  } catch (error) {
632
- 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
+ );
633
680
  throw error;
634
681
  }
635
682
  }