hyperframes 0.8.46 → 0.8.48

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.
@@ -1 +1 @@
1
- import{g as P}from"./index-DCblmTX3.js";function j(c,d){for(var s=0;s<d.length;s++){const a=d[s];if(typeof a!="string"&&!Array.isArray(a)){for(const i in a)if(i!=="default"&&!(i in c)){const l=Object.getOwnPropertyDescriptor(a,i);l&&Object.defineProperty(c,i,l.get?l:{enumerable:!0,get:()=>a[i]})}}}return Object.freeze(Object.defineProperty(c,Symbol.toStringTag,{value:"Module"}))}var v={},w;function k(){if(w)return v;w=1,Object.defineProperty(v,"__esModule",{value:!0}),v.default=d;var c=window.OfflineAudioContext||window.webkitOfflineAudioContext;function d(e){var r=a(e);return r.start(0),[i,y,O(e.sampleRate),s].reduce(function(t,o){return o(t)},r.buffer.getChannelData(0))}function s(e){return e.sort(function(r,t){return t.count-r.count}).splice(0,5)[0].tempo}function a(e){var r=e.length,t=e.numberOfChannels,o=e.sampleRate,n=new c(t,r,o),u=n.createBufferSource();u.buffer=e;var f=n.createBiquadFilter();return f.type="lowpass",u.connect(f),f.connect(n.destination),u}function i(e){for(var r=[],t=.9,o=.3,n=15;r.length<n&&t>=o;)r=l(e,t),t-=.05;if(r.length<n)throw new Error("Could not find enough samples for a reliable detection.");return r}function l(e,r){for(var t=[],o=0,n=e.length;o<n;o+=1)e[o]>r&&(t.push(o),o+=1e4);return t}function y(e){var r=[];return e.forEach(function(t,o){for(var n=function(x){var g=e[o+x]-t,_=r.some(function(h){if(h.interval===g)return h.count+=1});_||r.push({interval:g,count:1})},u=0;u<10;u+=1)n(u)}),r}function O(e){return function(r){var t=[];return r.forEach(function(o){if(o.interval!==0){for(var n=60/(o.interval/e);n<90;)n*=2;for(;n>180;)n/=2;n=Math.round(n);var u=t.some(function(f){if(f.tempo===n)return f.count+=o.count});u||t.push({tempo:n,count:o.count})}}),t}}return v}var p,b;function q(){return b||(b=1,p=k().default),p}var m=q();const A=P(m),D=j({__proto__:null,default:A},[m]);export{D as i};
1
+ import{g as P}from"./index-C9gJKpqQ.js";function j(c,d){for(var s=0;s<d.length;s++){const a=d[s];if(typeof a!="string"&&!Array.isArray(a)){for(const i in a)if(i!=="default"&&!(i in c)){const l=Object.getOwnPropertyDescriptor(a,i);l&&Object.defineProperty(c,i,l.get?l:{enumerable:!0,get:()=>a[i]})}}}return Object.freeze(Object.defineProperty(c,Symbol.toStringTag,{value:"Module"}))}var v={},w;function k(){if(w)return v;w=1,Object.defineProperty(v,"__esModule",{value:!0}),v.default=d;var c=window.OfflineAudioContext||window.webkitOfflineAudioContext;function d(e){var r=a(e);return r.start(0),[i,y,O(e.sampleRate),s].reduce(function(t,o){return o(t)},r.buffer.getChannelData(0))}function s(e){return e.sort(function(r,t){return t.count-r.count}).splice(0,5)[0].tempo}function a(e){var r=e.length,t=e.numberOfChannels,o=e.sampleRate,n=new c(t,r,o),u=n.createBufferSource();u.buffer=e;var f=n.createBiquadFilter();return f.type="lowpass",u.connect(f),f.connect(n.destination),u}function i(e){for(var r=[],t=.9,o=.3,n=15;r.length<n&&t>=o;)r=l(e,t),t-=.05;if(r.length<n)throw new Error("Could not find enough samples for a reliable detection.");return r}function l(e,r){for(var t=[],o=0,n=e.length;o<n;o+=1)e[o]>r&&(t.push(o),o+=1e4);return t}function y(e){var r=[];return e.forEach(function(t,o){for(var n=function(x){var g=e[o+x]-t,_=r.some(function(h){if(h.interval===g)return h.count+=1});_||r.push({interval:g,count:1})},u=0;u<10;u+=1)n(u)}),r}function O(e){return function(r){var t=[];return r.forEach(function(o){if(o.interval!==0){for(var n=60/(o.interval/e);n<90;)n*=2;for(;n>180;)n/=2;n=Math.round(n);var u=t.some(function(f){if(f.tempo===n)return f.count+=o.count});u||t.push({tempo:n,count:o.count})}}),t}}return v}var p,b;function q(){return b||(b=1,p=k().default),p}var m=q();const A=P(m),D=j({__proto__:null,default:A},[m]);export{D as i};
@@ -1,9 +1,10 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
3
  import { ReactNode, RefObject } from 'react';
