@slot-engine/core 0.1.13 → 0.1.14

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
@@ -107,6 +107,7 @@ declare class Simulation {
107
107
  private wallet;
108
108
  private recordsWriteStream;
109
109
  private hasWrittenRecord;
110
+ private readonly streamHighWaterMark;
110
111
  private readonly maxPendingSims;
111
112
  private readonly maxHighWaterMark;
112
113
  private PATHS;
package/dist/index.d.ts CHANGED
@@ -107,6 +107,7 @@ declare class Simulation {
107
107
  private wallet;
108
108
  private recordsWriteStream;
109
109
  private hasWrittenRecord;
110
+ private readonly streamHighWaterMark;
110
111
  private readonly maxPendingSims;
111
112
  private readonly maxHighWaterMark;
112
113
  private PATHS;
package/dist/index.js CHANGED
@@ -252,68 +252,6 @@ var RandomNumberGenerator = class {
252
252
  }
253
253
  };
254
254
 
255
- // utils.ts
256
- var import_fs = __toESM(require("fs"));
257
- var import_readline = __toESM(require("readline"));
258
- function createDirIfNotExists(dirPath) {
259
- if (!import_fs.default.existsSync(dirPath)) {
260
- import_fs.default.mkdirSync(dirPath, { recursive: true });
261
- }
262
- }
263
- function writeJsonFile(filePath, data) {
264
- try {
265
- import_fs.default.writeFileSync(filePath, JSON.stringify(data, null, 2), {
266
- encoding: "utf8"
267
- });
268
- } catch (error) {
269
- throw new Error(`Failed to write JSON file at ${filePath}: ${error}`);
270
- }
271
- }
272
- function writeFile(filePath, data) {
273
- try {
274
- import_fs.default.writeFileSync(filePath, data, { encoding: "utf8" });
275
- } catch (error) {
276
- throw new Error(`Failed to write file at ${filePath}: ${error}`);
277
- }
278
- }
279
- function copy(obj) {
280
- return JSON.parse(JSON.stringify(obj));
281
- }
282
- var JSONL = class {
283
- static stringify(array) {
284
- return array.map((object) => JSON.stringify(object)).join("\n");
285
- }
286
- static parse(jsonl) {
287
- return jsonl.split("\n").filter((s) => s !== "").map((str) => JSON.parse(str));
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
- }
312
- };
313
- function round(value, decimals) {
314
- return Number(Math.round(Number(value + "e" + decimals)) + "e-" + decimals);
315
- }
316
-
317
255
  // src/result-set/index.ts
318
256
  var ResultSet = class {
319
257
  criteria;
@@ -380,10 +318,10 @@ var ResultSet = class {
380
318
  * Checks if core criteria is met, e.g. target multiplier or max win.
381
319
  */
382
320
  meetsCriteria(ctx) {
383
- const customEval = this.evaluate?.(copy(ctx));
321
+ const customEval = this.evaluate?.(ctx);
384
322
  const freespinsMet = this.forceFreespins ? ctx.state.triggeredFreespins : true;
385
323
  const wallet = ctx.services.wallet._getWallet();
386
- const multiplierMet = this.multiplier !== void 0 ? wallet.getCurrentWin() === this.multiplier && !this.forceMaxWin : wallet.getCurrentWin() > 0 && (!this.forceMaxWin || true);
324
+ const multiplierMet = this.forceMaxWin ? true : this.multiplier !== void 0 ? wallet.getCurrentWin() === this.multiplier : wallet.getCurrentWin() > 0;
387
325
  const maxWinMet = this.forceMaxWin ? wallet.getCurrentWin() >= ctx.config.maxWinX : true;
388
326
  const coreCriteriaMet = freespinsMet && multiplierMet && maxWinMet;
389
327
  const finalResult = customEval !== void 0 ? coreCriteriaMet && customEval === true : coreCriteriaMet;
@@ -1330,6 +1268,68 @@ function createGameContext(opts) {
1330
1268
  return context;
1331
1269
  }
1332
1270
 
1271
+ // utils.ts
1272
+ var import_fs = __toESM(require("fs"));
1273
+ var import_readline = __toESM(require("readline"));
1274
+ function createDirIfNotExists(dirPath) {
1275
+ if (!import_fs.default.existsSync(dirPath)) {
1276
+ import_fs.default.mkdirSync(dirPath, { recursive: true });
1277
+ }
1278
+ }
1279
+ function writeJsonFile(filePath, data) {
1280
+ try {
1281
+ import_fs.default.writeFileSync(filePath, JSON.stringify(data, null, 2), {
1282
+ encoding: "utf8"
1283
+ });
1284
+ } catch (error) {
1285
+ throw new Error(`Failed to write JSON file at ${filePath}: ${error}`);
1286
+ }
1287
+ }
1288
+ function writeFile(filePath, data) {
1289
+ try {
1290
+ import_fs.default.writeFileSync(filePath, data, { encoding: "utf8" });
1291
+ } catch (error) {
1292
+ throw new Error(`Failed to write file at ${filePath}: ${error}`);
1293
+ }
1294
+ }
1295
+ function copy(obj) {
1296
+ return JSON.parse(JSON.stringify(obj));
1297
+ }
1298
+ var JSONL = class {
1299
+ static stringify(array) {
1300
+ return array.map((object) => JSON.stringify(object)).join("\n");
1301
+ }
1302
+ static parse(jsonl) {
1303
+ return jsonl.split("\n").filter((s) => s !== "").map((str) => JSON.parse(str));
1304
+ }
1305
+ static async convertToJson(inputPath, outputPath) {
1306
+ const writeStream = import_fs.default.createWriteStream(outputPath, { encoding: "utf-8" });
1307
+ writeStream.write("[\n");
1308
+ const rl = import_readline.default.createInterface({
1309
+ input: import_fs.default.createReadStream(inputPath),
1310
+ crlfDelay: Infinity
1311
+ });
1312
+ let isFirst = true;
1313
+ for await (const line of rl) {
1314
+ if (line.trim() === "") continue;
1315
+ if (!isFirst) {
1316
+ writeStream.write(",\n");
1317
+ }
1318
+ writeStream.write(line);
1319
+ isFirst = false;
1320
+ }
1321
+ writeStream.write("\n]");
1322
+ writeStream.end();
1323
+ return new Promise((resolve, reject) => {
1324
+ writeStream.on("finish", () => resolve());
1325
+ writeStream.on("error", reject);
1326
+ });
1327
+ }
1328
+ };
1329
+ function round(value, decimals) {
1330
+ return Number(Math.round(Number(value + "e" + decimals)) + "e-" + decimals);
1331
+ }
1332
+
1333
1333
  // src/book/index.ts
1334
1334
  var Book = class {
1335
1335
  id;
@@ -1711,6 +1711,7 @@ var Simulation = class {
1711
1711
  wallet;
1712
1712
  recordsWriteStream;
1713
1713
  hasWrittenRecord = false;
1714
+ streamHighWaterMark = 500 * 1024 * 1024;
1714
1715
  maxPendingSims;
1715
1716
  maxHighWaterMark;
1716
1717
  PATHS = {};
@@ -1803,24 +1804,34 @@ Simulating game mode: ${mode}`);
1803
1804
  console.log(
1804
1805
  `Writing final files for game mode "${mode}". This may take a while...`
1805
1806
  );
1806
- const finalBookStream = import_fs2.default.createWriteStream(booksPath);
1807
- let isFirstChunk = true;
1808
- for (let i = 0; i < chunks.length; i++) {
1809
- const tempBookPath = this.PATHS.tempBooks(mode, i);
1810
- if (import_fs2.default.existsSync(tempBookPath)) {
1811
- if (!isFirstChunk) {
1812
- finalBookStream.write("\n");
1813
- }
1814
- const content = import_fs2.default.createReadStream(tempBookPath);
1815
- for await (const chunk of content) {
1816
- finalBookStream.write(chunk);
1807
+ try {
1808
+ const finalBookStream = import_fs2.default.createWriteStream(booksPath, {
1809
+ highWaterMark: this.streamHighWaterMark
1810
+ });
1811
+ let isFirstChunk = true;
1812
+ for (let i = 0; i < chunks.length; i++) {
1813
+ const tempBookPath = this.PATHS.tempBooks(mode, i);
1814
+ if (import_fs2.default.existsSync(tempBookPath)) {
1815
+ if (!isFirstChunk) {
1816
+ if (!finalBookStream.write("\n")) {
1817
+ await new Promise((r) => finalBookStream.once("drain", r));
1818
+ }
1819
+ }
1820
+ const content = import_fs2.default.createReadStream(tempBookPath);
1821
+ for await (const chunk of content) {
1822
+ if (!finalBookStream.write(chunk)) {
1823
+ await new Promise((r) => finalBookStream.once("drain", r));
1824
+ }
1825
+ }
1826
+ import_fs2.default.rmSync(tempBookPath);
1827
+ isFirstChunk = false;
1817
1828
  }
1818
- import_fs2.default.rmSync(tempBookPath);
1819
- isFirstChunk = false;
1820
1829
  }
1830
+ finalBookStream.end();
1831
+ await new Promise((resolve) => finalBookStream.on("finish", resolve));
1832
+ } catch (error) {
1833
+ throw new Error(`Error merging book files: ${error.message}`);
1821
1834
  }
1822
- finalBookStream.end();
1823
- await new Promise((resolve) => finalBookStream.on("finish", resolve));
1824
1835
  const lutPath = this.PATHS.lookupTable(mode);
1825
1836
  const lutPathPublish = this.PATHS.lookupTablePublish(mode);
1826
1837
  const lutSegmentedPath = this.PATHS.lookupTableSegmented(mode);
@@ -2135,7 +2146,9 @@ ${error.stack}
2135
2146
  const forceRecordsPath = this.PATHS.forceRecords(mode);
2136
2147
  const aggregatedRecords = /* @__PURE__ */ new Map();
2137
2148
  if (import_fs2.default.existsSync(tempRecordsPath)) {
2138
- const fileStream = import_fs2.default.createReadStream(tempRecordsPath);
2149
+ const fileStream = import_fs2.default.createReadStream(tempRecordsPath, {
2150
+ highWaterMark: this.streamHighWaterMark
2151
+ });
2139
2152
  const rl = import_readline2.default.createInterface({
2140
2153
  input: fileStream,
2141
2154
  crlfDelay: Infinity
@@ -2258,20 +2271,29 @@ ${error.stack}
2258
2271
  }
2259
2272
  }
2260
2273
  async mergeCsv(chunks, outPath, tempName) {
2261
- import_fs2.default.rmSync(outPath, { force: true });
2262
- const out = import_fs2.default.createWriteStream(outPath);
2263
- let wroteAny = false;
2264
- for (let i = 0; i < chunks.length; i++) {
2265
- const p = import_path.default.join(this.PATHS.base, TEMP_FOLDER, tempName(i));
2266
- if (!import_fs2.default.existsSync(p)) continue;
2267
- if (wroteAny) out.write("");
2268
- const rs = import_fs2.default.createReadStream(p);
2269
- for await (const buf of rs) out.write(buf);
2270
- import_fs2.default.rmSync(p);
2271
- wroteAny = true;
2274
+ try {
2275
+ import_fs2.default.rmSync(outPath, { force: true });
2276
+ const out = import_fs2.default.createWriteStream(outPath, {
2277
+ highWaterMark: this.streamHighWaterMark
2278
+ });
2279
+ for (let i = 0; i < chunks.length; i++) {
2280
+ const p = import_path.default.join(this.PATHS.base, TEMP_FOLDER, tempName(i));
2281
+ if (!import_fs2.default.existsSync(p)) continue;
2282
+ const rs = import_fs2.default.createReadStream(p, {
2283
+ highWaterMark: this.streamHighWaterMark
2284
+ });
2285
+ for await (const buf of rs) {
2286
+ if (!out.write(buf)) {
2287
+ await new Promise((resolve) => out.once("drain", resolve));
2288
+ }
2289
+ }
2290
+ import_fs2.default.rmSync(p);
2291
+ }
2292
+ out.end();
2293
+ await new Promise((resolve) => out.on("finish", resolve));
2294
+ } catch (error) {
2295
+ throw new Error(`Error merging CSV files: ${error.message}`);
2272
2296
  }
2273
- out.end();
2274
- await new Promise((resolve) => out.on("finish", resolve));
2275
2297
  }
2276
2298
  /**
2277
2299
  * Confirms all pending records and adds them to the main records list.