@utoo/pack 1.4.0-alpha.3 → 1.4.0-alpha.4

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.
package/cjs/binding.d.ts CHANGED
@@ -81,6 +81,8 @@ export interface NapiProjectOptions {
81
81
  dev: boolean
82
82
  /** The build id. */
83
83
  buildId: string
84
+ /** Whether to enable default tracing logs. */
85
+ tracing: boolean
84
86
  packPath: string
85
87
  }
86
88
  /** [NapiProjectOptions] with all fields optional. */
@@ -29,7 +29,7 @@ function build(options, projectPath, rootPath) {
29
29
  return buildInternal(bundleOptions, projectPath, rootPath);
30
30
  }
31
31
  async function buildInternal(bundleOptions, projectPath, rootPath) {
32
- var _a, _b, _c, _d, _e, _f, _g, _h;
32
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
33
33
  (0, common_1.blockStdout)();
34
34
  if (process.env.XCODE_PROFILE) {
35
35
  await (0, xcodeProfile_1.xcodeProfilingReady)();
@@ -46,18 +46,19 @@ async function buildInternal(bundleOptions, projectPath, rootPath) {
46
46
  },
47
47
  dev: (_b = bundleOptions.dev) !== null && _b !== void 0 ? _b : false,
48
48
  buildId: bundleOptions.buildId || (0, nanoid_1.nanoid)(),
49
+ tracing: (_c = bundleOptions.tracing) !== null && _c !== void 0 ? _c : true,
49
50
  config: {
50
51
  ...bundleOptions.config,
51
52
  stats: Boolean(process.env.ANALYZE) ||
52
53
  bundleOptions.config.stats ||
53
54
  bundleOptions.config.entry.some((e) => !!e.html),
54
- pluginRuntimeStrategy: (_d = (_c = bundleOptions === null || bundleOptions === void 0 ? void 0 : bundleOptions.config) === null || _c === void 0 ? void 0 : _c.pluginRuntimeStrategy) !== null && _d !== void 0 ? _d : ((0, runtimePluginStratety_1.useWorkerThreads)() ? "workerThreads" : "childProcesses"),
55
+ pluginRuntimeStrategy: (_e = (_d = bundleOptions === null || bundleOptions === void 0 ? void 0 : bundleOptions.config) === null || _d === void 0 ? void 0 : _d.pluginRuntimeStrategy) !== null && _e !== void 0 ? _e : ((0, runtimePluginStratety_1.useWorkerThreads)() ? "workerThreads" : "childProcesses"),
55
56
  },
56
57
  projectPath: (0, normalize_path_1.normalizePath)(resolvedProjectPath),
57
58
  rootPath: resolvedRootPath,
58
59
  packPath: (0, common_1.getPackPath)(),
59
60
  }, {
60
- persistentCaching: (_e = bundleOptions.config.persistentCaching) !== null && _e !== void 0 ? _e : false,
61
+ persistentCaching: (_f = bundleOptions.config.persistentCaching) !== null && _f !== void 0 ? _f : false,
61
62
  });
62
63
  const entrypoints = await project.writeAllEntrypointsToDisk();
63
64
  (0, pack_shared_1.handleIssues)(entrypoints.issues);
@@ -73,20 +74,20 @@ async function buildInternal(bundleOptions, projectPath, rootPath) {
73
74
  ];
74
75
  if (htmlConfigs.length > 0) {
75
76
  const assets = { js: [], css: [] };
76
- const outputDir = ((_f = bundleOptions.config.output) === null || _f === void 0 ? void 0 : _f.path) || path_1.default.join(process.cwd(), "dist");
77
+ const outputDir = ((_g = bundleOptions.config.output) === null || _g === void 0 ? void 0 : _g.path) || path_1.default.join(process.cwd(), "dist");
77
78
  if (assets.js.length === 0 && assets.css.length === 0) {
78
79
  const discovered = (0, getInitialAssets_1.getInitialAssetsFromStats)(outputDir);
79
80
  assets.js.push(...discovered.js);
80
81
  assets.css.push(...discovered.css);
81
82
  }
82
- const publicPath = (_g = bundleOptions.config.output) === null || _g === void 0 ? void 0 : _g.publicPath;
83
+ const publicPath = (_h = bundleOptions.config.output) === null || _h === void 0 ? void 0 : _h.publicPath;
83
84
  for (const config of htmlConfigs) {
84
85
  const plugin = new HtmlPlugin_1.HtmlPlugin(config);
85
86
  await plugin.generate(outputDir, assets, publicPath);
86
87
  }
87
88
  }
