@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.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +113 -93
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +114 -94
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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?.(
|
|
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
|
|
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
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
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
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
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`
|