canvasengine 2.0.0-beta.8 → 2.0.0-rc.1

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.
Files changed (167) hide show
  1. package/dist/DebugRenderer-DkjTAc48.js +1384 -0
  2. package/dist/DebugRenderer-DkjTAc48.js.map +1 -0
  3. package/dist/components/Button.d.ts +185 -0
  4. package/dist/components/Button.d.ts.map +1 -0
  5. package/dist/components/Canvas.d.ts +17 -0
  6. package/dist/components/Canvas.d.ts.map +1 -0
  7. package/dist/components/DOMElement.d.ts +54 -0
  8. package/dist/components/DOMElement.d.ts.map +1 -0
  9. package/dist/components/DOMSprite.d.ts +127 -0
  10. package/dist/components/DOMSprite.d.ts.map +1 -0
  11. package/dist/components/FocusContainer.d.ts +129 -0
  12. package/dist/components/FocusContainer.d.ts.map +1 -0
  13. package/dist/components/Graphic.d.ts +64 -0
  14. package/dist/components/Graphic.d.ts.map +1 -0
  15. package/dist/components/Joystick.d.ts +36 -0
  16. package/dist/components/Joystick.d.ts.map +1 -0
  17. package/dist/components/NineSliceSprite.d.ts +16 -0
  18. package/dist/components/NineSliceSprite.d.ts.map +1 -0
  19. package/dist/components/ParticleEmitter.d.ts +4 -0
  20. package/dist/components/ParticleEmitter.d.ts.map +1 -0
  21. package/dist/components/Scene.d.ts +2 -0
  22. package/dist/components/Scene.d.ts.map +1 -0
  23. package/dist/components/Text.d.ts +24 -0
  24. package/dist/components/Text.d.ts.map +1 -0
  25. package/dist/components/TilingSprite.d.ts +17 -0
  26. package/dist/components/TilingSprite.d.ts.map +1 -0
  27. package/dist/components/Video.d.ts +14 -0
  28. package/dist/components/Video.d.ts.map +1 -0
  29. package/dist/components/index.d.ts +20 -0
  30. package/dist/components/index.d.ts.map +1 -0
  31. package/dist/components/types/DisplayObject.d.ts +122 -0
  32. package/dist/components/types/DisplayObject.d.ts.map +1 -0
  33. package/dist/components/types/MouseEvent.d.ts +4 -0
  34. package/dist/components/types/MouseEvent.d.ts.map +1 -0
  35. package/dist/components/types/Spritesheet.d.ts +248 -0
  36. package/dist/components/types/Spritesheet.d.ts.map +1 -0
  37. package/dist/components/types/index.d.ts +4 -0
  38. package/dist/components/types/index.d.ts.map +1 -0
  39. package/dist/directives/Controls.d.ts +112 -0
  40. package/dist/directives/Controls.d.ts.map +1 -0
  41. package/dist/directives/ControlsBase.d.ts +199 -0
  42. package/dist/directives/ControlsBase.d.ts.map +1 -0
  43. package/dist/directives/Drag.d.ts +69 -0
  44. package/dist/directives/Drag.d.ts.map +1 -0
  45. package/dist/directives/Flash.d.ts +116 -0
  46. package/dist/directives/Flash.d.ts.map +1 -0
  47. package/dist/directives/FocusNavigation.d.ts +52 -0
  48. package/dist/directives/FocusNavigation.d.ts.map +1 -0
  49. package/dist/directives/FogVisibility.d.ts +47 -0
  50. package/dist/directives/FogVisibility.d.ts.map +1 -0
  51. package/dist/directives/GamepadControls.d.ts +224 -0
  52. package/dist/directives/GamepadControls.d.ts.map +1 -0
  53. package/dist/directives/JoystickControls.d.ts +171 -0
  54. package/dist/directives/JoystickControls.d.ts.map +1 -0
  55. package/dist/directives/KeyboardControls.d.ts +219 -0
  56. package/dist/directives/KeyboardControls.d.ts.map +1 -0
  57. package/dist/directives/Scheduler.d.ts +36 -0
  58. package/dist/directives/Scheduler.d.ts.map +1 -0
  59. package/dist/directives/Shake.d.ts +98 -0
  60. package/dist/directives/Shake.d.ts.map +1 -0
  61. package/dist/directives/Sound.d.ts +25 -0
  62. package/dist/directives/Sound.d.ts.map +1 -0
  63. package/dist/directives/SpriteEffects.d.ts +70 -0
  64. package/dist/directives/SpriteEffects.d.ts.map +1 -0
  65. package/dist/directives/Transition.d.ts +10 -0
  66. package/dist/directives/Transition.d.ts.map +1 -0
  67. package/dist/directives/ViewportCull.d.ts +11 -0
  68. package/dist/directives/ViewportCull.d.ts.map +1 -0
  69. package/dist/directives/ViewportFollow.d.ts +18 -0
  70. package/dist/directives/ViewportFollow.d.ts.map +1 -0
  71. package/dist/directives/index.d.ts +15 -0
  72. package/dist/directives/index.d.ts.map +1 -0
  73. package/dist/dist-BOOc43Qm.js +778 -0
  74. package/dist/dist-BOOc43Qm.js.map +1 -0
  75. package/dist/engine/FocusManager.d.ts +174 -0
  76. package/dist/engine/FocusManager.d.ts.map +1 -0
  77. package/dist/engine/animation.d.ts +72 -0
  78. package/dist/engine/animation.d.ts.map +1 -0
  79. package/dist/engine/bootstrap.d.ts +52 -0
  80. package/dist/engine/bootstrap.d.ts.map +1 -0
  81. package/dist/engine/directive.d.ts +13 -0
  82. package/dist/engine/directive.d.ts.map +1 -0
  83. package/dist/engine/reactive.d.ts +135 -0
  84. package/dist/engine/reactive.d.ts.map +1 -0
  85. package/dist/engine/signal.d.ts +73 -0
  86. package/dist/engine/signal.d.ts.map +1 -0
  87. package/dist/engine/trigger.d.ts +54 -0
  88. package/dist/engine/trigger.d.ts.map +1 -0
  89. package/dist/engine/utils.d.ts +89 -0
  90. package/dist/engine/utils.d.ts.map +1 -0
  91. package/dist/hooks/addContext.d.ts +2 -0
  92. package/dist/hooks/addContext.d.ts.map +1 -0
  93. package/dist/hooks/useFocus.d.ts +60 -0
  94. package/dist/hooks/useFocus.d.ts.map +1 -0
  95. package/dist/hooks/useProps.d.ts +42 -0
  96. package/dist/hooks/useProps.d.ts.map +1 -0
  97. package/dist/hooks/useRef.d.ts +4 -0
  98. package/dist/hooks/useRef.d.ts.map +1 -0
  99. package/dist/index.d.ts +19 -1135
  100. package/dist/index.d.ts.map +1 -0
  101. package/dist/index.global.js +189 -0
  102. package/dist/index.global.js.map +1 -0
  103. package/dist/index.js +15001 -3211
  104. package/dist/index.js.map +1 -1
  105. package/dist/utils/Ease.d.ts +17 -0
  106. package/dist/utils/Ease.d.ts.map +1 -0
  107. package/dist/utils/GlobalAssetLoader.d.ts +141 -0
  108. package/dist/utils/GlobalAssetLoader.d.ts.map +1 -0
  109. package/dist/utils/RadialGradient.d.ts +57 -0
  110. package/dist/utils/RadialGradient.d.ts.map +1 -0
  111. package/dist/utils/functions.d.ts +2 -0
  112. package/dist/utils/functions.d.ts.map +1 -0
  113. package/dist/utils/tabindex.d.ts +16 -0
  114. package/dist/utils/tabindex.d.ts.map +1 -0
  115. package/package.json +16 -9
  116. package/src/components/Button.ts +399 -0
  117. package/src/components/Canvas.ts +82 -51
  118. package/src/components/Container.ts +21 -2
  119. package/src/components/DOMContainer.ts +379 -0
  120. package/src/components/DOMElement.ts +556 -0
  121. package/src/components/DOMSprite.ts +1040 -0
  122. package/src/components/DisplayObject.ts +422 -201
  123. package/src/components/FocusContainer.ts +368 -0
  124. package/src/components/Graphic.ts +239 -73
  125. package/src/components/Joystick.ts +363 -0
  126. package/src/components/Mesh.ts +222 -0
  127. package/src/components/NineSliceSprite.ts +4 -1
  128. package/src/components/ParticleEmitter.ts +12 -8
  129. package/src/components/Sprite.ts +418 -52
  130. package/src/components/Text.ts +268 -24
  131. package/src/components/Viewport.ts +122 -63
  132. package/src/components/index.ts +9 -2
  133. package/src/components/types/DisplayObject.ts +57 -5
  134. package/src/components/types/Spritesheet.ts +0 -118
  135. package/src/directives/Controls.ts +254 -0
  136. package/src/directives/ControlsBase.ts +267 -0
  137. package/src/directives/Drag.ts +357 -52
  138. package/src/directives/Flash.ts +419 -0
  139. package/src/directives/FocusNavigation.ts +113 -0
  140. package/src/directives/FogVisibility.ts +273 -0
  141. package/src/directives/GamepadControls.ts +537 -0
  142. package/src/directives/JoystickControls.ts +396 -0
  143. package/src/directives/KeyboardControls.ts +85 -430
  144. package/src/directives/Scheduler.ts +21 -5
  145. package/src/directives/Shake.ts +298 -0
  146. package/src/directives/Sound.ts +94 -31
  147. package/src/directives/SpriteEffects.ts +461 -0
  148. package/src/directives/ViewportFollow.ts +40 -9
  149. package/src/directives/index.ts +14 -6
  150. package/src/engine/FocusManager.ts +510 -0
  151. package/src/engine/animation.ts +137 -19
  152. package/src/engine/bootstrap.ts +140 -6
  153. package/src/engine/directive.ts +4 -4
  154. package/src/engine/reactive.ts +979 -236
  155. package/src/engine/signal.ts +241 -47
  156. package/src/engine/trigger.ts +34 -7
  157. package/src/engine/utils.ts +19 -3
  158. package/src/hooks/useFocus.ts +91 -0
  159. package/src/hooks/useProps.ts +1 -1
  160. package/src/index.ts +8 -2
  161. package/src/types/pixi-cull.d.ts +7 -0
  162. package/src/utils/GlobalAssetLoader.ts +257 -0
  163. package/src/utils/functions.ts +7 -0
  164. package/src/utils/tabindex.ts +70 -0
  165. package/testing/index.ts +35 -4
  166. package/tsconfig.json +18 -0
  167. package/vite.config.ts +39 -0
