@dimina-kit/devkit 0.1.2-dev.20260702182435 → 0.1.2-dev.20260703051110

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 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAE1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AACzD,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAyCzE,MAAM,WAAW,OAAO;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1B;AAED,MAAM,WAAW,kBAAkB;IAClC,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;OAIG;IACH,SAAS,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,oFAAoF;IACpF,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC;;;;OAIG;IACH,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;CACxC;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CAgLnF;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CACnC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAClC;IAAE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CA+CtD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAgB,eAAe,EAAiB,MAAM,qBAAqB,CAAA;AAEvF,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AACzD,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAyCzE,MAAM,WAAW,OAAO;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC1B;AAED,MAAM,WAAW,kBAAkB;IAClC,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;OAIG;IACH,SAAS,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;IAC5E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,oFAAoF;IACpF,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC;;;;OAIG;IACH,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAA;CACxC;AAuFD,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CAqInF;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CACnC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAClC;IAAE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CA+CtD"}
package/dist/index.js CHANGED
@@ -38,6 +38,81 @@ function getRandomPort() {
38
38
  srv.on('error', reject);
39
39
  });
40
40
  }
41
+ /**
42
+ * Best-effort fallback when the compiler returns no AppInfo (e.g. a build
43
+ * racing against a just-closed project in the same Electron process): reads
44
+ * the canonical appid from project.config.json so storage prefixing (which
45
+ * keys off appInfo.appId) still lines up with the runtime instead of
46
+ * silently falling to 'unknown'.
47
+ */
48
+ function resolveAppInfoFallback(projectPath) {
49
+ try {
50
+ const configRaw = fs.readFileSync(path.join(projectPath, 'project.config.json'), 'utf8');
51
+ const config = JSON.parse(configRaw);
52
+ if (!config.appid || typeof config.appid !== 'string' || config.appid.length === 0)
53
+ return null;
54
+ return {
55
+ appId: config.appid,
56
+ name: config.projectname ?? path.basename(projectPath),
57
+ path: projectPath,
58
+ };
59
+ }
60
+ catch {
61
+ // best-effort — fall through to the 'unknown' fallback in the caller
62
+ return null;
63
+ }
64
+ }
65
+ /** Insert or replace `rebuilt` in the session's app list, keyed by appId. */
66
+ function upsertSessionApp(sessionApps, rebuilt) {
67
+ const idx = sessionApps.findIndex(a => a.appId === rebuilt.appId);
68
+ if (idx === -1)
69
+ sessionApps.push(rebuilt);
70
+ else
71
+ sessionApps[idx] = rebuilt;
72
+ }
73
+ /**
74
+ * Run one watcher-triggered rebuild. `getReload` is read at call time (not
75
+ * captured eagerly) because `reload` is only assigned once the dev server has
76
+ * started, after this runner is wired into the rebuild scheduler.
77
+ */
78
+ async function runRebuild(compileWorker, buildRequest, sessionApps, getReload, onRebuild, onBuildError) {
79
+ try {
80
+ const rebuilt = (await compileWorker.build(buildRequest));
81
+ if (rebuilt)
82
+ upsertSessionApp(sessionApps, rebuilt);
83
+ getReload()?.();
84
+ onRebuild?.();
85
+ }
86
+ catch (e) {
87
+ onBuildError?.(e);
88
+ }
89
+ }
90
+ /**
91
+ * Tear down whatever partially started before `openProject` failed: the
92
+ * watcher, the forked compile worker, and the dev server if it was already
93
+ * listening. Every step is best-effort so a secondary failure here never
94
+ * masks the primary error the caller is about to rethrow.
95
+ */
96
+ async function cleanupFailedOpen(watcher, compileWorker, server) {
97
+ try {
98
+ await watcher?.close();
99
+ }
100
+ catch {
101
+ // best-effort — the open is already failing with the primary error
102
+ }
103
+ try {
104
+ await compileWorker.close();
105
+ }
106
+ catch {
107
+ // best-effort — never mask the primary error
108
+ }
109
+ if (server) {
110
+ ;
111
+ server.closeAllConnections?.();
112
+ const listening = server;
113
+ await new Promise(resolve => listening.close(() => resolve()));
114
+ }
115
+ }
41
116
  export async function openProject(opts) {
42
117
  const { projectPath: rawProjectPath, port = 0, sourcemap = false, fileTypes, simulatorDir, containerDir: overrideContainerDir, outputDir, watch = true, onRebuild, onBuildError, onLog, } = opts;
43
118
  const projectPath = path.resolve(rawProjectPath);
@@ -78,20 +153,7 @@ export async function openProject(opts) {
78
153
  // `'unknown'` is only used as a last resort when the manifest itself
79
154
  // is missing/unreadable, preserving the original error path.
80
155
  if (!initialAppInfo) {
81
- try {
82
- const configRaw = fs.readFileSync(path.join(projectPath, 'project.config.json'), 'utf8');
83
- const config = JSON.parse(configRaw);
84
- if (config.appid && typeof config.appid === 'string' && config.appid.length > 0) {
85
- initialAppInfo = {
86
- appId: config.appid,
87
- name: config.projectname ?? path.basename(projectPath),
88
- path: projectPath,
89
- };
90
- }
91
- }
92
- catch {
93
- // best-effort — fall through to the 'unknown' fallback below
94
- }
156
+ initialAppInfo = resolveAppInfoFallback(projectPath);
95
157
  }
96
158
  if (!initialAppInfo) {
97
159
  // Both the compile (null AppInfo) and the project.config.json fallback
@@ -114,23 +176,6 @@ export async function openProject(opts) {
114
176
  let server = null;
115
177
  let reload;
116
178
  let watcher = null;
117
- async function rebuild() {
118
- try {
119
- const rebuilt = (await compileWorker.build(buildRequest));
120
- if (rebuilt) {
121
- const idx = sessionApps.findIndex(a => a.appId === rebuilt.appId);
122
- if (idx === -1)
123
- sessionApps.push(rebuilt);
124
- else
125
- sessionApps[idx] = rebuilt;
126
- }
127
- reload?.();
128
- onRebuild?.();
129
- }
130
- catch (e) {
131
- onBuildError?.(e);
132
- }
133
- }
134
179
  try {
135
180
  process.env.DIMINA_NO_OPEN_BROWSER = '1';
136
181
  const fe = await import('../fe/index.js');
@@ -148,7 +193,7 @@ export async function openProject(opts) {
148
193
  // Watcher events are routed through the scheduler so a save landing while
149
194
  // a build is in flight is never dropped: it coalesces into exactly one
150
195
  // trailing rebuild once the current run settles.
151
- const rebuildScheduler = createRebuildScheduler(rebuild);
196
+ const rebuildScheduler = createRebuildScheduler(() => runRebuild(compileWorker, buildRequest, sessionApps, () => reload, onRebuild, onBuildError));
152
197
  watcher = watch ? createProjectWatcher(projectPath, () => rebuildScheduler.schedule()) : null;
153
198
  // Don't resolve until the watcher's initial scan is done: a save landing
154
199
  // in the gap between `openProject` resolving and chokidar going live
@@ -159,24 +204,7 @@ export async function openProject(opts) {
159
204
  await watcher?.ready;
160
205
  }
161
206
  catch (err) {
162
- try {
163
- await watcher?.close();
164
- }
165
- catch {
166
- // best-effort — the open is already failing with the primary error
167
- }
168
- try {
169
- await compileWorker.close();
170
- }
171
- catch {
172
- // best-effort — never mask the primary error
173
- }
174
- if (server) {
175
- ;
176
- server.closeAllConnections?.();
177
- const listening = server;
178
- await new Promise(resolve => listening.close(() => resolve()));
179
- }
207
+ await cleanupFailedOpen(watcher, compileWorker, server);
180
208
  throw err;
181
209
  }
182
210
  // `server` is always assigned when the try block completes without throwing
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dimina-kit/devkit",
3
- "version": "0.1.2-dev.20260702182435",
3
+ "version": "0.1.2-dev.20260703051110",
4
4
  "description": "Development toolkit for Dimina mini-apps with H5 container preview",
5
5
  "keywords": [
6
6
  "dimina",
@@ -62,7 +62,7 @@
62
62
  "cors": "^2.8.6",
63
63
  "express": "^5.2.1",
64
64
  "open": "^11.0.0",
65
- "@dimina-kit/compiler": "0.0.1-dev.20260702182435"
65
+ "@dimina-kit/compiler": "0.0.1-dev.20260703051110"
66
66
  },
67
67
  "publishConfig": {
68
68
  "access": "public"