action-lens 1.0.11 → 1.0.13

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,15 +50,24 @@ 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;
53
56
  constructor(_userId: string | null, projectId: string | null, userMeta: {
54
57
  name: string;
55
58
  email: string;
56
59
  } | null, metaData?: Record<string, any>, _db?: Firestore | null, prefix?: string);
60
+ /** バッファ内イベントをまとめて Firestore に書き込む */
61
+ private flushBuffer;
62
+ /** コンソール呼び出しを rrweb カスタムイベントとして記録 */
57
63
  startConsoleRecording(): void;
58
- startTimelineRecording(): void;
64
+ /** rrweb を使って画面操作をバッファ&バッチ保存 */
59
65
  startRrwebRecordingForStore(): void;
66
+ /** 録画停止とバッファフラッシュ */
60
67
  stopRrwebRecordingForStore(): void;
68
+ /** セッションの endTime を更新 */
61
69
  updateActionRecordSession(): void;
70
+ startTimelineRecording(): void;
62
71
  }
63
72
 
64
73
  /** Timestampの時はDateへの変更 */
package/dist/index.d.ts CHANGED
@@ -50,15 +50,24 @@ 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;
53
56
  constructor(_userId: string | null, projectId: string | null, userMeta: {
54
57
  name: string;
55
58
  email: string;
56
59
  } | null, metaData?: Record<string, any>, _db?: Firestore | null, prefix?: string);
60
+ /** バッファ内イベントをまとめて Firestore に書き込む */
61
+ private flushBuffer;
62
+ /** コンソール呼び出しを rrweb カスタムイベントとして記録 */
57
63
  startConsoleRecording(): void;
58
- startTimelineRecording(): void;
64
+ /** rrweb を使って画面操作をバッファ&バッチ保存 */
59
65
  startRrwebRecordingForStore(): void;
66
+ /** 録画停止とバッファフラッシュ */
60
67
  stopRrwebRecordingForStore(): void;
68
+ /** セッションの endTime を更新 */
61
69
  updateActionRecordSession(): void;
70
+ startTimelineRecording(): void;
62
71
  }
63
72
 
64
73
  /** Timestampの時はDateへの変更 */
package/dist/index.js CHANGED
@@ -290,213 +290,121 @@ var ActionLensRc = class {
290
290
  projectData = null;
291
291
  organizationId = null;
292
292
  originalUserId = null;
293
- // 元のユーザーID(外部システムのIDなど)
293
+ /** イベントバッファとコミット閾値 */
294
+ eventBuffer = [];
295
+ flushThreshold = 50;
294
296
  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) {
297
+ this.originalUserId = _userId;
298
+ this.db = _db || db;
299
+ (0, import_firestore3.getDoc)((0, import_firestore3.doc)((0, import_firestore3.collection)(this.db, `${prefix}project`), projectId)).then(async (_proj) => {
300
+ this.projectData = _proj.data();
301
+ this.organizationId = this.projectData?.organizationId || null;
302
+ if (!this.db) {
307
303
  this.db = db;
308
- } else {
309
- this.db = _db;
310
304
  }
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;
436
- }
305
+ (0, import_firestore3.getDoc)((0, import_firestore3.doc)((0, import_firestore3.collection)(this.db, `${prefix}user`), _userId)).then(async (_usr) => {
306
+ this.userId = `${this.organizationId}-${_userId}`;
307
+ this.prefix = prefix;
308
+ this.projectId = projectId;
309
+ this.startRrwebRecordingForStore();
310
+ this.startConsoleRecording();
311
+ }).catch((e) => console.error("\u30E6\u30FC\u30B6\u30FC\u30C7\u30FC\u30BF\u53D6\u5F97\u30A8\u30E9\u30FC:", e));
312
+ }).catch((e) => console.error("\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u53D6\u5F97\u30A8\u30E9\u30FC:", e));
313
+ }
314
+ /** バッファ内イベントをまとめて Firestore に書き込む */
315
+ flushBuffer() {
316
+ if (!this.db || this.eventBuffer.length === 0) return;
317
+ const batch = (0, import_firestore3.writeBatch)(this.db);
318
+ this.eventBuffer.forEach((rec) => {
319
+ const ref = (0, import_firestore3.doc)((0, import_firestore3.collection)(this.db, `${this.prefix}ActionRecord`));
320
+ batch.set(ref, rec);
321
+ });
322
+ batch.commit().catch((e) => console.error("Batch commit error:", e));
323
+ this.eventBuffer = [];
437
324
  }
