@dimina-kit/devtools 0.4.0-dev.20260706064107 → 0.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.
Files changed (40) hide show
  1. package/dist/main/app/app.d.ts +4 -1
  2. package/dist/main/app/app.js +20 -0
  3. package/dist/main/index.bundle.js +136 -5
  4. package/dist/main/ipc/popover.js +10 -1
  5. package/dist/main/ipc/session.js +17 -1
  6. package/dist/main/services/notifications/renderer-notifier.d.ts +5 -1
  7. package/dist/main/services/notifications/renderer-notifier.js +6 -0
  8. package/dist/main/services/projects/local-provider.js +4 -0
  9. package/dist/main/services/projects/project-repository.d.ts +7 -1
  10. package/dist/main/services/projects/project-repository.js +24 -0
  11. package/dist/main/services/projects/types.d.ts +25 -1
  12. package/dist/main/services/render-inspect/index.js +4 -4
  13. package/dist/main/services/workspace/workspace-service.d.ts +5 -1
  14. package/dist/main/services/workspace/workspace-service.js +8 -0
  15. package/dist/native-host/render/render.js +42 -52
  16. package/dist/native-host/service/service.js +2 -2
  17. package/dist/preload/windows/host-toolbar-runtime.cjs.map +2 -2
  18. package/dist/preload/windows/simulator.cjs.map +1 -1
  19. package/dist/renderer/assets/index-BMqyDx71.js +49 -0
  20. package/dist/renderer/assets/{input-CTb_le7F.js → input-CDAEwpBO.js} +2 -2
  21. package/dist/renderer/assets/ipc-transport-B7eFOR68.css +1 -0
  22. package/dist/renderer/assets/{ipc-transport-Ck5Xa8Tu.js → ipc-transport-_G1k5V1p.js} +2 -2
  23. package/dist/renderer/assets/popover-DEdjK14m.js +2 -0
  24. package/dist/renderer/assets/{select-ozSk5Pt6.js → select-DpKPCh3y.js} +2 -2
  25. package/dist/renderer/assets/{settings-CNwGOI22.js → settings-M5q2elUr.js} +2 -2
  26. package/dist/renderer/assets/{settings-api-DMbMp1Eq.js → settings-api-CDlZoHiO.js} +2 -2
  27. package/dist/renderer/assets/{workbenchSettings-Cr4EHo5w.js → workbenchSettings-CT_H1WhV.js} +2 -2
  28. package/dist/renderer/entries/main/index.html +6 -6
  29. package/dist/renderer/entries/popover/index.html +5 -5
  30. package/dist/renderer/entries/settings/index.html +5 -5
  31. package/dist/renderer/entries/workbench-settings/index.html +4 -4
  32. package/dist/shared/ipc-channels.d.ts +6 -0
  33. package/dist/shared/ipc-channels.js +6 -0
  34. package/dist/shared/ipc-schemas.d.ts +29 -0
  35. package/dist/shared/ipc-schemas.js +34 -0
  36. package/dist/shared/types.d.ts +28 -0
  37. package/package.json +6 -6
  38. package/dist/renderer/assets/index-BwzPwCmM.js +0 -49
  39. package/dist/renderer/assets/ipc-transport-BPWIV5hA.css +0 -1
  40. package/dist/renderer/assets/popover-B1Zu2UQu.js +0 -2
@@ -1,5 +1,5 @@
1
1
  import { BrowserWindow } from 'electron';
2
- import type { WorkbenchAppConfig } from '../../shared/types.js';
2
+ import type { LaunchConfig, WorkbenchAppConfig } from '../../shared/types.js';
3
3
  import type { SimulatorApiHandler } from '../services/simulator/custom-apis.js';
4
4
  import { type WorkbenchContext } from '../services/workbench-context.js';
5
5
  import { type AutomationServer } from '../services/automation/index.js';
@@ -18,6 +18,9 @@ export interface WorkbenchAppInstance {
18
18
  automationServer?: AutomationServer;
19
19
  updateManager?: UpdateManager;
20
20
  dispose: () => Promise<void>;
21
+ getLaunchConfigs: () => Promise<LaunchConfig[]>;
22
+ setLaunchConfigs: (configs: LaunchConfig[]) => Promise<void>;
23
+ setActiveLaunchConfig: (id: string | null) => Promise<void>;
21
24
  }
