### Execute Theatre.js Compatibility Test Workflow Source: https://github.com/theatre-js/theatre/blob/main/compat-tests/README.md This sequence of commands outlines the complete workflow for running Theatre.js compatibility tests. It starts by installing project fixtures using a local npm registry, followed by running the Jest-based compatibility tests. ```shell yarn run install-fixtures ``` ```shell $ npm install ``` ```shell $ yarn test:compat:run ``` -------------------------------- ### Initialize Theatre.js Studio, Project, and Object Source: https://github.com/theatre-js/theatre/blob/main/packages/browser-bundles/test.html This snippet illustrates the fundamental steps to get started with Theatre.js. It initializes the Theatre.js studio, retrieves a specific project and sheet by name, creates a new animatable object with initial properties, and then logs one of its property values to the console. This is a common starting point for animating elements with Theatre.js. ```JavaScript const {core} = Theatre const studio = Theatre.studio studio.initialize() const project = core.getProject('My project') const sheet = project.sheet('My sheet') const obj = sheet.object('Box', {x: 0, y: 0}) console.log(obj.value.x) ``` -------------------------------- ### Develop with Theatre.js Examples Source: https://github.com/theatre-js/theatre/blob/main/CONTRIBUTING.md Steps to build all Theatre.js packages from the monorepo root and then run specific examples, demonstrating usage with various build tools like Parcel and Create React App. ```sh $ yarn cli build ``` ```sh $ cd examples/dom-cra $ yarn start ``` -------------------------------- ### Install @theatre/dataverse and @theatre/react Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/README.md Instructions for installing the Dataverse library and its React bindings using npm. ```sh npm install @theatre/dataverse # and the react bindings npm install @theatre/react ``` -------------------------------- ### Set up Development Environment for Theatre.js Source: https://github.com/theatre-js/theatre/blob/main/CONTRIBUTING.md Instructions to prepare your local machine for Theatre.js development, including checking Node.js and Yarn versions, cloning the repository, and installing initial dependencies using Yarn workspaces. ```sh $ node -v > v14.0.0 ``` ```sh $ yarn -v > 1.22.10 ``` ```sh # for SSH: $ git clone git@github.com:/theatre.git # for HTTPS: $ git clone https://github.com//theatre.git $ cd theatre ``` ```sh $ yarn $ yarn postinstall ``` -------------------------------- ### Install @theatre/r3f and Dependencies Source: https://github.com/theatre-js/theatre/blob/main/packages/r3f/README.md Provides the necessary `yarn add` commands to set up a project with React, Three.js, React Three Fiber, Theatre.js core, Theatre.js Studio, and the `@theatre/r3f` extension. This ensures all required packages are installed for development. ```bash # r3f and its deps yarn add react yarn add three yarn add @react-three/fiber # Theatre.js yarn add @theatre/core yarn add @theatre/studio yarn add @theatre/r3f ``` -------------------------------- ### Install Theatric Library via npm Source: https://github.com/theatre-js/theatre/blob/main/packages/theatric/README.md This command demonstrates how to install the Theatric library as a project dependency using the npm package manager. It's the essential first step to integrate Theatric into any React application. ```bash $ npm install theatric ``` -------------------------------- ### Instantiating a Dataverse Atom Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/README.md Basic example of creating a new Atom instance with an initial state object, which can hold various data types. ```ts import {Atom} from '@theatre/dataverse' const atom = new Atom({intensity: 1, position: {x: 0, y: 0}}) ``` -------------------------------- ### Running Visual Regression Tests with Docker Source: https://github.com/theatre-js/theatre/blob/main/packages/playground/README.md This set of commands details how to run visual regression tests in a consistent Linux environment using Docker Compose, which helps mitigate cross-platform screenshot differences. It includes steps to start the Docker VM, establish an SSH session into the Node container, and execute the CI-specific test command. ```bash $ cd repo $ docker-compose up -d # start the linux vm $ docker-compose exec -it node bash # ssh into the vm $ cd app $ yarn $ yarn test:e2e:ci ``` -------------------------------- ### Prism Source Function API and Example Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/api/modules/prism.md The `prism.source()` function allows a prism to react to changes from an external data source. It takes a `subscribe` function to listen for changes and a `getValue` function to retrieve the current value. The example demonstrates how to create a prism that tracks the value of an HTML input element. ```APIDOC source: (subscribe: (fn: (val: V) => void) => VoidFn, getValue: () => V) => V Type declaration: (subscribe, getValue): V Type parameters: V Parameters: subscribe: (fn: (val: V) => void) => VoidFn The prism will call this function as soon as the prism goes hot. This function should return an unsubscribe function function which the prism will call when it goes cold. getValue: () => V A function that returns the current value of the external source. Returns: V The current value of the source ``` ```ts function prismFromInputElement(input: HTMLInputElement): Prism { function listen(cb: (value: string) => void) { const listener = () => { cb(input.value) } input.addEventListener('input', listener) return () => { input.removeEventListener('input', listener) } } function get() { return input.value } return prism(() => prism.source(listen, get)) } ``` -------------------------------- ### Basic React Application Setup with Theatric useControls Source: https://github.com/theatre-js/theatre/blob/main/packages/theatric/README.md This snippet illustrates the fundamental setup of a React application integrating Theatric's `useControls` hook. It shows how to render a root component and define simple controllable properties like 'name' and 'age' within a functional component. ```tsx // index.jsx ReactDOM.render(, document.getElementById('root')) // App.jsx import {useControls} from 'theatric' import React from 'react' export default function App() { const {name, age} = useControls({name: 'Andrew', age: 28}) return (
Hey, I'm {name} and I'm {age} years old.
) } ``` -------------------------------- ### Initialize and Use Ticker for Reactive Updates (TypeScript) Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/README.md Shows how to create a `Ticker` and use `onChange` to react to atom changes outside of React's render loop. This example also illustrates how updates are batched by the ticker, leading to a single log for multiple rapid changes. ```TypeScript import {Ticker, onChange} from '@theatre/dataverse' const ticker = new Ticker() // advance the ticker roughly 60 times per second (note that it's better to use requestAnimationFrame) setInterval(ticker.tick, 1000 / 60) onChange(atom.pointer.intensity, (newIntensity) => { console.log('intensity changed to', newIntensity) }) atom.setByPointer(atom.pointer.intensity, 3) // After a few milliseconds, logs 'intensity changed to 3' setTimeout(() => { atom.setByPointer(atom.pointer.intensity, 4) atom.setByPointer(atom.pointer.intensity, 5) // updates are batched because our ticker advances every 16ms, so we // will only get one log for 'intensity changed to 5', even though we changed the intensity twice }, 1000) ``` -------------------------------- ### Theatre.js Prism State Propagation in Topological Order Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/README.md Extends the previous example by adding a `double` prism dependent on `sum`, illustrating how state transitions (hottening) occur in topological order (from dependents to dependencies) and freshening happens in reverse order (from dependencies to dependents). This highlights the precise flow of state changes in complex graphs. ```ts // continued from the previous example const double = prism(() => val(sum) * 2) // Initially, all prisms are 🧊 cold // a | b | sum | double | // 🧊 | 🧊 | 🧊 | 🧊 | let unsub = double.onStale(() => {}) // here is how the state transitions will happen, step by step: // (step) | a | b | sum | double | // 1 | 🧊 | 🧊 | 🧊 | 🔥🪵 | // 2 | 🧊 | 🧊 | 🔥🪵 | 🔥🪵 | // 3 | 🔥🪵 | 🔥🪵 | 🔥🪵 | 🔥🪵 | val(double) // freshening happens in the reverse order // (step) | a | b | sum | double | // 0 | 🔥🪵 | 🔥🪵 | 🔥🪵 | 🔥🪵 | // --------------------------------------------------| // 1 ▲ ▼ | double reads the value of sum // └────◄────┘ | // --------------------------------------------------| // 2 ▲ ▲ ▼ | sum reads the value of a and b // │ │ │ | // └────◄───┴────◄─────┘ | // --------------------------------------------------| // 3 | 🔥🌲 | 🔥🌲 | 🔥🪵 | 🔥🪵 | a and b go fresh ``` -------------------------------- ### Subscribe to Atom State Changes by Pointer in TypeScript Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/api/classes/Atom.md Demonstrates how to subscribe to specific state changes within an `Atom` using `onChangeByPointer`. It illustrates how to get notified when a value at a given pointer changes, and how to trigger these changes using `setByPointer` and `set`. The example also shows how to unsubscribe from the listener. ```ts const a = atom({foo: 1}) const unsubscribe = a.onChangeByPointer(a.pointer.foo, (v) => { console.log('foo changed to', v) }) a.setByPointer(a.pointer.foo, 2) // logs 'foo changed to 2' a.set({foo: 3}) // logs 'foo changed to 3' unsubscribe() ``` -------------------------------- ### Create Prism from External Source with `prism.source()` (TypeScript) Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/README.md Demonstrates how to use `prism.source()` to create a prism that reads and reacts to changes from an external, non-atom/prism source, such as an HTML input element. It requires a `subscribe` function for reactivity and a `get` function for current value retrieval. ```TypeScript function prismFromInputElement(input: HTMLInputElement): Prism { function subscribe(cb: (value: string) => void) { const listener = () => { cb(input.value) } input.addEventListener('input', listener) return () => { input.removeEventListener('input', listener) } } function get() { return input.value } return prism(() => prism.source(subscribe, get)) } const p = prismFromInputElement(document.querySelector('input')) p.onChange(ticker, (value) => { console.log('input value changed to', value) }) ``` -------------------------------- ### Initialize Theatric UI and Load State Source: https://github.com/theatre-js/theatre/blob/main/packages/theatric/README.md This snippet demonstrates how to initialize the Theatric UI using the `initialize()` function. It shows loading a predefined UI state from a JSON file and integrating it into a React application. The example also highlights the use of `useControls` for defining interactive UI elements. ```tsx import {initialize, useControls, types, getAssetUrl} from 'theatric' import theatricState from './theatricState.json' initialize({ // use the state of the state.json file you exported from the UI state: theatricState, }).then(() => { // theatric is ready (although we don't have to wait for it unless we want to use assets) }) ReactDOM.render(, document.getElementById('root')) function App() { const {img} = useControls({ name: 'Andrew', age: types.number(28, { range: [0, 150], }), }) return (
Hey, I'm {name} and I'm {age} years old.
) } ``` -------------------------------- ### Prism State Hook API and Example Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/api/modules/prism.md The `prism.state()` function provides a state hook similar to React's `useState()`. It takes a unique key and an initial value, returning a tuple containing the current state and a setter function. The example illustrates how to use `prism.state` to track and update mouse position within a prism, leveraging `prism.effect` for side effects. ```APIDOC state: (key: string, initialValue: T) => [T, (val: T) => void] Type declaration: (key, initialValue): [T, (val: T) => void] Type parameters: T Parameters: key: string the key for the state initialValue: T the initial value Returns: [T, (val: T) => void] [currentState, setState] ``` ```ts import {prism} from 'dataverse' // This prism holds the current mouse position and updates when the mouse moves const mousePositionD = prism(() => { const [pos, setPos] = prism.state<[x: number, y: number]>('pos', [0, 0]) prism.effect( 'setupListeners', () => { const handleMouseMove = (e: MouseEvent) => { setPos([e.screenX, e.screenY]) } document.addEventListener('mousemove', handleMouseMove) return () => { document.removeEventListener('mousemove', handleMouseMove) } }, [], ) return pos }) ``` -------------------------------- ### Adding Button Controls to Theatric Panel with useControls Source: https://github.com/theatre-js/theatre/blob/main/packages/theatric/README.md This example illustrates how to integrate interactive buttons directly into the Theatric control panel using the `button` helper function. It demonstrates defining a button that triggers a custom action, such as incrementing an age value, by combining it with the `$get` and `$set` methods for imperative updates. ```tsx import {useControls, button} from 'theatric' function Introduction() { const {name, age, $get, $set} = useControls({ name: 'Andrew', age: 28, IncrementAge: button(() => { $set((values) => values.age, $get((values) => values.age) + 1) }) }) return (
Hey, I'm {name} and I'm {age} years old.
) } ``` -------------------------------- ### prism.memo Hook Documentation and Example Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/api/modules/prism.md Documents the `memo` hook, which provides memoization similar to React's `useMemo`. It caches function results based on a unique key and a dependency array, allowing for order-independent memoization within a prism. ```APIDOC memo: (key: string, fn: () => T, deps: undefined | any[] | readonly any[]) => T Description: `prism.memo()` works just like React's `useMemo()` hook. It's a way to cache the result of a function call. The only difference is that `prism.memo()` requires a key to be passed into it, whlie `useMemo()` doesn't. This means that we can call `prism.memo()` in any order, and we can call it multiple times with the same key. Type Parameters: T Parameters: key: string - The key for the memo. Should be unique inside of the prism fn: () => T - The function to memoize deps: undefined | any[] | readonly any[] - The dependency array. Provide `[]` if you want to the value to be memoized only once and never re-calculated. Returns: T - The result of the function call ``` ```TypeScript const pr = prism(() => { const memoizedReturnValueOfExpensiveFn = prism.memo("memo1", expensiveFn, []) }) ``` -------------------------------- ### Using useControls with Folder Option for UI Namespacing Source: https://github.com/theatre-js/theatre/blob/main/packages/theatric/README.md This example illustrates how to utilize the `folder` option with `useControls` to organize and namespace controls within the Theatric UI. This feature is particularly beneficial for preventing control collisions when multiple instances of the same component are present, by grouping their controls into distinct folders. ```tsx import {useControls} from 'theatric' function Introduction({id}) { const {name, age} = useControls({name: 'Andrew', age: 28}, {folder: id}) return (
Hey, I'm {name} and I'm {age} years old.
) } ``` -------------------------------- ### Reading Dataverse Atom State Non-Reactively Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/README.md Shows how to retrieve the current state of an Atom, either the whole state using `get()` or a specific property using `getByPointer()`, without reactive subscriptions. ```ts // get the whole state atom.get() // {intensity: 4, position: {x: 0, y: 0}} // or get a specific property using a pointer atom.getByPointer(atom.pointer.intensity) // 4 ``` -------------------------------- ### Optimizing Prism Recalculations with `prism.sub()` in Theatre.js Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/README.md `prism.sub()` creates a sub-prism within another, allowing for granular recalculation based on specific dependency changes. This is an optimization tool, equivalent to `prism.memo(key, () => prism(fn), deps).getValue()`, and supports nesting other prism hooks like `prism.memo()` internally. The example demonstrates how changing one dependency only triggers recalculation for its associated sub-prism. ```ts function factorial(num: number): number { if (num === 0) return 1 return num * factorial(num - 1) } const events: Array<'foo-calculated' | 'bar-calculated'> = [] // example: const state = new Atom({foo: 0, bar: 0}) const pr = prism(() => { const resultOfFoo = prism.sub( 'foo', () => { events.push('foo-calculated') const foo = val(state.pointer.foo) % 10 // Note how `prism.sub()` is more powerful than `prism.memo()` because it allows us to use `prism.memo()` and other hooks inside of it: return prism.memo('factorial', () => factorial(foo), [foo]) }, [], ) const resultOfBar = prism.sub( 'bar', () => { events.push('bar-calculated') const bar = val(state.pointer.bar) % 10 return prism.memo('factorial', () => factorial(bar), [bar]) }, [], ) return `result of foo is ${resultOfFoo}, result of bar is ${resultOfBar}` }) const unsub = pr.onChange(ticker, () => {}) // on the first run, both subs should be calculated: console.log(events) // ['foo-calculated', 'bar-calculated'] events.length = 0 // clear the events array // now if we change the value of `bar`, only `bar` should be recalculated: state.setByPointer(state.pointer.bar, 2) pr.getValue() console.log(events) // ['bar-calculated'] unsub() ``` -------------------------------- ### Initialize Theatre.js Core and Studio in Browser Source: https://github.com/theatre-js/theatre/blob/main/packages/browser-bundles/README.md This HTML snippet demonstrates how to include and initialize Theatre.js using its browser bundles. It shows how to load either `core-and-studio.js` or `core-only.min.js` and then access the `core` and `studio` objects from the global `Theatre` object. It also illustrates how to initialize the studio (if available) and begin working with projects and sheets. ```html ``` -------------------------------- ### API Documentation for PointerProxy Class Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/api/classes/PointerProxy.md Comprehensive API reference for the `PointerProxy` class, detailing its structure, constructor, properties, and methods. This includes type parameters, parameter definitions, return types, and implementation details. ```APIDOC Class: PointerProxy Description: Allows creating pointer-prisms where the pointer can be switched out. Type parameters: O: extends Object Implements: PointerToPrismProvider Constructors: constructor(currentPointer: Pointer) Type parameters: O: extends Object Parameters: currentPointer: Pointer Properties: pointer: Readonly Pointer Description: Convenience pointer pointing to the root of this PointerProxy. Methods: pointerToPrism