438
- // コンソールログをキャプチャ
325
+ /** コンソール呼び出しを rrweb カスタムイベントとして記録 */
439
326
  startConsoleRecording() {
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();
327
+ const methods = ["log", "info", "warn", "error", "debug", "trace"];
328
+ const original = {};
329
+ methods.forEach((m) => {
330
+ original[m] = console[m].bind(console);
331
+ console[m] = (...args) => {
332
+ original[m](...args);
333
+ import_rrweb2.record.addCustomEvent("console", { method: m, args });
334
+ this.updateActionRecordSession();
335
+ };
336
+ });
337
+ }
338
+ /** rrweb を使って画面操作をバッファ&バッチ保存 */
339
+ startRrwebRecordingForStore() {
340
+ if (this.stopFnForStore) return;
341
+ const userId = this.userId || "unknown";
342
+ const originalUserId = this.originalUserId || "";
343
+ const sessionId = this.sessionId;
344
+ const db2 = this.db;
345
+ const prefix = this.prefix;
346
+ (0, import_firestore3.setDoc)((0, import_firestore3.doc)((0, import_firestore3.collection)(db2, `${prefix}ActionRecordSession`), sessionId), {
347
+ id: sessionId,
348
+ startTime: /* @__PURE__ */ new Date(),
349
+ endTime: null,
350
+ userId,
351
+ projectId: this.projectId,
352
+ organizationId: this.projectData?.organizationId || null,
353
+ createAt: /* @__PURE__ */ new Date(),
354
+ updateAt: /* @__PURE__ */ new Date(),
355
+ createdBy: userId,
356
+ updatedBy: userId
357
+ }).catch((e) => console.error(e));
358
+ this.stopFnForStore = (0, import_rrweb2.record)({
359
+ collectFonts: true,
360
+ inlineImages: false,
361
+ sampling: { canvas: 500, mousemove: false, scroll: 500 },
362
+ emit: (event) => {
363
+ const rec = {
364
+ id: (0, import_firestore3.doc)((0, import_firestore3.collection)(db2, `${prefix}ActionRecord`)).id,
365
+ timeStamp: /* @__PURE__ */ new Date(),
366
+ userId,
367
+ originalUserId,
368
+ sessionId,
369
+ type: "rrweb",
370
+ rrwebRecord: JSON.stringify(event),
371
+ createAt: /* @__PURE__ */ new Date(),
372
+ updateAt: /* @__PURE__ */ new Date(),
373
+ hidden: false,
374
+ createdBy: userId,
375
+ updatedBy: userId,
376
+ hiddenBy: ""
493
377
  };
494
- });
495
- } catch (error) {
496
- console.error("\u30B3\u30F3\u30BD\u30FC\u30EB\u9332\u753B\u30A8\u30E9\u30FC:", error);
497
- throw error;
378
+ this.eventBuffer.push(rec);
379
+ (0, import_firestore3.setDoc)(
380
+ (0, import_firestore3.doc)((0, import_firestore3.collection)(db2, `${prefix}ActionRecordSession`), sessionId),
381
+ { endTime: /* @__PURE__ */ new Date(), updateAt: /* @__PURE__ */ new Date(), updatedBy: userId },
382
+ { merge: true }
383
+ ).catch((e) => console.error(e));
384
+ },
385
+ recordCanvas: false
386
+ });
387
+ }
388
+ /** 録画停止とバッファフラッシュ */
389
+ stopRrwebRecordingForStore() {
390
+ if (this.stopFnForStore) {
391
+ this.stopFnForStore();
392
+ this.stopFnForStore = null;
393
+ this.flushBuffer();
498
394
  }
499
395
  }
396
+ /** セッションの endTime を更新 */
397
+ updateActionRecordSession() {
398
+ if (!this.db || !this.sessionId || !this.userId) return;
399
+ (0, import_firestore3.setDoc)(
400
+ (0, import_firestore3.doc)(
401
+ (0, import_firestore3.collection)(this.db, `${this.prefix}ActionRecordSession`),
402
+ this.sessionId
403
+ ),
404
+ { endTime: /* @__PURE__ */ new Date(), updateAt: /* @__PURE__ */ new Date(), updatedBy: this.userId },
405
+ { merge: true }
406
+ ).catch((e) => console.error(e));
407
+ }
500
408
  // タイムライン(ナビゲーションとパフォーマンス)をキャプチャ
501
409
  startTimelineRecording() {
502
410
  try {
@@ -586,110 +494,6 @@ var ActionLensRc = class {
586
494
  throw error;
587
495
  }
588
496
  }
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: 1e3,
623
- mousemove: 600
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
- }
693
497
  };
694
498
 
695
499
  // src/utils/date.ts