@m3rcena/eco 14.28.1-dev.0 → 14.28.1

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/CHANGELOG.md CHANGED
@@ -5,6 +5,34 @@ All notable changes to `@m3rcena/eco` will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ---
9
+
10
+ ## [14.28.1] - 2026-11-05
11
+
12
+ ### 🚀 Enhancements & Compatibility
13
+
14
+ #### Added
15
+ - **Discord.js v14.28.1 Compatibility**:
16
+ - Full compatibility with Discord.js `14.28.1` and `Events.ClientReady` lifecycle.
17
+ - **Zero-Dependency Native SQLite Storage (`SqliteEcoStorage`)**:
18
+ - Built-in persistent storage adapter utilizing Node.js 22+ native `node:sqlite` DatabaseSync with WAL journal mode.
19
+ - Automatic table initialization for `eco_accounts` and `eco_kv`.
20
+ - **Enterprise Prisma ORM Adapter (`PrismaEcoStorage`)**:
21
+ - Auto-migrating Prisma storage with auto-schema injection and raw SQL fallbacks for PostgreSQL, MySQL, and SQLite.
22
+ - Schema migration helpers (`PRISMA_ECO_MODEL`, `applyPrismaEcoModel`).
23
+ - **Rust-Style Submodule Resolver & Local Hosting**:
24
+ - Local-first Git submodule detection via `@m3rcena/eco/resolver`.
25
+ - Zero-config runtime interception flag via `@m3rcena/eco/register`.
26
+ - Standalone CLI host service via `@m3rcena/eco/host` (`hostEco`).
27
+ - **Terminal Update Notifier**:
28
+ - Symmetrical terminal notification box with semver comparison (`checkPackageUpdates`).
29
+ - **Strongly-Typed Event Emitter**:
30
+ - Comprehensive TypeScript definition for all `EcoEvents` parameters across `on`, `once`, and `off`.
31
+ - **Synchronized with `@m3rcena/bridge` v14.28.1**:
32
+ - Full real-time bi-directional action dispatching, debit card REST streaming, and presence-filtered audio cues.
33
+
34
+ ---
35
+
8
36
  ## [14.28.0] - 2026-11-01
9
37
 
10
38
  ### Added