4
- import { RuntimeTimelineClipIdentity } from '@hyperframes/core';
4
+ import { RuntimeTimelineClipIdentity, HyperframePickerElementInfo } from '@hyperframes/core';
5
5
  import { GsapAnimation, PropertyGroupName } from '@hyperframes/core/gsap-parser';
6
6
  import * as zustand from 'zustand';
7
+ import { StoreApi } from 'zustand';
7
8
  import { MusicBeatAnalysis } from '@hyperframes/core/beats';
8
9
  import { GsapAnimation as GsapAnimation$1, ArcPathSegment } from '@hyperframes/parsers/gsap-parser';
9
10
 
@@ -250,6 +251,20 @@ interface ThumbnailSlice {
250
251
  bumpThumbnailContentRevision: () => void;
251
252
  }
252
253
 
254
+ /** Gates `timelineReady` on the composition's declared readiness inputs
255
+ * (media, for now) instead of just a known duration. The generation counter
256
+ * is module-scope, not store state: it guards an in-flight settlement, not
257
+ * something a component reads, so bumping it shouldn't trigger a render. */
258
+
259
+ interface PlaybackReadinessSlice {
260
+ timelineReady: boolean;
261
+ setTimelineReady: (ready: boolean) => void;
262
+ /** Sets timelineReady once doc's readiness inputs settle, or immediately
263
+ * if doc is null. A wait a later call supersedes never wins the race. */
264
+ requestTimelineReady: (doc: Document | null) => void;
265
+ }
266
+ declare function createPlaybackReadinessSlice(set: StoreApi<PlaybackReadinessSlice>["setState"]): PlaybackReadinessSlice;
267
+
253
268
  type TimeListener = (time: number) => void;
