vite-plugin-taro 0.6.20-beta.2 → 0.6.20
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/dist/index.d.ts +1 -1
- package/dist/index.js +119 -120
- package/dist/node/plugins/wx/dev/dev-host.d.ts +15 -6
- package/dist/node/plugins/wx/dev/hmr-files.d.ts +10 -22
- package/dist/node/plugins/wx/dev/hmr-mode.d.ts +31 -0
- package/dist/node/plugins/wx/dev/hmr-protocol.d.ts +16 -0
- package/dist/node/plugins/wx/dev/modes/devtools/devtools-hmr-mode.d.ts +31 -0
- package/dist/node/plugins/wx/dev/modes/interpreter/interpreter-hmr-mode.d.ts +3 -0
- package/dist/node/plugins/wx/dev/patch-journal.d.ts +45 -0
- package/dist/node/plugins/wx/dev/plugins.d.ts +6 -10
- package/dist/node/plugins/wx/dev/wx-dev-options.d.ts +3 -1
- package/dist/options.d.ts +11 -0
- package/dist/runtime/wx/capsule/taro-runtime.js +5 -0
- package/dist/runtime/wx/dev/modes/devtools/devtools-runtime.js +30 -0
- package/dist/runtime/wx/dev/modes/devtools/page-hmr.d.ts +20 -0
- package/dist/runtime/wx/dev/modes/devtools/page-hmr.js +133 -0
- package/dist/runtime/wx/dev/modes/interpreter/interpreter-protocol.d.ts +12 -0
- package/dist/runtime/wx/dev/modes/interpreter/interpreter-protocol.js +1 -0
- package/dist/runtime/wx/dev/modes/interpreter/interpreter-runtime.d.ts +1 -0
- package/dist/runtime/wx/dev/modes/interpreter/interpreter-runtime.js +29 -0
- package/dist/runtime/wx/dev/wx-hmr-protocol.d.ts +22 -0
- package/dist/runtime/wx/dev/wx-hmr-protocol.js +4 -0
- package/dist/runtime/wx/dev/wx-hmr-runtime.d.ts +107 -0
- package/dist/runtime/wx/dev/{dev-runtime.js → wx-hmr-runtime.js} +83 -130
- package/package.json +5 -4
- package/dist/node/plugins/wx/dev/patch-publisher.d.ts +0 -42
- package/dist/node/plugins/wx/dev/runtime-reports.d.ts +0 -27
- /package/dist/runtime/wx/dev/{dev-runtime.d.ts → modes/devtools/devtools-runtime.d.ts} +0 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { DevRuntime as RolldownDevRuntime } from 'rolldown/experimental/runtime-types';
|
|
2
|
+
import { type HmrInfo } from './wx-hmr-protocol.ts';
|
|
3
|
+
/** Lexical base class injected into the runtime chunk by Rolldown; typed via the contract. */
|
|
4
|
+
declare const DevRuntime: new (clientId: string) => RolldownDevRuntime;
|
|
5
|
+
/** Mode-independent patch metadata consumed by the shared sequence and graph reducer. */
|
|
6
|
+
export type RuntimePatch = Readonly<{
|
|
7
|
+
seq: number;
|
|
8
|
+
/** Stable ids of the changed modules; synchronous application walks the graph from these roots. */
|
|
9
|
+
changedIds: readonly string[];
|
|
10
|
+
}>;
|
|
11
|
+
type AcceptCallback = (moduleExports: unknown) => void;
|
|
12
|
+
/**
|
|
13
|
+
* Per-module hot state, mirroring Rolldown's web runtime: accept is a passive registration;
|
|
14
|
+
* the propagation invokes the previous execution's callbacks with the fresh exports.
|
|
15
|
+
*/
|
|
16
|
+
declare class WxHotContext {
|
|
17
|
+
readonly _internal: Readonly<{
|
|
18
|
+
updateStyle(): void;
|
|
19
|
+
removeStyle(): void;
|
|
20
|
+
}>;
|
|
21
|
+
/**
|
|
22
|
+
* Callbacks registered by this module execution. The array is allocated on first accept,
|
|
23
|
+
* remains attached to the old execution across cache eviction, and is invoked by the next
|
|
24
|
+
* boundary execution. Undefined means this context stays passive.
|
|
25
|
+
*/
|
|
26
|
+
private acceptCallbacks;
|
|
27
|
+
/** Stable module identity and shared sparse index used only when this context accepts. */
|
|
28
|
+
private readonly moduleId;
|
|
29
|
+
private readonly acceptingContexts;
|
|
30
|
+
constructor(moduleId: string, acceptingContexts: Map<string, WxHotContext>);
|
|
31
|
+
accept(callback?: AcceptCallback): void;
|
|
32
|
+
/** Invokes this old context's callbacks; invalidation aborts the update synchronously. */
|
|
33
|
+
runAccept(moduleExports: unknown): void;
|
|
34
|
+
invalidate(reason?: string): never;
|
|
35
|
+
prune(_callback?: () => void): void;
|
|
36
|
+
}
|
|
37
|
+
/** Shared WX host mechanics extending the Rolldown contract instead of reimplementing it. */
|
|
38
|
+
export declare class WxHmrRuntime extends DevRuntime {
|
|
39
|
+
/**
|
|
40
|
+
* One session for this App heap. Undefined only before the mode-selected entry initializes the runtime; its identity then
|
|
41
|
+
* stays fixed while appliedSeq records the committed frontier.
|
|
42
|
+
*/
|
|
43
|
+
private session;
|
|
44
|
+
/** The App heap's sole SocketTask, assigned once by initialize and retained for its lifetime. */
|
|
45
|
+
private socket;
|
|
46
|
+
/**
|
|
47
|
+
* Sparse current-generation accepting boundaries keyed by module id. Entries alone must
|
|
48
|
+
* outlive Rolldown module-cache eviction so old callbacks can receive fresh exports.
|
|
49
|
+
* createModuleHotContext removes the prior generation immediately; first accept inserts
|
|
50
|
+
* the new one. Passive contexts are never retained, so space is O(number of boundaries).
|
|
51
|
+
*/
|
|
52
|
+
private readonly moduleHotContexts;
|
|
53
|
+
constructor();
|
|
54
|
+
/**
|
|
55
|
+
* Generated code always calls this before registerModule and reads `_internal` from the
|
|
56
|
+
* return value. Each execution immediately retires its previous accepting boundary;
|
|
57
|
+
* calling accept registers the new context after the apply plan captured old callbacks.
|
|
58
|
+
*/
|
|
59
|
+
createModuleHotContext(moduleId: string): WxHotContext;
|
|
60
|
+
/** Computes accepting boundaries and every executed module that must be re-armed. */
|
|
61
|
+
private computeHmrUpdate;
|
|
62
|
+
/** Walks executed importers until an accepting boundary is found. */
|
|
63
|
+
private bubble;
|
|
64
|
+
/**
|
|
65
|
+
* Applies one patch in three phases: capture old contexts, evict the whole update set,
|
|
66
|
+
* then re-run accepting modules and pass their fresh exports to the old contexts.
|
|
67
|
+
*/
|
|
68
|
+
private applyHmrUpdate;
|
|
69
|
+
/**
|
|
70
|
+
* Initializes exactly once per App heap. Repeated entry evaluation must not replace the identity or reset `appliedSeq`, because
|
|
71
|
+
* either change could acknowledge factories against another host client or replay already committed application generations.
|
|
72
|
+
*/
|
|
73
|
+
initialize(info: HmrInfo): void;
|
|
74
|
+
/** Receives mode-specific Vite custom events after shared control messages have been handled. */
|
|
75
|
+
protected onSocketEvent(_info: HmrInfo, _event: string, _data: unknown): void;
|
|
76
|
+
/** Sends one typed Vite custom event through the current App-level socket. */
|
|
77
|
+
protected sendSocketEvent(event: string, data: unknown): void;
|
|
78
|
+
/** Closes the sole socket after terminal host control or interpreter failure. */
|
|
79
|
+
protected stopSocket(reason: string): void;
|
|
80
|
+
/**
|
|
81
|
+
* Applies one mode-delivered cumulative payload through its mode-specific patch installer.
|
|
82
|
+
*
|
|
83
|
+
* Application is deliberately synchronous so every later message observes the committed module generation. The installer is
|
|
84
|
+
* the only mode seam; sequence validation and ACK reporting stay here so no mode can mistake delivery for application.
|
|
85
|
+
*/
|
|
86
|
+
protected applyPatchPayload<Patch extends RuntimePatch>(payload: Readonly<{
|
|
87
|
+
buildId: string;
|
|
88
|
+
patches: readonly Patch[];
|
|
89
|
+
}>, installPatch: (patch: Patch) => void): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Folds one cumulative mode delivery into a single logical HMR update.
|
|
92
|
+
*
|
|
93
|
+
* A delivery may contain several unacknowledged application patches and may be replayed by its mode—for DevTools, every
|
|
94
|
+
* affected live Page evaluates the same physical file. The runtime therefore ignores old sequences, rejects a missing one,
|
|
95
|
+
* and moves directly from the live module generation to the latest published one without intermediate renders.
|
|
96
|
+
*
|
|
97
|
+
* For an appliedSeq of 4:
|
|
98
|
+
*
|
|
99
|
+
* - [5, 6, 7] installs every patch, applies their unioned changedIds, commits appliedSeq 7, and reports 7;
|
|
100
|
+
* - a replay of [5, 6, 7] leaves the latest factories untouched;
|
|
101
|
+
* - [5, 7] fails at expected sequence 6, keeps appliedSeq 4, and requests a complete rebuild.
|
|
102
|
+
*/
|
|
103
|
+
private applyPatchBatch;
|
|
104
|
+
/** Sends one application-frontier or rebuild report through the shared Vite WebSocket. */
|
|
105
|
+
private sendReport;
|
|
106
|
+
}
|
|
107
|
+
export {};
|
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const pageHmrStateKey = Symbol('vpt.pageHmrState');
|
|
11
|
-
/** Calls a native lifecycle with the same Page bound to `this` and the same arguments. */
|
|
12
|
-
function forward(handler, page, args) {
|
|
13
|
-
if (typeof handler === 'function')
|
|
14
|
-
handler.apply(page, args);
|
|
15
|
-
}
|
|
1
|
+
/*
|
|
2
|
+
* Shared WX HMR runtime, bundled into the mode-selected entry and injected into Rolldown's generated runtime chunk.
|
|
3
|
+
* Rolldown provides the lexical `DevRuntime` base class; this file extends that registry instead of duplicating module loading.
|
|
4
|
+
*
|
|
5
|
+
* Concrete modes decide how executable registrations arrive—native project JavaScript or interpreted source—and provide only a
|
|
6
|
+
* synchronous installer. This class owns the invariant that installation, graph propagation, cache eviction, boundary execution,
|
|
7
|
+
* and ACK form one application transaction; it has no file-delivery or interpreter policy of its own.
|
|
8
|
+
*/
|
|
9
|
+
import { runtimeControlEvent, runtimeReportEvent } from './wx-hmr-protocol.js';
|
|
16
10
|
/** Shared no-op CSS contract because physical rebuilds replace styles wholesale. */
|
|
17
11
|
const hotContextInternals = Object.freeze({
|
|
18
12
|
updateStyle() { },
|
|
@@ -62,13 +56,15 @@ class WxHotContext {
|
|
|
62
56
|
// rebuild replaces styles wholesale, so it is a no-op.
|
|
63
57
|
prune(_callback) { }
|
|
64
58
|
}
|
|
65
|
-
/**
|
|
66
|
-
class
|
|
59
|
+
/** Shared WX host mechanics extending the Rolldown contract instead of reimplementing it. */
|
|
60
|
+
export class WxHmrRuntime extends DevRuntime {
|
|
67
61
|
/**
|
|
68
|
-
* One session for this App heap. Undefined only before
|
|
69
|
-
*
|
|
62
|
+
* One session for this App heap. Undefined only before the mode-selected entry initializes the runtime; its identity then
|
|
63
|
+
* stays fixed while appliedSeq records the committed frontier.
|
|
70
64
|
*/
|
|
71
65
|
session;
|
|
66
|
+
/** The App heap's sole SocketTask, assigned once by initialize and retained for its lifetime. */
|
|
67
|
+
socket;
|
|
72
68
|
/**
|
|
73
69
|
* Sparse current-generation accepting boundaries keyed by module id. Entries alone must
|
|
74
70
|
* outlive Rolldown module-cache eviction so old callbacks can receive fresh exports.
|
|
@@ -159,112 +155,82 @@ class WxDevRuntime extends DevRuntime {
|
|
|
159
155
|
hotContext?.runAccept(this.initModule(moduleId));
|
|
160
156
|
}
|
|
161
157
|
}
|
|
162
|
-
/**
|
|
158
|
+
/**
|
|
159
|
+
* Initializes exactly once per App heap. Repeated entry evaluation must not replace the identity or reset `appliedSeq`, because
|
|
160
|
+
* either change could acknowledge factories against another host client or replay already committed application generations.
|
|
161
|
+
*/
|
|
163
162
|
initialize(info) {
|
|
164
163
|
if (this.session)
|
|
165
164
|
return;
|
|
166
|
-
this.session = {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
if (existingState) {
|
|
172
|
-
const mountedPage = existingState.mountedPage;
|
|
173
|
-
/*
|
|
174
|
-
* The static config can outlive a native Page instance. Before its first ordinary onLoad, or after a real onUnload,
|
|
175
|
-
* there is no mounted Page or current view-model to carry into another registration. Leave the lifecycle gate
|
|
176
|
-
* unarmed and preserve the config's existing initial data so a future real onLoad still enters Taro normally.
|
|
177
|
-
*/
|
|
178
|
-
if (!mountedPage) {
|
|
179
|
-
return config;
|
|
180
|
-
}
|
|
181
|
-
/*
|
|
182
|
-
* Arm the lifecycle wrappers on this exact static config before it is passed back to `Page(config)`. DevTools then
|
|
183
|
-
* triggers an unload/load/show sequence for that native re-registration: unload and load observe `true` and return
|
|
184
|
-
* before entering Taro, preserving the mounted React tree and its original Page connection; show consumes the
|
|
185
|
-
* one-shot gate by restoring `false`. Ordinary navigation never enters this branch, and every Page config owns an
|
|
186
|
-
* independent state object, so no route map, global phase, or Page identity comparison participates in the decision.
|
|
187
|
-
*/
|
|
188
|
-
existingState.isReregistering = true;
|
|
189
|
-
/*
|
|
190
|
-
* `Page(config)` reads `config.data` as the initial native view-model for this registration. Supplying the mounted
|
|
191
|
-
* Page's latest data before that call prevents the temporary Page used for re-registration callbacks from starting
|
|
192
|
-
* empty. This is an O(1) reference assignment in vpt: it does not clone the recursive data tree, call `setData`, move
|
|
193
|
-
* React state, or rebind Taro. The ordinary Taro lifecycle remains suppressed until re-registration onShow, so its
|
|
194
|
-
* React tree and output connection stay attached to `mountedPage`; every later registration reads its latest data.
|
|
195
|
-
*/
|
|
196
|
-
config.data = mountedPage.data;
|
|
197
|
-
return config;
|
|
198
|
-
}
|
|
199
|
-
const originalOnUnload = config.onUnload;
|
|
200
|
-
const originalOnLoad = config.onLoad;
|
|
201
|
-
const originalOnShow = config.onShow;
|
|
202
|
-
const state = {
|
|
203
|
-
isReregistering: false,
|
|
204
|
-
mountedPage: undefined
|
|
205
|
-
};
|
|
206
|
-
/*
|
|
207
|
-
* Attach the one mutable HMR state object to this exact static config. The lifecycle wrappers below close over the same
|
|
208
|
-
* object, while a later `injectPageHmr(config)` call finds it through the symbol and knows wrapping is already complete.
|
|
209
|
-
* A symbol cannot collide with WeChat or Taro's string-named Page options, and config-local ownership avoids route maps,
|
|
210
|
-
* a runtime-wide WeakMap, or state shared by two Page configs. The state becomes unreachable together with the config.
|
|
211
|
-
*/
|
|
212
|
-
config[pageHmrStateKey] = state;
|
|
213
|
-
config.onUnload = function (...args) {
|
|
214
|
-
if (state.isReregistering) {
|
|
165
|
+
this.session = { buildId: info.buildId, appliedSeq: 0 };
|
|
166
|
+
const socket = wx.connectSocket({ url: info.endpoint, protocols: ['vite-hmr'] });
|
|
167
|
+
this.socket = socket;
|
|
168
|
+
socket.onMessage(({ data }) => {
|
|
169
|
+
if (typeof data !== 'string')
|
|
215
170
|
return;
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
state.mountedPage = undefined;
|
|
219
|
-
};
|
|
220
|
-
config.onLoad = function (...args) {
|
|
221
|
-
if (state.isReregistering) {
|
|
171
|
+
const message = JSON.parse(data);
|
|
172
|
+
if (message.type !== 'custom' || !message.event)
|
|
222
173
|
return;
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
};
|
|
227
|
-
config.onShow = function (...args) {
|
|
228
|
-
if (state.isReregistering) {
|
|
229
|
-
state.isReregistering = false;
|
|
174
|
+
if (message.event === runtimeControlEvent) {
|
|
175
|
+
const control = message.data;
|
|
176
|
+
this.stopSocket(control.reason);
|
|
230
177
|
return;
|
|
231
178
|
}
|
|
232
|
-
|
|
233
|
-
};
|
|
234
|
-
return config;
|
|
179
|
+
this.onSocketEvent(info, message.event, message.data);
|
|
180
|
+
});
|
|
235
181
|
}
|
|
236
|
-
/**
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
182
|
+
/** Receives mode-specific Vite custom events after shared control messages have been handled. */
|
|
183
|
+
onSocketEvent(_info, _event, _data) { }
|
|
184
|
+
/** Sends one typed Vite custom event through the current App-level socket. */
|
|
185
|
+
sendSocketEvent(event, data) {
|
|
186
|
+
const socket = this.socket;
|
|
187
|
+
if (!socket) {
|
|
188
|
+
throw new Error('WX HMR socket is not initialized');
|
|
189
|
+
}
|
|
190
|
+
socket.send({ data: JSON.stringify({ type: 'custom', event: event, data: data }) });
|
|
191
|
+
}
|
|
192
|
+
/** Closes the sole socket after terminal host control or interpreter failure. */
|
|
193
|
+
stopSocket(reason) {
|
|
194
|
+
const socket = this.socket;
|
|
195
|
+
if (!socket) {
|
|
196
|
+
throw new Error('WX HMR socket is not initialized');
|
|
197
|
+
}
|
|
198
|
+
socket.close({ code: 1000, reason: reason });
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Applies one mode-delivered cumulative payload through its mode-specific patch installer.
|
|
202
|
+
*
|
|
203
|
+
* Application is deliberately synchronous so every later message observes the committed module generation. The installer is
|
|
204
|
+
* the only mode seam; sequence validation and ACK reporting stay here so no mode can mistake delivery for application.
|
|
205
|
+
*/
|
|
206
|
+
applyPatchPayload(payload, installPatch) {
|
|
241
207
|
const session = this.session;
|
|
242
208
|
if (!session || payload.buildId !== session.buildId) {
|
|
243
209
|
console.warn('[vpt] patches for a stale build');
|
|
244
|
-
return;
|
|
210
|
+
return false;
|
|
245
211
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
//
|
|
250
|
-
// the application frontier: publisher history is never pruned merely because its JavaScript file was observed.
|
|
212
|
+
const applied = this.applyPatchBatch(session, payload.patches, installPatch);
|
|
213
|
+
if (applied) {
|
|
214
|
+
// The host may publish later generations while synchronous application runs. Reporting only afterward makes this the
|
|
215
|
+
// application frontier: journal history is never pruned merely because a delivery became observable.
|
|
251
216
|
void this.sendReport({ kind: 'applied', seq: session.appliedSeq });
|
|
252
217
|
}
|
|
218
|
+
return applied;
|
|
253
219
|
}
|
|
254
220
|
/**
|
|
255
|
-
* Folds one cumulative
|
|
221
|
+
* Folds one cumulative mode delivery into a single logical HMR update.
|
|
256
222
|
*
|
|
257
|
-
*
|
|
258
|
-
*
|
|
259
|
-
* module generation to the latest published
|
|
223
|
+
* A delivery may contain several unacknowledged application patches and may be replayed by its mode—for DevTools, every
|
|
224
|
+
* affected live Page evaluates the same physical file. The runtime therefore ignores old sequences, rejects a missing one,
|
|
225
|
+
* and moves directly from the live module generation to the latest published one without intermediate renders.
|
|
260
226
|
*
|
|
261
227
|
* For an appliedSeq of 4:
|
|
262
228
|
*
|
|
263
|
-
* - [5, 6, 7]
|
|
264
|
-
* - a
|
|
265
|
-
* - [5, 7] fails at
|
|
229
|
+
* - [5, 6, 7] installs every patch, applies their unioned changedIds, commits appliedSeq 7, and reports 7;
|
|
230
|
+
* - a replay of [5, 6, 7] leaves the latest factories untouched;
|
|
231
|
+
* - [5, 7] fails at expected sequence 6, keeps appliedSeq 4, and requests a complete rebuild.
|
|
266
232
|
*/
|
|
267
|
-
applyPatchBatch(session, patches) {
|
|
233
|
+
applyPatchBatch(session, patches, installPatch) {
|
|
268
234
|
// Keep the initial watermark immutable throughout the fold. Comparing replays against a moving watermark would allow
|
|
269
235
|
// a duplicate new sequence in the same payload to masquerade as an already-applied patch.
|
|
270
236
|
const previousSeq = session.appliedSeq;
|
|
@@ -274,19 +240,19 @@ class WxDevRuntime extends DevRuntime {
|
|
|
274
240
|
const changedIds = new Set();
|
|
275
241
|
try {
|
|
276
242
|
for (const patch of patches) {
|
|
277
|
-
//
|
|
278
|
-
//
|
|
243
|
+
// Replayed delivery prefixes must not let an old installation overwrite newer factories already stored in the
|
|
244
|
+
// Rolldown runtime.
|
|
279
245
|
if (patch.seq <= previousSeq) {
|
|
280
246
|
continue;
|
|
281
247
|
}
|
|
282
|
-
// Every patch is incremental: if one
|
|
283
|
-
//
|
|
248
|
+
// Every patch is incremental: if one delivery was missed, later patches cannot reconstruct modules changed only
|
|
249
|
+
// by that missing sequence. Rebuilding is safer than silently running a mixed module generation.
|
|
284
250
|
if (patch.seq !== nextSeq) {
|
|
285
251
|
throw new Error(`missing patch sequence ${nextSeq}`);
|
|
286
252
|
}
|
|
287
|
-
//
|
|
288
|
-
//
|
|
289
|
-
patch
|
|
253
|
+
// Mode installation registers module graphs and factories without executing application modules. Running every
|
|
254
|
+
// installer first leaves the registry at the latest generation while avoiding intermediate renders.
|
|
255
|
+
installPatch(patch);
|
|
290
256
|
for (const changedId of patch.changedIds) {
|
|
291
257
|
changedIds.add(changedId);
|
|
292
258
|
}
|
|
@@ -298,7 +264,7 @@ class WxDevRuntime extends DevRuntime {
|
|
|
298
264
|
}
|
|
299
265
|
// Apply once after every factory is registered. React Refresh arms a newly executed module's hot.accept callback
|
|
300
266
|
// in a microtask; applying consecutive patches separately would inspect that intermediate context too early and
|
|
301
|
-
// incorrectly bubble through the capsule
|
|
267
|
+
// incorrectly bubble through the accepting capsule as though no HMR boundary existed.
|
|
302
268
|
this.applyHmrUpdate(changedIds);
|
|
303
269
|
// Commit application only after graph propagation and boundary callbacks succeed. A failure leaves the old watermark
|
|
304
270
|
// intact and requests a full rebuild below, so a partially applied batch is never acknowledged as healthy.
|
|
@@ -306,6 +272,8 @@ class WxDevRuntime extends DevRuntime {
|
|
|
306
272
|
return true;
|
|
307
273
|
}
|
|
308
274
|
catch (error) {
|
|
275
|
+
// An installer may already have replaced some factories and the module registry has no inverse operation. Keep the
|
|
276
|
+
// old application watermark unacknowledged and request a complete build, the only coherent rollback boundary.
|
|
309
277
|
console.warn('[vpt] patch batch failed; apply stopped', error);
|
|
310
278
|
void this.sendReport({
|
|
311
279
|
kind: 'rebuild',
|
|
@@ -314,7 +282,7 @@ class WxDevRuntime extends DevRuntime {
|
|
|
314
282
|
return false;
|
|
315
283
|
}
|
|
316
284
|
}
|
|
317
|
-
/** Sends one
|
|
285
|
+
/** Sends one application-frontier or rebuild report through the shared Vite WebSocket. */
|
|
318
286
|
sendReport(data) {
|
|
319
287
|
const session = this.session;
|
|
320
288
|
if (!session) {
|
|
@@ -322,22 +290,7 @@ class WxDevRuntime extends DevRuntime {
|
|
|
322
290
|
// silently dropping the sync traffic.
|
|
323
291
|
throw new Error('WX dev runtime is not initialized');
|
|
324
292
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
url: session.endpoint,
|
|
328
|
-
method: 'POST',
|
|
329
|
-
data: { buildId: session.buildId, ...data },
|
|
330
|
-
header: { 'content-type': 'application/json' },
|
|
331
|
-
success() {
|
|
332
|
-
resolve();
|
|
333
|
-
},
|
|
334
|
-
fail(error) {
|
|
335
|
-
reject(error);
|
|
336
|
-
}
|
|
337
|
-
});
|
|
338
|
-
});
|
|
293
|
+
const report = { buildId: session.buildId, ...data };
|
|
294
|
+
this.sendSocketEvent(runtimeReportEvent, report);
|
|
339
295
|
}
|
|
340
296
|
}
|
|
341
|
-
const runtime = new WxDevRuntime();
|
|
342
|
-
globalThis.__rolldown_runtime__ = runtime;
|
|
343
|
-
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-taro",
|
|
3
|
-
"version": "0.6.20
|
|
3
|
+
"version": "0.6.20",
|
|
4
4
|
"author": "sep2",
|
|
5
5
|
"description": "Vite 8 plugin for building one React/Taro codebase for WeChat Mini Program and H5 targets.",
|
|
6
6
|
"type": "module",
|
|
@@ -58,16 +58,17 @@
|
|
|
58
58
|
"@tailwindcss/vite": "4.3.3",
|
|
59
59
|
"@tarojs/components": "4.2.1",
|
|
60
60
|
"@tarojs/helper": "4.2.1",
|
|
61
|
-
"@tarojs/plugin-framework-react": "npm:vite-plugin-taro-plugin-framework-react@0.6.20
|
|
61
|
+
"@tarojs/plugin-framework-react": "npm:vite-plugin-taro-plugin-framework-react@0.6.20",
|
|
62
62
|
"@tarojs/plugin-platform-h5": "4.2.1",
|
|
63
63
|
"@tarojs/plugin-platform-weapp": "4.2.1",
|
|
64
|
-
"@tarojs/react": "npm:vite-plugin-taro-react@0.6.20
|
|
64
|
+
"@tarojs/react": "npm:vite-plugin-taro-react@0.6.20",
|
|
65
65
|
"@tarojs/router": "4.2.1",
|
|
66
|
-
"@tarojs/runtime": "npm:vite-plugin-taro-runtime@0.6.20
|
|
66
|
+
"@tarojs/runtime": "npm:vite-plugin-taro-runtime@0.6.20",
|
|
67
67
|
"@tarojs/taro": "4.2.1",
|
|
68
68
|
"@vitejs/plugin-react": "^6.1.0",
|
|
69
69
|
"react-reconciler": "0.33.0",
|
|
70
70
|
"rolldown": "1.2.5",
|
|
71
|
+
"sval": "0.6.12",
|
|
71
72
|
"tailwindcss": "^4.3.3"
|
|
72
73
|
},
|
|
73
74
|
"peerDependencies": {
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { type PatchUpdate } from './hmr-files.ts';
|
|
2
|
-
/** Abstracts the physical patches write; the engine owns the file destination. */
|
|
3
|
-
type WritePatches = (content: string) => Promise<void>;
|
|
4
|
-
/**
|
|
5
|
-
* Owns the cumulative sequence range between the host's published frontier and the runtime's applied frontier.
|
|
6
|
-
*
|
|
7
|
-
* For example, if the runtime has applied sequence 4:
|
|
8
|
-
*
|
|
9
|
-
* 1. produce([5, 6]) writes [5, 6];
|
|
10
|
-
* 2. produce([7]) before an application report writes [5, 6, 7], so DevTools may miss the first file event safely;
|
|
11
|
-
* 3. acknowledge(6) retains [7];
|
|
12
|
-
* 4. produce([8]) then writes [7, 8], exactly the suffix the runtime still needs.
|
|
13
|
-
*
|
|
14
|
-
* The host may advance Rolldown's published frontier through 8 immediately after those writes, but this history is pruned only
|
|
15
|
-
* through 6 until the runtime reports successful application. Published sequence and applied sequence are deliberately distinct.
|
|
16
|
-
*/
|
|
17
|
-
export declare class PatchPublisher {
|
|
18
|
-
private readonly writePatches;
|
|
19
|
-
private buildId;
|
|
20
|
-
private readonly pendingPatches;
|
|
21
|
-
constructor(writePatches: WritePatches);
|
|
22
|
-
/** True when the buildId belongs to the current full build. */
|
|
23
|
-
isCurrentBuild(buildId: string): boolean;
|
|
24
|
-
/** Begins a fresh build and returns both sides of the client-session rotation. */
|
|
25
|
-
startBuild(): Readonly<{
|
|
26
|
-
buildId: string;
|
|
27
|
-
previousBuildId: string | undefined;
|
|
28
|
-
}>;
|
|
29
|
-
/**
|
|
30
|
-
* Appends a Rolldown batch and publishes the complete range not yet applied by the runtime.
|
|
31
|
-
*
|
|
32
|
-
* Resolution means the cumulative JavaScript generation is physically visible. The host may then advance Rolldown's
|
|
33
|
-
* published frontier immediately; pendingPatches remains intact until an application report proves the runtime caught up.
|
|
34
|
-
*/
|
|
35
|
-
produce(patches: readonly PatchUpdate[]): Promise<void>;
|
|
36
|
-
/**
|
|
37
|
-
* Removes only the prefix covered by the runtime's successful application frontier. Publication alone never calls this:
|
|
38
|
-
* retaining the gap between published and applied frontiers is what lets DevTools safely miss intermediate file events.
|
|
39
|
-
*/
|
|
40
|
-
acknowledge(seq: number): void;
|
|
41
|
-
}
|
|
42
|
-
export {};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { type SchedulerLike, Subject } from 'rxjs';
|
|
2
|
-
type AppliedReport = Readonly<{
|
|
3
|
-
kind: 'applied';
|
|
4
|
-
buildId: string;
|
|
5
|
-
seq: number;
|
|
6
|
-
}>;
|
|
7
|
-
/** The runtime hit an unrecoverable state and needs a complete build. */
|
|
8
|
-
type RebuildReport = Readonly<{
|
|
9
|
-
kind: 'rebuild';
|
|
10
|
-
buildId: string;
|
|
11
|
-
reason: string;
|
|
12
|
-
}>;
|
|
13
|
-
export type RuntimeReport = AppliedReport | RebuildReport;
|
|
14
|
-
/**
|
|
15
|
-
* Conflates runtime receipts without weakening their build identity or recovery semantics.
|
|
16
|
-
*
|
|
17
|
-
* Reports are metadata frontiers rather than executable deltas: for one build, the highest applied sequence subsumes lower and
|
|
18
|
-
* duplicate acknowledgements. A rebuild does not subsume reports from a different build, because delayed Pages may still POST
|
|
19
|
-
* after session rotation, but it dominates every acknowledgement for its own build. The host validates each retained build ID
|
|
20
|
-
* against the physical publisher only when its serialized task executes, preserving rotation order.
|
|
21
|
-
*
|
|
22
|
-
* Completing the Subject flushes the active window synchronously so shutdown can include its host task before closing Rolldown.
|
|
23
|
-
* Reduction is O(reports) time and O(distinct builds) retained space per quiet window.
|
|
24
|
-
*/
|
|
25
|
-
export declare function createRuntimeReportsStream(settleMilliseconds: number, scheduler: SchedulerLike, publish: (reports: readonly RuntimeReport[]) => void): Subject<RuntimeReport>;
|
|
26
|
-
export declare function reduceRuntimeReportWindow(window: readonly RuntimeReport[]): readonly RuntimeReport[];
|
|
27
|
-
export {};
|
|
File without changes
|