22
25
  /**
23
26
  * Pre-ready bootstrap side effects (app name, CDP port, CSP suppression,
@@ -400,6 +400,26 @@ export async function createDevtoolsRuntime(config = {}) {
400
400
  registerTrustedWindow: (win) => context.registry.add(registerTrustedWindow(context, win)),
401
401
  registerSimulatorApi: (name, handler) => context.registry.add(toDisposable(context.simulatorApis.register(name, handler))),
402
402
  dispose: () => disposeContext(context),
403
+ async getLaunchConfigs() {
404
+ const projectPath = context.workspace.getProjectPath();
405
+ if (!projectPath)
406
+ return [];
407
+ return context.workspace.getLaunchConfigs(projectPath);
408
+ },
409
+ async setLaunchConfigs(configs) {
410
+ const projectPath = context.workspace.getProjectPath();
411
+ if (!projectPath)
412
+ return;
413
+ await context.workspace.saveLaunchConfigs(projectPath, configs);
414
+ context.notify.popoverUpdateLaunchConfigs(configs);
415
+ },
416
+ async setActiveLaunchConfig(id) {
417
+ const projectPath = context.workspace.getProjectPath();
418
+ if (!projectPath)
419
+ return;
420
+ await context.workspace.saveActiveLaunchConfigId(projectPath, id);
421
+ context.notify.popoverSwitchLaunchConfig(id);
422
+ },
403
423
  };
404
424
  // Built-in simulator APIs: devtools-supplied wx.* implementations that run
405
425
  // in the main process. Hosts can override any of these in their onSetup by
@@ -391,7 +391,11 @@ var ProjectChannel = {
391
391
  // contract (compileEvents), this one carries the line stream (compileLogs).
392
392
  CompileLog: "project:compileLog",
393
393
  CaptureThumbnail: "project:captureThumbnail",
394
- GetThumbnail: "project:getThumbnail"
394
+ GetThumbnail: "project:getThumbnail",
395
+ GetLaunchConfigs: "project:getLaunchConfigs",
396
+ SaveLaunchConfigs: "project:saveLaunchConfigs",
397
+ GetActiveLaunchConfigId: "project:getActiveLaunchConfigId",
398
+ SaveActiveLaunchConfigId: "project:saveActiveLaunchConfigId"
395
399
  };
396
400
  var SessionChannel = {
397
401
  RuntimeStatus: "session:runtimeStatus"
@@ -476,7 +480,9 @@ var PopoverChannel = {
476
480
  Hide: "popover:hide",
477
481
  Relaunch: "popover:relaunch",
478
482
  Closed: "popover:closed",
479
- Init: "popover:init"
483
+ Init: "popover:init",
484
+ SwitchLaunchConfig: "popover:switchLaunchConfig",
485
+ UpdateLaunchConfigs: "popover:updateLaunchConfigs"
480
486
  };
481
487
  var WindowChannel = {
482
488
  NavigateBack: "window:navigateBack"
@@ -1123,6 +1129,12 @@ function createRendererNotifier(ctx) {
1123
1129
  popoverRelaunch(config) {
1124
1130
  sendToMain(PopoverChannel.Relaunch, config);
1125
1131
  },
1132
+ popoverSwitchLaunchConfig(id) {
1133
+ sendToMain(PopoverChannel.SwitchLaunchConfig, id);
1134
+ },
1135
+ popoverUpdateLaunchConfigs(configs) {
1136
+ sendToMain(PopoverChannel.UpdateLaunchConfigs, configs);
1137
+ },
1126
1138
  hostToolbarHeightChanged(height) {
1127
1139
  sendToMain(ViewChannel.HostToolbarHeightChanged, height);
1128
1140
  },
@@ -3960,6 +3972,30 @@ function getProjectSettings(projectPath) {
3960
3972
  return { uploadWithSourceMap: false };
3961
3973
  }
3962
3974
  }
3975
+ function getLaunchConfigs(dirPath) {
3976
+ const project = load().find((p) => p.path === dirPath);
3977
+ return project?.launchConfigs ?? [];
3978
+ }
3979
+ function saveLaunchConfigs(dirPath, configs) {
3980
+ const projects = load();
3981
+ const idx = projects.findIndex((p) => p.path === dirPath);
3982
+ if (idx >= 0) {
3983
+ projects[idx] = { ...projects[idx], launchConfigs: configs };
3984
+ save(projects);
3985
+ }
3986
+ }
3987
+ function getActiveLaunchConfigId(dirPath) {
3988
+ const project = load().find((p) => p.path === dirPath);
3989
+ return project?.activeLaunchConfigId ?? null;
3990
+ }
3991
+ function saveActiveLaunchConfigId(dirPath, id) {
3992
+ const projects = load();
3993
+ const idx = projects.findIndex((p) => p.path === dirPath);
3994
+ if (idx >= 0) {
3995
+ projects[idx] = { ...projects[idx], activeLaunchConfigId: id };
3996
+ save(projects);
3997
+ }
3998
+ }
3963
3999
  function updateProjectSettings(projectPath, patch) {
3964
4000
  if (!projectPath) return;
3965
4001
  const configPath = path10.join(projectPath, "project.config.json");
@@ -4265,7 +4301,15 @@ function createWorkspaceService(ctx) {
4265
4301
  // Per-project settings (uploadWithSourceMap etc.) live in the project's
4266
4302
  // own `project.config.json`, not the registry — keep direct repo calls.
4267
4303
  getProjectSettings: (projectPath) => getProjectSettings(projectPath),
4268
- updateProjectSettings: (projectPath, patch) => updateProjectSettings(projectPath, patch)
4304
+ updateProjectSettings: (projectPath, patch) => updateProjectSettings(projectPath, patch),
4305
+ getLaunchConfigs: async (p) => provider.getLaunchConfigs ? await provider.getLaunchConfigs(p) : [],
4306
+ saveLaunchConfigs: async (p, c) => {
4307
+ if (provider.saveLaunchConfigs) await provider.saveLaunchConfigs(p, c);
4308
+ },
4309
+ getActiveLaunchConfigId: async (p) => provider.getActiveLaunchConfigId ? await provider.getActiveLaunchConfigId(p) : null,
4310
+ saveActiveLaunchConfigId: async (p, id) => {
4311
+ if (provider.saveActiveLaunchConfigId) await provider.saveActiveLaunchConfigId(p, id);
4312
+ }
4269
4313
  };
4270
4314
  }
4271
4315
 
@@ -4311,7 +4355,11 @@ function createLocalProjectsProvider() {
4311
4355
  getCompileConfig: (dirPath) => getCompileConfig(dirPath),
4312
4356
  saveCompileConfig: (dirPath, cfg) => saveCompileConfig(dirPath, cfg),
4313
4357
  saveThumbnail: (dirPath, dataUrl) => saveThumbnailFromDataUrl(dirPath, dataUrl),
4314
- getThumbnail: (dirPath) => loadThumbnail(dirPath)
4358
+ getThumbnail: (dirPath) => loadThumbnail(dirPath),
4359
+ getLaunchConfigs: (dirPath) => getLaunchConfigs(dirPath),
4360
+ saveLaunchConfigs: (dirPath, configs) => saveLaunchConfigs(dirPath, configs),
4361
+ getActiveLaunchConfigId: (dirPath) => getActiveLaunchConfigId(dirPath),
4362
+ saveActiveLaunchConfigId: (dirPath, id) => saveActiveLaunchConfigId(dirPath, id)
4315
4363
  };
4316
4364
  }
4317
4365
 
@@ -4645,6 +4693,29 @@ var SettingsProjectSettingsChangedSchema = z3.tuple([
4645
4693
  ]);
4646
4694
  var ProjectCaptureThumbnailSchema = z3.tuple([AbsolutePath]);
4647
4695
  var ProjectGetThumbnailSchema = z3.tuple([AbsolutePath]);
4696
+ var ProjectGetLaunchConfigsSchema = z3.tuple([AbsolutePath]);
4697
+ var LaunchConfigShape = z3.looseObject({
4698
+ id: z3.string().min(1),
4699
+ name: z3.string(),
4700
+ startPage: z3.string().optional(),
4701
+ scene: z3.number().optional(),
4702
+ queryParams: z3.array(z3.looseObject({ key: z3.string(), value: z3.string() })).optional()
4703
+ });
4704
+ var ProjectSaveLaunchConfigsSchema = z3.tuple([
4705
+ AbsolutePath,
4706
+ z3.array(LaunchConfigShape)
4707
+ ]);
4708
+ var ProjectGetActiveLaunchConfigIdSchema = z3.tuple([AbsolutePath]);
4709
+ var ProjectSaveActiveLaunchConfigIdSchema = z3.tuple([
4710
+ AbsolutePath,
4711
+ z3.union([z3.string(), z3.null()])
4712
+ ]);
4713
+ var PopoverSwitchLaunchConfigSchema = z3.tuple([
4714
+ z3.union([z3.string(), z3.null()])
4715
+ ]);
4716
+ var PopoverUpdateLaunchConfigsSchema = z3.tuple([
4717
+ z3.array(LaunchConfigShape)
4718
+ ]);
4648
4719
 
4649
4720
  // src/main/ipc/simulator.ts
4650
4721
  function registerSimulatorIpc(ctx) {
@@ -4681,6 +4752,21 @@ function registerPopoverIpc(ctx) {
4681
4752
  const [newConfig] = validate(PopoverChannel.Relaunch, PopoverRelaunchSchema, args);
4682
4753
  ctx.views.hidePopover();
4683
4754
  ctx.notify.popoverRelaunch(newConfig);
4755
+ }).on(PopoverChannel.SwitchLaunchConfig, (_event, ...args) => {
4756
+ const [id] = validate(
4757
+ PopoverChannel.SwitchLaunchConfig,
4758
+ PopoverSwitchLaunchConfigSchema,
4759
+ args
4760
+ );
4761
+ ctx.views.hidePopover();
4762
+ ctx.notify.popoverSwitchLaunchConfig(id);
4763
+ }).on(PopoverChannel.UpdateLaunchConfigs, (_event, ...args) => {
4764
+ const [configs] = validate(
4765
+ PopoverChannel.UpdateLaunchConfigs,
4766
+ PopoverUpdateLaunchConfigsSchema,
4767
+ args
4768
+ );
4769
+ ctx.notify.popoverUpdateLaunchConfigs(configs);
4684
4770
  });
4685
4771
  }
4686
4772
  var popoverModule = {
@@ -4906,6 +4992,34 @@ function registerSessionIpc(ctx) {
4906
4992
  args
4907
4993
  );
4908
4994
  return ctx.workspace.getThumbnail(projectPath);
4995
+ }).handle(ProjectChannel.GetLaunchConfigs, (_, ...args) => {
4996
+ const [projectPath] = validate(
4997
+ ProjectChannel.GetLaunchConfigs,
4998
+ ProjectGetLaunchConfigsSchema,
4999
+ args
5000
+ );
5001
+ return ctx.workspace.getLaunchConfigs(projectPath);
5002
+ }).handle(ProjectChannel.SaveLaunchConfigs, (_, ...args) => {
5003
+ const [projectPath, configs] = validate(
5004
+ ProjectChannel.SaveLaunchConfigs,
5005
+ ProjectSaveLaunchConfigsSchema,
5006
+ args
5007
+ );
5008
+ return ctx.workspace.saveLaunchConfigs(projectPath, configs);
5009
+ }).handle(ProjectChannel.GetActiveLaunchConfigId, (_, ...args) => {
5010
+ const [projectPath] = validate(
5011
+ ProjectChannel.GetActiveLaunchConfigId,
5012
+ ProjectGetActiveLaunchConfigIdSchema,
5013
+ args
5014
+ );
5015
+ return ctx.workspace.getActiveLaunchConfigId(projectPath);
5016
+ }).handle(ProjectChannel.SaveActiveLaunchConfigId, (_, ...args) => {
5017
+ const [projectPath, id] = validate(
5018
+ ProjectChannel.SaveActiveLaunchConfigId,
5019
+ ProjectSaveActiveLaunchConfigIdSchema,
5020
+ args
5021
+ );
5022
+ return ctx.workspace.saveActiveLaunchConfigId(projectPath, id);
4909
5023
  });
4910
5024
  }
4911
5025
  var sessionModule = {
@@ -11444,7 +11558,24 @@ async function createDevtoolsRuntime(config = {}) {
11444
11558
  // teardown, so a single dispose leaves no dead entry behind.
11445
11559
  registerTrustedWindow: (win) => context.registry.add(registerTrustedWindow(context, win)),
11446
11560
  registerSimulatorApi: (name, handler) => context.registry.add(toDisposable8(context.simulatorApis.register(name, handler))),
11447
- dispose: () => disposeContext(context)
11561
+ dispose: () => disposeContext(context),
11562
+ async getLaunchConfigs() {
11563
+ const projectPath = context.workspace.getProjectPath();
11564
+ if (!projectPath) return [];
11565
+ return context.workspace.getLaunchConfigs(projectPath);
11566
+ },
11567
+ async setLaunchConfigs(configs) {
11568
+ const projectPath = context.workspace.getProjectPath();
11569
+ if (!projectPath) return;
11570
+ await context.workspace.saveLaunchConfigs(projectPath, configs);
11571
+ context.notify.popoverUpdateLaunchConfigs(configs);
11572
+ },
11573
+ async setActiveLaunchConfig(id) {
11574
+ const projectPath = context.workspace.getProjectPath();
11575
+ if (!projectPath) return;
11576
+ await context.workspace.saveActiveLaunchConfigId(projectPath, id);
11577
+ context.notify.popoverSwitchLaunchConfig(id);
11578
+ }
11448
11579
  };
11449
11580
  instance.registerSimulatorApi("login", async () => {
11450
11581
  return "hello";
@@ -1,5 +1,5 @@
1
1
  import { PopoverChannel } from '../../shared/ipc-channels.js';
2
- import { PopoverShowSchema, PopoverRelaunchSchema, } from '../../shared/ipc-schemas.js';
2
+ import { PopoverShowSchema, PopoverRelaunchSchema, PopoverSwitchLaunchConfigSchema, PopoverUpdateLaunchConfigsSchema, } from '../../shared/ipc-schemas.js';
3
3
  import { validate } from '../utils/ipc-schema.js';
4
4
  import { IpcRegistry } from '../utils/ipc-registry.js';
5
5
  export function registerPopoverIpc(ctx) {
@@ -15,6 +15,15 @@ export function registerPopoverIpc(ctx) {
15
15
  const [newConfig] = validate(PopoverChannel.Relaunch, PopoverRelaunchSchema, args);
16
16
  ctx.views.hidePopover();
17
17
  ctx.notify.popoverRelaunch(newConfig);
18
+ })
19
+ .on(PopoverChannel.SwitchLaunchConfig, (_event, ...args) => {
20
+ const [id] = validate(PopoverChannel.SwitchLaunchConfig, PopoverSwitchLaunchConfigSchema, args);
21
+ ctx.views.hidePopover();
22
+ ctx.notify.popoverSwitchLaunchConfig(id);
23
+ })
24
+ .on(PopoverChannel.UpdateLaunchConfigs, (_event, ...args) => {
25
+ const [configs] = validate(PopoverChannel.UpdateLaunchConfigs, PopoverUpdateLaunchConfigsSchema, args);
26
+ ctx.notify.popoverUpdateLaunchConfigs(configs);
18
27
  });
19
28
  }
20
29
  export const popoverModule = {
@@ -1,5 +1,5 @@
1
1
  import { ProjectChannel } from '../../shared/ipc-channels.js';
2
- import { ProjectCaptureThumbnailSchema, ProjectGetCompileConfigSchema, ProjectGetPagesSchema, ProjectGetThumbnailSchema, ProjectOpenSchema, ProjectSaveCompileConfigSchema, } from '../../shared/ipc-schemas.js';
2
+ import { ProjectCaptureThumbnailSchema, ProjectGetCompileConfigSchema, ProjectGetPagesSchema, ProjectGetThumbnailSchema, ProjectOpenSchema, ProjectSaveCompileConfigSchema, ProjectGetLaunchConfigsSchema, ProjectSaveLaunchConfigsSchema, ProjectGetActiveLaunchConfigIdSchema, ProjectSaveActiveLaunchConfigIdSchema, } from '../../shared/ipc-schemas.js';
3
3
  import { validate } from '../utils/ipc-schema.js';
4
4
  import { IpcRegistry } from '../utils/ipc-registry.js';
5
5
  export function registerSessionIpc(ctx) {
@@ -30,6 +30,22 @@ export function registerSessionIpc(ctx) {
30
30
  .handle(ProjectChannel.GetThumbnail, (_, ...args) => {
31
31
  const [projectPath] = validate(ProjectChannel.GetThumbnail, ProjectGetThumbnailSchema, args);
32
32
  return ctx.workspace.getThumbnail(projectPath);
33
+ })
34
+ .handle(ProjectChannel.GetLaunchConfigs, (_, ...args) => {
35
+ const [projectPath] = validate(ProjectChannel.GetLaunchConfigs, ProjectGetLaunchConfigsSchema, args);
36
+ return ctx.workspace.getLaunchConfigs(projectPath);
37
+ })
38
+ .handle(ProjectChannel.SaveLaunchConfigs, (_, ...args) => {
39
+ const [projectPath, configs] = validate(ProjectChannel.SaveLaunchConfigs, ProjectSaveLaunchConfigsSchema, args);
40
+ return ctx.workspace.saveLaunchConfigs(projectPath, configs);
41
+ })
42
+ .handle(ProjectChannel.GetActiveLaunchConfigId, (_, ...args) => {
43
+ const [projectPath] = validate(ProjectChannel.GetActiveLaunchConfigId, ProjectGetActiveLaunchConfigIdSchema, args);
44
+ return ctx.workspace.getActiveLaunchConfigId(projectPath);
45
+ })
46
+ .handle(ProjectChannel.SaveActiveLaunchConfigId, (_, ...args) => {
47
+ const [projectPath, id] = validate(ProjectChannel.SaveActiveLaunchConfigId, ProjectSaveActiveLaunchConfigIdSchema, args);
48
+ return ctx.workspace.saveActiveLaunchConfigId(projectPath, id);
33
49
  });
34
50
  }
35
51
  export const sessionModule = {
@@ -1,5 +1,5 @@
1
1
  import type { BrowserWindow, WebContents, WebContentsView } from 'electron';
2
- import type { CompileConfig } from '../../../shared/types.js';
2
+ import type { CompileConfig, LaunchConfig } from '../../../shared/types.js';
3
3
  import { type EditorOpenFilePayload } from '../../../shared/ipc-channels.js';
4
4
  import type { WorkbenchSettings } from '../settings/index.js';
5
5
  import type { ProjectSettings } from '../projects/project-repository.js';
@@ -98,6 +98,10 @@ export interface RendererNotifier {
98
98
  popoverClosed(): void;
99
99
  /** Ask the main renderer to relaunch the simulator with a new config. */
