@unseenco/theatre-core 0.4.1 → 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,14 +239,17 @@ 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,
245
246
  notify: () => notify,
246
247
  onChange: () => onChange,
248
+ privateAPI: () => privateAPI,
247
249
  setCoreRafDriver: () => setCoreRafDriver,
250
+ setPrivateAPI: () => setPrivateAPI,
248
251
  types: () => propTypes_exports,
249
- val: () => val10
252
+ val: () => val11
250
253
  });
251
254
 
252
255
  // core/src/projects/projectsSingleton.ts
@@ -3220,11 +3223,11 @@ function sanitizeCompoundProps(props) {
3220
3223
  );
3221
3224
  }
3222
3225
  }
3223
- const val11 = props[key];
3224
- if (isLonghandPropType(val11)) {
3225
- sanitizedProps[key] = val11;
3226
+ const val12 = props[key];
3227
+ if (isLonghandPropType(val12)) {
3228
+ sanitizedProps[key] = val12;
3226
3229
  } else {
3227
- sanitizedProps[key] = toLonghandProp(val11);
3230
+ sanitizedProps[key] = toLonghandProp(val12);
3228
3231
  }
3229
3232
  }
3230
3233
  return sanitizedProps;
@@ -3322,15 +3325,15 @@ var file = (defaultValue, opts = {}) => {
3322
3325
  deserializeAndSanitize: _ensureFile
3323
3326
  };
3324
3327
  };
