@duyquangnvx/spindle 1.0.0-beta.1 → 1.0.0-beta.2

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
@@ -14,7 +14,6 @@ Subpath exports:
14
14
 
15
15
  ```ts
16
16
  import { createSpindle } from "@jagaming/spindle"; // core engine
17
- import { createSlotRenderer } from "@jagaming/spindle/renderer"; // abstract renderer
18
17
  import { recording } from "@jagaming/spindle/testing"; // test utilities
19
18
  ```
20
19
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duyquangnvx/spindle",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.2",
4
4
  "description": "Headless TypeScript slot engine",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -26,19 +26,11 @@
26
26
  "types": "./dist/testing/index.d.cts",
27
27
  "default": "./dist/testing/index.cjs"
28
28
  }
29
- },
30
- "./renderer": {
31
- "import": {
32
- "types": "./dist/renderer/index.d.mts",
33
- "default": "./dist/renderer/index.mjs"
34
- },
35
- "require": {
36
- "types": "./dist/renderer/index.d.cts",
37
- "default": "./dist/renderer/index.cjs"
38
- }
39
29
  }
40
30
  },
41
- "files": ["dist"],
31
+ "files": [
32
+ "dist"
33
+ ],
42
34
  "scripts": {
43
35
  "build": "tsdown",
44
36
  "dev": "tsdown --watch",
@@ -50,7 +42,11 @@
50
42
  "clean": "rm -rf dist",
51
43
  "prepublishOnly": "npm run build"
52
44
  },
53
- "keywords": ["slot", "game", "engine"],
45
+ "keywords": [
46
+ "slot",
47
+ "game",
48
+ "engine"
49
+ ],
54
50
  "license": "UNLICENSED",
55
51
  "devDependencies": {
56
52
  "@biomejs/biome": "^1.9.0",
@@ -58,4 +54,4 @@
58
54
  "typescript": "^5.7.0",
59
55
  "vitest": "^4.0.18"
60
56
  }
