@forgeax/engine-app 0.1.4 → 0.1.6

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 (145) hide show
  1. package/README.md +20 -14
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/__tests__/create-app-error-retention.integration.test.d.ts +2 -0
  4. package/dist/__tests__/create-app-error-retention.integration.test.d.ts.map +1 -0
  5. package/dist/__tests__/create-app-physics-plugin-failure.integration.test.d.ts +2 -0
  6. package/dist/__tests__/create-app-physics-plugin-failure.integration.test.d.ts.map +1 -0
  7. package/dist/animation-asset-lookup.d.ts +1 -2
  8. package/dist/animation-asset-lookup.d.ts.map +1 -1
  9. package/dist/create-app.d.ts +31 -10
  10. package/dist/create-app.d.ts.map +1 -1
  11. package/dist/engine-worker-runtime.mjs +72 -129
  12. package/dist/engine-worker-runtime.mjs.map +1 -1
  13. package/dist/errors.d.ts +3 -12
  14. package/dist/errors.d.ts.map +1 -1
  15. package/dist/execution/attached-world-swap.d.ts +1 -12
  16. package/dist/execution/attached-world-swap.d.ts.map +1 -1
  17. package/dist/execution/bootstrap-url.d.ts +5 -0
  18. package/dist/execution/bootstrap-url.d.ts.map +1 -0
  19. package/dist/execution/control.d.ts +0 -2
  20. package/dist/execution/control.d.ts.map +1 -1
  21. package/dist/execution/engine-worker.d.ts +1 -0
  22. package/dist/execution/engine-worker.d.ts.map +1 -1
  23. package/dist/execution/host-controller.d.ts.map +1 -1
  24. package/dist/execution/index.d.ts +1 -1
  25. package/dist/execution/index.d.ts.map +1 -1
  26. package/dist/execution/protocol.d.ts +4 -1
  27. package/dist/execution/protocol.d.ts.map +1 -1
  28. package/dist/execution/types.d.ts +17 -1
  29. package/dist/execution/types.d.ts.map +1 -1
  30. package/dist/game-context.d.ts +1 -1
  31. package/dist/game-context.d.ts.map +1 -1
  32. package/dist/index.d.ts +4 -2
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.mjs +331 -362
  35. package/dist/index.mjs.map +1 -1
  36. package/dist/internal/assembled-engine-profile.d.ts.map +1 -1
  37. package/dist/internal/assets-world-plugin.d.ts +3 -17
  38. package/dist/internal/assets-world-plugin.d.ts.map +1 -1
  39. package/dist/internal/browser-remote-bridge.d.ts +1 -2
  40. package/dist/internal/browser-remote-bridge.d.ts.map +1 -1
  41. package/dist/internal/browser-rhi-debug-runtime.d.ts +1 -1
  42. package/dist/internal/browser-rhi-debug-runtime.d.ts.map +1 -1
  43. package/dist/internal/debug-draw.d.ts +9 -0
  44. package/dist/internal/debug-draw.d.ts.map +1 -0
  45. package/dist/internal/engine-profile-common.d.ts +2 -2
  46. package/dist/internal/engine-profile-common.d.ts.map +1 -1
  47. package/dist/internal/frame-loop.d.ts +7 -4
  48. package/dist/internal/frame-loop.d.ts.map +1 -1
  49. package/dist/internal/main-engine-profile.d.ts +4 -0
  50. package/dist/internal/main-engine-profile.d.ts.map +1 -1
  51. package/dist/internal/remote-serve-flag.d.ts +3 -7
  52. package/dist/internal/remote-serve-flag.d.ts.map +1 -1
  53. package/dist/internal/rhi-capture.d.ts +1 -1
  54. package/dist/internal/rhi-capture.d.ts.map +1 -1
  55. package/dist/internal/worker-engine-profile.d.ts +2 -0
  56. package/dist/internal/worker-engine-profile.d.ts.map +1 -1
  57. package/dist/renderer-plugin.d.ts +25 -0
  58. package/dist/renderer-plugin.d.ts.map +1 -0
  59. package/dist/tool-preview/bootstrap.d.ts.map +1 -1
  60. package/dist/types.d.ts +21 -61
  61. package/dist/types.d.ts.map +1 -1
  62. package/package.json +25 -26
  63. package/src/__tests__/callback-inference.test-d.ts +7 -3
  64. package/src/__tests__/consumer-migration.unit.test.ts +13 -0
  65. package/src/__tests__/create-app-error-retention.integration.test.ts +125 -0
  66. package/src/__tests__/create-app-features.test.ts +21 -10
  67. package/src/__tests__/create-app-listener-sync.test.ts +23 -19
  68. package/src/__tests__/create-app-physics-plugin-failure.integration.test.ts +142 -0
  69. package/src/__tests__/create-app-stop.test.ts +4 -12
  70. package/src/__tests__/create-app.test-d.ts +12 -11
  71. package/src/__tests__/create-app.test.ts +1 -60
  72. package/src/__tests__/create-renderer-error.integration.test.ts +3 -2
  73. package/src/__tests__/create-renderer-lifecycle.integration.test.ts +10 -5
  74. package/src/__tests__/draw-source-injected-world-update-visibility.test.ts +7 -13
  75. package/src/__tests__/draw-source-single-world-regression.test.ts +23 -24
  76. package/src/__tests__/engine-worker-bootstrap-channel.unit.test.ts +8 -0
  77. package/src/__tests__/engine-worker-world-swap.unit.test.ts +15 -22
  78. package/src/__tests__/errors-pointer-lock-failed.test.ts +4 -7
  79. package/src/__tests__/execution-bootstrap-isolation.unit.test.ts +5 -6
  80. package/src/__tests__/execution-frame-order.unit.test.ts +2 -2
  81. package/src/__tests__/execution-frame-protocol.unit.test.ts +3 -4
  82. package/src/__tests__/execution-public-api.test-d.ts +4 -0
  83. package/src/__tests__/frame-loop-time-elapsed.test.ts +1 -1
  84. package/src/__tests__/frame-loop-time.unit.test.ts +1 -1
  85. package/src/__tests__/frame-loop-world-array.test.ts +82 -73
  86. package/src/__tests__/plugin-profiles.unit.test.ts +3 -3
  87. package/src/__tests__/profiler-default-off.test.ts +1 -1
  88. package/src/__tests__/profiler-frame-token.test.ts +17 -30
  89. package/src/__tests__/profiler-phase-integration.test.ts +15 -27
  90. package/src/__tests__/surface-handoff.test.ts +1 -4
  91. package/src/__tests__/visibility-remote.integration.test.ts +2 -5
  92. package/src/__tests__/worker-execution-stop.test.ts +64 -7
  93. package/src/animation-asset-lookup.ts +2 -2
  94. package/src/create-app.ts +197 -296
  95. package/src/errors.ts +27 -39
  96. package/src/execution/attached-world-swap.ts +4 -38
  97. package/src/execution/bootstrap-url.ts +25 -0
  98. package/src/execution/control.ts +3 -7
  99. package/src/execution/engine-worker-runtime.ts +23 -40
  100. package/src/execution/engine-worker.ts +2 -0
  101. package/src/execution/host-controller.ts +8 -2
  102. package/src/execution/index.ts +1 -0
  103. package/src/execution/protocol.ts +4 -1
  104. package/src/execution/types.ts +18 -1
  105. package/src/game-context.ts +1 -1
  106. package/src/index.ts +11 -4
  107. package/src/internal/assembled-engine-profile.ts +3 -11
  108. package/src/internal/assets-world-plugin.ts +7 -53
  109. package/src/internal/browser-remote-bridge.ts +2 -3
  110. package/src/internal/browser-rhi-debug-runtime.ts +1 -1
  111. package/src/internal/debug-draw.ts +38 -0
  112. package/src/internal/engine-profile-common.ts +2 -3
  113. package/src/internal/frame-loop.ts +77 -63
  114. package/src/internal/main-engine-profile.ts +21 -17
  115. package/src/internal/remote-serve-flag.ts +5 -14
  116. package/src/internal/rhi-capture.ts +1 -1
  117. package/src/internal/worker-engine-profile.ts +10 -10
  118. package/src/renderer-plugin.ts +96 -0
  119. package/src/tool-preview/bootstrap.ts +1 -14
  120. package/src/types.ts +22 -77
  121. package/src/vite-env.d.ts +0 -2
  122. package/dist/__tests__/app-rebuild.test.d.ts +0 -2
  123. package/dist/__tests__/app-rebuild.test.d.ts.map +0 -1
  124. package/dist/__tests__/asset-registry-types.test-d.d.ts +0 -2
  125. package/dist/__tests__/asset-registry-types.test-d.d.ts.map +0 -1
  126. package/dist/__tests__/assets-runtime-assembly.integration.test.d.ts +0 -2
  127. package/dist/__tests__/assets-runtime-assembly.integration.test.d.ts.map +0 -1
  128. package/dist/__tests__/draw-source-headless-full-chain.test.d.ts +0 -2
  129. package/dist/__tests__/draw-source-headless-full-chain.test.d.ts.map +0 -1
  130. package/dist/__tests__/ecs-import.unit.test.d.ts +0 -2
  131. package/dist/__tests__/ecs-import.unit.test.d.ts.map +0 -1
  132. package/dist/__tests__/execution-world-health-owner.test-d.d.ts +0 -2
  133. package/dist/__tests__/execution-world-health-owner.test-d.d.ts.map +0 -1
  134. package/dist/__tests__/remote-serve-flag.test.d.ts +0 -2
  135. package/dist/__tests__/remote-serve-flag.test.d.ts.map +0 -1
  136. package/dist/assets-runtime-assembly.d.ts +0 -19
  137. package/dist/assets-runtime-assembly.d.ts.map +0 -1
  138. package/src/__tests__/app-rebuild.test.ts +0 -31
  139. package/src/__tests__/asset-registry-types.test-d.ts +0 -16
  140. package/src/__tests__/assets-runtime-assembly.integration.test.ts +0 -68
  141. package/src/__tests__/draw-source-headless-full-chain.test.ts +0 -226
  142. package/src/__tests__/ecs-import.unit.test.ts +0 -40
  143. package/src/__tests__/execution-world-health-owner.test-d.ts +0 -9
  144. package/src/__tests__/remote-serve-flag.test.ts +0 -24
  145. package/src/assets-runtime-assembly.ts +0 -70