package/DOCUMENTATION.md CHANGED
@@ -8,7 +8,7 @@
8
8
  > - **[Stocks, Heists, Pets & Loot Crates](https://github.com/M3rcena/m3rcena-eco/wiki/Stocks-Heists-and-Pets)**
9
9
  > - **[Dashboard Bridge Integration](https://github.com/M3rcena/m3rcena-eco/wiki/Bridge-Integration)**
10
10
 
11
- Welcome to the definitive documentation for **`@m3rcena/eco`** (v14.28.0) — the ultimate enterprise-grade Discord.js v14 economy, progression, career, stock market, and casino engine.
11
+ Welcome to the definitive documentation for **`@m3rcena/eco`** (v14.28.1) — the ultimate enterprise-grade Discord.js v14 economy, progression, career, stock market, and casino engine.
12
12
 
13
13
  ---
14
14
 
package/README.md CHANGED
@@ -4,7 +4,9 @@
4
4
  <p><strong>The ultimate enterprise-grade Discord.js v14 economy, progression, stock market, and casino engine.</strong></p>
5
5
  <p>
6
6
  <a href="https://www.npmjs.com/package/@m3rcena/eco"><img src="https://img.shields.io/npm/v/@m3rcena/eco.svg?style=flat-square" alt="NPM Version" /></a>
7
- <a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E%3D22.0.0-brightgreen.svg?style=flat-square" alt="Node Support" /></a>
7
+ <img src="https://img.shields.io/badge/discord.js-v14.28.1-5865F2?style=flat-square&logo=discord" alt="discord.js v14.28.1" />
8
+ <img src="https://img.shields.io/badge/node-%3E%3D22.0.0-brightgreen.svg?style=flat-square&logo=node.js" alt="Node Support" />
9
+ <img src="https://img.shields.io/badge/TypeScript-7.0-blue?style=flat-square&logo=typescript" alt="TypeScript" />
8
10
  <a href="https://github.com/M3rcena/m3rcena-eco/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-blue.svg?style=flat-square" alt="License" /></a>
9
11
  <a href="https://github.com/M3rcena/m3rcena-eco/wiki"><img src="https://img.shields.io/badge/Wiki-Documentation-purple.svg?style=flat-square" alt="Eco Wiki Documentation" /></a>
10
12
  </p>
@@ -30,19 +32,69 @@
30
32
  - 🎰 **Casino & Gambling Suite**: Components V2 interactive Blackjack table (Hit, Stand, Double Down), Coinflip, Roulette, Crash multiplier rockets, Dice, and Slots.
31
33
  - 🏢 **Passive Business Enterprises**: Buy and upgrade companies (Lemonade Stands, Coffee Chains, Off-World Mining) with employee hiring and offline profit accumulation.
32
34
  - 🏆 **Interactive Leaderboards**: Paginated top rankings with metric selection (`Net Worth`, `Wallet`, `Bank`, `Level`, `Streaks`).
35
+ - 💾 **Native SQLite & Enterprise Prisma Storage**: Built-in zero-dependency local SQLite (`node:sqlite` WAL mode via `SqliteEcoStorage`) and auto-migrating Prisma ORM adapter (`PrismaEcoStorage`).
36
+ - 🦀 **Rust-Style Submodule Resolver**: Install and host via Git submodules locally with zero npm dependencies or transparently fall back to npm (`@m3rcena/eco/resolver`, `@m3rcena/eco/register`, `@m3rcena/eco/host`).
33
37
  - 🌐 **Dashboard Bridge**: Native integration with `@m3rcena/bridge` for real-time WebSocket syncing and presence-filtered audio cues (`coin_drop`, `win`, `purchase`, `rob_siren`).
38
+ - 🤖 **Discord.js v14.28.1 Ready**: Fully compatible with the latest Discord.js updates and `clientReady` lifecycle.
34
39
  - ⚡ **Next-Gen Performance**: Dual ESM/CJS, TypeScript 7.0 definitions, zero bloat, and sub-millisecond execution.
35
40
 
36
41
  ---
37
42
 
38
43
  ## 📦 Installation
39
44
 
45
+ ### Option A: Standard NPM Installation
46
+
40
47
  ```bash
48
+ # npm
41
49
  npm install @m3rcena/eco @m3rcena/bridge @napi-rs/canvas discord.js
50
+
51
+ # pnpm
52
+ pnpm add @m3rcena/eco @m3rcena/bridge @napi-rs/canvas discord.js
53
+
54
+ # yarn
55
+ yarn add @m3rcena/eco @m3rcena/bridge @napi-rs/canvas discord.js
42
56
  ```
43
57
 
44
58
  > **Note**: Requires Node.js **22.0.0+** (LTS 22, 24, 26). Node 20 is EOL and unsupported.
45
59
 
60
+ ### Option B: Local Git Submodule (Rust-Style Resolver)
61
+
62
+ You can vendor and host `@m3rcena/eco` locally via Git submodules without needing to publish or pull from npm:
63
+
64
+ ```bash
65
+ git submodule add https://github.com/M3rcena/m3rcena-eco.git submodules/m3rcena-eco
66
+ ```
67
+
68
+ Add auto-registration at the top of your app entrypoint:
69
+ ```typescript
70
+ import "@m3rcena/eco/register";
71
+ ```
72
+
73
+ Or run standalone hosting:
74
+ ```bash
75
+ npx tsx @m3rcena/eco/host --port 5124
76
+ ```
77
+
78
+ ---
79
+
80
+ ## 💾 Database Handlers & Persistence
81
+
82
+ `@m3rcena/eco` supports native SQLite WAL mode, Prisma ORM, and JSON file storage:
83
+
84
+ ```typescript
85
+ import {
86
+ EcoManager,
87
+ SqliteEcoStorage, // Zero-dependency SQLite (WAL mode)
88
+ PrismaEcoStorage, // PostgreSQL / MySQL / SQLite via Prisma ORM
89
+ JsonEcoStorage, // Lightweight JSON file storage
90
+ } from "@m3rcena/eco";
91
+
92
+ // Zero-dependency SQLite with WAL journal mode:
93
+ const eco = new EcoManager({
94
+ storage: new SqliteEcoStorage("./data/economy.sqlite"),
95
+ });
96
+ ```
97
+
46
98
  ---
47
99
 
48
100
  ## 🚀 Quick Example
@@ -159,9 +159,12 @@ var SqliteEcoStorage = class {
159
159
  dbPath;
160
160
  constructor(options = "./eco.sqlite") {
161
161
  const rawPath = typeof options === "string" ? options : options.path || "./eco.sqlite";
162
- this.dbPath = node_path.default.resolve(process.cwd(), rawPath);
163
- const dir = node_path.default.dirname(this.dbPath);
164
- if (!node_fs.default.existsSync(dir)) node_fs.default.mkdirSync(dir, { recursive: true });
162
+ if (rawPath === ":memory:") this.dbPath = ":memory:";
163
+ else {
164
+ this.dbPath = node_path.default.resolve(process.cwd(), rawPath);
165
+ const dir = node_path.default.dirname(this.dbPath);
166
+ if (!node_fs.default.existsSync(dir)) node_fs.default.mkdirSync(dir, { recursive: true });
167
+ }
165
168
  this.db = new node_sqlite.DatabaseSync(this.dbPath);
166
169
  if (typeof options === "object" ? options.walMode ?? true : true) try {
167
170
  this.db.exec("PRAGMA journal_mode = WAL;");
@@ -4393,6 +4396,103 @@ var RenderMarketChart = class {
4393
4396
  return canvas.toBuffer("image/png");
4394
4397
  }
4395
4398
  };
4399
+ // src/utils/Notifier.ts
4400
+ /**
4401
+ * @m3rcena/eco
4402
+ * Terminal update notification box utility.
4403
+ *
4404
+ * @copyright 2026 M3rcena Development. All rights reserved.
4405
+ * @license Apache-2.0
4406
+ */
4407
+ const yellow = (s) => `\x1b[33m${s}\x1b[39m`;
4408
+ const green = (s) => `\x1b[32m${s}\x1b[39m`;
4409
+ const red = (s) => `\x1b[31m${s}\x1b[39m`;
4410
+ const cyan = (s) => `\x1b[36m${s}\x1b[39m`;
4411
+ const ECO_VERSION = "14.28.1";
4412
+ /**
4413
+ * Strips ANSI color escape codes to compute visible string length.
4414
+ */
4415
+ function stripAnsi(str) {
4416
+ return str.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "");
4417
+ }
4418
+ /**
4419
+ * Renders an array of text messages inside a styled terminal box.
4420
+ */
4421
+ function boxConsole(messages) {
4422
+ const stripped = messages.map((m) => stripAnsi(m));
4423
+ const maxLen = Math.max(...stripped.map((s) => s.length)) + 8;
4424
+ const line = yellow("─".repeat(maxLen));
4425
+ console.log(yellow("┌") + line + yellow("┐"));
4426
+ console.log(yellow("│") + " ".repeat(maxLen) + yellow("│"));
4427
+ for (let i = 0; i < messages.length; i++) {
4428
+ const padTotal = maxLen - stripped[i].length;
4429
+ const padLeft = Math.floor(padTotal / 2);
4430
+ const padRight = padTotal - padLeft;
4431
+ console.log(yellow("│") + " ".repeat(padLeft) + messages[i] + " ".repeat(padRight) + yellow("│"));
4432
+ }
4433
+ console.log(yellow("│") + " ".repeat(maxLen) + yellow("│"));
4434
+ console.log(yellow("└") + line + yellow("┘"));
4435
+ }
4436
+ /**
4437
+ * Compares two semantic version strings.
4438
+ * Returns -1 if v1 < v2, 0 if equal, 1 if v1 > v2.
4439
+ */
4440
+ function compareSemver(v1, v2) {
4441
+ const clean1 = v1.replace(/^v/, "").split("-")[0].split(".").map((n) => parseInt(n, 10) || 0);
4442
+ const clean2 = v2.replace(/^v/, "").split("-")[0].split(".").map((n) => parseInt(n, 10) || 0);
4443
+ for (let i = 0; i < Math.max(clean1.length, clean2.length); i++) {
4444
+ const num1 = clean1[i] || 0;
4445
+ const num2 = clean2[i] || 0;
4446
+ if (num1 > num2) return 1;
4447
+ if (num1 < num2) return -1;
4448
+ }
4449
+ return 0;
4450
+ }
4451
+ /**
4452
+ * Fetches the latest published version of `@m3rcena/eco` from the npm registry.
4453
+ */
4454
+ async function fetchLatestVersion() {
4455
+ try {
4456
+ const controller = new AbortController();
4457
+ const timer = setTimeout(() => controller.abort(), 3500);
4458
+ timer.unref?.();
4459
+ const res = await fetch("https://registry.npmjs.org/@m3rcena/eco/latest", {
4460
+ signal: controller.signal,
4461
+ headers: { "User-Agent": "@m3rcena/eco-update-notifier" }
4462
+ });
4463
+ clearTimeout(timer);
4464
+ if (res.ok) {
4465
+ const data = await res.json();
4466
+ return typeof data.version === "string" ? data.version : null;
4467
+ }
4468
+ } catch {
4469
+ try {
4470
+ const { exec } = await import("child_process");
4471
+ const { promisify } = await import("util");
4472
+ const { stdout } = await promisify(exec)("npm show @m3rcena/eco version", { timeout: 3500 });
4473
+ return stdout.trim() || null;
4474
+ } catch {
4475
+ return null;
4476
+ }
4477
+ }
4478
+ return null;
4479
+ }
4480
+ /**
4481
+ * Checks if a newer version of `@m3rcena/eco` is available and logs the notification box.
4482
+ */
4483
+ async function checkPackageUpdates(currentVersion = ECO_VERSION, disabled) {
4484
+ if (disabled) return;
4485
+ try {
4486
+ const latest = await fetchLatestVersion();
4487
+ if (!latest) return;
4488
+ if (compareSemver(currentVersion, latest) < 0) boxConsole([
4489
+ `New ${green("version")} of ${yellow("@m3rcena/eco")} is available!`,
4490
+ `${red(currentVersion)} -> ${green(latest)}`,
4491
+ `Registry: ${cyan("https://www.npmjs.com/package/@m3rcena/eco")}`,
4492
+ `Run ${green(`npm i @m3rcena/eco@${latest}`)} to update!`
4493
+ ]);
4494
+ } catch {}
4495
+ }
4396
4496
  // src/bridge/EcoBridgeRouter.ts
4397
4497
  /**
4398
4498
  * @m3rcena/eco
@@ -4408,7 +4508,7 @@ var EcoBridgeRouter = class {
4408
4508
  name = "economy";
4409
4509
  basePath = "/api/eco";
4410
4510
  description = "Universal economy engine, financial banking, loans, taxes, stock market, and debit card rendering.";
4411
- version = "14.28.0";
4511
+ version = ECO_VERSION;
4412
4512
  eco;
4413
4513
  constructor(eco) {
4414
4514
  this.eco = eco;
@@ -4981,103 +5081,6 @@ var EcoWekyConnector = class extends node_events.EventEmitter {
4981
5081
  return this.activeWagers.get(wagerId);
4982
5082
  }
4983
5083
  };
4984
- // src/utils/Notifier.ts
4985
- /**
4986
- * @m3rcena/eco
4987
- * Terminal update notification box utility.
4988
- *
4989
- * @copyright 2026 M3rcena Development. All rights reserved.
4990
- * @license Apache-2.0
4991
- */
4992
- const yellow = (s) => `\x1b[33m${s}\x1b[39m`;
4993
- const green = (s) => `\x1b[32m${s}\x1b[39m`;
4994
- const red = (s) => `\x1b[31m${s}\x1b[39m`;
4995
- const cyan = (s) => `\x1b[36m${s}\x1b[39m`;
4996
- const ECO_VERSION = "14.28.0";
4997
- /**
4998
- * Strips ANSI color escape codes to compute visible string length.
4999
- */
5000
- function stripAnsi(str) {
5001
- return str.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "");
5002
- }
5003
- /**
5004
- * Renders an array of text messages inside a styled terminal box.
5005
- */
5006
- function boxConsole(messages) {
5007
- const stripped = messages.map((m) => stripAnsi(m));
5008
- const maxLen = Math.max(...stripped.map((s) => s.length)) + 8;
5009
- const line = yellow("─".repeat(maxLen));
5010
- console.log(yellow("┌") + line + yellow("┐"));
5011
- console.log(yellow("│") + " ".repeat(maxLen) + yellow("│"));
5012
- for (let i = 0; i < messages.length; i++) {
5013
- const padTotal = maxLen - stripped[i].length;
5014
- const padLeft = Math.floor(padTotal / 2);
5015
- const padRight = padTotal - padLeft;
5016
- console.log(yellow("│") + " ".repeat(padLeft) + messages[i] + " ".repeat(padRight) + yellow("│"));
5017
- }
5018
- console.log(yellow("│") + " ".repeat(maxLen) + yellow("│"));
5019
- console.log(yellow("└") + line + yellow("┘"));
5020
- }
5021
- /**
5022
- * Compares two semantic version strings.
5023
- * Returns -1 if v1 < v2, 0 if equal, 1 if v1 > v2.
5024
- */
5025
- function compareSemver(v1, v2) {
5026
- const clean1 = v1.replace(/^v/, "").split("-")[0].split(".").map((n) => parseInt(n, 10) || 0);
5027
- const clean2 = v2.replace(/^v/, "").split("-")[0].split(".").map((n) => parseInt(n, 10) || 0);
5028
- for (let i = 0; i < Math.max(clean1.length, clean2.length); i++) {
5029
- const num1 = clean1[i] || 0;
5030
- const num2 = clean2[i] || 0;
5031
- if (num1 > num2) return 1;
5032
- if (num1 < num2) return -1;
5033
- }
5034
- return 0;
5035
- }
5036
- /**
5037
- * Fetches the latest published version of `@m3rcena/eco` from the npm registry.
5038
- */
5039
- async function fetchLatestVersion() {
5040
- try {
5041
- const controller = new AbortController();
5042
- const timer = setTimeout(() => controller.abort(), 3500);
5043
- timer.unref?.();
5044
- const res = await fetch("https://registry.npmjs.org/@m3rcena/eco/latest", {
5045
- signal: controller.signal,
5046
- headers: { "User-Agent": "@m3rcena/eco-update-notifier" }
5047
- });
5048
- clearTimeout(timer);
5049
- if (res.ok) {
5050
- const data = await res.json();
5051
- return typeof data.version === "string" ? data.version : null;
5052
- }
5053
- } catch {
5054
- try {
5055
- const { exec } = await import("child_process");
5056
- const { promisify } = await import("util");
5057
- const { stdout } = await promisify(exec)("npm show @m3rcena/eco version", { timeout: 3500 });
5058
- return stdout.trim() || null;
5059
- } catch {
5060
- return null;
5061
- }
5062
- }
5063
- return null;
5064
- }
5065
- /**
5066
- * Checks if a newer version of `@m3rcena/eco` is available and logs the notification box.
5067
- */
5068
- async function checkPackageUpdates(currentVersion = ECO_VERSION, disabled) {
5069
- if (disabled) return;
5070
- try {
5071
- const latest = await fetchLatestVersion();
5072
- if (!latest) return;
5073
- if (compareSemver(currentVersion, latest) < 0) boxConsole([
5074
- `New ${green("version")} of ${yellow("@m3rcena/eco")} is available!`,
5075
- `${red(currentVersion)} -> ${green(latest)}`,
5076
- `Registry: ${cyan("https://www.npmjs.com/package/@m3rcena/eco")}`,
5077
- `Run ${green(`npm i @m3rcena/eco@${latest}`)} to update!`
5078
- ]);
5079
- } catch {}
5080
- }
5081
5084
  // src/EcoManager.ts
5082
5085
  /**
5083
5086
  * @m3rcena/eco
@@ -5792,7 +5795,7 @@ async function hostEco(options = {}) {
5792
5795
  status: "healthy",
5793
5796
  package: "@m3rcena/eco",
5794
5797
  mode: "local-submodule-host",
5795
- version: "14.28.0",
5798
+ version: ECO_VERSION,
5796
5799
  database: "SQLite",
5797
5800
  dbPath,
5798
5801
  uptime: process.uptime()
@@ -6157,4 +6160,4 @@ Object.defineProperty(exports, "stripAnsi", {
6157
6160
  }
6158
6161
  });
6159
6162
 
6160
- //# sourceMappingURL=host-3dAloQHW.cjs.map
6163
+ //# sourceMappingURL=host-Bmld-WtZ.cjs.map