100
100
  popoverRelaunch(config: CompileConfig): void;
101
+ /** Ask the main renderer to switch to a launch config (or null for normal). */
102
+ popoverSwitchLaunchConfig(id: string | null): void;
103
+ /** Ask the main renderer to update its launch configs list. */
104
+ popoverUpdateLaunchConfigs(configs: LaunchConfig[]): void;
101
105
  /**
102
106
  * Push the reserved host-toolbar height to the main renderer so its toolbar
103
107
  * placeholder div resizes (closes the host-toolbar dynamic-height loop).
@@ -39,6 +39,12 @@ export function createRendererNotifier(ctx) {
39
39
  popoverRelaunch(config) {
40
40
  sendToMain(PopoverChannel.Relaunch, config);
41
41
  },
42
+ popoverSwitchLaunchConfig(id) {
43
+ sendToMain(PopoverChannel.SwitchLaunchConfig, id);
44
+ },
45
+ popoverUpdateLaunchConfigs(configs) {
46
+ sendToMain(PopoverChannel.UpdateLaunchConfigs, configs);
47
+ },
42
48
  hostToolbarHeightChanged(height) {
43
49
  sendToMain(ViewChannel.HostToolbarHeightChanged, height);
44
50
  },
@@ -20,6 +20,10 @@ export function createLocalProjectsProvider() {
20
20
  saveCompileConfig: (dirPath, cfg) => repo.saveCompileConfig(dirPath, cfg),
21
21
  saveThumbnail: (dirPath, dataUrl) => saveThumbnailFromDataUrl(dirPath, dataUrl),
22
22
  getThumbnail: (dirPath) => loadThumbnail(dirPath),
23
+ getLaunchConfigs: (dirPath) => repo.getLaunchConfigs(dirPath),
24
+ saveLaunchConfigs: (dirPath, configs) => repo.saveLaunchConfigs(dirPath, configs),
25
+ getActiveLaunchConfigId: (dirPath) => repo.getActiveLaunchConfigId(dirPath),
26
+ saveActiveLaunchConfigId: (dirPath, id) => repo.saveActiveLaunchConfigId(dirPath, id),
23
27
  };
24
28
  }
25
29
  //# sourceMappingURL=local-provider.js.map
@@ -1,9 +1,11 @@
1
- import type { CompileConfig } from '../../../shared/types.js';
1
+ import type { CompileConfig, LaunchConfig } from '../../../shared/types.js';
2
2
  export interface Project {
3
3
  name: string;
4
4
  path: string;
5
5
  lastOpened?: string | null;
6
6
  compileConfig?: CompileConfig;
7
+ launchConfigs?: LaunchConfig[];
8
+ activeLaunchConfigId?: string | null;
7
9
  }
8
10
  export interface ProjectPages {
9
11
  pages: string[];
@@ -23,6 +25,10 @@ export declare function getProjectPages(dirPath: string): ProjectPages;
23
25
  export declare function saveCompileConfig(dirPath: string, config: CompileConfig): void;
24
26
  /** Read a subset of `project.config.json` exposed to the settings panel. */
