@editframe/react 0.24.1-beta.0 → 0.25.0-beta.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 (79) hide show
  1. package/dist/components/TimeDisplay.d.ts +8 -0
  2. package/dist/components/TimeDisplay.js +10 -7
  3. package/dist/components/TimeDisplay.js.map +1 -0
  4. package/dist/elements/Audio.d.ts +8 -2
  5. package/dist/elements/Audio.js +10 -7
  6. package/dist/elements/Audio.js.map +1 -0
  7. package/dist/elements/Captions.d.ts +12 -6
  8. package/dist/elements/Captions.js +23 -24
  9. package/dist/elements/Captions.js.map +1 -0
  10. package/dist/elements/Image.d.ts +8 -2
  11. package/dist/elements/Image.js +10 -7
  12. package/dist/elements/Image.js.map +1 -0
  13. package/dist/elements/Surface.d.ts +8 -2
  14. package/dist/elements/Surface.js +12 -9
  15. package/dist/elements/Surface.js.map +1 -0
  16. package/dist/elements/ThumbnailStrip.d.ts +8 -2
  17. package/dist/elements/ThumbnailStrip.js +12 -9
  18. package/dist/elements/ThumbnailStrip.js.map +1 -0
  19. package/dist/elements/Timegroup.d.ts +8 -2
  20. package/dist/elements/Timegroup.js +10 -7
  21. package/dist/elements/Timegroup.js.map +1 -0
  22. package/dist/elements/Video.d.ts +8 -2
  23. package/dist/elements/Video.js +10 -7
  24. package/dist/elements/Video.js.map +1 -0
  25. package/dist/elements/Waveform.d.ts +8 -2
  26. package/dist/elements/Waveform.js +10 -7
  27. package/dist/elements/Waveform.js.map +1 -0
  28. package/dist/gui/Configuration.d.ts +8 -2
  29. package/dist/gui/Configuration.js +10 -7
  30. package/dist/gui/Configuration.js.map +1 -0
  31. package/dist/gui/Controls.d.ts +8 -2
  32. package/dist/gui/Controls.js +10 -7
  33. package/dist/gui/Controls.js.map +1 -0
  34. package/dist/gui/EFDial.d.ts +9 -3
  35. package/dist/gui/EFDial.js +11 -10
  36. package/dist/gui/EFDial.js.map +1 -0
  37. package/dist/gui/EFResizableBox.d.ts +9 -3
  38. package/dist/gui/EFResizableBox.js +11 -10
  39. package/dist/gui/EFResizableBox.js.map +1 -0
  40. package/dist/gui/Filmstrip.d.ts +8 -2
  41. package/dist/gui/Filmstrip.js +10 -7
  42. package/dist/gui/Filmstrip.js.map +1 -0
  43. package/dist/gui/FitScale.d.ts +8 -2
  44. package/dist/gui/FitScale.js +10 -7
  45. package/dist/gui/FitScale.js.map +1 -0
  46. package/dist/gui/FocusOverlay.d.ts +8 -2
  47. package/dist/gui/FocusOverlay.js +10 -7
  48. package/dist/gui/FocusOverlay.js.map +1 -0
  49. package/dist/gui/Pause.d.ts +8 -2
  50. package/dist/gui/Pause.js +10 -7
  51. package/dist/gui/Pause.js.map +1 -0
  52. package/dist/gui/Play.d.ts +8 -2
  53. package/dist/gui/Play.js +10 -7
  54. package/dist/gui/Play.js.map +1 -0
  55. package/dist/gui/Preview.d.ts +8 -2
  56. package/dist/gui/Preview.js +10 -7
  57. package/dist/gui/Preview.js.map +1 -0
  58. package/dist/gui/Scrubber.d.ts +8 -2
  59. package/dist/gui/Scrubber.js +10 -7
  60. package/dist/gui/Scrubber.js.map +1 -0
  61. package/dist/gui/ToggleLoop.d.ts +8 -2
  62. package/dist/gui/ToggleLoop.js +10 -7
  63. package/dist/gui/ToggleLoop.js.map +1 -0
  64. package/dist/gui/TogglePlay.d.ts +8 -2
  65. package/dist/gui/TogglePlay.js +10 -7
  66. package/dist/gui/TogglePlay.js.map +1 -0
  67. package/dist/gui/Workbench.d.ts +8 -2
  68. package/dist/gui/Workbench.js +10 -7
  69. package/dist/gui/Workbench.js.map +1 -0
  70. package/dist/hooks/create-element.d.ts +9 -18
  71. package/dist/hooks/create-element.js +72 -94
  72. package/dist/hooks/create-element.js.map +1 -0
  73. package/dist/hooks/useTimingInfo.d.ts +12 -6
  74. package/dist/hooks/useTimingInfo.js +63 -66
  75. package/dist/hooks/useTimingInfo.js.map +1 -0
  76. package/dist/index.d.ts +25 -24
  77. package/dist/index.js +2 -30
  78. package/package.json +10 -19
  79. package/tsdown.config.ts +36 -0