254
269
  declare const liveTime: {
255
270
  notify: (time: number) => void;
@@ -382,11 +397,11 @@ type TimelineTool = "select" | "razor";
382
397
  interface SelectElementOptions {
383
398
  preserveSet?: boolean;
384
399
  }
385
- interface PlayerState extends KeyframeSlice, AutomationSelectionSlice, ThumbnailSlice, EditingModeSlice {
400
+ type PlayerStoreSlices = KeyframeSlice & AutomationSelectionSlice & ThumbnailSlice & EditingModeSlice & ReturnType<typeof createPlaybackReadinessSlice>;
401
+ interface PlayerState extends PlayerStoreSlices {
386
402
  isPlaying: boolean;
387
403
  currentTime: number;
388
404
  duration: number;
389
- timelineReady: boolean;
390
405
  /** Increments exactly once when the Studio switches to a different project. */
391
406
  timelineSessionEpoch: number;
392
407
  /** Project owning the current timeline session; null outside a project-scoped reset. */
@@ -428,14 +443,14 @@ interface PlayerState extends KeyframeSlice, AutomationSelectionSlice, Thumbnail
428
443
  /** Timeline magnet toggle — when false, clip drags/trims/drops never snap. */
429
444
  timelineSnapEnabled: boolean;
430
445
  setTimelineSnapEnabled: (enabled: boolean) => void;
446
+ /** Keeps the main track gapless on delete; distinct from the magnet above. */
447
+ rippleEditEnabled: boolean;
448
+ setRippleEditEnabled: (enabled: boolean) => void;
431
449
  /** Transport + ruler readout: timecode ("time") or frame number ("frame"). */
432
450
  timeDisplayMode: TimelineTimeDisplayMode;
433
451
  setTimeDisplayMode: (mode: TimelineTimeDisplayMode) => void;
434
- /**
435
- * Pin the timeline zoom to its current visual scale before a duration-changing
436
- * edit, so a subsequent duration change (which recomputes fit-pps) stops
437
- * rescaling every clip. No-op once already pinned (mode is "manual").
438
- */
452
+ /** Pin the timeline zoom to its current scale before a duration change, so
453
+ * it stops rescaling every clip. No-op once already pinned. */
439
454
  pinTimelineZoom: (currentPixelsPerSecond: number, fitPixelsPerSecond: number) => void;
440
455
  /** The timeline's live pixels-per-second + fit basis, published by <Timeline>. */
441
456
  timelinePps: number;
@@ -452,7 +467,6 @@ interface PlayerState extends KeyframeSlice, AutomationSelectionSlice, Thumbnail
452
467
  setAudioMuted: (muted: boolean) => void;
453
468
  setAudioVolume: (volume: number) => void;
454
469
  setLoopEnabled: (enabled: boolean) => void;
455
- setTimelineReady: (ready: boolean) => void;
456
470
  setBeatDragging: (dragging: boolean) => void;
457
471
  setElements: (elements: TimelineElement[]) => void;
458
472
  setSelectedElementId: (id: string | null, options?: SelectElementOptions) => void;
@@ -468,25 +482,15 @@ interface PlayerState extends KeyframeSlice, AutomationSelectionSlice, Thumbnail
468
482
  beginTimelineSession: (projectId: string) => void;
469
483
  /** Clears project data without creating a new hard-project session. */
470
484
  reset: () => void;
471
- /**
472
- * Request a seek from outside the player loop (e.g. Layers panel).
473
- * useTimelinePlayer subscribes and calls adapter.seek() + liveTime.notify().
474
- */
485
+ /** Request a seek from outside the player loop (e.g. Layers panel);
486
+ * useTimelinePlayer subscribes and calls adapter.seek() + liveTime.notify(). */
475
487
  requestedSeekTime: number | null;
476
488
  requestSeek: (time: number) => void;
477
489
  clearSeekRequest: () => void;
478
- /**
479
- * Request the transport start or stop from outside the player loop.
480
- *
481
- * The FX rack auditions a preset by writing it to the running graph, which is
482
- * silent while the transport is paused — so hovering one has to start
483
- * playback, and leaving has to put the playhead back where it was. Hovering is
484
- * not an edit and must not cost the author their place.
485
- *
486
- * A nonce rather than a bare boolean: two hovers in a row both want play, and
487
- * without it the second request is indistinguishable from the first having
488
- * already been served.
489
- */
490
+ /** Request the transport start or stop from outside the player loop: the FX
491
+ * rack starts playback to audition a preset (silent while paused) and
492
+ * restores the playhead on leave, without costing the author their place.
493
+ * A nonce, not a bare boolean, so two hovers in a row both register. */
490
494
  playbackRequest: {
491
495
  playing: boolean;
492
496
  returnTo: number | null;
@@ -661,6 +665,45 @@ interface DomEditSelection extends PatchTarget {
661
665
  gsapAnimations?: GsapAnimation$1[];
662
666
  }
663
667
 
668
+ /**
669
+ * Agent prompt builder for HyperFrames element edit requests.
670
+ */
671
+
672
+ /**
673
+ * The subset of an element selection shared by the Studio DOM editor (`DomEditSelection`) and the
674
+ * runtime picker (`HyperframePickerElementInfo`); a field absent from a caller's type is simply omitted.
675
+ */
676
+ interface AgentPromptElementInfo {
677
+ id: string | null;
678
+ selector?: string | null;
679
+ /** Disambiguates duplicate selectors in `DomEditSelection`. The picker
680
+ * payload has no such concept (one picked node, not a candidate list), so
681
+ * a picker-built prompt always prints index 0 — expected, not a gap. */
682
+ selectorIndex?: number;
683
+ tagName: string;
684
+ label?: string;
685
+ boundingBox: {
686
+ x: number;
687
+ y: number;
688
+ width: number;
689
+ height: number;
690
+ };
691
+ textContent: string | null;
692
+ src?: string | null;
693
+ textFields?: DomEditTextField[];
694
+ inlineStyles?: Record<string, string>;
695
+ computedStyles?: Record<string, string>;
696
+ }
697
+ /**
698
+ * Same convention as `buildElementAgentPrompt`, for a host app embedding only the player: built from
699
+ * the runtime picker's own payload, not `DomEditSelection`. Null selection yields a bare prompt, no guardrails.
700
+ */
701
+ declare function buildPickerAgentPrompt({ selection, userInstruction, }: {
702
+ selection: HyperframePickerElementInfo | null;
703
+ userInstruction?: string;
704
+ }): string;
705
+ declare function buildPickerAgentContextPreview(selection: HyperframePickerElementInfo | null): string;
706
+
664
707
  type BlockedTimelineEditIntent = "move" | "resize-start" | "resize-end";
665
708
 
666
709
  type TimelineMoveOperation = "timing" | "lane-reorder" | "track-insert";
@@ -1202,6 +1245,20 @@ declare const FileTree: react.NamedExoticComponent<FileTreeProps>;
1202
1245
 
1203
1246
  declare function StudioApp(): react_jsx_runtime.JSX.Element;
1204
1247
 
1248
+ interface AgentModalAnchorPoint {
1249
+ x: number;
1250
+ y: number;
1251
+ }
1252
+
1253
+ interface AskAgentModalProps {
1254
+ selectionLabel: string;
1255
+ contextPreview?: string;
1256
+ anchorPoint?: AgentModalAnchorPoint | null;
1257
+ onSubmit: (instruction: string) => void;
1258
+ onClose: () => void;
1259
+ }
1260
+ declare function AskAgentModal({ selectionLabel, contextPreview, anchorPoint, onSubmit, onClose, }: AskAgentModalProps): react_jsx_runtime.JSX.Element;
1261
+
1205
1262
  interface PickedElement {
1206
1263
  id: string | null;
1207
1264
  tagName: string;
@@ -1277,4 +1334,4 @@ declare function findElementBlock(html: string, elementId: string): {
1277
1334
  isSelfClosing: boolean;
1278
1335
  } | null;
1279
1336
 
1280
- export { CompositionBreadcrumb, type CompositionLevel, CompositionThumbnail, EditorShell, FileTree, NLEPreview, type PatchOperation, type PickedElement, Player, PlayerControls, PropertyPanel, SourceEditor, StudioApp, Timeline, type TimelineElement, VideoThumbnail, applyPatch, findElementBlock, formatTime, liveTime, mergeStyleIntoTag, parseStyleString, resolveIframe, resolveSourceFile, useElementPicker, usePlayerStore, useTimelinePlayer };
1337
+ export { type AgentModalAnchorPoint, type AgentPromptElementInfo, AskAgentModal, type AskAgentModalProps, CompositionBreadcrumb, type CompositionLevel, CompositionThumbnail, EditorShell, FileTree, NLEPreview, type PatchOperation, type PickedElement, Player, PlayerControls, PropertyPanel, SourceEditor, StudioApp, Timeline, type TimelineElement, VideoThumbnail, applyPatch, buildPickerAgentContextPreview, buildPickerAgentPrompt, findElementBlock, formatTime, liveTime, mergeStyleIntoTag, parseStyleString, resolveIframe, resolveSourceFile, useElementPicker, usePlayerStore, useTimelinePlayer };
@@ -5,8 +5,8 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
6
6
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
7
7
  <title>HyperFrames Studio</title>
8
- <script type="module" crossorigin src="/assets/index-DCblmTX3.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-DnRfAiK2.css">
8
+ <script type="module" crossorigin src="/assets/index-C9gJKpqQ.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-B9LfWNyM.css">
10
10
  </head>
11
11
  <body>
12
12
  <div data-hf-id="hf-aph5" id="root"></div>