@ik-firewall/core 2.3.7 → 2.4.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.cjs CHANGED
@@ -202,6 +202,7 @@ var ConfigManager = class {
202
202
  config;
203
203
  registry;
204
204
  hooks;
205
+ blockedInstances = /* @__PURE__ */ new Set();
205
206
  constructor(initialConfig, hooks) {
206
207
  this.config = initialConfig;
207
208
  this.hooks = hooks;
@@ -308,11 +309,27 @@ var ConfigManager = class {
308
309
  if (instanceId && this.config.instanceConfigs?.[instanceId]) {
309
310
  merged = { ...merged, ...this.config.instanceConfigs[instanceId] };
310
311
  }
312
+ if (instanceId && this.blockedInstances.has(instanceId)) {
313
+ merged.billingStatus = "blocked";
314
+ }
311
315
  if (override) {
312
316
  merged = { ...merged, ...override };
313
317
  }
314
318
  return merged;
315
319
  }
320
+ /**
321
+ * Updates the live blocked status for an instance (Kill-Switch).
322
+ * This is used by UsageTracker when it receives a response from the central server.
323
+ */
324
+ setBlockedStatus(instanceId, blocked) {
325
+ if (blocked) {
326
+ this.blockedInstances.add(instanceId);
327
+ this.setInstanceConfig(instanceId, { billingStatus: "blocked" });
328
+ } else {
329
+ this.blockedInstances.delete(instanceId);
330
+ this.setInstanceConfig(instanceId, { billingStatus: "active" });
331
+ }
332
+ }
316
333
  updateConfig(newConfig) {
317
334
  this.config = {
318
335
  ...this.config,
@@ -1567,6 +1584,16 @@ var UsageTracker = class {
1567
1584
  if (!response.ok) {
1568
1585
  throw new Error(`HTTP Error: ${response.status} ${response.statusText}`);
1569
1586
  }
1587
+ try {
1588
+ const data = await response.json();
1589
+ if (data && (data.status === "blocked" || data.billingStatus === "blocked")) {
1590
+ this.config.setBlockedStatus(payload.instanceId, true);
1591
+ console.warn(`[IK_TRACKER] \u{1F6E1}\uFE0F Kill-Switch triggered for ${payload.instanceId}: Subscription inactive/blocked.`);
1592
+ } else if (data && (data.status === "active" || data.billingStatus === "active" || data.status === "trial")) {
1593
+ this.config.setBlockedStatus(payload.instanceId, false);
1594
+ }
1595
+ } catch (e) {
1596
+ }
1570
1597
  this.hooks?.onFlushSuccess?.(payload);
1571
1598
  }
1572
1599
  async handleFailure(payload) {
@@ -1869,16 +1896,11 @@ var IKFirewallCore = class _IKFirewallCore {
1869
1896
  }
1870
1897
  if (instanceId) {
1871
1898
  this.configManager.ensureInstanceConfig(instanceId);
1872
- this.configManager.syncRemoteConfig(instanceId).catch((err) => {
1873
- console.warn("[IK_CORE] Heartbeat sync failed:", err);
1874
- });
1875
1899
  }
1876
1900
  const mergedConfig = this.configManager.getMergedConfig(instanceId);
1877
- if (instanceId && mergedConfig?.isVerified === false) {
1878
- if (mergedConfig?.billingStatus === "blocked") {
1879
- this.hooks?.onStatus?.("\u26A0\uFE0F [IK_FIREWALL] Subscription inactive. Optimization bypassed (Fail-Safe mode).");
1880
- return this.getEmptyMetrics();
1881
- }
1901
+ if (instanceId && mergedConfig?.billingStatus === "blocked") {
1902
+ this.hooks?.onStatus?.("\u26A0\uFE0F [IK_FIREWALL] Subscription inactive. Optimization bypassed (Fail-Safe mode).");
1903
+ return this.getEmptyMetrics();
1882
1904
  }
1883
1905
  let auditProvider = this.localProvider;
1884
1906
  let overrideProvider = null;
package/dist/index.js CHANGED
@@ -160,6 +160,7 @@ var ConfigManager = class {
160
160
  config;
161
161
  registry;
162
162
  hooks;
163
+ blockedInstances = /* @__PURE__ */ new Set();
163
164
  constructor(initialConfig, hooks) {
164
165
  this.config = initialConfig;
165
166
  this.hooks = hooks;
@@ -266,11 +267,27 @@ var ConfigManager = class {
266
267
  if (instanceId && this.config.instanceConfigs?.[instanceId]) {
267
268
  merged = { ...merged, ...this.config.instanceConfigs[instanceId] };
268
269
  }
270
+ if (instanceId && this.blockedInstances.has(instanceId)) {
271
+ merged.billingStatus = "blocked";
272
+ }
269
273
  if (override) {
270
274
  merged = { ...merged, ...override };
271
275
  }
272
276
  return merged;
273
277
  }
278
+ /**
279
+ * Updates the live blocked status for an instance (Kill-Switch).
280
+ * This is used by UsageTracker when it receives a response from the central server.
281
+ */
282
+ setBlockedStatus(instanceId, blocked) {
283
+ if (blocked) {
284
+ this.blockedInstances.add(instanceId);
285
+ this.setInstanceConfig(instanceId, { billingStatus: "blocked" });
286
+ } else {
287
+ this.blockedInstances.delete(instanceId);
288
+ this.setInstanceConfig(instanceId, { billingStatus: "active" });
289
+ }
290
+ }
274
291
  updateConfig(newConfig) {
275
292
  this.config = {
276
293
  ...this.config,
@@ -1525,6 +1542,16 @@ var UsageTracker = class {
1525
1542
  if (!response.ok) {
1526
1543
  throw new Error(`HTTP Error: ${response.status} ${response.statusText}`);
1527
1544
  }
1545
+ try {
1546
+ const data = await response.json();
1547
+ if (data && (data.status === "blocked" || data.billingStatus === "blocked")) {
1548
+ this.config.setBlockedStatus(payload.instanceId, true);
1549
+ console.warn(`[IK_TRACKER] \u{1F6E1}\uFE0F Kill-Switch triggered for ${payload.instanceId}: Subscription inactive/blocked.`);
1550
+ } else if (data && (data.status === "active" || data.billingStatus === "active" || data.status === "trial")) {
1551
+ this.config.setBlockedStatus(payload.instanceId, false);
1552
+ }
1553
+ } catch (e) {
1554
+ }
1528
1555
  this.hooks?.onFlushSuccess?.(payload);
1529
1556
  }
1530
1557
  async handleFailure(payload) {
@@ -1827,16 +1854,11 @@ var IKFirewallCore = class _IKFirewallCore {
1827
1854
  }
1828
1855
  if (instanceId) {
1829
1856
  this.configManager.ensureInstanceConfig(instanceId);
1830
- this.configManager.syncRemoteConfig(instanceId).catch((err) => {
1831
- console.warn("[IK_CORE] Heartbeat sync failed:", err);
1832
- });
1833
1857
  }
1834
1858
  const mergedConfig = this.configManager.getMergedConfig(instanceId);
1835
- if (instanceId && mergedConfig?.isVerified === false) {
1836
- if (mergedConfig?.billingStatus === "blocked") {
1837
- this.hooks?.onStatus?.("\u26A0\uFE0F [IK_FIREWALL] Subscription inactive. Optimization bypassed (Fail-Safe mode).");
1838
- return this.getEmptyMetrics();
1839
- }
1859
+ if (instanceId && mergedConfig?.billingStatus === "blocked") {
1860
+ this.hooks?.onStatus?.("\u26A0\uFE0F [IK_FIREWALL] Subscription inactive. Optimization bypassed (Fail-Safe mode).");
1861
+ return this.getEmptyMetrics();
1840
1862
  }
1841
1863
  let auditProvider = this.localProvider;
1842
1864
  let overrideProvider = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ik-firewall/core",
3
- "version": "2.3.7",
3
+ "version": "2.4.0",
4
4
  "type": "module",
5
5
  "description": "The core IK Firewall engine for semantic-driven AI optimization.",
6
6
  "main": "./dist/index.js",