pulse-rb 1.4.2 → 1.4.3

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.
@@ -25,6 +25,14 @@ local _BundleComponents = Components or {}
25
25
  local _BundlePages = _Pages or {}
26
26
  local _BundlePulse = Pulse or {}
27
27
 
28
+ -- Auto-enable dev logging when layout.dev = true.
29
+ -- Runs synchronously (before any task.spawn) so all UI setup logs are captured.
30
+ if _PULSE_LAYOUT.dev and _BundlePulse and _BundlePulse.Log then
31
+ _BundlePulse.Log.enable()
32
+ _BundlePulse.Log.configure({ level = "debug", console = true })
33
+ _BundlePulse.Log.info("dev", "dev build active")
34
+ end
35
+
28
36
  local _WINDUI_URL = "https://github.com/Footagesus/WindUI/releases/download/1.6.64-fix/main.lua"
29
37
  local _PULSE_LOGO = "https://pulse-rb.vercel.app/img/logo.svg"
30
38
 
@@ -594,13 +602,12 @@ task.spawn(function()
594
602
  local _execName = "Unknown"
595
603
  local _execVer = ""
596
604
  pcall(function()
597
- if type(rawget(_G, "identifyexecutor")) == "function" then
598
- local ok, n, v = pcall(identifyexecutor)
599
- if ok then _execName = tostring(n or "Unknown"); _execVer = tostring(v or "") end
600
- end
601
- if _execName == "Unknown" and type(rawget(_G, "getexecutorname")) == "function" then
602
- local ok, n = pcall(getexecutorname)
603
- if ok and n then _execName = tostring(n) end
605
+ -- pcall each call directly — avoids rawget missing __index-proxied executor globals
606
+ local ok, n, v = pcall(function() return identifyexecutor() end)
607
+ if ok and n then _execName = tostring(n); _execVer = tostring(v or "") end
608
+ if _execName == "Unknown" then
609
+ local ok2, n2 = pcall(function() return getexecutorname() end)
610
+ if ok2 and n2 then _execName = tostring(n2) end
604
611
  end
605
612
  if _execName == "Unknown" then
606
613
  if rawget(_G, "syn") or rawget(_G, "Synapse") then _execName = "Synapse X"
@@ -1056,12 +1063,6 @@ task.spawn(function()
1056
1063
  })
1057
1064
  end)
1058
1065
 
1059
- -- Auto-scan on inject
1060
- task.spawn(function()
1061
- if not game:IsLoaded() then game.Loaded:Wait() end
1062
- task.wait(2)
1063
- _doScan()
1064
- end)
1065
1066
  end
1066
1067
 
1067
1068
  -- Info section — framework version + signal counts for debugging
