dsh-builtin-browser 0.4.1 → 0.4.5

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.
Files changed (57) hide show
  1. package/CHANGELOG.md +1699 -0
  2. package/README.en.md +114 -33
  3. package/README.md +108 -32
  4. package/client.js +478 -29
  5. package/cordis.patch.yml +21 -0
  6. package/desktop-bridge/install.mjs +66 -6
  7. package/desktop-bridge/plugin-browser-bridge.js +426 -167
  8. package/docs/architecture.md +14 -4
  9. package/docs/tool-reference.md +13 -13
  10. package/docs/user-guide.md +58 -3
  11. package/docs/why-browser.md +1 -1
  12. package/lib/browser/types.d.ts +34 -3
  13. package/lib/browser-electron/bridge-connection.d.ts +49 -26
  14. package/lib/browser-electron/bridge-connection.js +185 -22
  15. package/lib/browser-electron/desktop-bridge-host.d.ts +69 -36
  16. package/lib/browser-electron/desktop-bridge-host.js +151 -86
  17. package/lib/browser-electron/entry.d.ts +1 -1
  18. package/lib/browser-electron/entry.js +133 -40
  19. package/lib/browser-electron/ephemeral-profile.d.ts +37 -0
  20. package/lib/browser-electron/ephemeral-profile.js +146 -0
  21. package/lib/browser-electron/history-store.d.ts +36 -2
  22. package/lib/browser-electron/history-store.js +76 -7
  23. package/lib/browser-electron/host-main.js +86 -28
  24. package/lib/browser-electron/provider.d.ts +106 -3
  25. package/lib/browser-electron/provider.js +407 -60
  26. package/lib/browser-electron/remote-host.d.ts +52 -3
  27. package/lib/browser-electron/remote-host.js +259 -25
  28. package/lib/browser-electron/rpc-ops.d.ts +18 -0
  29. package/lib/browser-electron/rpc-ops.js +36 -0
  30. package/lib/browser-electron/settings-route.d.ts +28 -0
  31. package/lib/browser-electron/settings-route.js +68 -0
  32. package/lib/browser-electron/settings-store.d.ts +40 -0
  33. package/lib/browser-electron/settings-store.js +160 -23
  34. package/lib/browser-electron/system-browser.d.ts +102 -12
  35. package/lib/browser-electron/system-browser.js +411 -51
  36. package/lib/index.js +0 -1
  37. package/lib/tool-browser/element-fields.d.ts +145 -0
  38. package/lib/tool-browser/element-fields.js +152 -0
  39. package/lib/tool-browser/index.js +149 -74
  40. package/package.json +10 -4
  41. package/scripts/verify-host-compat.mjs +195 -0
  42. package/src/browser/types.ts +34 -3
  43. package/src/browser-electron/bridge-connection.ts +179 -22
  44. package/src/browser-electron/desktop-bridge-host.ts +146 -84
  45. package/src/browser-electron/entry.ts +132 -39
  46. package/src/browser-electron/ephemeral-profile.ts +152 -0
  47. package/src/browser-electron/history-store.ts +81 -9
  48. package/src/browser-electron/host-main.ts +115 -36
  49. package/src/browser-electron/provider.ts +492 -69
  50. package/src/browser-electron/remote-host.ts +276 -38
  51. package/src/browser-electron/rpc-ops.ts +41 -0
  52. package/src/browser-electron/settings-route.ts +87 -0
  53. package/src/browser-electron/settings-store.ts +173 -24
  54. package/src/browser-electron/system-browser.ts +408 -39
  55. package/src/index.ts +3 -2
  56. package/src/tool-browser/element-fields.ts +167 -0
  57. package/src/tool-browser/index.ts +155 -76
@@ -106,11 +106,31 @@ ${MARKER} pages.
106
106
  // Installed by apps/desktop/bridge/install.mjs — re-run it after a desktop upgrade.
107
107
  // A bridge failure is never fatal to the shell.
