@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.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);
@@ -2083,7 +2094,9 @@ ${error.stack}
2083
2094
  const forceRecordsPath = this.PATHS.forceRecords(mode);
2084
2095
  const aggregatedRecords = /* @__PURE__ */ new Map();
2085
2096
  if (fs2.existsSync(tempRecordsPath)) {
2086
- const fileStream = fs2.createReadStream(tempRecordsPath);
2097
+ const fileStream = fs2.createReadStream(tempRecordsPath, {
2098
+ highWaterMark: this.streamHighWaterMark
2099
+ });
2087
2100
  const rl = readline2.createInterface({
2088
2101
  input: fileStream,
2089
2102
  crlfDelay: Infinity
@@ -2206,20 +2219,29 @@ ${error.stack}
2206
2219
  }
2207
2220
  }
2208
2221
  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));
2222
+ try {
2223
+ fs2.rmSync(outPath, { force: true });
2224
+ const out = fs2.createWriteStream(outPath, {
2225
+ highWaterMark: this.streamHighWaterMark
2226
+ });
2227
+ for (let i = 0; i < chunks.length; i++) {
2228
+ const p = path.join(this.PATHS.base, TEMP_FOLDER, tempName(i));
2229
+ if (!fs2.existsSync(p)) continue;
2230
+ const rs = fs2.createReadStream(p, {
2231
+ highWaterMark: this.streamHighWaterMark
2232
+ });
2233
+ for await (const buf of rs) {
2234
+ if (!out.write(buf)) {
2235
+ await new Promise((resolve) => out.once("drain", resolve));
2236
+ }
2237
+ }
2238
+ fs2.rmSync(p);
2239
+ }
2240
+ out.end();
2241
+ await new Promise((resolve) => out.on("finish", resolve));
2242
+ } catch (error) {
2243
+ throw new Error(`Error merging CSV files: ${error.message}`);
2244
+ }
2223
2245
  }
2224
2246
  /**
2225
2247
  * Confirms all pending records and adds them to the main records list.