(pointer: Pointer

): Prism

Description: Returns a prism of the value at the provided sub-path of the proxied pointer. Type parameters: P Parameters: pointer: Pointer

Returns: Prism

Implementation of: PointerToPrismProvider.pointerToPrism setPointer(p: Pointer): void Description: Sets the underlying pointer. Parameters: p: Pointer - The pointer to be proxied. Returns: void ``` -------------------------------- ### Imperative Control with $get and $set Methods in Theatric Source: https://github.com/theatre-js/theatre/blob/main/packages/theatric/README.md This snippet demonstrates how to leverage the `$get` and `$set` methods returned by `useControls` for imperative manipulation of control values. It shows how to programmatically retrieve and update a control's value, enabling custom interactions like incrementing an age property via a button click. ```tsx import {useControls} from 'theatric' function Introduction() { const {name, age, $get, $set} = useControls({name: 'Andrew', age: 28}) const increaseAge = useCallback(() => { $set((values) => values.age, $get((values) => values.age) + 1) }, [$get, $set]) return (

Hey, I'm {name} and I'm {age} years old.
) } ``` -------------------------------- ### Create Editable React Three Fiber Scene with Theatre.js Source: https://github.com/theatre-js/theatre/blob/main/packages/r3f/README.md Demonstrates how to set up a basic React Three Fiber canvas using `@theatre/r3f`. It shows importing necessary components, initializing Theatre.js Studio, and marking 3D objects like `spotLight`, `pointLight`, and `mesh` as editable using `` within a ``. Properties defined in code serve as initial values for the editor. ```tsx import React from 'react'; import { Canvas } from 'react-three-fiber'; import {editable as e, SheetProvider, extension} from '@theatre/r3f'; import studio from '@theatre/studio'; studio.extend(extension) studio.initialize() export default function App() { return ( {/* Mark objects as editable. */} {/* Properties in the code are used as initial values and reset points in the editor. */} ); } ``` -------------------------------- ### Develop with Theatre.js Playground Package Source: https://github.com/theatre-js/theatre/blob/main/CONTRIBUTING.md Commands to navigate to and run the `playground` package, which is used for experimenting with Theatre.js features and running end-to-end tests. Includes a shortcut command for direct access from the root directory. ```sh $ cd ./packages/playground $ yarn serve $ yarn cli build ``` ```sh $ cd root $ yarn playground ``` -------------------------------- ### Prism Interface API Documentation Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/api/interfaces/Prism-1.md Detailed API documentation for the Prism interface, including its type parameters, properties, and methods, along with their descriptions, parameters, and return types. ```APIDOC Interface: Prism Description: Common interface for prisms. Type Parameters: V Properties: isHot: boolean Description: Whether the prism is hot. isPrism: true Description: Whether the object is a prism. Methods: getValue(): V Description: Gets the current value of the prism. If the value is stale, it causes the prism to freshen. keepHot(): VoidFn Description: Keep the prism hot, even if there are no tappers (subscribers). onChange(ticker: Ticker, listener: (v: V) => void, immediate?: boolean): VoidFn Description: Calls `listener` with a fresh value every time the prism _has_ a new value, throttled by Ticker. Parameters: ticker: Ticker listener: (v: V) => void immediate?: boolean onStale(cb: () => void): VoidFn Parameters: cb: () => void ``` -------------------------------- ### Build Theatre.js Packages Source: https://github.com/theatre-js/theatre/blob/main/CONTRIBUTING.md Command to build all packages within the Theatre.js project using the CLI build command. ```shell yarn cli build ``` -------------------------------- ### prism.ensurePrism Function Documentation and Example Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/api/modules/prism.md Documents the `ensurePrism` function, which validates if the current code execution is within a `prism()` call. It's useful for enforcing context-dependent logic and throws an error if called outside a prism. ```APIDOC ensurePrism: () => void Description: This is useful to make sure your code is running inside a `prism()` call. Returns: void ``` ```TypeScript import {prism} from '@theatre/dataverse' function onlyUsefulInAPrism() { prism.ensurePrism() } prism(() => { onlyUsefulInAPrism() // will run fine }) setTimeout(() => { onlyUsefulInAPrism() // throws an error console.log('This will never get logged') }, 0) ``` -------------------------------- ### Generating Playwright Tests with Codegen Source: https://github.com/theatre-js/theatre/blob/main/packages/playground/README.md This snippet outlines the two-step process for using Playwright's codegen tool to automatically generate test scripts for a Theatre.js playground. It instructs users to first serve the playground application and then run the codegen command, pointing it to the specific playground's URL. ```bash $ cd playground $ yarn serve # first serve the playground $ yarn playwright codegen http://localhost:8080/tests/[playground-name] # run the codegen for [playground-name] ``` -------------------------------- ### prism.ref Hook Documentation and Example Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/api/modules/prism.md Documents the `ref` hook, which creates a mutable reference object similar to React's `useRef`. It requires a unique key and an initial value, allowing for order-independent reference management within a prism. ```APIDOC ref: (key: string, initialValue: T) => IRef Description: Just like React's `useRef()`, `prism.ref()` allows us to create a prism that holds a reference to some value. The only difference is that `prism.ref()` requires a key to be passed into it, whlie `useRef()` doesn't. This means that we can call `prism.ref()` in any order, and we can call it multiple times with the same key. Type Parameters: T Parameters: key: string - The key for the ref. Should be unique inside of the prism. initialValue: T - The initial value for the ref. Returns: IRef - `{current: V}` - The ref object. Note that the ref object will always return its initial value if the prism is cold. It'll only record its current value if the prism is hot (and will forget again if the prism goes cold again). ``` ```TypeScript const pr = prism(() => { const ref1 = prism.ref("ref1", 0) console.log(ref1.current) // will print 0, and if the prism is hot, it'll print the current value ref1.current++ // changing the current value of the ref }) ``` -------------------------------- ### API Documentation for Ticker Class Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/api/classes/Ticker.md Detailed API reference for the Ticker class, including its constructor, properties, accessors, and methods for scheduling and managing callbacks per tick. ```APIDOC Class: Ticker Description: The Ticker class helps schedule callbacks. Scheduled callbacks are executed per tick. Ticks can be triggered by an external scheduling strategy, e.g. a raf. Constructors: new Ticker(_conf?) Parameters: _conf?: Object onActive?: () => void onDormant?: () => void Properties: __ticks: number = 0 Description: Counts up for every tick executed. Internally, this is used to measure ticks per second. This is "public" to TypeScript, because it's a tool for performance measurements. Consider this as experimental, and do not rely on it always being here in future releases. Accessors: dormant: boolean (get) Description: Whether the Ticker is dormant time: number (get) Description: The time at the start of the current tick if there is a tick in progress, otherwise defaults to performance.now(). Methods: offNextTick(fn: ICallback): void Description: De-registers a fn to be called on the next tick. Parameters: fn: ICallback (The function to be de-registered.) See: onNextTick offThisOrNextTick(fn: ICallback): void Description: De-registers a fn to be called either on this tick or the next tick. Parameters: fn: ICallback (The function to be de-registered.) See: onThisOrNextTick onNextTick(fn: ICallback): void Description: Registers a side effect to be called on the next tick. Parameters: fn: ICallback (The function to be registered.) See: onThisOrNextTick, offNextTick onThisOrNextTick(fn: ICallback): void Description: Registers for fn to be called either on this tick or the next tick. If onThisOrNextTick() is called while Ticker.tick() is running, the side effect _will_ be called within the running tick. If you don't want this behavior, you can use onNextTick(). Note that fn will be added to a Set(). Which means, if you call onThisOrNextTick(fn) with the same fn twice in a single tick, it'll only run once. Parameters: fn: ICallback (The function to be registered.) See: offThisOrNextTick tick(t?: number): void Description: Triggers a tick which starts executing the callbacks scheduled for this tick. Parameters: t?: number (The time at the tick.) See: onThisOrNextTick, onNextTick ``` -------------------------------- ### Running End-to-End Tests with Playwright Source: https://github.com/theatre-js/theatre/blob/main/packages/playground/README.md This section provides command-line instructions for executing Playwright end-to-end tests within the Theatre.js playground. It demonstrates how to run all tests, filter tests by a specific browser like Firefox, run tests in a visible (headed) browser mode, and activate Playwright's debug inspector for troubleshooting. ```bash $ cd playground $ yarn test # runs the end-to-end tests $ yarn test --project=firefox # only run the tests in firefox $ yarn test --project=firefox --headed # run the test in headed mode in firefox $ yarn test --debug # run in debug mode using the inspector: https://playwright.dev/docs/inspector ``` -------------------------------- ### Get Root Object and Path from Pointer Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/api/README.md Extracts the root object and the property path from a given `Pointer`. This function is useful for deconstructing a pointer into its fundamental components, allowing for programmatic access to the referenced data's origin and traversal path. ```APIDOC getPointerParts< _ >(p: Pointer< _ >): Object Description: Returns the root object and the path of the pointer. Type parameters: _ Parameters: p: Pointer< _ > (The pointer.) Returns: Object (An object with two properties: root-the root object or the pointer, and path-the path of the pointer. path is an array of the property-chain.) path: PathToProp root: {} Defined in: pointer.ts:136 ``` ```TypeScript const {root, path} = getPointerParts(pointer) ``` -------------------------------- ### Run Theatre.js Tests Source: https://github.com/theatre-js/theatre/blob/main/CONTRIBUTING.md Commands to execute tests for the Theatre.js project. The `--watch` flag enables continuous testing, re-running tests automatically on file changes. ```shell yarn test --watch ``` -------------------------------- ### Common Root Workspace Commands Source: https://github.com/theatre-js/theatre/blob/main/CONTRIBUTING.md A summary of frequently used commands that can be executed directly from the root directory of the Theatre.js monorepo for quick development and testing tasks. ```sh # Run the playground. It's a shortcut for `cd ./playground; yarn run serve` $ yarn playground ``` ```sh # Run all the tests. $ yarn test ``` -------------------------------- ### Define Advanced Theatric Controls with Types Source: https://github.com/theatre-js/theatre/blob/main/packages/theatric/README.md This example illustrates how to use Theatric's `types` export to define advanced properties for UI controls. Specifically, it shows how to apply `types.number` to set a numerical range and adjust scrubbing sensitivity for an age control within a React component. ```tsx import {useControls, types} from 'theatric' function Introduction() { const {name, age} = useControls({ name: 'Andrew', age: types.number(28, { // The range allowed in the UI (just a visual guide, not a validation rule) range: [0, 10], // Factor influencing the mouse-sensitivity when scrubbing the input nudgeMultiplier: 0.1, }), }) return (
Hey, I'm {name} and I'm {age} years old.
) } ``` -------------------------------- ### Allow All User Agents to Crawl Site Source: https://github.com/theatre-js/theatre/blob/main/examples/r3f-cra/public/robots.txt This robots.txt configuration grants full access to all web crawlers (user agents) to index the entire website. The `User-agent: *` directive applies the rule to all bots, and the empty `Disallow:` directive explicitly indicates no restrictions on any path. ```Plain Text User-agent: * Disallow: ``` -------------------------------- ### Demonstrating Theatre.js Prism onStale() and State Transitions Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/README.md Illustrates the state transitions of a single prism from cold to hot, stale, and fresh using `onStale()` and `val()` calls. It shows how reading a prism's value causes recalculation and freshness, while dependency changes lead to staleness, triggering the `onStale` callback. ```ts const atom = new Atom(0) const a = prism(() => val(atom.pointer)) // 🧊 // onStale(cb) calls `cb` when the prism goes from 🌲 to 🪵 a.onStale(() => { console.log('a is stale') }) // a from 🧊 to 🔥 // console: a is stale // reading the value of `a` will cause it to recalculate, and make it 🌲 fresh. console.log(val(a)) // 1 // a from 🔥🪵 to 🔥🌲 atom.set(1) // a from 🔥🌲 to 🔥🪵 // console: a is stale // reading the value of `a` will cause it to recalculate, and make it 🌲 fresh. console.log(val(a)) // 2 ``` -------------------------------- ### Setting Nested Properties with Pointers in useControls Source: https://github.com/theatre-js/theatre/blob/main/packages/theatric/README.md This snippet demonstrates how to modify nested properties within the control object using the `$get` and `$set` methods with pointers. It shows how to define a hierarchical structure for controls and then imperatively update a specific sub-property, like `person.age`, via a button action, leveraging Theatre.js pointers. ```tsx import {useControls, button} from 'theatric' function Introduction() { const {person, $get, $set} = useControls({ // note how name and age are sub-props of person person: { name: 'Andrew', age: 28 }, IncrementAge: button(() => { // values.person.age is a pointer to the age prop of the person object $set((values) => values.person.age, $get((values) => values.person.age) + 1) }) }) return (
Hey, I'm {person.name} and I'm {person.age} years old.
) } ``` -------------------------------- ### Run ESLint for Theatre.js Codebase Source: https://github.com/theatre-js/theatre/blob/main/CONTRIBUTING.md Commands to run ESLint for code quality and style checks across the Theatre.js repository. An option is available to automatically fix common linting issues. ```sh $ yarn lint:all ``` ```sh $ yarn lint:all --fix ``` -------------------------------- ### Atom Constructor Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/api/classes/Atom.md Initializes a new `Atom` instance with a given initial state. The `State` type parameter defines the structure of the state managed by the atom. ```APIDOC constructor(initialState: State) Type Parameters: - Name: State Parameters: - Name: initialState Type: State ``` -------------------------------- ### Managing Side Effects and State with prism.effect() and prism.state() in Theatre.js Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/README.md `prism.effect()` allows for running side effects within a prism, akin to React's `useEffect()`. Prisms are ideally pure, so effects should clean themselves up when the prism becomes inactive. `prism.state()` enables the creation of stateful values scoped to a prism, similar to React's `useState()`. This example demonstrates tracking mouse position using these hooks. ```tsx import {prism} from '@theatre/dataverse' import {useVal} from '@theatre/react' // This prism holds the current mouse position and updates when the mouse moves const mousePositionPr = prism(() => { const [pos, setPos] = prism.state<[x: number, y: number]>('pos', [0, 0]) prism.effect( 'setupListeners', () => { const handleMouseMove = (e: MouseEvent) => { setPos([e.screenX, e.screenY]) } document.addEventListener('mousemove', handleMouseMove) return () => { document.removeEventListener('mousemove', handleMouseMove) } }, [], ) return pos }) function Component() { const [x, y] = useVal(mousePositionPr) return (
Mouse position: {x}, {y}
) } ``` -------------------------------- ### Prism Namespace Overview Source: https://github.com/theatre-js/theatre/blob/main/packages/dataverse/api/modules/prism.md Defines the core functionality of the `prism` namespace, which creates reactive contexts where functions rerun automatically when their dependencies (other prisms) change. ```APIDOC Namespace: prism Description: Creates a prism from the passed function that adds all prisms referenced in it as dependencies, and reruns the function when these change. Param: The function to rerun when the prisms referenced in it change. ``` -------------------------------- ### Publish Theatre.js Packages to npm Source: https://github.com/theatre-js/theatre/blob/main/CONTRIBUTING.md Commands to publish Theatre.js packages to npm, allowing specification of version numbers (e.g., major.minor.patch) and tags (e.g., 'dev', 'rc') for different release types. ```sh $ yarn cli release x.y.z # npm publish version x.y.z $ yarn cli release x.y.z-dev.w # npm publish version x.y.z-dev.w and tag it as "dev" $ yarn cli release x.y.z-rc.w # npm publish version x.y.z-rc.w and tag it as "rc" ``` -------------------------------- ### Creating Reactive Prisms with usePrism React Hook Source: https://github.com/theatre-js/theatre/blob/main/packages/react/README.md The `usePrism` React hook creates a new reactive prism from a provided function (`fn`) and subscribes the component to its value. The function runs within a prism context, allowing access to prism-specific hooks like `prism.memo()` and `prism.effect()`. Similar to `useMemo`, it requires a `deps` array to re-evaluate the prism when dependencies change. ```tsx import {Atom, val, prism} from '@theatre/dataverse' import {usePrism} from '@theatre/react' const state = new Atom({a: 1, b: 1}) function Component(props: {which: 'a' | 'b'}) { const value = usePrism( () => { prism.isPrism() // true // note that this function is running inside a prism, so all of prism's // hooks (prism.memo(), prism.effect(), etc) are available const num = val(props.which === 'a' ? state.pointer.a : state.pointer.b) return doExpensiveComputation(num) }, // since our prism reads `props.which`, we should include it in the deps array [props.which], ) return
{value}
} ```