88
89
  if (process.env.ANALYZE) {
89
- await analyzeBundle(((_h = bundleOptions.config.output) === null || _h === void 0 ? void 0 : _h.path) || "dist");
90
+ await analyzeBundle(((_j = bundleOptions.config.output) === null || _j === void 0 ? void 0 : _j.path) || "dist");
90
91
  }
91
92
  await project.shutdown();
92
93
  // TODO: Maybe run tasks in worker is a better way, see
package/cjs/core/hmr.js CHANGED
@@ -24,7 +24,7 @@ var pack_shared_2 = require("@utoo/pack-shared");
24
24
  Object.defineProperty(exports, "HMR_ACTIONS_SENT_TO_BROWSER", { enumerable: true, get: function () { return pack_shared_2.HMR_ACTIONS_SENT_TO_BROWSER; } });
25
25
  exports.FAST_REFRESH_RUNTIME_RELOAD = "Fast Refresh had to perform a full reload due to a runtime error.";
26
26
  async function createHotReloader(bundleOptions, projectPath, rootPath) {
27
- var _a, _b, _c, _d, _e, _f;
27
+ var _a, _b, _c, _d, _e, _f, _g;
28
28
  const resolvedProjectPath = projectPath || process.cwd();
29
29
  const resolvedRootPath = rootPath || projectPath || process.cwd();
30
30
  (0, htmlEntry_1.processHtmlEntry)(bundleOptions.config, resolvedProjectPath);
@@ -37,6 +37,7 @@ async function createHotReloader(bundleOptions, projectPath, rootPath) {
37
37
  },
38
38
  dev: true,
39
39
  buildId: bundleOptions.buildId || (0, nanoid_1.nanoid)(),
40
+ tracing: (_b = bundleOptions.tracing) !== null && _b !== void 0 ? _b : true,
40
41
  config: {
41
42
  ...bundleOptions.config,
42
43
  mode: "development",
@@ -48,14 +49,14 @@ async function createHotReloader(bundleOptions, projectPath, rootPath) {
48
49
  minify: false,
49
50
  moduleIds: "named",
50
51
  },
51
- persistentCaching: (_c = (_b = bundleOptions === null || bundleOptions === void 0 ? void 0 : bundleOptions.config) === null || _b === void 0 ? void 0 : _b.persistentCaching) !== null && _c !== void 0 ? _c : true,
52
- pluginRuntimeStrategy: (_e = (_d = bundleOptions === null || bundleOptions === void 0 ? void 0 : bundleOptions.config) === null || _d === void 0 ? void 0 : _d.pluginRuntimeStrategy) !== null && _e !== void 0 ? _e : ((0, runtimePluginStratety_1.useWorkerThreads)() ? "workerThreads" : "childProcesses"),
52
+ persistentCaching: (_d = (_c = bundleOptions === null || bundleOptions === void 0 ? void 0 : bundleOptions.config) === null || _c === void 0 ? void 0 : _c.persistentCaching) !== null && _d !== void 0 ? _d : true,
53
+ pluginRuntimeStrategy: (_f = (_e = bundleOptions === null || bundleOptions === void 0 ? void 0 : bundleOptions.config) === null || _e === void 0 ? void 0 : _e.pluginRuntimeStrategy) !== null && _f !== void 0 ? _f : ((0, runtimePluginStratety_1.useWorkerThreads)() ? "workerThreads" : "childProcesses"),
53
54
  },
54
55
  projectPath: (0, normalize_path_1.normalizePath)(resolvedProjectPath),
55
56
  rootPath: resolvedRootPath,
56
57
  packPath: (0, common_1.getPackPath)(),
57
58
  }, {
58
- persistentCaching: (_f = bundleOptions.config.persistentCaching) !== null && _f !== void 0 ? _f : false,
59
+ persistentCaching: (_g = bundleOptions.config.persistentCaching) !== null && _g !== void 0 ? _g : false,
59
60
  });
60
61
  const entrypointsSubscription = project.entrypointsSubscribe();
61
62
  let currentEntriesHandlingResolve;