108
108
  app.whenReady().then(async () => {
109
+ const bridgeUrl = new URL("./plugin-browser-bridge.js", import.meta.url);
110
+ const loadBridge = async (why) => {
111
+ try {
112
+ // A plain import is cached for the process lifetime, so an edited bridge
113
+ // would need a shell restart. The stamp makes every load read the current
114
+ // bytes; start() itself stops the previous instance, so this reloads in place.
115
+ const bridge = await import(bridgeUrl.href + "?v=" + Date.now());
116
+ bridge.start();
117
+ console.log("[dsh-browser-bridge] started" + (why ? " (" + why + ")" : ""));
118
+ } catch (error) {
119
+ console.error("[dsh-browser-bridge] start failed:", error);
120
+ }
121
+ };
122
+ await loadBridge();
123
+ // Watch the module so an edit reloads it in place instead of forcing a shell
124
+ // restart. Debounced; a failure here is never fatal to the shell.
109
125
  try {
110
- const bridge = await import("./plugin-browser-bridge.js");
111
- bridge.start();
126
+ const { watch } = await import("node:fs");
127
+ let timer = null;
128
+ watch(bridgeUrl, { persistent: false }, () => {
129
+ if (timer) clearTimeout(timer);
130
+ timer = setTimeout(() => void loadBridge("file changed"), 300);
131
+ });
112
132
  } catch (error) {
113
- console.error("[dsh-browser-bridge] start failed:", error);
133
+ console.error("[dsh-browser-bridge] watch failed:", error);
114
134
  }
115
135
  });
116
136
  `
@@ -273,9 +293,49 @@ if (revert) {
273
293
  reverted = true
274
294
  }
275
295
  if (existsSync(backupPath)) {
276
- copyFileSync(backupPath, mainPath)
277
- console.log(`restored ${mainPath} from ${backupPath}`)
278
- reverted = true
296
+ // Refuse when the backup no longer matches the tree it would overwrite.
297
+ //
298
+ // The backup is taken once and then kept, so after a desktop upgrade it holds the PREVIOUS
299
+ // build's main.js. Restoring it would silently roll the app back to that build's code — and
300
+ // it would also discard any patch another tool applied in the meantime, which is not a
301
+ // hypothetical here: `dsh-purge` patches this same file, so a blind revert erases its work
302
+ // while reporting success. A matching current file is the only case where the restore is
303
+ // unambiguously right; anything else needs a human to decide.
304
+ let backedUp
305
+ let current
306
+ try {
307
+ backedUp = readFileSync(backupPath)
308
+ current = readFileSync(mainPath)
309
+ } catch {
310
+ backedUp = undefined
311
+ current = undefined
312
+ }
313
+ const identical = backedUp !== undefined && current !== undefined && backedUp.equals(current)
314
+ const stillHasOurMarker = current !== undefined && current.includes(MARKER)
315
+ // A backup taken BEFORE the file was patched by anything else is not a clean restore
316
+ // point: reverting to it discards those patches. The marker test alone does not catch
317
+ // this, because the current file legitimately carries our marker — that is exactly what
318
+ // this script put there — while the backup predates a patch by another tool.
319
+ // `dsh-purge` patches this same file, so on this machine that is not hypothetical.
320
+ const backupHasOurMarker = backedUp !== undefined && backedUp.includes(MARKER)
321
+ if (!identical && stillHasOurMarker && !backupHasOurMarker) {
322
+ console.error(`WARNING: ${backupPath} predates the bridge patch, so it is not a clean`)
323
+ console.error(` restore point for ${mainPath}. Reverting would also discard anything`)
324
+ console.error(' patched in between (dsh-purge patches this same file). Refreshing the')
325
+ console.error(' backup from the current file instead, so a later --revert is safe.')
326
+ writeFileSync(backupPath, current ?? Buffer.alloc(0))
327
+ reverted = true
328
+ } else if (!identical && !stillHasOurMarker) {
329
+ console.error(`WARNING: ${mainPath} has changed since the backup was taken, and it does`)
330
+ console.error(' not contain the bridge import either — something else has edited it')
331
+ console.error(' (a desktop upgrade, or another patch tool). Restoring the backup would')
332
+ console.error(` discard that. The backup is at ${backupPath}; restore it by hand if that`)
333
+ console.error(' is what you want. Skipping this file.')
334
+ } else {
335
+ copyFileSync(backupPath, mainPath)
336
+ console.log(`restored ${mainPath} from ${backupPath}`)
337
+ reverted = true
338
+ }
279
339
  }
280
340
  if (existsSync(cliShimBackup)) {
281
341
  copyFileSync(cliShimBackup, cliShimPath)