25
27
  export declare function getProjectSettings(projectPath: string): ProjectSettings;
28
+ export declare function getLaunchConfigs(dirPath: string): LaunchConfig[];
29
+ export declare function saveLaunchConfigs(dirPath: string, configs: LaunchConfig[]): void;
30
+ export declare function getActiveLaunchConfigId(dirPath: string): string | null;
31
+ export declare function saveActiveLaunchConfigId(dirPath: string, id: string | null): void;
26
32
  /** Persist a partial patch into the `setting` block of `project.config.json`. */
27
33
  export declare function updateProjectSettings(projectPath: string, patch: Partial<ProjectSettings>): void;
28
34
  //# sourceMappingURL=project-repository.d.ts.map
@@ -132,6 +132,30 @@ export function getProjectSettings(projectPath) {
132
132
  return { uploadWithSourceMap: false };
133
133
  }
134
134
  }
135
+ export function getLaunchConfigs(dirPath) {
136
+ const project = load().find((p) => p.path === dirPath);
137
+ return project?.launchConfigs ?? [];
138
+ }
139
+ export function saveLaunchConfigs(dirPath, configs) {
140
+ const projects = load();
141
+ const idx = projects.findIndex((p) => p.path === dirPath);
142
+ if (idx >= 0) {
143
+ projects[idx] = { ...projects[idx], launchConfigs: configs };
144
+ save(projects);
145
+ }
146
+ }
147
+ export function getActiveLaunchConfigId(dirPath) {
148
+ const project = load().find((p) => p.path === dirPath);
149
+ return project?.activeLaunchConfigId ?? null;
150
+ }
151
+ export function saveActiveLaunchConfigId(dirPath, id) {
152
+ const projects = load();
153
+ const idx = projects.findIndex((p) => p.path === dirPath);
154
+ if (idx >= 0) {
155
+ projects[idx] = { ...projects[idx], activeLaunchConfigId: id };
156
+ save(projects);
157
+ }
158
+ }
135
159
  /** Persist a partial patch into the `setting` block of `project.config.json`. */
