vite-plugin-taro 0.3.2 → 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.
- package/README.en.md +44 -0
- package/README.md +22 -497
- package/client.d.ts +9 -0
- package/dist/node/plugins/client/client-taro.d.ts +4 -0
- package/dist/node/plugins/client/client-taro.js +19 -0
- package/dist/node/plugins/client/constant.d.ts +4 -0
- package/dist/node/plugins/client/constant.js +4 -0
- package/dist/node/plugins/conditional/conditional-directives.d.ts +4 -0
- package/dist/node/plugins/{conditional-directives.js → conditional/conditional-directives.js} +27 -11
- package/dist/node/plugins/css/plugins.d.ts +4 -0
- package/dist/node/plugins/css/plugins.js +84 -0
- package/dist/node/plugins/h5/constant.d.ts +2 -0
- package/dist/node/plugins/h5/constant.js +3 -0
- package/dist/node/plugins/h5/plugins.d.ts +4 -0
- package/dist/node/plugins/h5/plugins.js +161 -0
- package/dist/node/plugins/h5/resolver/module-resolver.d.ts +14 -0
- package/dist/node/plugins/h5/resolver/module-resolver.js +19 -0
- package/dist/node/plugins/h5/transform-app.d.ts +10 -0
- package/dist/node/plugins/h5/transform-app.js +48 -0
- package/dist/node/plugins/wx/dev/dev-host.d.ts +15 -0
- package/dist/node/plugins/wx/dev/dev-host.js +352 -0
- package/dist/node/plugins/wx/dev/hmr-files.d.ts +28 -0
- package/dist/node/plugins/wx/dev/hmr-files.js +34 -0
- package/dist/node/plugins/wx/dev/patch-publisher.d.ts +22 -0
- package/dist/node/plugins/wx/dev/patch-publisher.js +40 -0
- package/dist/node/plugins/wx/dev/plugin.d.ts +7 -0
- package/dist/node/plugins/wx/dev/plugin.js +73 -0
- package/dist/node/plugins/wx/dev/react-refresh.d.ts +20 -0
- package/dist/node/plugins/wx/dev/react-refresh.js +198 -0
- package/dist/node/plugins/wx/module.d.ts +45 -0
- package/dist/node/plugins/wx/module.js +66 -0
- package/dist/node/plugins/wx/native/compile-native-component-interface.d.ts +21 -0
- package/dist/node/plugins/wx/native/compile-native-component-interface.js +29 -0
- package/dist/node/plugins/wx/native/create-native-component-output.d.ts +15 -0
- package/dist/node/plugins/wx/native/create-native-component-output.js +39 -0
- package/dist/node/plugins/wx/native/native-component-assets.d.ts +26 -0
- package/dist/node/plugins/wx/native/native-component-assets.js +76 -0
- package/dist/node/plugins/wx/native/native-component-interface.d.ts +12 -0
- package/dist/node/plugins/wx/native/native-component-interface.js +201 -0
- package/dist/node/plugins/wx/output/files.d.ts +12 -0
- package/dist/node/plugins/wx/output/files.js +12 -0
- package/dist/node/plugins/wx/output/json.d.ts +14 -0
- package/dist/node/plugins/wx/output/json.js +52 -0
- package/dist/node/plugins/wx/output/relative-root.d.ts +2 -0
- package/dist/node/plugins/wx/output/relative-root.js +6 -0
- package/dist/node/plugins/wx/output/templates.d.ts +7 -0
- package/dist/node/plugins/wx/output/templates.js +100 -0
- package/dist/node/plugins/wx/placement/placer.d.ts +78 -0
- package/dist/node/plugins/wx/placement/placer.js +145 -0
- package/dist/node/plugins/wx/placement/plan.d.ts +46 -0
- package/dist/node/plugins/wx/placement/plan.js +210 -0
- package/dist/node/plugins/wx/plugins.d.ts +4 -0
- package/dist/node/plugins/wx/plugins.js +137 -0
- package/dist/node/plugins/wx/render/capsule-wrapper.d.ts +3 -0
- package/dist/node/plugins/wx/render/capsule-wrapper.js +64 -0
- package/dist/node/plugins/wx/render/capsule.d.ts +4 -0
- package/dist/node/plugins/wx/render/capsule.js +13 -0
- package/dist/node/plugins/wx/render/native.d.ts +9 -0
- package/dist/node/plugins/wx/render/native.js +45 -0
- package/dist/node/plugins/wx/render/transport.d.ts +17 -0
- package/dist/node/plugins/wx/render/transport.js +94 -0
- package/dist/node/plugins/wx/resolve/resolver.d.ts +7 -0
- package/dist/node/plugins/wx/resolve/resolver.js +86 -0
- package/dist/node/plugins/wx/resolve/specialize-bootstrap.d.ts +9 -0
- package/dist/node/plugins/wx/resolve/specialize-bootstrap.js +9 -0
- package/dist/node/plugins/wx/resolve/specialize-page-capsule.d.ts +9 -0
- package/dist/node/plugins/wx/resolve/specialize-page-capsule.js +11 -0
- package/dist/node/utils/constant.d.ts +1 -0
- package/dist/node/utils/constant.js +1 -0
- package/dist/node/utils/memoize.d.ts +122 -0
- package/dist/node/utils/memoize.js +86 -0
- package/dist/node/utils/modules.d.ts +20 -24
- package/dist/node/utils/modules.js +21 -34
- package/dist/node/utils/once.d.ts +10 -0
- package/dist/node/utils/once.js +20 -0
- package/dist/node/utils/packages.d.ts +1 -0
- package/dist/node/utils/packages.js +1 -1
- package/dist/node/utils/project-config.d.ts +3 -0
- package/dist/node/utils/project-config.js +8 -0
- package/dist/node/utils/serialized-task-queue.d.ts +9 -0
- package/dist/node/utils/serialized-task-queue.js +17 -0
- package/dist/node/utils/transform.d.ts +11 -0
- package/dist/node/utils/transform.js +58 -0
- package/dist/node/vite-plugin.d.ts +1 -1
- package/dist/node/vite-plugin.js +11 -27
- package/dist/options.d.ts +3 -4
- package/dist/runtime/{taro → client/taro}/api.d.ts +0 -1
- package/dist/runtime/client/taro/api.js +9 -0
- package/dist/runtime/client/taro/component.d.ts +1 -0
- package/dist/runtime/client/taro/component.js +1 -0
- package/dist/runtime/client/taro/define-native-component.d.ts +7 -0
- package/dist/runtime/client/taro/define-native-component.js +4 -0
- package/dist/runtime/h5/app.d.ts +2 -0
- package/dist/runtime/h5/app.js +15 -0
- package/dist/runtime/h5/taro-runtime.d.ts +1 -1
- package/dist/runtime/h5/taro-runtime.js +1 -4
- package/dist/runtime/wx/amphibious/bootstrap.d.ts +4 -0
- package/dist/runtime/wx/amphibious/bootstrap.js +16 -0
- package/dist/runtime/wx/amphibious/transport.d.ts +2 -0
- package/dist/runtime/wx/amphibious/transport.js +4 -0
- package/dist/runtime/wx/capsule/app.d.ts +2 -0
- package/dist/runtime/wx/capsule/app.js +7 -0
- package/dist/runtime/wx/capsule/component.d.ts +3 -0
- package/dist/runtime/wx/capsule/component.js +4 -0
- package/dist/runtime/wx/capsule/page.d.ts +3 -0
- package/dist/runtime/wx/capsule/page.js +68 -0
- package/dist/runtime/wx/capsule/taro-runtime.d.ts +6 -0
- package/dist/runtime/wx/capsule/taro-runtime.js +6 -0
- package/dist/runtime/wx/dev/dev-runtime.d.ts +1 -0
- package/dist/runtime/wx/dev/dev-runtime.js +246 -0
- package/dist/runtime/wx/native/app.d.ts +1 -0
- package/dist/runtime/wx/native/app.js +3 -0
- package/dist/runtime/wx/native/component.d.ts +1 -0
- package/dist/runtime/wx/native/component.js +3 -0
- package/dist/runtime/wx/native/page.d.ts +1 -0
- package/dist/runtime/wx/native/page.js +4 -0
- package/dist/runtime/wx/systemjs/system-core.d.ts +4 -0
- package/dist/runtime/wx/systemjs/system-core.js +331 -0
- package/package.json +21 -14
- package/src/node/plugins/client/client-taro.ts +23 -0
- package/src/node/plugins/client/constant.ts +5 -0
- package/src/node/plugins/{conditional-directives.ts → conditional/conditional-directives.ts} +33 -13
- package/src/node/plugins/css/plugins.ts +96 -0
- package/src/node/plugins/h5/constant.ts +4 -0
- package/src/node/plugins/h5/plugins.ts +197 -0
- package/src/node/plugins/h5/resolver/module-resolver.ts +32 -0
- package/src/node/plugins/h5/transform-app.ts +90 -0
- package/src/node/plugins/wx/dev/dev-host.ts +448 -0
- package/src/node/plugins/wx/dev/hmr-files.ts +55 -0
- package/src/node/plugins/wx/dev/patch-publisher.ts +49 -0
- package/src/node/plugins/wx/dev/plugin.ts +82 -0
- package/src/node/plugins/wx/dev/react-refresh.ts +227 -0
- package/src/node/plugins/wx/module.ts +97 -0
- package/src/node/plugins/wx/native/compile-native-component-interface.ts +47 -0
- package/src/node/plugins/wx/native/create-native-component-output.ts +57 -0
- package/src/node/plugins/wx/native/native-component-assets.ts +114 -0
- package/src/node/plugins/wx/native/native-component-interface.ts +265 -0
- package/src/node/plugins/wx/output/files.ts +27 -0
- package/src/node/plugins/wx/output/json.ts +79 -0
- package/src/node/plugins/wx/output/relative-root.ts +7 -0
- package/src/node/plugins/wx/output/templates.ts +141 -0
- package/src/node/plugins/wx/placement/placer.ts +172 -0
- package/src/node/plugins/wx/placement/plan.ts +306 -0
- package/src/node/plugins/wx/plugins.ts +165 -0
- package/src/node/plugins/wx/render/capsule-wrapper.ts +86 -0
- package/src/node/plugins/wx/render/capsule.ts +21 -0
- package/src/node/plugins/wx/render/native.ts +84 -0
- package/src/node/plugins/wx/render/transport.ts +157 -0
- package/src/node/plugins/wx/resolve/resolver.ts +125 -0
- package/src/node/plugins/wx/resolve/specialize-bootstrap.ts +27 -0
- package/src/node/plugins/wx/resolve/specialize-page-capsule.ts +29 -0
- package/src/node/utils/constant.ts +1 -0
- package/src/node/utils/memoize.ts +149 -0
- package/src/node/utils/modules.ts +36 -38
- package/src/node/utils/once.ts +21 -0
- package/src/node/utils/packages.ts +1 -1
- package/src/node/utils/project-config.ts +10 -0
- package/src/node/utils/serialized-task-queue.ts +20 -0
- package/src/node/utils/transform.ts +82 -0
- package/src/node/vite-plugin.ts +12 -32
- package/src/options.ts +3 -4
- package/src/runtime/client/taro/api.ts +11 -0
- package/src/runtime/client/taro/component.ts +1 -0
- package/src/runtime/client/taro/define-native-component.ts +15 -0
- package/src/runtime/h5/app.ts +25 -0
- package/src/runtime/h5/taro-runtime.ts +1 -4
- package/src/runtime/wx/amphibious/bootstrap.ts +22 -0
- package/src/runtime/wx/amphibious/transport.ts +10 -0
- package/src/runtime/wx/capsule/app.ts +9 -0
- package/src/runtime/wx/capsule/component.ts +6 -0
- package/src/runtime/wx/capsule/page.ts +96 -0
- package/src/runtime/wx/capsule/taro-runtime.ts +14 -0
- package/src/runtime/wx/dev/dev-runtime.ts +317 -0
- package/src/runtime/wx/native/app.ts +4 -0
- package/src/runtime/wx/native/component.ts +4 -0
- package/src/runtime/wx/native/page.ts +6 -0
- package/src/runtime/wx/systemjs/LICENSE +10 -0
- package/src/runtime/wx/systemjs/system-core.js +370 -0
- package/src/runtime/wx/systemjs/system.d.ts +55 -0
- package/src/runtime/wx/wechat.d.ts +52 -0
- package/README.zh.md +0 -521
- package/dist/node/build-context.d.ts +0 -25
- package/dist/node/build-context.js +0 -47
- package/dist/node/css/css-pipeline.d.ts +0 -35
- package/dist/node/css/css-pipeline.js +0 -154
- package/dist/node/plugins/conditional-directives.d.ts +0 -3
- package/dist/node/plugins/taro-runtime.d.ts +0 -5
- package/dist/node/plugins/taro-runtime.js +0 -18
- package/dist/node/targets/h5/plugin.d.ts +0 -6
- package/dist/node/targets/h5/plugin.js +0 -117
- package/dist/node/targets/h5/virtual-modules.d.ts +0 -5
- package/dist/node/targets/h5/virtual-modules.js +0 -60
- package/dist/node/targets/wx/companion-assets.d.ts +0 -19
- package/dist/node/targets/wx/companion-assets.js +0 -129
- package/dist/node/targets/wx/dev-server/development-session.d.ts +0 -32
- package/dist/node/targets/wx/dev-server/development-session.js +0 -215
- package/dist/node/targets/wx/dev-server/full-build-scheduler.d.ts +0 -14
- package/dist/node/targets/wx/dev-server/full-build-scheduler.js +0 -60
- package/dist/node/targets/wx/dev-server/js-utils.d.ts +0 -5
- package/dist/node/targets/wx/dev-server/js-utils.js +0 -28
- package/dist/node/targets/wx/dev-server/output.d.ts +0 -19
- package/dist/node/targets/wx/dev-server/output.js +0 -44
- package/dist/node/targets/wx/dev-server/rolldown-runtime-source.d.ts +0 -8
- package/dist/node/targets/wx/dev-server/rolldown-runtime-source.js +0 -95
- package/dist/node/targets/wx/dev-server/update-server-state.d.ts +0 -65
- package/dist/node/targets/wx/dev-server/update-server-state.js +0 -116
- package/dist/node/targets/wx/dev-server/update-transport.d.ts +0 -28
- package/dist/node/targets/wx/dev-server/update-transport.js +0 -212
- package/dist/node/targets/wx/dev-server/vite-bundled-dev-adapter.d.ts +0 -44
- package/dist/node/targets/wx/dev-server/vite-bundled-dev-adapter.js +0 -145
- package/dist/node/targets/wx/development-files.d.ts +0 -8
- package/dist/node/targets/wx/development-files.js +0 -8
- package/dist/node/targets/wx/plugin.d.ts +0 -6
- package/dist/node/targets/wx/plugin.js +0 -144
- package/dist/node/targets/wx/react-refresh.d.ts +0 -4
- package/dist/node/targets/wx/react-refresh.js +0 -38
- package/dist/node/targets/wx/virtual-modules.d.ts +0 -16
- package/dist/node/targets/wx/virtual-modules.js +0 -120
- package/dist/node/utils/async.d.ts +0 -8
- package/dist/node/utils/async.js +0 -16
- package/dist/node/utils/filesystem.d.ts +0 -13
- package/dist/node/utils/filesystem.js +0 -43
- package/dist/runtime/taro/api.js +0 -11
- package/dist/runtime/taro/components.d.ts +0 -2
- package/dist/runtime/taro/components.js +0 -2
- package/dist/runtime/wx/page-update.d.ts +0 -6
- package/dist/runtime/wx/page-update.js +0 -157
- package/dist/runtime/wx/taro-runtime.d.ts +0 -5
- package/dist/runtime/wx/taro-runtime.js +0 -6
- package/dist/runtime/wx/update-client-state.d.ts +0 -68
- package/dist/runtime/wx/update-client-state.js +0 -84
- package/dist/runtime/wx/update-client.d.ts +0 -1
- package/dist/runtime/wx/update-client.js +0 -171
- package/src/node/build-context.ts +0 -62
- package/src/node/css/css-pipeline.ts +0 -171
- package/src/node/plugins/taro-runtime.ts +0 -22
- package/src/node/targets/h5/plugin.ts +0 -135
- package/src/node/targets/h5/virtual-modules.ts +0 -71
- package/src/node/targets/wx/companion-assets.ts +0 -174
- package/src/node/targets/wx/dev-server/development-session.ts +0 -271
- package/src/node/targets/wx/dev-server/full-build-scheduler.ts +0 -62
- package/src/node/targets/wx/dev-server/js-utils.ts +0 -33
- package/src/node/targets/wx/dev-server/output.ts +0 -56
- package/src/node/targets/wx/dev-server/rolldown-runtime-source.ts +0 -95
- package/src/node/targets/wx/dev-server/update-server-state.ts +0 -183
- package/src/node/targets/wx/dev-server/update-transport.ts +0 -261
- package/src/node/targets/wx/dev-server/vite-bundled-dev-adapter.ts +0 -203
- package/src/node/targets/wx/development-files.ts +0 -11
- package/src/node/targets/wx/plugin.ts +0 -164
- package/src/node/targets/wx/react-refresh.ts +0 -51
- package/src/node/targets/wx/virtual-modules.ts +0 -152
- package/src/node/utils/async.ts +0 -19
- package/src/node/utils/filesystem.ts +0 -45
- package/src/runtime/taro/api.ts +0 -13
- package/src/runtime/taro/components.ts +0 -2
- package/src/runtime/wx/page-update.ts +0 -230
- package/src/runtime/wx/react-refresh.d.ts +0 -20
- package/src/runtime/wx/taro-runtime.ts +0 -7
- package/src/runtime/wx/update-client-state.ts +0 -138
- package/src/runtime/wx/update-client.ts +0 -223
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
/** Full-build scheduling owned by one WX development session. */
|
|
2
|
-
|
|
3
|
-
type FullBuildPhase = 'idle' | 'scheduled' | 'building' | 'building-with-pending-request' | 'closed'
|
|
4
|
-
|
|
5
|
-
/** Coalesces trailing-edge requests while guaranteeing one full build at a time. */
|
|
6
|
-
export class FullBuildScheduler {
|
|
7
|
-
private readonly delay: number
|
|
8
|
-
private readonly runBuild: () => Promise<void>
|
|
9
|
-
private readonly reportError: (error: unknown) => void
|
|
10
|
-
private phase: FullBuildPhase = 'idle'
|
|
11
|
-
private timer: NodeJS.Timeout | undefined
|
|
12
|
-
private work: Promise<void> | undefined
|
|
13
|
-
|
|
14
|
-
constructor(delay: number, runBuild: () => Promise<void>, reportError: (error: unknown) => void) {
|
|
15
|
-
this.delay = delay
|
|
16
|
-
this.runBuild = runBuild
|
|
17
|
-
this.reportError = reportError
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
request(): void {
|
|
21
|
-
switch (this.phase) {
|
|
22
|
-
case 'closed':
|
|
23
|
-
return
|
|
24
|
-
case 'building':
|
|
25
|
-
this.phase = 'building-with-pending-request'
|
|
26
|
-
return
|
|
27
|
-
case 'building-with-pending-request':
|
|
28
|
-
return
|
|
29
|
-
case 'idle':
|
|
30
|
-
case 'scheduled':
|
|
31
|
-
if (this.timer) clearTimeout(this.timer)
|
|
32
|
-
this.phase = 'scheduled'
|
|
33
|
-
this.timer = setTimeout(() => this.start(), this.delay)
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async close(): Promise<void> {
|
|
38
|
-
if (this.phase === 'closed') {
|
|
39
|
-
await this.work
|
|
40
|
-
return
|
|
41
|
-
}
|
|
42
|
-
this.phase = 'closed'
|
|
43
|
-
if (this.timer) clearTimeout(this.timer)
|
|
44
|
-
this.timer = undefined
|
|
45
|
-
await this.work
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
private start(): void {
|
|
49
|
-
if (this.phase !== 'scheduled') return
|
|
50
|
-
this.timer = undefined
|
|
51
|
-
this.phase = 'building'
|
|
52
|
-
this.work = this.runBuild()
|
|
53
|
-
.catch(this.reportError)
|
|
54
|
-
.finally(() => {
|
|
55
|
-
this.work = undefined
|
|
56
|
-
if (this.phase === 'closed') return
|
|
57
|
-
const repeat = this.phase === 'building-with-pending-request'
|
|
58
|
-
this.phase = 'idle'
|
|
59
|
-
if (repeat) this.request()
|
|
60
|
-
})
|
|
61
|
-
}
|
|
62
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { transformWithOxc } from 'vite'
|
|
2
|
-
import type { WxOutputFile } from './output.ts'
|
|
3
|
-
|
|
4
|
-
const wxJavaScriptTarget = 'es2018'
|
|
5
|
-
|
|
6
|
-
/** Lowers generated JavaScript syntax that WeChat's upload parser does not accept. */
|
|
7
|
-
export async function transformWxCompatibleJavaScript(code: string, filename: string): Promise<string> {
|
|
8
|
-
const result = await transformWithOxc(code, filename, {
|
|
9
|
-
lang: 'js',
|
|
10
|
-
target: wxJavaScriptTarget,
|
|
11
|
-
sourcemap: false,
|
|
12
|
-
assumptions: {
|
|
13
|
-
// Avoid external Oxc helpers when lowering public class fields in already-bundled chunks.
|
|
14
|
-
setPublicClassFields: true
|
|
15
|
-
}
|
|
16
|
-
})
|
|
17
|
-
return result.code
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/** Applies the compatibility transform to every JavaScript chunk in a DevEngine output batch. */
|
|
21
|
-
export async function transformWxOutputChunks(output: WxOutputFile[]): Promise<void> {
|
|
22
|
-
await Promise.all(
|
|
23
|
-
output.map(async (item, index) => {
|
|
24
|
-
if (item.type !== 'chunk') return
|
|
25
|
-
output[index] = {
|
|
26
|
-
type: 'chunk',
|
|
27
|
-
fileName: item.fileName,
|
|
28
|
-
modules: item.modules,
|
|
29
|
-
code: await transformWxCompatibleJavaScript(item.code, item.fileName)
|
|
30
|
-
}
|
|
31
|
-
})
|
|
32
|
-
)
|
|
33
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Normalizes private DevEngine output before the development session writes it to the fixed WX project directory.
|
|
3
|
-
* DevEngine rebuilds may be partial, so these helpers mutate only files present in the current output.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/** File shape emitted by Vite's private bundled-development engine. */
|
|
7
|
-
export type WxOutputFile =
|
|
8
|
-
| {
|
|
9
|
-
type: 'chunk'
|
|
10
|
-
fileName: string
|
|
11
|
-
code: string
|
|
12
|
-
modules?: Record<string, unknown>
|
|
13
|
-
}
|
|
14
|
-
| {
|
|
15
|
-
type: 'asset'
|
|
16
|
-
fileName: string
|
|
17
|
-
source: string | Uint8Array
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/** Extracts Vite's development CSS payloads and materializes them as app.wxss. */
|
|
21
|
-
export function normalizeWxBundleStyles(output: WxOutputFile[]): string | undefined {
|
|
22
|
-
const styles: string[] = []
|
|
23
|
-
for (let index = output.length - 1; index >= 0; index--) {
|
|
24
|
-
const item = output[index]
|
|
25
|
-
if (!item) continue
|
|
26
|
-
if (item.type === 'asset' && item.fileName.endsWith('.css')) {
|
|
27
|
-
styles.unshift(typeof item.source === 'string' ? item.source : new TextDecoder().decode(item.source))
|
|
28
|
-
output.splice(index, 1)
|
|
29
|
-
} else if (item.type === 'chunk') {
|
|
30
|
-
styles.push(...collectEmbeddedStyles(item.code))
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
if (styles.length === 0) return
|
|
34
|
-
const source = styles.join('\n')
|
|
35
|
-
setWxAppStyles(output, source)
|
|
36
|
-
return source
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function setWxAppStyles(output: WxOutputFile[], source: string): void {
|
|
40
|
-
const index = output.findIndex((item) => item.type === 'asset' && item.fileName === 'app.wxss')
|
|
41
|
-
const appStyle: WxOutputFile = { type: 'asset', fileName: 'app.wxss', source }
|
|
42
|
-
if (index >= 0) output[index] = appStyle
|
|
43
|
-
else output.push(appStyle)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function isWxFullBuildOutput(output: WxOutputFile[]): boolean {
|
|
47
|
-
return output.some((item) => item.fileName === 'app.js')
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function collectEmbeddedStyles(code: string): string[] {
|
|
51
|
-
const styles: string[] = []
|
|
52
|
-
for (const match of code.matchAll(/__vite__css(?:\$\d+)?\s*=\s*("(?:\\.|[^"\\])*");/g)) {
|
|
53
|
-
if (match[1]) styles.push(JSON.parse(match[1]) as string)
|
|
54
|
-
}
|
|
55
|
-
return styles
|
|
56
|
-
}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Self-contained source injected into Rolldown's DevEngine as the WX module bootstrap runtime.
|
|
3
|
-
*
|
|
4
|
-
* This TypeScript module runs in Node and only exports source text. The exported JavaScript becomes
|
|
5
|
-
* `runtime.js`, executes before every application module, and therefore cannot import Taro, React,
|
|
6
|
-
* or any module that depends on the runtime it is creating.
|
|
7
|
-
*/
|
|
8
|
-
export const wxRolldownRuntimeSource = `
|
|
9
|
-
var BaseDevRuntime = DevRuntime;
|
|
10
|
-
class WxHotContext {
|
|
11
|
-
callbacks = [];
|
|
12
|
-
data = {};
|
|
13
|
-
_internal = { updateStyle() {}, removeStyle() {} };
|
|
14
|
-
constructor(moduleId) { this.moduleId = moduleId; }
|
|
15
|
-
accept(...args) {
|
|
16
|
-
if (args.length === 0) {
|
|
17
|
-
this.callbacks.push({ deps: this.moduleId, callback: undefined });
|
|
18
|
-
} else if (args.length === 1 && typeof args[0] === 'function') {
|
|
19
|
-
this.callbacks.push({ deps: this.moduleId, callback: args[0] });
|
|
20
|
-
} else if (args.length === 1) {
|
|
21
|
-
this.callbacks.push({ deps: args[0], callback: undefined });
|
|
22
|
-
} else {
|
|
23
|
-
this.callbacks.push({ deps: args[0], callback: args[1] });
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
acceptExports(_exports, callback) { this.accept(callback); }
|
|
27
|
-
dispose() {}
|
|
28
|
-
prune() {}
|
|
29
|
-
invalidate() {}
|
|
30
|
-
on() {}
|
|
31
|
-
off() {}
|
|
32
|
-
send() {}
|
|
33
|
-
}
|
|
34
|
-
class WxRolldownRuntime extends BaseDevRuntime {
|
|
35
|
-
contexts = new Map();
|
|
36
|
-
patchedModules = new Set();
|
|
37
|
-
applyingPatch = false;
|
|
38
|
-
|
|
39
|
-
createEsmInitializer = (id, initialize, _deduplicate, result) => () => {
|
|
40
|
-
if (!initialize) return result;
|
|
41
|
-
if (!this.applyingPatch && this.patchedModules.has(id)) {
|
|
42
|
-
initialize = undefined;
|
|
43
|
-
return result;
|
|
44
|
-
}
|
|
45
|
-
const callback = initialize;
|
|
46
|
-
initialize = undefined;
|
|
47
|
-
result = callback(id);
|
|
48
|
-
if (this.applyingPatch) this.patchedModules.add(id);
|
|
49
|
-
return result;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
createCjsInitializer = (id, initialize, _deduplicate, module) => () => {
|
|
53
|
-
if (module) return module.exports;
|
|
54
|
-
if (!this.applyingPatch && this.patchedModules.has(id)) return this.loadExports(id);
|
|
55
|
-
module = { exports: {} };
|
|
56
|
-
initialize(module.exports, module, id);
|
|
57
|
-
if (this.applyingPatch) this.patchedModules.add(id);
|
|
58
|
-
return module.exports;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
createModuleHotContext(moduleId) {
|
|
62
|
-
const previous = this.contexts.get(moduleId);
|
|
63
|
-
const context = new WxHotContext(moduleId);
|
|
64
|
-
if (previous) {
|
|
65
|
-
context.callbacks = previous.callbacks;
|
|
66
|
-
context.data = previous.data;
|
|
67
|
-
}
|
|
68
|
-
this.contexts.set(moduleId, context);
|
|
69
|
-
return context;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
beginPatch() { this.applyingPatch = true; }
|
|
73
|
-
endPatch() { this.applyingPatch = false; }
|
|
74
|
-
|
|
75
|
-
applyUpdates(boundaries) {
|
|
76
|
-
for (const [boundary, acceptedVia] of boundaries) {
|
|
77
|
-
const context = this.contexts.get(boundary);
|
|
78
|
-
if (!context) continue;
|
|
79
|
-
const callbacks = [...context.callbacks];
|
|
80
|
-
if (boundary === acceptedVia) context.callbacks = [];
|
|
81
|
-
for (const { deps, callback } of callbacks) {
|
|
82
|
-
if (!callback) continue;
|
|
83
|
-
if (Array.isArray(deps)) {
|
|
84
|
-
if (deps.includes(acceptedVia)) callback(deps.map((id) => this.loadExports(id)));
|
|
85
|
-
} else if (deps === acceptedVia) {
|
|
86
|
-
callback(this.loadExports(acceptedVia));
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
// A full DevEngine runtime starts a new page-update generation before any application chunk executes.
|
|
93
|
-
globalThis.__VITE_PLUGIN_TARO_WX_PAGE_UPDATE__ = { ready: false };
|
|
94
|
-
globalThis.__rolldown_runtime__ = new WxRolldownRuntime(undefined, 'vite-plugin-taro-wx');
|
|
95
|
-
`
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pure host-side stop-and-wait protocol state machine.
|
|
3
|
-
*
|
|
4
|
-
* It retains versioned Rolldown deltas and selects one missing range for the active App Service. HTTP and filesystem
|
|
5
|
-
* effects are represented as commands and handled by update-transport.ts.
|
|
6
|
-
*/
|
|
7
|
-
type WxUpdateDelta = {
|
|
8
|
-
version: number
|
|
9
|
-
code: string
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export type WxUpdateBatch = {
|
|
13
|
-
buildId: string
|
|
14
|
-
sessionId: string
|
|
15
|
-
fromVersion: number
|
|
16
|
-
targetVersion: number
|
|
17
|
-
deltas: WxUpdateDelta[]
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
type WxUpdateServerState = {
|
|
21
|
-
buildId: string
|
|
22
|
-
hostVersion: number
|
|
23
|
-
retainedDeltaBytes: number
|
|
24
|
-
deltas: WxUpdateDelta[]
|
|
25
|
-
activeSessionId?: string
|
|
26
|
-
retiredSessionIds: string[]
|
|
27
|
-
inFlight?: Pick<WxUpdateBatch, 'sessionId' | 'fromVersion' | 'targetVersion'>
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
type WxUpdateServerEvent =
|
|
31
|
-
| { type: 'delta-added'; code: string; bytes?: number }
|
|
32
|
-
| { type: 'client-registered'; buildId: string; sessionId: string; version: number }
|
|
33
|
-
| { type: 'client-reported'; buildId: string; sessionId: string; version: number }
|
|
34
|
-
| { type: 'batch-publish-failed'; sessionId: string; targetVersion: number }
|
|
35
|
-
| { type: 'full-build-committed'; buildId: string }
|
|
36
|
-
|
|
37
|
-
export type WxUpdateServerCommand =
|
|
38
|
-
| { type: 'publish-batch'; batch: WxUpdateBatch }
|
|
39
|
-
| { type: 'request-full-build'; reason: 'client-version-ahead' | 'invalid-client-version' }
|
|
40
|
-
| { type: 'ignore-client'; reason: 'stale-build' | 'retired-session' | 'unknown-session' }
|
|
41
|
-
|
|
42
|
-
type WxUpdateServerTransition = {
|
|
43
|
-
state: WxUpdateServerState
|
|
44
|
-
commands: WxUpdateServerCommand[]
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function createWxUpdateServerState(buildId: string): WxUpdateServerState {
|
|
48
|
-
return {
|
|
49
|
-
buildId,
|
|
50
|
-
hostVersion: 0,
|
|
51
|
-
retainedDeltaBytes: 0,
|
|
52
|
-
deltas: [],
|
|
53
|
-
retiredSessionIds: []
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function transitionWxUpdateServer(
|
|
58
|
-
state: WxUpdateServerState,
|
|
59
|
-
event: WxUpdateServerEvent
|
|
60
|
-
): WxUpdateServerTransition {
|
|
61
|
-
switch (event.type) {
|
|
62
|
-
case 'delta-added': {
|
|
63
|
-
const version = state.hostVersion + 1
|
|
64
|
-
return transition({
|
|
65
|
-
...state,
|
|
66
|
-
hostVersion: version,
|
|
67
|
-
retainedDeltaBytes: state.retainedDeltaBytes + (event.bytes ?? event.code.length),
|
|
68
|
-
deltas: [...state.deltas, { version, code: event.code }]
|
|
69
|
-
})
|
|
70
|
-
}
|
|
71
|
-
case 'client-registered':
|
|
72
|
-
return registerClient(state, event)
|
|
73
|
-
case 'client-reported':
|
|
74
|
-
return reportClient(state, event)
|
|
75
|
-
case 'batch-publish-failed':
|
|
76
|
-
if (state.inFlight?.sessionId !== event.sessionId || state.inFlight.targetVersion !== event.targetVersion) {
|
|
77
|
-
return transition(state)
|
|
78
|
-
}
|
|
79
|
-
return transition({ ...state, inFlight: undefined })
|
|
80
|
-
case 'full-build-committed':
|
|
81
|
-
return transition(createWxUpdateServerState(event.buildId))
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function registerClient(
|
|
86
|
-
state: WxUpdateServerState,
|
|
87
|
-
client: { buildId: string; sessionId: string; version: number }
|
|
88
|
-
): WxUpdateServerTransition {
|
|
89
|
-
const rejected = rejectClient(state, client)
|
|
90
|
-
if (rejected) return rejected
|
|
91
|
-
if (state.retiredSessionIds.includes(client.sessionId)) {
|
|
92
|
-
return command(state, { type: 'ignore-client', reason: 'retired-session' })
|
|
93
|
-
}
|
|
94
|
-
if (state.activeSessionId === client.sessionId) return transition(state)
|
|
95
|
-
|
|
96
|
-
const retiredSessionIds = state.activeSessionId
|
|
97
|
-
? [...new Set([...state.retiredSessionIds, state.activeSessionId])]
|
|
98
|
-
: state.retiredSessionIds
|
|
99
|
-
const registered = {
|
|
100
|
-
...state,
|
|
101
|
-
activeSessionId: client.sessionId,
|
|
102
|
-
retiredSessionIds,
|
|
103
|
-
inFlight: undefined
|
|
104
|
-
}
|
|
105
|
-
return transition(registered)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function reportClient(
|
|
109
|
-
state: WxUpdateServerState,
|
|
110
|
-
client: { buildId: string; sessionId: string; version: number }
|
|
111
|
-
): WxUpdateServerTransition {
|
|
112
|
-
const rejected = rejectClient(state, client)
|
|
113
|
-
if (rejected) return rejected
|
|
114
|
-
if (state.retiredSessionIds.includes(client.sessionId)) {
|
|
115
|
-
return command(state, { type: 'ignore-client', reason: 'retired-session' })
|
|
116
|
-
}
|
|
117
|
-
if (client.sessionId !== state.activeSessionId) {
|
|
118
|
-
return command(state, { type: 'ignore-client', reason: 'unknown-session' })
|
|
119
|
-
}
|
|
120
|
-
return synchronizeClient(state, client.version)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
function rejectClient(
|
|
124
|
-
state: WxUpdateServerState,
|
|
125
|
-
client: { buildId: string; version: number }
|
|
126
|
-
): WxUpdateServerTransition | undefined {
|
|
127
|
-
if (client.buildId !== state.buildId) {
|
|
128
|
-
return command(state, { type: 'ignore-client', reason: 'stale-build' })
|
|
129
|
-
}
|
|
130
|
-
if (!Number.isInteger(client.version) || client.version < 0) {
|
|
131
|
-
return command(state, { type: 'request-full-build', reason: 'invalid-client-version' })
|
|
132
|
-
}
|
|
133
|
-
if (client.version > state.hostVersion) {
|
|
134
|
-
return command(state, { type: 'request-full-build', reason: 'client-version-ahead' })
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function synchronizeClient(state: WxUpdateServerState, clientVersion: number): WxUpdateServerTransition {
|
|
139
|
-
let synchronized = state
|
|
140
|
-
const inFlight = state.inFlight
|
|
141
|
-
if (inFlight) {
|
|
142
|
-
if (clientVersion === inFlight.fromVersion) {
|
|
143
|
-
const batch = createBatch(state, clientVersion, inFlight.targetVersion)
|
|
144
|
-
return command(state, { type: 'publish-batch', batch })
|
|
145
|
-
}
|
|
146
|
-
if (clientVersion !== inFlight.targetVersion) {
|
|
147
|
-
return command(state, { type: 'request-full-build', reason: 'invalid-client-version' })
|
|
148
|
-
}
|
|
149
|
-
synchronized = { ...state, inFlight: undefined }
|
|
150
|
-
}
|
|
151
|
-
if (clientVersion >= synchronized.hostVersion) return transition(synchronized)
|
|
152
|
-
|
|
153
|
-
const batch = createBatch(synchronized, clientVersion, synchronized.hostVersion)
|
|
154
|
-
return command(
|
|
155
|
-
{
|
|
156
|
-
...synchronized,
|
|
157
|
-
inFlight: {
|
|
158
|
-
sessionId: batch.sessionId,
|
|
159
|
-
fromVersion: batch.fromVersion,
|
|
160
|
-
targetVersion: batch.targetVersion
|
|
161
|
-
}
|
|
162
|
-
},
|
|
163
|
-
{ type: 'publish-batch', batch }
|
|
164
|
-
)
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function createBatch(state: WxUpdateServerState, fromVersion: number, targetVersion: number): WxUpdateBatch {
|
|
168
|
-
return {
|
|
169
|
-
buildId: state.buildId,
|
|
170
|
-
sessionId: state.activeSessionId!,
|
|
171
|
-
fromVersion,
|
|
172
|
-
targetVersion,
|
|
173
|
-
deltas: state.deltas.filter((delta) => delta.version > fromVersion && delta.version <= targetVersion)
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
function transition(state: WxUpdateServerState): WxUpdateServerTransition {
|
|
178
|
-
return { state, commands: [] }
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function command(state: WxUpdateServerState, value: WxUpdateServerCommand): WxUpdateServerTransition {
|
|
182
|
-
return { state, commands: [value] }
|
|
183
|
-
}
|
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Adapts the pure server protocol to Vite HTTP middleware and literal update-file publication.
|
|
3
|
-
* HTTP messages contain metadata only; executable JavaScript reaches DevTools through the injected file writer.
|
|
4
|
-
*/
|
|
5
|
-
import { randomBytes } from 'node:crypto'
|
|
6
|
-
import type { IncomingMessage, ServerResponse } from 'node:http'
|
|
7
|
-
import type { ViteDevServer } from 'vite'
|
|
8
|
-
import {
|
|
9
|
-
createWxUpdateServerState,
|
|
10
|
-
transitionWxUpdateServer,
|
|
11
|
-
type WxUpdateBatch,
|
|
12
|
-
type WxUpdateServerCommand
|
|
13
|
-
} from './update-server-state.ts'
|
|
14
|
-
|
|
15
|
-
const endpointPath = '/__vite_plugin_taro_wx_update__'
|
|
16
|
-
// Keep the host response below update-client.ts's 30-second wx.request timeout.
|
|
17
|
-
const pollTimeout = 25_000
|
|
18
|
-
|
|
19
|
-
type PendingPoll = {
|
|
20
|
-
response: ServerResponse
|
|
21
|
-
timeout: NodeJS.Timeout
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
type UpdateRequest = {
|
|
25
|
-
token?: unknown
|
|
26
|
-
action?: unknown
|
|
27
|
-
buildId?: unknown
|
|
28
|
-
sessionId?: unknown
|
|
29
|
-
version?: unknown
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export class WxUpdateTransport {
|
|
33
|
-
private state = createWxUpdateServerState(createId())
|
|
34
|
-
private readonly token = createId()
|
|
35
|
-
private readonly pendingPolls = new Map<string, PendingPoll>()
|
|
36
|
-
private closed = false
|
|
37
|
-
|
|
38
|
-
constructor(
|
|
39
|
-
private readonly server: ViteDevServer,
|
|
40
|
-
private readonly requestFullBuild: () => void,
|
|
41
|
-
private readonly writeUpdateFile: (buildId: string, source: string) => Promise<void>
|
|
42
|
-
) {}
|
|
43
|
-
|
|
44
|
-
get retainedDeltaCount(): number {
|
|
45
|
-
return this.state.hostVersion
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
get retainedDeltaBytes(): number {
|
|
49
|
-
return this.state.retainedDeltaBytes
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
install(): void {
|
|
53
|
-
this.server.middlewares.use(endpointPath, this.handleRequest)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
close(): void {
|
|
57
|
-
this.closed = true
|
|
58
|
-
this.respondToAll({ type: 'rebuilding' })
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
addDelta(code: string): void {
|
|
62
|
-
this.apply({ type: 'delta-added', code, bytes: Buffer.byteLength(code) })
|
|
63
|
-
this.respondToAll({ type: 'changed' })
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
createBuildId(): string {
|
|
67
|
-
return createId()
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
isCurrentBuild(buildId: string): boolean {
|
|
71
|
-
return this.state.buildId === buildId
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
commitFullBuild(buildId: string): void {
|
|
75
|
-
this.apply({ type: 'full-build-committed', buildId })
|
|
76
|
-
this.respondToAll({ type: 'rebuilding' })
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/** Generates late-bound App metadata after Vite has selected its actual listening port. */
|
|
80
|
-
createControlSource(buildId = this.state.buildId): string {
|
|
81
|
-
const address = this.server.httpServer?.address()
|
|
82
|
-
const port = address && typeof address !== 'string' ? address.port : this.server.config.server.port
|
|
83
|
-
return `globalThis.__VITE_PLUGIN_TARO_WX_CONTROL__ = ${JSON.stringify({
|
|
84
|
-
url: `http://localhost:${port}${endpointPath}`,
|
|
85
|
-
token: this.token,
|
|
86
|
-
buildId
|
|
87
|
-
})};\n`
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
private readonly handleRequest = async (request: IncomingMessage, response: ServerResponse): Promise<void> => {
|
|
91
|
-
if (this.closed || request.method !== 'POST') {
|
|
92
|
-
respond(response, 404, { type: 'not-found' })
|
|
93
|
-
return
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
let body: UpdateRequest
|
|
97
|
-
try {
|
|
98
|
-
body = JSON.parse(await readBody(request)) as UpdateRequest
|
|
99
|
-
} catch {
|
|
100
|
-
respond(response, 400, { type: 'invalid-request' })
|
|
101
|
-
return
|
|
102
|
-
}
|
|
103
|
-
if (body.token !== this.token || !isClientReport(body)) {
|
|
104
|
-
respond(response, 403, { type: 'forbidden' })
|
|
105
|
-
return
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (body.action === 'rebuild') {
|
|
109
|
-
this.requestFullBuild()
|
|
110
|
-
respond(response, 202, { type: 'rebuilding' })
|
|
111
|
-
return
|
|
112
|
-
}
|
|
113
|
-
if (body.action === 'register') {
|
|
114
|
-
const transition = this.apply({
|
|
115
|
-
type: 'client-registered',
|
|
116
|
-
buildId: body.buildId,
|
|
117
|
-
sessionId: body.sessionId,
|
|
118
|
-
version: body.version
|
|
119
|
-
})
|
|
120
|
-
if (transition.some((command) => command.type === 'request-full-build')) this.requestFullBuild()
|
|
121
|
-
respond(response, 200, { type: 'registered' })
|
|
122
|
-
return
|
|
123
|
-
}
|
|
124
|
-
if (body.action !== 'poll') {
|
|
125
|
-
respond(response, 400, { type: 'invalid-request' })
|
|
126
|
-
return
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const commands = this.apply({
|
|
130
|
-
type: 'client-reported',
|
|
131
|
-
buildId: body.buildId,
|
|
132
|
-
sessionId: body.sessionId,
|
|
133
|
-
version: body.version
|
|
134
|
-
})
|
|
135
|
-
await this.executePollCommands(body.sessionId, commands, response)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
private async executePollCommands(
|
|
139
|
-
sessionId: string,
|
|
140
|
-
commands: WxUpdateServerCommand[],
|
|
141
|
-
response: ServerResponse
|
|
142
|
-
): Promise<void> {
|
|
143
|
-
const publish = commands.find((command) => command.type === 'publish-batch')
|
|
144
|
-
if (publish?.type === 'publish-batch') {
|
|
145
|
-
try {
|
|
146
|
-
await this.writeBatch(publish.batch)
|
|
147
|
-
respond(response, 200, { type: 'batch-published', targetVersion: publish.batch.targetVersion })
|
|
148
|
-
} catch {
|
|
149
|
-
this.apply({
|
|
150
|
-
type: 'batch-publish-failed',
|
|
151
|
-
sessionId: publish.batch.sessionId,
|
|
152
|
-
targetVersion: publish.batch.targetVersion
|
|
153
|
-
})
|
|
154
|
-
respond(response, 500, { type: 'publish-failed' })
|
|
155
|
-
}
|
|
156
|
-
return
|
|
157
|
-
}
|
|
158
|
-
if (commands.some((command) => command.type === 'request-full-build')) {
|
|
159
|
-
this.requestFullBuild()
|
|
160
|
-
respond(response, 202, { type: 'rebuilding' })
|
|
161
|
-
return
|
|
162
|
-
}
|
|
163
|
-
if (commands.some((command) => command.type === 'ignore-client')) {
|
|
164
|
-
respond(response, 409, { type: 'rebuilding' })
|
|
165
|
-
return
|
|
166
|
-
}
|
|
167
|
-
this.holdPoll(sessionId, response)
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
private holdPoll(sessionId: string, response: ServerResponse): void {
|
|
171
|
-
const previous = this.pendingPolls.get(sessionId)
|
|
172
|
-
if (previous) this.finishPoll(sessionId, previous, { type: 'changed' })
|
|
173
|
-
|
|
174
|
-
let pending: PendingPoll
|
|
175
|
-
pending = {
|
|
176
|
-
response,
|
|
177
|
-
timeout: setTimeout(() => this.finishPoll(sessionId, pending, { type: 'idle' }), pollTimeout)
|
|
178
|
-
}
|
|
179
|
-
this.pendingPolls.set(sessionId, pending)
|
|
180
|
-
response.on('close', () => this.finishPoll(sessionId, pending))
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
private respondToAll(value: { type: string }): void {
|
|
184
|
-
for (const [sessionId, pending] of this.pendingPolls) this.finishPoll(sessionId, pending, value)
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
private finishPoll(sessionId: string, pending: PendingPoll, value?: { type: string }): void {
|
|
188
|
-
if (this.pendingPolls.get(sessionId) !== pending) return
|
|
189
|
-
clearTimeout(pending.timeout)
|
|
190
|
-
this.pendingPolls.delete(sessionId)
|
|
191
|
-
if (value) respond(pending.response, 200, value)
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
private apply(event: Parameters<typeof transitionWxUpdateServer>[1]): WxUpdateServerCommand[] {
|
|
195
|
-
const transition = transitionWxUpdateServer(this.state, event)
|
|
196
|
-
this.state = transition.state
|
|
197
|
-
return transition.commands
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
private async writeBatch(batch: WxUpdateBatch): Promise<void> {
|
|
201
|
-
await this.writeUpdateFile(batch.buildId, renderBatch(batch, createId()))
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/** Renders executable code for update.js; this source is never included in an HTTP response. */
|
|
206
|
-
function renderBatch(batch: WxUpdateBatch, nonce: string): string {
|
|
207
|
-
return `// ${nonce}\nglobalThis.__VITE_PLUGIN_TARO_WX_UPDATE_CLIENT__.receiveBatch(${JSON.stringify({
|
|
208
|
-
buildId: batch.buildId,
|
|
209
|
-
fromVersion: batch.fromVersion,
|
|
210
|
-
targetVersion: batch.targetVersion
|
|
211
|
-
})}, () => {
|
|
212
|
-
${indent(batch.deltas.map((delta) => delta.code).join('\n'), 4)}
|
|
213
|
-
});\n`
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
function indent(value: string, spaces: number): string {
|
|
217
|
-
const prefix = ' '.repeat(spaces)
|
|
218
|
-
return value
|
|
219
|
-
.split('\n')
|
|
220
|
-
.map((line) => `${prefix}${line}`)
|
|
221
|
-
.join('\n')
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
function isClientReport(value: UpdateRequest): value is {
|
|
225
|
-
token: string
|
|
226
|
-
action: 'register' | 'poll' | 'rebuild'
|
|
227
|
-
buildId: string
|
|
228
|
-
sessionId: string
|
|
229
|
-
version: number
|
|
230
|
-
} {
|
|
231
|
-
return (
|
|
232
|
-
typeof value.token === 'string' &&
|
|
233
|
-
typeof value.action === 'string' &&
|
|
234
|
-
typeof value.buildId === 'string' &&
|
|
235
|
-
typeof value.sessionId === 'string' &&
|
|
236
|
-
typeof value.version === 'number'
|
|
237
|
-
)
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
async function readBody(request: IncomingMessage): Promise<string> {
|
|
241
|
-
const chunks: Buffer[] = []
|
|
242
|
-
let size = 0
|
|
243
|
-
for await (const chunk of request) {
|
|
244
|
-
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)
|
|
245
|
-
size += buffer.length
|
|
246
|
-
if (size > 64 * 1024) throw new Error('WX update request body is too large.')
|
|
247
|
-
chunks.push(buffer)
|
|
248
|
-
}
|
|
249
|
-
return Buffer.concat(chunks).toString('utf8')
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
function respond(response: ServerResponse, status: number, body: unknown): void {
|
|
253
|
-
if (response.writableEnded) return
|
|
254
|
-
response.statusCode = status
|
|
255
|
-
response.setHeader('content-type', 'application/json')
|
|
256
|
-
response.end(JSON.stringify(body))
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
function createId(): string {
|
|
260
|
-
return randomBytes(16).toString('hex')
|
|
261
|
-
}
|