@slot-engine/core 0.1.3 → 0.1.4

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/dist/index.d.mts CHANGED
@@ -89,8 +89,9 @@ declare class Simulation {
89
89
  private debug;
90
90
  private actualSims;
91
91
  private library;
92
- private recorder;
93
92
  private wallet;
93
+ private recordsWriteStream;
94
+ private hasWrittenRecord;
94
95
  constructor(opts: SimulationOptions, gameConfigOpts: GameConfigOptions);
95
96
  runSimulation(opts: SimulationConfigOptions): Promise<void>;
96
97
  /**
@@ -148,13 +149,11 @@ declare class Simulation {
148
149
  private writeRecords;
149
150
  private writeIndexJson;
150
151
  private writeBooksJson;
151
- private logSymbolOccurrences;
152
152
  /**
153
153
  * Compiles user configured game to JS for use in different Node processes
154
154
  */
155
155
  private preprocessFiles;
156
156
  private getSimRangesForChunks;
157
- private mergeRecords;
158
157
  /**
159
158
  * Generates reelset CSV files for all game modes.
160
159
  */
@@ -1580,4 +1579,4 @@ interface StandaloneBoardOptions {
1580
1579
  padSymbols: number;
1581
1580
  }
1582
1581
 
1583
- export { type AnyGameModes, type AnySymbols, type AnyUserData, ClusterWinType, type GameContext, type GameHooks, GameMode, GameSymbol, GeneratedReelSet, type InferGameType, LinesWinType, ManywaysWinType, OptimizationConditions, OptimizationParameters, OptimizationScaling, type Reels, ResultSet, SPIN_TYPE, type SpinType, StandaloneBoard, StaticReelSet, createSlotGame, defineGameModes, defineSymbols, defineUserState };
1582
+ export { type AnyGameModes, type AnySymbols, type AnyUserData, ClusterWinType, type GameContext, type GameHooks, GameMode, GameSymbol, GeneratedReelSet, type InferGameType, LinesWinType, ManywaysWinType, OptimizationConditions, OptimizationParameters, OptimizationScaling, type Reels, ResultSet, SPIN_TYPE, type SpinType, StandaloneBoard, StaticReelSet, type WinCombination, createSlotGame, defineGameModes, defineSymbols, defineUserState };
package/dist/index.d.ts CHANGED
@@ -89,8 +89,9 @@ declare class Simulation {
89
89
  private debug;
90
90
  private actualSims;
91
91
  private library;
92
- private recorder;
93
92
  private wallet;
93
+ private recordsWriteStream;
94
+ private hasWrittenRecord;
94
95
  constructor(opts: SimulationOptions, gameConfigOpts: GameConfigOptions);
95
96
  runSimulation(opts: SimulationConfigOptions): Promise<void>;
96
97
  /**
@@ -148,13 +149,11 @@ declare class Simulation {
148
149
  private writeRecords;
149
150
  private writeIndexJson;
150
151
  private writeBooksJson;
151
- private logSymbolOccurrences;
152
152
  /**
153
153
  * Compiles user configured game to JS for use in different Node processes
154
154
  */
155
155
  private preprocessFiles;
156
156
  private getSimRangesForChunks;
157
- private mergeRecords;
158
157
  /**
159
158
  * Generates reelset CSV files for all game modes.
160
159
  */
@@ -1580,4 +1579,4 @@ interface StandaloneBoardOptions {
1580
1579
  padSymbols: number;
1581
1580
  }
1582
1581
 
1583
- export { type AnyGameModes, type AnySymbols, type AnyUserData, ClusterWinType, type GameContext, type GameHooks, GameMode, GameSymbol, GeneratedReelSet, type InferGameType, LinesWinType, ManywaysWinType, OptimizationConditions, OptimizationParameters, OptimizationScaling, type Reels, ResultSet, SPIN_TYPE, type SpinType, StandaloneBoard, StaticReelSet, createSlotGame, defineGameModes, defineSymbols, defineUserState };
1582
+ export { type AnyGameModes, type AnySymbols, type AnyUserData, ClusterWinType, type GameContext, type GameHooks, GameMode, GameSymbol, GeneratedReelSet, type InferGameType, LinesWinType, ManywaysWinType, OptimizationConditions, OptimizationParameters, OptimizationScaling, type Reels, ResultSet, SPIN_TYPE, type SpinType, StandaloneBoard, StaticReelSet, type WinCombination, createSlotGame, defineGameModes, defineSymbols, defineUserState };
package/dist/index.js CHANGED
@@ -86,6 +86,7 @@ var import_fs2 = __toESM(require("fs"));
86
86
  var import_path = __toESM(require("path"));
87
87
  var import_assert6 = __toESM(require("assert"));
88
88
  var import_zlib = __toESM(require("zlib"));
89
+ var import_readline2 = __toESM(require("readline"));
89
90
  var import_esbuild = require("esbuild");
90
91
  var import_worker_threads = require("worker_threads");
91
92
 
@@ -253,6 +254,7 @@ var RandomNumberGenerator = class {
253
254
 
254
255
  // utils.ts
255
256
  var import_fs = __toESM(require("fs"));
257
+ var import_readline = __toESM(require("readline"));
256
258
  function createDirIfNotExists(dirPath) {
257
259
  if (!import_fs.default.existsSync(dirPath)) {
258
260
  import_fs.default.mkdirSync(dirPath, { recursive: true });
@@ -284,6 +286,29 @@ var JSONL = class {
284
286
  static parse(jsonl) {
285
287
  return jsonl.split("\n").filter((s) => s !== "").map((str) => JSON.parse(str));
286
288
  }
289
+ static async convertToJson(inputPath, outputPath) {
290
+ const writeStream = import_fs.default.createWriteStream(outputPath, { encoding: "utf-8" });
291
+ writeStream.write("[\n");
292
+ const rl = import_readline.default.createInterface({
293
+ input: import_fs.default.createReadStream(inputPath),
294
+ crlfDelay: Infinity
295
+ });
296
+ let isFirst = true;
297
+ for await (const line of rl) {
298
+ if (line.trim() === "") continue;
299
+ if (!isFirst) {
300
+ writeStream.write(",\n");
301
+ }
302
+ writeStream.write(line);
303
+ isFirst = false;
304
+ }
305
+ writeStream.write("\n]");
306
+ writeStream.end();
307
+ return new Promise((resolve, reject) => {
308
+ writeStream.on("finish", () => resolve());
309
+ writeStream.on("error", reject);
310
+ });
311
+ }
287
312
  };
288
313
 
289
314
  // src/result-set/index.ts
@@ -1464,8 +1489,10 @@ var Wallet = class {
1464
1489
  };
1465
1490
 
1466
1491
  // src/simulation/index.ts
1492
+ var import_promises = require("stream/promises");
1467
1493
  var completedSimulations = 0;
1468
1494
  var TEMP_FILENAME = "__temp_compiled_src_IGNORE.js";
1495
+ var TEMP_FOLDER = "temp_files";
1469
1496
  var Simulation = class {
1470
1497
  gameConfigOpts;
1471
1498
  gameConfig;
@@ -1474,15 +1501,15 @@ var Simulation = class {
1474
1501
  debug = false;
1475
1502
  actualSims = 0;
1476
1503
  library;
1477
- recorder;
1478
1504
  wallet;
1505
+ recordsWriteStream;
1506
+ hasWrittenRecord = false;
1479
1507
  constructor(opts, gameConfigOpts) {
1480
1508
  this.gameConfig = createGameConfig(gameConfigOpts);
1481
1509
  this.gameConfigOpts = gameConfigOpts;
1482
1510
  this.simRunsAmount = opts.simRunsAmount || {};
1483
1511
  this.concurrency = (opts.concurrency || 6) >= 2 ? opts.concurrency || 6 : 2;
1484
1512
  this.library = /* @__PURE__ */ new Map();
1485
- this.recorder = new Recorder();
1486
1513
  this.wallet = new Wallet();
1487
1514
  const gameModeKeys = Object.keys(this.gameConfig.gameModes);
1488
1515
  (0, import_assert6.default)(
@@ -1508,7 +1535,7 @@ var Simulation = class {
1508
1535
  completedSimulations = 0;
1509
1536
  this.wallet = new Wallet();
1510
1537
  this.library = /* @__PURE__ */ new Map();
1511
- this.recorder = new Recorder();
1538
+ this.hasWrittenRecord = false;
1512
1539
  debugDetails[mode] = {};
1513
1540
  console.log(`
1514
1541
  Simulating game mode: ${mode}`);
@@ -1520,8 +1547,59 @@ Simulating game mode: ${mode}`);
1520
1547
  `Tried to simulate game mode "${mode}", but it's not configured in the game config.`
1521
1548
  );
1522
1549
  }
1550
+ const booksPath = import_path.default.join(
1551
+ this.gameConfig.rootDir,
1552
+ this.gameConfig.outputDir,
1553
+ `books_${mode}.jsonl`
1554
+ );
1555
+ const tempRecordsPath = import_path.default.join(
1556
+ this.gameConfig.rootDir,
1557
+ this.gameConfig.outputDir,
1558
+ TEMP_FOLDER,
1559
+ `temp_records_${mode}.jsonl`
1560
+ );
1561
+ createDirIfNotExists(
1562
+ import_path.default.join(this.gameConfig.rootDir, this.gameConfig.outputDir)
1563
+ );
1564
+ createDirIfNotExists(
1565
+ import_path.default.join(this.gameConfig.rootDir, this.gameConfig.outputDir, TEMP_FOLDER)
1566
+ );
1567
+ this.recordsWriteStream = import_fs2.default.createWriteStream(tempRecordsPath);
1523
1568
  const simNumsToCriteria = ResultSet.assignCriteriaToSimulations(this, mode);
1524
1569
  await this.spawnWorkersForGameMode({ mode, simNumsToCriteria });
1570
+ const finalBookStream = import_fs2.default.createWriteStream(booksPath);
1571
+ const numSims = Object.keys(simNumsToCriteria).length;
1572
+ const chunks = this.getSimRangesForChunks(numSims, this.concurrency);
1573
+ let isFirstChunk = true;
1574
+ for (let i = 0; i < chunks.length; i++) {
1575
+ const tempBookPath = import_path.default.join(
1576
+ this.gameConfig.rootDir,
1577
+ this.gameConfig.outputDir,
1578
+ TEMP_FOLDER,
1579
+ `temp_books_${mode}_${i}.jsonl`
1580
+ );
1581
+ if (import_fs2.default.existsSync(tempBookPath)) {
1582
+ if (!isFirstChunk) {
1583
+ finalBookStream.write("\n");
1584
+ }
1585
+ const content = import_fs2.default.createReadStream(tempBookPath);
1586
+ for await (const chunk of content) {
1587
+ finalBookStream.write(chunk);
1588
+ }
1589
+ import_fs2.default.rmSync(tempBookPath);
1590
+ isFirstChunk = false;
1591
+ }
1592
+ }
1593
+ finalBookStream.end();
1594
+ await new Promise((resolve) => finalBookStream.on("finish", resolve));
1595
+ if (this.recordsWriteStream) {
1596
+ await new Promise((resolve) => {
1597
+ this.recordsWriteStream.end(() => {
1598
+ resolve();
1599
+ });
1600
+ });
1601
+ this.recordsWriteStream = void 0;
1602
+ }
1525
1603
  createDirIfNotExists(
1526
1604
  import_path.default.join(
1527
1605
  this.gameConfig.rootDir,
@@ -1532,11 +1610,13 @@ Simulating game mode: ${mode}`);
1532
1610
  createDirIfNotExists(
1533
1611
  import_path.default.join(this.gameConfig.rootDir, this.gameConfig.outputDir, "publish_files")
1534
1612
  );
1613
+ console.log(`Writing final files for game mode: ${mode} ...`);
1535
1614
  this.writeLookupTableCSV(mode);
1536
1615
  this.writeLookupTableSegmentedCSV(mode);
1537
1616
  this.writeRecords(mode);
1538
1617
  await this.writeBooksJson(mode);
1539
1618
  this.writeIndexJson();
1619
+ console.log(`Mode ${mode} done!`);
1540
1620
  debugDetails[mode].rtp = this.wallet.getCumulativeWins() / (runs * this.gameConfig.gameModes[mode].cost);
1541
1621
  debugDetails[mode].wins = this.wallet.getCumulativeWins();
1542
1622
  debugDetails[mode].winsPerSpinType = this.wallet.getCumulativeWinsPerSpinType();
@@ -1615,6 +1695,12 @@ Simulating game mode: ${mode}`);
1615
1695
  index
1616
1696
  }
1617
1697
  });
1698
+ const tempBookPath = import_path.default.join(
1699
+ basePath,
1700
+ TEMP_FOLDER,
1701
+ `temp_books_${mode}_${index}.jsonl`
1702
+ );
1703
+ const bookStream = import_fs2.default.createWriteStream(tempBookPath);
1618
1704
  worker.on("message", (msg) => {
1619
1705
  if (msg.type === "log") {
1620
1706
  } else if (msg.type === "complete") {
@@ -1623,9 +1709,23 @@ Simulating game mode: ${mode}`);
1623
1709
  logArrowProgress(completedSimulations, totalSims);
1624
1710
  }
1625
1711
  const book = Book.fromSerialized(msg.book);
1712
+ const bookData = {
1713
+ id: book.id,
1714
+ payoutMultiplier: book.payout,
1715
+ events: book.events
1716
+ };
1717
+ const prefix = book.id === simStart ? "" : "\n";
1718
+ bookStream.write(prefix + JSONL.stringify([bookData]));
1719
+ book.events = [];
1626
1720
  this.library.set(book.id, book);
1721
+ if (this.recordsWriteStream) {
1722
+ for (const record of msg.records) {
1723
+ const recordPrefix = this.hasWrittenRecord ? "\n" : "";
1724
+ this.recordsWriteStream.write(recordPrefix + JSONL.stringify([record]));
1725
+ this.hasWrittenRecord = true;
1726
+ }
1727
+ }
1627
1728
  this.wallet.mergeSerialized(msg.wallet);
1628
- this.mergeRecords(msg.records);
1629
1729
  } else if (msg.type === "done") {
1630
1730
  resolve(true);
1631
1731
  }
@@ -1768,16 +1868,61 @@ Simulating game mode: ${mode}`);
1768
1868
  writeFile(outputFilePath, rows.join("\n"));
1769
1869
  return outputFilePath;
1770
1870
  }
1771
- writeRecords(gameMode) {
1772
- const outputFileName = `force_record_${gameMode}.json`;
1773
- const outputFilePath = import_path.default.join(
1871
+ async writeRecords(mode) {
1872
+ const tempRecordsPath = import_path.default.join(
1774
1873
  this.gameConfig.rootDir,
1775
1874
  this.gameConfig.outputDir,
1776
- outputFileName
1875
+ TEMP_FOLDER,
1876
+ `temp_records_${mode}.jsonl`
1777
1877
  );
1778
- writeFile(outputFilePath, JSON.stringify(this.recorder.records, null, 2));
1779
- if (this.debug) this.logSymbolOccurrences();
1780
- return outputFilePath;
1878
+ const forceRecordsPath = import_path.default.join(
1879
+ this.gameConfig.rootDir,
1880
+ this.gameConfig.outputDir,
1881
+ `force_record_${mode}.json`
1882
+ );
1883
+ const aggregatedRecords = /* @__PURE__ */ new Map();
1884
+ if (import_fs2.default.existsSync(tempRecordsPath)) {
1885
+ const fileStream = import_fs2.default.createReadStream(tempRecordsPath);
1886
+ const rl = import_readline2.default.createInterface({
1887
+ input: fileStream,
1888
+ crlfDelay: Infinity
1889
+ });
1890
+ for await (const line of rl) {
1891
+ if (line.trim() === "") continue;
1892
+ const record = JSON.parse(line);
1893
+ const key = JSON.stringify(record.search);
1894
+ let existing = aggregatedRecords.get(key);
1895
+ if (!existing) {
1896
+ existing = {
1897
+ search: record.search,
1898
+ timesTriggered: 0,
1899
+ bookIds: []
1900
+ };
1901
+ aggregatedRecords.set(key, existing);
1902
+ }
1903
+ existing.timesTriggered += record.timesTriggered;
1904
+ for (const bookId of record.bookIds) {
1905
+ existing.bookIds.push(bookId);
1906
+ }
1907
+ }
1908
+ }
1909
+ import_fs2.default.rmSync(forceRecordsPath, { force: true });
1910
+ const writeStream = import_fs2.default.createWriteStream(forceRecordsPath, { encoding: "utf-8" });
1911
+ writeStream.write("[\n");
1912
+ let isFirst = true;
1913
+ for (const record of aggregatedRecords.values()) {
1914
+ if (!isFirst) {
1915
+ writeStream.write(",\n");
1916
+ }
1917
+ writeStream.write(JSON.stringify(record));
1918
+ isFirst = false;
1919
+ }
1920
+ writeStream.write("\n]");
1921
+ writeStream.end();
1922
+ await new Promise((resolve) => {
1923
+ writeStream.on("finish", () => resolve());
1924
+ });
1925
+ import_fs2.default.rmSync(tempRecordsPath, { force: true });
1781
1926
  }
1782
1927
  writeIndexJson() {
1783
1928
  const outputFilePath = import_path.default.join(
@@ -1799,54 +1944,25 @@ Simulating game mode: ${mode}`);
1799
1944
  writeFile(outputFilePath, JSON.stringify({ modes }, null, 2));
1800
1945
  }
1801
1946
  async writeBooksJson(gameMode) {
1802
- const outputFileName = `books_${gameMode}.jsonl`;
1803
1947
  const outputFilePath = import_path.default.join(
1804
1948
  this.gameConfig.rootDir,
1805
1949
  this.gameConfig.outputDir,
1806
- outputFileName
1950
+ `books_${gameMode}.jsonl`
1807
1951
  );
1808
- const books = Array.from(this.library.values()).map((b) => b.serialize()).map((b) => ({
1809
- id: b.id,
1810
- payoutMultiplier: b.payout,
1811
- events: b.events
1812
- })).sort((a, b) => a.id - b.id);
1813
- const contents = JSONL.stringify(books);
1814
- writeFile(outputFilePath, contents);
1815
- const compressedFileName = `books_${gameMode}.jsonl.zst`;
1816
1952
  const compressedFilePath = import_path.default.join(
1817
1953
  this.gameConfig.rootDir,
1818
1954
  this.gameConfig.outputDir,
1819
1955
  "publish_files",
1820
- compressedFileName
1956
+ `books_${gameMode}.jsonl.zst`
1821
1957
  );
1822
1958
  import_fs2.default.rmSync(compressedFilePath, { force: true });
1823
- const compressed = import_zlib.default.zstdCompressSync(Buffer.from(contents));
1824
- import_fs2.default.writeFileSync(compressedFilePath, compressed);
1825
- }
1826
- logSymbolOccurrences() {
1827
- const validRecords = this.recorder.records.filter(
1828
- (r) => r.search.some((s) => s.name === "symbolId") && r.search.some((s) => s.name === "kind")
1829
- );
1830
- const structuredRecords = validRecords.map((r) => {
1831
- const symbolEntry = r.search.find((s) => s.name === "symbolId");
1832
- const kindEntry = r.search.find((s) => s.name === "kind");
1833
- const spinTypeEntry = r.search.find((s) => s.name === "spinType");
1834
- return {
1835
- symbol: symbolEntry ? symbolEntry.value : "unknown",
1836
- kind: kindEntry ? kindEntry.value : "unknown",
1837
- spinType: spinTypeEntry ? spinTypeEntry.value : "unknown",
1838
- timesTriggered: r.timesTriggered
1839
- };
1840
- }).sort((a, b) => {
1841
- if (a.symbol < b.symbol) return -1;
1842
- if (a.symbol > b.symbol) return 1;
1843
- if (a.kind < b.kind) return -1;
1844
- if (a.kind > b.kind) return 1;
1845
- if (a.spinType < b.spinType) return -1;
1846
- if (a.spinType > b.spinType) return 1;
1847
- return 0;
1848
- });
1849
- console.table(structuredRecords);
1959
+ if (import_fs2.default.existsSync(outputFilePath)) {
1960
+ await (0, import_promises.pipeline)(
1961
+ import_fs2.default.createReadStream(outputFilePath),
1962
+ import_zlib.default.createZstdCompress(),
1963
+ import_fs2.default.createWriteStream(compressedFilePath)
1964
+ );
1965
+ }
1850
1966
  }
1851
1967
  /**
1852
1968
  * Compiles user configured game to JS for use in different Node processes
@@ -1884,32 +2000,6 @@ Simulating game mode: ${mode}`);
1884
2000
  }
1885
2001
  return result;
1886
2002
  }
1887
- mergeRecords(otherRecords) {
1888
- for (const otherRecord of otherRecords) {
1889
- let record = this.recorder.records.find((r) => {
1890
- if (r.search.length !== otherRecord.search.length) return false;
1891
- for (let i = 0; i < r.search.length; i++) {
1892
- if (r.search[i].name !== otherRecord.search[i].name) return false;
1893
- if (r.search[i].value !== otherRecord.search[i].value) return false;
1894
- }
1895
- return true;
1896
- });
1897
- if (!record) {
1898
- record = {
1899
- search: otherRecord.search,
1900
- timesTriggered: 0,
1901
- bookIds: []
1902
- };
1903
- this.recorder.records.push(record);
1904
- }
1905
- record.timesTriggered += otherRecord.timesTriggered;
1906
- for (const bookId of otherRecord.bookIds) {
1907
- if (!record.bookIds.includes(bookId)) {
1908
- record.bookIds.push(bookId);
1909
- }
1910
- }
1911
- }
1912
- }
1913
2003
  /**
1914
2004
  * Generates reelset CSV files for all game modes.
1915
2005
  */
@@ -2523,11 +2613,6 @@ var Optimizer = class {
2523
2613
  );
2524
2614
  }
2525
2615
  }
2526
- const criteria = configMode.resultSets.map((r) => r.criteria);
2527
- (0, import_assert9.default)(
2528
- conditions.every((c) => criteria.includes(c)),
2529
- `Not all ResultSet criteria in game mode "${k}" are defined as optimization conditions.`
2530
- );
2531
2616
  let gameModeRtp = configMode.rtp;
2532
2617
  let paramRtp = 0;
2533
2618
  for (const cond of conditions) {
@@ -2580,6 +2665,7 @@ async function rustProgram(...args) {
2580
2665
  }
2581
2666
 
2582
2667
  // src/slot-game/index.ts
2668
+ var import_worker_threads4 = require("worker_threads");
2583
2669
  var SlotGame = class {
2584
2670
  configOpts;
2585
2671
  simulation;
@@ -2655,6 +2741,7 @@ var SlotGame = class {
2655
2741
  if (opts.doAnalysis) {
2656
2742
  await this.runAnalysis(opts.analysisOpts || { gameModes: [] });
2657
2743
  }
2744
+ if (import_worker_threads4.isMainThread) console.log("Finishing up...");
2658
2745
  }
2659
2746
  /**
2660
2747
  * Gets the game configuration.
@@ -2936,13 +3023,14 @@ var ClusterWinType = class extends WinType {
2936
3023
  }
2937
3024
  }
2938
3025
  }
2939
- potentialClusters.forEach((cluster) => {
3026
+ for (const cluster of potentialClusters) {
2940
3027
  const kind = cluster.length;
2941
3028
  let baseSymbol = cluster.find((s) => !this.isWild(s.symbol))?.symbol;
2942
3029
  if (!baseSymbol) baseSymbol = cluster[0].symbol;
2943
3030
  const payout = this.getSymbolPayout(baseSymbol, kind);
3031
+ if (payout === 0) continue;
2944
3032
  if (!baseSymbol.pays || Object.keys(baseSymbol.pays).length === 0) {
2945
- return;
3033
+ continue;
2946
3034
  }
2947
3035
  clusterWins.push({
2948
3036
  payout,
@@ -2955,7 +3043,7 @@ var ClusterWinType = class extends WinType {
2955
3043
  posIndex: s.row
2956
3044
  }))
2957
3045
  });
2958
- });
3046
+ }
2959
3047
  for (const win of clusterWins) {
2960
3048
  this.ctx.services.data.recordSymbolOccurrence({
2961
3049
  kind: win.kind,
@@ -3120,7 +3208,7 @@ var ManywaysWinType = class extends WinType {
3120
3208
  // src/reel-set/GeneratedReelSet.ts
3121
3209
  var import_fs5 = __toESM(require("fs"));
3122
3210
  var import_path7 = __toESM(require("path"));
3123
- var import_worker_threads4 = require("worker_threads");
3211
+ var import_worker_threads5 = require("worker_threads");
3124
3212
 
3125
3213
  // src/reel-set/index.ts
3126
3214
  var import_fs4 = __toESM(require("fs"));
@@ -3465,7 +3553,7 @@ var GeneratedReelSet = class extends ReelSet {
3465
3553
  }
3466
3554
  }
3467
3555
  const csvString = csvRows.map((row) => row.join(",")).join("\n");
3468
- if (import_worker_threads4.isMainThread) {
3556
+ if (import_worker_threads5.isMainThread) {
3469
3557
  import_fs5.default.writeFileSync(filePath, csvString);
3470
3558
  this.reels = this.parseReelsetCSV(filePath, config);
3471
3559
  console.log(