@@ -1,6 +1,7 @@
1
1
  import { World } from '@forgeax/engine-ecs';
2
+ import { createRenderReadLease } from '@forgeax/engine-ecs/projection';
2
3
  import { createProfiler, type ProfileCapture } from '@forgeax/engine-profiler';
3
- import type { DrawOwnerOptions, Renderer } from '@forgeax/engine-render';
4
+ import type { Renderer, RenderFrameInput } from '@forgeax/engine-render';
4
5
  import { describe, expect, it } from 'vitest';
5
6
 
6
7
  import { createFrameLoop } from '../internal/frame-loop';
@@ -32,18 +33,14 @@ function makeScheduler() {
32
33
  };
33
34
  }
34
35
 
35
- function makeRenderer(onDraw: (options: unknown) => void = () => {}): Renderer {
36
+ function makeRenderer(onDraw: (profileFrame: unknown) => void = () => {}): Renderer {
36
37
  return {
37
- backend: 'webgpu',
38
- ready: Promise.resolve({ ok: true, value: undefined }),
39
- attachWorld: () => ({ ok: true, value: undefined }),
40
- detachWorld: () => {},
41
- draw: (_worlds: World[], options: DrawOwnerOptions) => {
42
- onDraw(options);
38
+ attach: (world: World) => ({ ok: true, value: createRenderReadLease(world) }),
39
+ draw: (request: RenderFrameInput) => {
40
+ onDraw(request.profileFrame);
43
41
  return { ok: true, value: undefined };
44
42
  },
45
- onError: () => () => {},
46
- onLost: () => () => {},
43
+ subscribe: () => () => {},
47
44
  dispose: () => {},
48
45
  } as unknown as Renderer;
49
46
  }
@@ -98,42 +95,32 @@ describe('App profiler frame token', () => {
98
95
  const capture = finish(profiler);
99
96
  expect(capture.phaseCatalog.app).toEqual(APP_PHASE_CATALOG);
100
97
  expect(capture.captureId).toBe('capture-0001');
101
- expect(
102
- capture.records.filter(
103
- (record: ProfileCapture['records'][number]) => record.source === 'app',
104
- ),
105
- ).toHaveLength(10);
98
+ expect(capture.records.filter((record) => record.source === 'app')).toHaveLength(10);
106
99
  expect(
107
100
  capture.records
108
- .filter(
109
- (record: ProfileCapture['records'][number]) =>
110
- record.source === 'app' && record.kind === 'phase',
111
- )
112
- .map((record: ProfileCapture['records'][number]) => record.phase),
101
+ .filter((record) => record.source === 'app' && record.kind === 'phase')
102
+ .map((record) => record.phase),
113
103
  ).toEqual(expect.arrayContaining([...FRAME_LOOP_PHASES]));
114
104
  expect(
115
105
  new Set(
116
106
  capture.records
117
- .filter(
118
- (record: ProfileCapture['records'][number]) =>
119
- record.source === 'app' && record.kind === 'phase',
120
- )
121
- .map((record: ProfileCapture['records'][number]) => record.phase),
107
+ .filter((record) => record.source === 'app' && record.kind === 'phase')
108
+ .map((record) => record.phase),
122
109
  ),
123
110
  ).toEqual(new Set(FRAME_LOOP_PHASES));
124
111
  expect(
125
112
  new Set(
126
- capture.records
127
- .filter((record: ProfileCapture['records'][number]) => record.source === 'app')
128
- .map((record: ProfileCapture['records'][number]) => record.frameId),
113
+ capture.records.filter((record) => record.source === 'app').map((record) => record.frameId),
129
114
  ),
130
115
  ).toEqual(new Set([1, 2]));
131
116
  expect(drawOptions).toHaveLength(2);
132
117
  expect(drawOptions[0]).toMatchObject({
133
- profileFrame: { captureId: 'capture-0001', frameId: 1 },
118
+ captureId: 'capture-0001',
119
+ frameId: 1,
134
120
  });
135
121
  expect(drawOptions[1]).toMatchObject({
136
- profileFrame: { captureId: 'capture-0001', frameId: 2 },
122
+ captureId: 'capture-0001',
123
+ frameId: 2,
137
124
  });
138
125
  });
139
126
 
@@ -1,6 +1,7 @@
1
1
  import { World } from '@forgeax/engine-ecs';
2
- import { createProfiler, type ProfileCapture } from '@forgeax/engine-profiler';
3
- import type { DrawOwnerOptions, Renderer } from '@forgeax/engine-render';
2
+ import { createRenderReadLease } from '@forgeax/engine-ecs/projection';
3
+ import { createProfiler } from '@forgeax/engine-profiler';
4
+ import type { Renderer, RenderFrameInput } from '@forgeax/engine-render';
4
5
  import { describe, expect, it } from 'vitest';
5
6
 
6
7
  import { createFrameLoop } from '../internal/frame-loop';
@@ -24,18 +25,14 @@ function makeScheduler() {
24
25
  };
25
26
  }
26
27
 
27
- function makeRenderer(draw: (options: DrawOwnerOptions) => void): Renderer {
28
+ function makeRenderer(draw: (profileFrame: unknown) => void): Renderer {
28
29
  return {
29
- backend: 'webgpu',
30
- ready: Promise.resolve({ ok: true, value: undefined }),
31
- attachWorld: () => ({ ok: true, value: undefined }),
32
- detachWorld: () => {},
33
- draw: (_worlds: World[], options: DrawOwnerOptions) => {
34
- draw(options);
30
+ attach: (world: World) => ({ ok: true, value: createRenderReadLease(world) }),
31
+ draw: (request: RenderFrameInput) => {
32
+ draw(request.profileFrame);
35
33
  return { ok: true, value: undefined };
36
34
  },
37
- onError: () => () => {},
38
- onLost: () => () => {},
35
+ subscribe: () => () => {},
39
36
  dispose: () => {},
40
37
  } as unknown as Renderer;
41
38
  }
@@ -46,7 +43,7 @@ function start(profiler: ReturnType<typeof createProfiler>) {
46
43
  return result.value;
47
44
  }
48
45
 
49
- function finish(profiler: ReturnType<typeof createProfiler>): ProfileCapture {
46
+ function finish(profiler: ReturnType<typeof createProfiler>) {
50
47
  const session = profiler.activeSession();
51
48
  if (session === undefined) {
52
49
  const latest = profiler.latestCapture();
@@ -63,7 +60,7 @@ describe('App and Render profiler integration', () => {
63
60
  const profiler = createProfiler();
64
61
  start(profiler);
65
62
  const scheduler = makeScheduler();
66
- const drawOptions: DrawOwnerOptions[] = [];
63
+ const drawOptions: unknown[] = [];
67
64
  const loop = createFrameLoop({
68
65
  world: new World(),
69
66
  renderer: makeRenderer((options) => drawOptions.push(options)),
@@ -78,16 +75,11 @@ describe('App and Render profiler integration', () => {
78
75
  loop.stop().unwrap();
79
76
 
80
77
  const capture = finish(profiler);
81
- expect(
82
- capture.records.filter(
83
- (record: ProfileCapture['records'][number]) => record.source === 'app',
84
- ),
85
- ).toHaveLength(5);
86
- expect(
87
- capture.records.every((record: ProfileCapture['records'][number]) => record.frameId === 1),
88
- ).toBe(true);
78
+ expect(capture.records.filter((record) => record.source === 'app')).toHaveLength(5);
79
+ expect(capture.records.every((record) => record.frameId === 1)).toBe(true);
89
80
  expect(drawOptions[0]).toMatchObject({
90
- profileFrame: { captureId: capture.captureId, frameId: 1 },
81
+ captureId: capture.captureId,
82
+ frameId: 1,
91
83
  });
92
84
  expect(capture.phaseCatalog.app).toEqual(APP_PHASE_CATALOG);
93
85
  expect(profiler.phaseCatalog.app).toEqual([]);
@@ -120,10 +112,6 @@ describe('App and Render profiler integration', () => {
120
112
  const capture = finish(profiler);
121
113
  expect(draws).toBe(2);
122
114
  expect(errors).toHaveLength(2);
123
- expect(
124
- capture.records.filter(
125
- (record: ProfileCapture['records'][number]) => record.source === 'app',
126
- ),
127
- ).toHaveLength(10);
115
+ expect(capture.records.filter((record) => record.source === 'app')).toHaveLength(10);
128
116
  });
129
117
  });
@@ -30,10 +30,7 @@ describe('createApp presentation surface handoff', () => {
30
30
  drawSawReleasedSurface = surfaceReleased;
31
31
  return ok(undefined);
32
32
  },
33
- onError(): () => void {
34
- return () => {};
35
- },
36
- onLost(): () => void {
33
+ subscribe(): () => void {
37
34
  return () => {};
38
35
  },
39
36
  releaseSurface(): { ok: true; value: undefined } {
@@ -37,12 +37,11 @@ function makeRendererStub(): Renderer {
37
37
  onError: () => () => {},
38
38
  onLost: () => () => {},
39
39
  dispose: () => {},
40
- visibilityStats: { explicitlyHidden: 1 },
41
40
  } as unknown as Renderer;
42
41
  }
43
42
 
44
43
  describe('createApp to remote visibility discovery', () => {
45
- it('introspects then evaluates a Query, recovers an invalid write, and reads stats', async () => {
44
+ it('introspects then evaluates a Query and recovers an invalid write', async () => {
46
45
  const previous = process.env.FORGEAX_ENGINE_REMOTE_SERVE;
47
46
  process.env.FORGEAX_ENGINE_REMOTE_SERVE = '1';
48
47
  const world = new World();
@@ -77,7 +76,7 @@ describe('createApp to remote visibility discovery', () => {
77
76
  const query = world.query({ read: [render.Visibility] }).unwrap();
78
77
  let current;
79
78
  for (const row of query) {
80
- current = render.visibilityStateFromU32(row.get(render.Visibility).state);
79
+ current = ['inherited', 'hidden', 'visible'][row.get(render.Visibility).state];
81
80
  }
82
81
  const effective = render.resolveVisibility(world).effective(entity);
83
82
  const invalid = world.set(entity, render.Visibility, { state: 99 });
@@ -95,7 +94,6 @@ describe('createApp to remote visibility discovery', () => {
95
94
  },
96
95
  recovered: recovered.ok,
97
96
  restored: render.resolveVisibility(world).effective(entity),
98
- visibilityStats: renderer.visibilityStats,
99
97
  };
100
98
  })()`);
101
99
  expect(value).toMatchObject({
@@ -104,7 +102,6 @@ describe('createApp to remote visibility discovery', () => {
104
102
  invalid: { code: 'component-field-invalid-value' },
105
103
  recovered: true,
106
104
  restored: 'visible',
107
- visibilityStats: { explicitlyHidden: 1 },
108
105
  });
109
106
  expect((value as { invalid: { hint: string } }).invalid.hint.length).toBeGreaterThan(0);
110
107
  } finally {
@@ -1,12 +1,22 @@
1
1
  import { beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import type { EngineToHostMessage } from '../execution/protocol';
2
3
 
3
- const probes = vi.hoisted(() => ({
4
- audioDispose: vi.fn(),
5
- inputDetach: vi.fn(),
6
- sessionDispose: vi.fn(),
7
- sessionListen: vi.fn(() => () => {}),
8
- sessionPost: vi.fn(),
9
- }));
4
+ type SessionListener = (message: EngineToHostMessage) => void;
5
+
6
+ const probes = vi.hoisted(() => {
7
+ const sessionListeners: SessionListener[] = [];
8
+ return {
9
+ audioDispose: vi.fn(),
10
+ inputDetach: vi.fn(),
11
+ sessionDispose: vi.fn(),
12
+ sessionListen: vi.fn((listener: SessionListener) => {
13
+ sessionListeners.push(listener);
14
+ return () => {};
15
+ }),
16
+ sessionListeners,
17
+ sessionPost: vi.fn(),
18
+ };
19
+ });
10
20
 
11
21
  vi.mock('../execution/engine-worker', async () => {
12
22
  const { ok } = await import('@forgeax/engine-types');
@@ -73,6 +83,7 @@ const capabilities = {
73
83
  describe('Worker ExecutionApp terminal stop', () => {
74
84
  beforeEach(() => {
75
85
  vi.clearAllMocks();
86
+ probes.sessionListeners.length = 0;
76
87
  });
77
88
 
78
89
  it('cleans every host owner once when stopped while paused and cannot restart', async () => {
@@ -113,4 +124,50 @@ describe('Worker ExecutionApp terminal stop', () => {
113
124
  if (!restart.ok) expect(restart.error.code).toBe('app-not-started');
114
125
  expect(raf).toHaveBeenCalledTimes(1);
115
126
  });
127
+
128
+ it('retains the existing terminal fault identity for host inspection', async () => {
129
+ vi.stubGlobal(
130
+ 'requestAnimationFrame',
131
+ vi.fn(() => 7),
132
+ );
133
+ vi.stubGlobal('cancelAnimationFrame', vi.fn());
134
+ const result = await createWorkerExecutionApp({
135
+ canvas: {} as HTMLCanvasElement,
136
+ appOptions: { execution: { bootstrap: 'https://example.test/game.js' } } as never,
137
+ capabilities,
138
+ selection: {
139
+ requestedTier: 'engine-worker',
140
+ actualTier: 'engine-worker',
141
+ selectionReason: 'explicit-request',
142
+ missingCapabilities: [],
143
+ sharedEvidencePassed: false,
144
+ },
145
+ });
146
+ expect(result.ok).toBe(true);
147
+ if (!result.ok) return;
148
+ let observed: unknown;
149
+ result.value.onError((error) => {
150
+ observed = error;
151
+ });
152
+ const listener = probes.sessionListeners[0];
153
+ expect(listener).toBeTypeOf('function');
154
+
155
+ listener?.({
156
+ kind: 'fault',
157
+ worldIdentity: 'worker-world',
158
+ source: 'world',
159
+ code: 'app-system-update-failed',
160
+ expected: 'worker world update succeeds',
161
+ hint: 'inspect the retained cause',
162
+ detail: { cause: 'worker boom' },
163
+ partialWrite: true,
164
+ retryable: false,
165
+ });
166
+
167
+ expect(result.value.lastError).toBe(observed);
168
+ expect(result.value.lastError).toMatchObject({
169
+ code: 'app-system-update-failed',
170
+ detail: { cause: { cause: 'worker boom' } },
171
+ });
172
+ });
116
173
  });
@@ -1,8 +1,8 @@
1
1
  import type { AnimationPayloadLookup } from '@forgeax/engine-animation';
2
- import type { AnimationClip, Asset } from '@forgeax/engine-types';
2
+ import type { AnimationClip } from '@forgeax/engine-types';
3
3
 
4
4
  export interface AnimationPayloadSource {
5
- lookup<T extends Asset = Asset>(guid: string): T | undefined;
5
+ lookup<T = unknown>(guid: string): T | undefined;
6
6
  }
7
7
 
8
8
  /** Bridge the renderer-owned GUID catalogue into the animation plugin. */