@codefilm/recorder 3.0.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.
@@ -0,0 +1,11 @@
1
+ import { FilmRecorder } from '../core/FilmRecorder';
2
+ import { FilmRecorderOptions, RecorderState } from '../core/types';
3
+ export declare function useFilmRecorder(options?: FilmRecorderOptions): {
4
+ recorder: FilmRecorder | null;
5
+ state: RecorderState | null;
6
+ tourState: "idle" | "running" | "stopped" | "error";
7
+ currentScene: string | null;
8
+ stopTour: () => Promise<void>;
9
+ stopAll: () => Promise<void>;
10
+ };
11
+ //# sourceMappingURL=useFilmRecorder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFilmRecorder.d.ts","sourceRoot":"","sources":["../../src/react/useFilmRecorder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnE,wBAAgB,eAAe,CAAC,OAAO,GAAE,mBAAwB;;;;;;;EA4JhE"}
@@ -0,0 +1,61 @@
1
+ import { useRef as f, useState as i, useEffect as t } from "react";
2
+ import { FilmRecorder as C } from "../core/FilmRecorder.js";
3
+ function w(e = {}) {
4
+ const n = f(e);
5
+ n.current = e;
6
+ const [S, o] = i(null), [m, d] = i("idle"), [s, a] = i(null), r = f(null);
7
+ t(() => {
8
+ const l = new C(n.current);
9
+ r.current = l;
10
+ const c = l.getState();
11
+ o(c), d(c.tourState), a(c.currentScene);
12
+ const R = l.onStateChange((u) => {
13
+ o(u), d(u.tourState), a(u.currentScene);
14
+ });
15
+ return () => {
16
+ R(), l.destroy(), r.current = null;
17
+ };
18
+ }, []), t(() => {
19
+ r.current && e.autoZoom !== void 0 && r.current.setAutoZoom(e.autoZoom);
20
+ }, [e.autoZoom]), t(() => {
21
+ r.current && e.pauseDuringScroll !== void 0 && r.current.setPauseDuringScroll(e.pauseDuringScroll);
22
+ }, [e.pauseDuringScroll]), t(() => {
23
+ r.current && e.showGrid !== void 0 && r.current.setShowGrid(e.showGrid);
24
+ }, [e.showGrid]), t(() => {
25
+ r.current && e.showOutline !== void 0 && r.current.setShowOutline(e.showOutline);
26
+ }, [e.showOutline]), t(() => {
27
+ r.current && e.elementSelector !== void 0 && r.current.setElementSelector(e.elementSelector);
28
+ }, [e.elementSelector]), t(() => {
29
+ r.current && e.elementPadding !== void 0 && r.current.setElementPadding(e.elementPadding);
30
+ }, [e.elementPadding]), t(() => {
31
+ r.current && e.fixedRecordingRegion !== void 0 && r.current.setFixedRecordingRegion(e.fixedRecordingRegion);
32
+ }, [e.fixedRecordingRegion]), t(() => {
33
+ r.current && e.movePointerToSelector !== void 0 && r.current.setMovePointerToSelector(e.movePointerToSelector);
34
+ }, [e.movePointerToSelector]), t(() => {
35
+ r.current && e.ignoreSelector !== void 0 && r.current.setIgnoreSelector(e.ignoreSelector);
36
+ }, [e.ignoreSelector]), t(() => {
37
+ r.current && e.pointerClassName !== void 0 && r.current.setPointerClassName(e.pointerClassName);
38
+ }, [e.pointerClassName]), t(() => {
39
+ r.current && e.pointerFillColor !== void 0 && r.current.setPointerFillColor(e.pointerFillColor);
40
+ }, [e.pointerFillColor]), t(() => {
41
+ r.current && e.pointerBorderColor !== void 0 && r.current.setPointerBorderColor(e.pointerBorderColor);
42
+ }, [e.pointerBorderColor]), t(() => {
43
+ r.current && e.pointerRippleColor !== void 0 && r.current.setPointerRippleColor(e.pointerRippleColor);
44
+ }, [e.pointerRippleColor]), t(() => {
45
+ r.current && e.disableRipple !== void 0 && r.current.setDisableRipple(e.disableRipple);
46
+ }, [e.disableRipple]), t(() => {
47
+ r.current && e.overlays !== void 0 && r.current.setOverlays(e.overlays);
48
+ }, [e.overlays]);
49
+ const v = () => r.current?.stopTour() ?? Promise.resolve(), g = () => r.current?.stopAll() ?? Promise.resolve();
50
+ return {
51
+ recorder: r.current,
52
+ state: S,
53
+ tourState: m,
54
+ currentScene: s,
55
+ stopTour: v,
56
+ stopAll: g
57
+ };
58
+ }
59
+ export {
60
+ w as useFilmRecorder
61
+ };
@@ -0,0 +1,21 @@
1
+ import { FilmRecorder } from '../core/FilmRecorder';
2
+ export declare class RegionRecorderUI {
3
+ private recorder;
4
+ private container;
5
+ private unsubscribe;
6
+ private settingsBar;
7
+ private gridOverlay;
8
+ private cropBox;
9
+ private recordBtn;
10
+ private pngBtn;
11
+ private resSelect;
12
+ private gridCheckbox;
13
+ private autoZoomCheckbox;
14
+ private pauseScrollCheckbox;
15
+ private outlineCheckbox;
16
+ constructor(recorder: FilmRecorder, container?: HTMLElement);
17
+ private mount;
18
+ private updateDOM;
19
+ unmount(): void;
20
+ }
21
+ //# sourceMappingURL=RegionRecorderUI.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RegionRecorderUI.d.ts","sourceRoot":"","sources":["../../src/vanilla/RegionRecorderUI.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA6C,MAAM,sBAAsB,CAAC;AAG/F,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,WAAW,CAA6B;IAGhD,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,OAAO,CAA+B;IAG9C,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,YAAY,CAAiC;IACrD,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,mBAAmB,CAAiC;IAC5D,OAAO,CAAC,eAAe,CAAiC;gBAE5C,QAAQ,EAAE,YAAY,EAAE,SAAS,GAAE,WAA2B;IAO1E,OAAO,CAAC,KAAK;IA4Ib,OAAO,CAAC,SAAS;IAuEV,OAAO;CAgBf"}
@@ -0,0 +1,128 @@
1
+ import { HEADER_PX as d, OUTLINE_PX as o, SHORTCUT_KEY as l } from "../core/FilmRecorder.js";
2
+ class f {
3
+ recorder;
4
+ container;
5
+ unsubscribe = null;
6
+ // DOM Elements
7
+ settingsBar = null;
8
+ gridOverlay = null;
9
+ cropBox = null;
10
+ // Cached state controls
11
+ recordBtn = null;
12
+ pngBtn = null;
13
+ resSelect = null;
14
+ gridCheckbox = null;
15
+ autoZoomCheckbox = null;
16
+ pauseScrollCheckbox = null;
17
+ outlineCheckbox = null;
18
+ constructor(e, r = document.body) {
19
+ this.recorder = e, this.container = r, this.mount();
20
+ }
21
+ mount() {
22
+ if (typeof window > "u") return;
23
+ this.settingsBar = document.createElement("div"), this.settingsBar.className = "cfr-settings-bar", this.settingsBar.innerHTML = `
24
+ <div class="cfr-settings-bar-content">
25
+ <button class="cfr-btn cfr-btn-default" id="cfr-record-btn" aria-label="Start recording">
26
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor" style="margin-right:4px;"><circle cx="12" cy="12" r="10"/></svg>
27
+ Record <span class="cfr-kbd"></span>
28
+ </button>
29
+ <button class="cfr-btn cfr-btn-secondary" id="cfr-png-btn" disabled>
30
+ PNG frame
31
+ </button>
32
+ <button class="cfr-btn cfr-btn-ghost" id="cfr-full-btn">
33
+ Full <span class="cfr-kbd"></span>
34
+ </button>
35
+ <button class="cfr-btn cfr-btn-ghost" id="cfr-focus-btn">
36
+ Focus mouse <span class="cfr-kbd"></span>
37
+ </button>
38
+ <button class="cfr-btn cfr-btn-ghost" id="cfr-pause-mouse-btn">
39
+ Pause mouse <span class="cfr-kbd"></span>
40
+ </button>
41
+
42
+ <div class="cfr-divider"></div>
43
+
44
+ <div class="cfr-select-wrapper">
45
+ <select class="cfr-select" id="cfr-res-select"></select>
46
+ </div>
47
+
48
+ <div class="cfr-divider"></div>
49
+
50
+ <label class="cfr-checkbox-container">
51
+ <input type="checkbox" class="cfr-checkbox" id="cfr-grid-check">
52
+ <span class="cfr-label">Grid</span>
53
+ </label>
54
+ <label class="cfr-checkbox-container">
55
+ <input type="checkbox" class="cfr-checkbox" id="cfr-auto-zoom-check">
56
+ <span class="cfr-label">Auto-zoom on hold</span>
57
+ </label>
58
+ <label class="cfr-checkbox-container">
59
+ <input type="checkbox" class="cfr-checkbox" id="cfr-pause-scroll-check">
60
+ <span class="cfr-label">Pause zoom while scrolling</span>
61
+ </label>
62
+ <label class="cfr-checkbox-container">
63
+ <input type="checkbox" class="cfr-checkbox" id="cfr-outline-check">
64
+ <span class="cfr-label">Show outline border</span>
65
+ </label>
66
+ </div>
67
+ `, this.container.appendChild(this.settingsBar), this.gridOverlay = document.createElement("div"), this.gridOverlay.className = "cfr-grid-overlay", this.gridOverlay.setAttribute("aria-hidden", "true"), this.gridOverlay.style.top = `${d}px`, this.container.appendChild(this.gridOverlay), this.cropBox = document.createElement("div"), this.cropBox.className = "cfr-crop-box", this.cropBox.setAttribute("aria-label", "Cinematic 16:9 capture region");
68
+ const e = this.recorder.getState().showOutline;
69
+ this.cropBox.style.outline = e ? `${o}px solid var(--cfr-outline)` : "none", this.cropBox.style.outlineOffset = e ? `${o}px` : "0", this.container.appendChild(this.cropBox), this.recordBtn = this.container.querySelector("#cfr-record-btn"), this.pngBtn = this.container.querySelector("#cfr-png-btn"), this.resSelect = this.container.querySelector("#cfr-res-select"), this.gridCheckbox = this.container.querySelector("#cfr-grid-check"), this.autoZoomCheckbox = this.container.querySelector("#cfr-auto-zoom-check"), this.pauseScrollCheckbox = this.container.querySelector("#cfr-pause-scroll-check"), this.outlineCheckbox = this.container.querySelector("#cfr-outline-check");
70
+ const r = this.container.querySelector("#cfr-full-btn"), c = this.container.querySelector("#cfr-focus-btn"), n = this.container.querySelector("#cfr-pause-mouse-btn"), s = /Mac/i.test(navigator.platform) ? "⌘" : "Ctrl";
71
+ this.recordBtn && (this.recordBtn.querySelector(".cfr-kbd").textContent = `${s}+${l.toUpperCase()}`), r && (r.querySelector(".cfr-kbd").textContent = `${s}+↑`), c && (c.querySelector(".cfr-kbd").textContent = `${s}+↓`), n && (n.querySelector(".cfr-kbd").textContent = `${s}+L`), this.recorder.getState();
72
+ const a = this.recorder.options.resolutions;
73
+ a.forEach((t) => {
74
+ const i = document.createElement("option");
75
+ i.value = t.label, i.textContent = t.label, this.resSelect && this.resSelect.appendChild(i);
76
+ }), this.recordBtn?.addEventListener("click", () => {
77
+ this.recorder.getState().recording ? this.recorder.stopRecording() : this.recorder.startRecording();
78
+ }), this.pngBtn?.addEventListener("click", () => this.recorder.captureBitmap()), r?.addEventListener("click", () => this.recorder.resetFullScreen()), c?.addEventListener("click", () => this.recorder.zoomToMouse()), n?.addEventListener("click", () => {
79
+ const t = this.recorder.getState().mousePaused;
80
+ this.recorder.setMousePaused(!t);
81
+ }), this.resSelect?.addEventListener("change", (t) => {
82
+ const i = t.target.value, h = a.find((u) => u.label === i);
83
+ h && this.recorder.setResolution(h);
84
+ }), this.gridCheckbox?.addEventListener("change", (t) => {
85
+ this.recorder.setShowGrid(t.target.checked);
86
+ }), this.autoZoomCheckbox?.addEventListener("change", (t) => {
87
+ this.recorder.setAutoZoom(t.target.checked);
88
+ }), this.pauseScrollCheckbox?.addEventListener("change", (t) => {
89
+ this.recorder.setPauseDuringScroll(t.target.checked);
90
+ }), this.outlineCheckbox?.addEventListener("change", (t) => {
91
+ this.recorder.setShowOutline(t.target.checked);
92
+ }), this.unsubscribe = this.recorder.onStateChange((t) => this.updateDOM(t));
93
+ }
94
+ updateDOM(e) {
95
+ if (typeof window > "u") return;
96
+ const r = this.recorder.computeGrid(e.viewport.w, e.viewport.h);
97
+ if (this.recordBtn && (e.recording ? (this.recordBtn.className = "cfr-btn cfr-btn-destructive", this.recordBtn.innerHTML = `
98
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor" style="margin-right:4px;"><rect x="3" y="3" width="18" height="18" rx="2"/></svg>
99
+ ${e.mousePaused ? "Paused" : "Stop"}
100
+ <span class="cfr-kbd">${/Mac/i.test(navigator.platform) ? "⌘" : "Ctrl"}+${l.toUpperCase()}</span>
101
+ `) : (this.recordBtn.className = "cfr-btn cfr-btn-default", this.recordBtn.innerHTML = `
102
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor" style="margin-right:4px;"><circle cx="12" cy="12" r="10"/></svg>
103
+ Record
104
+ <span class="cfr-kbd">${/Mac/i.test(navigator.platform) ? "⌘" : "Ctrl"}+${l.toUpperCase()}</span>
105
+ `)), this.pngBtn && (this.pngBtn.disabled = !e.recording), this.resSelect && (this.resSelect.disabled = e.recording, this.resSelect.value = e.resolution.label), this.gridCheckbox && (this.gridCheckbox.disabled = e.recording, this.gridCheckbox.checked = e.showGrid), this.autoZoomCheckbox && (this.autoZoomCheckbox.checked = e.autoZoom), this.pauseScrollCheckbox && (this.pauseScrollCheckbox.checked = e.pauseDuringScroll), this.outlineCheckbox && (this.outlineCheckbox.checked = e.showOutline), this.gridOverlay) {
106
+ const c = e.showGrid && !e.recording;
107
+ this.gridOverlay.style.display = c ? "block" : "none", c && (this.gridOverlay.style.backgroundImage = `
108
+ linear-gradient(to right, var(--cfr-border) 1px, transparent 1px),
109
+ linear-gradient(to bottom, var(--cfr-border) 1px, transparent 1px)
110
+ `, this.gridOverlay.style.backgroundSize = `${r.cellW}px ${r.cellH}px`);
111
+ }
112
+ if (this.cropBox) {
113
+ const c = {
114
+ x: e.displayRect.col * r.cellW,
115
+ y: d + e.displayRect.row * r.cellH,
116
+ width: e.displayRect.w * r.cellW,
117
+ height: e.displayRect.h * r.cellH
118
+ };
119
+ this.cropBox.style.left = `${c.x}px`, this.cropBox.style.top = `${c.y}px`, this.cropBox.style.width = `${c.width}px`, this.cropBox.style.height = `${c.height}px`, this.cropBox.style.outline = e.showOutline ? `${o}px solid var(--cfr-outline)` : "none", this.cropBox.style.outlineOffset = e.showOutline ? `${o}px` : "0";
120
+ }
121
+ }
122
+ unmount() {
123
+ this.unsubscribe && (this.unsubscribe(), this.unsubscribe = null), this.settingsBar && this.settingsBar.parentNode && this.settingsBar.parentNode.removeChild(this.settingsBar), this.gridOverlay && this.gridOverlay.parentNode && this.gridOverlay.parentNode.removeChild(this.gridOverlay), this.cropBox && this.cropBox.parentNode && this.cropBox.parentNode.removeChild(this.cropBox);
124
+ }
125
+ }
126
+ export {
127
+ f as RegionRecorderUI
128
+ };
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@codefilm/recorder",
3
+ "version": "3.0.0",
4
+ "description": "Cinematic screen region recorder SDK with automatic focal zooming, pointer overlays, and custom aspects.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.umd.cjs"
14
+ },
15
+ "./app-script": {
16
+ "types": "./dist/core/app-script.d.ts",
17
+ "import": "./dist/core/app-script.js"
18
+ },
19
+ "./style.css": "./dist/code-film.css"
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+ssh://git@github.com/codedotfilm/code-film-recorder.git",
27
+ "directory": "sdk"
28
+ },
29
+ "bugs": {
30
+ "url": "https://github.com/codedotfilm/code-film-recorder/issues"
31
+ },
32
+ "homepage": "https://github.com/codedotfilm/code-film-recorder#readme",
33
+ "publishConfig": {
34
+ "access": "public"
35
+ },
36
+ "scripts": {
37
+ "build": "vite build",
38
+ "test": "bun test",
39
+ "prepublishOnly": "npm run build"
40
+ },
41
+ "sideEffects": [
42
+ "**/*.css",
43
+ "dist/*.css"
44
+ ],
45
+ "dependencies": {
46
+ "@openai/agents": "^0.1.0",
47
+ "openai": "^5.20.2",
48
+ "zod": "^3.24.2"
49
+ },
50
+ "peerDependencies": {
51
+ "react": "^18.0.0 || ^19.0.0",
52
+ "react-dom": "^18.0.0 || ^19.0.0"
53
+ },
54
+ "peerDependenciesMeta": {
55
+ "react": {
56
+ "optional": true
57
+ },
58
+ "react-dom": {
59
+ "optional": true
60
+ }
61
+ },
62
+ "devDependencies": {
63
+ "@types/react": "^19.0.0",
64
+ "@types/react-dom": "^19.0.0",
65
+ "@vitejs/plugin-react": "^5.0.0",
66
+ "typescript": "^5.8.3",
67
+ "vite": "^7.3.1",
68
+ "vite-plugin-dts": "^4.5.0"
69
+ }
70
+ }