@unseenco/theatre-core 0.4.2 → 0.4.3

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.mjs CHANGED
@@ -239,6 +239,7 @@ var require_propose = __commonJS({
239
239
  // core/src/coreExports.ts
240
240
  var coreExports_exports = {};
241
241
  __export(coreExports_exports, {
242
+ attachGsapSequenceBridge: () => attachGsapSequenceBridge,
242
243
  createRafDriver: () => createRafDriver,
243
244
  getProject: () => getProject,
244
245
  isRemoteEditorWindow: () => isRemoteEditorWindow,
@@ -248,7 +249,7 @@ __export(coreExports_exports, {
248
249
  setCoreRafDriver: () => setCoreRafDriver,
249
250
  setPrivateAPI: () => setPrivateAPI,
250
251
  types: () => propTypes_exports,
251
- val: () => val10
252
+ val: () => val11
252
253
  });
253
254
 
254
255
  // core/src/projects/projectsSingleton.ts
@@ -3222,11 +3223,11 @@ function sanitizeCompoundProps(props) {
3222
3223
  );
3223
3224
  }
3224
3225
  }
3225
- const val11 = props[key];
3226
- if (isLonghandPropType(val11)) {
3227
- sanitizedProps[key] = val11;
3226
+ const val12 = props[key];
3227
+ if (isLonghandPropType(val12)) {
3228
+ sanitizedProps[key] = val12;
3228
3229
  } else {
3229
- sanitizedProps[key] = toLonghandProp(val11);
3230
+ sanitizedProps[key] = toLonghandProp(val12);
3230
3231
  }
3231
3232
  }
3232
3233
  return sanitizedProps;
@@ -3324,15 +3325,15 @@ var file = (defaultValue, opts = {}) => {
3324
3325
  deserializeAndSanitize: _ensureFile
3325
3326
  };
3326
3327
  };
3327
- var _ensureFile = (val11) => {
3328
- if (!val11) return void 0;
3328
+ var _ensureFile = (val12) => {
3329
+ if (!val12) return void 0;
3329
3330
  let valid = true;
3330
- if (typeof val11.id !== "string" && ![null, void 0].includes(val11.id)) {
3331
+ if (typeof val12.id !== "string" && ![null, void 0].includes(val12.id)) {
3331
3332
  valid = false;
3332
3333
  }
3333
- if (val11.type !== "file") valid = false;
3334
+ if (val12.type !== "file") valid = false;
3334
3335
  if (!valid) return void 0;
3335
- return val11;
3336
+ return val12;
3336
3337
  };
3337
3338
  var image = (defaultValue, opts = {}) => {
3338
3339
  if (process.env.NODE_ENV !== "production") {
@@ -3356,15 +3357,15 @@ var image = (defaultValue, opts = {}) => {
3356
3357
  deserializeAndSanitize: _ensureImage
3357
3358
  };
3358
3359
  };
3359
- var _ensureImage = (val11) => {
3360
- if (!val11) return void 0;
3360
+ var _ensureImage = (val12) => {
3361
+ if (!val12) return void 0;
3361
3362
  let valid = true;
3362
- if (typeof val11.id !== "string" && ![null, void 0].includes(val11.id)) {
3363
+ if (typeof val12.id !== "string" && ![null, void 0].includes(val12.id)) {
3363
3364
  valid = false;
3364
3365
  }
3365
- if (val11.type !== "image") valid = false;
3366
+ if (val12.type !== "image") valid = false;
3366
3367
  if (!valid) return void 0;
3367
- return val11;
3368
+ return val12;
3368
3369
  };
3369
3370
  var number = (defaultValue, opts = {}) => {
3370
3371
  if (process.env.NODE_ENV !== "production") {
@@ -3487,11 +3488,11 @@ var rgba = (defaultValue = { r: 0, g: 0, b: 0, a: 1 }, opts = {}) => {
3487
3488
  deserializeAndSanitize: _sanitizeRgba
3488
3489
  };
3489
3490
  };
3490
- var _sanitizeRgba = (val11) => {
3491
- if (!val11) return void 0;
3491
+ var _sanitizeRgba = (val12) => {
3492
+ if (!val12) return void 0;
3492
3493
  let valid = true;
3493
3494
  for (const c2 of ["r", "g", "b", "a"]) {
3494
- if (!Object.prototype.hasOwnProperty.call(val11, c2) || typeof val11[c2] !== "number") {
3495
+ if (!Object.prototype.hasOwnProperty.call(val12, c2) || typeof val12[c2] !== "number") {
3495
3496
  valid = false;
3496
3497
  }
3497
3498
  }
@@ -3500,7 +3501,7 @@ var _sanitizeRgba = (val11) => {
3500
3501
  for (const c2 of ["r", "g", "b", "a"]) {
3501
3502
  ;
3502
3503
  sanitized[c2] = Math.min(
3503
- Math.max(val11[c2], 0),
3504
+ Math.max(val12[c2], 0),
3504
3505
  1
3505
3506
  );
3506
3507
  }
@@ -3539,8 +3540,8 @@ var boolean = (defaultValue, opts = {}) => {
3539
3540
  deserializeAndSanitize: _ensureBoolean
3540
3541
  };
3541
3542
  };
3542
- var _ensureBoolean = (val11) => {
3543
- return typeof val11 === "boolean" ? val11 : void 0;
3543
+ var _ensureBoolean = (val12) => {
3544
+ return typeof val12 === "boolean" ? val12 : void 0;
3544
3545
  };
3545
3546
  function leftInterpolate(left) {
3546
3547
  return left;
@@ -3747,8 +3748,8 @@ var TheatreSheetObject = class {
3747
3748
  }
3748
3749
  return der.getValue();
3749
3750
  }
3750
- set initialValue(val11) {
3751
- privateAPI(this).setInitialValue(val11);
3751
+ set initialValue(val12) {
3752
+ privateAPI(this).setInitialValue(val12);
3752
3753
  }
3753
3754
  showPropsOf(objects) {
3754
3755
  const host = privateAPI(this);
@@ -4516,9 +4517,9 @@ var SheetObject = class {
4516
4517
  }
4517
4518
  validateValue(pointer3, value) {
4518
4519
  }
4519
- setInitialValue(val11) {
4520
- this.validateValue(this.propsP, val11);
4521
- this._initialValue.set(val11);
4520
+ setInitialValue(val12) {
4521
+ this.validateValue(this.propsP, val12);
4522
+ this._initialValue.set(val12);
4522
4523
  }
4523
4524
  setSessionOverride(path, value) {
4524
4525
  const propConfig = getPropConfigByPath(this.template.staticConfig, path);
@@ -4538,8 +4539,8 @@ var SheetObject = class {
4538
4539
  * Internal: called by `RemoteSync` when a value update for this object
4539
4540
  * arrives from a remote editor window. Not exposed on the public API.
4540
4541
  */
4541
- setRemoteOverride(val11) {
4542
- this._remoteOverride.set(val11);
4542
+ setRemoteOverride(val12) {
4543
+ this._remoteOverride.set(val12);
4543
4544
  }
4544
4545
  /**
4545
4546
  * Internal: used by `RemoteSync` to subscribe to this object's fully
@@ -6211,6 +6212,19 @@ function isBasicKeyframedTrack(track) {
6211
6212
  function isGsapClipTrack(track) {
6212
6213
  return track.type === "GsapClipTrack";
6213
6214
  }
6215
+ function gsapClipEndTime(clip) {
6216
+ return clip.start + clip.duration;
6217
+ }
6218
+ function gsapClipSyncProgress(sequencePosition, clip) {
6219
+ if (clip.duration <= 0) return 0;
6220
+ if (sequencePosition < clip.start) return 0;
6221
+ const clipEnd = gsapClipEndTime(clip);
6222
+ if (sequencePosition >= clipEnd - 1e-5) return 1;
6223
+ const raw = (sequencePosition - clip.start) / clip.duration;
6224
+ if (raw <= 0) return 0;
6225
+ if (raw >= 1) return 1;
6226
+ return raw;
6227
+ }
6214
6228
 
6215
6229
  // core/src/sequences/Sequence.ts
6216
6230
  var possibleDirections = [
@@ -8339,13 +8353,13 @@ var Project = class {
8339
8353
  };
8340
8354
 
8341
8355
  // shared/src/utils/sanitizers.ts
8342
- var _validateSym = (val11, thingy, range) => {
8343
- if (typeof val11 !== "string") {
8344
- return "".concat(thingy, " must be a string. ").concat(userReadableTypeOfValue_default(val11), " given.");
8345
- } else if (val11.trim().length !== val11.length) {
8346
- return "".concat(thingy, " must not have leading or trailing spaces. '").concat(val11, "' given.");
8347
- } else if (val11.length < range[0] || val11.length > range[1]) {
8348
- return "".concat(thingy, " must have between ").concat(range[0], " and ").concat(range[1], " characters. '").concat(val11, "' given.");
8356
+ var _validateSym = (val12, thingy, range) => {
8357
+ if (typeof val12 !== "string") {
8358
+ return "".concat(thingy, " must be a string. ").concat(userReadableTypeOfValue_default(val12), " given.");
8359
+ } else if (val12.trim().length !== val12.length) {
8360
+ return "".concat(thingy, " must not have leading or trailing spaces. '").concat(val12, "' given.");
8361
+ } else if (val12.length < range[0] || val12.length > range[1]) {
8362
+ return "".concat(thingy, " must have between ").concat(range[0], " and ").concat(range[1], " characters. '").concat(val12, "' given.");
8349
8363
  }
8350
8364
  };
8351
8365
  var validateName = (name, thingy, shouldThrow = false) => {
@@ -8462,7 +8476,193 @@ var TheatreProject = class {
8462
8476
  // core/src/coreExports.ts
8463
8477
  var import_fast_deep_equal3 = __toESM(require_fast_deep_equal());
8464
8478
  import { isPointer } from "@unseenco/theatre-dataverse";
8465
- import { isPrism, pointerToPrism } from "@unseenco/theatre-dataverse";
8479
+ import { isPrism, pointerToPrism as pointerToPrism2 } from "@unseenco/theatre-dataverse";
8480
+
8481
+ // shared/src/gsap/applyTimelineChildTiming.ts
8482
+ function applyTimelineChildTimingToGsap(rootAnimation, timelineChildren, childById, onRebuild) {
8483
+ if (!timelineChildren.length) return true;
8484
+ let ok = applyTimelineChildTimingToGsapInner(
8485
+ rootAnimation,
8486
+ timelineChildren,
8487
+ childById
8488
+ );
8489
+ if (!ok && onRebuild) {
8490
+ const rebuilt = onRebuild();
8491
+ if (rebuilt) {
8492
+ ok = applyTimelineChildTimingToGsapInner(
8493
+ rebuilt,
8494
+ timelineChildren,
8495
+ childById
8496
+ );
8497
+ }
8498
+ }
8499
+ return ok;
8500
+ }
8501
+ function applyTimelineChildTimingToGsapInner(rootAnimation, timelineChildren, childById) {
8502
+ if (!childById || timelineChildren.length === 0) return true;
8503
+ let ok = true;
8504
+ for (const childState of timelineChildren) {
8505
+ const tween = childById.get(childState.childId);
8506
+ if (!tween) continue;
8507
+ try {
8508
+ const t2 = tween;
8509
+ if (typeof t2.startTime === "function") {
8510
+ t2.startTime(childState.localStart);
8511
+ }
8512
+ if (typeof t2.duration === "function") {
8513
+ t2.duration(childState.localDuration);
8514
+ }
8515
+ } catch {
8516
+ ok = false;
8517
+ }
8518
+ }
8519
+ return ok;
8520
+ }
8521
+
8522
+ // shared/src/gsap/syncGsapClipProgress.ts
8523
+ function getGsapAnimationTargetKey(animation, fallbackAnimationId) {
8524
+ const tween = animation;
8525
+ const targets = tween.targets?.();
8526
+ if (targets && targets.length > 0) {
8527
+ return targets[0];
8528
+ }
8529
+ return fallbackAnimationId;
8530
+ }
8531
+ function syncRegisteredGsapAnimationsForClips(sequencePosition, clips) {
8532
+ const enriched = [];
8533
+ for (const clip of clips) {
8534
+ const entry = getAnimationEntryBySheetAddressKey(
8535
+ clip.sheetObjectAddressKey,
8536
+ clip.gsapAnimationId
8537
+ );
8538
+ if (!entry?.animation) continue;
8539
+ enriched.push({
8540
+ ...clip,
8541
+ entry,
8542
+ targetKey: getGsapAnimationTargetKey(
8543
+ entry.animation,
8544
+ clip.gsapAnimationId
8545
+ )
8546
+ });
8547
+ }
8548
+ const byTarget = /* @__PURE__ */ new Map();
8549
+ for (const item of enriched) {
8550
+ const list = byTarget.get(item.targetKey) ?? [];
8551
+ list.push(item);
8552
+ byTarget.set(item.targetKey, list);
8553
+ }
8554
+ for (const group of byTarget.values()) {
8555
+ const sorted = [...group].sort((a2, b2) => a2.start - b2.start);
8556
+ for (const clip of sorted) {
8557
+ const progress = gsapClipSyncProgress(sequencePosition, clip);
8558
+ const entry = clip.entry;
8559
+ const animation = entry.animation;
8560
+ if (entry.kind === "timeline" && clip.timelineChildren && clip.timelineChildren.length > 0) {
8561
+ applyTimelineChildTimingToGsap(
8562
+ entry.animation,
8563
+ clip.timelineChildren,
8564
+ entry.timelineChildById,
8565
+ entry.onRebuildTimeline
8566
+ );
8567
+ const span = clip.timelineSpan ?? readGsapTweenTimelineDuration(entry.animation);
8568
+ const t2 = progress * Math.max(span, 0.01);
8569
+ if (typeof animation.time === "function") {
8570
+ animation.time(t2, true);
8571
+ } else {
8572
+ animation.progress?.(progress, true);
8573
+ }
8574
+ } else {
8575
+ animation.progress?.(progress, true);
8576
+ }
8577
+ }
8578
+ }
8579
+ }
8580
+ function readGsapTweenTimelineDuration(animation) {
8581
+ const tween = animation;
8582
+ const total = tween.totalDuration?.();
8583
+ if (typeof total === "number" && total > 0) return total;
8584
+ const d2 = tween.duration();
8585
+ return d2 > 0 ? d2 : 1;
8586
+ }
8587
+
8588
+ // shared/src/gsap/gsapStudioRegistryRevision.ts
8589
+ import { Atom as Atom11 } from "@unseenco/theatre-dataverse";
8590
+ var revisionAtom = new Atom11(0);
8591
+ var gsapStudioRegistryRevisionPointer = revisionAtom.pointer;
8592
+
8593
+ // shared/src/gsap/gsapAnimationRegistry.ts
8594
+ var DEFAULT_SHEET_INSTANCE_ID = "default";
8595
+ var REGISTRY_KEY = "__unseenco_theatre_gsap_animationRegistry__";
8596
+ function sheetObjectAddressKeyFromParts(address) {
8597
+ const sheetInstanceId = address.sheetInstanceId ?? DEFAULT_SHEET_INSTANCE_ID;
8598
+ return "".concat(address.projectId, "|").concat(address.sheetId, "|").concat(sheetInstanceId, "|").concat(address.objectKey);
8599
+ }
8600
+ function getStore() {
8601
+ const g2 = globalThis;
8602
+ if (!g2[REGISTRY_KEY]) {
8603
+ g2[REGISTRY_KEY] = {
8604
+ bySheetAddress: /* @__PURE__ */ new Map()
8605
+ };
8606
+ }
8607
+ return g2[REGISTRY_KEY];
8608
+ }
8609
+ function getAnimationEntryBySheetAddressKey(sheetObjectAddressKey, animationId) {
8610
+ return getStore().bySheetAddress.get(sheetObjectAddressKey)?.get(animationId);
8611
+ }
8612
+
8613
+ // shared/src/gsap/subscribeGsapClipSyncAtPlayhead.ts
8614
+ import { pointerToPrism, prism as prism8, val as val10 } from "@unseenco/theatre-dataverse";
8615
+
8616
+ // shared/src/gsap/syncGsapClipsAtSequencePosition.ts
8617
+ function syncGsapClipsAtSequencePosition(position, clips) {
8618
+ syncRegisteredGsapAnimationsForClips(
8619
+ position,
8620
+ clips
8621
+ );
8622
+ }
8623
+
8624
+ // shared/src/gsap/subscribeGsapClipSyncAtPlayhead.ts
8625
+ function subscribeGsapClipSyncAtPlayhead(source) {
8626
+ const positionPointer = source.pointer.position;
8627
+ const positionPrism = pointerToPrism(positionPointer);
8628
+ const clipsPrism = prism8(() => source.getGsapClipTimings());
8629
+ const syncNow = () => {
8630
+ const clips = clipsPrism.getValue();
8631
+ if (clips.length === 0) return;
8632
+ syncGsapClipsAtSequencePosition(val10(positionPointer), clips);
8633
+ };
8634
+ const untapPosition = positionPrism.onStale(syncNow);
8635
+ const untapClips = clipsPrism.onStale(syncNow);
8636
+ syncNow();
8637
+ return () => {
8638
+ untapPosition();
8639
+ untapClips();
8640
+ };
8641
+ }
8642
+
8643
+ // core/src/gsap/attachGsapSequenceBridge.ts
8644
+ function attachGsapSequenceBridge(sheet) {
8645
+ const sequence = sheet.sequence;
8646
+ const sheetAddress = privateAPI(sheet).address;
8647
+ return subscribeGsapClipSyncAtPlayhead({
8648
+ pointer: sequence.pointer,
8649
+ getGsapClipTimings: () => sequence.__experimental_getGsapClips().map(({ objectKey, clip }) => ({
8650
+ sheetObjectAddressKey: sheetObjectAddressKeyFromParts({
8651
+ projectId: sheetAddress.projectId,
8652
+ sheetId: sheetAddress.sheetId,
8653
+ sheetInstanceId: sheetAddress.sheetInstanceId,
8654
+ objectKey
8655
+ }),
8656
+ gsapAnimationId: clip.gsapAnimationId,
8657
+ start: clip.start,
8658
+ duration: clip.duration,
8659
+ timelineChildren: clip.timelineChildren,
8660
+ timelineSpan: clip.timelineSpan
8661
+ }))
8662
+ });
8663
+ }
8664
+
8665
+ // core/src/coreExports.ts
8466
8666
  function getProject(id, config = {}) {
8467
8667
  const existingProject = projectsSingleton_default.get(id);
8468
8668
  if (existingProject) {
@@ -8543,7 +8743,7 @@ var validateProjectIdOrThrow = (value) => {
8543
8743
  function onChange(pointer3, callback, rafDriver) {
8544
8744
  const ticker = rafDriver ? privateAPI(rafDriver).ticker : getCoreTicker();
8545
8745
  if (isPointer(pointer3)) {
8546
- const pr = pointerToPrism(pointer3);
8746
+ const pr = pointerToPrism2(pointer3);
8547
8747
  return pr.onChange(ticker, callback, true);
8548
8748
  } else if (isPrism(pointer3)) {
8549
8749
  return pointer3.onChange(ticker, callback, true);
@@ -8553,9 +8753,9 @@ function onChange(pointer3, callback, rafDriver) {
8553
8753
  );
8554
8754
  }
8555
8755
  }
8556
- function val10(pointer3) {
8756
+ function val11(pointer3) {
8557
8757
  if (isPointer(pointer3)) {
8558
- return pointerToPrism(pointer3).getValue();
8758
+ return pointerToPrism2(pointer3).getValue();
8559
8759
  } else {
8560
8760
  throw new Error("Called val(p) where p is not a pointer.");
8561
8761
  }
@@ -8570,7 +8770,7 @@ var CoreBundle = class {
8570
8770
  return "Theatre_CoreBundle";
8571
8771
  }
8572
8772
  get version() {
8573
- return "0.4.2";
8773
+ return "0.4.3";
8574
8774
  }
8575
8775
  getBitsForStudio(studio, callback) {
8576
8776
  if (this._studio) {
@@ -8619,6 +8819,7 @@ function registerCoreBundle() {
8619
8819
  }
8620
8820
  }
8621
8821
  export {
8822
+ attachGsapSequenceBridge,
8622
8823
  createRafDriver,
8623
8824
  getProject,
8624
8825
  isRemoteEditorWindow,
@@ -8628,7 +8829,7 @@ export {
8628
8829
  setCoreRafDriver,
8629
8830
  setPrivateAPI,
8630
8831
  propTypes_exports as types,
8631
- val10 as val
8832
+ val11 as val
8632
8833
  };
8633
8834
  /*! Bundled license information:
8634
8835