3325
- var _ensureFile = (val11) => {
3326
- if (!val11) return void 0;
3328
+ var _ensureFile = (val12) => {
3329
+ if (!val12) return void 0;
3327
3330
  let valid = true;
3328
- if (typeof val11.id !== "string" && ![null, void 0].includes(val11.id)) {
3331
+ if (typeof val12.id !== "string" && ![null, void 0].includes(val12.id)) {
3329
3332
  valid = false;
3330
3333
  }
3331
- if (val11.type !== "file") valid = false;
3334
+ if (val12.type !== "file") valid = false;
3332
3335
  if (!valid) return void 0;
3333
- return val11;
3336
+ return val12;
3334
3337
  };
3335
3338
  var image = (defaultValue, opts = {}) => {
3336
3339
  if (process.env.NODE_ENV !== "production") {
@@ -3354,15 +3357,15 @@ var image = (defaultValue, opts = {}) => {
3354
3357
  deserializeAndSanitize: _ensureImage
3355
3358
  };
3356
3359
  };
3357
- var _ensureImage = (val11) => {
3358
- if (!val11) return void 0;
3360
+ var _ensureImage = (val12) => {
3361
+ if (!val12) return void 0;
3359
3362
  let valid = true;
3360
- if (typeof val11.id !== "string" && ![null, void 0].includes(val11.id)) {
3363
+ if (typeof val12.id !== "string" && ![null, void 0].includes(val12.id)) {
3361
3364
  valid = false;
3362
3365
  }
3363
- if (val11.type !== "image") valid = false;
3366
+ if (val12.type !== "image") valid = false;
3364
3367
  if (!valid) return void 0;
3365
- return val11;
3368
+ return val12;
3366
3369
  };
3367
3370
  var number = (defaultValue, opts = {}) => {
3368
3371
  if (process.env.NODE_ENV !== "production") {
@@ -3485,11 +3488,11 @@ var rgba = (defaultValue = { r: 0, g: 0, b: 0, a: 1 }, opts = {}) => {
3485
3488
  deserializeAndSanitize: _sanitizeRgba
3486
3489
  };
3487
3490
  };
3488
- var _sanitizeRgba = (val11) => {
3489
- if (!val11) return void 0;
3491
+ var _sanitizeRgba = (val12) => {
3492
+ if (!val12) return void 0;
3490
3493
  let valid = true;
3491
3494
  for (const c2 of ["r", "g", "b", "a"]) {
3492
- if (!Object.prototype.hasOwnProperty.call(val11, c2) || typeof val11[c2] !== "number") {
3495
+ if (!Object.prototype.hasOwnProperty.call(val12, c2) || typeof val12[c2] !== "number") {
3493
3496
  valid = false;
3494
3497
  }
3495
3498
  }
@@ -3498,7 +3501,7 @@ var _sanitizeRgba = (val11) => {
3498
3501
  for (const c2 of ["r", "g", "b", "a"]) {
3499
3502
  ;
3500
3503
  sanitized[c2] = Math.min(
3501
- Math.max(val11[c2], 0),
3504
+ Math.max(val12[c2], 0),
3502
3505
  1
3503
3506
  );
3504
3507
  }
@@ -3537,8 +3540,8 @@ var boolean = (defaultValue, opts = {}) => {
3537
3540
  deserializeAndSanitize: _ensureBoolean
3538
3541
  };
3539
3542
  };
3540
- var _ensureBoolean = (val11) => {
3541
- return typeof val11 === "boolean" ? val11 : void 0;
3543
+ var _ensureBoolean = (val12) => {
3544
+ return typeof val12 === "boolean" ? val12 : void 0;
3542
3545
  };
3543
3546
  function leftInterpolate(left) {
3544
3547
  return left;
@@ -3745,8 +3748,8 @@ var TheatreSheetObject = class {
3745
3748
  }
3746
3749
  return der.getValue();
3747
3750
  }
3748
- set initialValue(val11) {
3749
- privateAPI(this).setInitialValue(val11);
3751
+ set initialValue(val12) {
3752
+ privateAPI(this).setInitialValue(val12);
3750
3753
  }
3751
3754
  showPropsOf(objects) {
3752
3755
  const host = privateAPI(this);
@@ -4514,9 +4517,9 @@ var SheetObject = class {
4514
4517
  }
4515
4518
  validateValue(pointer3, value) {
4516
4519
  }
4517
- setInitialValue(val11) {
4518
- this.validateValue(this.propsP, val11);
4519
- this._initialValue.set(val11);
4520
+ setInitialValue(val12) {
4521
+ this.validateValue(this.propsP, val12);
4522
+ this._initialValue.set(val12);
4520
4523
  }
4521
4524
  setSessionOverride(path, value) {
4522
4525
  const propConfig = getPropConfigByPath(this.template.staticConfig, path);
@@ -4536,8 +4539,8 @@ var SheetObject = class {
4536
4539
  * Internal: called by `RemoteSync` when a value update for this object
4537
4540
  * arrives from a remote editor window. Not exposed on the public API.
4538
4541
  */
4539
- setRemoteOverride(val11) {
4540
- this._remoteOverride.set(val11);
4542
+ setRemoteOverride(val12) {
4543
+ this._remoteOverride.set(val12);
4541
4544
  }
4542
4545
  /**
4543
4546
  * Internal: used by `RemoteSync` to subscribe to this object's fully
@@ -6209,6 +6212,19 @@ function isBasicKeyframedTrack(track) {
6209
6212
  function isGsapClipTrack(track) {
6210
6213
  return track.type === "GsapClipTrack";
6211
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
+ }
6212
6228
 
6213
6229
  // core/src/sequences/Sequence.ts
6214
6230
  var possibleDirections = [
@@ -8337,13 +8353,13 @@ var Project = class {
8337
8353
  };
8338
8354
 
8339
8355
  // shared/src/utils/sanitizers.ts
8340
- var _validateSym = (val11, thingy, range) => {
8341
- if (typeof val11 !== "string") {
8342
- return "".concat(thingy, " must be a string. ").concat(userReadableTypeOfValue_default(val11), " given.");
8343
- } else if (val11.trim().length !== val11.length) {
8344
- return "".concat(thingy, " must not have leading or trailing spaces. '").concat(val11, "' given.");
8345
- } else if (val11.length < range[0] || val11.length > range[1]) {
8346
- 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.");
8347
8363
  }
8348
8364
  };
8349
8365
  var validateName = (name, thingy, shouldThrow = false) => {
@@ -8460,7 +8476,193 @@ var TheatreProject = class {
8460
8476
  // core/src/coreExports.ts
8461
8477
  var import_fast_deep_equal3 = __toESM(require_fast_deep_equal());
8462
8478
  import { isPointer } from "@unseenco/theatre-dataverse";
8463
- 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
8464
8666
  function getProject(id, config = {}) {
8465
8667
  const existingProject = projectsSingleton_default.get(id);
8466
8668
  if (existingProject) {
@@ -8541,7 +8743,7 @@ var validateProjectIdOrThrow = (value) => {
8541
8743
  function onChange(pointer3, callback, rafDriver) {
8542
8744
  const ticker = rafDriver ? privateAPI(rafDriver).ticker : getCoreTicker();
8543
8745
  if (isPointer(pointer3)) {
8544
- const pr = pointerToPrism(pointer3);
8746
+ const pr = pointerToPrism2(pointer3);
8545
8747
  return pr.onChange(ticker, callback, true);
8546
8748
  } else if (isPrism(pointer3)) {
8547
8749
  return pointer3.onChange(ticker, callback, true);
@@ -8551,9 +8753,9 @@ function onChange(pointer3, callback, rafDriver) {
8551
8753
  );
8552
8754
  }
8553
8755
  }
8554
- function val10(pointer3) {
8756
+ function val11(pointer3) {
8555
8757
  if (isPointer(pointer3)) {
8556
- return pointerToPrism(pointer3).getValue();
8758
+ return pointerToPrism2(pointer3).getValue();
8557
8759
  } else {
8558
8760
  throw new Error("Called val(p) where p is not a pointer.");
8559
8761
  }
@@ -8568,7 +8770,7 @@ var CoreBundle = class {
8568
8770
  return "Theatre_CoreBundle";
8569
8771
  }
8570
8772
  get version() {
8571
- return "0.4.1";
8773
+ return "0.4.3";
8572
8774
  }
8573
8775
  getBitsForStudio(studio, callback) {
8574
8776
  if (this._studio) {
@@ -8617,14 +8819,17 @@ function registerCoreBundle() {
8617
8819
  }
8618
8820
  }
8619
8821
  export {
8822
+ attachGsapSequenceBridge,
8620
8823
  createRafDriver,
8621
8824
  getProject,
8622
8825
  isRemoteEditorWindow,
8623
8826
  notify,
8624
8827
  onChange,
8828
+ privateAPI,
8625
8829
  setCoreRafDriver,
8830
+ setPrivateAPI,
8626
8831
  propTypes_exports as types,
8627
- val10 as val
8832
+ val11 as val
8628
8833
  };
8629
8834
  /*! Bundled license information:
8630
8835