@slot-engine/core 0.1.12 → 0.1.14-test.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/dist/index.mjs CHANGED
@@ -200,68 +200,6 @@ var RandomNumberGenerator = class {
200
200
  }
201
201
  };
202
202
 
203
- // utils.ts
204
- import fs from "fs";
205
- import readline from "readline";
206
- function createDirIfNotExists(dirPath) {
207
- if (!fs.existsSync(dirPath)) {
208
- fs.mkdirSync(dirPath, { recursive: true });
209
- }
210
- }
211
- function writeJsonFile(filePath, data) {
212
- try {
213
- fs.writeFileSync(filePath, JSON.stringify(data, null, 2), {
214
- encoding: "utf8"
215
- });
216
- } catch (error) {
217
- throw new Error(`Failed to write JSON file at ${filePath}: ${error}`);
218
- }
219
- }
220
- function writeFile(filePath, data) {
221
- try {
222
- fs.writeFileSync(filePath, data, { encoding: "utf8" });
223
- } catch (error) {
224
- throw new Error(`Failed to write file at ${filePath}: ${error}`);
225
- }
226
- }
227
- function copy(obj) {
228
- return JSON.parse(JSON.stringify(obj));
229
- }
230
- var JSONL = class {
231
- static stringify(array) {
232
- return array.map((object) => JSON.stringify(object)).join("\n");
233
- }
234
- static parse(jsonl) {
235
- return jsonl.split("\n").filter((s) => s !== "").map((str) => JSON.parse(str));
236
- }
237
- static async convertToJson(inputPath, outputPath) {
238
- const writeStream = fs.createWriteStream(outputPath, { encoding: "utf-8" });
239
- writeStream.write("[\n");
240
- const rl = readline.createInterface({
241
- input: fs.createReadStream(inputPath),
242
- crlfDelay: Infinity
243
- });
244
- let isFirst = true;
245
- for await (const line of rl) {
246
- if (line.trim() === "") continue;
247
- if (!isFirst) {
248
- writeStream.write(",\n");
249
- }
250
- writeStream.write(line);
251
- isFirst = false;
252
- }
253
- writeStream.write("\n]");
254
- writeStream.end();
255
- return new Promise((resolve, reject) => {
256
- writeStream.on("finish", () => resolve());
257
- writeStream.on("error", reject);
258
- });
259
- }
260
- };
261
- function round(value, decimals) {
262
- return Number(Math.round(Number(value + "e" + decimals)) + "e-" + decimals);
263
- }
264
-
265
203
  // src/result-set/index.ts
