@dimina-kit/devtools 0.3.2-dev.20260524102544 → 0.3.2-dev.20260525152421

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.
@@ -1,5 +1,12 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
1
8
  // src/main/app/bootstrap.ts
2
- import { app as app2 } from "electron";
9
+ import { app as app2, protocol } from "electron";
3
10
 
4
11
  // src/shared/constants.ts
5
12
  var DEFAULT_CDP_PORT = 9222;
@@ -63,6 +70,24 @@ function applyTheme(theme) {
63
70
  }
64
71
 
65
72
  // src/main/app/bootstrap.ts
73
+ var difileSchemeRegistered = false;
74
+ function registerDifileScheme() {
75
+ if (difileSchemeRegistered) return;
76
+ difileSchemeRegistered = true;
77
+ protocol.registerSchemesAsPrivileged([
78
+ {
79
+ scheme: "difile",
80
+ privileges: {
81
+ standard: true,
82
+ secure: true,
83
+ supportFetchAPI: true,
84
+ stream: true,
85
+ bypassCSP: true,
86
+ corsEnabled: true
87
+ }
88
+ }
89
+ ]);
90
+ }
66
91
  function setupCdpPort() {
67
92
  if (app2.commandLine.getSwitchValue("remote-debugging-port")) return;
68
93
  const envPort = process.env.DIMINA_DEBUG_PORT;
@@ -79,9 +104,9 @@ function setupCdpPort() {
79
104
  }
80
105
 
81
106
  // src/main/app/app.ts
82
- import { app as app13, BrowserWindow as BrowserWindow4, nativeImage } from "electron";
83
- import fs7 from "fs";
84
- import path12 from "path";
107
+ import { app as app13, BrowserWindow as BrowserWindow4, nativeImage, session as session2 } from "electron";
108
+ import fs9 from "fs";
109
+ import path14 from "path";
85
110
 
86
111
  // src/main/utils/paths.ts
87
112
  import fs2 from "fs";
@@ -1094,11 +1119,11 @@ function createWorkspaceService(ctx) {
1094
1119
  }
1095
1120
  async function disposeSession() {
1096
1121
  if (!currentSession) return;
1097
- const session2 = currentSession;
1122
+ const session3 = currentSession;
1098
1123
  currentSession = null;
1099
1124
  try {
1100
1125
  await Promise.race([
1101
- session2.close(),
1126
+ session3.close(),
1102
1127
  new Promise(
1103
1128
  (_, reject) => setTimeout(() => reject(new Error("session close timed out")), 5e3)
1104
1129
  )
@@ -1107,8 +1132,8 @@ function createWorkspaceService(ctx) {
1107
1132
  console.error("[workspace] session close failed:", err);
1108
1133
  }
1109
1134
  }
1110
- function applyRefererFromSession(session2) {
1111
- const appInfo = session2.appInfo;
1135
+ function applyRefererFromSession(session3) {
1136
+ const appInfo = session3.appInfo;
1112
1137
  if (appInfo && typeof appInfo.appId === "string" && appInfo.appId.length > 0) {
1113
1138
  setSimulatorServicewechatReferer(
1114
1139
  appInfo.appId,
@@ -1139,9 +1164,9 @@ function createWorkspaceService(ctx) {
1139
1164
  }
1140
1165
  sendStatus("compiling", "\u6B63\u5728\u7F16\u8BD1...");
1141
1166
  const { compile } = loadWorkbenchSettings();
1142
- let session2;
1167
+ let session3;
1143
1168
  try {
1144
- session2 = await ctx.adapter.openProject({
1169
+ session3 = await ctx.adapter.openProject({
1145
1170
  projectPath,
1146
1171
  sourcemap: true,
1147
1172
  watch: compile.watch,
@@ -1153,17 +1178,17 @@ function createWorkspaceService(ctx) {
1153
1178
  sendStatus("error", String(err));
1154
1179
  return { success: false, error: String(err) };
1155
1180
  }
1156
- currentSession = session2;
1181
+ currentSession = session3;
1157
1182
  currentProjectPath = projectPath;
1158
1183
  bestEffort("updateLastOpened", () => {
1159
1184
  if (provider.updateLastOpened) provider.updateLastOpened(projectPath);
1160
1185
  });
1161
1186
  bestEffort("sendStatus", () => sendStatus("ready", "\u7F16\u8BD1\u5B8C\u6210"));
1162
- bestEffort("applyReferer", () => applyRefererFromSession(session2));
1187
+ bestEffort("applyReferer", () => applyRefererFromSession(session3));
1163
1188
  return {
1164
1189
  success: true,
1165
- port: session2.port,
1166
- appInfo: session2.appInfo
1190
+ port: session3.port,
1191
+ appInfo: session3.appInfo
1167
1192
  };
1168
1193
  },
1169
1194
  async closeProject() {
@@ -3532,6 +3557,528 @@ async function clearElementInspection() {
3532
3557
  }
3533
3558
  }
3534
3559
 
3560
+ // src/main/services/simulator-temp-files/store.ts
3561
+ function registerTempFile(store, path16, mime, bytes) {
3562
+ const buf = Buffer.isBuffer(bytes) ? bytes : Buffer.from(new Uint8Array(bytes));
3563
+ store.delete(path16);
3564
+ store.set(path16, { bytes: buf, mime });
3565
+ }
3566
+ function revokeTempFile(store, path16) {
3567
+ store.delete(path16);
3568
+ }
3569
+ function revokeAllTempFiles(store) {
3570
+ store.clear();
3571
+ }
3572
+
3573
+ // src/simulator/vpath.ts
3574
+ var _os = typeof __require !== "undefined" ? __require("os") : null;
3575
+ var _path = typeof __require !== "undefined" ? __require("path") : null;
3576
+ var DIFILE_PREFIX = "difile://";
3577
+ function sandboxBase() {
3578
+ const env = typeof process !== "undefined" && process.env && process.env.DIMINA_HOME || "";
3579
+ if (env) {
3580
+ return _path.join(env, "files");
3581
+ }
3582
+ const home = _os ? _os.homedir() : "/tmp";
3583
+ return _path.join(home, ".dimina", "files");
3584
+ }
3585
+ function resolveVPath(url) {
3586
+ if (typeof url !== "string") return null;
3587
+ if (!url.startsWith(DIFILE_PREFIX)) return null;
3588
+ const raw = url.slice(DIFILE_PREFIX.length);
3589
+ if (raw.length === 0) return null;
3590
+ let decoded;
3591
+ try {
3592
+ decoded = decodeURIComponent(raw);
3593
+ } catch {
3594
+ return null;
3595
+ }
3596
+ if (decoded.includes("\0")) return null;
3597
+ decoded = decoded.replace(/^[/\\]+/, "");
3598
+ if (decoded.length === 0) return null;
3599
+ const segments = decoded.split(/[/\\]+/);
3600
+ if (segments.some((s) => s === ".." || s === ".")) return null;
3601
+ let kind;
3602
+ let writable;
3603
+ if (decoded.startsWith("_tmp/")) {
3604
+ kind = "tmp";
3605
+ writable = false;
3606
+ } else if (decoded.startsWith("_store/")) {
3607
+ kind = "store";
3608
+ writable = false;
3609
+ } else {
3610
+ kind = "usr";
3611
+ writable = true;
3612
+ }
3613
+ if (kind === "tmp") {
3614
+ return { kind, writable };
3615
+ }
3616
+ const base = sandboxBase();
3617
+ const joined = _path.join(base, decoded);
3618
+ const normalized = _path.normalize(joined);
3619
+ if (normalized !== base && !normalized.startsWith(base + _path.sep)) return null;
3620
+ return { kind, writable, realPath: normalized };
3621
+ }
3622
+
3623
+ // src/main/services/simulator-temp-files/disk.ts
3624
+ import fs7 from "node:fs/promises";
3625
+ import path12 from "node:path";
3626
+ var EXT_MIME = {
3627
+ ".txt": "text/plain",
3628
+ ".log": "text/plain",
3629
+ ".md": "text/markdown",
3630
+ ".html": "text/html",
3631
+ ".htm": "text/html",
3632
+ ".css": "text/css",
3633
+ ".csv": "text/csv",
3634
+ ".json": "application/json",
3635
+ ".xml": "application/xml",
3636
+ ".js": "application/javascript",
3637
+ ".mjs": "application/javascript",
3638
+ ".svg": "image/svg+xml",
3639
+ ".png": "image/png",
3640
+ ".jpg": "image/jpeg",
3641
+ ".jpeg": "image/jpeg",
3642
+ ".gif": "image/gif",
3643
+ ".webp": "image/webp",
3644
+ ".bmp": "image/bmp",
3645
+ ".ico": "image/x-icon",
3646
+ ".mp4": "video/mp4",
3647
+ ".m4v": "video/mp4",
3648
+ ".webm": "video/webm",
3649
+ ".mov": "video/quicktime",
3650
+ ".mp3": "audio/mpeg",
3651
+ ".wav": "audio/wav",
3652
+ ".ogg": "audio/ogg",
3653
+ ".pdf": "application/pdf",
3654
+ ".zip": "application/zip"
3655
+ };
3656
+ function sniffMime(head) {
3657
+ if (head.length >= 8 && head[0] === 137 && head[1] === 80 && head[2] === 78 && head[3] === 71 && head[4] === 13 && head[5] === 10 && head[6] === 26 && head[7] === 10) {
3658
+ return "image/png";
3659
+ }
3660
+ if (head.length >= 3 && head[0] === 255 && head[1] === 216 && head[2] === 255) {
3661
+ return "image/jpeg";
3662
+ }
3663
+ if (head.length >= 6 && head[0] === 71 && head[1] === 73 && head[2] === 70 && head[3] === 56 && (head[4] === 55 || head[4] === 57) && head[5] === 97) {
3664
+ return "image/gif";
3665
+ }
3666
+ if (head.length >= 12 && head[0] === 82 && head[1] === 73 && head[2] === 70 && head[3] === 70 && head[8] === 87 && head[9] === 69 && head[10] === 66 && head[11] === 80) {
3667
+ return "image/webp";
3668
+ }
3669
+ if (head.length >= 12 && head[4] === 102 && head[5] === 116 && head[6] === 121 && head[7] === 112) {
3670
+ return "video/mp4";
3671
+ }
3672
+ if (head.length >= 4 && head[0] === 37 && head[1] === 80 && head[2] === 68 && head[3] === 70) {
3673
+ return "application/pdf";
3674
+ }
3675
+ if (head.length >= 2 && head[0] === 66 && head[1] === 77) {
3676
+ return "image/bmp";
3677
+ }
3678
+ if (head.length >= 4 && head[0] === 80 && head[1] === 75 && head[2] === 3 && head[3] === 4) {
3679
+ return "application/zip";
3680
+ }
3681
+ if (head.length >= 3 && head[0] === 73 && head[1] === 68 && head[2] === 51) {
3682
+ return "audio/mpeg";
3683
+ }
3684
+ if (head.length >= 4 && head[0] === 79 && head[1] === 103 && head[2] === 103 && head[3] === 83) {
3685
+ return "audio/ogg";
3686
+ }
3687
+ return null;
3688
+ }
3689
+ function extMime(realPath) {
3690
+ const ext = path12.extname(realPath).toLowerCase();
3691
+ if (!ext) return null;
3692
+ return EXT_MIME[ext] ?? null;
3693
+ }
3694
+ function detectMime(realPath, head) {
3695
+ const sniffed = sniffMime(head);
3696
+ if (sniffed) return sniffed;
3697
+ const byExt = extMime(realPath);
3698
+ if (byExt) return byExt;
3699
+ return "application/octet-stream";
3700
+ }
3701
+ function etagOf(mtimeMs, size) {
3702
+ return `W/"${Math.floor(mtimeMs)}-${size}"`;
3703
+ }
3704
+ async function readDiskFile(realPath, opts) {
3705
+ const handle = await fs7.open(realPath, "r");
3706
+ try {
3707
+ const st = await handle.stat();
3708
+ const totalSize = st.size;
3709
+ const mtimeMs = st.mtimeMs;
3710
+ const range = opts?.range;
3711
+ let sliceStart = 0;
3712
+ let sliceLen = totalSize;
3713
+ if (range) {
3714
+ const { start, end } = range;
3715
+ if (!Number.isFinite(start) || !Number.isFinite(end)) {
3716
+ throw new RangeError(`invalid range: ${start}-${end}`);
3717
+ }
3718
+ if (start < 0) throw new RangeError(`range start out of bounds: ${start}`);
3719
+ if (start > end) throw new RangeError(`range start > end: ${start} > ${end}`);
3720
+ if (start >= totalSize) {
3721
+ throw new RangeError(`range start beyond file size: ${start} >= ${totalSize}`);
3722
+ }
3723
+ const clampedEnd = Math.min(end, totalSize - 1);
3724
+ sliceStart = start;
3725
+ sliceLen = clampedEnd - start + 1;
3726
+ }
3727
+ const head = Buffer.alloc(Math.min(12, totalSize));
3728
+ if (head.length > 0) {
3729
+ await handle.read(head, 0, head.length, 0);
3730
+ }
3731
+ let bytes;
3732
+ if (!range) {
3733
+ bytes = Buffer.alloc(totalSize);
3734
+ if (totalSize > 0) {
3735
+ if (totalSize <= head.length) {
3736
+ head.copy(bytes, 0, 0, totalSize);
3737
+ } else {
3738
+ head.copy(bytes, 0, 0, head.length);
3739
+ await handle.read(bytes, head.length, totalSize - head.length, head.length);
3740
+ }
3741
+ }
3742
+ } else {
3743
+ bytes = Buffer.alloc(sliceLen);
3744
+ if (sliceLen > 0) {
3745
+ await handle.read(bytes, 0, sliceLen, sliceStart);
3746
+ }
3747
+ }
3748
+ return {
3749
+ bytes,
3750
+ mime: detectMime(realPath, head),
3751
+ etag: etagOf(mtimeMs, totalSize),
3752
+ totalSize
3753
+ };
3754
+ } finally {
3755
+ await handle.close();
3756
+ }
3757
+ }
3758
+ async function writeDiskFile(realPath, bytes) {
3759
+ const buf = Buffer.isBuffer(bytes) ? bytes : Buffer.from(new Uint8Array(bytes));
3760
+ await fs7.mkdir(path12.dirname(realPath), { recursive: true });
3761
+ await fs7.writeFile(realPath, buf);
3762
+ }
3763
+ async function readDiskDir(realPath) {
3764
+ const entries = await fs7.readdir(realPath);
3765
+ return entries;
3766
+ }
3767
+ async function statDiskFile(realPath) {
3768
+ const st = await fs7.stat(realPath);
3769
+ return {
3770
+ size: st.size,
3771
+ mtime: Math.floor(st.mtimeMs),
3772
+ mode: st.mode,
3773
+ isFile: st.isFile(),
3774
+ isDirectory: st.isDirectory()
3775
+ };
3776
+ }
3777
+
3778
+ // src/main/services/simulator-temp-files/request-handler.ts
3779
+ var CACHE_CONTROL = "public, max-age=31536000, immutable";
3780
+ function getHeader(headers, name) {
3781
+ if (!headers) return void 0;
3782
+ const lc = name.toLowerCase();
3783
+ for (const k of Object.keys(headers)) {
3784
+ if (k.toLowerCase() === lc) return headers[k];
3785
+ }
3786
+ return void 0;
3787
+ }
3788
+ function etagsMatch(a, b) {
3789
+ if (!a) return false;
3790
+ const stripped = (s) => s.startsWith("W/") ? s.slice(2) : s;
3791
+ return stripped(a.trim()) === stripped(b);
3792
+ }
3793
+ function parseRange(header, totalSize) {
3794
+ if (!header) return null;
3795
+ const m = /^bytes=(\d*)-(\d*)$/.exec(header.trim());
3796
+ if (!m) return null;
3797
+ const startStr = m[1];
3798
+ const endStr = m[2];
3799
+ if (startStr === "" && endStr === "") return null;
3800
+ if (startStr === "") {
3801
+ const n = Number(endStr);
3802
+ if (!Number.isFinite(n) || n <= 0) return null;
3803
+ const start2 = Math.max(0, totalSize - n);
3804
+ return { start: start2, end: totalSize - 1 };
3805
+ }
3806
+ const start = Number(startStr);
3807
+ if (!Number.isFinite(start) || start < 0) return null;
3808
+ const end = endStr === "" ? totalSize - 1 : Number(endStr);
3809
+ if (!Number.isFinite(end)) return null;
3810
+ return { start, end };
3811
+ }
3812
+ function notFound() {
3813
+ return new Response(null, { status: 404 });
3814
+ }
3815
+ function notModified(etag) {
3816
+ return new Response(null, {
3817
+ status: 304,
3818
+ headers: {
3819
+ ETag: etag,
3820
+ "Cache-Control": CACHE_CONTROL,
3821
+ "Access-Control-Allow-Origin": "*"
3822
+ }
3823
+ });
3824
+ }
3825
+ function bufferToBody(bytes) {
3826
+ const out = new ArrayBuffer(bytes.byteLength);
3827
+ new Uint8Array(out).set(bytes);
3828
+ return out;
3829
+ }
3830
+ function tempBody(bytes, mime) {
3831
+ return new Response(bufferToBody(bytes), {
3832
+ status: 200,
3833
+ headers: {
3834
+ "Content-Type": mime,
3835
+ "Cache-Control": CACHE_CONTROL,
3836
+ "Access-Control-Allow-Origin": "*"
3837
+ }
3838
+ });
3839
+ }
3840
+ async function handleDifileRequest(ctx, req) {
3841
+ const v = resolveVPath(req.url);
3842
+ if (!v) return notFound();
3843
+ if (v.kind === "tmp") {
3844
+ const record = ctx.tempStore.get(req.url);
3845
+ if (!record) return notFound();
3846
+ return tempBody(record.bytes, record.mime || "application/octet-stream");
3847
+ }
3848
+ if (!v.realPath) return notFound();
3849
+ try {
3850
+ const probe = await readDiskFile(v.realPath);
3851
+ const etag = probe.etag;
3852
+ const totalSize = probe.totalSize;
3853
+ const mime = probe.mime;
3854
+ const ifNoneMatch = getHeader(req.headers, "If-None-Match");
3855
+ if (etagsMatch(ifNoneMatch, etag)) {
3856
+ return notModified(etag);
3857
+ }
3858
+ const rangeHeader = getHeader(req.headers, "Range");
3859
+ const range = parseRange(rangeHeader, totalSize);
3860
+ if (range) {
3861
+ if (range.start < 0 || range.start >= totalSize || range.end < range.start) {
3862
+ return new Response(null, {
3863
+ status: 416,
3864
+ headers: {
3865
+ "Content-Range": `bytes */${totalSize}`,
3866
+ "Access-Control-Allow-Origin": "*"
3867
+ }
3868
+ });
3869
+ }
3870
+ const clampedEnd = Math.min(range.end, totalSize - 1);
3871
+ const sliced = await readDiskFile(v.realPath, { range: { start: range.start, end: clampedEnd } });
3872
+ const { bytes } = sliced;
3873
+ const lastByte = range.start + bytes.length - 1;
3874
+ return new Response(bufferToBody(bytes), {
3875
+ status: 206,
3876
+ headers: {
3877
+ "Content-Type": mime,
3878
+ "Content-Length": String(bytes.length),
3879
+ "Content-Range": `bytes ${range.start}-${lastByte}/${totalSize}`,
3880
+ "Cache-Control": CACHE_CONTROL,
3881
+ ETag: etag,
3882
+ "Access-Control-Allow-Origin": "*"
3883
+ }
3884
+ });
3885
+ }
3886
+ return new Response(bufferToBody(probe.bytes), {
3887
+ status: 200,
3888
+ headers: {
3889
+ "Content-Type": mime,
3890
+ "Cache-Control": CACHE_CONTROL,
3891
+ ETag: etag,
3892
+ "Access-Control-Allow-Origin": "*"
3893
+ }
3894
+ });
3895
+ } catch {
3896
+ return notFound();
3897
+ }
3898
+ }
3899
+
3900
+ // src/main/services/simulator-temp-files/fs-channels.ts
3901
+ import fs8 from "node:fs/promises";
3902
+ import path13 from "node:path";
3903
+ async function enforceSandbox(realPath) {
3904
+ if (typeof realPath !== "string" || realPath.length === 0) {
3905
+ throw new Error("sandbox: realPath must be a non-empty string");
3906
+ }
3907
+ const base = sandboxBase();
3908
+ const baseReal = await fs8.realpath(base).catch(() => base);
3909
+ const normalized = path13.normalize(realPath);
3910
+ if (normalized !== base && !normalized.startsWith(base + path13.sep)) {
3911
+ throw new Error("sandbox: realPath escapes the user-data base");
3912
+ }
3913
+ let probe = normalized;
3914
+ while (probe !== path13.parse(probe).root) {
3915
+ try {
3916
+ const resolved = await fs8.realpath(probe);
3917
+ if (resolved !== baseReal && !resolved.startsWith(baseReal + path13.sep)) {
3918
+ throw new Error("sandbox: realPath escapes the user-data base via symlink");
3919
+ }
3920
+ break;
3921
+ } catch (err) {
3922
+ if (err.code === "ENOENT") {
3923
+ probe = path13.dirname(probe);
3924
+ continue;
3925
+ }
3926
+ throw err;
3927
+ }
3928
+ }
3929
+ return normalized;
3930
+ }
3931
+ async function handleFsRead(req) {
3932
+ const safe = await enforceSandbox(req.realPath);
3933
+ const result = await readDiskFile(safe, req.range ? { range: req.range } : void 0);
3934
+ return {
3935
+ bytes: result.bytes,
3936
+ mime: result.mime,
3937
+ etag: result.etag,
3938
+ totalSize: result.totalSize
3939
+ };
3940
+ }
3941
+ async function handleFsWrite(req) {
3942
+ const safe = await enforceSandbox(req.realPath);
3943
+ await writeDiskFile(safe, req.bytes);
3944
+ return { ok: true };
3945
+ }
3946
+ async function handleFsStat(req) {
3947
+ const safe = await enforceSandbox(req.realPath);
3948
+ return statDiskFile(safe);
3949
+ }
3950
+ async function handleFsReaddir(req) {
3951
+ const safe = await enforceSandbox(req.realPath);
3952
+ return readDiskDir(safe);
3953
+ }
3954
+ async function handleFsUnlink(req) {
3955
+ const safe = await enforceSandbox(req.realPath);
3956
+ await fs8.unlink(safe);
3957
+ return { ok: true };
3958
+ }
3959
+ async function handleFsMkdir(req) {
3960
+ const safe = await enforceSandbox(req.realPath);
3961
+ await fs8.mkdir(safe, { recursive: !!req.recursive });
3962
+ return { ok: true };
3963
+ }
3964
+
3965
+ // src/main/services/simulator-temp-files/index.ts
3966
+ var MAX_STORE_ENTRIES = 200;
3967
+ var PENDING_TIMEOUT_MS = 500;
3968
+ function enforceStoreCap(store) {
3969
+ while (store.size > MAX_STORE_ENTRIES) {
3970
+ const next = store.keys().next();
3971
+ if (next.done) break;
3972
+ store.delete(next.value);
3973
+ }
3974
+ }
3975
+ function setupSimulatorTempFiles(simSession) {
3976
+ const store = /* @__PURE__ */ new Map();
3977
+ const pendingWaiters = /* @__PURE__ */ new Map();
3978
+ let disposed = false;
3979
+ function drainWaiters(path16) {
3980
+ const list = pendingWaiters.get(path16);
3981
+ if (!list) return;
3982
+ pendingWaiters.delete(path16);
3983
+ for (const fn of list) fn();
3984
+ }
3985
+ function drainAllWaiters() {
3986
+ const lists = Array.from(pendingWaiters.values());
3987
+ pendingWaiters.clear();
3988
+ for (const list of lists) for (const fn of list) fn();
3989
+ }
3990
+ const simulatorOnlyPolicy = (sender) => !sender.isDestroyed() && sender.session === simSession;
3991
+ const registry = new IpcRegistry(simulatorOnlyPolicy);
3992
+ registry.on("simulator:temp-file:write", (_event, payload) => {
3993
+ if (disposed) return;
3994
+ const { path: path16, mime, bytes } = payload;
3995
+ registerTempFile(store, path16, mime, bytes);
3996
+ enforceStoreCap(store);
3997
+ drainWaiters(path16);
3998
+ });
3999
+ registry.on("simulator:temp-file:revoke", (_event, payload) => {
4000
+ if (disposed) return;
4001
+ const { path: path16 } = payload;
4002
+ revokeTempFile(store, path16);
4003
+ });
4004
+ registry.on("simulator:temp-file:revoke-all", () => {
4005
+ if (disposed) return;
4006
+ revokeAllTempFiles(store);
4007
+ });
4008
+ try {
4009
+ simSession.protocol.unhandle("difile");
4010
+ } catch {
4011
+ }
4012
+ simSession.protocol.handle("difile", async (req) => {
4013
+ const url = req.url;
4014
+ const headers = {};
4015
+ try {
4016
+ req.headers.forEach((v, k) => {
4017
+ headers[k] = v;
4018
+ });
4019
+ } catch {
4020
+ }
4021
+ const ctx = { tempStore: store };
4022
+ let res = await handleDifileRequest(ctx, { url, headers });
4023
+ if (res.status === 404 && !disposed && url.startsWith("difile://_tmp/")) {
4024
+ await new Promise((resolve) => {
4025
+ let timer = null;
4026
+ const notify = () => {
4027
+ if (timer) clearTimeout(timer);
4028
+ resolve();
4029
+ };
4030
+ const list = pendingWaiters.get(url) ?? /* @__PURE__ */ new Set();
4031
+ list.add(notify);
4032
+ pendingWaiters.set(url, list);
4033
+ timer = setTimeout(() => {
4034
+ const cur = pendingWaiters.get(url);
4035
+ if (cur) {
4036
+ cur.delete(notify);
4037
+ if (cur.size === 0) pendingWaiters.delete(url);
4038
+ }
4039
+ resolve();
4040
+ }, PENDING_TIMEOUT_MS);
4041
+ });
4042
+ res = await handleDifileRequest(ctx, { url, headers });
4043
+ }
4044
+ return res;
4045
+ });
4046
+ registry.handle(
4047
+ "simulator:fs:read",
4048
+ (_event, payload) => handleFsRead(payload)
4049
+ );
4050
+ registry.handle(
4051
+ "simulator:fs:write",
4052
+ (_event, payload) => handleFsWrite(payload)
4053
+ );
4054
+ registry.handle(
4055
+ "simulator:fs:stat",
4056
+ (_event, payload) => handleFsStat(payload)
4057
+ );
4058
+ registry.handle(
4059
+ "simulator:fs:readdir",
4060
+ (_event, payload) => handleFsReaddir(payload)
4061
+ );
4062
+ registry.handle(
4063
+ "simulator:fs:unlink",
4064
+ (_event, payload) => handleFsUnlink(payload)
4065
+ );
4066
+ registry.handle(
4067
+ "simulator:fs:mkdir",
4068
+ (_event, payload) => handleFsMkdir(payload)
4069
+ );
4070
+ return toDisposable(async () => {
4071
+ disposed = true;
4072
+ drainAllWaiters();
4073
+ store.clear();
4074
+ try {
4075
+ simSession.protocol.unhandle("difile");
4076
+ } catch {
4077
+ }
4078
+ await registry.dispose();
4079
+ });
4080
+ }
4081
+
3535
4082
  // src/main/services/update/update-manager.ts
3536
4083
  import { app as app11, shell as shell3 } from "electron";
3537
4084
  var UpdateManager = class {
@@ -3690,7 +4237,7 @@ async function disposeContext(ctx) {
3690
4237
  function createConfiguredMainWindow(config, rendererDir2) {
3691
4238
  const mainWindow = createMainWindow({
3692
4239
  title: config.appName ?? "Dimina DevTools",
3693
- indexHtml: path12.join(rendererDir2, "entries/main/index.html"),
4240
+ indexHtml: path14.join(rendererDir2, "entries/main/index.html"),
3694
4241
  width: config.window?.width,
3695
4242
  height: config.window?.height,
3696
4243
  minWidth: config.window?.minWidth,
@@ -3788,7 +4335,7 @@ function enableDevRendererAutoReload(rendererDir2) {
3788
4335
  });
3789
4336
  }
3790
4337
  let reloadTimer = null;
3791
- const watcher = fs7.watch(rendererDir2, { recursive: true }, () => {
4338
+ const watcher = fs9.watch(rendererDir2, { recursive: true }, () => {
3792
4339
  if (reloadTimer) clearTimeout(reloadTimer);
3793
4340
  reloadTimer = setTimeout(() => {
3794
4341
  for (const win of BrowserWindow4.getAllWindows()) {
@@ -3808,6 +4355,7 @@ function createWorkbenchApp(config = {}) {
3808
4355
  let setupPromise = null;
3809
4356
  let appEventsRegistered = false;
3810
4357
  setupCdpPort();
4358
+ registerDifileScheme();
3811
4359
  async function setup() {
3812
4360
  if (setupPromise) return setupPromise;
3813
4361
  setupPromise = app13.whenReady().then(async () => {
@@ -3818,6 +4366,8 @@ function createWorkbenchApp(config = {}) {
3818
4366
  context.registry.add(registerAppIpc(context));
3819
4367
  context.registry.add(installThemeBackgroundSync());
3820
4368
  registerBuiltinModules(config, context);
4369
+ const simSession = session2.fromPartition("persist:simulator");
4370
+ context.registry.add(setupSimulatorTempFiles(simSession));
3821
4371
  installMenu(config, mainWindow, context);
3822
4372
  const hostIpc = new IpcRegistry(context.senderPolicy);
3823
4373
  context.registry.add(hostIpc);
@@ -3864,8 +4414,8 @@ function createWorkbenchApp(config = {}) {
3864
4414
  // prefixes; this callback lets the storage panel filter the CDP
3865
4415
  // snapshot/event stream to the active appId.
3866
4416
  getActiveAppId: () => {
3867
- const session2 = context.workspace.getSession();
3868
- const appInfo = session2?.appInfo;
4417
+ const session3 = context.workspace.getSession();
4418
+ const appInfo = session3?.appInfo;
3869
4419
  return appInfo?.appId ?? null;
3870
4420
  }
3871
4421
  }));
@@ -3890,7 +4440,7 @@ function createWorkbenchApp(config = {}) {
3890
4440
 
3891
4441
  // src/main/windows/settings-window/create.ts
3892
4442
  import { BrowserWindow as BrowserWindow5 } from "electron";
3893
- import path13 from "path";
4443
+ import path15 from "path";
3894
4444
  async function createSettingsWindow(parent, rendererDir2) {
3895
4445
  const win = new BrowserWindow5({
3896
4446
  width: 420,
@@ -3908,7 +4458,7 @@ async function createSettingsWindow(parent, rendererDir2) {
3908
4458
  }
3909
4459
  });
3910
4460
  applyNavigationHardening(win.webContents, rendererDir2);
3911
- await win.loadFile(path13.join(rendererDir2, "entries/workbench-settings/index.html"));
4461
+ await win.loadFile(path15.join(rendererDir2, "entries/workbench-settings/index.html"));
3912
4462
  return win;
3913
4463
  }
3914
4464