@unseenco/theatre-core 0.1.15 → 0.1.17

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.d.ts CHANGED
@@ -1,10 +1,1638 @@
1
- export * from './coreExports';
2
- export { IProject, IProjectConfig, ISheetOptions } from './projects/TheatreProject';
3
- export { ISequence } from './sequences/TheatreSequence';
4
- export { ISheetObject } from './sheetObjects/TheatreSheetObject';
5
- export { ISheet, ISheetObjectOptions } from './sheets/TheatreSheet';
6
- export { UnknownShorthandCompoundProps } from './propTypes/index';
7
- import { OnDiskState } from './projects/store/storeTypes';
1
+ import { Pointer, PointerType, Prism } from '@unseenco/theatre-dataverse';
2
+
3
+ /**
4
+ * Using a symbol, we can sort of add unique properties to arbitrary other types.
5
+ * So, we use this to our advantage to add a "marker" of information to strings using
6
+ * the {@link Nominal} type.
7
+ *
8
+ * Can be used with keys in pointers.
9
+ * This identifier shows in the expanded {@link Nominal} as `string & {[nominal]:"SequenceTrackId"}`,
10
+ * So, we're opting to keeping the identifier short.
11
+ */
12
+ declare const nominal: unique symbol;
13
+ /**
14
+ * This creates an "opaque"/"nominal" type.
15
+ *
16
+ * Our primary use case is to be able to use with keys in pointers.
17
+ *
18
+ * Numbers cannot be added together if they are "nominal"
19
+ *
20
+ * See {@link nominal} for more details.
21
+ */
22
+ type Nominal<N extends string> = string & {
23
+ [nominal]: N;
24
+ };
25
+ declare global {
26
+ interface ObjectConstructor {
27
+ /** Nominal: Extension to the Object prototype definition to properly manage {@link Nominal} keyed records */
28
+ keys<T extends Record<Nominal<string>, any>>(obj: T): any extends T ? never[] : Extract<keyof T, string>[];
29
+ /** Nominal: Extension to the Object prototype definition to properly manage {@link Nominal} keyed records */
30
+ entries<T extends Record<Nominal<string>, any>>(obj: T): any extends T ? [never, never][] : Array<{
31
+ [P in keyof T]: [P, T[P]];
32
+ }[Extract<keyof T, string>]>;
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Addresses are used to identify projects, sheets, objects, and other things.
38
+ *
39
+ * For example, a project's address looks like `{projectId: 'my-project'}`, and a sheet's
40
+ * address looks like `{projectId: 'my-project', sheetId: 'my-sheet'}`.
41
+ *
42
+ * As you see, a Sheet's address is a superset of a Project's address. This is so that we can
43
+ * use the same address type for both. All addresses follow the same rule. An object's address
44
+ * extends its sheet's address, which extends its project's address.
45
+ *
46
+ * For example, generating an object's address from a sheet's address is as simple as `{...sheetAddress, objectId: 'my-object'}`.
47
+ *
48
+ * Also, if you need the projectAddress of an object, you can just re-use the object's address:
49
+ * `aFunctionThatRequiresProjectAddress(objectAddress)`.
50
+ */
51
+ /**
52
+ * Represents the address to a project
53
+ */
54
+ interface ProjectAddress {
55
+ projectId: ProjectId;
56
+ }
57
+ /**
58
+ * Represents the address to a specific instance of a Sheet
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * const sheet = project.sheet('a sheet', 'some instance id')
63
+ * sheet.address.sheetId === 'a sheet'
64
+ * sheet.address.sheetInstanceId === 'sheetInstanceId'
65
+ * ```
66
+ *
67
+ * See {@link WithoutSheetInstance} for a type that doesn't include the sheet instance id.
68
+ */
69
+ interface SheetAddress extends ProjectAddress {
70
+ sheetId: SheetId;
71
+ sheetInstanceId: SheetInstanceId;
72
+ }
73
+ /**
74
+ * Represents the address to a Sheet's Object.
75
+ *
76
+ * It includes the sheetInstance, so it's specific to a single instance of a sheet. If you
77
+ * would like an address that doesn't include the sheetInstance, use `WithoutSheetInstance<SheetObjectAddress>`.
78
+ */
79
+ interface SheetObjectAddress extends SheetAddress {
80
+ /**
81
+ * The key of the object.
82
+ *
83
+ * @example
84
+ * ```ts
85
+ * const obj = sheet.object('foo', {})
86
+ * obj.address.objectKey === 'foo'
87
+ * ```
88
+ */
89
+ objectKey: ObjectAddressKey;
90
+ }
91
+ /**
92
+ * Just like {@link PathToProp}, but encoded as a string. Since this type is nominal,
93
+ * it can only be generated using {@link encodePathToProp}.
94
+ */
95
+ type PathToProp_Encoded = Nominal<'PathToProp_Encoded'>;
96
+
97
+ type Asset = {
98
+ type: 'image';
99
+ id: string | undefined;
100
+ };
101
+ type File = {
102
+ type: 'file';
103
+ id: string | undefined;
104
+ };
105
+
106
+ type VoidFn = () => void;
107
+ /**
108
+ * A `SerializableMap` is a plain JS object that can be safely serialized to JSON.
109
+ */
110
+ type SerializableMap<Primitives extends SerializablePrimitive = SerializablePrimitive> = {
111
+ [Key in string]?: SerializableValue<Primitives>;
112
+ };
113
+ type SerializablePrimitive = string | number | boolean | {
114
+ r: number;
115
+ g: number;
116
+ b: number;
117
+ a: number;
118
+ } | Asset;
119
+ /**
120
+ * This type represents all values that can be safely serialized.
121
+ * Also, it's notable that this type is compatible for dataverse pointer traversal (everything
122
+ * is path accessible [e.g. `a.b.c`]).
123
+ *
124
+ * One example usage is for keyframe values or static overrides such as `Rgba`, `string`, `number`, and "compound values".
125
+ */
126
+ type SerializableValue<Primitives extends SerializablePrimitive = SerializablePrimitive> = Primitives | SerializableMap;
127
+ type DeepPartialOfSerializableValue<T extends SerializableValue> = T extends SerializableMap ? {
128
+ [K in keyof T]?: DeepPartialOfSerializableValue<Exclude<T[K], undefined>>;
129
+ } : T;
130
+ /**
131
+ * This is equivalent to `Partial<Record<Key, V>>` being used to describe a sort of Map
132
+ * where the keys might not have values.
133
+ *
134
+ * We do not use `Map`s or `Set`s, because they add complexity with converting to
135
+ * `JSON.stringify` + pointer types.
136
+ */
137
+ type StrictRecord<Key extends string, V> = {
138
+ [K in Key]?: V;
139
+ };
140
+ /** For `any`s that we don't care about */
141
+ type $IntentionalAny = any;
142
+
143
+ interface SheetState_Historic {
144
+ /**
145
+ * @remarks
146
+ * Notes for when we implement FSMs:
147
+ *
148
+ * Each FSM state will have overrides of its own. Since a state could be a descendant
149
+ * of another state, it will be able to inherit the overrides from ancestor states.
150
+ */
151
+ staticOverrides: {
152
+ byObject: StrictRecord<ObjectAddressKey, SerializableMap>;
153
+ };
154
+ /**
155
+ * Per-variant static overrides. The `default` variant uses `staticOverrides.byObject`
156
+ * for backward compatibility. Non-default variants store only their own overrides here
157
+ * and inherit from `staticOverrides.byObject` at read time.
158
+ */
159
+ staticOverridesByVariant?: StrictRecord<string, {
160
+ byObject: StrictRecord<ObjectAddressKey, SerializableMap>;
161
+ }>;
162
+ /**
163
+ * @deprecated Use `sequencesById` instead. Kept for backward compatibility with
164
+ * project states saved before sequence variants were introduced.
165
+ */
166
+ sequence?: HistoricPositionalSequence;
167
+ /**
168
+ * Each variant has its own sequence data (tracks, length, etc.), allowing the same
169
+ * sheet properties to be animated differently per variant (e.g. mobile vs desktop).
170
+ */
171
+ sequencesById?: StrictRecord<string, HistoricPositionalSequence>;
172
+ /**
173
+ * Sheet objects explicitly opted into a non-default sequence variant for editing
174
+ * variant-specific overrides in the outline. All objects inherit default static
175
+ * and sequence data on every variant unless overridden here.
176
+ */
177
+ variantObjectOverrides?: StrictRecord<string, ObjectAddressKey[]>;
178
+ }
179
+ type HistoricPositionalSequence = {
180
+ type: 'PositionalSequence';
181
+ /**
182
+ * This is the length of the sequence in unit position. If the sequence
183
+ * is interpreted in seconds, then a length=2 means the sequence is two
184
+ * seconds long.
185
+ *
186
+ * Note that if there are keyframes sitting after sequence.length, they don't
187
+ * get truncated, but calling sequence.play() will play until it reaches the
188
+ * length of the sequence.
189
+ */
190
+ length: number;
191
+ /**
192
+ * Given the most common case of tracking a sequence against time (where 1 second = position 1),
193
+ * If set to, say, 30, then the keyframe editor will try to snap all keyframes
194
+ * to a 30fps grid
195
+ */
196
+ subUnitsPerUnit: number;
197
+ tracksByObject: StrictRecord<ObjectAddressKey, {
198
+ trackIdByPropPath: StrictRecord<PathToProp_Encoded, SequenceTrackId>;
199
+ /**
200
+ * Props on this variant that should not inherit default-variant sequences.
201
+ * Used when a prop is made static while inheriting from the default variant.
202
+ */
203
+ unsequencedPropPaths?: PathToProp_Encoded[];
204
+ /**
205
+ * A flat record of SequenceTrackId to TrackData. It's better
206
+ * that only its sub-props are observed (say via val(pointer(...))),
207
+ * rather than the object as a whole.
208
+ */
209
+ trackData: StrictRecord<SequenceTrackId, TrackData>;
210
+ }>;
211
+ };
212
+ /**
213
+ * Currently just {@link BasicKeyframedTrack}.
214
+ *
215
+ * Future: Other types of tracks can be added in, such as `MixedTrack` which would
216
+ * look like `[keyframes, expression, moreKeyframes, anotherExpression, …]`.
217
+ */
218
+ type TrackData = BasicKeyframedTrack;
219
+ type KeyframeType = 'bezier' | 'hold';
220
+ type Keyframe = {
221
+ id: KeyframeId;
222
+ /** The `value` is the raw value type such as `Rgba` or `number`. See {@link SerializableValue} */
223
+ value: SerializableValue;
224
+ position: number;
225
+ handles: [leftX: number, leftY: number, rightX: number, rightY: number];
226
+ connectedRight: boolean;
227
+ type?: KeyframeType;
228
+ };
229
+ type TrackDataCommon<TypeName extends string> = {
230
+ type: TypeName;
231
+ /**
232
+ * Initial name of the track for debugging purposes. In the future, let's
233
+ * strip this value from `studio.createContentOfSaveFile()` Could also be
234
+ * useful for users who manually edit the project state.
235
+ */
236
+ __debugName?: string;
237
+ };
238
+ type BasicKeyframedTrack = TrackDataCommon<'BasicKeyframedTrack'> & {
239
+ /**
240
+ * {@link Keyframe} is not provided an explicit generic value `T`, because
241
+ * a single track can technically have multiple different types for each keyframe.
242
+ */
243
+ keyframes: Keyframe[];
244
+ };
245
+
246
+ type SequenceVariantId = string;
247
+
248
+ type Rgba = {
249
+ r: number;
250
+ g: number;
251
+ b: number;
252
+ a: number;
253
+ };
254
+
255
+ declare const propTypeSymbol: unique symbol;
256
+ type UnknownValidCompoundProps = {
257
+ [K in string]: PropTypeConfig;
258
+ };
259
+ /**
260
+ *
261
+ * This does not include Rgba since Rgba does not have a predictable
262
+ * object shape. We prefer to infer that compound props are described as
263
+ * `Record<string, IShorthandProp>` for now.
264
+ *
265
+ * In the future, it might be reasonable to wrap these types up into something
266
+ * which would allow us to differentiate between values at runtime
267
+ * (e.g. `val.type = "Rgba"` vs `val.type = "Compound"` etc)
268
+ */
269
+ type UnknownShorthandProp = string | number | boolean | PropTypeConfig | UnknownShorthandCompoundProps;
270
+ /** Given an object like this, we have enough info to predict the compound prop */
271
+ type UnknownShorthandCompoundProps = {
272
+ [K in string]: UnknownShorthandProp;
273
+ };
274
+ type ShorthandPropToLonghandProp<P extends UnknownShorthandProp> = P extends string ? PropTypeConfig_String : P extends number ? PropTypeConfig_Number : P extends boolean ? PropTypeConfig_Boolean : P extends PropTypeConfig ? P : P extends UnknownShorthandCompoundProps ? PropTypeConfig_Compound<ShorthandCompoundPropsToLonghandCompoundProps<P>> : never;
275
+ type LonghandCompoundPropsToInitialValue<P extends UnknownValidCompoundProps> = {
276
+ [K in keyof P]: P[K]['valueType'];
277
+ };
278
+ type PropsValue<P> = P extends UnknownValidCompoundProps ? LonghandCompoundPropsToInitialValue<P> : P extends UnknownShorthandCompoundProps ? LonghandCompoundPropsToInitialValue<ShorthandCompoundPropsToLonghandCompoundProps<P>> : never;
279
+ type ShorthandCompoundPropsToLonghandCompoundProps<P extends UnknownShorthandCompoundProps> = {
280
+ [K in keyof P]: ShorthandPropToLonghandProp<P[K]>;
281
+ };
282
+
283
+ /**
284
+ * A compound prop type (basically a JS object).
285
+ *
286
+ * @example
287
+ * Usage:
288
+ * ```ts
289
+ * // shorthand
290
+ * const position = {
291
+ * x: 0,
292
+ * y: 0
293
+ * }
294
+ * assert(sheet.object('some object', position).value.x === 0)
295
+ *
296
+ * // nesting
297
+ * const foo = {bar: {baz: {quo: 0}}}
298
+ * assert(sheet.object('some object', foo).value.bar.baz.quo === 0)
299
+ *
300
+ * // With additional options:
301
+ * const position = t.compound(
302
+ * {x: 0, y: 0},
303
+ * // a custom label for the prop:
304
+ * {label: "Position"}
305
+ * )
306
+ * ```
307
+ *
308
+ */
309
+ declare function compoundFromSanitizedProps<Props extends UnknownValidCompoundProps>(sanitizedProps: Props, opts?: CommonOpts): PropTypeConfig_Compound<Props>;
310
+ declare const compound: <Props extends UnknownShorthandCompoundProps>(props: Props, opts?: CommonOpts) => PropTypeConfig_Compound<ShorthandCompoundPropsToLonghandCompoundProps<Props>>;
311
+ /**
312
+ * A file prop type
313
+ *
314
+ * @example
315
+ * Usage:
316
+ * ```ts
317
+ *
318
+ * // with a label:
319
+ * const obj = sheet.object('key', {
320
+ * url: t.file('My file.glb', {
321
+ * label: 'Model'
322
+ * })
323
+ * })
324
+ * ```
325
+ *
326
+ * @param opts - Options (See usage examples)
327
+ */
328
+ declare const file: (defaultValue: File['id'], opts?: {
329
+ label?: string;
330
+ interpolate?: Interpolator<File['id']>;
331
+ }) => PropTypeConfig_File;
332
+ /**
333
+ * An image prop type
334
+ *
335
+ * @example
336
+ * Usage:
337
+ * ```ts
338
+ *
339
+ * // with a label:
340
+ * const obj = sheet.object('key', {
341
+ * url: t.image('My image.png', {
342
+ * label: 'texture'
343
+ * })
344
+ * })
345
+ * ```
346
+ *
347
+ * @param opts - Options (See usage examples)
348
+ */
349
+ declare const image: (defaultValue: Asset['id'], opts?: {
350
+ label?: string;
351
+ interpolate?: Interpolator<Asset['id']>;
352
+ /**
353
+ * When `false`, values edited in Studio are kept in memory for the
354
+ * current session only and are not written to persisted project state.
355
+ * Defaults to `true`.
356
+ */
357
+ persist?: boolean;
358
+ }) => PropTypeConfig_Image;
359
+ /**
360
+ * A number prop type.
361
+ *
362
+ * @example
363
+ * Usage
364
+ * ```ts
365
+ * // shorthand:
366
+ * const obj = sheet.object('key', {x: 0})
367
+ *
368
+ * // With options (equal to above)
369
+ * const obj = sheet.object('key', {
370
+ * x: t.number(0)
371
+ * })
372
+ *
373
+ * // With a range (note that opts.range is just a visual guide, not a validation rule)
374
+ * const x = t.number(0, {range: [0, 10]}) // limited to 0 and 10
375
+ *
376
+ * // With custom nudging
377
+ * const x = t.number(0, {nudgeMultiplier: 0.1}) // nudging will happen in 0.1 increments
378
+ *
379
+ * // With custom nudging function
380
+ * const x = t.number({
381
+ * nudgeFn: (
382
+ * // the mouse movement (in pixels)
383
+ * deltaX: number,
384
+ * // the movement as a fraction of the width of the number editor's input
385
+ * deltaFraction: number,
386
+ * // A multiplier that's usually 1, but might be another number if user wants to nudge slower/faster
387
+ * magnitude: number,
388
+ * // the configuration of the number
389
+ * config: {nudgeMultiplier?: number; range?: [number, number]},
390
+ * ): number => {
391
+ * return deltaX * magnitude
392
+ * },
393
+ * })
394
+ * ```
395
+ *
396
+ * @param defaultValue - The default value (Must be a finite number)
397
+ * @param opts - The options (See usage examples)
398
+ * @returns A number prop config
399
+ */
400
+ declare const number: (defaultValue: number, opts?: {
401
+ nudgeFn?: PropTypeConfig_Number['nudgeFn'];
402
+ range?: PropTypeConfig_Number['range'];
403
+ nudgeMultiplier?: number;
404
+ label?: string;
405
+ }) => PropTypeConfig_Number;
406
+ declare const rgba: (defaultValue?: Rgba, opts?: CommonOpts) => PropTypeConfig_Rgba;
407
+ /**
408
+ * A boolean prop type
409
+ *
410
+ * @example
411
+ * Usage:
412
+ * ```ts
413
+ * // shorthand:
414
+ * const obj = sheet.object('key', {isOn: true})
415
+ *
416
+ * // with a label:
417
+ * const obj = sheet.object('key', {
418
+ * isOn: t.boolean(true, {
419
+ * label: 'Enabled'
420
+ * })
421
+ * })
422
+ * ```
423
+ *
424
+ * @param defaultValue - The default value (must be a boolean)
425
+ * @param opts - Options (See usage examples)
426
+ */
427
+ declare const boolean: (defaultValue: boolean, opts?: {
428
+ label?: string;
429
+ interpolate?: Interpolator<boolean>;
430
+ }) => PropTypeConfig_Boolean;
431
+ /**
432
+ * A string prop type
433
+ *
434
+ * @example
435
+ * Usage:
436
+ * ```ts
437
+ * // shorthand:
438
+ * const obj = sheet.object('key', {message: "Animation loading"})
439
+ *
440
+ * // with a label:
441
+ * const obj = sheet.object('key', {
442
+ * message: t.string("Animation Loading", {
443
+ * label: 'The Message'
444
+ * })
445
+ * })
446
+ * ```
447
+ *
448
+ * @param defaultValue - The default value (must be a string)
449
+ * @param opts - The options (See usage examples)
450
+ * @returns A string prop type
451
+ */
452
+ declare const string: (defaultValue: string, opts?: {
453
+ label?: string;
454
+ interpolate?: Interpolator<string>;
455
+ }) => PropTypeConfig_String;
456
+ /**
457
+ * A stringLiteral prop type, useful for building menus or radio buttons.
458
+ *
459
+ * @example
460
+ * Usage:
461
+ * ```ts
462
+ * // Basic usage
463
+ * const obj = sheet.object('key', {
464
+ * light: t.stringLiteral("r", {r: "Red", "g": "Green"})
465
+ * })
466
+ *
467
+ * // Shown as a radio switch with a custom label
468
+ * const obj = sheet.object('key', {
469
+ * light: t.stringLiteral("r", {r: "Red", "g": "Green"})
470
+ * }, {as: "switch", label: "Street Light"})
471
+ * ```
472
+ *
473
+ * @returns A stringLiteral prop type
474
+ *
475
+ */
476
+ declare function stringLiteral<ValuesAndLabels extends {
477
+ [key in string]: string;
478
+ }>(
479
+ /**
480
+ * Default value (a string that equals one of the options)
481
+ */
482
+ defaultValue: Extract<keyof ValuesAndLabels, string>,
483
+ /**
484
+ * The options. Use the `"value": "Label"` format.
485
+ *
486
+ * An object like `{[value]: Label}`. Example: `{r: "Red", "g": "Green"}`
487
+ */
488
+ valuesAndLabels: ValuesAndLabels,
489
+ /**
490
+ * opts.as Determines if editor is shown as a menu or a switch. Either 'menu' or 'switch'. Default: 'menu'
491
+ */
492
+ opts?: {
493
+ as?: 'menu' | 'switch';
494
+ label?: string;
495
+ interpolate?: Interpolator<Extract<keyof ValuesAndLabels, string>>;
496
+ }): PropTypeConfig_StringLiteral<Extract<keyof ValuesAndLabels, string>>;
497
+ /**
498
+ * A linear interpolator for a certain value type.
499
+ *
500
+ * @param left - the value to interpolate from (beginning)
501
+ * @param right - the value to interpolate to (end)
502
+ * @param progression - the amount of progression. Starts at 0 and ends at 1. But could overshoot in either direction
503
+ *
504
+ * @example
505
+ * ```ts
506
+ * const numberInterpolator: Interpolator<number> = (left, right, progression) => left + progression * (right - left)
507
+ *
508
+ * numberInterpolator(-50, 50, 0.5) === 0
509
+ * numberInterpolator(-50, 50, 0) === -50
510
+ * numberInterpolator(-50, 50, 1) === 50
511
+ * numberInterpolator(-50, 50, 2) === 150 // overshoot
512
+ * ```
513
+ */
514
+ type Interpolator<T> = (left: T, right: T, progression: number) => T;
515
+ interface IBasePropType<LiteralIdentifier extends string, ValueType, DeserializeType = ValueType> {
516
+ /**
517
+ * Each prop config has a string literal identifying it. For example,
518
+ * `assert.equal(t.number(10).type, 'number')`
519
+ */
520
+ type: LiteralIdentifier;
521
+ /**
522
+ * the `valueType` is only used by typescript. It won't be present in runtime.
523
+ */
524
+ valueType: ValueType;
525
+ [propTypeSymbol]: 'TheatrePropType';
526
+ /**
527
+ * Each prop type may be given a custom label instead of the name of the sub-prop
528
+ * it is in.
529
+ *
530
+ * @example
531
+ * ```ts
532
+ * const position = {
533
+ * x: t.number(0), // label would be 'x'
534
+ * y: t.number(0, {label: 'top'}) // label would be 'top'
535
+ * }
536
+ * ```
537
+ */
538
+ label: string | undefined;
539
+ default: ValueType;
540
+ /**
541
+ * Each prop config has a `deserializeAndSanitize()` function that deserializes and sanitizes
542
+ * any js value into one that is acceptable by this prop config, or `undefined`.
543
+ *
544
+ * As a rule, the value returned by this function should not hold any reference to `json` or any
545
+ * other value referenced by the descendent props of `json`. This is to ensure that json values
546
+ * controlled by the user can never change the values in the store. See `deserializeAndSanitize()` in
547
+ * `t.compound()` or `t.rgba()` as examples.
548
+ *
549
+ * The `DeserializeType` is usually equal to `ValueType`. That is the case with
550
+ * all simple prop configs, such as `number`, `string`, or `rgba`. However, composite
551
+ * configs such as `compound` or `enum` may deserialize+sanitize into a partial value. For example,
552
+ * a prop config of `t.compound({x: t.number(0), y: t.number(0)})` may deserialize+sanitize into `{x: 10}`.
553
+ * This behavior is used by {@link SheetObject.getValues} to replace the missing sub-props
554
+ * with their default value.
555
+ *
556
+ * Admittedly, this partial deserialization behavior is not what the word "deserialize"
557
+ * typically implies in most codebases, so feel free to change this name into a more
558
+ * appropriate one.
559
+ *
560
+ * Additionally, returning an `undefined` allows {@link SheetObject.getValues} to
561
+ * replace the `undefined` with the default value of that prop.
562
+ */
563
+ deserializeAndSanitize: (json: unknown) => undefined | DeserializeType;
564
+ }
565
+ interface ISimplePropType<LiteralIdentifier extends string, ValueType> extends IBasePropType<LiteralIdentifier, ValueType, ValueType> {
566
+ interpolate: Interpolator<ValueType>;
567
+ }
568
+ interface PropTypeConfig_Number extends ISimplePropType<'number', number> {
569
+ range?: [min: number, max: number];
570
+ nudgeFn: NumberNudgeFn;
571
+ /**
572
+ * See {@link defaultNumberNudgeFn} to see how `nudgeMultiplier` is treated.
573
+ */
574
+ nudgeMultiplier: number | undefined;
575
+ }
576
+ type NumberNudgeFn = (p: {
577
+ deltaX: number;
578
+ deltaFraction: number;
579
+ magnitude: number;
580
+ config: PropTypeConfig_Number;
581
+ }) => number;
582
+ interface PropTypeConfig_Boolean extends ISimplePropType<'boolean', boolean> {
583
+ }
584
+ type CommonOpts = {
585
+ /**
586
+ * Each prop type may be given a custom label instead of the name of the sub-prop
587
+ * it is in.
588
+ *
589
+ * @example
590
+ * ```ts
591
+ * const position = {
592
+ * x: t.number(0), // label would be 'x'
593
+ * y: t.number(0, {label: 'top'}) // label would be 'top'
594
+ * }
595
+ * ```
596
+ */
597
+ label?: string;
598
+ };
599
+ interface PropTypeConfig_String extends ISimplePropType<'string', string> {
600
+ }
601
+ interface PropTypeConfig_StringLiteral<T extends string> extends ISimplePropType<'stringLiteral', T> {
602
+ valuesAndLabels: Record<T, string>;
603
+ as: 'menu' | 'switch';
604
+ }
605
+ interface PropTypeConfig_Rgba extends ISimplePropType<'rgba', Rgba> {
606
+ }
607
+ interface PropTypeConfig_Image extends ISimplePropType<'image', Asset> {
608
+ /**
609
+ * When `false`, Studio edits are session-only and not written to persisted
610
+ * project state. Defaults to `true`.
611
+ */
612
+ persist: boolean;
613
+ }
614
+ interface PropTypeConfig_File extends ISimplePropType<'file', File> {
615
+ }
616
+ type DeepPartialCompound<Props extends UnknownValidCompoundProps> = {
617
+ [K in keyof Props]?: DeepPartial<Props[K]>;
618
+ };
619
+ type DeepPartial<Conf extends PropTypeConfig> = Conf extends PropTypeConfig_AllSimples ? Conf['valueType'] : Conf extends PropTypeConfig_Compound<infer T> ? DeepPartialCompound<T> : never;
620
+ interface PropTypeConfig_Compound<Props extends UnknownValidCompoundProps> extends IBasePropType<'compound', {
621
+ [K in keyof Props]: Props[K]['valueType'];
622
+ }, DeepPartialCompound<Props>> {
623
+ props: Record<keyof Props, PropTypeConfig>;
624
+ }
625
+ interface PropTypeConfig_Enum extends IBasePropType<'enum', {}> {
626
+ cases: Record<string, PropTypeConfig>;
627
+ defaultCase: string;
628
+ }
629
+ type PropTypeConfig_AllSimples = PropTypeConfig_Number | PropTypeConfig_Boolean | PropTypeConfig_String | PropTypeConfig_StringLiteral<$IntentionalAny> | PropTypeConfig_Rgba | PropTypeConfig_Image | PropTypeConfig_File;
630
+ type PropTypeConfig = PropTypeConfig_AllSimples | PropTypeConfig_Compound<$IntentionalAny> | PropTypeConfig_Enum;
631
+
632
+ type index_d_UnknownShorthandCompoundProps = UnknownShorthandCompoundProps;
633
+ declare const index_d_compoundFromSanitizedProps: typeof compoundFromSanitizedProps;
634
+ declare const index_d_compound: typeof compound;
635
+ declare const index_d_file: typeof file;
636
+ declare const index_d_image: typeof image;
637
+ declare const index_d_number: typeof number;
638
+ declare const index_d_rgba: typeof rgba;
639
+ declare const index_d_boolean: typeof boolean;
640
+ declare const index_d_string: typeof string;
641
+ declare const index_d_stringLiteral: typeof stringLiteral;
642
+ type index_d_Interpolator<_0> = Interpolator<_0>;
643
+ type index_d_IBasePropType<_0, _1, _2> = IBasePropType<_0, _1, _2>;
644
+ type index_d_PropTypeConfig_Number = PropTypeConfig_Number;
645
+ type index_d_NumberNudgeFn = NumberNudgeFn;
646
+ type index_d_PropTypeConfig_Boolean = PropTypeConfig_Boolean;
647
+ type index_d_PropTypeConfig_String = PropTypeConfig_String;
648
+ type index_d_PropTypeConfig_StringLiteral<_0> = PropTypeConfig_StringLiteral<_0>;
649
+ type index_d_PropTypeConfig_Rgba = PropTypeConfig_Rgba;
650
+ type index_d_PropTypeConfig_Image = PropTypeConfig_Image;
651
+ type index_d_PropTypeConfig_File = PropTypeConfig_File;
652
+ type index_d_PropTypeConfig_Compound<_0> = PropTypeConfig_Compound<_0>;
653
+ type index_d_PropTypeConfig_Enum = PropTypeConfig_Enum;
654
+ type index_d_PropTypeConfig_AllSimples = PropTypeConfig_AllSimples;
655
+ type index_d_PropTypeConfig = PropTypeConfig;
656
+ declare namespace index_d {
657
+ export {
658
+ index_d_UnknownShorthandCompoundProps as UnknownShorthandCompoundProps,
659
+ index_d_compoundFromSanitizedProps as compoundFromSanitizedProps,
660
+ index_d_compound as compound,
661
+ index_d_file as file,
662
+ index_d_image as image,
663
+ index_d_number as number,
664
+ index_d_rgba as rgba,
665
+ index_d_boolean as boolean,
666
+ index_d_string as string,
667
+ index_d_stringLiteral as stringLiteral,
668
+ index_d_Interpolator as Interpolator,
669
+ index_d_IBasePropType as IBasePropType,
670
+ index_d_PropTypeConfig_Number as PropTypeConfig_Number,
671
+ index_d_NumberNudgeFn as NumberNudgeFn,
672
+ index_d_PropTypeConfig_Boolean as PropTypeConfig_Boolean,
673
+ index_d_PropTypeConfig_String as PropTypeConfig_String,
674
+ index_d_PropTypeConfig_StringLiteral as PropTypeConfig_StringLiteral,
675
+ index_d_PropTypeConfig_Rgba as PropTypeConfig_Rgba,
676
+ index_d_PropTypeConfig_Image as PropTypeConfig_Image,
677
+ index_d_PropTypeConfig_File as PropTypeConfig_File,
678
+ index_d_PropTypeConfig_Compound as PropTypeConfig_Compound,
679
+ index_d_PropTypeConfig_Enum as PropTypeConfig_Enum,
680
+ index_d_PropTypeConfig_AllSimples as PropTypeConfig_AllSimples,
681
+ index_d_PropTypeConfig as PropTypeConfig,
682
+ };
683
+ }
684
+
685
+ type TransientPropPath = string | readonly (string | number)[];
686
+ /** Same path format as {@link TransientPropPath}. */
687
+ type StaticPropPath = TransientPropPath;
688
+
689
+ interface IRafDriver {
690
+ /**
691
+ * All raf derivers have have `driver.type === 'Theatre_RafDriver_PublicAPI'`
692
+ */
693
+ readonly type: 'Theatre_RafDriver_PublicAPI';
694
+ /**
695
+ * The name of the driver. This is used for debugging purposes.
696
+ */
697
+ name: string;
698
+ /**
699
+ * The id of the driver. This is used for debugging purposes.
700
+ * It's guaranteed to be unique.
701
+ */
702
+ id: number;
703
+ /**
704
+ * This is called by the driver when it's time to tick forward.
705
+ * The time param is of the same type returned by `performance.now()`.
706
+ */
707
+ tick: (time: number) => void;
708
+ }
709
+ /**
710
+ * Creates a custom raf driver.
711
+ * `rafDriver`s allow you to control when and how often computations in Theatre tick forward. (raf stands for [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame)).
712
+ * The default `rafDriver` in Theatre creates a `raf` loop and ticks forward on each frame. You can create your own `rafDriver`, which enables the following use-cases:
713
+ *
714
+ * 1. When using Theatre.js alongside other animation libs (`gsap`/`lenis`/`etc`), you'd want all animation libs to use a single `raf` loop to keep the libraries in sync and also to get better performance.
715
+ * 2. In XR sessions, you'd want Theatre to tick forward using [`xr.requestAnimationFrame()`](https://developer.mozilla.org/en-US/docs/Web/API/XRSession/requestAnimationFrame).
716
+ * 3. In some advanced cases, you'd just want to manually tick forward (many ticks per frame, or skipping many frames, etc). This is useful for recording an animation, rendering to a file, testing an animation, running benchmarks, etc.
717
+ *
718
+ * Here is how you'd create a custom `rafDriver`:
719
+ *
720
+ * ```js
721
+ * import { createRafDriver } from '@unseenco/theatre-core'
722
+ *
723
+ * const rafDriver = createRafDriver({ name: 'a custom 5fps raf driver' })
724
+ *
725
+ * setInterval(() => {
726
+ * rafDriver.tick(performance.now())
727
+ * }, 200)
728
+ * ```
729
+ *
730
+ * Now, any time you set up an `onChange()` listener, pass your custom `rafDriver`:
731
+ *
732
+ * ```js
733
+ * import { onChange } from '@unseenco/theatre-core'
734
+ *
735
+ * onChange(
736
+ * // let's say object is a Theatre object, the one returned from calling `sheet.object()`
737
+ * object.props,
738
+ * // this callback will now only be called at 5fps (and won't be called if there are no new values)
739
+ * // even if `sequence.play()` updates `object.props` at 60fps, this listener is called a maximum of 5fps
740
+ * (propValues) => {
741
+ * console.log(propValues)
742
+ * },
743
+ * rafDriver,
744
+ * )
745
+ *
746
+ * // this will update the values of `object.props` at 60fps, but the listener above will still get called a maximum of 5fps
747
+ * sheet.sequence.play()
748
+ *
749
+ * // we can also customize at what resolution the sequence's playhead moves forward
750
+ * sheet.sequence.play({ rafDriver }) // the playhead will move forward at 5fps
751
+ * ```
752
+ *
753
+ * You can optionally make studio use this `rafDriver`. This means the parts of the studio that tick based on raf, will now tick at 5fps. This is only useful if you're doing something crazy like running the studio (and not the core) in an XR frame.
754
+ *
755
+ * ```js
756
+ * studio.initialize({
757
+ * __experimental_rafDriver: rafDriver,
758
+ * })
759
+ * ```
760
+ *
761
+ * `rafDriver`s can optionally provide a `start/stop` callback. Theatre will call `start()` when it actually has computations scheduled, and will call `stop` if there is nothing to update after a few ticks:
762
+ *
763
+ * ```js
764
+ * import { createRafDriver } from '@unseenco/theatre-core'
765
+ * import type { IRafDriver } from '@theare/core'
766
+ *
767
+ * function createBasicRafDriver(): IRafDriver {
768
+ * let rafId: number | null = null
769
+ * const start = (): void => {
770
+ * if (typeof window !== 'undefined') {
771
+ * const onAnimationFrame = (t: number) => {
772
+ * driver.tick(t)
773
+ * rafId = window.requestAnimationFrame(onAnimationFrame)
774
+ * }
775
+ * rafId = window.requestAnimationFrame(onAnimationFrame)
776
+ * } else {
777
+ * driver.tick(0)
778
+ * setTimeout(() => driver.tick(1), 0)
779
+ * }
780
+ * }
781
+ *
782
+ * const stop = (): void => {
783
+ * if (typeof window !== 'undefined') {
784
+ * if (rafId !== null) {
785
+ * window.cancelAnimationFrame(rafId)
786
+ * }
787
+ * } else {
788
+ * // nothing to do in SSR
789
+ * }
790
+ * }
791
+ *
792
+ * const driver = createRafDriver({ name: 'DefaultCoreRafDriver', start, stop })
793
+ *
794
+ * return driver
795
+ * }
796
+ * ```
797
+ */
798
+ declare function createRafDriver(conf?: {
799
+ name?: string;
800
+ start?: () => void;
801
+ stop?: () => void;
802
+ }): IRafDriver;
803
+
804
+ type SheetObjectValuesChangeMeta = {
805
+ /**
806
+ * The sequence variant whose values are being applied.
807
+ * This reflects the sheet's active sequence variant.
808
+ */
809
+ variant: SequenceVariantId;
810
+ };
811
+ interface ISheetObject<Props extends UnknownShorthandCompoundProps = UnknownShorthandCompoundProps> {
812
+ /**
813
+ * All Objects will have `object.type === 'Theatre_SheetObject_PublicAPI'`
814
+ */
815
+ readonly type: 'Theatre_SheetObject_PublicAPI';
816
+ /**
817
+ * The current values of the props.
818
+ *
819
+ * @example
820
+ * Usage:
821
+ * ```ts
822
+ * const obj = sheet.object("obj", {x: 0})
823
+ * console.log(obj.value.x) // prints 0 or the current numeric value
824
+ * ```
825
+ *
826
+ * Future: Notice that if the user actually changes the Props config for one of the
827
+ * properties, then this type can't be guaranteed accurrate.
828
+ * * Right now the user can't change prop configs, but we'll probably enable that
829
+ * functionality later via (`object.overrideConfig()`). We need to educate the
830
+ * user that they can't rely on static types to know the type of object.value.
831
+ */
832
+ readonly value: PropsValue<Props>;
833
+ /**
834
+ * A Pointer to the props of the object.
835
+ *
836
+ * More documentation soon.
837
+ */
838
+ readonly props: Pointer<this['value']>;
839
+ /**
840
+ * The instance of Sheet the Object belongs to
841
+ */
842
+ readonly sheet: ISheet;
843
+ /**
844
+ * The Project the project belongs to
845
+ */
846
+ readonly project: IProject;
847
+ /**
848
+ * An object representing the address of the Object
849
+ */
850
+ readonly address: SheetObjectAddress;
851
+ /**
852
+ * Calls `fn` every time the value of the props change.
853
+ *
854
+ * @param fn - The callback is called every time the value of the props change, plus once at the beginning.
855
+ * @param rafDriver - (optional) The `rafDriver` to use. Learn how to use `rafDriver`s [from the docs](https://www.theatrejs.com/docs/latest/manual/advanced#rafdrivers).
856
+ * @returns an Unsubscribe function
857
+ *
858
+ * @example
859
+ * Usage:
860
+ * ```ts
861
+ * const obj = sheet.object("Box", {position: {x: 0, y: 0}})
862
+ * const div = document.getElementById("box")
863
+ *
864
+ * const unsubscribe = obj.onValuesChange((newValues, {variant}) => {
865
+ * div.style.left = newValues.position.x + 'px'
866
+ * div.style.top = newValues.position.y + 'px'
867
+ * console.log('Active variant:', variant)
868
+ * })
869
+ *
870
+ * // you can call unsubscribe() to stop listening to changes
871
+ * ```
872
+ */
873
+ onValuesChange(fn: (values: this['value'], meta: SheetObjectValuesChangeMeta) => void, rafDriver?: IRafDriver): VoidFn;
874
+ /**
875
+ * Sets the initial value of the object. This value overrides the default
876
+ * values defined in the prop types, but would itself be overridden if the user
877
+ * overrides it in the UI with a static or animated value.
878
+ *
879
+ * @example
880
+ * Usage:
881
+ * ```ts
882
+ * const obj = sheet.object("obj", {position: {x: 0, y: 0}})
883
+ *
884
+ * obj.value // {position: {x: 0, y: 0}}
885
+ *
886
+ * // here, we only override position.x
887
+ * obj.initialValue = {position: {x: 2}}
888
+ *
889
+ * obj.value // {position: {x: 2, y: 0}}
890
+ * ```
891
+ */
892
+ set initialValue(value: DeepPartialOfSerializableValue<this['value']>);
893
+ /**
894
+ * Show another object's props in this object's Studio details pane.
895
+ * Runtime-only (not persisted). Edits and sequencing still target the
896
+ * source objects. Pass `[]` to clear.
897
+ *
898
+ * @example
899
+ * ```ts
900
+ * const appearance = sheet.object('Appearance', {color: types.rgba()})
901
+ * const box = sheet.object('Box', {x: 0})
902
+ * box.showPropsOf([appearance])
903
+ * ```
904
+ */
905
+ showPropsOf(objects: ISheetObject<any>[]): void;
906
+ /**
907
+ * Returns the objects currently linked via {@link showPropsOf}.
908
+ */
909
+ getShowPropsOf(): ISheetObject<any>[];
910
+ /**
911
+ * Replace this object's prop config. Props removed from `config` disappear
912
+ * from the Studio details pane; historic statics/tracks for those paths are
913
+ * stripped. Same effect as `sheet.object(key, config, {reconfigure: true})`.
914
+ */
915
+ reconfigure(config: UnknownShorthandCompoundProps, opts?: {
916
+ transient?: readonly TransientPropPath[];
917
+ static?: readonly StaticPropPath[];
918
+ }): void;
919
+ /**
920
+ * Add new props to this object's config. Existing props are preserved; only
921
+ * the keys in `config` are added. Throws if a key already exists on the object.
922
+ *
923
+ * @example
924
+ * ```ts
925
+ * const obj = sheet.object('Box', {x: 0})
926
+ * obj.addProps({y: 0})
927
+ * // obj now has props x and y
928
+ * ```
929
+ */
930
+ addProps(config: UnknownShorthandCompoundProps, opts?: {
931
+ transient?: readonly TransientPropPath[];
932
+ static?: readonly StaticPropPath[];
933
+ }): void;
934
+ }
935
+
936
+ type KeyframeId = Nominal<'KeyframeId'>;
937
+ type ProjectId = Nominal<'ProjectId'>;
938
+ type SheetId = Nominal<'SheetId'>;
939
+ type SheetInstanceId = Nominal<'SheetInstanceId'>;
940
+ type SequenceTrackId = Nominal<'SequenceTrackId'>;
941
+ type ObjectAddressKey = Nominal<'ObjectAddressKey'>;
942
+
943
+ /**
944
+ * This is the state of each project that is consumable by `@unseenco/theatre-core`.
945
+ * If the studio is present, this part of the state joins the studio's historic state,
946
+ * at {@link StudioHistoricState.coreByProject}
947
+ */
948
+ interface ProjectState_Historic {
949
+ sheetsById: StrictRecord<SheetId, SheetState_Historic>;
950
+ /**
951
+ * The last 50 revision IDs this state is based on, starting with the most recent one.
952
+ * The most recent one is the revision ID of this state
953
+ */
954
+ revisionHistory: string[];
955
+ definitionVersion: string;
956
+ }
957
+ interface OnDiskState extends ProjectState_Historic {
958
+ }
959
+
960
+ type IPlaybackRange = [from: number, to: number];
961
+ type IPlaybackDirection = 'normal' | 'reverse' | 'alternate' | 'alternateReverse';
962
+
963
+ interface IAttachAudioArgs {
964
+ /**
965
+ * Either a URL to the audio file (eg "http://localhost:3000/audio.mp3") or an instance of AudioBuffer
966
+ */
967
+ source: string | AudioBuffer;
968
+ /**
969
+ * An optional AudioContext. If not provided, one will be created.
970
+ */
971
+ audioContext?: AudioContext;
972
+ /**
973
+ * An AudioNode to feed the audio into. Will use audioContext.destination if not provided.
974
+ */
975
+ destinationNode?: AudioNode;
976
+ }
977
+ interface ISequence {
978
+ readonly type: 'Theatre_Sequence_PublicAPI';
979
+ /**
980
+ * Starts playback of a sequence.
981
+ * Returns a promise that either resolves to true when the playback completes,
982
+ * or resolves to false if playback gets interrupted (for example by calling sequence.pause())
983
+ *
984
+ * @returns A promise that resolves when the playback is finished, or rejects if interruped
985
+ *
986
+ * @example
987
+ * Usage:
988
+ * ```ts
989
+ * // plays the sequence from the current position to sequence.length
990
+ * sheet.sequence.play()
991
+ *
992
+ * // plays the sequence at 2.4x speed
993
+ * sheet.sequence.play({rate: 2.4})
994
+ *
995
+ * // plays the sequence from second 1 to 4
996
+ * sheet.sequence.play({range: [1, 4]})
997
+ *
998
+ * // plays the sequence 4 times
999
+ * sheet.sequence.play({iterationCount: 4})
1000
+ *
1001
+ * // plays the sequence in reverse
1002
+ * sheet.sequence.play({direction: 'reverse'})
1003
+ *
1004
+ * // plays the sequence back and forth forever (until interrupted)
1005
+ * sheet.sequence.play({iterationCount: Infinity, direction: 'alternateReverse})
1006
+ *
1007
+ * // plays the sequence and logs "done" once playback is finished
1008
+ * sheet.sequence.play().then(() => console.log('done'))
1009
+ * ```
1010
+ */
1011
+ play(conf?: {
1012
+ /**
1013
+ * The number of times the animation must run. Must be an integer larger
1014
+ * than 0. Defaults to 1. Pick Infinity to run forever
1015
+ */
1016
+ iterationCount?: number;
1017
+ /**
1018
+ * Limits the range to be played. Default is [0, sequence.length]
1019
+ */
1020
+ range?: IPlaybackRange;
1021
+ /**
1022
+ * The playback rate. Defaults to 1. Choosing 2 would play the animation
1023
+ * at twice the speed.
1024
+ */
1025
+ rate?: number;
1026
+ /**
1027
+ * The direction of the playback. Similar to CSS's animation-direction
1028
+ */
1029
+ direction?: IPlaybackDirection;
1030
+ /**
1031
+ * Optionally provide a rafDriver to use for the playback. It'll default to
1032
+ * the core driver if not provided, which is a `requestAnimationFrame()` driver.
1033
+ * Learn how to use `rafDriver`s [from the docs](https://www.theatrejs.com/docs/latest/manual/advanced#rafdrivers).
1034
+ */
1035
+ rafDriver?: IRafDriver;
1036
+ }): Promise<boolean>;
1037
+ /**
1038
+ * Pauses the currently playing animation
1039
+ */
1040
+ pause(): void;
1041
+ /**
1042
+ * The current position of the playhead.
1043
+ * In a time-based sequence, this represents the current time in seconds.
1044
+ */
1045
+ position: number;
1046
+ /**
1047
+ * A Pointer to the sequence's inner state.
1048
+ *
1049
+ * @remarks
1050
+ * As with any Pointer, you can use this with {@link onChange | onChange()} to listen to its value changes
1051
+ * or with {@link val | val()} to read its current value.
1052
+ *
1053
+ * @example Usage
1054
+ * ```ts
1055
+ * import {onChange, val} from '@unseenco/theatre-core'
1056
+ *
1057
+ * // let's assume `sheet` is a sheet
1058
+ * const sequence = sheet.sequence
1059
+ *
1060
+ * onChange(sequence.pointer.length, (len) => {
1061
+ * console.log("Length of the sequence changed to:", len)
1062
+ * })
1063
+ *
1064
+ * onChange(sequence.pointer.position, (position) => {
1065
+ * console.log("Position of the sequence changed to:", position)
1066
+ * })
1067
+ *
1068
+ * onChange(sequence.pointer.playing, (playing) => {
1069
+ * console.log(playing ? 'playing' : 'paused')
1070
+ * })
1071
+ *
1072
+ * // we can also read the current value of the pointer
1073
+ * console.log('current length is', val(sequence.pointer.length))
1074
+ * ```
1075
+ */
1076
+ pointer: Pointer<{
1077
+ playing: boolean;
1078
+ length: number;
1079
+ position: number;
1080
+ }>;
1081
+ /**
1082
+ * Given a property, returns a list of keyframes that affect that property.
1083
+ *
1084
+ * @example
1085
+ * Usage:
1086
+ * ```ts
1087
+ * // let's assume `sheet` is a sheet and obj is one of its objects
1088
+ * const keyframes = sheet.sequence.__experimental_getKeyframes(obj.pointer.x)
1089
+ * console.log(keyframes) // an array of keyframes
1090
+ * ```
1091
+ */
1092
+ __experimental_getKeyframes(prop: Pointer<{}>): Keyframe[];
1093
+ /**
1094
+ * Attaches an audio source to the sequence. Playing the sequence automatically
1095
+ * plays the audio source and their times are kept in sync.
1096
+ *
1097
+ * @returns A promise that resolves once the audio source is loaded and decoded
1098
+ *
1099
+ * Learn more [here](https://www.theatrejs.com/docs/latest/manual/audio).
1100
+ *
1101
+ * @example
1102
+ * Usage:
1103
+ * ```ts
1104
+ * // Loads and decodes audio from the URL and then attaches it to the sequence
1105
+ * await sheet.sequence.attachAudio({source: "http://localhost:3000/audio.mp3"})
1106
+ * sheet.sequence.play()
1107
+ *
1108
+ * // Providing your own AudioAPI Context, destination, etc
1109
+ * const audioContext: AudioContext = {...} // create an AudioContext using the Audio API
1110
+ * const audioBuffer: AudioBuffer = {...} // create an AudioBuffer
1111
+ * const destinationNode = audioContext.destination
1112
+ *
1113
+ * await sheet.sequence.attachAudio({source: audioBuffer, audioContext, destinationNode})
1114
+ * ```
1115
+ *
1116
+ * Note: It's better to provide the `audioContext` rather than allow Theatre.js to create it.
1117
+ * That's because some browsers [suspend the audioContext](https://developer.chrome.com/blog/autoplay/#webaudio)
1118
+ * unless it's initiated by a user gesture, like a click. If that happens, Theatre.js will
1119
+ * wait for a user gesture to resume the audioContext. But that's probably not an
1120
+ * optimal user experience. It is better to provide a button or some other UI element
1121
+ * to communicate to the user that they have to initiate the animation.
1122
+ *
1123
+ * @example
1124
+ * Example:
1125
+ * ```ts
1126
+ * // html: <button id="#start">start</button>
1127
+ * const button = document.getElementById('start')
1128
+ *
1129
+ * button.addEventListener('click', async () => {
1130
+ * const audioContext = ...
1131
+ * await sheet.sequence.attachAudio({audioContext, source: '...'})
1132
+ * sheet.sequence.play()
1133
+ * })
1134
+ * ```
1135
+ */
1136
+ attachAudio(args: IAttachAudioArgs): Promise<{
1137
+ /**
1138
+ * An {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBuffer | AudioBuffer}.
1139
+ * If `args.source` is a URL, then `decodedBuffer` would be the result
1140
+ * of {@link https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/decodeAudioData | audioContext.decodeAudioData()}
1141
+ * on the audio file at that URL.
1142
+ *
1143
+ * If `args.source` is an `AudioBuffer`, then `decodedBuffer` would be equal to `args.source`
1144
+ */
1145
+ decodedBuffer: AudioBuffer;
1146
+ /**
1147
+ * The `AudioContext`. It is either equal to `source.audioContext` if it is provided, or
1148
+ * one that's created on the fly.
1149
+ */
1150
+ audioContext: AudioContext;
1151
+ /**
1152
+ * Equals to either `args.destinationNode`, or if none is provided, it equals `audioContext.destinationNode`.
1153
+ *
1154
+ * See `gainNode` for more info.
1155
+ */
1156
+ destinationNode: AudioNode;
1157
+ /**
1158
+ * This is an intermediate GainNode that Theatre.js feeds its audio to. It is by default
1159
+ * connected to destinationNode, but you can disconnect the gainNode and feed it to your own graph.
1160
+ *
1161
+ * @example
1162
+ * For example:
1163
+ * ```ts
1164
+ * const {gainNode, audioContext} = await sequence.attachAudio({source: '/audio.mp3'})
1165
+ * // disconnect the gainNode (at this point, the sequence's audio track won't be audible)
1166
+ * gainNode.disconnect()
1167
+ * // create our own gain node
1168
+ * const lowerGain = audioContext.createGain()
1169
+ * // lower its volume to 10%
1170
+ * lowerGain.gain.setValueAtTime(0.1, audioContext.currentTime)
1171
+ * // feed the sequence's audio to our lowered gainNode
1172
+ * gainNode.connect(lowerGain)
1173
+ * // feed the lowered gainNode to the audioContext's destination
1174
+ * lowerGain.connect(audioContext.destination)
1175
+ * // now audio will be audible, with 10% the volume
1176
+ * ```
1177
+ */
1178
+ gainNode: GainNode;
1179
+ }>;
1180
+ }
1181
+
1182
+ type SheetObjectAction = (object: ISheetObject) => void;
1183
+ type SheetObjectActionsConfig = Record<string, SheetObjectAction>;
1184
+ type ISheetObjectOptions = {
1185
+ reconfigure?: boolean;
1186
+ /**
1187
+ * Whether the object appears in the Studio outline panel. Defaults to `true`.
1188
+ */
1189
+ visible?: boolean;
1190
+ /**
1191
+ * Other sheet objects whose props are shown in this object's Studio details
1192
+ * pane. Runtime-only (not persisted). Edits and sequencing still target the
1193
+ * source objects. Same-sheet only; cannot include the host object.
1194
+ *
1195
+ * @example
1196
+ * ```ts
1197
+ * const appearance = sheet.object('Appearance', {color: types.rgba()})
1198
+ * sheet.object('Box', {x: 0}, {showPropsOf: [appearance]})
1199
+ * ```
1200
+ */
1201
+ showPropsOf?: ISheetObject<any>[];
1202
+ /**
1203
+ * Prop paths that are excluded from exported project state JSON.
1204
+ * Values are stored in ahistoric static overrides (persist across Studio
1205
+ * reloads) but never written to historic state or sequence tracks.
1206
+ *
1207
+ * Paths accept dot notation (`'foo.bar'`) or arrays (`['foo', 'bar']`).
1208
+ * A prefix path like `'foo'` marks the entire subtree as transient.
1209
+ */
1210
+ transient?: readonly TransientPropPath[];
1211
+ /**
1212
+ * Prop paths that cannot be sequenced but are saved to exported project state.
1213
+ *
1214
+ * Paths accept dot notation (`'foo.bar'`) or arrays (`['foo', 'bar']`).
1215
+ * A prefix path like `'foo'` marks the entire subtree as static.
1216
+ */
1217
+ static?: readonly StaticPropPath[];
1218
+ __actions__THIS_API_IS_UNSTABLE_AND_WILL_CHANGE_IN_THE_NEXT_VERSION?: SheetObjectActionsConfig;
1219
+ };
1220
+ interface ISheet {
1221
+ /**
1222
+ * All sheets have `sheet.type === 'Theatre_Sheet_PublicAPI'`
1223
+ */
1224
+ readonly type: 'Theatre_Sheet_PublicAPI';
1225
+ /**
1226
+ * The Project this Sheet belongs to
1227
+ */
1228
+ readonly project: IProject;
1229
+ /**
1230
+ * The address of the Sheet
1231
+ */
1232
+ readonly address: SheetAddress;
1233
+ /**
1234
+ * Creates a child object for the sheet
1235
+ *
1236
+ * **Docs: https://www.theatrejs.com/docs/latest/manual/objects**
1237
+ *
1238
+ * @param key - Each object is identified by a key, which is a non-empty string
1239
+ * @param props - The props of the object. See examples
1240
+ * @param options - (Optional) Provide `{reconfigure: true}` to reconfigure an existing object, `{visible: false}` to hide it from the Studio outline panel, or `{actions: { ... }}` to add custom buttons to the UI. Read the example below for details.
1241
+ *
1242
+ * @returns An Object
1243
+ *
1244
+ * @example
1245
+ * Usage:
1246
+ * ```ts
1247
+ * // Create an object named "a unique key" with no props
1248
+ * const obj = sheet.object("a unique key", {})
1249
+ * obj.address.objectKey // "a unique key"
1250
+ *
1251
+ *
1252
+ * // Create an object with {x: 0}
1253
+ * const obj = sheet.object("obj", {x: 0})
1254
+ * obj.value.x // returns 0 or the current number that the user has set
1255
+ *
1256
+ * // Create an object with nested props
1257
+ * const obj = sheet.object("obj", {position: {x: 0, y: 0}})
1258
+ * obj.value.position // {x: 0, y: 0}
1259
+ *
1260
+ * // you can also reconfigure an existing object:
1261
+ * const obj = sheet.object("obj", {foo: 0})
1262
+ * console.log(object.value.foo) // prints 0
1263
+ *
1264
+ * const obj2 = sheet.object("obj", {bar: 0}, {reconfigure: true})
1265
+ * console.log(object.value.foo) // prints undefined, since we've removed this prop via reconfiguring the object
1266
+ * console.log(object.value.bar) // prints 0, since we've introduced this prop by reconfiguring the object
1267
+ *
1268
+ * assert(obj === obj2) // passes, because reconfiguring the object returns the same object
1269
+ *
1270
+ * // you can add custom actions to an object:
1271
+ * const obj = sheet.object("obj", {foo: 0}, {
1272
+ * actions: {
1273
+ * // This will display a button in the UI that will reset the value of `foo` to 0
1274
+ * Reset: () => {
1275
+ * studio.transaction((api) => {
1276
+ * api.set(obj.props.foo, 0)
1277
+ * })
1278
+ * }
1279
+ * }
1280
+ * })
1281
+ *
1282
+ * // you can mark props as transient (excluded from exported state JSON):
1283
+ * const obj = sheet.object("Camera", {
1284
+ * fov: 50,
1285
+ * orbitEnabled: false,
1286
+ * }, {
1287
+ * transient: ['orbitEnabled']
1288
+ * })
1289
+ *
1290
+ * // static props are saved to state but cannot be sequenced:
1291
+ * const obj = sheet.object("Camera", { fov: 50, zoom: 1 }, {
1292
+ * static: ['zoom']
1293
+ * })
1294
+ * ```
1295
+ */
1296
+ object<Props extends UnknownShorthandCompoundProps>(key: string, props: Props, options?: ISheetObjectOptions): ISheetObject<Props>;
1297
+ /**
1298
+ * Detaches a previously created child object from the sheet.
1299
+ *
1300
+ * If you call `sheet.object(key)` again with the same `key`, the object's values of the object's
1301
+ * props WILL NOT be reset to their initial values.
1302
+ *
1303
+ * @param key - The `key` of the object previously given to `sheet.object(key, ...)`.
1304
+ */
1305
+ detachObject(key: string): void;
1306
+ /**
1307
+ * Returns all currently attached objects on this sheet.
1308
+ *
1309
+ * Use with {@link ISheet.detachObject} to detach individual objects.
1310
+ */
1311
+ getObjects(): ISheetObject[];
1312
+ /**
1313
+ * Unloads this sheet instance from memory: detaches all objects, pauses
1314
+ * sequences, and removes the sheet from the project.
1315
+ *
1316
+ * Runtime-only: persisted prop overrides and sequence data are kept. Calling
1317
+ * `project.sheet` again with the same id recreates the sheet.
1318
+ */
1319
+ unload(): void;
1320
+ /**
1321
+ * Declares an outline namespace folder in the Studio. The folder appears in
1322
+ * the outline panel even before any sheet objects are added under it.
1323
+ *
1324
+ * You can also use this to set the default collapsed state for a namespace
1325
+ * folder. The default only applies when the user has not manually expanded
1326
+ * or collapsed the folder yet.
1327
+ *
1328
+ * This method is part of `@unseenco/theatre-core` so you can configure outline folders
1329
+ * without importing `@unseenco/theatre-studio`.
1330
+ *
1331
+ * @param namespacePath - The namespace path, e.g. `"My Folder"` or `"My Folder / Subfolder"`
1332
+ * @param opts - Optional configuration for the namespace folder
1333
+ *
1334
+ * @example
1335
+ * ```ts
1336
+ * const sheet = project.sheet('Scene')
1337
+ *
1338
+ * // Create an empty folder ahead of time, collapsed by default
1339
+ * sheet.declareOutlineNamespace('Props', {collapsed: true})
1340
+ *
1341
+ * // Later, add objects under that folder
1342
+ * sheet.object('Props / Chair', {x: 0})
1343
+ * sheet.object('Props / Table', {x: 0})
1344
+ * ```
1345
+ */
1346
+ declareOutlineNamespace(namespacePath: string, opts?: {
1347
+ collapsed?: boolean;
1348
+ }): void;
1349
+ /**
1350
+ * Sets whether a namespace folder in the Studio outline panel is collapsed.
1351
+ *
1352
+ * Call this on load to force a folder closed every time your app starts.
1353
+ * Unlike `declareOutlineNamespace()`, this overrides any previous user
1354
+ * preference for the current session's initial render.
1355
+ *
1356
+ * @param namespacePath - The namespace path, e.g. `"My Folder"` or `"My Folder / Subfolder"`
1357
+ * @param collapsed - Whether the folder should be collapsed
1358
+ *
1359
+ * @example
1360
+ * ```ts
1361
+ * const sheet = project.sheet('Scene')
1362
+ *
1363
+ * // Force a folder closed every time your app loads
1364
+ * sheet.setOutlineNamespaceCollapsed('Props', true)
1365
+ * ```
1366
+ */
1367
+ setOutlineNamespaceCollapsed(namespacePath: string, collapsed: boolean): void;
1368
+ /**
1369
+ * The Sequence of this Sheet (uses the currently active sequence variant)
1370
+ */
1371
+ readonly sequence: ISequence;
1372
+ /**
1373
+ * Declares the sequence variants available on this sheet. Each variant has its own
1374
+ * independent sequence data, allowing the same properties to be animated differently
1375
+ * per variant (e.g. mobile vs desktop).
1376
+ *
1377
+ * The `"default"` variant is always required and is included automatically if omitted.
1378
+ *
1379
+ * @param variants - An array of variant names (each at least 3 characters long)
1380
+ *
1381
+ * @example
1382
+ * ```ts
1383
+ * const sheet = project.sheet('Scene')
1384
+ * sheet.declareSequenceVariants(['default', 'mobile', 'desktop'])
1385
+ * sheet.setActiveSequenceVariant('mobile')
1386
+ * ```
1387
+ */
1388
+ declareSequenceVariants(variants: SequenceVariantId[]): void;
1389
+ /**
1390
+ * Sets which sequence variant is currently active. The active variant determines
1391
+ * which sequence's keyframes are used when computing prop values, and which sequence
1392
+ * `sheet.sequence` refers to.
1393
+ */
1394
+ setActiveSequenceVariant(variant: SequenceVariantId): void;
1395
+ /**
1396
+ * Returns the currently active sequence variant name.
1397
+ */
1398
+ getActiveSequenceVariant(): SequenceVariantId;
1399
+ }
1400
+
1401
+ /**
1402
+ * A project's config object (currently the only point of configuration is the project's state)
1403
+ */
1404
+ type ISheetOptions = {
1405
+ /**
1406
+ * Whether the sheet appears in the Studio outline panel. Defaults to `true`.
1407
+ */
1408
+ visible?: boolean;
1409
+ };
1410
+ type IProjectConfig = {
1411
+ /**
1412
+ * The state of the project, as [exported](https://www.theatrejs.com/docs/latest/manual/projects#state) by the studio.
1413
+ */
1414
+ state?: $IntentionalAny;
1415
+ assets?: {
1416
+ baseUrl?: string;
1417
+ };
1418
+ };
1419
+ /**
1420
+ * A Theatre.js project
1421
+ */
1422
+ interface IProject {
1423
+ readonly type: 'Theatre_Project_PublicAPI';
1424
+ /**
1425
+ * If `@unseenco/theatre-studio` is used, this promise would resolve when studio has loaded
1426
+ * the state of the project into memory.
1427
+ *
1428
+ * If `@unseenco/theatre-studio` is not used, this promise is already resolved.
1429
+ */
1430
+ readonly ready: Promise<void>;
1431
+ /**
1432
+ * Shows whether the project is ready to be used.
1433
+ * Better to use {@link IProject.ready}, which is a promise that would
1434
+ * resolve when the project is ready.
1435
+ */
1436
+ readonly isReady: boolean;
1437
+ /**
1438
+ * The project's address
1439
+ */
1440
+ readonly address: ProjectAddress;
1441
+ /**
1442
+ * Creates a Sheet under the project
1443
+ * @param sheetId - Sheets are identified by their `sheetId`, which must be a string longer than 3 characters
1444
+ * @param instanceIdOrOpts - Optionally provide an `instanceId` if you want to create multiple instances of the same Sheet, or pass `{ visible: false }` to hide the sheet from the Studio outline panel
1445
+ * @param opts - Optionally provide `{ visible: false }` to hide the sheet from the Studio outline panel
1446
+ * @returns The newly created Sheet
1447
+ *
1448
+ * **Docs: https://www.theatrejs.com/docs/latest/manual/sheets**
1449
+ */
1450
+ sheet(sheetId: string, instanceIdOrOpts?: string | ISheetOptions): ISheet;
1451
+ sheet(sheetId: string, instanceId: string, opts?: ISheetOptions): ISheet;
1452
+ /**
1453
+ * Returns all currently loaded sheet instances under this project.
1454
+ *
1455
+ * Use with {@link ISheet.detachObject} or {@link ISheet.unload} to tear down
1456
+ * individual sheets/objects at runtime. Persisted project state is not cleared.
1457
+ */
1458
+ getSheets(): ISheet[];
1459
+ /**
1460
+ * Unloads one sheet and its attached objects from memory.
1461
+ *
1462
+ * Runtime-only: persisted prop overrides and sequence data are kept. Calling
1463
+ * {@link IProject.sheet} again with the same `sheetId` recreates the sheet.
1464
+ *
1465
+ * @param sheetId - The sheet id previously given to {@link IProject.sheet}
1466
+ * @param instanceId - If provided, only that instance is unloaded. If omitted,
1467
+ * all loaded instances of `sheetId` are unloaded.
1468
+ */
1469
+ unloadSheet(sheetId: string, instanceId?: string): void;
1470
+ /**
1471
+ * Unloads every currently loaded sheet and its objects from memory.
1472
+ *
1473
+ * Runtime-only: persisted project state is kept.
1474
+ */
1475
+ unloadSheets(): void;
1476
+ /**
1477
+ * Returns the URL for an asset.
1478
+ *
1479
+ * @param asset - The asset to get the URL for
1480
+ * @returns The URL for the asset, or `undefined` if the asset is not found
1481
+ */
1482
+ getAssetUrl(asset: Asset | File): string | undefined;
1483
+ }
1484
+
1485
+ type Notify = (
1486
+ /**
1487
+ * The title of the notification.
1488
+ */
1489
+ title: string,
1490
+ /**
1491
+ * The message of the notification.
1492
+ */
1493
+ message: string,
1494
+ /**
1495
+ * An array of doc pages to link to.
1496
+ */
1497
+ docs?: {
1498
+ url: string;
1499
+ title: string;
1500
+ }[],
1501
+ /**
1502
+ * Whether duplicate notifications should be allowed.
1503
+ */
1504
+ allowDuplicates?: boolean) => void;
1505
+ type Notifiers = {
1506
+ /**
1507
+ * Show a success notification.
1508
+ */
1509
+ success: Notify;
1510
+ /**
1511
+ * Show a warning notification.
1512
+ *
1513
+ * Say what happened in the title.
1514
+ * In the message, start with 1) a reassurance, then 2) explain why it happened, and 3) what the user can do about it.
1515
+ */
1516
+ warning: Notify;
1517
+ /**
1518
+ * Show an info notification.
1519
+ */
1520
+ info: Notify;
1521
+ /**
1522
+ * Show an error notification.
1523
+ */
1524
+ error: Notify;
1525
+ };
1526
+ declare const notify: Notifiers;
1527
+
1528
+ /**
1529
+ * Sets the `rafDriver` that Theatre's core uses internally to tick forward.
1530
+ *
1531
+ * Call this **before** any other `@unseenco/theatre-core` API that would trigger tick creation
1532
+ * (e.g. `onChange`, `sequence.play`, `val`). Calling it after the core ticker has
1533
+ * already been initialised will throw.
1534
+ *
1535
+ * This is the recommended way to drive Theatre from your own
1536
+ * `requestAnimationFrame` loop — for example when integrating with
1537
+ * `gsap`, `lenis`, or an XR session:
1538
+ *
1539
+ * ```ts
1540
+ * import { createRafDriver, setCoreRafDriver } from '@unseenco/theatre-core'
1541
+ *
1542
+ * const driver = createRafDriver({ name: 'MyRafDriver' })
1543
+ * setCoreRafDriver(driver)
1544
+ *
1545
+ * function myLoop(time: number) {
1546
+ * driver.tick(time)
1547
+ * requestAnimationFrame(myLoop)
1548
+ * }
1549
+ * requestAnimationFrame(myLoop)
1550
+ * ```
1551
+ *
1552
+ * Because you hold the `driver` reference you created, you do not need a separate
1553
+ * `getCoreRafDriver()` call — just keep the reference around and call
1554
+ * `driver.tick(time)` from your loop.
1555
+ */
1556
+ declare function setCoreRafDriver(driver: IRafDriver): void;
1557
+
1558
+ /**
1559
+ * A window is considered the "remote editor" for a project when its URL
1560
+ * contains the `editor` hash, e.g. `https://myapp.com/#editor`. Every other
1561
+ * window is a listener that mirrors whatever the editor window broadcasts.
1562
+ *
1563
+ * This convention is shared with `@unseenco/theatre-studio`'s "Open remote editor
1564
+ * window" toolbar button, which opens a popup at the current URL with this
1565
+ * hash set.
1566
+ */
1567
+ declare function isRemoteEditorWindow(): boolean;
1568
+
1569
+ /**
1570
+ * Returns a project of the given id, or creates one if it doesn't already exist.
1571
+ *
1572
+ * @remarks
1573
+ * If \@unseenco/theatre-studio is also loaded, then the state of the project will be managed by the studio.
1574
+ *
1575
+ * [Learn more about exporting](https://www.theatrejs.com/docs/latest/manual/projects#state)
1576
+ *
1577
+ * @example
1578
+ * Usage:
1579
+ * ```ts
1580
+ * import {getProject} from '@unseenco/theatre-core'
1581
+ * const config = {} // the config can be empty when starting a new project
1582
+ * const project = getProject("a-unique-id", config)
1583
+ * ```
1584
+ *
1585
+ * @example
1586
+ * Usage with an explicit state:
1587
+ * ```ts
1588
+ * import {getProject} from '@unseenco/theatre-core'
1589
+ * import state from './saved-state.json'
1590
+ * const config = {state} // here the config contains our saved state
1591
+ * const project = getProject("a-unique-id", config)
1592
+ * ```
1593
+ */
1594
+ declare function getProject(id: string, config?: IProjectConfig): IProject;
1595
+ /**
1596
+ * Calls `callback` every time the pointed value of `pointer` changes.
1597
+ *
1598
+ * @param pointer - A Pointer (like `object.props.x`)
1599
+ * @param callback - The callback is called every time the value of pointer changes
1600
+ * @param rafDriver - (optional) The `rafDriver` to use. Learn how to use `rafDriver`s [from the docs](https://www.theatrejs.com/docs/latest/manual/advanced#rafdrivers).
1601
+ * @returns An unsubscribe function
1602
+ *
1603
+ * @example
1604
+ * Usage:
1605
+ * ```ts
1606
+ * import {getProject, onChange} from '@unseenco/theatre-core'
1607
+ *
1608
+ * const obj = getProject("A project").sheet("Scene").object("Box", {position: {x: 0}})
1609
+ *
1610
+ * const usubscribe = onChange(obj.props.position.x, (x) => {
1611
+ * console.log('position.x changed to:', x)
1612
+ * })
1613
+ *
1614
+ * setTimeout(usubscribe, 10000) // stop listening to changes after 10 seconds
1615
+ * ```
1616
+ */
1617
+ declare function onChange<P extends PointerType<$IntentionalAny> | Prism<$IntentionalAny>>(pointer: P, callback: (value: P extends PointerType<infer T> ? T : P extends Prism<infer T> ? T : unknown) => void, rafDriver?: IRafDriver): VoidFn;
1618
+ /**
1619
+ * Takes a Pointer and returns the value it points to.
1620
+ *
1621
+ * @param pointer - A pointer (like `object.props.x`)
1622
+ * @returns The value the pointer points to
1623
+ *
1624
+ * @example
1625
+ *
1626
+ * Usage
1627
+ * ```ts
1628
+ * import {val, getProject} from '@unseenco/theatre-core'
1629
+ *
1630
+ * const obj = getProject("A project").sheet("Scene").object("Box", {position: {x: 0}})
1631
+ *
1632
+ * console.log(val(obj.props.position.x)) // logs the value of obj.props.x
1633
+ * ```
1634
+ */
1635
+ declare function val<T>(pointer: PointerType<T>): T;
8
1636
 
9
1637
  /**
10
1638
  * The library providing the runtime functionality of Theatre.js.
@@ -23,4 +1651,4 @@ import { OnDiskState } from './projects/store/storeTypes';
23
1651
  */
24
1652
  type __UNSTABLE_Project_OnDiskState = OnDiskState;
25
1653
 
26
- export { __UNSTABLE_Project_OnDiskState };
1654
+ export { IProject, IProjectConfig, IRafDriver, ISequence, ISheet, ISheetObject, ISheetObjectOptions, ISheetOptions, UnknownShorthandCompoundProps, __UNSTABLE_Project_OnDiskState, createRafDriver, getProject, isRemoteEditorWindow, notify, onChange, setCoreRafDriver, index_d as types, val };