266
204
  var ResultSet = class {
267
205
  criteria;
@@ -328,10 +266,10 @@ var ResultSet = class {
328
266
  * Checks if core criteria is met, e.g. target multiplier or max win.
329
267
  */
330
268
  meetsCriteria(ctx) {
331
- const customEval = this.evaluate?.(copy(ctx));
269
+ const customEval = this.evaluate?.(ctx);
332
270
  const freespinsMet = this.forceFreespins ? ctx.state.triggeredFreespins : true;
333
271
  const wallet = ctx.services.wallet._getWallet();
334
- const multiplierMet = this.multiplier !== void 0 ? wallet.getCurrentWin() === this.multiplier && !this.forceMaxWin : wallet.getCurrentWin() > 0 && (!this.forceMaxWin || true);
272
+ const multiplierMet = this.forceMaxWin ? true : this.multiplier !== void 0 ? wallet.getCurrentWin() === this.multiplier : wallet.getCurrentWin() > 0;
335
273
  const maxWinMet = this.forceMaxWin ? wallet.getCurrentWin() >= ctx.config.maxWinX : true;
336
274
  const coreCriteriaMet = freespinsMet && multiplierMet && maxWinMet;
337
275
  const finalResult = customEval !== void 0 ? coreCriteriaMet && customEval === true : coreCriteriaMet;
@@ -1278,6 +1216,68 @@ function createGameContext(opts) {
1278
1216
  return context;
1279
1217
  }
1280
1218
 
1219
+ // utils.ts
1220
+ import fs from "fs";
1221
+ import readline from "readline";
1222
+ function createDirIfNotExists(dirPath) {
1223
+ if (!fs.existsSync(dirPath)) {
1224
+ fs.mkdirSync(dirPath, { recursive: true });
1225
+ }
1226
+ }
1227
+ function writeJsonFile(filePath, data) {
1228
+ try {
1229
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2), {
1230
+ encoding: "utf8"
1231
+ });
1232
+ } catch (error) {
1233
+ throw new Error(`Failed to write JSON file at ${filePath}: ${error}`);
1234
+ }
1235
+ }
1236
+ function writeFile(filePath, data) {
1237
+ try {
1238
+ fs.writeFileSync(filePath, data, { encoding: "utf8" });
1239
+ } catch (error) {
1240
+ throw new Error(`Failed to write file at ${filePath}: ${error}`);
1241
+ }
1242
+ }
1243
+ function copy(obj) {
1244
+ return JSON.parse(JSON.stringify(obj));
1245
+ }
1246
+ var JSONL = class {
1247
+ static stringify(array) {
1248
+ return array.map((object) => JSON.stringify(object)).join("\n");
1249
+ }
1250
+ static parse(jsonl) {
1251
+ return jsonl.split("\n").filter((s) => s !== "").map((str) => JSON.parse(str));
1252
+ }
1253
+ static async convertToJson(inputPath, outputPath) {
1254
+ const writeStream = fs.createWriteStream(outputPath, { encoding: "utf-8" });
1255
+ writeStream.write("[\n");
1256
+ const rl = readline.createInterface({
1257
+ input: fs.createReadStream(inputPath),
1258
+ crlfDelay: Infinity
1259
+ });
1260
+ let isFirst = true;
1261
+ for await (const line of rl) {
1262
+ if (line.trim() === "") continue;
1263
+ if (!isFirst) {
1264
+ writeStream.write(",\n");
1265
+ }
1266
+ writeStream.write(line);
1267
+ isFirst = false;
1268
+ }
1269
+ writeStream.write("\n]");
1270
+ writeStream.end();
1271
+ return new Promise((resolve, reject) => {
1272
+ writeStream.on("finish", () => resolve());
1273
+ writeStream.on("error", reject);
1274
+ });
1275
+ }
1276
+ };
1277
+ function round(value, decimals) {
1278
+ return Number(Math.round(Number(value + "e" + decimals)) + "e-" + decimals);
1279
+ }
1280
+
1281
1281
  // src/book/index.ts
1282
1282
  var Book = class {
1283
1283
  id;
@@ -1659,6 +1659,7 @@ var Simulation = class {
1659
1659
  wallet;
1660
1660
  recordsWriteStream;
1661
1661
  hasWrittenRecord = false;
1662
+ streamHighWaterMark = 500 * 1024 * 1024;
1662
1663
  maxPendingSims;
1663
1664
  maxHighWaterMark;
1664
1665
  PATHS = {};
@@ -1751,24 +1752,34 @@ Simulating game mode: ${mode}`);
1751
1752
  console.log(
1752
1753
  `Writing final files for game mode "${mode}". This may take a while...`
1753
1754
  );
1754
- const finalBookStream = fs2.createWriteStream(booksPath);
1755
- let isFirstChunk = true;
1756
- for (let i = 0; i < chunks.length; i++) {
1757
- const tempBookPath = this.PATHS.tempBooks(mode, i);
1758
- if (fs2.existsSync(tempBookPath)) {
1759
- if (!isFirstChunk) {
1760
- finalBookStream.write("\n");
1761
- }
1762
- const content = fs2.createReadStream(tempBookPath);
1763
- for await (const chunk of content) {
1764
- finalBookStream.write(chunk);
1755
+ try {
1756
+ const finalBookStream = fs2.createWriteStream(booksPath, {
1757
+ highWaterMark: this.streamHighWaterMark
1758
+ });
1759
+ let isFirstChunk = true;
1760
+ for (let i = 0; i < chunks.length; i++) {
1761
+ const tempBookPath = this.PATHS.tempBooks(mode, i);
1762
+ if (fs2.existsSync(tempBookPath)) {
1763
+ if (!isFirstChunk) {
1764
+ if (!finalBookStream.write("\n")) {
1765
+ await new Promise((r) => finalBookStream.once("drain", r));
1766
+ }
1767
+ }
1768
+ const content = fs2.createReadStream(tempBookPath);
1769
+ for await (const chunk of content) {
1770
+ if (!finalBookStream.write(chunk)) {
1771
+ await new Promise((r) => finalBookStream.once("drain", r));
1772
+ }
1773
+ }
1774
+ fs2.rmSync(tempBookPath);
1775
+ isFirstChunk = false;
1765
1776
  }
1766
- fs2.rmSync(tempBookPath);
1767
- isFirstChunk = false;
1768
1777
  }
1778
+ finalBookStream.end();
1779
+ await new Promise((resolve) => finalBookStream.on("finish", resolve));
1780
+ } catch (error) {
1781
+ throw new Error(`Error merging book files: ${error.message}`);
1769
1782
  }
1770
- finalBookStream.end();
1771
- await new Promise((resolve) => finalBookStream.on("finish", resolve));
1772
1783
  const lutPath = this.PATHS.lookupTable(mode);
1773
1784
  const lutPathPublish = this.PATHS.lookupTablePublish(mode);
1774
1785
  const lutSegmentedPath = this.PATHS.lookupTableSegmented(mode);
@@ -2206,20 +2217,29 @@ ${error.stack}
2206
2217
  }
2207
2218
  }
2208
2219
  async mergeCsv(chunks, outPath, tempName) {
2209
- fs2.rmSync(outPath, { force: true });
2210
- const out = fs2.createWriteStream(outPath);
2211
- let wroteAny = false;
2212
- for (let i = 0; i < chunks.length; i++) {
2213
- const p = path.join(this.PATHS.base, TEMP_FOLDER, tempName(i));
2214
- if (!fs2.existsSync(p)) continue;
2215
- if (wroteAny) out.write("");
2216
- const rs = fs2.createReadStream(p);
2217
- for await (const buf of rs) out.write(buf);
2218
- fs2.rmSync(p);
2219
- wroteAny = true;
2220
- }
2221
- out.end();
2222
- await new Promise((resolve) => out.on("finish", resolve));
2220
+ try {
2221
+ fs2.rmSync(outPath, { force: true });
2222
+ const out = fs2.createWriteStream(outPath, {
2223
+ highWaterMark: this.streamHighWaterMark
2224
+ });
2225
+ for (let i = 0; i < chunks.length; i++) {
2226
+ const p = path.join(this.PATHS.base, TEMP_FOLDER, tempName(i));
2227
+ if (!fs2.existsSync(p)) continue;
2228
+ const rs = fs2.createReadStream(p, {
2229
+ highWaterMark: this.streamHighWaterMark
2230
+ });
2231
+ for await (const buf of rs) {
2232
+ if (!out.write(buf)) {
2233
+ await new Promise((resolve) => out.once("drain", resolve));
2234
+ }
2235
+ }
2236
+ fs2.rmSync(p);
2237
+ }
2238
+ out.end();
2239
+ await new Promise((resolve) => out.on("finish", resolve));
2240
+ } catch (error) {
2241
+ throw new Error(`Error merging CSV files: ${error.message}`);
2242
+ }
2223
2243
  }
2224
2244
  /**
2225
2245
  * Confirms all pending records and adds them to the main records list.
@@ -3624,7 +3644,7 @@ var GeneratedReelSet = class extends ReelSet {
3624
3644
  `Error generating reels for game mode "${this.associatedGameModeName}". It's not defined in the game config.`
3625
3645
  );
3626
3646
  }
3627
- const outputDir = path7.join(config.rootDir, config.outputDir);
3647
+ const outputDir = config.rootDir.endsWith(config.outputDir) ? config.rootDir : path7.join(config.rootDir, config.outputDir);
3628
3648
  const filePath = path7.join(
3629
3649
  outputDir,
3630
3650
  `reels_${this.associatedGameModeName}-${this.id}.csv`