Skip to content

Commit

Permalink
fix: get more specific with Instance types
Browse files Browse the repository at this point in the history
  • Loading branch information
trezy committed Jun 15, 2024
1 parent f648739 commit 27c099b
Show file tree
Hide file tree
Showing 13 changed files with 50 additions and 33 deletions.
1 change: 0 additions & 1 deletion src/helpers/appendChild.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { log } from './log.js';

/** @typedef {import('pixi.js').Container} Container */
/** @typedef {import('../typedefs/Instance.js').Instance} Instance */

/**
Expand Down
23 changes: 16 additions & 7 deletions src/helpers/applyProps.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ const DEFAULTS_CONTAINERS = new Map();
*/
export function applyProps(instance, data)
{
const localState = instance.__reactpixi;
const localState = instance.__pixireact;
const {
__reactpixi,
__pixireact,
...instanceProps
} = instance;

Expand All @@ -38,10 +38,13 @@ export function applyProps(instance, data)
{
const change = changes[changeIndex];

let key = change[0];
/** @type {keyof Instance} */
let key = /** @type {*} */ (change[0]);
let value = change[1];
const isEvent = change[2];
const keys = change[3];

/** @type {(keyof Instance)[]} */
const keys = /** @type {*} */ (change[3]);

/** @type {Instance} */
let currentInstance = /** @type {*} */ (instance);
Expand All @@ -55,8 +58,7 @@ export function applyProps(instance, data)
// Resolve dashed props
if (keys.length)
{
targetProp = keys.reduce((accumulator, key) =>
accumulator[key], currentInstance);
targetProp = keys.reduce((accumulator, key) => accumulator[key], currentInstance);

// If the target is atomic, it forces us to switch the root
if (!(targetProp && targetProp.set))
Expand Down Expand Up @@ -121,7 +123,14 @@ export function applyProps(instance, data)
}
else
{
currentInstance[key] = value;
const prototype = Object.getPrototypeOf(currentInstance);
const propertyDescriptor = Object.getOwnPropertyDescriptor(prototype, key);

if (typeof propertyDescriptor === 'undefined' || propertyDescriptor.set)
{
// @ts-expect-error The key is cast to any property of Container, including read-only properties. The check above prevents us from setting read-only properties, but TS doesn't understand it. 🤷🏻‍♂️
currentInstance[key] = value;
}
}

changeIndex += 1;
Expand Down
1 change: 0 additions & 1 deletion src/helpers/createInstance.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ export function createInstance(type, props, root)
} = props;

const instance = prepareInstance(new PixiComponent(pixiProps), {
children,
root,
type,
});
Expand Down
11 changes: 3 additions & 8 deletions src/helpers/insertBefore.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { invariant } from './invariant.js';
import { log } from './log.js';

/** @typedef {import('pixi.js').Container} Container */
/** @typedef {import('../typedefs/Instance.js').Instance} Instance */

/**
Expand All @@ -15,16 +14,12 @@ export function insertBefore(parentInstance, childInstance, beforeChildInstance)

invariant(childInstance === beforeChildInstance, 'Cannot insert node before itself');

const { component: parentComponent } = parentInstance;
const { component: childComponent } = childInstance;
const { component: beforeChildComponent } = beforeChildInstance;

if (parentComponent.children.indexOf(childComponent) === -1)
if (parentInstance.children.indexOf(childInstance) === -1)
{
parentInstance.removeChild(childInstance);
}

const index = parentComponent.getChildIndex(beforeChildComponent);
const index = parentInstance.getChildIndex(beforeChildInstance);

parentInstance.addChild(childInstance, index);
parentInstance.addChildAt(childInstance, index);
}
11 changes: 5 additions & 6 deletions src/helpers/prepareInstance.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
/** @typedef {import('pixi.js').Container} Container */

/** @typedef {import('../typedefs/ContainerElement.js').ContainerElement} ContainerElement */
/** @typedef {import('../typedefs/Instance.js').Instance} Instance */
/** @typedef {import('../typedefs/InstanceState.js').InstanceState} InstanceState */

/**
* Create the instance with the provided sate and attach the component to it.
*
* @template {Container} T
* @template {ContainerElement} T
* @param {T} component
* @param {Partial<Instance>} [state]
* @param {Partial<InstanceState>} [state]
*/
export function prepareInstance(component, state = {})
{
/** @type {Instance} */
const instance = /** @type {*} */ (component);

instance.__reactpixi = {
children: undefined,
instance.__pixireact = {
eventCount: 0,
handlers: {},
parent: null,
Expand Down
1 change: 0 additions & 1 deletion src/helpers/removeChild.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { log } from './log.js';

/** @typedef {import('pixi.js').Container} Container */
/** @typedef {import('../typedefs/Instance.js').Instance} Instance */

/**
Expand Down
7 changes: 5 additions & 2 deletions src/helpers/switchInstance.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { createInstance } from './createInstance.js';
import { removeChild } from './removeChild.js';

/** @typedef {import('../typedefs/HostConfig.js').HostConfig} HostConfig */
/** @typedef {import('../typedefs/Instance.js').Instance} Instance */

/**
* @param {HostConfig['instance']} instance
Expand All @@ -18,14 +19,16 @@ export function switchInstance(
fiber,
)
{
const parent = instance.parent;
const parent = instance.__pixireact?.parent;

if (!parent)
{
return;
}

const newInstance = createInstance(type, newProps, instance.root);
/** @type {Instance} */
const root = /** @type {*} */ (instance.__pixireact?.root);
const newInstance = createInstance(type, newProps, root);

if (!instance.autoRemovedBeforeAppend)
{
Expand Down
3 changes: 2 additions & 1 deletion src/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ const context = createContext(null);
const roots = new Map();

/** @typedef {import('pixi.js').ApplicationOptions} ApplicationOptions */
/** @typedef {Partial<import('react').PropsWithChildren<ApplicationOptions>>} RenderProps */
/** @typedef {import('react').PropsWithChildren} PropsWithChildren */
/** @typedef {Partial<PropsWithChildren & ApplicationOptions>} RenderProps */

/**
* This renders an element to a canvas, creates a renderer, scene, etc.
Expand Down
5 changes: 5 additions & 0 deletions src/typedefs/ContainerElement.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @typedef {import('pixi.js').Container} Container */
/** @typedef {import('react').ReactElement} ReactElement */

/** @typedef {Container & ReactElement} ContainerElement */
export const ContainerElement = {};
8 changes: 5 additions & 3 deletions src/typedefs/Instance.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
/** @typedef {import('pixi.js').Container} Container */

/** @typedef {import('./ContainerElement.js').ContainerElement} ContainerElement */
/** @typedef {import('./EventHandlers.js').EventHandlers} EventHandlers */
/** @typedef {import('./InstanceState.js').InstanceState} InstanceState */

/**
* @typedef {object} BaseInstance
* @property {InstanceState} [__pixireact]
* @property {boolean} [autoRemovedBeforeAppend]
* @property {ContainerElement | ContainerElement[]} [children]
* @property {(...args: any[]) => any} [draw]
*/

/** @typedef {{ [key: string]: any } & Container & BaseInstance} Instance */
/** @typedef {ContainerElement & BaseInstance} Instance */

export const Instance = {};
2 changes: 0 additions & 2 deletions src/typedefs/InstanceState.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
/** @typedef {import('pixi.js').Container} Container */

/** @typedef {import('./EventHandlers.js').EventHandlers} EventHandlers */
/** @typedef {import('./Instance.js').Instance} Instance */

Expand Down
3 changes: 2 additions & 1 deletion src/typedefs/MaybeInstance.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/** @typedef {import('./Instance.js').Instance} Instance */
/** @typedef {import('./InstanceState.js').InstanceState} InstanceState */

/** @typedef {Omit<Instance, '__pixireact'> & object} MaybeInstance */
/** @typedef {import('./PartialBy.js').PartialBy<Instance, '__pixireact'>} MaybeInstance */
export const MaybeInstance = {};
7 changes: 7 additions & 0 deletions src/typedefs/PartialBy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* @template T
* @template {keyof T} K
* @typedef {Omit<T, K> & Partial<Pick<T, K>>} PartialBy
* @see https://stackoverflow.com/a/54178819
*/
export const PartialBy = {};

0 comments on commit 27c099b

Please sign in to comment.