@@ -1,11 +1,24 @@
1
- import { effect, signal, type WritableSignal } from "@signe/reactive";
1
+ import { effect, signal, type WritableSignal, type Signal } from "@signe/reactive";
2
2
  import { animate as animatePopmotion } from "popmotion";
3
+ import { Tick } from "../directives/Scheduler";
4
+ import { Subscription } from "rxjs";
5
+
6
+ /**
7
+ * Gets the global tick signal from the engine context.
8
+ * This is automatically set by the Canvas component when it initializes.
9
+ *
10
+ * @returns The global tick signal if available, undefined otherwise
11
+ */
12
+ function getGlobalTickSignal(): Signal<Tick> | undefined {
13
+ return (globalThis as any).__CANVAS_ENGINE_TICK__;
14
+ }
3
15
 
4
16
  export interface AnimateOptions<T> {
5
17
  duration?: number;
6
18
  ease?: (t: number) => number;
7
19
  onUpdate?: (value: T) => void;
8
20
  onComplete?: () => void;
21
+ tick?: Signal<Tick>;
9
22
  }
10
23
 
11
24
  export interface AnimatedState<T> {
@@ -19,12 +32,62 @@ export interface AnimatedSignal<T> extends Omit<WritableSignal<T>, 'set'> {
19
32
  set: (newValue: T, options?: AnimateOptions<T>) => Promise<void>;
20
33
  animatedState: WritableSignal<AnimatedState<T>>;
21
34
  update: (updater: (value: T) => T) => void;
35
+ pause: () => void;
36
+ resume: () => void;
22
37
  }
23
38
 
24
39
  export function isAnimatedSignal(signal: WritableSignal<any>): boolean {
25
40
  return (signal as unknown as AnimatedSignal<any>).animatedState !== undefined;
26
41
  }
27
42
 
43
+ /**
44
+ * Creates a popmotion driver that uses the engine's tick system.
45
+ * The driver subscribes to the tick signal and calls the update function with deltaTime on each tick.
46
+ *
47
+ * @param tickSignal - The tick signal from the engine context
48
+ * @returns A driver function for popmotion
49
+ * @example
50
+ * ```ts
51
+ * const driver = createTickDriver(context.tick);
52
+ * animate({
53
+ * to: 100,
54
+ * driver: driver
55
+ * });
56
+ * ```
57
+ */
58
+ function createTickDriver(tickSignal: Signal<Tick>) {
59
+ return (update: (delta: number) => void) => {
60
+ let subscription: Subscription | undefined;
61
+ let lastTimestamp: number | null = null;
62
+
63
+ const start = () => {
64
+ if (subscription) return;
65
+
66
+ subscription = (tickSignal.observable as any).subscribe((result: any) => {
67
+ const tick = result?.value ?? result;
68
+ if (!tick) return;
69
+
70
+ if (lastTimestamp === null) {
71
+ lastTimestamp = tick.timestamp;
72
+ return;
73
+ }
74
+
75
+ const delta = tick.deltaTime;
76
+ lastTimestamp = tick.timestamp;
77
+ update(delta);
78
+ });
79
+ };
80
+
81
+ const stop = () => {
82
+ subscription?.unsubscribe();
83
+ subscription = undefined;
84
+ lastTimestamp = null;
85
+ };
86
+
87
+ return { start, stop };
88
+ };
89
+ }
90
+
28
91
  /**
29
92
  * Creates an animated signal with the given initial value and animation options.
30
93
  * It's a writable signal that can be animated using popmotion. Properties of the animated signal are:
@@ -32,16 +95,26 @@ export function isAnimatedSignal(signal: WritableSignal<any>): boolean {
32
95
  * - start: the start value of the animation.
33
96
  * - end: the end value of the animation.
34
97
  *
98
+ * If a tick signal is provided in options, the animation will use the engine's tick system.
99
+ * Otherwise, it will automatically use the global tick signal from the Canvas context if available.
100
+ * If no tick signal is available, it will use requestAnimationFrame by default.
101
+ *
35
102
  * @param initialValue The initial value of the signal.
36
- * @param options The animation options.
103
+ * @param options The animation options. Can include a `tick` signal to use a specific tick system.
37
104
  * @returns The animated signal.
38
105
  * @example
106
+ * ```ts
107
+ * // Automatically uses the Canvas tick system if available, otherwise requestAnimationFrame
39
108
  * const animatedValue = animatedSignal(0, { duration: 1000 });
40
109
  * animatedValue.set(10);
41
- * animatedValue.update((value) => value + 1);
42
- * console.log(animatedValue()); // 11
43
110
  *
44
- * animatedValue.animatedState() // { current: 10, start: 10, end: 11 }
111
+ * // Explicitly using a specific tick signal
112
+ * mount((element) => {
113
+ * const tickSignal = element.props.context.tick;
114
+ * const animatedValue = animatedSignal(0, { duration: 1000, tick: tickSignal });
115
+ * animatedValue.set(10);
116
+ * });
117
+ * ```
45
118
  */
46
119
  export function animatedSignal<T>(initialValue: T, options: AnimateOptions<T> = {}): AnimatedSignal<T> {
47
120
  const state: AnimatedState<T> = {
@@ -49,7 +122,9 @@ export function animatedSignal<T>(initialValue: T, options: AnimateOptions<T> =
49
122
  start: initialValue,
50
123
  end: initialValue,
51
124
  };
52
- let animation
125
+ const DEFAULT_DURATION = 20;
126
+ let animation: { stop: () => void } | null = null;
127
+ let isPaused = false;
53
128
 
54
129
  const publicSignal = signal(initialValue);
55
130
  const privateSignal = signal(state);
@@ -76,24 +151,43 @@ export function animatedSignal<T>(initialValue: T, options: AnimateOptions<T> =
76
151
 
77
152
  privateSignal.set(newState);
78
153
 
154
+ // Stop any running animation
79
155
  if (animation) {
80
156
  animation.stop();
157
+ animation = null;
81
158
  }
82
159
 
160
+ isPaused = false;
161
+ const mergedConfig = { ...options, ...animationConfig };
162
+ const duration = mergedConfig.duration ?? DEFAULT_DURATION;
163
+ const ease = mergedConfig.ease ?? ((t: number) => t);
164
+ const tickSignal = mergedConfig.tick || getGlobalTickSignal();
165
+
166
+ const startValue = prevState.current;
167
+ const endValue = newValue;
168
+
169
+ const onCompleteCb = animationConfig.onComplete ?? options.onComplete;
170
+
171
+
83
172
  animation = animatePopmotion({
84
- // TODO
85
- duration: 20,
86
- ...options,
87
- ...animationConfig,
88
- from: prevState.current,
89
- to: newValue,
90
- onUpdate: (value) => {
91
- privateSignal.update(s => ({ ...s, current: value as T }));
92
- if (options.onUpdate) {
93
- options.onUpdate(value as T);
94
- }
173
+ from: startValue as any,
174
+ to: endValue as any,
175
+ duration,
176
+ ease,
177
+
178
+ onUpdate: (value: any) => {
179
+ if (isPaused) return;
180
+ const nextValue = value as T;
181
+ privateSignal.update(s => ({ ...s, current: nextValue }));
182
+ mergedConfig.onUpdate?.(nextValue);
183
+ animationConfig.onUpdate?.(nextValue);
95
184
  },
185
+ onComplete: () => {
186
+ privateSignal.update(s => ({ ...s, current: endValue }));
187
+ onCompleteCb?.();
188
+ }
96
189
  });
190
+
97
191
  }
98
192
 
99
193
  const fn = function() {
@@ -110,11 +204,35 @@ export function animatedSignal<T>(initialValue: T, options: AnimateOptions<T> =
110
204
  }
111
205
  fn.set = async (newValue: T, animationConfig: AnimateOptions<T> = {}) => {
112
206
  return new Promise<void>((resolve) => {
207
+ const userOnComplete = animationConfig.onComplete;
113
208
  animatedSignal(newValue, {
114
209
  ...animationConfig,
115
- onComplete: resolve
210
+ onComplete: () => {
211
+ if (userOnComplete) {
212
+ userOnComplete();
213
+ } else if (options.onComplete) {
214
+ options.onComplete();
215
+ }
216
+ resolve();
217
+ }
116
218
  });
117
- })
219
+ });
220
+ }
221
+ fn.pause = () => {
222
+ if (isPaused) return;
223
+ isPaused = true;
224
+ if (animation) {
225
+ animation.stop();
226
+ animation = null;
227
+ }
228
+ }
229
+ fn.resume = () => {
230
+ if (!isPaused) return;
231
+ isPaused = false;
232
+ const currentState = privateSignal();
233
+ if (currentState.current !== currentState.end) {
234
+ animatedSignal(currentState.end, options);
235
+ }
118
236
  }
119
237
 
120
238
  return fn as any
@@ -1,19 +1,153 @@
1
+ import { Application, ApplicationOptions } from "pixi.js";
2
+ import { Observable, Subscription } from "rxjs";
1
3
  import { ComponentFunction, h } from "./signal";
4
+ import { useProps } from '../hooks/useProps';
5
+ import { registerAllComponents, registerComponent } from './reactive';
6
+
7
+ // Import all components to ensure they are registered
8
+ // This is done here (not in reactive.ts) to avoid circular dependencies
9
+ // Components register themselves when their modules are imported
10
+ import '../components/Canvas';
11
+ import '../components/Container';
12
+ import '../components/Sprite';
13
+ import '../components/Text';
14
+ import '../components/Graphic';
15
+ import '../components/Mesh';
16
+ import '../components/Viewport';
17
+ import '../components/TilingSprite';
18
+ import '../components/NineSliceSprite';
19
+ import '../components/DOMContainer';
20
+ import '../components/DOMElement';
21
+ import '../components/ParticleEmitter';
22
+
23
+ /**
24
+ * Extended options for bootstrapCanvas that includes component registration configuration.
25
+ *
26
+ * @property components - Optional mapping of component names to their classes (can include mocks for testing)
27
+ * @property autoRegister - If true (default), registers all default components before applying custom components. If false, only registers the specified components.
28
+ */
29
+ export interface BootstrapOptions extends ApplicationOptions {
30
+ components?: {
31
+ [name: string]: any; // ComponentClass
32
+ };
33
+ autoRegister?: boolean; // true by default if components is not provided
34
+ enableLayout?: boolean; // true by default
35
+ }
36
+
37
+ type BootstrapResult = {
38
+ canvasElement: any;
39
+ app: Application;
40
+ hmrSubscription?: Subscription;
41
+ };
2
42
 
3
43
  /**
4
44
  * Bootstraps a canvas element and renders it to the DOM.
5
45
  *
6
46
  * @param rootElement - The HTML element where the canvas will be rendered. Can be null.
7
47
  * @param canvas - A Promise that resolves to an Element representing the canvas component.
48
+ * @param options - Optional bootstrap options including ApplicationOptions and component registration configuration.
8
49
  * @returns A Promise that resolves to the rendered canvas element.
9
50
  * @throws {Error} If the provided element is not a Canvas component.
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * // Default: all components registered automatically
55
+ * await bootstrapCanvas(rootElement, MyComponent, {
56
+ * width: 800,
57
+ * height: 600
58
+ * });
59
+ * ```
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * // With mocks for testing
64
+ * import { mockComponents } from '@canvasengine/testing';
65
+ * await bootstrapCanvas(rootElement, MyComponent, {
66
+ * components: mockComponents,
67
+ * autoRegister: false
68
+ * });
69
+ * ```
10
70
  */
11
- export const bootstrapCanvas = async (rootElement: HTMLElement | null, canvas: ComponentFunction<any>) => {
12
- const canvasElement = await h(canvas);
13
- if (canvasElement.tag != 'Canvas') {
14
- throw new Error('Canvas is required');
71
+ export const bootstrapCanvas = async (rootElement: HTMLElement | null, canvas: ComponentFunction<any>, options?: BootstrapOptions): Promise<BootstrapResult> => {
72
+ // Extract component registration options
73
+ const { components, autoRegister, enableLayout, ...appOptions } = options ?? {};
74
+ if (enableLayout !== false) {
75
+ await import('@pixi/layout');
76
+ }
77
+
78
+ // Handle component registration
79
+ if (components) {
80
+ if (autoRegister !== false) {
81
+ // Register all default components first, then override with custom ones
82
+ registerAllComponents();
83
+ }
84
+ // Register the specified components (overriding defaults if autoRegister is true)
85
+ Object.entries(components).forEach(([name, componentClass]) => {
86
+ registerComponent(name, componentClass);
87
+ });
88
+ } else {
89
+ // Default behavior: register all components
90
+ registerAllComponents();
91
+ }
92
+
93
+ const app = new Application();
94
+ await app.init({
95
+ resizeTo: rootElement,
96
+ autoStart: false,
97
+ antialias: true,
98
+ ...appOptions
99
+ });
100
+
101
+ const renderCanvasElement = (canvasElement: any) => {
102
+ if (canvasElement.tag != 'Canvas') {
103
+ throw new Error('Canvas is required');
104
+ }
105
+ canvasElement.render(rootElement, app);
106
+
107
+ const { backgroundColor } = useProps(canvasElement.props, {
108
+ backgroundColor: 'black'
109
+ });
110
+
111
+ app.renderer.background.color = backgroundColor()
112
+
113
+ return {
114
+ canvasElement,
115
+ app
116
+ };
117
+ };
118
+
119
+ const canvasElement = h(canvas) as any;
120
+
121
+ if (canvasElement instanceof Observable) {
122
+ return new Promise<BootstrapResult>((resolve, reject) => {
123
+ let resolved = false;
124
+ let hmrSubscription: Subscription;
125
+
126
+ hmrSubscription = canvasElement.subscribe({
127
+ next(value: any) {
128
+ try {
129
+ const nextCanvasElement = value?.elements?.[0] ?? value;
130
+ if (!nextCanvasElement) return;
131
+
132
+ const result = renderCanvasElement(nextCanvasElement);
133
+
134
+ if (!resolved) {
135
+ resolved = true;
136
+ Promise.resolve().then(() => {
137
+ resolve({
138
+ ...result,
139
+ hmrSubscription
140
+ });
141
+ });
142
+ }
143
+ } catch (error) {
144
+ reject(error);
145
+ }
146
+ },
147
+ error: reject
148
+ });
149
+ });
15
150
  }
16
- (canvasElement as any).render(rootElement);
17
151
 
18
- return canvasElement;
152
+ return renderCanvasElement(await canvasElement);
19
153
  };
@@ -3,21 +3,21 @@ import { Element } from "./reactive"
3
3
  export const directives: { [key: string]: any } = {}
4
4
 
5
5
  export abstract class Directive {
6
- abstract onDestroy();
6
+ abstract onDestroy(element: Element<any>);
7
7
  abstract onInit(element: Element<any>);
8
8
  abstract onMount(element: Element<any>);
9
- abstract onUpdate(props: any);
9
+ abstract onUpdate(props: any, element: Element<any>);
10
10
  }
11
11
 
12
12
  export function registerDirective(name: string, directive: any) {
13
13
  directives[name] = directive
14
14
  }
15
15
 
16
- export function applyDirective(element: Element, directiveName: string) {
16
+ export function applyDirective(element: Element<any>, directiveName: string) {
17
17
  if (!directives[directiveName]) {
18
18
  return null
19
19
  }
20
20
  const directive = new directives[directiveName]()
21
21
  directive.onInit?.(element)
22
22
  return directive
23
- }
23
+ }