@@ -1,68 +1,65 @@
1
- import { useRef, useState, useEffect } from "react";
2
- class CurrentTimeController {
3
- constructor(host, setCurrentTime) {
4
- this.host = host;
5
- this.setCurrentTime = setCurrentTime;
6
- this.host.addController(this);
7
- }
8
- #lastTaskPromise = null;
9
- #isConnected = false;
10
- hostConnected() {
11
- this.#isConnected = true;
12
- }
13
- hostDisconnected() {
14
- this.#isConnected = false;
15
- this.#lastTaskPromise = null;
16
- this.host.removeController(this);
17
- }
18
- hostUpdated() {
19
- const currentTaskPromise = this.host.frameTask.taskComplete;
20
- if (currentTaskPromise !== this.#lastTaskPromise) {
21
- this.#lastTaskPromise = currentTaskPromise;
22
- currentTaskPromise.then(() => {
23
- if (this.#isConnected) {
24
- this.#updateReactState();
25
- }
26
- }).catch(() => {
27
- });
28
- }
29
- }
30
- #updateReactState() {
31
- this.setCurrentTime({
32
- ownCurrentTimeMs: this.host.ownCurrentTimeMs,
33
- durationMs: this.host.durationMs,
34
- percentComplete: this.host.ownCurrentTimeMs / this.host.durationMs
35
- });
36
- }
37
- // Public method to manually trigger sync (for initialization)
38
- syncNow() {
39
- this.#updateReactState();
40
- }
41
- }
42
- const useTimingInfo = (timegroupRef = useRef(null)) => {
43
- const [timeInfo, setTimeInfo] = useState({
44
- ownCurrentTimeMs: 0,
45
- durationMs: 0,
46
- percentComplete: 0
47
- });
48
- useEffect(() => {
49
- if (!timegroupRef.current) {
50
- throw new Error("Timegroup ref not set");
51
- }
52
- const controller = new CurrentTimeController(
53
- timegroupRef.current,
54
- setTimeInfo
55
- );
56
- if (timegroupRef.current.isConnected) {
57
- controller.hostConnected();
58
- controller.syncNow();
59
- }
60
- return () => {
61
- controller.hostDisconnected();
62
- };
63
- }, [timegroupRef.current]);
64
- return { ...timeInfo, ref: timegroupRef };
1
+ import { useEffect, useRef, useState } from "react";
2
+
3
+ //#region src/hooks/useTimingInfo.ts
4
+ var CurrentTimeController = class {
5
+ #lastTaskPromise = null;
6
+ #isConnected = false;
7
+ constructor(host, setCurrentTime) {
8
+ this.host = host;
9
+ this.setCurrentTime = setCurrentTime;
10
+ this.host.addController(this);
11
+ }
12
+ hostConnected() {
13
+ this.#isConnected = true;
14
+ }
15
+ hostDisconnected() {
16
+ this.#isConnected = false;
17
+ this.#lastTaskPromise = null;
18
+ this.host.removeController(this);
19
+ }
20
+ hostUpdated() {
21
+ const currentTaskPromise = this.host.frameTask.taskComplete;
22
+ if (currentTaskPromise !== this.#lastTaskPromise) {
23
+ this.#lastTaskPromise = currentTaskPromise;
24
+ currentTaskPromise.then(() => {
25
+ if (this.#isConnected) this.#updateReactState();
26
+ }).catch(() => {});
27
+ }
28
+ }
29
+ #updateReactState() {
30
+ this.setCurrentTime({
31
+ ownCurrentTimeMs: this.host.ownCurrentTimeMs,
32
+ durationMs: this.host.durationMs,
33
+ percentComplete: this.host.ownCurrentTimeMs / this.host.durationMs
34
+ });
35
+ }
36
+ syncNow() {
37
+ this.#updateReactState();
38
+ }
65
39
  };
66
- export {
67
- useTimingInfo
40
+ const useTimingInfo = (timegroupRef = useRef(null)) => {
41
+ const [timeInfo, setTimeInfo] = useState({
42
+ ownCurrentTimeMs: 0,
43
+ durationMs: 0,
44
+ percentComplete: 0
45
+ });
46
+ useEffect(() => {
47
+ if (!timegroupRef.current) throw new Error("Timegroup ref not set");
48
+ const controller = new CurrentTimeController(timegroupRef.current, setTimeInfo);
49
+ if (timegroupRef.current.isConnected) {
50
+ controller.hostConnected();
51
+ controller.syncNow();
52
+ }
53
+ return () => {
54
+ controller.hostDisconnected();
55
+ };
56
+ }, [timegroupRef.current]);
57
+ return {
58
+ ...timeInfo,
59
+ ref: timegroupRef
60
+ };
68
61
  };
62
+
63
+ //#endregion
64
+ export { useTimingInfo };
65
+ //# sourceMappingURL=useTimingInfo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTimingInfo.js","names":["host: {\n ownCurrentTimeMs: number;\n durationMs: number;\n frameTask: Task<readonly unknown[], unknown>;\n } & ReactiveControllerHost","setCurrentTime: React.Dispatch<React.SetStateAction<TimeInfo>>","#isConnected","#lastTaskPromise","#updateReactState"],"sources":["../../src/hooks/useTimingInfo.ts"],"sourcesContent":["import type { EFTimegroup } from \"@editframe/elements\";\nimport type { Task } from \"@lit/task\";\nimport type { ReactiveController, ReactiveControllerHost } from \"lit\";\nimport { useEffect, useRef, useState } from \"react\";\n\ninterface TimeInfo {\n ownCurrentTimeMs: number;\n durationMs: number;\n percentComplete: number;\n}\n\nclass CurrentTimeController implements ReactiveController {\n #lastTaskPromise: Promise<unknown> | null = null;\n #isConnected = false;\n\n constructor(\n private host: {\n ownCurrentTimeMs: number;\n durationMs: number;\n frameTask: Task<readonly unknown[], unknown>;\n } & ReactiveControllerHost,\n private setCurrentTime: React.Dispatch<React.SetStateAction<TimeInfo>>,\n ) {\n this.host.addController(this);\n }\n\n hostConnected(): void {\n this.#isConnected = true;\n }\n\n hostDisconnected(): void {\n this.#isConnected = false;\n this.#lastTaskPromise = null;\n this.host.removeController(this);\n }\n\n hostUpdated(): void {\n const currentTaskPromise = this.host.frameTask.taskComplete;\n\n // Detect if a new frame task has started (promise reference changed)\n if (currentTaskPromise !== this.#lastTaskPromise) {\n this.#lastTaskPromise = currentTaskPromise;\n\n // Wait for this specific task to complete, then update React\n // This is async so it doesn't block the update cycle\n currentTaskPromise\n .then(() => {\n // Only update if still connected\n if (this.#isConnected) {\n this.#updateReactState();\n }\n })\n .catch(() => {\n // Ignore task errors - we'll continue observing\n });\n }\n }\n\n #updateReactState(): void {\n // Always update to ensure React has the latest state\n this.setCurrentTime({\n ownCurrentTimeMs: this.host.ownCurrentTimeMs,\n durationMs: this.host.durationMs,\n percentComplete: this.host.ownCurrentTimeMs / this.host.durationMs,\n });\n }\n\n // Public method to manually trigger sync (for initialization)\n syncNow(): void {\n this.#updateReactState();\n }\n}\n\nexport const useTimingInfo = (\n timegroupRef: React.RefObject<EFTimegroup> = useRef<EFTimegroup>(null),\n) => {\n const [timeInfo, setTimeInfo] = useState<TimeInfo>({\n ownCurrentTimeMs: 0,\n durationMs: 0,\n percentComplete: 0,\n });\n\n useEffect(() => {\n if (!timegroupRef.current) {\n throw new Error(\"Timegroup ref not set\");\n }\n\n const controller = new CurrentTimeController(\n timegroupRef.current,\n setTimeInfo,\n );\n\n // Trigger initial update if the timegroup is already connected\n if (timegroupRef.current.isConnected) {\n controller.hostConnected();\n // Sync initial state immediately\n controller.syncNow();\n }\n\n // Cleanup function\n return () => {\n controller.hostDisconnected();\n };\n }, [timegroupRef.current]);\n\n return { ...timeInfo, ref: timegroupRef };\n};\n"],"mappings":";;;AAWA,IAAM,wBAAN,MAA0D;CACxD,mBAA4C;CAC5C,eAAe;CAEf,YACE,AAAQA,MAKR,AAAQC,gBACR;EANQ;EAKA;AAER,OAAK,KAAK,cAAc,KAAK;;CAG/B,gBAAsB;AACpB,QAAKC,cAAe;;CAGtB,mBAAyB;AACvB,QAAKA,cAAe;AACpB,QAAKC,kBAAmB;AACxB,OAAK,KAAK,iBAAiB,KAAK;;CAGlC,cAAoB;EAClB,MAAM,qBAAqB,KAAK,KAAK,UAAU;AAG/C,MAAI,uBAAuB,MAAKA,iBAAkB;AAChD,SAAKA,kBAAmB;AAIxB,sBACG,WAAW;AAEV,QAAI,MAAKD,YACP,OAAKE,kBAAmB;KAE1B,CACD,YAAY,GAEX;;;CAIR,oBAA0B;AAExB,OAAK,eAAe;GAClB,kBAAkB,KAAK,KAAK;GAC5B,YAAY,KAAK,KAAK;GACtB,iBAAiB,KAAK,KAAK,mBAAmB,KAAK,KAAK;GACzD,CAAC;;CAIJ,UAAgB;AACd,QAAKA,kBAAmB;;;AAI5B,MAAa,iBACX,eAA6C,OAAoB,KAAK,KACnE;CACH,MAAM,CAAC,UAAU,eAAe,SAAmB;EACjD,kBAAkB;EAClB,YAAY;EACZ,iBAAiB;EAClB,CAAC;AAEF,iBAAgB;AACd,MAAI,CAAC,aAAa,QAChB,OAAM,IAAI,MAAM,wBAAwB;EAG1C,MAAM,aAAa,IAAI,sBACrB,aAAa,SACb,YACD;AAGD,MAAI,aAAa,QAAQ,aAAa;AACpC,cAAW,eAAe;AAE1B,cAAW,SAAS;;AAItB,eAAa;AACX,cAAW,kBAAkB;;IAE9B,CAAC,aAAa,QAAQ,CAAC;AAE1B,QAAO;EAAE,GAAG;EAAU,KAAK;EAAc"}
package/dist/index.d.ts CHANGED
@@ -1,24 +1,25 @@
1
- export { TimeDisplay } from './components/TimeDisplay.js';
2
- export { Audio } from './elements/Audio.js';
3
- export { Captions, CaptionsActiveWord, CaptionsAfterActiveWord, CaptionsBeforeActiveWord, CaptionsSegment, } from './elements/Captions.js';
4
- export { Image } from './elements/Image.js';
5
- export { Surface } from './elements/Surface.js';
6
- export { ThumbnailStrip } from './elements/ThumbnailStrip.js';
7
- export { Timegroup } from './elements/Timegroup.js';
8
- export { Video } from './elements/Video.js';
9
- export { Waveform } from './elements/Waveform.js';
10
- export { Configuration } from './gui/Configuration.js';
11
- export { Controls } from './gui/Controls.js';
12
- export { Dial } from './gui/EFDial.js';
13
- export { ResizableBox } from './gui/EFResizableBox.js';
14
- export { Filmstrip } from './gui/Filmstrip.js';
15
- export { FitScale } from './gui/FitScale.js';
16
- export { FocusOverlay } from './gui/FocusOverlay.js';
17
- export { Pause } from './gui/Pause.js';
18
- export { Play } from './gui/Play.js';
19
- export { Preview } from './gui/Preview.js';
20
- export { Scrubber } from './gui/Scrubber.js';
21
- export { ToggleLoop } from './gui/ToggleLoop.js';
22
- export { TogglePlay } from './gui/TogglePlay.js';
23
- export { Workbench } from './gui/Workbench.js';
24
- export { useTimingInfo } from './hooks/useTimingInfo.js';
1
+ import { TimeDisplay } from "./components/TimeDisplay.js";
2
+ import { Audio } from "./elements/Audio.js";
3
+ import { Captions, CaptionsActiveWord, CaptionsAfterActiveWord, CaptionsBeforeActiveWord, CaptionsSegment } from "./elements/Captions.js";
4
+ import { Image } from "./elements/Image.js";
5
+ import { Surface } from "./elements/Surface.js";
6
+ import { ThumbnailStrip } from "./elements/ThumbnailStrip.js";
7
+ import { Timegroup } from "./elements/Timegroup.js";
8
+ import { Video } from "./elements/Video.js";
9
+ import { Waveform } from "./elements/Waveform.js";
10
+ import { Configuration } from "./gui/Configuration.js";
11
+ import { Controls } from "./gui/Controls.js";
12
+ import { Dial } from "./gui/EFDial.js";
13
+ import { ResizableBox } from "./gui/EFResizableBox.js";
14
+ import { Filmstrip } from "./gui/Filmstrip.js";
15
+ import { FitScale } from "./gui/FitScale.js";
16
+ import { FocusOverlay } from "./gui/FocusOverlay.js";
17
+ import { Pause } from "./gui/Pause.js";
18
+ import { Play } from "./gui/Play.js";
19
+ import { Preview } from "./gui/Preview.js";
20
+ import { Scrubber } from "./gui/Scrubber.js";
21
+ import { ToggleLoop } from "./gui/ToggleLoop.js";
22
+ import { TogglePlay } from "./gui/TogglePlay.js";
23
+ import { Workbench } from "./gui/Workbench.js";
24
+ import { useTimingInfo } from "./hooks/useTimingInfo.js";
25
+ export { Audio, Captions, CaptionsActiveWord, CaptionsAfterActiveWord, CaptionsBeforeActiveWord, CaptionsSegment, Configuration, Controls, Dial, Filmstrip, FitScale, FocusOverlay, Image, Pause, Play, Preview, ResizableBox, Scrubber, Surface, ThumbnailStrip, TimeDisplay, Timegroup, ToggleLoop, TogglePlay, Video, Waveform, Workbench, useTimingInfo };
package/dist/index.js CHANGED
@@ -22,33 +22,5 @@ import { ToggleLoop } from "./gui/ToggleLoop.js";
22
22
  import { TogglePlay } from "./gui/TogglePlay.js";
23
23
  import { Workbench } from "./gui/Workbench.js";
24
24
  import { useTimingInfo } from "./hooks/useTimingInfo.js";
25
- export {
26
- Audio,
27
- Captions,
28
- CaptionsActiveWord,
29
- CaptionsAfterActiveWord,
30
- CaptionsBeforeActiveWord,
31
- CaptionsSegment,
32
- Configuration,
33
- Controls,
34
- Dial,
35
- Filmstrip,
36
- FitScale,
37
- FocusOverlay,
38
- Image,
39
- Pause,
40
- Play,
41
- Preview,
42
- ResizableBox,
43
- Scrubber,
44
- Surface,
45
- ThumbnailStrip,
46
- TimeDisplay,
47
- Timegroup,
48
- ToggleLoop,
49
- TogglePlay,
50
- Video,
51
- Waveform,
52
- Workbench,
53
- useTimingInfo
54
- };
25
+
26
+ export { Audio, Captions, CaptionsActiveWord, CaptionsAfterActiveWord, CaptionsBeforeActiveWord, CaptionsSegment, Configuration, Controls, Dial, Filmstrip, FitScale, FocusOverlay, Image, Pause, Play, Preview, ResizableBox, Scrubber, Surface, ThumbnailStrip, TimeDisplay, Timegroup, ToggleLoop, TogglePlay, Video, Waveform, Workbench, useTimingInfo };
package/package.json CHANGED
@@ -1,31 +1,22 @@
1
1
  {
2
2
  "name": "@editframe/react",
3
- "version": "0.24.1-beta.0",
3
+ "version": "0.25.0-beta.0",
4
4
  "description": "",
5
5
  "exports": {
6
- ".": {
7
- "import": {
8
- "types": "./dist/index.d.ts",
9
- "default": "./dist/index.js"
10
- }
11
- },
12
- "./types.json": {
13
- "import": {
14
- "default": "./types.json"
15
- }
16
- }
6
+ ".": "./dist/index.js",
7
+ "./package.json": "./package.json"
17
8
  },
18
9
  "type": "module",
19
10
  "scripts": {
20
11
  "typecheck": "tsc --noEmit --emitDeclarationOnly false",
21
- "build": "vite build",
22
- "build:watch": "vite build --watch",
12
+ "build": "tsdown",
13
+ "build:watch": "tsdown --watch",
23
14
  "typedoc": "typedoc --json ./types.json --plugin typedoc-plugin-zod --excludeExternals ./src && jq -c . ./types.json > ./types.tmp.json && mv ./types.tmp.json ./types.json"
24
15
  },
25
16
  "author": "",
26
17
  "license": "UNLICENSED",
27
18
  "dependencies": {
28
- "@editframe/elements": "0.24.1-beta.0",
19
+ "@editframe/elements": "0.25.0-beta.0",
29
20
  "@lit/react": "^1.0.8",
30
21
  "@lit/task": "^1.0.1",
31
22
  "debug": "^4.3.5",
@@ -37,10 +28,10 @@
37
28
  "@types/node": "^22.0.0",
38
29
  "@types/react": "^18.3.0",
39
30
  "@types/react-dom": "^18.3.0",
40
- "rollup-plugin-tsconfig-paths": "^1.5.2",
41
31
  "typescript": "^5.5.4",
42
- "vite-plugin-dts": "^4.5.4",
43
- "vite-tsconfig-paths": "^4.3.2",
44
32
  "vitest": "^1.6.0"
45
- }
33
+ },
34
+ "main": "./dist/index.js",
35
+ "module": "./dist/index.js",
36
+ "types": "./dist/index.d.ts"
46
37
  }
@@ -0,0 +1,36 @@
1
+ import { readFileSync } from "node:fs";
2
+ import path from "node:path";
3
+
4
+ import { defineConfig, type Plugin } from "tsdown";
5
+
6
+ import { createTsdownConfig } from "../tsdown.config.base.ts";
7
+
8
+ // Plugin to handle CSS ?inline imports from @editframe/elements
9
+ const inlineCssPlugin = (): Plugin => ({
10
+ name: "inline-css",
11
+ resolveId(source, importer) {
12
+ if (source.endsWith(".css?inline") && importer) {
13
+ const resolved = path.resolve(
14
+ path.dirname(importer),
15
+ source.replace("?inline", ""),
16
+ );
17
+ return { id: resolved + "?inline", external: false };
18
+ }
19
+ return null;
20
+ },
21
+ load(id) {
22
+ if (id.endsWith("?inline")) {
23
+ const filePath = id.replace("?inline", "");
24
+ const css = readFileSync(filePath, "utf-8");
25
+ return `export default ${JSON.stringify(css)}`;
26
+ }
27
+ return null;
28
+ },
29
+ });
30
+
31
+ export default defineConfig(
32
+ createTsdownConfig({
33
+ plugins: [inlineCssPlugin()],
34
+ external: [/@editframe\/(elements|assets)/],
35
+ }),
36
+ );