136
160
  export function updateProjectSettings(projectPath, patch) {
137
161
  if (!projectPath)
@@ -4,7 +4,7 @@
4
4
  * `WorkbenchAppConfig` to fully take over the project source-of-truth, the
5
5
  * template catalog, and the "新建项目" dialog.
6
6
  */
7
- import type { CompileConfig } from '../../../shared/types.js';
7
+ import type { CompileConfig, LaunchConfig } from '../../../shared/types.js';
8
8
  import type { Project } from './project-repository.js';
9
9
  export type { Project };
10
10
  export type { ProjectTemplate, CreateProjectInput } from '../../../shared/types.js';
@@ -81,6 +81,30 @@ export interface ProjectsProvider {
81
81
  * Default when omitted: returns `null`.
82
82
  */
83
83
  getThumbnail?(dirPath: string): string | null | Promise<string | null>;
84
+ /**
85
+ * Read saved launch configs for a project.
86
+ *
87
+ * Default when omitted: returns `[]`.
88
+ */
89
+ getLaunchConfigs?(dirPath: string): LaunchConfig[] | Promise<LaunchConfig[]>;
90
+ /**
91
+ * Persist the full list of launch configs for a project.
92
+ *
93
+ * Default when omitted: silently no-ops.
94
+ */
95
+ saveLaunchConfigs?(dirPath: string, configs: LaunchConfig[]): void | Promise<void>;
96
+ /**
97
+ * Read the active launch config id for a project.
98
+ *
99
+ * Default when omitted: returns `null` (normal mode).
100
+ */
101
+ getActiveLaunchConfigId?(dirPath: string): string | null | Promise<string | null>;
102
+ /**
103
+ * Persist the active launch config id for a project.
104
+ *
105
+ * Default when omitted: silently no-ops.
106
+ */
107
+ saveActiveLaunchConfigId?(dirPath: string, id: string | null): void | Promise<void>;
84
108
  }
85
109
  /** Built-in template policy. */
86
110
  export type BuiltinTemplatesMode = 'all' | 'none' | readonly string[];
@@ -91,7 +91,7 @@ export function createRenderInspector(options = {}) {
91
91
  if (!(await ensureInjected(wc)))
92
92
  return null;
93
93
  try {
94
- const result = await wc.executeJavaScript('window.__diminaRenderInspect ? window.__diminaRenderInspect.getWxml() : null');
94
+ const result = (await wc.executeJavaScript('window.__diminaRenderInspect ? window.__diminaRenderInspect.getWxml() : null'));
95
95
  return result ?? null;
96
96
  }
97
97
  catch {
@@ -105,7 +105,7 @@ export function createRenderInspector(options = {}) {
105
105
  return null;
106
106
  let inspection;
107
107
  try {
108
- const result = await wc.executeJavaScript(`window.__diminaRenderInspect ? window.__diminaRenderInspect.highlightElement(${JSON.stringify(sid)}) : null`);
108
+ const result = (await wc.executeJavaScript(`window.__diminaRenderInspect ? window.__diminaRenderInspect.highlightElement(${JSON.stringify(sid)}) : null`));
109
109
  inspection = result ?? null;
110
110
  }
111
111
  catch {
@@ -149,11 +149,11 @@ export function createRenderInspector(options = {}) {
149
149
  return;
150
150
  const expression = `window.__diminaRenderInspect && window.__diminaRenderInspect.elementFor(${JSON.stringify(sid)})`;
151
151
  try {
152
- const evaluated = await wc.debugger.sendCommand('Runtime.evaluate', {
152
+ const evaluated = (await wc.debugger.sendCommand('Runtime.evaluate', {
153
153
  expression,
154
154
  returnByValue: false,
155
155
  objectGroup: HOVER_OBJECT_GROUP,
156
- });
156
+ }));
157
157
  const objectId = evaluated?.result?.objectId;
158
158
  if (!objectId)
159
159
  return;
@@ -1,4 +1,4 @@
1
- import type { AppInfo, CompileConfig, ProjectSession } from '../../../shared/types.js';
1
+ import type { AppInfo, CompileConfig, LaunchConfig, ProjectSession } from '../../../shared/types.js';
2
2
  import type { WorkbenchContext } from '../workbench-context.js';
3
3
  import type { Project, ProjectPages, ProjectSettings } from '../projects/project-repository.js';
4
4
  /**
@@ -57,6 +57,10 @@ export interface WorkspaceService {
57
57
  saveCompileConfig(projectPath: string, config: CompileConfig): Promise<void>;
58
58
  getProjectSettings(projectPath: string): ProjectSettings;
59
59
  updateProjectSettings(projectPath: string, patch: Partial<ProjectSettings>): void;
60
+ getLaunchConfigs(projectPath: string): Promise<LaunchConfig[]>;
61
+ saveLaunchConfigs(projectPath: string, configs: LaunchConfig[]): Promise<void>;
62
+ getActiveLaunchConfigId(projectPath: string): Promise<string | null>;
63
+ saveActiveLaunchConfigId(projectPath: string, id: string | null): Promise<void>;
60
64
  }
61
65
  /** Build a workspace service bound to the given workbench context. */
62
66
  export declare function createWorkspaceService(ctx: WorkbenchContext): WorkspaceService;
@@ -383,6 +383,14 @@ export function createWorkspaceService(ctx) {
383
383
  // own `project.config.json`, not the registry — keep direct repo calls.
384
384
  getProjectSettings: (projectPath) => repo.getProjectSettings(projectPath),
385
385
  updateProjectSettings: (projectPath, patch) => repo.updateProjectSettings(projectPath, patch),
386
+ getLaunchConfigs: async (p) => (provider.getLaunchConfigs ? await provider.getLaunchConfigs(p) : []),
387
+ saveLaunchConfigs: async (p, c) => { if (provider.saveLaunchConfigs)
388
+ await provider.saveLaunchConfigs(p, c); },
389
+ getActiveLaunchConfigId: async (p) => provider.getActiveLaunchConfigId ? await provider.getActiveLaunchConfigId(p) : null,
390
+ saveActiveLaunchConfigId: async (p, id) => {
391
+ if (provider.saveActiveLaunchConfigId)
392
+ await provider.saveActiveLaunchConfigId(p, id);
393
+ },
386
394
  };
387
395
  }
388
396
  //# sourceMappingURL=workspace-service.js.map
@@ -1768,7 +1768,13 @@ var yi = /* @__PURE__ */ new WeakMap(), bi = /* @__PURE__ */ Symbol("_vte"), xi
1768
1768
  r ? (o !== "svg" && wi(r) ? o = "svg" : o !== "mathml" && Ti(r) && (o = "mathml"), i && i.isCE && (i.ce._teleportTargets || (i.ce._teleportTargets = /* @__PURE__ */ new Set())).add(r), n || (b(e, r, a), ji(e, !1))) : process.env.NODE_ENV !== "production" && !n && z("Invalid Teleport target on mount:", r, `(${typeof r})`);
1769
1769
  }, S = (e) => {
1770
1770
  let t = () => {
1771
- yi.get(e) === t && (yi.delete(e), Si(e.props) && (b(e, _(e.el) || n, e.anchor), ji(e, !0)), x(e));
1771
+ if (yi.get(e) === t) {
1772
+ if (yi.delete(e), Si(e.props)) {
1773
+ let t = _(e.el) || n;
1774
+ b(e, t, e.anchor), ji(e, !0);
1775
+ }
1776
+ x(e);
1777
+ }
1772
1778
  };
1773
1779
  yi.set(e, t), Ko(t, a);
1774
1780
  };
@@ -2913,7 +2919,10 @@ function Jo(e, t) {
2913
2919
  }
2914
2920
  }
2915
2921
  }, C = (e, t, n, r, i, a, o, s, c = 0) => {
2916
- for (let l = c; l < e.length; l++) h(null, e[l] = s ? Vs(e[l]) : Bs(e[l]), t, n, r, i, a, o, s);
2922
+ for (let l = c; l < e.length; l++) {
2923
+ let c = e[l] = s ? Vs(e[l]) : Bs(e[l]);
2924
+ h(null, c, t, n, r, i, a, o, s);
2925
+ }
2917
2926
  }, ne = (e, t, n, r, i, o, s) => {
2918
2927
  let c = t.el = e.el;
2919
2928
  process.env.NODE_ENV !== "production" && (c.__vnode = t);
@@ -2936,8 +2945,8 @@ function Jo(e, t) {
2936
2945
  }, r);
2937
2946
  }, re = (e, t, n, r, i, a, o) => {
2938
2947
  for (let s = 0; s < t.length; s++) {
2939
- let c = e[s], l = t[s];
2940
- h(c, l, c.el && (c.type === W || !Os(c, l) || c.shapeFlag & 198) ? d(c.el) : n, null, r, i, a, o, !0);
2948
+ let c = e[s], l = t[s], u = c.el && (c.type === W || !Os(c, l) || c.shapeFlag & 198) ? d(c.el) : n;
2949
+ h(c, l, u, null, r, i, a, o, !0);
2941
2950
  }
2942
2951
  }, w = (e, t, n, r, i) => {
2943
2952
  if (t !== n) {
@@ -6485,7 +6494,10 @@ var Ru = {
6485
6494
  let e = c();
6486
6495
  if (t.value.style = o.indicatorStyle, v.default && v.default()[0].children.length > 0) {
6487
6496
  let e = r.value.querySelector(":first-child");
6488
- e && (m.value = window.getComputedStyle(e).lineHeight || "34px", t.value.style.height = m.value);
6497
+ if (e) {
6498
+ let n = window.getComputedStyle(e);
6499
+ m.value = n.lineHeight || "34px", t.value.style.height = m.value;
6500
+ }
6489
6501
  }
6490
6502
  x = t.value.offsetHeight;
6491
6503
  let s = (e - x) / 2;
@@ -7331,19 +7343,25 @@ var Ru = {
7331
7343
  function be() {
7332
7344
  C &&= (cancelAnimationFrame(C), void 0);
7333
7345
  let e = p.value.getBoundingClientRect();
7334
- t.vertical ? Q("transition", {
7335
- info: n,
7336
- detail: {
7337
- dx: 0,
7338
- dy: te - e.y
7339
- }
7340
- }) : Q("transition", {
7341
- info: n,
7342
- detail: {
7343
- dx: ee - e.x,
7344
- dy: 0
7345
- }
7346
- });
7346
+ if (t.vertical) {
7347
+ let t = te - e.y;
7348
+ Q("transition", {
7349
+ info: n,
7350
+ detail: {
7351
+ dx: 0,
7352
+ dy: t
7353
+ }
7354
+ });
7355
+ } else {
7356
+ let t = ee - e.x;
7357
+ Q("transition", {
7358
+ info: n,
7359
+ detail: {
7360
+ dx: t,
7361
+ dy: 0
7362
+ }
7363
+ });
7364
+ }
7347
7365
  }
7348
7366
  function N() {
7349
7367
  xe(), t.autoplay && i.value > T.value && (ne = setInterval(() => {
@@ -8933,7 +8951,7 @@ var Jp = new class {
8933
8951
  }
8934
8952
  getCanvasImage(e) {
8935
8953
  let t = this.getCanvasResource(e);
8936
- return t || (t = new Image(), t.crossOrigin = "anonymous", this.setCanvasResource(e, t)), t;
8954
+ return t || (t = new Image(), this.setCanvasResource(e, t)), t;
8937
8955
  }
8938
8956
  executeCanvasOperation(e, t, n) {
8939
8957
  switch (t.op) {
@@ -8981,23 +8999,6 @@ var Jp = new class {
8981
8999
  }, e.src = t.src;
8982
9000
  break;
8983
9001
  }
8984
- case "getImageData": {
8985
- let e = this.getCanvasResource(t.contextId);
8986
- if (e) {
8987
- let r = e.getImageData(t.x, t.y, t.width, t.height);
8988
- this.triggerCallback(n, t.callback, {
8989
- data: Array.from(r.data),
8990
- width: r.width,
8991
- height: r.height
8992
- });
8993
- }
8994
- break;
8995
- }
8996
- case "toDataURL": {
8997
- let r = t.mimeType || "image/png", i = t.quality === void 0 ? e.canvas.toDataURL(r) : e.canvas.toDataURL(r, t.quality);
8998
- this.triggerCallback(n, t.callback, i);
8999
- break;
9000
- }
9001
9002
  default: console.warn("[system]", "[render]", `Unsupported canvas node operation: ${t.op}`);
9002
9003
  }
9003
9004
  }
@@ -9228,22 +9229,11 @@ var Jp = new class {
9228
9229
  this.ensureCanvasResolution(d);
9229
9230
  let n = a || d.width, f = o || d.height, p = document.createElement("canvas");
9230
9231
  p.width = s || n, p.height = c || f, p.getContext("2d").drawImage(d, r, i, n, f, 0, 0, p.width, p.height);
9231
- let m = l === "jpg" || l === "jpeg" ? "image/jpeg" : "image/png", h = p.toDataURL(m, u);
9232
- T.invoke({
9233
- type: "invokeAPI",
9234
- target: "container",
9235
- body: {
9236
- name: "saveCanvasTempFile",
9237
- bridgeId: e,
9238
- params: {
9239
- dataURL: h,
9240
- fileType: l,
9241
- success: t.success,
9242
- fail: t.fail,
9243
- complete: t.complete
9244
- }
9245
- }
9246
- });
9232
+ let m = l === "jpg" || l === "jpeg" ? "image/jpeg" : "image/png", h = {
9233
+ errMsg: "canvasToTempFilePath:ok",
9234
+ tempFilePath: p.toDataURL(m, u)
9235
+ };
9236
+ this.triggerCallback(e, t.success, [h], h), this.triggerCallback(e, t.complete, [h], h);
9247
9237
  } catch (n) {
9248
9238
  this.triggerCanvasFailure(e, t, `canvasToTempFilePath:fail ${n.message}`);
9249
9239
  }