@energy8platform/game-engine 0.7.1 → 0.9.0

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.
@@ -25,17 +25,22 @@ interface SceneManagerEvents {
25
25
  * ```
26
26
  */
27
27
  export class SceneManager extends EventEmitter<SceneManagerEvents> {
28
+ private static MAX_TRANSITION_DEPTH = 10;
29
+
28
30
  /** Root container that scenes are added to */
29
31
  public root!: Container;
30
32
 
31
33
  private registry = new Map<string, SceneConstructor>();
32
34
  private stack: SceneEntry[] = [];
33
- private _transitioning = false;
35
+ private _transitionDepth = 0;
34
36
 
35
37
  /** Current viewport dimensions — set by ViewportManager */
36
38
  private _width = 0;
37
39
  private _height = 0;
38
40
 
41
+ /** @internal GameApplication reference — passed to scenes */
42
+ private _app: any;
43
+
39
44
  constructor(root?: Container) {
40
45
  super();
41
46
  if (root) this.root = root;
@@ -46,6 +51,11 @@ export class SceneManager extends EventEmitter<SceneManagerEvents> {
46
51
  this.root = root;
47
52
  }
48
53
 
54
+ /** @internal Set the app reference (called by GameApplication) */
55
+ setApp(app: any): void {
56
+ this._app = app;
57
+ }
58
+
49
59
  /** Register a scene class by key */
50
60
  register(key: string, ctor: SceneConstructor): this {
51
61
  this.registry.set(key, ctor);
@@ -64,7 +74,7 @@ export class SceneManager extends EventEmitter<SceneManagerEvents> {
64
74
 
65
75
  /** Whether a scene transition is in progress */
66
76
  get isTransitioning(): boolean {
67
- return this._transitioning;
77
+ return this._transitionDepth > 0;
68
78
  }
69
79
 
70
80
  /**
@@ -75,6 +85,9 @@ export class SceneManager extends EventEmitter<SceneManagerEvents> {
75
85
  data?: unknown,
76
86
  transition?: TransitionConfig,
77
87
  ): Promise<void> {
88
+ if (this._transitionDepth >= SceneManager.MAX_TRANSITION_DEPTH) {
89
+ throw new Error('[SceneManager] Max transition depth exceeded — possible infinite loop');
90
+ }
78
91
  const prevKey = this.currentKey;
79
92
 
80
93
  // Exit all current scenes
@@ -96,6 +109,9 @@ export class SceneManager extends EventEmitter<SceneManagerEvents> {
96
109
  data?: unknown,
97
110
  transition?: TransitionConfig,
98
111
  ): Promise<void> {
112
+ if (this._transitionDepth >= SceneManager.MAX_TRANSITION_DEPTH) {
113
+ throw new Error('[SceneManager] Max transition depth exceeded — possible infinite loop');
114
+ }
99
115
  const prevKey = this.currentKey;
100
116
  await this.pushInternal(key, data, transition);
101
117
  this.emit('change', { from: prevKey, to: key });
@@ -109,6 +125,9 @@ export class SceneManager extends EventEmitter<SceneManagerEvents> {
109
125
  console.warn('[SceneManager] Cannot pop the last scene');
110
126
  return;
111
127
  }
128
+ if (this._transitionDepth >= SceneManager.MAX_TRANSITION_DEPTH) {
129
+ throw new Error('[SceneManager] Max transition depth exceeded — possible infinite loop');
130
+ }
112
131
  const prevKey = this.currentKey;
113
132
  await this.popInternal(true, transition);
114
133
  this.emit('change', { from: prevKey, to: this.currentKey! });
@@ -122,6 +141,9 @@ export class SceneManager extends EventEmitter<SceneManagerEvents> {
122
141
  data?: unknown,
123
142
  transition?: TransitionConfig,
124
143
  ): Promise<void> {
144
+ if (this._transitionDepth >= SceneManager.MAX_TRANSITION_DEPTH) {
145
+ throw new Error('[SceneManager] Max transition depth exceeded — possible infinite loop');
146
+ }
125
147
  const prevKey = this.currentKey;
126
148
  await this.popInternal(false);
127
149
  await this.pushInternal(key, data, transition);
@@ -169,7 +191,11 @@ export class SceneManager extends EventEmitter<SceneManagerEvents> {
169
191
  if (!Ctor) {
170
192
  throw new Error(`[SceneManager] Scene "${key}" is not registered`);
171
193
  }
172
- return new Ctor();
194
+ const scene = new Ctor();
195
+ if (this._app) {
196
+ scene.__engineApp = this._app;
197
+ }
198
+ return scene;
173
199
  }
174
200
 
175
201
  private async pushInternal(
@@ -177,7 +203,7 @@ export class SceneManager extends EventEmitter<SceneManagerEvents> {
177
203
  data?: unknown,
178
204
  transition?: TransitionConfig,
179
205
  ): Promise<void> {
180
- this._transitioning = true;
206
+ this._transitionDepth++;
181
207
 
182
208
  const scene = this.createScene(key);
183
209
  this.root.addChild(scene.container);
@@ -195,7 +221,7 @@ export class SceneManager extends EventEmitter<SceneManagerEvents> {
195
221
 
196
222
  await scene.onEnter?.(data);
197
223
 
198
- this._transitioning = false;
224
+ this._transitionDepth--;
199
225
  }
200
226
 
201
227
  private async popInternal(
@@ -205,7 +231,7 @@ export class SceneManager extends EventEmitter<SceneManagerEvents> {
205
231
  const entry = this.stack.pop();
206
232
  if (!entry) return;
207
233
 
208
- this._transitioning = true;
234
+ this._transitionDepth++;
209
235
 
210
236
  await entry.scene.onExit?.();
211
237
 
@@ -216,7 +242,7 @@ export class SceneManager extends EventEmitter<SceneManagerEvents> {
216
242
  entry.scene.onDestroy?.();
217
243
  entry.scene.container.destroy({ children: true });
218
244
 
219
- this._transitioning = false;
245
+ this._transitionDepth--;
220
246
  }
221
247
 
222
248
  private async transitionIn(
@@ -0,0 +1,26 @@
1
+ import { createContext, useContext } from 'react';
2
+ import type { GameApplication } from '../core/GameApplication';
3
+ import type { AudioManager } from '../audio/AudioManager';
4
+ import type { InputManager } from '../input/InputManager';
5
+ import type { ViewportManager } from '../viewport/ViewportManager';
6
+ import type { CasinoGameSDK } from '@energy8platform/game-sdk';
7
+ import type { GameConfigData } from '@energy8platform/game-sdk';
8
+
9
+ export interface EngineContextValue {
10
+ app: GameApplication;
11
+ sdk: CasinoGameSDK | null;
12
+ audio: AudioManager;
13
+ input: InputManager;
14
+ viewport: ViewportManager;
15
+ gameConfig: GameConfigData | null;
16
+ screen: { width: number; height: number; scale: number };
17
+ isPortrait: boolean;
18
+ }
19
+
20
+ export const EngineContext = createContext<EngineContextValue | null>(null);
21
+
22
+ export function useEngine(): EngineContextValue {
23
+ const ctx = useContext(EngineContext);
24
+ if (!ctx) throw new Error('useEngine() must be used inside a ReactScene');
25
+ return ctx;
26
+ }
@@ -0,0 +1,88 @@
1
+ import { createElement } from 'react';
2
+ import type { ReactElement } from 'react';
3
+ import { Scene } from '../core/Scene';
4
+ import { createPixiRoot } from './createPixiRoot';
5
+ import type { PixiRoot } from './createPixiRoot';
6
+ import { EngineContext } from './EngineContext';
7
+ import type { EngineContextValue } from './EngineContext';
8
+ import type { GameApplication } from '../core/GameApplication';
9
+ import { Orientation } from '../types';
10
+
11
+ export abstract class ReactScene extends Scene {
12
+ private _pixiRoot: PixiRoot | null = null;
13
+ private _contextValue: EngineContextValue | null = null;
14
+
15
+ /** Subclasses implement this to return their React element tree. */
16
+ abstract render(): ReactElement;
17
+
18
+ /** Access the GameApplication instance. */
19
+ protected getApp(): GameApplication {
20
+ const app = (this as any).__engineApp;
21
+ if (!app) {
22
+ throw new Error(
23
+ '[ReactScene] No GameApplication reference. ' +
24
+ 'Ensure this scene is managed by SceneManager (not instantiated manually).',
25
+ );
26
+ }
27
+ return app;
28
+ }
29
+
30
+ override async onEnter(data?: unknown): Promise<void> {
31
+ const app = this.getApp();
32
+
33
+ this._contextValue = {
34
+ app,
35
+ sdk: app.sdk,
36
+ audio: app.audio,
37
+ input: app.input,
38
+ viewport: app.viewport,
39
+ gameConfig: app.gameConfig,
40
+ screen: {
41
+ width: app.viewport.width,
42
+ height: app.viewport.height,
43
+ scale: app.viewport.scale,
44
+ },
45
+ isPortrait: app.viewport.orientation === Orientation.PORTRAIT,
46
+ };
47
+
48
+ this._pixiRoot = createPixiRoot(this.container);
49
+ this._mountReactTree();
50
+ }
51
+
52
+ override async onExit(): Promise<void> {
53
+ this._pixiRoot?.unmount();
54
+ this._pixiRoot = null;
55
+ this._contextValue = null;
56
+ }
57
+
58
+ override onResize(width: number, height: number): void {
59
+ if (!this._contextValue) return;
60
+ const app = this.getApp();
61
+
62
+ this._contextValue = {
63
+ ...this._contextValue,
64
+ screen: { width, height, scale: app.viewport.scale },
65
+ isPortrait: height > width,
66
+ };
67
+
68
+ this._mountReactTree();
69
+ }
70
+
71
+ override onDestroy(): void {
72
+ this._pixiRoot?.unmount();
73
+ this._pixiRoot = null;
74
+ this._contextValue = null;
75
+ }
76
+
77
+ private _mountReactTree(): void {
78
+ if (!this._pixiRoot || !this._contextValue) return;
79
+
80
+ this._pixiRoot.render(
81
+ createElement(
82
+ EngineContext.Provider,
83
+ { value: this._contextValue },
84
+ this.render(),
85
+ ),
86
+ );
87
+ }
88
+ }
@@ -0,0 +1,107 @@
1
+ const RESERVED = new Set(['children', 'key', 'ref']);
2
+
3
+ const REACT_TO_PIXI_EVENTS: Record<string, string> = {
4
+ onClick: 'onclick',
5
+ onPointerDown: 'onpointerdown',
6
+ onPointerUp: 'onpointerup',
7
+ onPointerMove: 'onpointermove',
8
+ onPointerOver: 'onpointerover',
9
+ onPointerOut: 'onpointerout',
10
+ onPointerEnter: 'onpointerenter',
11
+ onPointerLeave: 'onpointerleave',
12
+ onPointerCancel: 'onpointercancel',
13
+ onPointerTap: 'onpointertap',
14
+ onPointerUpOutside: 'onpointerupoutside',
15
+ onMouseDown: 'onmousedown',
16
+ onMouseUp: 'onmouseup',
17
+ onMouseMove: 'onmousemove',
18
+ onMouseOver: 'onmouseover',
19
+ onMouseOut: 'onmouseout',
20
+ onMouseEnter: 'onmouseenter',
21
+ onMouseLeave: 'onmouseleave',
22
+ onMouseUpOutside: 'onmouseupoutside',
23
+ onTouchStart: 'ontouchstart',
24
+ onTouchEnd: 'ontouchend',
25
+ onTouchMove: 'ontouchmove',
26
+ onTouchCancel: 'ontouchcancel',
27
+ onTouchEndOutside: 'ontouchendoutside',
28
+ onWheel: 'onwheel',
29
+ onRightClick: 'onrightclick',
30
+ onRightDown: 'onrightdown',
31
+ onRightUp: 'onrightup',
32
+ onRightUpOutside: 'onrightupoutside',
33
+ onTap: 'ontap',
34
+ onGlobalpointermove: 'onglobalpointermove',
35
+ onGlobalmousemove: 'onglobalmousemove',
36
+ onGlobaltouchmove: 'onglobaltouchmove',
37
+ };
38
+
39
+ export function isEventProp(key: string): boolean {
40
+ return key in REACT_TO_PIXI_EVENTS;
41
+ }
42
+
43
+ export function hasEventProps(props: Record<string, any>): boolean {
44
+ for (const key in props) {
45
+ if (isEventProp(key)) return true;
46
+ }
47
+ return false;
48
+ }
49
+
50
+ function setNestedValue(target: any, path: string[], value: any): void {
51
+ let obj = target;
52
+ for (let i = 0; i < path.length - 1; i++) {
53
+ obj = obj[path[i]];
54
+ if (obj == null) return;
55
+ }
56
+ obj[path[path.length - 1]] = value;
57
+ }
58
+
59
+ export function applyProps(
60
+ instance: any,
61
+ newProps: Record<string, any>,
62
+ oldProps: Record<string, any> = {},
63
+ ): void {
64
+ // Remove old props not in newProps
65
+ for (const key in oldProps) {
66
+ if (RESERVED.has(key) || key in newProps) continue;
67
+
68
+ const pixiEvent = REACT_TO_PIXI_EVENTS[key];
69
+ if (pixiEvent) {
70
+ instance[pixiEvent] = null;
71
+ } else if (key === 'draw') {
72
+ // no-op: can't un-draw
73
+ } else if (key.includes('-')) {
74
+ // Nested property reset not trivially possible, skip
75
+ } else {
76
+ try {
77
+ instance[key] = undefined;
78
+ } catch {
79
+ // read-only or non-configurable
80
+ }
81
+ }
82
+ }
83
+
84
+ // Apply new props
85
+ for (const key in newProps) {
86
+ if (RESERVED.has(key)) continue;
87
+
88
+ const value = newProps[key];
89
+ const pixiEvent = REACT_TO_PIXI_EVENTS[key];
90
+
91
+ if (pixiEvent) {
92
+ instance[pixiEvent] = value;
93
+ } else if (key === 'draw' && typeof value === 'function') {
94
+ instance.clear?.();
95
+ value(instance);
96
+ } else if (key.includes('-')) {
97
+ const parts = key.split('-');
98
+ setNestedValue(instance, parts, value);
99
+ } else {
100
+ try {
101
+ instance[key] = value;
102
+ } catch {
103
+ // read-only property
104
+ }
105
+ }
106
+ }
107
+ }
@@ -0,0 +1,17 @@
1
+ /** Mutable catalogue: PascalCase name -> PixiJS constructor */
2
+ export const catalogue: Record<string, any> = {};
3
+
4
+ /**
5
+ * Register PixiJS classes for use as JSX elements.
6
+ * Keys must be PascalCase; JSX uses the camelCase equivalent.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { Container, Sprite, Text } from 'pixi.js';
11
+ * extend({ Container, Sprite, Text });
12
+ * // Now <container>, <sprite>, <text> work in JSX
13
+ * ```
14
+ */
15
+ export function extend(components: Record<string, any>): void {
16
+ Object.assign(catalogue, components);
17
+ }
@@ -0,0 +1,31 @@
1
+ import { ConcurrentRoot } from 'react-reconciler/constants';
2
+ import type { Container } from 'pixi.js';
3
+ import type { ReactElement } from 'react';
4
+ import { reconciler } from './reconciler';
5
+
6
+ export interface PixiRoot {
7
+ render(element: ReactElement): void;
8
+ unmount(): void;
9
+ }
10
+
11
+ export function createPixiRoot(container: Container): PixiRoot {
12
+ const fiberRoot = reconciler.createContainer(
13
+ container, // containerInfo
14
+ ConcurrentRoot, // tag
15
+ null, // hydrationCallbacks
16
+ false, // isStrictMode
17
+ null, // concurrentUpdatesByDefaultOverride
18
+ '', // identifierPrefix
19
+ (err: Error) => console.error('[PixiRoot]', err),
20
+ null, // transitionCallbacks
21
+ );
22
+
23
+ return {
24
+ render(element: ReactElement) {
25
+ reconciler.updateContainer(element, fiberRoot, null, () => {});
26
+ },
27
+ unmount() {
28
+ reconciler.updateContainer(null, fiberRoot, null, () => {});
29
+ },
30
+ };
31
+ }
@@ -0,0 +1,51 @@
1
+ import {
2
+ Container,
3
+ Sprite,
4
+ Graphics,
5
+ Text,
6
+ AnimatedSprite,
7
+ NineSliceSprite,
8
+ TilingSprite,
9
+ Mesh,
10
+ MeshPlane,
11
+ MeshRope,
12
+ MeshSimple,
13
+ BitmapText,
14
+ HTMLText,
15
+ } from 'pixi.js';
16
+ import { extend } from './catalogue';
17
+
18
+ /**
19
+ * Register all standard PixiJS display objects for JSX use.
20
+ * Call once at app startup before rendering any React scenes.
21
+ */
22
+ export function extendPixiElements(): void {
23
+ extend({
24
+ Container,
25
+ Sprite,
26
+ Graphics,
27
+ Text,
28
+ AnimatedSprite,
29
+ NineSliceSprite,
30
+ TilingSprite,
31
+ Mesh,
32
+ MeshPlane,
33
+ MeshRope,
34
+ MeshSimple,
35
+ BitmapText,
36
+ HTMLText,
37
+ });
38
+ }
39
+
40
+ /**
41
+ * Register @pixi/layout components for JSX use.
42
+ * Pass the dynamically imported module:
43
+ *
44
+ * ```ts
45
+ * const layout = await import('@pixi/layout/components');
46
+ * extendLayoutElements(layout);
47
+ * ```
48
+ */
49
+ export function extendLayoutElements(layoutModule: Record<string, any>): void {
50
+ extend(layoutModule);
51
+ }
@@ -0,0 +1,46 @@
1
+ import { useState, useEffect } from 'react';
2
+ import { useEngine } from './EngineContext';
3
+ import type { CasinoGameSDK, SessionData, GameConfigData } from '@energy8platform/game-sdk';
4
+ import type { AudioManager } from '../audio/AudioManager';
5
+ import type { InputManager } from '../input/InputManager';
6
+
7
+ export function useSDK(): CasinoGameSDK | null {
8
+ return useEngine().sdk;
9
+ }
10
+
11
+ export function useAudio(): AudioManager {
12
+ return useEngine().audio;
13
+ }
14
+
15
+ export function useInput(): InputManager {
16
+ return useEngine().input;
17
+ }
18
+
19
+ export function useViewport(): { width: number; height: number; scale: number; isPortrait: boolean } {
20
+ const { screen, isPortrait } = useEngine();
21
+ return { ...screen, isPortrait };
22
+ }
23
+
24
+ export function useBalance(): number {
25
+ const { sdk } = useEngine();
26
+ const [balance, setBalance] = useState(sdk?.balance ?? 0);
27
+
28
+ useEffect(() => {
29
+ if (!sdk) return;
30
+ const handler = (data: { balance: number }) => setBalance(data.balance);
31
+ sdk.on('balanceUpdate', handler);
32
+ return () => {
33
+ sdk.off('balanceUpdate', handler);
34
+ };
35
+ }, [sdk]);
36
+
37
+ return balance;
38
+ }
39
+
40
+ export function useSession(): SessionData | null {
41
+ return useEngine().app.session;
42
+ }
43
+
44
+ export function useGameConfig<T = GameConfigData>(): T | null {
45
+ return useEngine().gameConfig as T | null;
46
+ }
@@ -0,0 +1,23 @@
1
+ // Core
2
+ export { createPixiRoot } from './createPixiRoot';
3
+ export type { PixiRoot } from './createPixiRoot';
4
+
5
+ // Catalogue
6
+ export { extend } from './catalogue';
7
+ export { extendPixiElements, extendLayoutElements } from './extendAll';
8
+
9
+ // Scene
10
+ export { ReactScene } from './ReactScene';
11
+
12
+ // Context & Hooks
13
+ export { EngineContext, useEngine } from './EngineContext';
14
+ export type { EngineContextValue } from './EngineContext';
15
+ export {
16
+ useSDK,
17
+ useAudio,
18
+ useInput,
19
+ useViewport,
20
+ useBalance,
21
+ useSession,
22
+ useGameConfig,
23
+ } from './hooks';
@@ -0,0 +1,169 @@
1
+ import Reconciler from 'react-reconciler';
2
+ import { DefaultEventPriority } from 'react-reconciler/constants';
3
+ import { Container } from 'pixi.js';
4
+ import { catalogue } from './catalogue';
5
+ import { applyProps, hasEventProps } from './applyProps';
6
+
7
+ function toPascalCase(str: string): string {
8
+ return str.charAt(0).toUpperCase() + str.slice(1);
9
+ }
10
+
11
+ const hostConfig: Reconciler.HostConfig<
12
+ string, // Type
13
+ Record<string, any>, // Props
14
+ Container, // Container
15
+ any, // Instance
16
+ any, // TextInstance
17
+ any, // SuspenseInstance
18
+ any, // HydratableInstance
19
+ any, // PublicInstance
20
+ any, // HostContext
21
+ any, // UpdatePayload
22
+ any, // ChildSet
23
+ any, // TimeoutHandle
24
+ any // NoTimeout
25
+ > = {
26
+ isPrimaryRenderer: false,
27
+ supportsMutation: true,
28
+ supportsPersistence: false,
29
+ supportsHydration: false,
30
+
31
+ createInstance(type, props) {
32
+ const name = toPascalCase(type);
33
+ const Ctor = catalogue[name];
34
+ if (!Ctor) {
35
+ throw new Error(
36
+ `[PixiReconciler] Unknown element "<${type}>". ` +
37
+ `Call extend({ ${name} }) before rendering.`,
38
+ );
39
+ }
40
+ const instance = new Ctor();
41
+ applyProps(instance, props);
42
+
43
+ // Enable interactivity if any event prop is present
44
+ if (hasEventProps(props) && instance.eventMode === 'auto') {
45
+ instance.eventMode = 'static';
46
+ }
47
+
48
+ return instance;
49
+ },
50
+
51
+ createTextInstance() {
52
+ throw new Error(
53
+ '[PixiReconciler] Text strings are not supported. Use a <text> element.',
54
+ );
55
+ },
56
+
57
+ appendInitialChild(parent, child) {
58
+ if (child instanceof Container) parent.addChild(child);
59
+ },
60
+
61
+ appendChild(parent, child) {
62
+ if (child instanceof Container) parent.addChild(child);
63
+ },
64
+
65
+ appendChildToContainer(container, child) {
66
+ if (child instanceof Container) container.addChild(child);
67
+ },
68
+
69
+ removeChild(parent, child) {
70
+ if (child instanceof Container) {
71
+ parent.removeChild(child);
72
+ child.destroy({ children: true });
73
+ }
74
+ },
75
+
76
+ removeChildFromContainer(container, child) {
77
+ if (child instanceof Container) {
78
+ container.removeChild(child);
79
+ child.destroy({ children: true });
80
+ }
81
+ },
82
+
83
+ insertBefore(parent, child, beforeChild) {
84
+ if (child instanceof Container && beforeChild instanceof Container) {
85
+ if (child.parent) child.parent.removeChild(child);
86
+ const index = parent.getChildIndex(beforeChild);
87
+ parent.addChildAt(child, index);
88
+ }
89
+ },
90
+
91
+ insertInContainerBefore(container, child, beforeChild) {
92
+ if (child instanceof Container && beforeChild instanceof Container) {
93
+ if (child.parent) child.parent.removeChild(child);
94
+ const index = container.getChildIndex(beforeChild);
95
+ container.addChildAt(child, index);
96
+ }
97
+ },
98
+
99
+ commitUpdate(instance, _updatePayload, _type, oldProps, newProps) {
100
+ applyProps(instance, newProps, oldProps);
101
+
102
+ if (hasEventProps(newProps) && instance.eventMode === 'auto') {
103
+ instance.eventMode = 'static';
104
+ }
105
+ },
106
+
107
+ finalizeInitialChildren() {
108
+ return false;
109
+ },
110
+
111
+ prepareUpdate() {
112
+ return true;
113
+ },
114
+
115
+ shouldSetTextContent() {
116
+ return false;
117
+ },
118
+
119
+ getRootHostContext() {
120
+ return null;
121
+ },
122
+
123
+ getChildHostContext(parentHostContext: any) {
124
+ return parentHostContext;
125
+ },
126
+
127
+ getPublicInstance(instance: any) {
128
+ return instance;
129
+ },
130
+
131
+ prepareForCommit() {
132
+ return null;
133
+ },
134
+
135
+ resetAfterCommit() {},
136
+
137
+ preparePortalMount() {},
138
+
139
+ scheduleTimeout: setTimeout,
140
+ cancelTimeout: clearTimeout,
141
+ noTimeout: -1,
142
+
143
+ getCurrentEventPriority() {
144
+ return DefaultEventPriority;
145
+ },
146
+
147
+ hideInstance(instance) {
148
+ instance.visible = false;
149
+ },
150
+
151
+ unhideInstance(instance) {
152
+ instance.visible = true;
153
+ },
154
+
155
+ hideTextInstance() {},
156
+ unhideTextInstance() {},
157
+
158
+ clearContainer() {},
159
+
160
+ detachDeletedInstance() {},
161
+
162
+ prepareScopeUpdate() {},
163
+ getInstanceFromNode() { return null; },
164
+ getInstanceFromScope() { return null; },
165
+ beforeActiveInstanceBlur() {},
166
+ afterActiveInstanceBlur() {},
167
+ };
168
+
169
+ export const reconciler = Reconciler(hostConfig);