@taskp3/react 0.1.0

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.
Files changed (142) hide show
  1. package/README.md +258 -0
  2. package/dist/changelog-hooks.d.ts +46 -0
  3. package/dist/changelog-hooks.d.ts.map +1 -0
  4. package/dist/changelog-hooks.js +163 -0
  5. package/dist/changelog-hooks.js.map +1 -0
  6. package/dist/changelog.d.ts +17 -0
  7. package/dist/changelog.d.ts.map +1 -0
  8. package/dist/changelog.js +86 -0
  9. package/dist/changelog.js.map +1 -0
  10. package/dist/context.d.ts +33 -0
  11. package/dist/context.d.ts.map +1 -0
  12. package/dist/context.js +62 -0
  13. package/dist/context.js.map +1 -0
  14. package/dist/fetch.d.ts +3 -0
  15. package/dist/fetch.d.ts.map +1 -0
  16. package/dist/fetch.js +19 -0
  17. package/dist/fetch.js.map +1 -0
  18. package/dist/hooks.d.ts +50 -0
  19. package/dist/hooks.d.ts.map +1 -0
  20. package/dist/hooks.js +140 -0
  21. package/dist/hooks.js.map +1 -0
  22. package/dist/icons.d.ts +52 -0
  23. package/dist/icons.d.ts.map +1 -0
  24. package/dist/icons.js +40 -0
  25. package/dist/icons.js.map +1 -0
  26. package/dist/index.d.ts +33 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +43 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/loom-recorder.d.ts +9 -0
  31. package/dist/loom-recorder.d.ts.map +1 -0
  32. package/dist/loom-recorder.js +92 -0
  33. package/dist/loom-recorder.js.map +1 -0
  34. package/dist/past-submissions.d.ts +10 -0
  35. package/dist/past-submissions.d.ts.map +1 -0
  36. package/dist/past-submissions.js +198 -0
  37. package/dist/past-submissions.js.map +1 -0
  38. package/dist/recorder/audio.d.ts +6 -0
  39. package/dist/recorder/audio.d.ts.map +1 -0
  40. package/dist/recorder/audio.js +30 -0
  41. package/dist/recorder/audio.js.map +1 -0
  42. package/dist/recorder/capture.d.ts +6 -0
  43. package/dist/recorder/capture.d.ts.map +1 -0
  44. package/dist/recorder/capture.js +32 -0
  45. package/dist/recorder/capture.js.map +1 -0
  46. package/dist/recorder/finalize-recording-worker-source.d.ts +2 -0
  47. package/dist/recorder/finalize-recording-worker-source.d.ts.map +1 -0
  48. package/dist/recorder/finalize-recording-worker-source.js +6 -0
  49. package/dist/recorder/finalize-recording-worker-source.js.map +1 -0
  50. package/dist/recorder/finalize-recording-worker.d.ts +2 -0
  51. package/dist/recorder/finalize-recording-worker.d.ts.map +1 -0
  52. package/dist/recorder/finalize-recording-worker.js +16 -0
  53. package/dist/recorder/finalize-recording-worker.js.map +1 -0
  54. package/dist/recorder/finalizeRecording.d.ts +12 -0
  55. package/dist/recorder/finalizeRecording.d.ts.map +1 -0
  56. package/dist/recorder/finalizeRecording.js +92 -0
  57. package/dist/recorder/finalizeRecording.js.map +1 -0
  58. package/dist/recorder/finalizeRecordingInWorker.d.ts +3 -0
  59. package/dist/recorder/finalizeRecordingInWorker.d.ts.map +1 -0
  60. package/dist/recorder/finalizeRecordingInWorker.js +49 -0
  61. package/dist/recorder/finalizeRecordingInWorker.js.map +1 -0
  62. package/dist/recorder/index.d.ts +7 -0
  63. package/dist/recorder/index.d.ts.map +1 -0
  64. package/dist/recorder/index.js +14 -0
  65. package/dist/recorder/index.js.map +1 -0
  66. package/dist/recorder/session.d.ts +19 -0
  67. package/dist/recorder/session.d.ts.map +1 -0
  68. package/dist/recorder/session.js +237 -0
  69. package/dist/recorder/session.js.map +1 -0
  70. package/dist/recorder/support.d.ts +8 -0
  71. package/dist/recorder/support.d.ts.map +1 -0
  72. package/dist/recorder/support.js +41 -0
  73. package/dist/recorder/support.js.map +1 -0
  74. package/dist/recorder/timer-worker.d.ts +5 -0
  75. package/dist/recorder/timer-worker.d.ts.map +1 -0
  76. package/dist/recorder/timer-worker.js +28 -0
  77. package/dist/recorder/timer-worker.js.map +1 -0
  78. package/dist/recorder/types.d.ts +26 -0
  79. package/dist/recorder/types.d.ts.map +1 -0
  80. package/dist/recorder/types.js +3 -0
  81. package/dist/recorder/types.js.map +1 -0
  82. package/dist/recorder-preview-player.d.ts +9 -0
  83. package/dist/recorder-preview-player.d.ts.map +1 -0
  84. package/dist/recorder-preview-player.js +136 -0
  85. package/dist/recorder-preview-player.js.map +1 -0
  86. package/dist/screen-recorder-context.d.ts +16 -0
  87. package/dist/screen-recorder-context.d.ts.map +1 -0
  88. package/dist/screen-recorder-context.js +124 -0
  89. package/dist/screen-recorder-context.js.map +1 -0
  90. package/dist/screen-recorder.d.ts +16 -0
  91. package/dist/screen-recorder.d.ts.map +1 -0
  92. package/dist/screen-recorder.js +126 -0
  93. package/dist/screen-recorder.js.map +1 -0
  94. package/dist/styles.d.ts +3 -0
  95. package/dist/styles.d.ts.map +1 -0
  96. package/dist/styles.js +841 -0
  97. package/dist/styles.js.map +1 -0
  98. package/dist/triage-attachments.d.ts +5 -0
  99. package/dist/triage-attachments.d.ts.map +1 -0
  100. package/dist/triage-attachments.js +44 -0
  101. package/dist/triage-attachments.js.map +1 -0
  102. package/dist/triage-button.d.ts +26 -0
  103. package/dist/triage-button.d.ts.map +1 -0
  104. package/dist/triage-button.js +228 -0
  105. package/dist/triage-button.js.map +1 -0
  106. package/dist/triage-rich-content.d.ts +6 -0
  107. package/dist/triage-rich-content.d.ts.map +1 -0
  108. package/dist/triage-rich-content.js +121 -0
  109. package/dist/triage-rich-content.js.map +1 -0
  110. package/dist/triage-slate-editor.d.ts +8 -0
  111. package/dist/triage-slate-editor.d.ts.map +1 -0
  112. package/dist/triage-slate-editor.js +112 -0
  113. package/dist/triage-slate-editor.js.map +1 -0
  114. package/dist/triage-slate.d.ts +20 -0
  115. package/dist/triage-slate.d.ts.map +1 -0
  116. package/dist/triage-slate.js +64 -0
  117. package/dist/triage-slate.js.map +1 -0
  118. package/dist/triage-ui-controller.d.ts +52 -0
  119. package/dist/triage-ui-controller.d.ts.map +1 -0
  120. package/dist/triage-ui-controller.js +146 -0
  121. package/dist/triage-ui-controller.js.map +1 -0
  122. package/dist/triage-ui-notifications.d.ts +5 -0
  123. package/dist/triage-ui-notifications.d.ts.map +1 -0
  124. package/dist/triage-ui-notifications.js +10 -0
  125. package/dist/triage-ui-notifications.js.map +1 -0
  126. package/dist/use-past-submissions.d.ts +43 -0
  127. package/dist/use-past-submissions.d.ts.map +1 -0
  128. package/dist/use-past-submissions.js +240 -0
  129. package/dist/use-past-submissions.js.map +1 -0
  130. package/dist/use-recorder-controller.d.ts +33 -0
  131. package/dist/use-recorder-controller.d.ts.map +1 -0
  132. package/dist/use-recorder-controller.js +309 -0
  133. package/dist/use-recorder-controller.js.map +1 -0
  134. package/dist/use-screen-recorder.d.ts +25 -0
  135. package/dist/use-screen-recorder.d.ts.map +1 -0
  136. package/dist/use-screen-recorder.js +34 -0
  137. package/dist/use-screen-recorder.js.map +1 -0
  138. package/dist/whats-new.d.ts +16 -0
  139. package/dist/whats-new.d.ts.map +1 -0
  140. package/dist/whats-new.js +72 -0
  141. package/dist/whats-new.js.map +1 -0
  142. package/package.json +58 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finalize-recording-worker-source.js","sourceRoot":"","sources":["../../src/recorder/finalize-recording-worker-source.ts"],"names":[],"mappings":";;;AAAA,uDAAuD;AAC1C,QAAA,gCAAgC,GAAG,os8ZAAos8Z,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=finalize-recording-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finalize-recording-worker.d.ts","sourceRoot":"","sources":["../../src/recorder/finalize-recording-worker.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const finalizeRecording_1 = require("./finalizeRecording");