@@ -1091,47 +1092,6 @@ task.spawn(function()
1091
1092
  end
1092
1093
  end
1093
1094
 
1094
- -- Heartbeat Monitor section — tick counts per component (left)
1095
- -- Uses Pulse.Monitor which is independent of the log system.
1096
- local _monSect
1097
- pcall(function()
1098
- _monSect = _devLeft:Section({ Title="Heartbeat Monitor", Icon="activity", Box=true, BoxBorder=true, Opened=true })
1099
- end)
1100
- if _monSect then
1101
- local _monPara
1102
- pcall(function()
1103
- _monPara = _monSect:Paragraph({
1104
- Title = "raw / cond (updates 2s)",
1105
- Desc = "raw = every HB fire · cond = when() passed",
1106
- })
1107
- end)
1108
- -- Reads _rawHb/_condHb plain-Lua counters set in runtime._hbBind.
1109
- -- No dependency on Pulse.Monitor — works regardless of log system state.
1110
- task.spawn(function()
1111
- while _windWindow do
1112
- task.wait(2)
1113
- pcall(function()
1114
- local lines = {}
1115
- for cname, comp in pairs(_BundleComponents) do
1116
- if type(comp) == "table" and comp._rawHb ~= nil then
1117
- lines[#lines+1] = cname
1118
- .. " raw=" .. tostring(comp._rawHb)
1119
- .. " cond=" .. tostring(comp._condHb)
1120
- end
1121
- end
1122
- if _monPara then
1123
- if #lines == 0 then
1124
- _monPara:SetDesc("No heartbeat components registered")
1125
- else
1126
- table.sort(lines)
1127
- _monPara:SetDesc(table.concat(lines, "\n"))
1128
- end
1129
- end
1130
- end)
1131
- end
1132
- end)
1133
- end
1134
-
1135
1095
  -- Console section — controls for the Roblox developer console (F9).
1136
1096
  -- "Clear" wipes the output so only your next prints are visible.
1137
1097
  -- "Print Logs" re-dumps all buffered Pulse.Log entries so you can read
@@ -1177,6 +1137,17 @@ task.spawn(function()
1177
1137
  print("─────────────────────────────────────────")
1178
1138
  end
1179
1139
 
1140
+ pcall(function()
1141
+ _consoleSect:Button({
1142
+ Title = "Open Console",
1143
+ Desc = "Show the Roblox developer console (F9)",
1144
+ Callback = function()
1145
+ pcall(function()
1146
+ game:GetService("StarterGui"):SetCore("DevConsoleVisible", true)
1147
+ end)
1148
+ end,
1149
+ })
1150
+ end)
1180
1151
  pcall(function()
1181
1152
  _consoleSect:Button({
1182
1153
  Title = "Clear Console",
@@ -1212,6 +1183,30 @@ task.spawn(function()
1212
1183
  end
1213
1184
  end
1214
1185
 
1186
+ -- Apply defaults and notify ready — runs after all widgets are created so
1187
+ -- Toggles/Options are populated and SetValue calls land correctly.
1188
+ task.spawn(function()
1189
+ task.wait(0.5)
1190
+ for _, d in ipairs(_PULSE_DEFAULTS) do
1191
+ if d.set then pcall(d.set, d.value) end
1192
+ if d.type == "toggle" then
1193
+ pcall(function()
1194
+ local t = Toggles and Toggles[d.id]
1195
+ if t then t:SetValue(d.value) end
1196
+ end)
1197
+ else
1198
+ pcall(function()
1199
+ local t = Options and Options[d.id]
1200
+ if t then t:SetValue(d.value) end
1201
+ end)
1202
+ end
1203
+ task.wait(0.05)
1204
+ end
1205
+ if #_PULSE_DEFAULTS > 0 and _PulseNotify then
1206
+ _PulseNotify((L.title or "Hub") .. " loaded!", 5)
1207
+ end
1208
+ end)
1209
+
1215
1210
  -- Re-select first tab (Home) — Settings is last so Wind UI leaves it active
1216
1211
  task.defer(function()
1217
1212
  if _UIAdapter._firstTab then
package/dist/index.js CHANGED
@@ -56,7 +56,7 @@ var RB_VERSION, RB_HOME, IRONBREW2_DIR, IRONBREW2_REPO, ALWAYS_EXCLUDE, VALID_UI
56
56
  var init_constants = __esm({
57
57
  "src/constants.ts"() {
58
58
  init_cjs_shims();
59
- RB_VERSION = "1.4.2";
59
+ RB_VERSION = "1.4.3";
60
60
  RB_HOME = path.join(os.homedir(), ".rb");
61
61
  path.join(RB_HOME, "bin");
62
62
  IRONBREW2_DIR = path.join(RB_HOME, "ironbrew2");
@@ -1110,7 +1110,7 @@ function rglob(dir, exts) {
1110
1110
  walk(dir);
1111
1111
  return results;
1112
1112
  }
1113
- var PULSE_DIR, PULSE_DEV_DIR, PULSE_UI_DIR, REEXEC_GUARD, DESTROY_REGISTRATION, DEFAULTS_RUNNER, Compiler;
1113
+ var PULSE_DIR, PULSE_DEV_DIR, PULSE_UI_DIR, REEXEC_GUARD, DESTROY_REGISTRATION, Compiler;
1114
1114
  var init_compiler = __esm({
1115
1115
  "src/compiler.ts"() {
1116
1116
  init_cjs_shims();
@@ -1130,43 +1130,6 @@ if _G.__AOT_R_DESTROY then pcall(_G.__AOT_R_DESTROY) end
1130
1130
  `;
1131
1131
  DESTROY_REGISTRATION = `-- Register this instance so the next re-execution can clean it up.
1132
1132
  _G.__AOT_R_DESTROY = _PulseDestroy
1133
- `;
1134
- DEFAULTS_RUNNER = `task.spawn(function()
1135
- task.wait(0.5)
1136
- for _, d in ipairs(_PULSE_DEFAULTS) do
1137
- local effectiveValue = d.value
1138
- if d.type == "toggle" and Pulse.TestMode and Pulse.TestMode.isActive() then
1139
- if not Pulse.TestMode.isTarget(d.id) then
1140
- effectiveValue = false
1141
- end
1142
- end
1143
- if d.set then pcall(d.set, effectiveValue) end
1144
- if d.type == "toggle" then
1145
- pcall(function()
1146
- local t = Toggles and Toggles[d.id]
1147
- if t then t:SetValue(effectiveValue) end
1148
- end)
1149
- else
1150
- pcall(function()
1151
- local t = Options and Options[d.id]
1152
- if t then t:SetValue(d.value) end
1153
- end)
1154
- end
1155
- task.wait(0.05)
1156
- end
1157
- if #_PULSE_DEFAULTS > 0 then
1158
- local _notifyMsg = "AOT:Resistance Hub ready!"
1159
- if Pulse.TestMode and Pulse.TestMode.isActive() then
1160
- local _tt = Pulse.TestMode.getTargets()
1161
- if #_tt > 0 then
1162
- _notifyMsg = "Test mode: " .. table.concat(_tt, ", ")
1163
- end
1164
- end
1165
- if _PulseNotify then
1166
- _PulseNotify(_notifyMsg, 5)
1167
- end
1168
- end
1169
- end)
1170
1133
  `;
1171
1134
  Compiler = class {
1172
1135
  root;
@@ -1365,12 +1328,6 @@ end)
1365
1328
  `);
1366
1329
  parts.push(`local _P=loadstring(game:HttpGet("${base}/pulse.lua"))(_PULSE_LAYOUT)
1367
1330
  `);
1368
- if (opts.dev) {
1369
- parts.push(`_PULSE_DEV = true
1370
- `);
1371
- parts.push(`if _P.Pulse and _P.Pulse.Log then _P.Pulse.Log.enable() end
1372
- `);
1373
- }
1374
1331
  parts.push(`for _k,_v in pairs(_P) do _G[_k]=_v end
1375
1332
  `);
1376
1333
  parts.push(
@@ -1463,16 +1420,6 @@ end
1463
1420
  }
1464
1421
  parts.push("\n");
1465
1422
  }
1466
- if (order.some((f) => f.endsWith(".rblua") || f.endsWith(".ts"))) {
1467
- parts.push("-- [generated: defaults runner]\n");
1468
- parts.push(DEFAULTS_RUNNER);
1469
- parts.push("\n");
1470
- }
1471
- if (opts.dev) {
1472
- parts.push(
1473
- '-- [dev: log config]\nif Pulse and Pulse.Log then\n Pulse.Log.configure({ level = "debug", console = true })\n Pulse.Log.info("dev", "dev build active")\nend\n\n'
1474
- );
1475
- }
1476
1423
  parts.push("-- [generated: destroy registration]\n");
1477
1424
  parts.push(DESTROY_REGISTRATION);
1478
1425
  parts.push("\n");
@@ -1612,7 +1559,12 @@ async function obfuscateSource(source, ib2Dir) {
1612
1559
  if (stdout.startsWith("ERR:")) throw new Error(stdout.slice(4).trim());
1613
1560
  if (result.status !== 0) throw new Error(stderr || stdout || `exit ${result.status}`);
1614
1561
  if (!fs.existsSync(outPath)) throw new Error("IronBrew2 CLI produced no output file");
1615
- return fs.readFileSync(outPath, "utf8");
1562
+ let out = fs.readFileSync(outPath, "utf8");
1563
+ if (out.startsWith("--[[")) {
1564
+ const closeIdx = out.indexOf("]]");
1565
+ if (closeIdx !== -1) out = out.slice(closeIdx + 2).replace(/^\r?\n/, "");
1566
+ }
1567
+ return out;
1616
1568
  } finally {
1617
1569
  try {
1618
1570
  __require("fs").unlinkSync(tmpIn);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pulse-rb",
3
- "version": "1.4.2",
3
+ "version": "1.4.3",
4
4
  "description": "rb CLI — Pulse framework build tool for Roblox script projects",
5
5
  "bin": {
6
6
  "rb": "./bin/rb.js"
package/pulse/runtime.lua CHANGED
@@ -343,10 +343,11 @@ local function _signal(default)
343
343
  _sigCounter = _sigCounter + 1
344
344
  local s = Signal(default)
345
345
  s._id = ((_currentComponent and _currentComponent._name) or "g") .. "_s" .. _sigCounter
346
- s.set = function(_, v) s:set(v) end
347
- s.toggle = function(_) s:set(not s:get()) end
346
+ local _rawSet = s.set -- capture original before any override to avoid infinite recursion
347
+ s.set = function(_, v) _rawSet(s, v) end
348
+ s.toggle = function(_) _rawSet(s, not s:get()) end
348
349
  s.watch = function(_, fn) return s:onChange(fn) end
349
- s.update = function(_, fn) s:set(fn(s:get())) end
350
+ s.update = function(_, fn) _rawSet(s, fn(s:get())) end
350
351
  return s
351
352
  end
352
353