@codexo/exojs-react 0.15.2 → 0.16.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.
package/README.md CHANGED
@@ -33,10 +33,7 @@ import { TitleScene, GameScene } from './scenes';
33
33
 
34
34
  function Game() {
35
35
  return (
36
- <ExoCanvas
37
- options={{ canvas: { width: 1280, height: 720 }, clearColor: someColor }}
38
- style={{ width: 1280, height: 720 }}
39
- >
36
+ <ExoCanvas options={{ canvas: { width: 1280, height: 720 }, clearColor: someColor }} style={{ width: 1280, height: 720 }}>
40
37
  <Scenes active="game" transition={{ type: 'fade', duration: 300 }}>
41
38
  <Scene name="title" component={TitleScene} />
42
39
  <Scene name="game" component={GameScene}>
@@ -70,17 +67,17 @@ function Game() {
70
67
 
71
68
  ## API
72
69
 
73
- | Export | Kind | Purpose |
74
- |---|---|---|
75
- | `ExoCanvas` | component | Batteries-included canvas host (wrapper div + canvas + context). Accepts `onReady`/`onError`. |
76
- | `useExoApplication(options?, onReady?, onError?)` | hook | Headless: owns the `Application`, returns `{ app, canvasRef }`. `onError` mirrors `Application.onError`. |
77
- | `useExoApp()` | hook | The `Application` from the nearest `<ExoCanvas>`/provider. Throws if absent. |
78
- | `useExoContext()` | hook | Like `useExoApp` but returns `Application \| null` (no throw). |
79
- | `ExoContext` | context | The underlying context (advanced / testing). |
80
- | `useScene(SceneClass, deps?)` | hook | Instantiate + activate a single scene; returns it once live. Load failures route to `app.onError`. |
81
- | `Scenes` / `Scene` | components | Declarative scene switch over the one-active-scene model. Load failures route to `app.onError`. |
82
- | `useActiveScene()` | hook | The active scene instance from the nearest `<Scenes>`. |
83
- | `useSignal(signal, getSnapshot)` | hook | Subscribes to an engine `Signal` and re-renders on every dispatch (e.g. `app.onFrame`). |
70
+ | Export | Kind | Purpose |
71
+ | ------------------------------------------------- | ---------- | -------------------------------------------------------------------------------------------------------- |
72
+ | `ExoCanvas` | component | Batteries-included canvas host (wrapper div + canvas + context). Accepts `onReady`/`onError`. |
73
+ | `useExoApplication(options?, onReady?, onError?)` | hook | Headless: owns the `Application`, returns `{ app, canvasRef }`. `onError` mirrors `Application.onError`. |
74
+ | `useExoApp()` | hook | The `Application` from the nearest `<ExoCanvas>`/provider. Throws if absent. |
75
+ | `useExoContext()` | hook | Like `useExoApp` but returns `Application \| null` (no throw). |
76
+ | `ExoContext` | context | The underlying context (advanced / testing). |
77
+ | `useScene(SceneClass, deps?)` | hook | Instantiate + activate a single scene; returns it once live. Load failures route to `app.onError`. |
78
+ | `Scenes` / `Scene` | components | Declarative scene switch over the one-active-scene model. Load failures route to `app.onError`. |
79
+ | `useActiveScene()` | hook | The active scene instance from the nearest `<Scenes>`. |
80
+ | `useSignal(signal, getSnapshot)` | hook | Subscribes to an engine `Signal` and re-renders on every dispatch (e.g. `app.onFrame`). |
84
81
 
85
82
  ### Reactivity model
86
83
 
@@ -89,12 +86,15 @@ render `backend` (WebGL2 ↔ WebGPU cannot be hot-swapped). Other supported opti
89
86
  are applied **live**:
90
87
 
91
88
  - `canvas.width` / `canvas.height` → `app.resize(...)`
92
- - `canvas.sizingMode` → `app.sizingMode`
93
89
  - `clearColor` → `app.clearColor`
94
90
 
95
91
  Options without a live setter (`canvas.pixelRatio`, `seed`, `extensions`, …) are
96
92
  captured at creation; change the `backend` or remount to apply them.
97
93
 
94
+ `canvas.sizing` is captured at creation as well: a sizing policy is an object, so
95
+ a fresh instance on every render would detach and re-attach the previous one each
96
+ time. Assign `app.sizing` yourself to switch strategies at runtime.
97
+
98
98
  ## License
99
99
 
100
100
  MIT © Codexo
@@ -4,22 +4,22 @@ import { type ExoApplicationOptions } from './useExoApplication';
4
4
  export interface ExoCanvasProps extends HTMLAttributes<HTMLDivElement> {
5
5
  /**
6
6
  * Options forwarded to the ExoJS {@link Application}. Pass
7
- * `canvas.width`/`height`/`sizingMode`/etc.; most options are captured at
8
- * creation, but `canvas.width`/`height`, `canvas.sizingMode` and `clearColor`
9
- * are applied live (see {@link useExoApplication}).
7
+ * `canvas.width`/`height`/`sizing`/etc.; most options are captured at
8
+ * creation, but `canvas.width`/`height` and `clearColor` are applied live
9
+ * (see {@link useExoApplication}).
10
10
  */
11
11
  options?: ExoApplicationOptions;
12
12
  /**
13
13
  * Called once each time the {@link Application} is (re)created. The backend
14
- * (WebGL2 / WebGPU) is not yet initialized at this point that happens when
14
+ * (WebGL2 / WebGPU) is not yet initialized at this point - that happens when
15
15
  * the first {@link import('./useScene').useScene} child calls `app.start()`.
16
16
  */
17
17
  onReady?: (app: Application) => void;
18
18
  /**
19
- * Called for every {@link Application.onError} dispatch async init or
19
+ * Called for every {@link Application.onError} dispatch - async init or
20
20
  * scene-load failures (including the ones surfaced by
21
21
  * {@link import('./useScene').useScene} and {@link import('./Scenes').Scenes}
22
- * descendants) while an Application exists.
22
+ * descendants) - while an Application exists.
23
23
  */
24
24
  onError?: (error: unknown) => void;
25
25
  /**
@@ -35,10 +35,10 @@ export interface ExoCanvasProps extends HTMLAttributes<HTMLDivElement> {
35
35
  * `position: relative`, absolutely-positioned `children` (HUD overlays,
36
36
  * {@link import('./Scenes').Scenes}) sit over the canvas out of the box.
37
37
  *
38
- * Layout props (`style`, `className`, ) apply to the **wrapper**; size it to
39
- * size the canvas in `'fill'`/`'letterbox'` modes. Use {@link canvasProps} to
40
- * style the canvas itself. For full control with no wrapper element, use the
41
- * headless {@link useExoApplication} hook directly.
38
+ * Layout props (`style`, `className`, ...) apply to the **wrapper**, which is
39
+ * the element a `canvas.sizing` policy measures - size it to size the canvas.
40
+ * Use {@link canvasProps} to style the canvas itself. For full control with no
41
+ * wrapper element, use the headless {@link useExoApplication} hook directly.
42
42
  *
43
43
  * @example
44
44
  * ```tsx
@@ -48,3 +48,4 @@ export interface ExoCanvasProps extends HTMLAttributes<HTMLDivElement> {
48
48
  * ```
49
49
  */
50
50
  export declare function ExoCanvas({ options, onReady, onError, canvasProps, children, style, ...divProps }: ExoCanvasProps): ReactElement;
51
+ //# sourceMappingURL=ExoCanvas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExoCanvas.d.ts","sourceRoot":"","sources":["../../src/ExoCanvas.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,KAAK,oBAAoB,EAAsB,KAAK,cAAc,EAAE,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAG9G,OAAO,EAAE,KAAK,qBAAqB,EAAqB,MAAM,qBAAqB,CAAC;AAKpF,MAAM,WAAW,cAAe,SAAQ,cAAc,CAAC,cAAc,CAAC;IACpE;;;;;OAKG;IACH,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAChC;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,CAAC;IACrC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC;;;OAGG;IACH,WAAW,CAAC,EAAE,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC,CAAC;CACzF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,SAAS,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAE,EAAE,cAAc,GAAG,YAAY,CAehI"}
@@ -1,36 +1,55 @@
1
- import { jsx, jsxs } from 'react/jsx-runtime';
2
- import 'react';
3
- import { ExoContext } from './ExoContext.js';
4
- import { useExoApplication } from './useExoApplication.js';
1
+ import { ExoContext } from "./ExoContext.js";
2
+ import { useExoApplication } from "./useExoApplication.js";
3
+ import "react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
5
 
6
+ //#region src/ExoCanvas.tsx
6
7
  /** Default canvas style: block layout avoids the inline-element baseline gap. */
7
- const defaultCanvasStyle = { display: 'block' };
8
+ const defaultCanvasStyle = { display: "block" };
8
9
  /**
9
- * Batteries-included canvas host. Renders a **positioned wrapper `<div>`**
10
- * containing a React-managed `<canvas>` bound to an ExoJS {@link Application},
11
- * and provides the app to descendant hooks via context. Because the wrapper is
12
- * `position: relative`, absolutely-positioned `children` (HUD overlays,
13
- * {@link import('./Scenes').Scenes}) sit over the canvas out of the box.
14
- *
15
- * Layout props (`style`, `className`, ) apply to the **wrapper**; size it to
16
- * size the canvas in `'fill'`/`'letterbox'` modes. Use {@link canvasProps} to
17
- * style the canvas itself. For full control with no wrapper element, use the
18
- * headless {@link useExoApplication} hook directly.
19
- *
20
- * @example
21
- * ```tsx
22
- * <ExoCanvas options={{ canvas: { width: 800, height: 600 } }} style={{ width: 800, height: 600 }}>
23
- * <Hud /> // absolutely-positioned overlay; works because the wrapper is relative
24
- * </ExoCanvas>
25
- * ```
26
- */
10
+ * Batteries-included canvas host. Renders a **positioned wrapper `<div>`**
11
+ * containing a React-managed `<canvas>` bound to an ExoJS {@link Application},
12
+ * and provides the app to descendant hooks via context. Because the wrapper is
13
+ * `position: relative`, absolutely-positioned `children` (HUD overlays,
14
+ * {@link import('./Scenes').Scenes}) sit over the canvas out of the box.
15
+ *
16
+ * Layout props (`style`, `className`, ...) apply to the **wrapper**, which is
17
+ * the element a `canvas.sizing` policy measures - size it to size the canvas.
18
+ * Use {@link canvasProps} to style the canvas itself. For full control with no
19
+ * wrapper element, use the headless {@link useExoApplication} hook directly.
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * <ExoCanvas options={{ canvas: { width: 800, height: 600 } }} style={{ width: 800, height: 600 }}>
24
+ * <Hud /> // absolutely-positioned overlay; works because the wrapper is relative
25
+ * </ExoCanvas>
26
+ * ```
27
+ */
27
28
  function ExoCanvas({ options, onReady, onError, canvasProps, children, style, ...divProps }) {
28
- const { app, canvasRef } = useExoApplication(options, onReady, onError);
29
- const { style: canvasStyle, ...restCanvasProps } = canvasProps ?? {};
30
- const wrapperStyle = { position: 'relative', ...style };
31
- const mergedCanvasStyle = { ...defaultCanvasStyle, ...canvasStyle };
32
- return (jsx(ExoContext.Provider, { value: app, children: jsxs("div", { style: wrapperStyle, ...divProps, children: [jsx("canvas", { ref: canvasRef, style: mergedCanvasStyle, ...restCanvasProps }), app !== null && children] }) }));
29
+ const { app, canvasRef } = useExoApplication(options, onReady, onError);
30
+ const { style: canvasStyle, ...restCanvasProps } = canvasProps ?? {};
31
+ const wrapperStyle = {
32
+ position: "relative",
33
+ ...style
34
+ };
35
+ const mergedCanvasStyle = {
36
+ ...defaultCanvasStyle,
37
+ ...canvasStyle
38
+ };
39
+ return /* @__PURE__ */ jsx(ExoContext.Provider, {
40
+ value: app,
41
+ children: /* @__PURE__ */ jsxs("div", {
42
+ style: wrapperStyle,
43
+ ...divProps,
44
+ children: [/* @__PURE__ */ jsx("canvas", {
45
+ ref: canvasRef,
46
+ style: mergedCanvasStyle,
47
+ ...restCanvasProps
48
+ }), app !== null && children]
49
+ })
50
+ });
33
51
  }
34
52
 
53
+ //#endregion
35
54
  export { ExoCanvas };
36
- //# sourceMappingURL=ExoCanvas.js.map
55
+ //# sourceMappingURL=ExoCanvas.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ExoCanvas.js","sources":["../../../src/ExoCanvas.tsx"],"sourcesContent":[null],"names":["_jsx","_jsxs"],"mappings":";;;;;AAMA;AACA,MAAM,kBAAkB,GAAkB,EAAE,OAAO,EAAE,OAAO,EAAE;AA8B9D;;;;;;;;;;;;;;;;;;AAkBG;SACa,SAAS,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,QAAQ,EAAkB,EAAA;AAChH,IAAA,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;AAEvE,IAAA,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,eAAe,EAAE,GAAG,WAAW,IAAI,EAAE;IACpE,MAAM,YAAY,GAAkB,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,KAAK,EAAE;IACtE,MAAM,iBAAiB,GAAkB,EAAE,GAAG,kBAAkB,EAAE,GAAG,WAAW,EAAE;AAElF,IAAA,QACEA,GAAA,CAAC,UAAU,CAAC,QAAQ,IAAC,KAAK,EAAE,GAAG,EAAA,QAAA,EAC7BC,cAAK,KAAK,EAAE,YAAY,EAAA,GAAM,QAAQ,EAAA,QAAA,EAAA,CACpCD,GAAA,CAAA,QAAA,EAAA,EAAQ,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,iBAAiB,KAAM,eAAe,EAAA,CAAI,EACxE,GAAG,KAAK,IAAI,IAAI,QAAQ,CAAA,EAAA,CACrB,EAAA,CACc;AAE1B;;;;"}
1
+ {"version":3,"file":"ExoCanvas.js","names":[],"sources":["../../src/ExoCanvas.tsx"],"sourcesContent":["import type { Application } from '@codexo/exojs';\nimport { type CanvasHTMLAttributes, type CSSProperties, type HTMLAttributes, type ReactElement } from 'react';\n\nimport { ExoContext } from './ExoContext';\nimport { type ExoApplicationOptions, useExoApplication } from './useExoApplication';\n\n/** Default canvas style: block layout avoids the inline-element baseline gap. */\nconst defaultCanvasStyle: CSSProperties = { display: 'block' };\n\nexport interface ExoCanvasProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * Options forwarded to the ExoJS {@link Application}. Pass\n * `canvas.width`/`height`/`sizing`/etc.; most options are captured at\n * creation, but `canvas.width`/`height` and `clearColor` are applied live\n * (see {@link useExoApplication}).\n */\n options?: ExoApplicationOptions;\n /**\n * Called once each time the {@link Application} is (re)created. The backend\n * (WebGL2 / WebGPU) is not yet initialized at this point - that happens when\n * the first {@link import('./useScene').useScene} child calls `app.start()`.\n */\n onReady?: (app: Application) => void;\n /**\n * Called for every {@link Application.onError} dispatch - async init or\n * scene-load failures (including the ones surfaced by\n * {@link import('./useScene').useScene} and {@link import('./Scenes').Scenes}\n * descendants) - while an Application exists.\n */\n onError?: (error: unknown) => void;\n /**\n * Props forwarded to the inner `<canvas>` (e.g. its own `style`/`className`).\n * `ref`, `width` and `height` are managed by the engine and cannot be set.\n */\n canvasProps?: Omit<CanvasHTMLAttributes<HTMLCanvasElement>, 'ref' | 'width' | 'height'>;\n}\n\n/**\n * Batteries-included canvas host. Renders a **positioned wrapper `<div>`**\n * containing a React-managed `<canvas>` bound to an ExoJS {@link Application},\n * and provides the app to descendant hooks via context. Because the wrapper is\n * `position: relative`, absolutely-positioned `children` (HUD overlays,\n * {@link import('./Scenes').Scenes}) sit over the canvas out of the box.\n *\n * Layout props (`style`, `className`, ...) apply to the **wrapper**, which is\n * the element a `canvas.sizing` policy measures - size it to size the canvas.\n * Use {@link canvasProps} to style the canvas itself. For full control with no\n * wrapper element, use the headless {@link useExoApplication} hook directly.\n *\n * @example\n * ```tsx\n * <ExoCanvas options={{ canvas: { width: 800, height: 600 } }} style={{ width: 800, height: 600 }}>\n * <Hud /> // absolutely-positioned overlay; works because the wrapper is relative\n * </ExoCanvas>\n * ```\n */\nexport function ExoCanvas({ options, onReady, onError, canvasProps, children, style, ...divProps }: ExoCanvasProps): ReactElement {\n const { app, canvasRef } = useExoApplication(options, onReady, onError);\n\n const { style: canvasStyle, ...restCanvasProps } = canvasProps ?? {};\n const wrapperStyle: CSSProperties = { position: 'relative', ...style };\n const mergedCanvasStyle: CSSProperties = { ...defaultCanvasStyle, ...canvasStyle };\n\n return (\n <ExoContext.Provider value={app}>\n <div style={wrapperStyle} {...divProps}>\n <canvas ref={canvasRef} style={mergedCanvasStyle} {...restCanvasProps} />\n {app !== null && children}\n </div>\n </ExoContext.Provider>\n );\n}\n"],"mappings":";;;;;;;AAOA,MAAM,qBAAoC,EAAE,SAAS,QAAQ;;;;;;;;;;;;;;;;;;;;AAiD7D,SAAgB,UAAU,EAAE,SAAS,SAAS,SAAS,aAAa,UAAU,OAAO,GAAG,YAA0C;CAChI,MAAM,EAAE,KAAK,cAAc,kBAAkB,SAAS,SAAS,OAAO;CAEtE,MAAM,EAAE,OAAO,aAAa,GAAG,oBAAoB,eAAe,CAAC;CACnE,MAAM,eAA8B;EAAE,UAAU;EAAY,GAAG;CAAM;CACrE,MAAM,oBAAmC;EAAE,GAAG;EAAoB,GAAG;CAAY;CAEjF,OACE,oBAAC,WAAW,UAAZ;EAAqB,OAAO;YAC1B,qBAAC,OAAD;GAAK,OAAO;GAAc,GAAI;aAA9B,CACE,oBAAC,UAAD;IAAQ,KAAK;IAAW,OAAO;IAAmB,GAAI;GAAkB,IACvE,QAAQ,QAAQ,QACd;;CACc;AAEzB"}
@@ -5,11 +5,12 @@ import type { Application } from '@codexo/exojs';
5
5
  * hook rather than reading this context directly; the context object is
6
6
  * exported for advanced use (e.g. testing, custom providers).
7
7
  */
8
- export declare const ExoContext: import("react").Context<Application | null>;
8
+ export declare const ExoContext: import("react").Context<Application<{}> | null>;
9
9
  /**
10
10
  * Returns the nearest {@link Application} from the React tree, or `null`
11
11
  * when called outside of an {@link ExoCanvas}. Prefer {@link useExoApp} for
12
- * component-level use it throws an actionable error instead of returning
12
+ * component-level use - it throws an actionable error instead of returning
13
13
  * null.
14
14
  */
15
- export declare function useExoContext(): Application | null;
15
+ export declare const useExoContext: () => Application | null;
16
+ //# sourceMappingURL=ExoContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExoContext.d.ts","sourceRoot":"","sources":["../../src/ExoContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAGjD;;;;;GAKG;AACH,eAAO,MAAM,UAAU,iDAA0C,CAAC;AAGlE;;;;;GAKG;AACH,eAAO,MAAM,aAAa,QAAO,WAAW,GAAG,IAA8B,CAAC"}
@@ -1,23 +1,22 @@
1
- import { createContext, useContext } from 'react';
1
+ import { createContext, useContext } from "react";
2
2
 
3
+ //#region src/ExoContext.ts
3
4
  /**
4
- * Internal React context that carries the active {@link Application} instance
5
- * created by {@link ExoCanvas}. Consumers should use the {@link useExoApp}
6
- * hook rather than reading this context directly; the context object is
7
- * exported for advanced use (e.g. testing, custom providers).
8
- */
9
- // eslint-disable-next-line @typescript-eslint/naming-convention
5
+ * Internal React context that carries the active {@link Application} instance
6
+ * created by {@link ExoCanvas}. Consumers should use the {@link useExoApp}
7
+ * hook rather than reading this context directly; the context object is
8
+ * exported for advanced use (e.g. testing, custom providers).
9
+ */
10
10
  const ExoContext = createContext(null);
11
- ExoContext.displayName = 'ExoContext';
11
+ ExoContext.displayName = "ExoContext";
12
12
  /**
13
- * Returns the nearest {@link Application} from the React tree, or `null`
14
- * when called outside of an {@link ExoCanvas}. Prefer {@link useExoApp} for
15
- * component-level use it throws an actionable error instead of returning
16
- * null.
17
- */
18
- function useExoContext() {
19
- return useContext(ExoContext);
20
- }
13
+ * Returns the nearest {@link Application} from the React tree, or `null`
14
+ * when called outside of an {@link ExoCanvas}. Prefer {@link useExoApp} for
15
+ * component-level use - it throws an actionable error instead of returning
16
+ * null.
17
+ */
18
+ const useExoContext = () => useContext(ExoContext);
21
19
 
20
+ //#endregion
22
21
  export { ExoContext, useExoContext };
23
- //# sourceMappingURL=ExoContext.js.map
22
+ //# sourceMappingURL=ExoContext.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ExoContext.js","sources":["../../../src/ExoContext.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAGA;;;;;AAKG;AACH;MACa,UAAU,GAAG,aAAa,CAAqB,IAAI;AAChE,UAAU,CAAC,WAAW,GAAG,YAAY;AAErC;;;;;AAKG;SACa,aAAa,GAAA;AAC3B,IAAA,OAAO,UAAU,CAAC,UAAU,CAAC;AAC/B;;;;"}
1
+ {"version":3,"file":"ExoContext.js","names":[],"sources":["../../src/ExoContext.ts"],"sourcesContent":["import type { Application } from '@codexo/exojs';\nimport { createContext, useContext } from 'react';\n\n/**\n * Internal React context that carries the active {@link Application} instance\n * created by {@link ExoCanvas}. Consumers should use the {@link useExoApp}\n * hook rather than reading this context directly; the context object is\n * exported for advanced use (e.g. testing, custom providers).\n */\nexport const ExoContext = createContext<Application | null>(null);\nExoContext.displayName = 'ExoContext';\n\n/**\n * Returns the nearest {@link Application} from the React tree, or `null`\n * when called outside of an {@link ExoCanvas}. Prefer {@link useExoApp} for\n * component-level use - it throws an actionable error instead of returning\n * null.\n */\nexport const useExoContext = (): Application | null => useContext(ExoContext);\n"],"mappings":";;;;;;;;;AASA,MAAa,aAAa,cAAkC,IAAI;AAChE,WAAW,cAAc;;;;;;;AAQzB,MAAa,sBAA0C,WAAW,UAAU"}
@@ -1,4 +1,4 @@
1
- import { type Scene as ExoScene, type SceneTransition } from '@codexo/exojs';
1
+ import { type Scene as ExoScene, type SceneTransitionSelection } from '@codexo/exojs';
2
2
  import { type ReactElement, type ReactNode } from 'react';
3
3
  /**
4
4
  * Returns the currently-active scene instance from the nearest {@link Scenes},
@@ -16,7 +16,7 @@ export interface SceneProps {
16
16
  readonly children?: ReactNode;
17
17
  }
18
18
  /**
19
- * Declares one scene inside a {@link Scenes} switch. Renders nothing on its own
19
+ * Declares one scene inside a {@link Scenes} switch. Renders nothing on its own -
20
20
  * {@link Scenes} reads its props and renders its {@link SceneProps.children} only
21
21
  * while the scene is active.
22
22
  */
@@ -25,28 +25,31 @@ export declare function Scene(_props: SceneProps): ReactElement | null;
25
25
  export interface ScenesProps {
26
26
  /** Name of the active {@link Scene}. Changing it switches scenes. */
27
27
  readonly active: string;
28
- /** Optional transition (e.g. a fade) applied when switching scenes. */
29
- readonly transition?: SceneTransition;
28
+ /** Optional transition (e.g. a `FadeSceneTransition`) applied when switching scenes. */
29
+ readonly transition?: SceneTransitionSelection;
30
30
  /** {@link Scene} declarations. */
31
31
  readonly children?: ReactNode;
32
32
  }
33
33
  /**
34
34
  * Declarative scene switch over the one-active-scene model. Renders a set of
35
35
  * {@link Scene} declarations and activates the one whose `name` equals `active`
36
- * via `app.start()` (first activation) or `app.scene.setScene()` (subsequent
37
- * switches, with the optional `transition`). The active scene's React children
38
- * (HUD overlay) render alongside, and can read the instance via
39
- * {@link useActiveScene}.
36
+ * via `app.start()` (first activation) or `app.scenes.change()` (subsequent
37
+ * switches, with the optional `transition`) - the declaration's `component`
38
+ * constructor must be registered in `ApplicationOptions.scenes`. The active
39
+ * scene's React children (HUD overlay) render alongside, and can read the
40
+ * instance via {@link useActiveScene}.
40
41
  *
41
- * A failure in `app.start()`/`app.scene.setScene()` (e.g. a scene's `onLoad`
42
+ * A failure in `app.start()`/`app.scenes.change()` (e.g. a scene's `load()`
42
43
  * rejects) is caught and routed to {@link Application.onError} rather than
43
- * left as an unhandled promise rejection subscribe via `app.onError.add(...)`
44
+ * left as an unhandled promise rejection - subscribe via `app.onError.add(...)`
44
45
  * or the {@link import('./ExoCanvas').ExoCanvas} `onError` prop to observe it.
45
46
  *
46
47
  * @example
47
48
  * ```tsx
49
+ * import { FadeSceneTransition } from '@codexo/exojs';
50
+ *
48
51
  * <ExoCanvas>
49
- * <Scenes active={screen} transition={{ type: 'fade', duration: 0.3 }}>
52
+ * <Scenes active={screen} transition={new FadeSceneTransition({ duration: 300 })}>
50
53
  * <Scene name="title" component={TitleScene} />
51
54
  * <Scene name="game" component={GameScene}>
52
55
  * <Hud />
@@ -56,3 +59,4 @@ export interface ScenesProps {
56
59
  * ```
57
60
  */
58
61
  export declare function Scenes({ active, transition, children }: ScenesProps): ReactElement;
62
+ //# sourceMappingURL=Scenes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Scenes.d.ts","sourceRoot":"","sources":["../../src/Scenes.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,KAAK,IAAI,QAAQ,EAAE,KAAK,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACxG,OAAO,EAA2C,KAAK,YAAY,EAAE,KAAK,SAAS,EAA4C,MAAM,OAAO,CAAC;AAQ7I;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ,KAAK,CAAC,GAAG,IAAI,CAExE;AAED,6CAA6C;AAC7C,MAAM,WAAW,UAAU;IACzB,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,QAAQ,CAAC,SAAS,EAAE,UAAU,QAAQ,CAAC;IACvC,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI,CAE7D;AAED,2CAA2C;AAC3C,MAAM,WAAW,WAAW;IAC1B,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,wFAAwF;IACxF,QAAQ,CAAC,UAAU,CAAC,EAAE,wBAAwB,CAAC;IAC/C,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,WAAW,GAAG,YAAY,CAiElF"}
@@ -1,110 +1,98 @@
1
- import { jsx } from 'react/jsx-runtime';
2
- import { ApplicationStatus } from '@codexo/exojs';
3
- import { createContext, useState, useMemo, Children, isValidElement, useEffect, useContext } from 'react';
4
- import { useExoApp } from './useExoApp.js';
1
+ import { useExoApp } from "./useExoApp.js";
2
+ import { Children, createContext, isValidElement, useContext, useEffect, useMemo, useState } from "react";
3
+ import { ApplicationState } from "@codexo/exojs";
4
+ import { jsx } from "react/jsx-runtime";
5
5
 
6
+ //#region src/Scenes.tsx
6
7
  /** Carries the active {@link ExoScene} instance to descendants (HUD overlays). */
7
8
  const ActiveSceneContext = createContext(null);
8
- ActiveSceneContext.displayName = 'ExoActiveScene';
9
+ ActiveSceneContext.displayName = "ExoActiveScene";
9
10
  /**
10
- * Returns the currently-active scene instance from the nearest {@link Scenes},
11
- * or `null` while none is live. Useful for HUD/overlay components that need to
12
- * read scene state.
13
- */
11
+ * Returns the currently-active scene instance from the nearest {@link Scenes},
12
+ * or `null` while none is live. Useful for HUD/overlay components that need to
13
+ * read scene state.
14
+ */
14
15
  function useActiveScene() {
15
- return useContext(ActiveSceneContext);
16
+ return useContext(ActiveSceneContext);
16
17
  }
17
18
  /**
18
- * Declares one scene inside a {@link Scenes} switch. Renders nothing on its own
19
- * {@link Scenes} reads its props and renders its {@link SceneProps.children} only
20
- * while the scene is active.
21
- */
19
+ * Declares one scene inside a {@link Scenes} switch. Renders nothing on its own -
20
+ * {@link Scenes} reads its props and renders its {@link SceneProps.children} only
21
+ * while the scene is active.
22
+ */
22
23
  function Scene(_props) {
23
- return null;
24
+ return null;
24
25
  }
25
26
  /**
26
- * Declarative scene switch over the one-active-scene model. Renders a set of
27
- * {@link Scene} declarations and activates the one whose `name` equals `active`
28
- * via `app.start()` (first activation) or `app.scene.setScene()` (subsequent
29
- * switches, with the optional `transition`). The active scene's React children
30
- * (HUD overlay) render alongside, and can read the instance via
31
- * {@link useActiveScene}.
32
- *
33
- * A failure in `app.start()`/`app.scene.setScene()` (e.g. a scene's `onLoad`
34
- * rejects) is caught and routed to {@link Application.onError} rather than
35
- * left as an unhandled promise rejection subscribe via `app.onError.add(...)`
36
- * or the {@link import('./ExoCanvas').ExoCanvas} `onError` prop to observe it.
37
- *
38
- * @example
39
- * ```tsx
40
- * <ExoCanvas>
41
- * <Scenes active={screen} transition={{ type: 'fade', duration: 0.3 }}>
42
- * <Scene name="title" component={TitleScene} />
43
- * <Scene name="game" component={GameScene}>
44
- * <Hud />
45
- * </Scene>
46
- * </Scenes>
47
- * </ExoCanvas>
48
- * ```
49
- */
27
+ * Declarative scene switch over the one-active-scene model. Renders a set of
28
+ * {@link Scene} declarations and activates the one whose `name` equals `active`
29
+ * via `app.start()` (first activation) or `app.scenes.change()` (subsequent
30
+ * switches, with the optional `transition`) - the declaration's `component`
31
+ * constructor must be registered in `ApplicationOptions.scenes`. The active
32
+ * scene's React children (HUD overlay) render alongside, and can read the
33
+ * instance via {@link useActiveScene}.
34
+ *
35
+ * A failure in `app.start()`/`app.scenes.change()` (e.g. a scene's `load()`
36
+ * rejects) is caught and routed to {@link Application.onError} rather than
37
+ * left as an unhandled promise rejection - subscribe via `app.onError.add(...)`
38
+ * or the {@link import('./ExoCanvas').ExoCanvas} `onError` prop to observe it.
39
+ *
40
+ * @example
41
+ * ```tsx
42
+ * import { FadeSceneTransition } from '@codexo/exojs';
43
+ *
44
+ * <ExoCanvas>
45
+ * <Scenes active={screen} transition={new FadeSceneTransition({ duration: 300 })}>
46
+ * <Scene name="title" component={TitleScene} />
47
+ * <Scene name="game" component={GameScene}>
48
+ * <Hud />
49
+ * </Scene>
50
+ * </Scenes>
51
+ * </ExoCanvas>
52
+ * ```
53
+ */
50
54
  function Scenes({ active, transition, children }) {
51
- const app = useExoApp();
52
- const [instance, setInstance] = useState(null);
53
- // Collect the <Scene> declarations from children (keyed by name).
54
- const registry = useMemo(() => {
55
- const map = new Map();
56
- Children.forEach(children, child => {
57
- if (isValidElement(child) && child.type === Scene) {
58
- const props = child.props;
59
- map.set(props.name, props);
60
- }
61
- });
62
- return map;
63
- }, [children]);
64
- const entry = registry.get(active);
65
- const SceneClass = entry?.component ?? null;
66
- useEffect(() => {
67
- if (SceneClass === null) {
68
- setInstance(null);
69
- void app.scene.setScene(null).catch((error) => {
70
- app.onError.dispatch(error instanceof Error ? error : new Error(String(error)));
71
- });
72
- return;
73
- }
74
- let cancelled = false;
75
- const scene = new SceneClass();
76
- const apply = async () => {
77
- try {
78
- if (app.status === ApplicationStatus.Stopped) {
79
- // First activation initializes the backend and starts the frame loop;
80
- // transitions only apply to subsequent switches.
81
- await app.start(scene);
82
- }
83
- else {
84
- await app.scene.setScene(scene, transition !== undefined ? { transition } : {});
85
- }
86
- if (!cancelled) {
87
- setInstance(scene);
88
- }
89
- }
90
- catch (error) {
91
- // Route to Application.onError instead of leaving an unhandled
92
- // rejection — app.start()/setScene() reject rather than dispatching
93
- // onError themselves.
94
- app.onError.dispatch(error instanceof Error ? error : new Error(String(error)));
95
- }
96
- };
97
- void apply();
98
- return () => {
99
- cancelled = true;
100
- setInstance(null);
101
- };
102
- // Re-activate when the active name changes. SceneClass/transition derive
103
- // from `active`; keying on app + active avoids re-instantiating each render.
104
- // eslint-disable-next-line react-hooks/exhaustive-deps
105
- }, [app, active]);
106
- return (jsx(ActiveSceneContext.Provider, { value: instance, children: instance !== null && entry?.children }));
55
+ const app = useExoApp();
56
+ const [instance, setInstance] = useState(null);
57
+ const entry = useMemo(() => {
58
+ const map = /* @__PURE__ */ new Map();
59
+ Children.forEach(children, (child) => {
60
+ if (isValidElement(child) && child.type === Scene) {
61
+ const props = child.props;
62
+ map.set(props.name, props);
63
+ }
64
+ });
65
+ return map;
66
+ }, [children]).get(active);
67
+ const SceneClass = entry?.component ?? null;
68
+ useEffect(() => {
69
+ if (SceneClass === null) {
70
+ console.warn(`<Scenes>: no <Scene name="${active}"> declaration found; the previously active scene (if any) keeps running.`);
71
+ setInstance(null);
72
+ return;
73
+ }
74
+ let cancelled = false;
75
+ const apply = async () => {
76
+ try {
77
+ if (app.state === ApplicationState.Stopped) await app.start(SceneClass);
78
+ else await app.scenes.change(SceneClass, transition !== void 0 ? { transition } : {});
79
+ if (!cancelled) setInstance(app.scenes.currentScene);
80
+ } catch (error) {
81
+ app.onError.dispatch(error instanceof Error ? error : new Error(String(error)));
82
+ }
83
+ };
84
+ apply();
85
+ return () => {
86
+ cancelled = true;
87
+ setInstance(null);
88
+ };
89
+ }, [app, active]);
90
+ return /* @__PURE__ */ jsx(ActiveSceneContext.Provider, {
91
+ value: instance,
92
+ children: instance !== null && entry?.children
93
+ });
107
94
  }
108
95
 
96
+ //#endregion
109
97
  export { Scene, Scenes, useActiveScene };
110
- //# sourceMappingURL=Scenes.js.map
98
+ //# sourceMappingURL=Scenes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Scenes.js","sources":["../../../src/Scenes.tsx"],"sourcesContent":[null],"names":["_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"Scenes.js","names":[],"sources":["../../src/Scenes.tsx"],"sourcesContent":["import { ApplicationState, type Scene as ExoScene, type SceneTransitionSelection } from '@codexo/exojs';\nimport { Children, createContext, isValidElement, type ReactElement, type ReactNode, useContext, useEffect, useMemo, useState } from 'react';\n\nimport { useExoApp } from './useExoApp';\n\n/** Carries the active {@link ExoScene} instance to descendants (HUD overlays). */\nconst ActiveSceneContext = createContext<ExoScene | null>(null);\nActiveSceneContext.displayName = 'ExoActiveScene';\n\n/**\n * Returns the currently-active scene instance from the nearest {@link Scenes},\n * or `null` while none is live. Useful for HUD/overlay components that need to\n * read scene state.\n */\nexport function useActiveScene<T extends ExoScene = ExoScene>(): T | null {\n return useContext(ActiveSceneContext) as T | null;\n}\n\n/** Props for a {@link Scene} declaration. */\nexport interface SceneProps {\n /** Unique name used to select this scene via {@link ScenesProps.active}. */\n readonly name: string;\n /** Scene class to instantiate when this scene becomes active. */\n readonly component: new () => ExoScene;\n /** React overlay (HUD) rendered only while this scene is active. */\n readonly children?: ReactNode;\n}\n\n/**\n * Declares one scene inside a {@link Scenes} switch. Renders nothing on its own -\n * {@link Scenes} reads its props and renders its {@link SceneProps.children} only\n * while the scene is active.\n */\nexport function Scene(_props: SceneProps): ReactElement | null {\n return null;\n}\n\n/** Props for the {@link Scenes} switch. */\nexport interface ScenesProps {\n /** Name of the active {@link Scene}. Changing it switches scenes. */\n readonly active: string;\n /** Optional transition (e.g. a `FadeSceneTransition`) applied when switching scenes. */\n readonly transition?: SceneTransitionSelection;\n /** {@link Scene} declarations. */\n readonly children?: ReactNode;\n}\n\n/**\n * Declarative scene switch over the one-active-scene model. Renders a set of\n * {@link Scene} declarations and activates the one whose `name` equals `active`\n * via `app.start()` (first activation) or `app.scenes.change()` (subsequent\n * switches, with the optional `transition`) - the declaration's `component`\n * constructor must be registered in `ApplicationOptions.scenes`. The active\n * scene's React children (HUD overlay) render alongside, and can read the\n * instance via {@link useActiveScene}.\n *\n * A failure in `app.start()`/`app.scenes.change()` (e.g. a scene's `load()`\n * rejects) is caught and routed to {@link Application.onError} rather than\n * left as an unhandled promise rejection - subscribe via `app.onError.add(...)`\n * or the {@link import('./ExoCanvas').ExoCanvas} `onError` prop to observe it.\n *\n * @example\n * ```tsx\n * import { FadeSceneTransition } from '@codexo/exojs';\n *\n * <ExoCanvas>\n * <Scenes active={screen} transition={new FadeSceneTransition({ duration: 300 })}>\n * <Scene name=\"title\" component={TitleScene} />\n * <Scene name=\"game\" component={GameScene}>\n * <Hud />\n * </Scene>\n * </Scenes>\n * </ExoCanvas>\n * ```\n */\nexport function Scenes({ active, transition, children }: ScenesProps): ReactElement {\n const app = useExoApp();\n const [instance, setInstance] = useState<ExoScene | null>(null);\n\n // Collect the <Scene> declarations from children (keyed by name).\n const registry = useMemo(() => {\n const map = new Map<string, SceneProps>();\n Children.forEach(children, child => {\n if (isValidElement(child) && child.type === Scene) {\n const props = child.props as SceneProps;\n map.set(props.name, props);\n }\n });\n return map;\n }, [children]);\n\n const entry = registry.get(active);\n const SceneClass = entry?.component ?? null;\n\n useEffect(() => {\n if (SceneClass === null) {\n // No matching <Scene name={active}> declaration. No public API switches\n // the director back to scene-less mid-lifetime - the\n // last-active scene keeps running underneath; only the React-rendered\n // HUD overlay is cleared. This is a caller mismatch (an `active` name\n // with no matching <Scene>), not a supported \"show nothing\" path.\n console.warn(`<Scenes>: no <Scene name=\"${active}\"> declaration found; the previously active scene (if any) keeps running.`);\n setInstance(null);\n return;\n }\n\n let cancelled = false;\n\n const apply = async (): Promise<void> => {\n try {\n if (app.state === ApplicationState.Stopped) {\n // First activation initializes the backend and starts the frame loop;\n // transitions only apply to subsequent switches.\n await app.start(SceneClass);\n } else {\n await app.scenes.change(SceneClass, transition !== undefined ? { transition } : {});\n }\n if (!cancelled) {\n setInstance(app.scenes.currentScene);\n }\n } catch (error) {\n // Route to Application.onError instead of leaving an unhandled\n // rejection - app.start()/change() reject rather than dispatching\n // onError themselves.\n app.onError.dispatch(error instanceof Error ? error : new Error(String(error)));\n }\n };\n\n void apply();\n\n return () => {\n cancelled = true;\n setInstance(null);\n };\n // Re-activate when the active name changes. SceneClass/transition derive\n // from `active`; keying on app + active avoids re-instantiating each render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [app, active]);\n\n return <ActiveSceneContext.Provider value={instance}>{instance !== null && entry?.children}</ActiveSceneContext.Provider>;\n}\n"],"mappings":";;;;;;;AAMA,MAAM,qBAAqB,cAA+B,IAAI;AAC9D,mBAAmB,cAAc;;;;;;AAOjC,SAAgB,iBAA0D;CACxE,OAAO,WAAW,kBAAkB;AACtC;;;;;;AAiBA,SAAgB,MAAM,QAAyC;CAC7D,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,SAAgB,OAAO,EAAE,QAAQ,YAAY,YAAuC;CAClF,MAAM,MAAM,UAAU;CACtB,MAAM,CAAC,UAAU,eAAe,SAA0B,IAAI;CAc9D,MAAM,QAXW,cAAc;EAC7B,MAAM,sBAAM,IAAI,IAAwB;EACxC,SAAS,QAAQ,WAAU,UAAS;GAClC,IAAI,eAAe,KAAK,KAAK,MAAM,SAAS,OAAO;IACjD,MAAM,QAAQ,MAAM;IACpB,IAAI,IAAI,MAAM,MAAM,KAAK;GAC3B;EACF,CAAC;EACD,OAAO;CACT,GAAG,CAAC,QAAQ,CAES,CAAC,CAAC,IAAI,MAAM;CACjC,MAAM,aAAa,OAAO,aAAa;CAEvC,gBAAgB;EACd,IAAI,eAAe,MAAM;GAMvB,QAAQ,KAAK,6BAA6B,OAAO,0EAA0E;GAC3H,YAAY,IAAI;GAChB;EACF;EAEA,IAAI,YAAY;EAEhB,MAAM,QAAQ,YAA2B;GACvC,IAAI;IACF,IAAI,IAAI,UAAU,iBAAiB,SAGjC,MAAM,IAAI,MAAM,UAAU;SAE1B,MAAM,IAAI,OAAO,OAAO,YAAY,eAAe,SAAY,EAAE,WAAW,IAAI,CAAC,CAAC;IAEpF,IAAI,CAAC,WACH,YAAY,IAAI,OAAO,YAAY;GAEvC,SAAS,OAAO;IAId,IAAI,QAAQ,SAAS,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;GAChF;EACF;EAEA,AAAK,MAAM;EAEX,aAAa;GACX,YAAY;GACZ,YAAY,IAAI;EAClB;CAIF,GAAG,CAAC,KAAK,MAAM,CAAC;CAEhB,OAAO,oBAAC,mBAAmB,UAApB;EAA6B,OAAO;YAAW,aAAa,QAAQ,OAAO;CAAsC;AAC1H"}
@@ -8,3 +8,4 @@ export type { ExoApplicationOptions, UseExoApplicationResult } from './useExoApp
8
8
  export { useExoApplication } from './useExoApplication';
9
9
  export { useScene } from './useScene';
10
10
  export { useSignal } from './useSignal';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACzD,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC1F,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
package/dist/esm/index.js CHANGED
@@ -1,8 +1,9 @@
1
- export { ExoCanvas } from './ExoCanvas.js';
2
- export { ExoContext, useExoContext } from './ExoContext.js';
3
- export { Scene, Scenes, useActiveScene } from './Scenes.js';
4
- export { useExoApp } from './useExoApp.js';
5
- export { useExoApplication } from './useExoApplication.js';
6
- export { useScene } from './useScene.js';
7
- export { useSignal } from './useSignal.js';
8
- //# sourceMappingURL=index.js.map
1
+ import { ExoContext, useExoContext } from "./ExoContext.js";
2
+ import { useExoApplication } from "./useExoApplication.js";
3
+ import { ExoCanvas } from "./ExoCanvas.js";
4
+ import { useExoApp } from "./useExoApp.js";
5
+ import { Scene, Scenes, useActiveScene } from "./Scenes.js";
6
+ import { useScene } from "./useScene.js";
7
+ import { useSignal } from "./useSignal.js";
8
+
9
+ export { ExoCanvas, ExoContext, Scene, Scenes, useActiveScene, useExoApp, useExoApplication, useExoContext, useScene, useSignal };