4
+ self.onmessage = async (event) => {
5
+ try {
6
+ const result = await (0, finalizeRecording_1.finalizeRecording)(event.data.blob, event.data.durationMs);
7
+ self.postMessage({ ok: true, result });
8
+ }
9
+ catch (error) {
10
+ self.postMessage({
11
+ ok: false,
12
+ error: error instanceof Error ? error.message : "Failed to finalize recording",
13
+ });
14
+ }
15
+ };
16
+ //# sourceMappingURL=finalize-recording-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finalize-recording-worker.js","sourceRoot":"","sources":["../../src/recorder/finalize-recording-worker.ts"],"names":[],"mappings":";;AAAA,2DAAwD;AAOxD,IAAI,CAAC,SAAS,GAAG,KAAK,EACpB,KAAmD,EACnD,EAAE;IACF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAA,qCAAiB,EACpC,KAAK,CAAC,IAAI,CAAC,IAAI,EACf,KAAK,CAAC,IAAI,CAAC,UAAU,CACtB,CAAC;QACF,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,WAAW,CAAC;YACf,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,8BAA8B;SAC/E,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ export interface RecorderAttachmentMetadata {
2
+ durationSeconds: number;
3
+ mimeType?: string;
4
+ fileExtension?: string;
5
+ conversionMode?: "mp4" | "webm" | "passthrough";
6
+ }
7
+ export interface FinalizedRecordingResult {
8
+ blob: Blob;
9
+ metadata: RecorderAttachmentMetadata;
10
+ }
11
+ export declare function finalizeRecording(blob: Blob, durationMs: number): Promise<FinalizedRecordingResult>;
12
+ //# sourceMappingURL=finalizeRecording.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finalizeRecording.d.ts","sourceRoot":"","sources":["../../src/recorder/finalizeRecording.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,0BAA0B;IACzC,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,aAAa,CAAC;CACjD;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,0BAA0B,CAAC;CACtC;AA8DD,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,wBAAwB,CAAC,CA0CnC"}
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.finalizeRecording = finalizeRecording;
4
+ const mediabunny_1 = require("mediabunny");
5
+ const normalizeDurationSeconds = (durationMs) => Math.max(1, Math.round(durationMs / 1000));
6
+ async function convertRecordingBlob(blob, target) {
7
+ const input = new mediabunny_1.Input({
8
+ source: new mediabunny_1.BlobSource(blob),
9
+ formats: mediabunny_1.ALL_FORMATS,
10
+ });
11
+ const outputTarget = new mediabunny_1.BufferTarget();
12
+ const output = new mediabunny_1.Output({
13
+ format: target === "mp4" ? new mediabunny_1.Mp4OutputFormat() : new mediabunny_1.WebMOutputFormat(),
14
+ target: outputTarget,
15
+ });
16
+ try {
17
+ const conversion = await mediabunny_1.Conversion.init({
18
+ input,
19
+ output,
20
+ video: target === "mp4"
21
+ ? {
22
+ codec: "avc",
23
+ bitrate: mediabunny_1.QUALITY_HIGH,
24
+ hardwareAcceleration: "prefer-hardware",
25
+ }
26
+ : undefined,
27
+ audio: target === "mp4"
28
+ ? {
29
+ codec: "aac",
30
+ bitrate: mediabunny_1.QUALITY_HIGH,
31
+ }
32
+ : undefined,
33
+ showWarnings: false,
34
+ });
35
+ if (!conversion.isValid) {
36
+ throw new Error(`Mediabunny ${target} conversion is not valid`);
37
+ }
38
+ await conversion.execute();
39
+ if (!outputTarget.buffer) {
40
+ throw new Error(`Mediabunny ${target} conversion produced no output`);
41
+ }
42
+ return new Blob([outputTarget.buffer], {
43
+ type: target === "mp4" ? "video/mp4" : "video/webm",
44
+ });
45
+ }
46
+ finally {
47
+ input.dispose();
48
+ }
49
+ }
50
+ async function finalizeRecording(blob, durationMs) {
51
+ const durationSeconds = normalizeDurationSeconds(durationMs);
52
+ try {
53
+ const mp4Blob = await convertRecordingBlob(blob, "mp4");
54
+ return {
55
+ blob: mp4Blob,
56
+ metadata: {
57
+ durationSeconds,
58
+ mimeType: "video/mp4",
59
+ fileExtension: "mp4",
60
+ conversionMode: "mp4",
61
+ },
62
+ };
63
+ }
64
+ catch {
65
+ // Fall through to a WebM normalization pass.
66
+ }
67
+ try {
68
+ const webmBlob = await convertRecordingBlob(blob, "webm");
69
+ return {
70
+ blob: webmBlob,
71
+ metadata: {
72
+ durationSeconds,
73
+ mimeType: "video/webm",
74
+ fileExtension: "webm",
75
+ conversionMode: "webm",
76
+ },
77
+ };
78
+ }
79
+ catch {
80
+ // Final fallback preserves recording availability even if conversion fails.
81
+ }
82
+ return {
83
+ blob,
84
+ metadata: {
85
+ durationSeconds,
86
+ mimeType: blob.type || "video/webm",
87
+ fileExtension: blob.type.includes("mp4") ? "mp4" : "webm",
88
+ conversionMode: "passthrough",
89
+ },
90
+ };
91
+ }
92
+ //# sourceMappingURL=finalizeRecording.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finalizeRecording.js","sourceRoot":"","sources":["../../src/recorder/finalizeRecording.ts"],"names":[],"mappings":";;AAoFA,8CA6CC;AAjID,2CAUoB;AAgBpB,MAAM,wBAAwB,GAAG,CAAC,UAAkB,EAAE,EAAE,CACtD,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC;AAE7C,KAAK,UAAU,oBAAoB,CACjC,IAAU,EACV,MAAwB;IAExB,MAAM,KAAK,GAAG,IAAI,kBAAK,CAAC;QACtB,MAAM,EAAE,IAAI,uBAAU,CAAC,IAAI,CAAC;QAC5B,OAAO,EAAE,wBAAW;KACrB,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,IAAI,yBAAY,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,mBAAM,CAAC;QACxB,MAAM,EAAE,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,4BAAe,EAAE,CAAC,CAAC,CAAC,IAAI,6BAAgB,EAAE;QACzE,MAAM,EAAE,YAAY;KACrB,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,uBAAU,CAAC,IAAI,CAAC;YACvC,KAAK;YACL,MAAM;YACN,KAAK,EACH,MAAM,KAAK,KAAK;gBACd,CAAC,CAAC;oBACE,KAAK,EAAE,KAAK;oBACZ,OAAO,EAAE,yBAAY;oBACrB,oBAAoB,EAAE,iBAAiB;iBACxC;gBACH,CAAC,CAAC,SAAS;YACf,KAAK,EACH,MAAM,KAAK,KAAK;gBACd,CAAC,CAAC;oBACE,KAAK,EAAE,KAAK;oBACZ,OAAO,EAAE,yBAAY;iBACtB;gBACH,CAAC,CAAC,SAAS;YACf,YAAY,EAAE,KAAK;SACpB,CAAC,CAAC;QAEH,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,cAAc,MAAM,0BAA0B,CAAC,CAAC;QAClE,CAAC;QAED,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC;QAE3B,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,cAAc,MAAM,gCAAgC,CAAC,CAAC;QACxE,CAAC;QAED,OAAO,IAAI,IAAI,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE;YACrC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY;SACpD,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QACT,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,iBAAiB,CACrC,IAAU,EACV,UAAkB;IAElB,MAAM,eAAe,GAAG,wBAAwB,CAAC,UAAU,CAAC,CAAC;IAE7D,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACxD,OAAO;YACL,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE;gBACR,eAAe;gBACf,QAAQ,EAAE,WAAW;gBACrB,aAAa,EAAE,KAAK;gBACpB,cAAc,EAAE,KAAK;aACtB;SACF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,6CAA6C;IAC/C,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1D,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE;gBACR,eAAe;gBACf,QAAQ,EAAE,YAAY;gBACtB,aAAa,EAAE,MAAM;gBACrB,cAAc,EAAE,MAAM;aACvB;SACF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,4EAA4E;IAC9E,CAAC;IAED,OAAO;QACL,IAAI;QACJ,QAAQ,EAAE;YACR,eAAe;YACf,QAAQ,EAAE,IAAI,CAAC,IAAI,IAAI,YAAY;YACnC,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM;YACzD,cAAc,EAAE,aAAa;SAC9B;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type FinalizedRecordingResult } from "./finalizeRecording";
2
+ export declare function finalizeRecordingInWorker(blob: Blob, durationMs: number): Promise<FinalizedRecordingResult>;
3
+ //# sourceMappingURL=finalizeRecordingInWorker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finalizeRecordingInWorker.d.ts","sourceRoot":"","sources":["../../src/recorder/finalizeRecordingInWorker.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,qBAAqB,CAAC;AAiB7B,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,wBAAwB,CAAC,CAkDnC"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.finalizeRecordingInWorker = finalizeRecordingInWorker;
4
+ const finalizeRecording_1 = require("./finalizeRecording");
5
+ const finalize_recording_worker_source_1 = require("./finalize-recording-worker-source");
6
+ async function finalizeRecordingInWorker(blob, durationMs) {
7
+ if (typeof Worker === "undefined"
8
+ || typeof URL === "undefined"
9
+ || !finalize_recording_worker_source_1.FINALIZE_RECORDING_WORKER_SOURCE) {
10
+ return (0, finalizeRecording_1.finalizeRecording)(blob, durationMs);
11
+ }
12
+ let worker = null;
13
+ let workerUrl = null;
14
+ try {
15
+ workerUrl = URL.createObjectURL(new Blob([finalize_recording_worker_source_1.FINALIZE_RECORDING_WORKER_SOURCE], {
16
+ type: "application/javascript",
17
+ }));
18
+ worker = new Worker(workerUrl);
19
+ const result = await new Promise((resolve, reject) => {
20
+ if (!worker) {
21
+ reject(new Error("Failed to initialize recording worker"));
22
+ return;
23
+ }
24
+ worker.onmessage = (event) => {
25
+ if (event.data.ok) {
26
+ resolve(event.data.result);
27
+ }
28
+ else {
29
+ reject(new Error(event.data.error));
30
+ }
31
+ };
32
+ worker.onerror = () => {
33
+ reject(new Error("Recording worker failed"));
34
+ };
35
+ worker.postMessage({ blob, durationMs });
36
+ });
37
+ return result;
38
+ }
39
+ catch {
40
+ return (0, finalizeRecording_1.finalizeRecording)(blob, durationMs);
41
+ }
42
+ finally {
43
+ worker?.terminate();
44
+ if (workerUrl) {
45
+ URL.revokeObjectURL(workerUrl);
46
+ }
47
+ }
48
+ }
49
+ //# sourceMappingURL=finalizeRecordingInWorker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finalizeRecordingInWorker.js","sourceRoot":"","sources":["../../src/recorder/finalizeRecordingInWorker.ts"],"names":[],"mappings":";;AAoBA,8DAqDC;AAzED,2DAG6B;AAC7B,yFAAsF;AAgB/E,KAAK,UAAU,yBAAyB,CAC7C,IAAU,EACV,UAAkB;IAElB,IACE,OAAO,MAAM,KAAK,WAAW;WAC1B,OAAO,GAAG,KAAK,WAAW;WAC1B,CAAC,mEAAgC,EACpC,CAAC;QACD,OAAO,IAAA,qCAAiB,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC7C,CAAC;IAED,IAAI,MAAM,GAAkB,IAAI,CAAC;IACjC,IAAI,SAAS,GAAkB,IAAI,CAAC;IAEpC,IAAI,CAAC;QACH,SAAS,GAAG,GAAG,CAAC,eAAe,CAC7B,IAAI,IAAI,CAAC,CAAC,mEAAgC,CAAC,EAAE;YAC3C,IAAI,EAAE,wBAAwB;SAC/B,CAAC,CACH,CAAC;QACF,MAAM,GAAG,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC;QAE/B,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,CAA2B,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC7E,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,CAAC,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC,CAAC;gBAC3D,OAAO;YACT,CAAC;YAED,MAAM,CAAC,SAAS,GAAG,CAAC,KAAoD,EAAE,EAAE;gBAC1E,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;oBAClB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAC7B,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE;gBACpB,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;YAC/C,CAAC,CAAC;YAEF,MAAM,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAA,qCAAiB,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC7C,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,SAAS,EAAE,CAAC;QACpB,IAAI,SAAS,EAAE,CAAC;YACd,GAAG,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ export type { RecorderState, RecorderSessionConfig, CaptureResult, MixedAudioResult, RecordingFinalization } from "./types";
2
+ export { isRecorderSupported, getPreferredMimeType, mimeBase } from "./support";
3
+ export { acquireCapture } from "./capture";
4
+ export { createMixedAudio } from "./audio";
5
+ export { createRecordingSession } from "./session";
6
+ export type { SessionCallbacks, RecordingSessionHandle } from "./session";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recorder/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,qBAAqB,EAAE,aAAa,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAC5H,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACnD,YAAY,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createRecordingSession = exports.createMixedAudio = exports.acquireCapture = exports.mimeBase = exports.getPreferredMimeType = exports.isRecorderSupported = void 0;
4
+ var support_1 = require("./support");
5
+ Object.defineProperty(exports, "isRecorderSupported", { enumerable: true, get: function () { return support_1.isRecorderSupported; } });
6
+ Object.defineProperty(exports, "getPreferredMimeType", { enumerable: true, get: function () { return support_1.getPreferredMimeType; } });
7
+ Object.defineProperty(exports, "mimeBase", { enumerable: true, get: function () { return support_1.mimeBase; } });
8
+ var capture_1 = require("./capture");
9
+ Object.defineProperty(exports, "acquireCapture", { enumerable: true, get: function () { return capture_1.acquireCapture; } });
10
+ var audio_1 = require("./audio");
11
+ Object.defineProperty(exports, "createMixedAudio", { enumerable: true, get: function () { return audio_1.createMixedAudio; } });
12
+ var session_1 = require("./session");
13
+ Object.defineProperty(exports, "createRecordingSession", { enumerable: true, get: function () { return session_1.createRecordingSession; } });
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/recorder/index.ts"],"names":[],"mappings":";;;AACA,qCAAgF;AAAvE,8GAAA,mBAAmB,OAAA;AAAE,+GAAA,oBAAoB,OAAA;AAAE,mGAAA,QAAQ,OAAA;AAC5D,qCAA2C;AAAlC,yGAAA,cAAc,OAAA;AACvB,iCAA2C;AAAlC,yGAAA,gBAAgB,OAAA;AACzB,qCAAmD;AAA1C,iHAAA,sBAAsB,OAAA"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Recording session: owns MediaRecorder instances, chunk buffers, and finalization.
3
+ * Single continuous recording (no timeslice). Preview built only after controlled stop.
4
+ */
5
+ import type { RecorderSessionConfig, RecordingFinalization } from "./types";
6
+ export interface SessionCallbacks {
7
+ onFinalized: (f: RecordingFinalization) => void;
8
+ onError: (err: Error) => void;
9
+ onDurationTick?: (seconds: number) => void;
10
+ }
11
+ export interface RecordingSessionHandle {
12
+ start: () => void;
13
+ stop: () => void;
14
+ pause: () => void;
15
+ resume: () => void;
16
+ release: () => void;
17
+ }
18
+ export declare function createRecordingSession(combinedStream: MediaStream, cameraVideoStream: MediaStream | null, config: RecorderSessionConfig, callbacks: SessionCallbacks): RecordingSessionHandle;
19
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/recorder/session.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAiC5E,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,CAAC,CAAC,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAChD,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IAC9B,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,WAAW,EAC3B,iBAAiB,EAAE,WAAW,GAAG,IAAI,EACrC,MAAM,EAAE,qBAAqB,EAC7B,SAAS,EAAE,gBAAgB,GAC1B,sBAAsB,CAwMxB"}
@@ -0,0 +1,237 @@
1
+ "use strict";
2
+ /**
3
+ * Recording session: owns MediaRecorder instances, chunk buffers, and finalization.
4
+ * Single continuous recording (no timeslice). Preview built only after controlled stop.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.createRecordingSession = createRecordingSession;
8
+ const support_1 = require("./support");
9
+ const timer_worker_1 = require("./timer-worker");
10
+ const DEFAULT_SCREEN_MIME = "video/webm";
11
+ const CAMERA_BITRATE = 500000;
12
+ function createRecorder(stream, bitsPerSecond, preferredMime) {
13
+ const candidates = [
14
+ preferredMime,
15
+ "video/webm;codecs=vp9,opus",
16
+ "video/webm;codecs=vp8,opus",
17
+ "video/webm",
18
+ "video/mp4;codecs=avc1.42E01E,mp4a.40.2",
19
+ "video/mp4;codecs=avc1",
20
+ "video/mp4",
21
+ ].filter((m, i, a) => a.indexOf(m) === i);
22
+ for (const mime of candidates) {
23
+ if (!MediaRecorder.isTypeSupported(mime))
24
+ continue;
25
+ try {
26
+ const recorder = new MediaRecorder(stream, { mimeType: mime, videoBitsPerSecond: bitsPerSecond });
27
+ return { recorder, mimeType: mime };
28
+ }
29
+ catch {
30
+ // try next
31
+ }
32
+ }
33
+ const recorder = new MediaRecorder(stream, { videoBitsPerSecond: bitsPerSecond });
34
+ return { recorder, mimeType: recorder.mimeType || DEFAULT_SCREEN_MIME };
35
+ }
36
+ function createRecordingSession(combinedStream, cameraVideoStream, config, callbacks) {
37
+ const { maxDurationMs, videoBitsPerSecond, cameraBitsPerSecond } = config;
38
+ const preferredMime = (0, support_1.getPreferredMimeType)();
39
+ let screenRecorder = null;
40
+ let cameraRecorder = null;
41
+ let screenMime = preferredMime;
42
+ let cameraMime = null;
43
+ const screenChunks = [];
44
+ const cameraChunks = [];
45
+ let maxTimerId = null;
46
+ let worker = null;
47
+ let workerUrl = null;
48
+ let shareEndedListener = null;
49
+ let released = false;
50
+ let pendingStops = 0;
51
+ function finish() {
52
+ if (released)
53
+ return;
54
+ if (maxTimerId != null) {
55
+ clearTimeout(maxTimerId);
56
+ maxTimerId = null;
57
+ }
58
+ if (worker) {
59
+ worker.postMessage("stop");
60
+ worker = null;
61
+ }
62
+ if (workerUrl) {
63
+ URL.revokeObjectURL(workerUrl);
64
+ workerUrl = null;
65
+ }
66
+ if (shareEndedListener) {
67
+ const track = combinedStream.getVideoTracks()[0];
68
+ if (track)
69
+ track.removeEventListener("ended", shareEndedListener);
70
+ shareEndedListener = null;
71
+ }
72
+ released = true;
73
+ }
74
+ function maybeFinalize() {
75
+ if (pendingStops > 0)
76
+ return;
77
+ if (!screenRecorder)
78
+ return;
79
+ // Defer to next task so the final dataavailable (from stop()) is processed before we read chunks.
80
+ const rec = screenRecorder;
81
+ const mime = screenMime;
82
+ const camRec = cameraRecorder;
83
+ const camMime = cameraMime;
84
+ setTimeout(() => {
85
+ if (released)
86
+ return;
87
+ const screenBlob = new Blob(screenChunks, {
88
+ type: (0, support_1.mimeBase)(rec.mimeType || mime),
89
+ });
90
+ let cameraBlob = null;
91
+ if (camRec && cameraChunks.length > 0) {
92
+ cameraBlob = new Blob(cameraChunks, {
93
+ type: (0, support_1.mimeBase)(camRec.mimeType || camMime || "video/webm"),
94
+ });
95
+ }
96
+ finish();
97
+ callbacks.onFinalized({
98
+ screenBlob,
99
+ screenMimeType: (0, support_1.mimeBase)(rec.mimeType || mime),
100
+ cameraBlob,
101
+ cameraMimeType: camMime ? (0, support_1.mimeBase)(camMime) : null,
102
+ });
103
+ }, 0);
104
+ }
105
+ function onScreenStop() {
106
+ pendingStops--;
107
+ if (pendingStops <= 0)
108
+ maybeFinalize();
109
+ }
110
+ function onScreenError() {
111
+ if (released)
112
+ return;
113
+ finish();
114
+ callbacks.onError(new Error("Recording failed"));
115
+ }
116
+ function onCameraStop() {
117
+ pendingStops--;
118
+ if (pendingStops <= 0)
119
+ maybeFinalize();
120
+ }
121
+ function onCameraError() {
122
+ cameraChunks.length = 0;
123
+ pendingStops--;
124
+ if (pendingStops <= 0)
125
+ maybeFinalize();
126
+ }
127
+ const handle = {
128
+ start() {
129
+ if (released)
130
+ return;
131
+ screenChunks.length = 0;
132
+ cameraChunks.length = 0;
133
+ const screen = createRecorder(combinedStream, videoBitsPerSecond, preferredMime);
134
+ screenRecorder = screen.recorder;
135
+ screenMime = screen.mimeType;
136
+ screenRecorder.ondataavailable = (e) => {
137
+ if (e.data.size > 0)
138
+ screenChunks.push(e.data);
139
+ };
140
+ screenRecorder.onstop = onScreenStop;
141
+ screenRecorder.onerror = onScreenError;
142
+ pendingStops = 1;
143
+ if (cameraVideoStream && cameraVideoStream.getVideoTracks().length > 0) {
144
+ const camStream = new MediaStream(cameraVideoStream.getVideoTracks());
145
+ const cam = createRecorder(camStream, cameraBitsPerSecond, preferredMime);
146
+ cameraRecorder = cam.recorder;
147
+ cameraMime = cam.mimeType;
148
+ cameraRecorder.ondataavailable = (e) => {
149
+ if (e.data.size > 0)
150
+ cameraChunks.push(e.data);
151
+ };
152
+ cameraRecorder.onstop = onCameraStop;
153
+ cameraRecorder.onerror = onCameraError;
154
+ pendingStops = 2;
155
+ }
156
+ const videoTrack = combinedStream.getVideoTracks()[0];
157
+ if (videoTrack) {
158
+ shareEndedListener = () => handle.stop();
159
+ videoTrack.addEventListener("ended", shareEndedListener);
160
+ }
161
+ // No timeslice: one continuous recording; final blob delivered in dataavailable when we stop().
162
+ screenRecorder.start();
163
+ cameraRecorder?.start();
164
+ const blob = new Blob([timer_worker_1.TIMER_WORKER_SOURCE], { type: "application/javascript" });
165
+ workerUrl = URL.createObjectURL(blob);
166
+ worker = new Worker(workerUrl);
167
+ worker.onmessage = (e) => callbacks.onDurationTick?.(e.data);
168
+ worker.postMessage("start");
169
+ maxTimerId = setTimeout(() => handle.stop(), maxDurationMs);
170
+ },
171
+ stop() {
172
+ if (released)
173
+ return;
174
+ if (maxTimerId != null) {
175
+ clearTimeout(maxTimerId);
176
+ maxTimerId = null;
177
+ }
178
+ if (worker) {
179
+ worker.postMessage("stop");
180
+ worker = null;
181
+ }
182
+ if (workerUrl) {
183
+ URL.revokeObjectURL(workerUrl);
184
+ workerUrl = null;
185
+ }
186
+ // Flush any buffered data so we get a final chunk before stop.
187
+ try {
188
+ if (screenRecorder?.state === "recording" || screenRecorder?.state === "paused") {
189
+ screenRecorder.requestData();
190
+ }
191
+ if (cameraRecorder?.state === "recording" || cameraRecorder?.state === "paused") {
192
+ cameraRecorder.requestData();
193
+ }
194
+ }
195
+ catch {
196
+ // ignore
197
+ }
198
+ if (screenRecorder && (screenRecorder.state === "recording" || screenRecorder.state === "paused")) {
199
+ screenRecorder.stop();
200
+ }
201
+ if (cameraRecorder && (cameraRecorder.state === "recording" || cameraRecorder.state === "paused")) {
202
+ cameraRecorder.stop();
203
+ }
204
+ },
205
+ pause() {
206
+ if (released)
207
+ return;
208
+ if (screenRecorder?.state === "recording")
209
+ screenRecorder.pause();
210
+ if (cameraRecorder?.state === "recording")
211
+ cameraRecorder.pause();
212
+ worker?.postMessage("pause");
213
+ },
214
+ resume() {
215
+ if (released)
216
+ return;
217
+ if (screenRecorder?.state === "paused")
218
+ screenRecorder.resume();
219
+ if (cameraRecorder?.state === "paused")
220
+ cameraRecorder.resume();
221
+ worker?.postMessage("resume");
222
+ },
223
+ release() {
224
+ if (released)
225
+ return;
226
+ if (screenRecorder && (screenRecorder.state === "recording" || screenRecorder.state === "paused")) {
227
+ screenRecorder.stop();
228
+ }
229
+ if (cameraRecorder && (cameraRecorder.state === "recording" || cameraRecorder.state === "paused")) {
230
+ cameraRecorder.stop();
231
+ }
232
+ finish();
233
+ },
234
+ };
235
+ return handle;
236
+ }
237
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/recorder/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Centralized MIME/codec selection for Chromium-first recording.
3
+ * Single place for container choice to avoid scattered logic and broken preview.
4
+ */
5
+ export declare function isRecorderSupported(): boolean;
6
+ export declare function getPreferredMimeType(): string;
7
+ export declare function mimeBase(fullMime: string): string;
8
+ //# sourceMappingURL=support.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"support.d.ts","sourceRoot":"","sources":["../../src/recorder/support.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,wBAAgB,mBAAmB,IAAI,OAAO,CAK7C;AAED,wBAAgB,oBAAoB,IAAI,MAAM,CAU7C;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEjD"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ /**
3
+ * Centralized MIME/codec selection for Chromium-first recording.
4
+ * Single place for container choice to avoid scattered logic and broken preview.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.isRecorderSupported = isRecorderSupported;
8
+ exports.getPreferredMimeType = getPreferredMimeType;
9
+ exports.mimeBase = mimeBase;
10
+ const MIME_CANDIDATES = [
11
+ "video/webm;codecs=vp9,opus",
12
+ "video/webm;codecs=vp8,opus",
13
+ "video/webm;codecs=vp9",
14
+ "video/webm;codecs=vp8",
15
+ "video/webm",
16
+ "video/mp4;codecs=avc1.42E01E,mp4a.40.2",
17
+ "video/mp4;codecs=avc1",
18
+ "video/mp4",
19
+ ];
20
+ function isRecorderSupported() {
21
+ if (typeof window === "undefined")
22
+ return false;
23
+ if (typeof MediaRecorder === "undefined")
24
+ return false;
25
+ if (!navigator.mediaDevices?.getDisplayMedia)
26
+ return false;
27
+ return true;
28
+ }
29
+ function getPreferredMimeType() {
30
+ for (const mime of MIME_CANDIDATES) {
31
+ if (typeof MediaRecorder !== "undefined" &&
32
+ MediaRecorder.isTypeSupported(mime)) {
33
+ return mime;
34
+ }
35
+ }
36
+ return "video/webm";
37
+ }
38
+ function mimeBase(fullMime) {
39
+ return (fullMime || "video/webm").split(";")[0];
40
+ }
41
+ //# sourceMappingURL=support.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"support.js","sourceRoot":"","sources":["../../src/recorder/support.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAaH,kDAKC;AAED,oDAUC;AAED,4BAEC;AAhCD,MAAM,eAAe,GAAG;IACtB,4BAA4B;IAC5B,4BAA4B;IAC5B,uBAAuB;IACvB,uBAAuB;IACvB,YAAY;IACZ,wCAAwC;IACxC,uBAAuB;IACvB,WAAW;CACH,CAAC;AAEX,SAAgB,mBAAmB;IACjC,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IAChD,IAAI,OAAO,aAAa,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IACvD,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,eAAe;QAAE,OAAO,KAAK,CAAC;IAC3D,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,oBAAoB;IAClC,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;QACnC,IACE,OAAO,aAAa,KAAK,WAAW;YACpC,aAAa,CAAC,eAAe,CAAC,IAAI,CAAC,EACnC,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,SAAgB,QAAQ,CAAC,QAAgB;IACvC,OAAO,CAAC,QAAQ,IAAI,YAAY,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Inline worker code for elapsed-time counter (background-tab safe).
3
+ */
4
+ export declare const TIMER_WORKER_SOURCE = "\nlet tid = null;\nlet elapsed = 0;\nlet lastResume = 0;\nfunction tick() {\n self.postMessage(elapsed + Math.floor((Date.now() - lastResume) / 1000));\n tid = setTimeout(tick, 500);\n}\nself.onmessage = function(e) {\n if (e.data === \"start\" || e.data === \"resume\") {\n lastResume = Date.now();\n tick();\n } else if (e.data === \"pause\") {\n if (tid !== null) { clearTimeout(tid); tid = null; }\n elapsed += Math.floor((Date.now() - lastResume) / 1000);\n } else if (e.data === \"stop\") {\n if (tid !== null) clearTimeout(tid);\n self.close();\n }\n};\n";
5
+ //# sourceMappingURL=timer-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timer-worker.d.ts","sourceRoot":"","sources":["../../src/recorder/timer-worker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,mBAAmB,8kBAoB/B,CAAC"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ /**
3
+ * Inline worker code for elapsed-time counter (background-tab safe).
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.TIMER_WORKER_SOURCE = void 0;
7
+ exports.TIMER_WORKER_SOURCE = `
8
+ let tid = null;
9
+ let elapsed = 0;
10
+ let lastResume = 0;
11
+ function tick() {
12
+ self.postMessage(elapsed + Math.floor((Date.now() - lastResume) / 1000));
13
+ tid = setTimeout(tick, 500);
14
+ }
15
+ self.onmessage = function(e) {
16
+ if (e.data === "start" || e.data === "resume") {
17
+ lastResume = Date.now();
18
+ tick();
19
+ } else if (e.data === "pause") {
20
+ if (tid !== null) { clearTimeout(tid); tid = null; }
21
+ elapsed += Math.floor((Date.now() - lastResume) / 1000);
22
+ } else if (e.data === "stop") {
23
+ if (tid !== null) clearTimeout(tid);
24
+ self.close();
25
+ }
26
+ };
27
+ `;
28
+ //# sourceMappingURL=timer-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timer-worker.js","sourceRoot":"","sources":["../../src/recorder/timer-worker.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEU,QAAA,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;CAoBlC,CAAC"}