@@ -64,6 +65,22 @@ async function createHotReloader(bundleOptions, projectPath, rootPath) {
64
65
  let hmrHash = 0;
65
66
  const clients = new Set();
66
67
  const clientStates = new WeakMap();
68
+ const backgroundWatchSubscriptions = new Set();
69
+ const htmlConfigs = [
70
+ ...(Array.isArray(bundleOptions.config.html)
71
+ ? bundleOptions.config.html
72
+ : bundleOptions.config.html
73
+ ? [bundleOptions.config.html]
74
+ : []),
75
+ ...bundleOptions.config.entry
76
+ .filter((e) => !!e.html)
77
+ .map((e) => e.html),
78
+ ];
79
+ let currentWatchedEntrypoints = [];
80
+ let backgroundWatchersStarted = false;
81
+ let backgroundWatchGeneration = 0;
82
+ const backgroundWriteTasks = new Map();
83
+ let closed = false;
67
84
  function sendToClient(client, payload) {
68
85
  client.send(JSON.stringify(payload));
69
86
  }
@@ -97,6 +114,103 @@ async function createHotReloader(bundleOptions, projectPath, rootPath) {
97
114
  hmrEventHappened = true;
98
115
  sendEnqueuedMessagesDebounce();
99
116
  }
117
+ async function regenerateHtml() {
118
+ var _a, _b;
119
+ if (htmlConfigs.length === 0) {
120
+ return;
121
+ }
122
+ const outputDir = ((_a = bundleOptions.config.output) === null || _a === void 0 ? void 0 : _a.path) || path_1.default.join(process.cwd(), "dist");
123
+ const publicPath = (_b = bundleOptions.config.output) === null || _b === void 0 ? void 0 : _b.publicPath;
124
+ const assets = (0, getInitialAssets_1.getInitialAssetsFromStats)(outputDir);
125
+ for (const config of htmlConfigs) {
126
+ const plugin = new HtmlPlugin_1.HtmlPlugin(config);
127
+ await plugin.generate(outputDir, assets, publicPath);
128
+ }
129
+ }
130
+ async function writeEntrypointToDisk(entrypoint) {
131
+ const result = await entrypoint.writeToDisk();
132
+ (0, common_1.processIssues)(result, true, true);
133
+ await regenerateHtml();
134
+ }
135
+ async function writeEntrypointsToDisk(entrypoints) {
136
+ await Promise.all(entrypoints.map((entrypoint) => writeEntrypointToDisk(entrypoint)));
137
+ }
138
+ async function disposeBackgroundWatchSubscriptions() {
139
+ const subscriptions = [...backgroundWatchSubscriptions];
140
+ backgroundWatchSubscriptions.clear();
141
+ backgroundWriteTasks.clear();
142
+ await Promise.all(subscriptions.map((subscription) => { var _a; return (_a = subscription.return) === null || _a === void 0 ? void 0 : _a.call(subscription); }));
143
+ }
144
+ function scheduleEntrypointWrite(entrypoint, generation) {
145
+ var _a;
146
+ if (!backgroundWatchersStarted ||
147
+ closed ||
148
+ generation !== backgroundWatchGeneration) {
149
+ return;
150
+ }
151
+ const previousTask = (_a = backgroundWriteTasks.get(entrypoint)) !== null && _a !== void 0 ? _a : Promise.resolve();
152
+ const task = previousTask
153
+ .catch(() => { })
154
+ .then(async () => {
155
+ await currentEntriesHandling;
156
+ if (closed || generation !== backgroundWatchGeneration) {
157
+ return;
158
+ }
159
+ await writeEntrypointToDisk(entrypoint);
160
+ hmrEventHappened = true;
161
+ })
162
+ .finally(() => {
163
+ if (backgroundWriteTasks.get(entrypoint) === task) {
164
+ backgroundWriteTasks.delete(entrypoint);
165
+ }
166
+ });
167
+ backgroundWriteTasks.set(entrypoint, task);
168
+ }
169
+ async function refreshBackgroundWatchers() {
170
+ const generation = ++backgroundWatchGeneration;
171
+ await disposeBackgroundWatchSubscriptions();
172
+ if (!backgroundWatchersStarted || closed) {
173
+ return;
174
+ }
175
+ await Promise.all(currentWatchedEntrypoints.map(async (entrypoint) => {
176
+ var _a, _b;
177
+ const [clientChanges, serverChanges] = await Promise.all([
178
+ entrypoint.clientChanged(),
179
+ entrypoint.serverChanged(true),
180
+ ]);
181
+ if (closed || generation !== backgroundWatchGeneration) {
182
+ await Promise.all([
183
+ (_a = clientChanges.return) === null || _a === void 0 ? void 0 : _a.call(clientChanges),
184
+ (_b = serverChanges.return) === null || _b === void 0 ? void 0 : _b.call(serverChanges),
185
+ ]);
186
+ return;
187
+ }
188
+ backgroundWatchSubscriptions.add(clientChanges);
189
+ backgroundWatchSubscriptions.add(serverChanges);
190
+ const watchChanges = async (subscription) => {
191
+ try {
192
+ for await (const data of subscription) {
193
+ if (closed || generation !== backgroundWatchGeneration) {
194
+ return;
195
+ }
196
+ (0, common_1.processIssues)(data, true, true);
197
+ scheduleEntrypointWrite(entrypoint, generation);
198
+ }
199
+ }
200
+ catch (error) {
201
+ if (!closed && generation === backgroundWatchGeneration) {
202
+ console.error(error);
203
+ process.exit(1);
204
+ }
205
+ }
206
+ finally {
207
+ backgroundWatchSubscriptions.delete(subscription);
208
+ }
209
+ };
210
+ void watchChanges(clientChanges);
211
+ void watchChanges(serverChanges);
212
+ }));
213
+ }
100
214
  async function subscribeToHmrEvents(client, id) {
101
215
  const state = clientStates.get(client);
102
216
  if (!state || state.subscriptions.has(id)) {
@@ -138,39 +252,19 @@ async function createHotReloader(bundleOptions, projectPath, rootPath) {
138
252
  subscription === null || subscription === void 0 ? void 0 : subscription.return();
139
253
  }
140
254
  async function handleEntrypointsSubscription() {
141
- var _a, _b;
142
255
  for await (const entrypoints of entrypointsSubscription) {
143
256
  if (!currentEntriesHandlingResolve) {
144
257
  currentEntriesHandling = new Promise(
145
258
  // eslint-disable-next-line no-loop-func
146
259
  (resolve) => (currentEntriesHandlingResolve = resolve));
147
260
  }
148
- const assets = { js: [], css: [] };
149
- await Promise.all([...entrypoints.apps, ...entrypoints.libraries].map((l) => l.writeToDisk().then((res) => {
150
- (0, common_1.processIssues)(res, true, true);
151
- })));
152
- const htmlConfigs = [
153
- ...(Array.isArray(bundleOptions.config.html)
154
- ? bundleOptions.config.html
155
- : bundleOptions.config.html
156
- ? [bundleOptions.config.html]
157
- : []),
158
- ...bundleOptions.config.entry
159
- .filter((e) => !!e.html)
160
- .map((e) => e.html),
261
+ currentWatchedEntrypoints = [
262
+ ...entrypoints.apps,
263
+ ...entrypoints.libraries,
161
264
  ];
162
- if (htmlConfigs.length > 0) {
163
- const outputDir = ((_a = bundleOptions.config.output) === null || _a === void 0 ? void 0 : _a.path) || path_1.default.join(process.cwd(), "dist");
164
- const publicPath = (_b = bundleOptions.config.output) === null || _b === void 0 ? void 0 : _b.publicPath;
165
- if (assets.js.length === 0 && assets.css.length === 0) {
166
- const discovered = (0, getInitialAssets_1.getInitialAssetsFromStats)(outputDir);
167
- assets.js.push(...discovered.js);
168
- assets.css.push(...discovered.css);
169
- }
170
- for (const config of htmlConfigs) {
171
- const plugin = new HtmlPlugin_1.HtmlPlugin(config);
172
- await plugin.generate(outputDir, assets, publicPath);
173
- }
265
+ await writeEntrypointsToDisk(currentWatchedEntrypoints);
266
+ if (backgroundWatchersStarted) {
267
+ await refreshBackgroundWatchers();
174
268
  }
175
269
  currentEntriesHandlingResolve();
176
270
  currentEntriesHandlingResolve = undefined;
@@ -338,11 +432,19 @@ async function createHotReloader(bundleOptions, projectPath, rootPath) {
338
432
  clearHmrServerError() {
339
433
  // Not implemented yet.
340
434
  },
341
- async start() { },
435
+ async start() {
436
+ if (backgroundWatchersStarted) {
437
+ return;
438
+ }
439
+ backgroundWatchersStarted = true;
440
+ await refreshBackgroundWatchers();
441
+ },
342
442
  async buildFallbackError() {
343
443
  // Not implemented yet.
344
444
  },
345
445
  close() {
446
+ closed = true;
447
+ void disposeBackgroundWatchSubscriptions();
346
448
  for (const wsClient of clients) {
347
449
  wsClient.close();
348
450
  }
package/esm/binding.d.ts CHANGED
@@ -81,6 +81,8 @@ export interface NapiProjectOptions {
81
81
  dev: boolean
82
82
  /** The build id. */
83
83
  buildId: string
84
+ /** Whether to enable default tracing logs. */
85
+ tracing: boolean
84
86
  packPath: string
85
87
  }
86
88
  /** [NapiProjectOptions] with all fields optional. */
@@ -23,7 +23,7 @@ export function build(options, projectPath, rootPath) {
23
23
  return buildInternal(bundleOptions, projectPath, rootPath);
24
24
  }
25
25
  async function buildInternal(bundleOptions, projectPath, rootPath) {
26
- var _a, _b, _c, _d, _e, _f, _g, _h;
26
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
27
27
  blockStdout();
28
28
  if (process.env.XCODE_PROFILE) {
29
29
  await xcodeProfilingReady();
@@ -40,18 +40,19 @@ async function buildInternal(bundleOptions, projectPath, rootPath) {
40
40
  },
41
41
  dev: (_b = bundleOptions.dev) !== null && _b !== void 0 ? _b : false,
42
42
  buildId: bundleOptions.buildId || nanoid(),
43
+ tracing: (_c = bundleOptions.tracing) !== null && _c !== void 0 ? _c : true,
43
44
  config: {
44
45
  ...bundleOptions.config,
45
46
  stats: Boolean(process.env.ANALYZE) ||
46
47
  bundleOptions.config.stats ||
47
48
  bundleOptions.config.entry.some((e) => !!e.html),
48
- pluginRuntimeStrategy: (_d = (_c = bundleOptions === null || bundleOptions === void 0 ? void 0 : bundleOptions.config) === null || _c === void 0 ? void 0 : _c.pluginRuntimeStrategy) !== null && _d !== void 0 ? _d : (useWorkerThreads() ? "workerThreads" : "childProcesses"),
49
+ pluginRuntimeStrategy: (_e = (_d = bundleOptions === null || bundleOptions === void 0 ? void 0 : bundleOptions.config) === null || _d === void 0 ? void 0 : _d.pluginRuntimeStrategy) !== null && _e !== void 0 ? _e : (useWorkerThreads() ? "workerThreads" : "childProcesses"),
49
50
  },
50
51
  projectPath: normalizePath(resolvedProjectPath),
51
52
  rootPath: resolvedRootPath,
52
53
  packPath: getPackPath(),
53
54
  }, {
54
- persistentCaching: (_e = bundleOptions.config.persistentCaching) !== null && _e !== void 0 ? _e : false,
55
+ persistentCaching: (_f = bundleOptions.config.persistentCaching) !== null && _f !== void 0 ? _f : false,
55
56
  });
56
57
  const entrypoints = await project.writeAllEntrypointsToDisk();
57
58
  handleIssues(entrypoints.issues);
@@ -67,20 +68,20 @@ async function buildInternal(bundleOptions, projectPath, rootPath) {
67
68
  ];
68
69
  if (htmlConfigs.length > 0) {
69
70
  const assets = { js: [], css: [] };
70
- const outputDir = ((_f = bundleOptions.config.output) === null || _f === void 0 ? void 0 : _f.path) || path.join(process.cwd(), "dist");
71
+ const outputDir = ((_g = bundleOptions.config.output) === null || _g === void 0 ? void 0 : _g.path) || path.join(process.cwd(), "dist");
71
72
  if (assets.js.length === 0 && assets.css.length === 0) {
72
73
  const discovered = getInitialAssetsFromStats(outputDir);
73
74
  assets.js.push(...discovered.js);
74
75
  assets.css.push(...discovered.css);
75
76
  }
76
- const publicPath = (_g = bundleOptions.config.output) === null || _g === void 0 ? void 0 : _g.publicPath;
77
+ const publicPath = (_h = bundleOptions.config.output) === null || _h === void 0 ? void 0 : _h.publicPath;
77
78
  for (const config of htmlConfigs) {
78
79
  const plugin = new HtmlPlugin(config);
79
80
  await plugin.generate(outputDir, assets, publicPath);
80
81
  }
81
82
  }
82
83
  if (process.env.ANALYZE) {
83
- await analyzeBundle(((_h = bundleOptions.config.output) === null || _h === void 0 ? void 0 : _h.path) || "dist");
84
+ await analyzeBundle(((_j = bundleOptions.config.output) === null || _j === void 0 ? void 0 : _j.path) || "dist");
84
85
  }
85
86
  await project.shutdown();
86
87
  // TODO: Maybe run tasks in worker is a better way, see
package/esm/core/hmr.js CHANGED
@@ -16,7 +16,7 @@ const sessionId = Math.floor(Number.MAX_SAFE_INTEGER * Math.random());
16
16
  export { HMR_ACTIONS_SENT_TO_BROWSER, } from "@utoo/pack-shared";
17
17
  export const FAST_REFRESH_RUNTIME_RELOAD = "Fast Refresh had to perform a full reload due to a runtime error.";
18
18
  export async function createHotReloader(bundleOptions, projectPath, rootPath) {
19
- var _a, _b, _c, _d, _e, _f;
19
+ var _a, _b, _c, _d, _e, _f, _g;
20
20
  const resolvedProjectPath = projectPath || process.cwd();
21
21
  const resolvedRootPath = rootPath || projectPath || process.cwd();
22
22
  processHtmlEntry(bundleOptions.config, resolvedProjectPath);
@@ -29,6 +29,7 @@ export async function createHotReloader(bundleOptions, projectPath, rootPath) {
29
29
  },
30
30
  dev: true,
31
31
  buildId: bundleOptions.buildId || nanoid(),
32
+ tracing: (_b = bundleOptions.tracing) !== null && _b !== void 0 ? _b : true,
32
33
  config: {
33
34
  ...bundleOptions.config,
34
35
  mode: "development",
@@ -40,14 +41,14 @@ export async function createHotReloader(bundleOptions, projectPath, rootPath) {
40
41
  minify: false,
41
42
  moduleIds: "named",
42
43
  },
43
- persistentCaching: (_c = (_b = bundleOptions === null || bundleOptions === void 0 ? void 0 : bundleOptions.config) === null || _b === void 0 ? void 0 : _b.persistentCaching) !== null && _c !== void 0 ? _c : true,
44
- pluginRuntimeStrategy: (_e = (_d = bundleOptions === null || bundleOptions === void 0 ? void 0 : bundleOptions.config) === null || _d === void 0 ? void 0 : _d.pluginRuntimeStrategy) !== null && _e !== void 0 ? _e : (useWorkerThreads() ? "workerThreads" : "childProcesses"),
44
+ persistentCaching: (_d = (_c = bundleOptions === null || bundleOptions === void 0 ? void 0 : bundleOptions.config) === null || _c === void 0 ? void 0 : _c.persistentCaching) !== null && _d !== void 0 ? _d : true,
45
+ pluginRuntimeStrategy: (_f = (_e = bundleOptions === null || bundleOptions === void 0 ? void 0 : bundleOptions.config) === null || _e === void 0 ? void 0 : _e.pluginRuntimeStrategy) !== null && _f !== void 0 ? _f : (useWorkerThreads() ? "workerThreads" : "childProcesses"),
45
46
  },
46
47
  projectPath: normalizePath(resolvedProjectPath),
47
48
  rootPath: resolvedRootPath,
48
49
  packPath: getPackPath(),
49
50
  }, {
50
- persistentCaching: (_f = bundleOptions.config.persistentCaching) !== null && _f !== void 0 ? _f : false,
51
+ persistentCaching: (_g = bundleOptions.config.persistentCaching) !== null && _g !== void 0 ? _g : false,
51
52
  });
52
53
  const entrypointsSubscription = project.entrypointsSubscribe();
53
54
  let currentEntriesHandlingResolve;
@@ -56,6 +57,22 @@ export async function createHotReloader(bundleOptions, projectPath, rootPath) {
56
57
  let hmrHash = 0;
57
58
  const clients = new Set();
58
59
  const clientStates = new WeakMap();
60
+ const backgroundWatchSubscriptions = new Set();
61
+ const htmlConfigs = [
62
+ ...(Array.isArray(bundleOptions.config.html)
63
+ ? bundleOptions.config.html
64
+ : bundleOptions.config.html
65
+ ? [bundleOptions.config.html]
66
+ : []),
67
+ ...bundleOptions.config.entry
68
+ .filter((e) => !!e.html)
69
+ .map((e) => e.html),
70
+ ];
71
+ let currentWatchedEntrypoints = [];
72
+ let backgroundWatchersStarted = false;
73
+ let backgroundWatchGeneration = 0;
74
+ const backgroundWriteTasks = new Map();
75
+ let closed = false;
59
76
  function sendToClient(client, payload) {
60
77
  client.send(JSON.stringify(payload));
61
78
  }
@@ -89,6 +106,103 @@ export async function createHotReloader(bundleOptions, projectPath, rootPath) {
89
106
  hmrEventHappened = true;
90
107
  sendEnqueuedMessagesDebounce();
91
108
  }
109
+ async function regenerateHtml() {
110
+ var _a, _b;
111
+ if (htmlConfigs.length === 0) {
112
+ return;
113
+ }
114
+ const outputDir = ((_a = bundleOptions.config.output) === null || _a === void 0 ? void 0 : _a.path) || path.join(process.cwd(), "dist");
115
+ const publicPath = (_b = bundleOptions.config.output) === null || _b === void 0 ? void 0 : _b.publicPath;
116
+ const assets = getInitialAssetsFromStats(outputDir);
117
+ for (const config of htmlConfigs) {
118
+ const plugin = new HtmlPlugin(config);
119
+ await plugin.generate(outputDir, assets, publicPath);
120
+ }
121
+ }
122
+ async function writeEntrypointToDisk(entrypoint) {
123
+ const result = await entrypoint.writeToDisk();
124
+ processIssues(result, true, true);
125
+ await regenerateHtml();
126
+ }
127
+ async function writeEntrypointsToDisk(entrypoints) {
128
+ await Promise.all(entrypoints.map((entrypoint) => writeEntrypointToDisk(entrypoint)));
129
+ }
130
+ async function disposeBackgroundWatchSubscriptions() {
131
+ const subscriptions = [...backgroundWatchSubscriptions];
132
+ backgroundWatchSubscriptions.clear();
133
+ backgroundWriteTasks.clear();
134
+ await Promise.all(subscriptions.map((subscription) => { var _a; return (_a = subscription.return) === null || _a === void 0 ? void 0 : _a.call(subscription); }));
135
+ }
136
+ function scheduleEntrypointWrite(entrypoint, generation) {
137
+ var _a;
138
+ if (!backgroundWatchersStarted ||
139
+ closed ||
140
+ generation !== backgroundWatchGeneration) {
141
+ return;
142
+ }
143
+ const previousTask = (_a = backgroundWriteTasks.get(entrypoint)) !== null && _a !== void 0 ? _a : Promise.resolve();
144
+ const task = previousTask
145
+ .catch(() => { })
146
+ .then(async () => {
147
+ await currentEntriesHandling;
148
+ if (closed || generation !== backgroundWatchGeneration) {
149
+ return;
150
+ }
151
+ await writeEntrypointToDisk(entrypoint);
152
+ hmrEventHappened = true;
153
+ })
154
+ .finally(() => {
155
+ if (backgroundWriteTasks.get(entrypoint) === task) {
156
+ backgroundWriteTasks.delete(entrypoint);
157
+ }
158
+ });
159
+ backgroundWriteTasks.set(entrypoint, task);
160
+ }
161
+ async function refreshBackgroundWatchers() {
162
+ const generation = ++backgroundWatchGeneration;
163
+ await disposeBackgroundWatchSubscriptions();
164
+ if (!backgroundWatchersStarted || closed) {
165
+ return;
166
+ }
167
+ await Promise.all(currentWatchedEntrypoints.map(async (entrypoint) => {
168
+ var _a, _b;
169
+ const [clientChanges, serverChanges] = await Promise.all([
170
+ entrypoint.clientChanged(),
171
+ entrypoint.serverChanged(true),
172
+ ]);
173
+ if (closed || generation !== backgroundWatchGeneration) {
174
+ await Promise.all([
175
+ (_a = clientChanges.return) === null || _a === void 0 ? void 0 : _a.call(clientChanges),
176
+ (_b = serverChanges.return) === null || _b === void 0 ? void 0 : _b.call(serverChanges),
177
+ ]);
178
+ return;
179
+ }
180
+ backgroundWatchSubscriptions.add(clientChanges);
181
+ backgroundWatchSubscriptions.add(serverChanges);
182
+ const watchChanges = async (subscription) => {
183
+ try {
184
+ for await (const data of subscription) {
185
+ if (closed || generation !== backgroundWatchGeneration) {
186
+ return;
187
+ }
188
+ processIssues(data, true, true);
189
+ scheduleEntrypointWrite(entrypoint, generation);
190
+ }
191
+ }
192
+ catch (error) {
193
+ if (!closed && generation === backgroundWatchGeneration) {
194
+ console.error(error);
195
+ process.exit(1);
196
+ }
197
+ }
198
+ finally {
199
+ backgroundWatchSubscriptions.delete(subscription);
200
+ }
201
+ };
202
+ void watchChanges(clientChanges);
203
+ void watchChanges(serverChanges);
204
+ }));
205
+ }
92
206
  async function subscribeToHmrEvents(client, id) {
93
207
  const state = clientStates.get(client);
94
208
  if (!state || state.subscriptions.has(id)) {
@@ -130,39 +244,19 @@ export async function createHotReloader(bundleOptions, projectPath, rootPath) {
130
244
  subscription === null || subscription === void 0 ? void 0 : subscription.return();
131
245
  }
132
246
  async function handleEntrypointsSubscription() {
133
- var _a, _b;
134
247
  for await (const entrypoints of entrypointsSubscription) {
135
248
  if (!currentEntriesHandlingResolve) {
136
249
  currentEntriesHandling = new Promise(
137
250
  // eslint-disable-next-line no-loop-func
138
251
  (resolve) => (currentEntriesHandlingResolve = resolve));
139
252
  }
140
- const assets = { js: [], css: [] };
141
- await Promise.all([...entrypoints.apps, ...entrypoints.libraries].map((l) => l.writeToDisk().then((res) => {
142
- processIssues(res, true, true);
143
- })));
144
- const htmlConfigs = [
145
- ...(Array.isArray(bundleOptions.config.html)
146
- ? bundleOptions.config.html
147
- : bundleOptions.config.html
148
- ? [bundleOptions.config.html]
149
- : []),
150
- ...bundleOptions.config.entry
151
- .filter((e) => !!e.html)
152
- .map((e) => e.html),
253
+ currentWatchedEntrypoints = [
254
+ ...entrypoints.apps,
255
+ ...entrypoints.libraries,
153
256
  ];
154
- if (htmlConfigs.length > 0) {
155
- const outputDir = ((_a = bundleOptions.config.output) === null || _a === void 0 ? void 0 : _a.path) || path.join(process.cwd(), "dist");
156
- const publicPath = (_b = bundleOptions.config.output) === null || _b === void 0 ? void 0 : _b.publicPath;
157
- if (assets.js.length === 0 && assets.css.length === 0) {
158
- const discovered = getInitialAssetsFromStats(outputDir);
159
- assets.js.push(...discovered.js);
160
- assets.css.push(...discovered.css);
161
- }
162
- for (const config of htmlConfigs) {
163
- const plugin = new HtmlPlugin(config);
164
- await plugin.generate(outputDir, assets, publicPath);
165
- }
257
+ await writeEntrypointsToDisk(currentWatchedEntrypoints);
258
+ if (backgroundWatchersStarted) {
259
+ await refreshBackgroundWatchers();
166
260
  }
167
261
  currentEntriesHandlingResolve();
168
262
  currentEntriesHandlingResolve = undefined;
@@ -330,11 +424,19 @@ export async function createHotReloader(bundleOptions, projectPath, rootPath) {
330
424
  clearHmrServerError() {
331
425
  // Not implemented yet.
332
426
  },
333
- async start() { },
427
+ async start() {
428
+ if (backgroundWatchersStarted) {
429
+ return;
430
+ }
431
+ backgroundWatchersStarted = true;
432
+ await refreshBackgroundWatchers();
433
+ },
334
434
  async buildFallbackError() {
335
435
  // Not implemented yet.
336
436
  },
337
437
  close() {
438
+ closed = true;
439
+ void disposeBackgroundWatchSubscriptions();
338
440
  for (const wsClient of clients) {
339
441
  wsClient.close();
340
442
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@utoo/pack",
3
- "version": "1.4.0-alpha.3",
3
+ "version": "1.4.0-alpha.4",
4
4
  "main": "cjs/index.js",
5
5
  "module": "esm/index.js",
6
6
  "types": "esm/index.d.ts",
@@ -41,7 +41,7 @@
41
41
  "@hono/node-server": "^1.19.11",
42
42
  "@hono/node-ws": "^1.3.0",
43
43
  "@swc/helpers": "0.5.15",
44
- "@utoo/pack-shared": "1.4.0-alpha.3",
44
+ "@utoo/pack-shared": "1.4.0-alpha.4",
45
45
  "domparser-rs": "^0.0.7",
46
46
  "find-up": "4.1.0",
47
47
  "get-port": "5.1.1",
@@ -92,12 +92,12 @@
92
92
  },
93
93
  "repository": "git@github.com:utooland/utoo.git",
94
94
  "optionalDependencies": {
95
- "@utoo/pack-darwin-arm64": "1.4.0-alpha.3",
96
- "@utoo/pack-darwin-x64": "1.4.0-alpha.3",
97
- "@utoo/pack-linux-arm64-gnu": "1.4.0-alpha.3",
98
- "@utoo/pack-linux-arm64-musl": "1.4.0-alpha.3",
99
- "@utoo/pack-linux-x64-gnu": "1.4.0-alpha.3",
100
- "@utoo/pack-linux-x64-musl": "1.4.0-alpha.3",
101
- "@utoo/pack-win32-x64-msvc": "1.4.0-alpha.3"
95
+ "@utoo/pack-darwin-arm64": "1.4.0-alpha.4",
96
+ "@utoo/pack-darwin-x64": "1.4.0-alpha.4",
97
+ "@utoo/pack-linux-arm64-gnu": "1.4.0-alpha.4",
98
+ "@utoo/pack-linux-arm64-musl": "1.4.0-alpha.4",
99
+ "@utoo/pack-linux-x64-gnu": "1.4.0-alpha.4",
100
+ "@utoo/pack-linux-x64-musl": "1.4.0-alpha.4",
101
+ "@utoo/pack-win32-x64-msvc": "1.4.0-alpha.4"
102
102
  }
103
103
  }