61
- }
57
+ }
@@ -1,548 +0,0 @@
1
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_types = require('../types-NL78Eg3j.cjs');
3
-
4
- //#region src/renderer/timeout.ts
5
- function withTimeout(promise, ms, label) {
6
- if (ms <= 0 || !Number.isFinite(ms)) return promise;
7
- return new Promise((resolve, reject) => {
8
- const timer = setTimeout(() => {
9
- reject(/* @__PURE__ */ new Error(`Timeout: ${label} exceeded ${ms}ms`));
10
- }, ms);
11
- promise.then((value) => {
12
- clearTimeout(timer);
13
- resolve(value);
14
- }, (err) => {
15
- clearTimeout(timer);
16
- reject(err);
17
- });
18
- });
19
- }
20
-
21
- //#endregion
22
- //#region src/renderer/scenes/free-spins-scene.ts
23
- var FreeSpinsScene = class {
24
- scene;
25
- hud;
26
- timeout;
27
- constructor(scene, hud, timeout) {
28
- this.scene = scene;
29
- this.hud = hud;
30
- this.timeout = timeout;
31
- }
32
- async onFreeSpinsEnter(data) {
33
- await withTimeout(this.scene.transitionTo("freeSpins"), this.timeout, "SceneView.transitionTo(freeSpins)");
34
- this.hud.showFeatureCounter(0, data.totalSpins);
35
- }
36
- async onFreeSpinStart(data) {
37
- this.hud.showFeatureCounter(data.currentSpin, data.totalSpins);
38
- }
39
- async onFreeSpinsRetrigger(data) {
40
- this.hud.showFeatureCounter(data.totalSpins - data.added, data.totalSpins);
41
- }
42
- async onFreeSpinsExit(data) {
43
- await withTimeout(this.hud.animateWinCounter(0, data.totalWin), this.timeout, "HUD.animateWinCounter(freeSpinsExit)");
44
- await withTimeout(this.scene.transitionTo("base"), this.timeout, "SceneView.transitionTo(base)");
45
- }
46
- };
47
-
48
- //#endregion
49
- //#region src/renderer/scenes/hold-and-spin-scene.ts
50
- var HoldAndSpinScene = class {
51
- scene;
52
- hud;
53
- gridManager;
54
- timeout;
55
- constructor(scene, hud, gridManager, timeout) {
56
- this.scene = scene;
57
- this.hud = hud;
58
- this.gridManager = gridManager;
59
- this.timeout = timeout;
60
- }
61
- async onHoldAndSpinEnter(data) {
62
- await withTimeout(this.scene.transitionTo("holdAndSpin"), this.timeout, "SceneView.transitionTo(holdAndSpin)");
63
- this.hud.showFeatureCounter(0, data.totalRounds);
64
- for (const locked of data.lockedSymbols) this.gridManager.getSymbolAt(locked.position.reel, locked.position.row).setSticky(true);
65
- }
66
- async onHoldAndSpinRound(data) {
67
- this.hud.showFeatureCounter(data.round, data.round + data.remaining);
68
- for (const locked of data.newLocked) this.gridManager.getSymbolAt(locked.position.reel, locked.position.row).setSticky(true);
69
- }
70
- async onHoldAndSpinExit(data) {
71
- await withTimeout(this.hud.animateWinCounter(0, data.totalWin), this.timeout, "HUD.animateWinCounter(holdAndSpinExit)");
72
- await withTimeout(this.scene.transitionTo("base"), this.timeout, "SceneView.transitionTo(base)");
73
- }
74
- };
75
-
76
- //#endregion
77
- //#region src/renderer/delegate-builder.ts
78
- var DelegateBuilder = class {
79
- views;
80
- systems;
81
- gridManager;
82
- timeout;
83
- constructor(views, systems, gridManager, timeout) {
84
- this.views = views;
85
- this.systems = systems;
86
- this.gridManager = gridManager;
87
- this.timeout = timeout;
88
- }
89
- build() {
90
- const delegate = {};
91
- this.wireCore(delegate);
92
- this.wireReels(delegate);
93
- if (this.systems.winPresenter) this.wireWins(delegate, this.systems.winPresenter);
94
- if (this.systems.wildPresenter) this.wireWilds(delegate, this.systems.wildPresenter);
95
- if (this.systems.cascadeOrchestrator) this.wireCascade(delegate, this.systems.cascadeOrchestrator);
96
- if (this.systems.scatterPresenter) this.wireScatter(delegate, this.systems.scatterPresenter);
97
- this.wireCelebrations(delegate);
98
- this.wireSymbolTransform(delegate);
99
- this.wireFeatureScenes(delegate);
100
- this.wireBonusViews(delegate);
101
- return delegate;
102
- }
103
- wireCore(delegate) {
104
- const { hud, server } = this.views;
105
- const timeout = this.timeout;
106
- delegate.onSpinStart = async () => {
107
- hud.lock();
108
- };
109
- delegate.onSpinEnd = async (data) => {
110
- hud.unlock();
111
- if (data.totalWin > 0) await withTimeout(hud.animateWinCounter(0, data.totalWin), timeout, "HUD.animateWinCounter");
112
- };
113
- delegate.requestSpinResult = async (context) => {
114
- return server.spin(context);
115
- };
116
- }
117
- wireReels(delegate) {
118
- const { reelSystem } = this.systems;
119
- const gm = this.gridManager;
120
- delegate.presentReelStop = async (data) => {
121
- await reelSystem.handleReelStop(data, gm);
122
- };
123
- delegate.presentAnticipation = async (data) => {
124
- await reelSystem.handleAnticipation(data);
125
- };
126
- }
127
- wireWins(delegate, wp) {
128
- const gm = this.gridManager;
129
- const present = async (data) => {
130
- const { mode, metadata, ...win } = data;
131
- await wp.presentWin(win, gm, {
132
- mode,
133
- metadata
134
- });
135
- };
136
- delegate.presentWaysWin = present;
137
- delegate.presentPaylineWin = present;
138
- delegate.presentClusterWin = present;
139
- }
140
- wireWilds(delegate, wild) {
141
- const gm = this.gridManager;
142
- delegate.presentExpandingWild = async (data) => {
143
- await wild.handleExpandingWild(data, gm);
144
- };
145
- delegate.presentStickyWild = async (data) => {
146
- await wild.handleStickyWild(data, gm);
147
- };
148
- delegate.presentWalkingWild = async (data) => {
149
- await wild.handleWalkingWild(data, gm);
150
- };
151
- delegate.presentStackedWild = async (data) => {
152
- await wild.handleStackedWild(data, gm);
153
- };
154
- delegate.presentMultiplierWild = async (data) => {
155
- await wild.handleMultiplierWild(data, gm);
156
- };
157
- delegate.presentRandomWild = async (data) => {
158
- await wild.handleRandomWild(data, gm);
159
- };
160
- }
161
- wireCascade(delegate, cascade) {
162
- const gm = this.gridManager;
163
- delegate.presentCascadeDestroy = async (data) => {
164
- await cascade.handleDestroy(data, gm);
165
- };
166
- delegate.presentCascadeDrop = async (data) => {
167
- await cascade.handleDrop(data, gm);
168
- };
169
- delegate.presentCascadeFill = async (data) => {
170
- await cascade.handleFill(data, gm);
171
- };
172
- }
173
- wireScatter(delegate, scatter) {
174
- const gm = this.gridManager;
175
- delegate.presentScatterWin = async (data) => {
176
- await scatter.handleScatterWin(data, gm);
177
- };
178
- }
179
- wireCelebrations(delegate) {
180
- const { celebration } = this.views;
181
- const { hud } = this.views;
182
- const timeout = this.timeout;
183
- delegate.presentBigWin = async (data) => {
184
- await withTimeout(celebration.playBigWin(data.tier, data.amount), timeout, "CelebrationView.playBigWin");
185
- };
186
- delegate.presentJackpotTrigger = async (data) => {
187
- await withTimeout(celebration.playJackpot(data.tier, data.amount), timeout, "CelebrationView.playJackpot");
188
- };
189
- delegate.onJackpotAwarded = async (data) => {
190
- await withTimeout(hud.animateWinCounter(0, data.amount), timeout, "HUD.animateWinCounter(jackpot)");
191
- };
192
- }
193
- wireFeatureScenes(delegate) {
194
- const freeSpins = new FreeSpinsScene(this.views.scene, this.views.hud, this.timeout);
195
- const holdAndSpin = new HoldAndSpinScene(this.views.scene, this.views.hud, this.gridManager, this.timeout);
196
- delegate.onFreeSpinsEnter = async (data) => {
197
- await freeSpins.onFreeSpinsEnter(data);
198
- };
199
- delegate.onFreeSpinStart = async (data) => {
200
- await freeSpins.onFreeSpinStart(data);
201
- };
202
- delegate.onFreeSpinsRetrigger = async (data) => {
203
- await freeSpins.onFreeSpinsRetrigger(data);
204
- };
205
- delegate.onFreeSpinsExit = async (data) => {
206
- await freeSpins.onFreeSpinsExit(data);
207
- };
208
- delegate.onHoldAndSpinEnter = async (data) => {
209
- await holdAndSpin.onHoldAndSpinEnter(data);
210
- };
211
- delegate.onHoldAndSpinRound = async (data) => {
212
- await holdAndSpin.onHoldAndSpinRound(data);
213
- };
214
- delegate.onHoldAndSpinExit = async (data) => {
215
- await holdAndSpin.onHoldAndSpinExit(data);
216
- };
217
- }
218
- wireSymbolTransform(delegate) {
219
- const gm = this.gridManager;
220
- const timeout = this.timeout;
221
- delegate.presentSymbolTransform = async (data) => {
222
- for (const t of data.transforms) await withTimeout(gm.getSymbolAt(t.position.reel, t.position.row).transform(t.to), timeout, `SymbolView.transform at reel:${t.position.reel} row:${t.position.row}`);
223
- };
224
- }
225
- wireBonusViews(delegate) {
226
- const { pickBonus, wheelBonus, gamble, server } = this.views;
227
- const timeout = this.timeout;
228
- delegate.onPickBonusEnter = async (data) => {
229
- await withTimeout(pickBonus.show(data.itemCount), timeout, "PickBonusView.show");
230
- };
231
- delegate.requestPickChoice = async (_data) => {
232
- return { choiceIndex: await withTimeout(pickBonus.waitForPick(), timeout, "PickBonusView.waitForPick") };
233
- };
234
- delegate.requestPickReveal = async (data) => {
235
- if (!server.pickReveal) throw new Error("ServerAdapter.pickReveal() not implemented");
236
- return server.pickReveal(data);
237
- };
238
- delegate.presentPickReveal = async (data) => {
239
- await withTimeout(pickBonus.revealItem(data.choiceIndex, data.prize), timeout, "PickBonusView.revealItem");
240
- };
241
- delegate.onPickBonusExit = async (_data) => {
242
- await withTimeout(pickBonus.hide(), timeout, "PickBonusView.hide");
243
- };
244
- delegate.onWheelBonusEnter = async (data) => {
245
- await withTimeout(wheelBonus.show(data.segments), timeout, "WheelBonusView.show");
246
- };
247
- delegate.requestWheelSpinResult = async (data) => {
248
- if (!server.wheelSpin) throw new Error("ServerAdapter.wheelSpin() not implemented");
249
- return server.wheelSpin(data);
250
- };
251
- delegate.presentWheelResult = async (data) => {
252
- await withTimeout(wheelBonus.spinTo(data.segmentIndex), timeout, "WheelBonusView.spinTo");
253
- };
254
- delegate.onWheelBonusExit = async (_data) => {
255
- await withTimeout(wheelBonus.hide(), timeout, "WheelBonusView.hide");
256
- };
257
- delegate.onGambleStart = async (data) => {
258
- await withTimeout(gamble.show(data.currentWin), timeout, "GambleView.show");
259
- };
260
- delegate.requestGambleChoice = async (_data) => {
261
- return withTimeout(gamble.waitForChoice(), timeout, "GambleView.waitForChoice");
262
- };
263
- delegate.requestGambleResult = async (data) => {
264
- if (!server.gambleResult) throw new Error("ServerAdapter.gambleResult() not implemented");
265
- return server.gambleResult(data);
266
- };
267
- delegate.presentGambleResult = async (data) => {
268
- await withTimeout(gamble.revealResult(data), timeout, "GambleView.revealResult");
269
- };
270
- delegate.onGambleEnd = async (_data) => {
271
- await withTimeout(gamble.hide(), timeout, "GambleView.hide");
272
- };
273
- }
274
- };
275
-
276
- //#endregion
277
- //#region src/renderer/systems/cascade-orchestrator.ts
278
- var DefaultCascadeOrchestrator = class {
279
- timeout;
280
- destroyedPositions = /* @__PURE__ */ new Set();
281
- constructor(timeout) {
282
- this.timeout = timeout;
283
- }
284
- async handleDestroy(data, gridManager) {
285
- for (const pos of data.positions) this.destroyedPositions.add(`${pos.reel},${pos.row}`);
286
- const destroyPromises = data.positions.map((pos) => {
287
- return withTimeout(gridManager.getSymbolAt(pos.reel, pos.row).destroy(), this.timeout, `SymbolView.destroy at reel:${pos.reel} row:${pos.row}`);
288
- });
289
- await Promise.all(destroyPromises);
290
- }
291
- async handleDrop(_data, _gridManager) {}
292
- async handleFill(data, gridManager) {
293
- for (let reel = 0; reel < data.grid.length; reel++) for (let row = 0; row < data.grid[reel].length; row++) {
294
- const key = `${reel},${row}`;
295
- if (this.destroyedPositions.has(key)) gridManager.replaceSymbol(reel, row, data.grid[reel][row]);
296
- else gridManager.updateSymbol(reel, row, data.grid[reel][row]);
297
- }
298
- this.destroyedPositions.clear();
299
- }
300
- };
301
-
302
- //#endregion
303
- //#region src/renderer/systems/defaults.ts
304
- const noopSceneView = { async transitionTo() {} };
305
- const noopHUD = {
306
- setBalance() {},
307
- async animateWinCounter() {},
308
- showFeatureCounter() {},
309
- lock() {},
310
- unlock() {}
311
- };
312
- const noopCelebrationView = {
313
- async playBigWin() {},
314
- async playJackpot() {}
315
- };
316
- const noopPickBonusView = {
317
- async show() {},
318
- async waitForPick() {
319
- return 0;
320
- },
321
- async revealItem() {},
322
- async hide() {}
323
- };
324
- const noopWheelBonusView = {
325
- async show() {},
326
- async spinTo() {},
327
- async hide() {}
328
- };
329
- const noopGambleView = {
330
- async show() {},
331
- async waitForChoice() {
332
- return { action: "collect" };
333
- },
334
- async revealResult() {},
335
- async hide() {}
336
- };
337
-
338
- //#endregion
339
- //#region src/renderer/systems/grid-manager.ts
340
- var GridManager = class {
341
- grid;
342
- factory;
343
- constructor(reels, rows, factory) {
344
- this.factory = factory;
345
- this.grid = [];
346
- for (let r = 0; r < reels; r++) {
347
- const column = [];
348
- for (let row = 0; row < rows; row++) column.push(null);
349
- this.grid.push(column);
350
- }
351
- }
352
- ensureSymbol(reel, row, symbolId) {
353
- const existing = this.grid[reel][row];
354
- if (existing) {
355
- existing.setSymbol(symbolId);
356
- return existing;
357
- }
358
- const view = this.factory.create(symbolId, reel, row);
359
- this.grid[reel][row] = view;
360
- return view;
361
- }
362
- getSymbolAt(reel, row) {
363
- const view = this.grid[reel][row];
364
- if (!view) throw new Error(`No SymbolView at reel:${reel} row:${row} — grid not yet initialized`);
365
- return view;
366
- }
367
- replaceSymbol(reel, row, newId) {
368
- const old = this.grid[reel][row];
369
- if (old) old.destroy();
370
- const view = this.factory.create(newId, reel, row);
371
- this.grid[reel][row] = view;
372
- return view;
373
- }
374
- updateSymbol(reel, row, symbolId) {
375
- this.getSymbolAt(reel, row).setSymbol(symbolId);
376
- }
377
- getColumn(reel) {
378
- return this.grid[reel].filter((v) => v !== null);
379
- }
380
- forEachPosition(fn) {
381
- for (let r = 0; r < this.grid.length; r++) {
382
- const column = this.grid[r];
383
- for (let row = 0; row < column.length; row++) {
384
- const view = column[row];
385
- if (view) fn(view, r, row);
386
- }
387
- }
388
- }
389
- getPositions(positions) {
390
- return positions.map((p) => this.getSymbolAt(p.reel, p.row));
391
- }
392
- resize(reels, rowsPerReel) {
393
- this.grid = [];
394
- for (let r = 0; r < reels; r++) {
395
- const rows = rowsPerReel[r];
396
- const column = [];
397
- for (let row = 0; row < rows; row++) column.push(null);
398
- this.grid.push(column);
399
- }
400
- }
401
- get reelCount() {
402
- return this.grid.length;
403
- }
404
- getRowCount(reel) {
405
- return this.grid[reel].length;
406
- }
407
- };
408
-
409
- //#endregion
410
- //#region src/renderer/systems/reel-system.ts
411
- var DefaultReelSystem = class {
412
- config;
413
- timeout;
414
- constructor(config, timeout) {
415
- this.config = config;
416
- this.timeout = timeout;
417
- }
418
- async handleReelStop(data, gridManager) {
419
- const { reelIndex, symbols } = data;
420
- for (let row = 0; row < symbols.length; row++) gridManager.ensureSymbol(reelIndex, row, symbols[row]);
421
- if (this.config.stopDelay > 0) await this.delay(this.config.stopDelay);
422
- }
423
- async handleAnticipation(_data) {
424
- if (this.config.anticipationDelay > 0) await this.delay(this.config.anticipationDelay);
425
- }
426
- delay(ms) {
427
- return withTimeout(new Promise((resolve) => setTimeout(resolve, ms)), this.timeout, `ReelSystem.delay(${ms})`);
428
- }
429
- };
430
-
431
- //#endregion
432
- //#region src/renderer/systems/scatter-presenter.ts
433
- var DefaultScatterPresenter = class {
434
- timeout;
435
- constructor(timeout) {
436
- this.timeout = timeout;
437
- }
438
- async handleScatterWin(data, gridManager) {
439
- gridManager.forEachPosition((view) => view.dim());
440
- for (const pos of data.positions) gridManager.getSymbolAt(pos.reel, pos.row).undim();
441
- const winPromises = data.positions.map((pos) => {
442
- return withTimeout(gridManager.getSymbolAt(pos.reel, pos.row).playWin(), this.timeout, `SymbolView.playWin(scatter) at reel:${pos.reel} row:${pos.row}`);
443
- });
444
- await Promise.all(winPromises);
445
- gridManager.forEachPosition((view) => view.playIdle());
446
- }
447
- };
448
-
449
- //#endregion
450
- //#region src/renderer/systems/wild-presenter.ts
451
- var DefaultWildPresenter = class {
452
- wildSymbolId;
453
- constructor(wildSymbolId = require_types.createSymbolId("WILD")) {
454
- this.wildSymbolId = wildSymbolId;
455
- }
456
- async handleExpandingWild(data, gridManager) {
457
- for (const pos of data.expandedPositions) gridManager.getSymbolAt(pos.reel, pos.row).setSymbol(this.wildSymbolId);
458
- }
459
- async handleStickyWild(data, gridManager) {
460
- gridManager.getSymbolAt(data.position.reel, data.position.row).setSticky(true);
461
- }
462
- async handleWalkingWild(data, gridManager) {
463
- gridManager.getSymbolAt(data.from.reel, data.from.row).setSticky(false);
464
- gridManager.getSymbolAt(data.to.reel, data.to.row).setSymbol(this.wildSymbolId);
465
- gridManager.getSymbolAt(data.to.reel, data.to.row).setSticky(true);
466
- }
467
- async handleStackedWild(data, gridManager) {
468
- for (const pos of data.positions) gridManager.getSymbolAt(pos.reel, pos.row).setSymbol(this.wildSymbolId);
469
- }
470
- async handleMultiplierWild(data, gridManager) {
471
- const view = gridManager.getSymbolAt(data.position.reel, data.position.row);
472
- view.setSymbol(this.wildSymbolId);
473
- view.showMultiplier(data.multiplier);
474
- }
475
- async handleRandomWild(data, gridManager) {
476
- for (const pos of data.positions) gridManager.getSymbolAt(pos.reel, pos.row).setSymbol(this.wildSymbolId);
477
- }
478
- };
479
-
480
- //#endregion
481
- //#region src/renderer/systems/win-presenter.ts
482
- var DefaultWinPresenter = class {
483
- timeout;
484
- constructor(timeout) {
485
- this.timeout = timeout;
486
- }
487
- async presentWin(win, gridManager, _ctx) {
488
- gridManager.forEachPosition((view) => view.dim());
489
- for (const pos of win.positions) gridManager.getSymbolAt(pos.reel, pos.row).undim();
490
- const winPromises = win.positions.map((pos) => {
491
- return withTimeout(gridManager.getSymbolAt(pos.reel, pos.row).playWin(), this.timeout, `SymbolView.playWin at reel:${pos.reel} row:${pos.row}`);
492
- });
493
- await Promise.all(winPromises);
494
- gridManager.forEachPosition((view) => view.playIdle());
495
- }
496
- };
497
-
498
- //#endregion
499
- //#region src/renderer/slot-renderer.ts
500
- const DEFAULT_TIMEOUT = 3e4;
501
- function createSlotRenderer(config) {
502
- validateConfig(config);
503
- const timeout = config.timeout ?? DEFAULT_TIMEOUT;
504
- const { gameConfig, views, reel } = config;
505
- const gridManager = new GridManager(gameConfig.reels, gameConfig.rows, views.symbolFactory);
506
- return {
507
- delegate: new DelegateBuilder({
508
- server: views.server,
509
- scene: views.scene ?? noopSceneView,
510
- hud: views.hud ?? noopHUD,
511
- celebration: views.celebration ?? noopCelebrationView,
512
- pickBonus: views.pickBonus ?? noopPickBonusView,
513
- wheelBonus: views.wheelBonus ?? noopWheelBonusView,
514
- gamble: views.gamble ?? noopGambleView
515
- }, {
516
- reelSystem: config.overrides?.reelSystem ?? new DefaultReelSystem(reel, timeout),
517
- winPresenter: config.overrides?.winPresenter ?? new DefaultWinPresenter(timeout),
518
- cascadeOrchestrator: config.overrides?.cascadeOrchestrator ?? new DefaultCascadeOrchestrator(timeout),
519
- wildPresenter: config.overrides?.wildPresenter ?? new DefaultWildPresenter(config.wildSymbolId),
520
- scatterPresenter: config.overrides?.scatterPresenter ?? new DefaultScatterPresenter(timeout)
521
- }, gridManager, timeout).build(),
522
- dispose() {}
523
- };
524
- }
525
- function validateConfig(config) {
526
- if (!config.views.symbolFactory) throw new Error("SymbolViewFactory is required");
527
- if (!config.views.server) throw new Error("ServerAdapter is required");
528
- if (config.gameConfig.reels <= 0) throw new Error("Invalid reel count");
529
- if (config.gameConfig.rows <= 0) throw new Error("Invalid row count");
530
- if (config.timeout !== void 0 && config.timeout < 0) throw new Error("Timeout must be non-negative");
531
- }
532
-
533
- //#endregion
534
- exports.DefaultCascadeOrchestrator = DefaultCascadeOrchestrator;
535
- exports.DefaultReelSystem = DefaultReelSystem;
536
- exports.DefaultScatterPresenter = DefaultScatterPresenter;
537
- exports.DefaultWildPresenter = DefaultWildPresenter;
538
- exports.DefaultWinPresenter = DefaultWinPresenter;
539
- exports.GridManager = GridManager;
540
- exports.createSlotRenderer = createSlotRenderer;
541
- exports.noopCelebrationView = noopCelebrationView;
542
- exports.noopGambleView = noopGambleView;
543
- exports.noopHUD = noopHUD;
544
- exports.noopPickBonusView = noopPickBonusView;
545
- exports.noopSceneView = noopSceneView;
546
- exports.noopWheelBonusView = noopWheelBonusView;
547
- exports.withTimeout = withTimeout;
548
- //# sourceMappingURL=index.cjs.map