@nativescript/vite 8.0.0-alpha.6 → 8.0.0-alpha.61
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.md +51 -11
- package/bin/cli.cjs +8 -14
- package/configuration/angular.d.ts +34 -1
- package/configuration/angular.js +390 -165
- package/configuration/angular.js.map +1 -1
- package/configuration/base.js +244 -53
- package/configuration/base.js.map +1 -1
- package/configuration/javascript.js +14 -93
- package/configuration/javascript.js.map +1 -1
- package/configuration/react.js +41 -73
- package/configuration/react.js.map +1 -1
- package/configuration/solid.js +51 -6
- package/configuration/solid.js.map +1 -1
- package/configuration/typescript.js +12 -93
- package/configuration/typescript.js.map +1 -1
- package/helpers/app-components.d.ts +2 -1
- package/helpers/app-components.js.map +1 -1
- package/helpers/app-css-state.d.ts +8 -0
- package/helpers/app-css-state.js +8 -0
- package/helpers/app-css-state.js.map +1 -0
- package/helpers/bundler-context.d.ts +11 -0
- package/helpers/bundler-context.js +71 -0
- package/helpers/bundler-context.js.map +1 -0
- package/helpers/cli-flags.d.ts +12 -0
- package/helpers/cli-flags.js +34 -0
- package/helpers/cli-flags.js.map +1 -1
- package/helpers/css-platform-plugin.d.ts +14 -0
- package/helpers/css-platform-plugin.js +43 -25
- package/helpers/css-platform-plugin.js.map +1 -1
- package/helpers/dev-host.d.ts +360 -0
- package/helpers/dev-host.js +694 -0
- package/helpers/dev-host.js.map +1 -0
- package/helpers/dynamic-import-plugin.js +9 -4
- package/helpers/dynamic-import-plugin.js.map +1 -1
- package/helpers/esbuild-platform-resolver.js +4 -1
- package/helpers/esbuild-platform-resolver.js.map +1 -1
- package/helpers/external-configs.d.ts +10 -12
- package/helpers/external-configs.js +58 -35
- package/helpers/external-configs.js.map +1 -1
- package/helpers/global-defines.d.ts +100 -13
- package/helpers/global-defines.js +165 -28
- package/helpers/global-defines.js.map +1 -1
- package/helpers/hmr-scope.d.ts +26 -0
- package/helpers/hmr-scope.js +67 -0
- package/helpers/hmr-scope.js.map +1 -0
- package/helpers/init.js +0 -18
- package/helpers/init.js.map +1 -1
- package/helpers/logging.js +29 -1
- package/helpers/logging.js.map +1 -1
- package/helpers/main-entry.d.ts +4 -1
- package/helpers/main-entry.js +368 -53
- package/helpers/main-entry.js.map +1 -1
- package/helpers/nativeclass-esbuild-plugin.d.ts +2 -1
- package/helpers/nativeclass-esbuild-plugin.js +6 -1
- package/helpers/nativeclass-esbuild-plugin.js.map +1 -1
- package/helpers/nativeclass-transform.d.ts +13 -0
- package/helpers/nativeclass-transform.js +37 -7
- package/helpers/nativeclass-transform.js.map +1 -1
- package/helpers/nativeclass-transformer-plugin.d.ts +9 -2
- package/helpers/nativeclass-transformer-plugin.js +163 -15
- package/helpers/nativeclass-transformer-plugin.js.map +1 -1
- package/helpers/nativescript-package-resolver.js +10 -62
- package/helpers/nativescript-package-resolver.js.map +1 -1
- package/helpers/normalize-id.d.ts +42 -0
- package/helpers/normalize-id.js +60 -0
- package/helpers/normalize-id.js.map +1 -0
- package/helpers/ns-core-url.d.ts +29 -7
- package/helpers/ns-core-url.js +69 -12
- package/helpers/ns-core-url.js.map +1 -1
- package/helpers/optimize-deps.d.ts +16 -0
- package/helpers/optimize-deps.js +17 -0
- package/helpers/optimize-deps.js.map +1 -0
- package/helpers/package-platform-aliases.js +34 -49
- package/helpers/package-platform-aliases.js.map +1 -1
- package/helpers/platform-types.d.ts +2 -0
- package/helpers/platform-types.js +2 -0
- package/helpers/platform-types.js.map +1 -0
- package/helpers/postcss-platform-config.d.ts +17 -1
- package/helpers/postcss-platform-config.js +20 -37
- package/helpers/postcss-platform-config.js.map +1 -1
- package/helpers/project.d.ts +35 -0
- package/helpers/project.js +120 -2
- package/helpers/project.js.map +1 -1
- package/helpers/resolve-main-field-platform.d.ts +20 -0
- package/helpers/resolve-main-field-platform.js +49 -0
- package/helpers/resolve-main-field-platform.js.map +1 -0
- package/helpers/resolver.js +17 -2
- package/helpers/resolver.js.map +1 -1
- package/helpers/theme-core-plugins.js +1 -1
- package/helpers/theme-core-plugins.js.map +1 -1
- package/helpers/ts-config-paths.d.ts +32 -0
- package/helpers/ts-config-paths.js +156 -27
- package/helpers/ts-config-paths.js.map +1 -1
- package/helpers/typescript-check.d.ts +2 -1
- package/helpers/typescript-check.js +2 -2
- package/helpers/typescript-check.js.map +1 -1
- package/helpers/ui-registration.d.ts +21 -0
- package/helpers/ui-registration.js +156 -0
- package/helpers/ui-registration.js.map +1 -0
- package/helpers/utils.d.ts +9 -0
- package/helpers/utils.js +22 -2
- package/helpers/utils.js.map +1 -1
- package/helpers/vite-package-version.d.ts +7 -0
- package/helpers/vite-package-version.js +44 -0
- package/helpers/vite-package-version.js.map +1 -0
- package/helpers/workers.d.ts +48 -19
- package/helpers/workers.js +662 -13
- package/helpers/workers.js.map +1 -1
- package/hmr/client/css-handler.d.ts +2 -1
- package/hmr/client/css-handler.js +50 -26
- package/hmr/client/css-handler.js.map +1 -1
- package/hmr/client/css-update-overlay.d.ts +18 -0
- package/hmr/client/css-update-overlay.js +27 -0
- package/hmr/client/css-update-overlay.js.map +1 -0
- package/hmr/client/framework-client-strategy.d.ts +79 -0
- package/hmr/client/framework-client-strategy.js +19 -0
- package/hmr/client/framework-client-strategy.js.map +1 -0
- package/hmr/client/hmr-pending-overlay.d.ts +0 -14
- package/hmr/client/hmr-pending-overlay.js +14 -4
- package/hmr/client/hmr-pending-overlay.js.map +1 -1
- package/hmr/client/hot-context.d.ts +67 -0
- package/hmr/client/hot-context.js +284 -0
- package/hmr/client/hot-context.js.map +1 -0
- package/hmr/client/index.js +922 -273
- package/hmr/client/index.js.map +1 -1
- package/hmr/client/utils.d.ts +2 -1
- package/hmr/client/utils.js +111 -99
- package/hmr/client/utils.js.map +1 -1
- package/hmr/entry-runtime.d.ts +2 -1
- package/hmr/entry-runtime.js +279 -71
- package/hmr/entry-runtime.js.map +1 -1
- package/hmr/frameworks/angular/build/angular-linker.d.ts +12 -0
- package/hmr/frameworks/angular/build/angular-linker.js +109 -0
- package/hmr/frameworks/angular/build/angular-linker.js.map +1 -0
- package/hmr/frameworks/angular/build/inject-component-hmr-registration.d.ts +112 -0
- package/hmr/frameworks/angular/build/inject-component-hmr-registration.js +291 -0
- package/hmr/frameworks/angular/build/inject-component-hmr-registration.js.map +1 -0
- package/hmr/frameworks/angular/build/inject-hmr-vite-ignore.d.ts +75 -0
- package/hmr/frameworks/angular/build/inject-hmr-vite-ignore.js +221 -0
- package/hmr/frameworks/angular/build/inject-hmr-vite-ignore.js.map +1 -0
- package/{helpers/angular → hmr/frameworks/angular/build}/inline-decorator-component-templates.js +1 -170
- package/hmr/frameworks/angular/build/inline-decorator-component-templates.js.map +1 -0
- package/hmr/frameworks/angular/build/js-lexer.d.ts +4 -0
- package/{helpers/angular/synthesize-decorator-ctor-parameters.js → hmr/frameworks/angular/build/js-lexer.js} +22 -96
- package/hmr/frameworks/angular/build/js-lexer.js.map +1 -0
- package/hmr/frameworks/angular/build/shared-linker.d.ts +39 -0
- package/hmr/frameworks/angular/build/shared-linker.js +128 -0
- package/hmr/frameworks/angular/build/shared-linker.js.map +1 -0
- package/hmr/frameworks/angular/build/synthesize-decorator-ctor-parameters.js +88 -0
- package/hmr/frameworks/angular/build/synthesize-decorator-ctor-parameters.js.map +1 -0
- package/{helpers/angular → hmr/frameworks/angular/build}/synthesize-injectable-factories.js +1 -174
- package/hmr/frameworks/angular/build/synthesize-injectable-factories.js.map +1 -0
- package/{helpers/angular → hmr/frameworks/angular/build}/util.d.ts +1 -0
- package/hmr/frameworks/angular/build/util.js +155 -0
- package/hmr/frameworks/angular/build/util.js.map +1 -0
- package/hmr/frameworks/angular/client/index.js +542 -175
- package/hmr/frameworks/angular/client/index.js.map +1 -1
- package/hmr/frameworks/angular/client/strategy.d.ts +9 -0
- package/hmr/frameworks/angular/client/strategy.js +19 -0
- package/hmr/frameworks/angular/client/strategy.js.map +1 -0
- package/hmr/frameworks/angular/server/angular-root-component.d.ts +79 -0
- package/hmr/frameworks/angular/server/angular-root-component.js +149 -0
- package/hmr/frameworks/angular/server/angular-root-component.js.map +1 -0
- package/hmr/frameworks/angular/server/linker.js +1 -4
- package/hmr/frameworks/angular/server/linker.js.map +1 -1
- package/hmr/frameworks/angular/server/strategy.js +458 -12
- package/hmr/frameworks/angular/server/strategy.js.map +1 -1
- package/hmr/{server → frameworks/angular/server}/websocket-angular-entry.js +2 -2
- package/hmr/frameworks/angular/server/websocket-angular-entry.js.map +1 -0
- package/hmr/{server → frameworks/angular/server}/websocket-angular-hot-update.d.ts +14 -11
- package/hmr/{server → frameworks/angular/server}/websocket-angular-hot-update.js +108 -111
- package/hmr/frameworks/angular/server/websocket-angular-hot-update.js.map +1 -0
- package/hmr/frameworks/react/server/strategy.d.ts +2 -0
- package/hmr/frameworks/react/server/strategy.js +230 -0
- package/hmr/frameworks/react/server/strategy.js.map +1 -0
- package/hmr/frameworks/solid/build/solid-jsx-deps.d.ts +15 -0
- package/hmr/frameworks/solid/build/solid-jsx-deps.js +178 -0
- package/hmr/frameworks/solid/build/solid-jsx-deps.js.map +1 -0
- package/hmr/frameworks/solid/client/app-runtime.d.ts +68 -0
- package/hmr/frameworks/solid/client/app-runtime.js +246 -0
- package/hmr/frameworks/solid/client/app-runtime.js.map +1 -0
- package/hmr/frameworks/solid/server/strategy.js +291 -16
- package/hmr/frameworks/solid/server/strategy.js.map +1 -1
- package/hmr/frameworks/typescript/server/strategy.js +38 -14
- package/hmr/frameworks/typescript/server/strategy.js.map +1 -1
- package/hmr/frameworks/vue/client/dep-propagation.d.ts +44 -0
- package/hmr/frameworks/vue/client/dep-propagation.js +148 -0
- package/hmr/frameworks/vue/client/dep-propagation.js.map +1 -0
- package/hmr/frameworks/vue/client/index.d.ts +9 -0
- package/hmr/frameworks/vue/client/index.js +251 -247
- package/hmr/frameworks/vue/client/index.js.map +1 -1
- package/hmr/frameworks/vue/client/strategy.d.ts +33 -0
- package/hmr/frameworks/vue/client/strategy.js +157 -0
- package/hmr/frameworks/vue/client/strategy.js.map +1 -0
- package/hmr/frameworks/vue/client/vue-sfc-update-overlay.d.ts +49 -0
- package/hmr/frameworks/vue/client/vue-sfc-update-overlay.js +142 -0
- package/hmr/frameworks/vue/client/vue-sfc-update-overlay.js.map +1 -0
- package/hmr/frameworks/vue/server/compiler.d.ts +3 -1
- package/hmr/frameworks/vue/server/compiler.js +3 -1
- package/hmr/frameworks/vue/server/compiler.js.map +1 -1
- package/hmr/frameworks/vue/server/sfc-route-assemble.d.ts +7 -0
- package/hmr/frameworks/vue/server/sfc-route-assemble.js +823 -0
- package/hmr/frameworks/vue/server/sfc-route-assemble.js.map +1 -0
- package/hmr/frameworks/vue/server/sfc-route-meta.d.ts +7 -0
- package/hmr/frameworks/vue/server/sfc-route-meta.js +80 -0
- package/hmr/frameworks/vue/server/sfc-route-meta.js.map +1 -0
- package/hmr/frameworks/vue/server/sfc-route-serve.d.ts +8 -0
- package/hmr/frameworks/vue/server/sfc-route-serve.js +462 -0
- package/hmr/frameworks/vue/server/sfc-route-serve.js.map +1 -0
- package/hmr/frameworks/vue/server/sfc-route-shared.d.ts +45 -0
- package/hmr/frameworks/vue/server/sfc-route-shared.js +105 -0
- package/hmr/frameworks/vue/server/sfc-route-shared.js.map +1 -0
- package/hmr/frameworks/vue/server/strategy.d.ts +35 -0
- package/hmr/frameworks/vue/server/strategy.js +286 -7
- package/hmr/frameworks/vue/server/strategy.js.map +1 -1
- package/hmr/frameworks/vue/server/websocket-sfc.d.ts +15 -0
- package/hmr/frameworks/vue/server/websocket-sfc.js +20 -0
- package/hmr/frameworks/vue/server/websocket-sfc.js.map +1 -0
- package/hmr/helpers/ast-normalizer.d.ts +3 -1
- package/hmr/helpers/ast-normalizer.js +77 -10
- package/hmr/helpers/ast-normalizer.js.map +1 -1
- package/hmr/helpers/cjs-named-exports.d.ts +23 -0
- package/hmr/helpers/cjs-named-exports.js +152 -0
- package/hmr/helpers/cjs-named-exports.js.map +1 -0
- package/hmr/helpers/package-exports.d.ts +16 -0
- package/hmr/helpers/package-exports.js +396 -0
- package/hmr/helpers/package-exports.js.map +1 -0
- package/hmr/helpers/vendor-rewrite.d.ts +1 -1
- package/hmr/helpers/vendor-rewrite.js +5 -3
- package/hmr/helpers/vendor-rewrite.js.map +1 -1
- package/hmr/server/boot-archive-route.d.ts +40 -0
- package/hmr/server/boot-archive-route.js +154 -0
- package/hmr/server/boot-archive-route.js.map +1 -0
- package/hmr/server/boot-closure-route.d.ts +49 -0
- package/hmr/server/boot-closure-route.js +144 -0
- package/hmr/server/boot-closure-route.js.map +1 -0
- package/hmr/server/boot-recording.d.ts +58 -0
- package/hmr/server/boot-recording.js +228 -0
- package/hmr/server/boot-recording.js.map +1 -0
- package/hmr/server/constants.js +20 -5
- package/hmr/server/constants.js.map +1 -1
- package/hmr/server/core-bundle.d.ts +140 -0
- package/hmr/server/core-bundle.js +614 -0
- package/hmr/server/core-bundle.js.map +1 -0
- package/hmr/server/core-sanitize.d.ts +86 -7
- package/hmr/server/core-sanitize.js +170 -45
- package/hmr/server/core-sanitize.js.map +1 -1
- package/hmr/server/css-device-module.d.ts +28 -0
- package/hmr/server/css-device-module.js +44 -0
- package/hmr/server/css-device-module.js.map +1 -0
- package/hmr/server/deps-bundle.d.ts +218 -0
- package/hmr/server/deps-bundle.js +998 -0
- package/hmr/server/deps-bundle.js.map +1 -0
- package/hmr/server/device-transform-helpers.d.ts +24 -0
- package/hmr/server/device-transform-helpers.js +408 -0
- package/hmr/server/device-transform-helpers.js.map +1 -0
- package/hmr/server/framework-strategy.d.ts +113 -11
- package/hmr/server/hmr-module-graph.d.ts +37 -0
- package/hmr/server/hmr-module-graph.js +215 -0
- package/hmr/server/hmr-module-graph.js.map +1 -0
- package/hmr/server/import-map.d.ts +13 -4
- package/hmr/server/import-map.js +94 -47
- package/hmr/server/import-map.js.map +1 -1
- package/hmr/server/index.js +7 -16
- package/hmr/server/index.js.map +1 -1
- package/hmr/server/ns-core-cjs-shape.d.ts +2 -4
- package/hmr/server/ns-core-cjs-shape.js +4 -6
- package/hmr/server/ns-core-cjs-shape.js.map +1 -1
- package/hmr/server/ns-m-response-memo.d.ts +10 -0
- package/hmr/server/ns-m-response-memo.js +33 -0
- package/hmr/server/ns-m-response-memo.js.map +1 -0
- package/hmr/server/ns-rt-bridge.d.ts +51 -0
- package/hmr/server/ns-rt-bridge.js +131 -0
- package/hmr/server/ns-rt-bridge.js.map +1 -0
- package/hmr/server/ns-rt-route.d.ts +5 -0
- package/hmr/server/ns-rt-route.js +39 -0
- package/hmr/server/ns-rt-route.js.map +1 -0
- package/hmr/server/perf-instrumentation.d.ts +6 -10
- package/hmr/server/perf-instrumentation.js +5 -6
- package/hmr/server/perf-instrumentation.js.map +1 -1
- package/hmr/server/process-code-for-device.d.ts +30 -0
- package/hmr/server/process-code-for-device.js +791 -0
- package/hmr/server/process-code-for-device.js.map +1 -0
- package/hmr/server/require-guard.d.ts +1 -0
- package/hmr/server/require-guard.js +12 -0
- package/hmr/server/require-guard.js.map +1 -0
- package/hmr/server/rewrite-imports.d.ts +2 -0
- package/hmr/server/rewrite-imports.js +638 -0
- package/hmr/server/rewrite-imports.js.map +1 -0
- package/hmr/server/route-helpers.d.ts +7 -0
- package/hmr/server/route-helpers.js +13 -0
- package/hmr/server/route-helpers.js.map +1 -0
- package/hmr/server/server-origin.d.ts +2 -0
- package/hmr/server/server-origin.js +83 -0
- package/hmr/server/server-origin.js.map +1 -0
- package/hmr/server/shared-transform-request.js +1 -2
- package/hmr/server/shared-transform-request.js.map +1 -1
- package/hmr/server/transform-cache-invalidation.d.ts +37 -0
- package/hmr/server/transform-cache-invalidation.js +156 -0
- package/hmr/server/transform-cache-invalidation.js.map +1 -0
- package/hmr/server/vendor-bare-module-shims.d.ts +4 -0
- package/hmr/server/vendor-bare-module-shims.js +80 -0
- package/hmr/server/vendor-bare-module-shims.js.map +1 -0
- package/hmr/server/vite-plugin.d.ts +1 -0
- package/hmr/server/vite-plugin.js +180 -54
- package/hmr/server/vite-plugin.js.map +1 -1
- package/hmr/server/websocket-core-bridge.d.ts +51 -4
- package/hmr/server/websocket-core-bridge.js +62 -54
- package/hmr/server/websocket-core-bridge.js.map +1 -1
- package/hmr/server/websocket-css-hot-update.d.ts +33 -0
- package/hmr/server/websocket-css-hot-update.js +65 -0
- package/hmr/server/websocket-css-hot-update.js.map +1 -0
- package/hmr/server/websocket-device-transform.d.ts +3 -0
- package/hmr/server/websocket-device-transform.js +7 -0
- package/hmr/server/websocket-device-transform.js.map +1 -0
- package/hmr/server/websocket-hmr-pending.d.ts +3 -9
- package/hmr/server/websocket-hmr-pending.js +1 -1
- package/hmr/server/websocket-hmr-pending.js.map +1 -1
- package/hmr/server/websocket-hot-update.d.ts +77 -0
- package/hmr/server/websocket-hot-update.js +360 -0
- package/hmr/server/websocket-hot-update.js.map +1 -0
- package/hmr/server/websocket-import-map-route.d.ts +15 -0
- package/hmr/server/websocket-import-map-route.js +50 -0
- package/hmr/server/websocket-import-map-route.js.map +1 -0
- package/hmr/server/websocket-module-bindings.js +3 -3
- package/hmr/server/websocket-module-bindings.js.map +1 -1
- package/hmr/server/websocket-module-specifiers.d.ts +66 -2
- package/hmr/server/websocket-module-specifiers.js +191 -20
- package/hmr/server/websocket-module-specifiers.js.map +1 -1
- package/hmr/server/websocket-ns-core.d.ts +34 -0
- package/hmr/server/websocket-ns-core.js +414 -0
- package/hmr/server/websocket-ns-core.js.map +1 -0
- package/hmr/server/websocket-ns-entry.d.ts +21 -0
- package/hmr/server/websocket-ns-entry.js +164 -0
- package/hmr/server/websocket-ns-entry.js.map +1 -0
- package/hmr/server/websocket-ns-m-paths.d.ts +1 -3
- package/hmr/server/websocket-ns-m-paths.js +25 -82
- package/hmr/server/websocket-ns-m-paths.js.map +1 -1
- package/hmr/server/websocket-ns-m-request.d.ts +11 -1
- package/hmr/server/websocket-ns-m-request.js +17 -9
- package/hmr/server/websocket-ns-m-request.js.map +1 -1
- package/hmr/server/websocket-ns-m.d.ts +52 -0
- package/hmr/server/websocket-ns-m.js +835 -0
- package/hmr/server/websocket-ns-m.js.map +1 -0
- package/hmr/server/websocket-served-module-helpers.d.ts +50 -4
- package/hmr/server/websocket-served-module-helpers.js +384 -86
- package/hmr/server/websocket-served-module-helpers.js.map +1 -1
- package/hmr/server/websocket-txn.js +6 -9
- package/hmr/server/websocket-txn.js.map +1 -1
- package/hmr/server/websocket-vendor-unifier.d.ts +0 -1
- package/hmr/server/websocket-vendor-unifier.js +4 -9
- package/hmr/server/websocket-vendor-unifier.js.map +1 -1
- package/hmr/server/websocket.d.ts +7 -39
- package/hmr/server/websocket.js +643 -6716
- package/hmr/server/websocket.js.map +1 -1
- package/hmr/shared/ns-globals.d.ts +108 -0
- package/hmr/shared/ns-globals.js +28 -0
- package/hmr/shared/ns-globals.js.map +1 -0
- package/hmr/shared/protocol.d.ts +145 -0
- package/hmr/shared/protocol.js +28 -0
- package/hmr/shared/protocol.js.map +1 -0
- package/hmr/shared/runtime/boot-archive-format.d.ts +16 -0
- package/hmr/shared/runtime/boot-archive-format.js +31 -0
- package/hmr/shared/runtime/boot-archive-format.js.map +1 -0
- package/hmr/shared/runtime/boot-complete.d.ts +14 -0
- package/hmr/shared/runtime/boot-complete.js +32 -0
- package/hmr/shared/runtime/boot-complete.js.map +1 -0
- package/hmr/shared/runtime/boot-placeholder-ui.d.ts +69 -0
- package/hmr/shared/runtime/boot-placeholder-ui.js +101 -0
- package/hmr/shared/runtime/boot-placeholder-ui.js.map +1 -0
- package/hmr/shared/runtime/boot-progress.d.ts +44 -0
- package/hmr/shared/runtime/boot-progress.js +134 -0
- package/hmr/shared/runtime/boot-progress.js.map +1 -0
- package/hmr/shared/runtime/boot-timeline.d.ts +2 -1
- package/hmr/shared/runtime/boot-timeline.js +9 -22
- package/hmr/shared/runtime/boot-timeline.js.map +1 -1
- package/hmr/shared/runtime/browser-runtime-contract.d.ts +53 -22
- package/hmr/shared/runtime/browser-runtime-contract.js +6 -9
- package/hmr/shared/runtime/browser-runtime-contract.js.map +1 -1
- package/hmr/shared/runtime/dev-overlay-snapshots.d.ts +31 -0
- package/hmr/shared/runtime/dev-overlay-snapshots.js +324 -0
- package/hmr/shared/runtime/dev-overlay-snapshots.js.map +1 -0
- package/hmr/shared/runtime/dev-overlay.d.ts +76 -30
- package/hmr/shared/runtime/dev-overlay.js +767 -408
- package/hmr/shared/runtime/dev-overlay.js.map +1 -1
- package/hmr/shared/runtime/global-scope.d.ts +18 -0
- package/hmr/shared/runtime/global-scope.js +21 -0
- package/hmr/shared/runtime/global-scope.js.map +1 -0
- package/hmr/shared/runtime/hooks.js +2 -1
- package/hmr/shared/runtime/hooks.js.map +1 -1
- package/hmr/shared/runtime/http-only-boot.js +7 -6
- package/hmr/shared/runtime/http-only-boot.js.map +1 -1
- package/hmr/shared/runtime/module-provenance.js +4 -6
- package/hmr/shared/runtime/module-provenance.js.map +1 -1
- package/hmr/shared/runtime/root-placeholder-view.d.ts +19 -0
- package/hmr/shared/runtime/root-placeholder-view.js +311 -0
- package/hmr/shared/runtime/root-placeholder-view.js.map +1 -0
- package/hmr/shared/runtime/root-placeholder.js +398 -204
- package/hmr/shared/runtime/root-placeholder.js.map +1 -1
- package/hmr/shared/runtime/session-bootstrap.js +274 -55
- package/hmr/shared/runtime/session-bootstrap.js.map +1 -1
- package/hmr/shared/runtime/vendor-bootstrap.js +3 -10
- package/hmr/shared/runtime/vendor-bootstrap.js.map +1 -1
- package/hmr/shared/vendor/manifest-collect.d.ts +4 -0
- package/hmr/shared/vendor/manifest-collect.js +549 -0
- package/hmr/shared/vendor/manifest-collect.js.map +1 -0
- package/hmr/shared/vendor/manifest-loader.d.ts +2 -1
- package/hmr/shared/vendor/manifest-loader.js +5 -3
- package/hmr/shared/vendor/manifest-loader.js.map +1 -1
- package/hmr/shared/vendor/manifest.d.ts +1 -7
- package/hmr/shared/vendor/manifest.js +136 -825
- package/hmr/shared/vendor/manifest.js.map +1 -1
- package/hmr/shared/vendor/registry.d.ts +2 -0
- package/hmr/shared/vendor/registry.js +14 -0
- package/hmr/shared/vendor/registry.js.map +1 -1
- package/hmr/shared/vendor/vendor-device-shim.d.ts +1 -0
- package/hmr/shared/vendor/vendor-device-shim.js +208 -0
- package/hmr/shared/vendor/vendor-device-shim.js.map +1 -0
- package/hmr/shared/vendor/vendor-esbuild-plugins.d.ts +76 -0
- package/hmr/shared/vendor/vendor-esbuild-plugins.js +401 -0
- package/hmr/shared/vendor/vendor-esbuild-plugins.js.map +1 -0
- package/hmr/vendor-bootstrap.d.ts +1 -3
- package/hmr/vendor-bootstrap.js +4 -6
- package/hmr/vendor-bootstrap.js.map +1 -1
- package/index.d.ts +1 -0
- package/index.js +5 -0
- package/index.js.map +1 -1
- package/package.json +65 -11
- package/runtime/core-aliases-early.js +25 -55
- package/runtime/core-aliases-early.js.map +1 -1
- package/shims/react-jsx-runtime.d.ts +4 -0
- package/shims/react-jsx-runtime.js +61 -0
- package/shims/react-jsx-runtime.js.map +1 -0
- package/helpers/angular/angular-linker.d.ts +0 -13
- package/helpers/angular/angular-linker.js +0 -194
- package/helpers/angular/angular-linker.js.map +0 -1
- package/helpers/angular/inline-decorator-component-templates.js.map +0 -1
- package/helpers/angular/shared-linker.d.ts +0 -11
- package/helpers/angular/shared-linker.js +0 -75
- package/helpers/angular/shared-linker.js.map +0 -1
- package/helpers/angular/synthesize-decorator-ctor-parameters.js.map +0 -1
- package/helpers/angular/synthesize-injectable-factories.js.map +0 -1
- package/helpers/angular/util.js +0 -67
- package/helpers/angular/util.js.map +0 -1
- package/helpers/prelink-angular.d.ts +0 -2
- package/helpers/prelink-angular.js +0 -117
- package/helpers/prelink-angular.js.map +0 -1
- package/hmr/server/websocket-angular-entry.js.map +0 -1
- package/hmr/server/websocket-angular-hot-update.js.map +0 -1
- package/hmr/server/websocket-ns-m-finalize.d.ts +0 -22
- package/hmr/server/websocket-ns-m-finalize.js +0 -88
- package/hmr/server/websocket-ns-m-finalize.js.map +0 -1
- package/hmr/server/websocket-runtime-compat.d.ts +0 -19
- package/hmr/server/websocket-runtime-compat.js +0 -286
- package/hmr/server/websocket-runtime-compat.js.map +0 -1
- package/hmr/server/websocket-vue-sfc.d.ts +0 -27
- package/hmr/server/websocket-vue-sfc.js +0 -1114
- package/hmr/server/websocket-vue-sfc.js.map +0 -1
- package/transformers/NativeClass/index.d.ts +0 -2
- package/transformers/NativeClass/index.js +0 -222
- package/transformers/NativeClass/index.js.map +0 -1
- /package/{helpers/angular → hmr/frameworks/angular/build}/inline-decorator-component-templates.d.ts +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/synthesize-decorator-ctor-parameters.d.ts +0 -0
- /package/{helpers/angular → hmr/frameworks/angular/build}/synthesize-injectable-factories.d.ts +0 -0
- /package/hmr/{server → frameworks/angular/server}/websocket-angular-entry.d.ts +0 -0
|
@@ -1,18 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
1
|
+
import { getGlobalScope } from '../../../shared/runtime/global-scope.js';
|
|
2
|
+
import { getNsHotRegistry } from '../../../client/hot-context.js';
|
|
3
|
+
import { readNsRuntimeDevHostApi } from '../../../shared/runtime/browser-runtime-contract.js';
|
|
4
|
+
// Opt-out flag for the apply-progress overlay (default: enabled).
|
|
5
|
+
// Driven by `NS_VITE_PROGRESS_OVERLAY=0` (or `false`/`off`/`no`) on the
|
|
6
|
+
// dev server; baked into the bundle via
|
|
7
|
+
// `__NS_HMR_PROGRESS_OVERLAY_ENABLED__` at build time. We collapse the
|
|
8
|
+
// build-time constant into a runtime boolean once so each call-site is
|
|
9
|
+
// a single property check rather than a try/typeof. Tests that re-run
|
|
10
|
+
// the angular client (via vitest) see `undefined` and default to
|
|
11
|
+
// enabled — matching the production dev-server experience.
|
|
9
12
|
const overlayEnabled = (() => {
|
|
13
|
+
// Define substitution does not reach this raw-served file — fall back to
|
|
14
|
+
// the globalThis seed planted by the entry's defines-seed module (which
|
|
15
|
+
// evaluates before this client is loaded) before defaulting to enabled.
|
|
10
16
|
try {
|
|
11
|
-
|
|
17
|
+
if (typeof __NS_HMR_PROGRESS_OVERLAY_ENABLED__ === 'boolean')
|
|
18
|
+
return __NS_HMR_PROGRESS_OVERLAY_ENABLED__;
|
|
12
19
|
}
|
|
13
|
-
catch {
|
|
14
|
-
|
|
20
|
+
catch { }
|
|
21
|
+
try {
|
|
22
|
+
const seeded = getGlobalScope().__NS_HMR_PROGRESS_OVERLAY_ENABLED__;
|
|
23
|
+
if (typeof seeded === 'boolean')
|
|
24
|
+
return seeded;
|
|
15
25
|
}
|
|
26
|
+
catch { }
|
|
27
|
+
return true;
|
|
16
28
|
})();
|
|
17
29
|
function getHmrOverlayApi() {
|
|
18
30
|
if (!overlayEnabled)
|
|
@@ -45,8 +57,7 @@ function hideUpdateOverlay() {
|
|
|
45
57
|
}
|
|
46
58
|
catch { }
|
|
47
59
|
}
|
|
48
|
-
//
|
|
49
|
-
// constant.
|
|
60
|
+
// Safe accessor for the build-time `__NS_ENV_VERBOSE__` constant.
|
|
50
61
|
//
|
|
51
62
|
// Vite replaces `__NS_ENV_VERBOSE__` at build time via `define`. In
|
|
52
63
|
// unit tests (vitest, plain ts-node, etc.) the identifier is
|
|
@@ -55,11 +66,10 @@ function hideUpdateOverlay() {
|
|
|
55
66
|
// build-time constant into a runtime boolean once at module load and
|
|
56
67
|
// then short-circuit on `verbose` arguments at every call-site.
|
|
57
68
|
//
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
// build constant.
|
|
69
|
+
// Always order `verbose && envVerbose` so the runtime flag
|
|
70
|
+
// short-circuits the build-time constant; that prevents reference
|
|
71
|
+
// errors in test environments where the `define` substitution does
|
|
72
|
+
// not run.
|
|
63
73
|
const envVerbose = (() => {
|
|
64
74
|
try {
|
|
65
75
|
return typeof __NS_ENV_VERBOSE__ === 'boolean' ? __NS_ENV_VERBOSE__ : false;
|
|
@@ -81,72 +91,293 @@ export function installAngularHmrClientHooks() {
|
|
|
81
91
|
}
|
|
82
92
|
catch { }
|
|
83
93
|
}
|
|
84
|
-
//
|
|
94
|
+
// HMR cycle serialization mutex.
|
|
85
95
|
//
|
|
86
|
-
//
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
//
|
|
96
|
+
// A back-to-back save (e.g., the user holds Cmd+S, or `runOnSave`
|
|
97
|
+
// saves a file twice during one tick) could overlap two HMR cycles:
|
|
98
|
+
// the first cycle's `import(entry)` would still be resolving when the
|
|
99
|
+
// second cycle's `__NS_DEV__.invalidateModules` ran, leaving the registry in
|
|
100
|
+
// a half-evicted state and producing flaky "module already evaluated"
|
|
101
|
+
// errors.
|
|
92
102
|
//
|
|
93
|
-
// Each `handleAngularHotUpdateMessage` call
|
|
94
|
-
//
|
|
103
|
+
// Each `handleAngularHotUpdateMessage` call publishes a promise to
|
|
104
|
+
// `inFlightHmrCycle` and awaits the previous publication before
|
|
95
105
|
// starting its own evict + import. The previous-cycle promise resolves
|
|
96
106
|
// regardless of success or failure (we always run `resolveCycle()` in
|
|
97
107
|
// `finally`), so a stuck cycle can't deadlock the queue. The mutex is
|
|
98
108
|
// intentionally process-wide and resets naturally on cold-boot or
|
|
99
109
|
// websocket reconnect (both blow away the JS realm).
|
|
100
110
|
let inFlightHmrCycle = null;
|
|
101
|
-
//
|
|
111
|
+
// Explicit module eviction.
|
|
102
112
|
//
|
|
103
|
-
// `
|
|
104
|
-
// array of canonical /ns/m/<rel> URLs
|
|
105
|
-
// module registry (`g_moduleRegistry`)
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
// every cache entry historically created for that module — even if a
|
|
109
|
-
// pre-alpha.59 stale tagged URL is still around.
|
|
113
|
+
// `__NS_DEV__.invalidateModules` is a runtime-installed global that takes an
|
|
114
|
+
// array of canonical /ns/m/<rel> URLs, removes each one from V8's
|
|
115
|
+
// module registry (`g_moduleRegistry`) and the prefetch cache, and
|
|
116
|
+
// marks the keys "bust next fetch" so the runtime's next HTTP fetch
|
|
117
|
+
// for them defeats OS-level caches with a one-shot query nonce.
|
|
110
118
|
//
|
|
111
|
-
// Soft-fails
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
|
|
116
|
-
|
|
119
|
+
// Soft-fails (with a loud warning) if the runtime is missing the
|
|
120
|
+
// function — the eviction protocol is a required part of the runtime
|
|
121
|
+
// contract, so that indicates a runtime/vite version mismatch.
|
|
122
|
+
// Dispatch one of Vite's standard HMR lifecycle events through the JS
|
|
123
|
+
// hot registry (`hot-context.ts`). The registry owns the listener map
|
|
124
|
+
// that `import.meta.hot.on(event, cb)` populates; this function is the
|
|
125
|
+
// producer side that lets the Angular HMR client emit the canonical
|
|
126
|
+
// Vite events (`vite:beforeUpdate`, `vite:afterUpdate`,
|
|
127
|
+
// `vite:beforeFullReload`, `vite:invalidate`, `vite:error`) at the
|
|
128
|
+
// right moments. User code that does
|
|
129
|
+
// `import.meta.hot.on('vite:beforeUpdate', cb)` only fires when this is
|
|
130
|
+
// called.
|
|
131
|
+
//
|
|
132
|
+
// The registry is a `globalThis.__NS_HOT_REGISTRY__` singleton, so this
|
|
133
|
+
// works even if this module and the served app modules were evaluated
|
|
134
|
+
// from different URLs. Per-listener failures are swallowed inside the
|
|
135
|
+
// registry, so a single bad listener can't break the HMR cycle.
|
|
136
|
+
function dispatchHotEvent(_g, event, payload) {
|
|
137
|
+
try {
|
|
138
|
+
getNsHotRegistry().dispatchHotEvent(event, payload);
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
// Defensive safety net for registry regressions. Log only under
|
|
142
|
+
// verbose to avoid noisy dev logs.
|
|
143
|
+
if (envVerbose) {
|
|
144
|
+
console.warn(`[ns-hmr][client] dispatchHotEvent('${event}') threw:`, err?.message ?? err);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Trigger a JS-driven full app reload, dispatching `vite:beforeFullReload`
|
|
149
|
+
// first so user-code listeners can react. The registry's full-reload path
|
|
150
|
+
// evicts every loaded app module (`__NS_DEV__.getLoadedModuleUrls` →
|
|
151
|
+
// `__NS_DEV__.invalidateModules`) and re-imports the dev entry; the
|
|
152
|
+
// `Application.run` patch in root-placeholder converts re-entry into
|
|
153
|
+
// `resetRootView`. Returns `true` if the reload was triggered. Used both
|
|
154
|
+
// by `import.meta.hot.invalidate()` (handled inside the registry) AND by
|
|
155
|
+
// the declined-module check below (where the JS layer makes the decision
|
|
156
|
+
// and asks for the reload).
|
|
157
|
+
function triggerFullReload(_g, message) {
|
|
158
|
+
dispatchHotEvent(_g, 'vite:beforeFullReload', { message });
|
|
159
|
+
try {
|
|
160
|
+
// Fire-and-forget — the reload path is async, but we don't await
|
|
161
|
+
// it here because the module graph is about to be torn down. The
|
|
162
|
+
// HMR cycle's caller treats this as terminal and short-circuits
|
|
163
|
+
// the rest of the cycle.
|
|
164
|
+
getNsHotRegistry().requestFullReload(message);
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
if (envVerbose) {
|
|
168
|
+
console.warn('[ns-hmr][client] requestFullReload threw:', err?.message ?? err);
|
|
169
|
+
}
|
|
117
170
|
return false;
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
171
|
+
}
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
// Check if any module being touched by this HMR update has called
|
|
175
|
+
// `import.meta.hot.decline()`. If so, per Vite spec we MUST do a full
|
|
176
|
+
// reload instead of a hot-update — declining means "I refuse to be
|
|
177
|
+
// hot-updated". Returns `true` if a full reload was triggered (caller
|
|
178
|
+
// should short-circuit the rest of the cycle).
|
|
179
|
+
function checkDeclinedAndReload(g, msg, options) {
|
|
180
|
+
// `evictPaths` is the eviction set the dev server computed for this
|
|
181
|
+
// HMR cycle — every module that needs to be re-evaluated. If ANY of
|
|
182
|
+
// those modules declined HMR, the whole cycle has to convert to a
|
|
183
|
+
// full reload. Pass them through verbatim; the registry canonicalizes
|
|
184
|
+
// internally when matching against its declined set.
|
|
185
|
+
const evictPaths = Array.isArray(msg?.evictPaths) ? msg.evictPaths : [];
|
|
186
|
+
let declined = false;
|
|
187
|
+
try {
|
|
188
|
+
declined = getNsHotRegistry().hasDeclined(evictPaths);
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
if (options.verbose && envVerbose) {
|
|
192
|
+
console.warn('[ns-hmr][client] hasDeclined threw:', err?.message ?? err);
|
|
193
|
+
}
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
if (!declined)
|
|
197
|
+
return false;
|
|
198
|
+
const filePath = typeof msg?.path === 'string' ? msg.path : '<unknown>';
|
|
199
|
+
const message = `module declined HMR (file=${filePath}, evictPaths=${evictPaths.length})`;
|
|
200
|
+
console.info(`[ns-hmr][decline] ${message} — falling back to full reload`);
|
|
201
|
+
const reloaded = triggerFullReload(g, message);
|
|
202
|
+
if (!reloaded && options.verbose && envVerbose) {
|
|
203
|
+
console.warn('[ns-hmr][client] declined module detected but full reload unavailable; HMR will proceed');
|
|
204
|
+
}
|
|
205
|
+
return reloaded;
|
|
206
|
+
}
|
|
207
|
+
// Drain `import.meta.hot.dispose(cb)` callbacks via the JS hot
|
|
208
|
+
// registry before Angular's reboot.
|
|
209
|
+
//
|
|
210
|
+
// The registry (`hot-context.ts`) owns the dispose map — every call to
|
|
211
|
+
// `import.meta.hot.dispose(cb)` from user code lands there. We pass NO
|
|
212
|
+
// key argument so the registry drains every registered callback across
|
|
213
|
+
// every module, which matches the wholesale-reboot semantics of
|
|
214
|
+
// `__reboot_ng_modules__`: when Angular tears down its component tree
|
|
215
|
+
// and re-bootstraps, every module's accumulated side effects are
|
|
216
|
+
// conceptually being thrown away. (A future per-module HMR client could
|
|
217
|
+
// pass an explicit key list to limit the drain.)
|
|
218
|
+
function runHmrDisposeCallbacks(_g, options) {
|
|
219
|
+
let executed = null;
|
|
220
|
+
try {
|
|
221
|
+
const result = getNsHotRegistry().runDispose();
|
|
222
|
+
executed = typeof result === 'number' ? result : 0;
|
|
223
|
+
}
|
|
224
|
+
catch (err) {
|
|
225
|
+
// Per-callback failures are swallowed inside the registry. If
|
|
226
|
+
// the registry itself throws we MUST NOT take down the HMR cycle.
|
|
227
|
+
if (options.verbose && envVerbose) {
|
|
228
|
+
console.warn('[ns-hmr][client] runDispose threw:', err?.message ?? err);
|
|
229
|
+
}
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
// Surface ONE concise log per HMR cycle that actually had disposers
|
|
233
|
+
// to run. Quiet on cycles where no module had registered any.
|
|
234
|
+
if (executed && executed > 0) {
|
|
235
|
+
console.info(`[ns-hmr][dispose] ran ${executed} import.meta.hot.dispose callback${executed === 1 ? '' : 's'} before reboot`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// Terminate every live worker before Angular's reboot. Two-tier strategy:
|
|
239
|
+
//
|
|
240
|
+
// 1. PREFERRED — `globalThis.__NS_DEV__.terminateAllWorkers()` (NS iOS runtime
|
|
241
|
+
// ≥ the version that ships `Worker::TerminateAllWorkersCallback`).
|
|
242
|
+
// Native code iterates `Caches::Workers` (the runtime's authoritative
|
|
243
|
+
// worker registry) and calls `WorkerWrapper::Terminate()` on each
|
|
244
|
+
// live entry. Universal: catches every worker regardless of how it
|
|
245
|
+
// was created — `new Worker(new URL(...))`, raw `Worker('~/x.js')`,
|
|
246
|
+
// dynamic-import-spawned workers, plugin-spawned workers, etc.
|
|
247
|
+
//
|
|
248
|
+
// 2. FALLBACK — drain `globalThis.__NS_HMR_WORKERS__` (a Set populated
|
|
249
|
+
// by `__nsHmrTrackWorker`, the helper that `workerHmrUrlPlugin`
|
|
250
|
+
// injects at the top of every dev module containing a
|
|
251
|
+
// `new Worker(new URL(...))` call). This keeps HMR worker cleanup
|
|
252
|
+
// working on runtimes that don't expose
|
|
253
|
+
// `__NS_DEV__.terminateAllWorkers`. It only catches workers spawned via
|
|
254
|
+
// the Vite-rewritten path, so the runtime API is strictly better
|
|
255
|
+
// coverage.
|
|
256
|
+
//
|
|
257
|
+
// Either way: producer-side wraps are still useful as diagnostic
|
|
258
|
+
// metadata (which user code spawned which worker), so we always clear
|
|
259
|
+
// the JS Set after termination — irrespective of which tier ran — so
|
|
260
|
+
// it doesn't grow unbounded across HMR cycles.
|
|
261
|
+
//
|
|
262
|
+
// Tolerant of:
|
|
263
|
+
// * Missing globals — non-worker apps have neither global; we no-op.
|
|
264
|
+
// * `terminate()` throwing — the runtime can throw on already-dead
|
|
265
|
+
// workers; we catch per-entry so subsequent terminations and the
|
|
266
|
+
// reboot itself still proceed.
|
|
267
|
+
// * Native API throwing — wrapped in try/catch so a runtime regression
|
|
268
|
+
// can't take down the HMR cycle; we degrade to the JS-Set fallback.
|
|
269
|
+
function terminateTrackedWorkers(g, options) {
|
|
270
|
+
let nativeApi;
|
|
271
|
+
try {
|
|
272
|
+
const candidate = g && readNsRuntimeDevHostApi(g).terminateAllWorkers;
|
|
273
|
+
if (typeof candidate === 'function') {
|
|
274
|
+
nativeApi = candidate;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
// Reading the global threw (extremely defensive — `globalThis`
|
|
279
|
+
// access shouldn't, but Proxy-wrapped globals can).
|
|
280
|
+
}
|
|
281
|
+
let nativeTerminated = null;
|
|
282
|
+
if (nativeApi) {
|
|
283
|
+
try {
|
|
284
|
+
const result = nativeApi.call(g);
|
|
285
|
+
// The native API returns the count of workers terminated;
|
|
286
|
+
// treat any non-number as "ran successfully, count unknown".
|
|
287
|
+
nativeTerminated = typeof result === 'number' ? result : 0;
|
|
288
|
+
}
|
|
289
|
+
catch (err) {
|
|
290
|
+
if (options.verbose && envVerbose) {
|
|
291
|
+
console.warn('[ns-hmr][client] __NS_DEV__.terminateAllWorkers threw; falling back to JS-tracked Set:', err?.message ?? err);
|
|
292
|
+
}
|
|
293
|
+
nativeApi = undefined; // force fallback below
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
// Always touch the JS-tracked Set so producer-side bookkeeping
|
|
297
|
+
// doesn't outlive its workers across HMR cycles. If the native API
|
|
298
|
+
// already terminated everything, this is just a `.clear()`. If the
|
|
299
|
+
// runtime doesn't expose the primitive, this is the actual cleanup
|
|
300
|
+
// path.
|
|
301
|
+
let workers;
|
|
302
|
+
try {
|
|
303
|
+
workers = g && g.__NS_HMR_WORKERS__;
|
|
304
|
+
}
|
|
305
|
+
catch {
|
|
306
|
+
// fall through with `workers === undefined`
|
|
307
|
+
}
|
|
308
|
+
let fallbackTerminated = 0;
|
|
309
|
+
let fallbackFailed = 0;
|
|
310
|
+
const fallbackTotal = workers && typeof workers.size === 'number' ? workers.size : 0;
|
|
311
|
+
if (!nativeApi && workers && fallbackTotal > 0) {
|
|
312
|
+
// No native API — drain the JS-tracked Set as the primary path.
|
|
313
|
+
for (const worker of workers) {
|
|
122
314
|
try {
|
|
123
|
-
|
|
315
|
+
if (worker && typeof worker.terminate === 'function') {
|
|
316
|
+
worker.terminate();
|
|
317
|
+
fallbackTerminated++;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
catch {
|
|
321
|
+
fallbackFailed++;
|
|
124
322
|
}
|
|
125
|
-
catch { }
|
|
126
323
|
}
|
|
324
|
+
}
|
|
325
|
+
if (workers) {
|
|
326
|
+
try {
|
|
327
|
+
workers.clear();
|
|
328
|
+
}
|
|
329
|
+
catch { }
|
|
330
|
+
}
|
|
331
|
+
// Surface ONE concise log per HMR cycle when there was actually work
|
|
332
|
+
// to do. This isn't gated on `verbose` so the user can see in the
|
|
333
|
+
// dev terminal which cleanup tier ran without flipping a flag —
|
|
334
|
+
// it's a single line per HMR-cycle-with-workers, never per cycle
|
|
335
|
+
// when no workers exist. Filter on "actually did something" so we
|
|
336
|
+
// stay quiet on no-worker apps and on cycles where neither tier
|
|
337
|
+
// found anything.
|
|
338
|
+
if (nativeApi && (nativeTerminated ?? 0) > 0) {
|
|
339
|
+
console.info(`[ns-hmr][workers] terminated ${nativeTerminated} via runtime __NS_DEV__.terminateAllWorkers before reboot`);
|
|
340
|
+
}
|
|
341
|
+
else if (!nativeApi && fallbackTerminated > 0) {
|
|
342
|
+
console.info(`[ns-hmr][workers] terminated ${fallbackTerminated}/${fallbackTotal} via JS-tracked Set before reboot (__NS_DEV__.terminateAllWorkers not exposed by this runtime)`);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
// Narrow an unknown eviction-list entry to a fetchable http(s) URL. Shared by
|
|
346
|
+
// the reboot path (refreshAngularBootstrapOptions) and the leaf re-import
|
|
347
|
+
// fallback so the two stay in lockstep on what counts as a valid evict URL.
|
|
348
|
+
const isHttpUrl = (u) => typeof u === 'string' && /^https?:\/\//.test(u);
|
|
349
|
+
function invalidateModules(urls, verbose) {
|
|
350
|
+
if (!urls || !urls.length)
|
|
351
|
+
return false;
|
|
352
|
+
const fn = readNsRuntimeDevHostApi(globalThis).invalidateModules;
|
|
353
|
+
if (typeof fn !== 'function') {
|
|
354
|
+
console.warn(`[ns-hmr][client] runtime missing __NS_DEV__.invalidateModules (runtime/vite version mismatch?); update cannot apply. evict=${urls.length}`);
|
|
127
355
|
return false;
|
|
128
356
|
}
|
|
129
357
|
try {
|
|
130
|
-
|
|
358
|
+
if (verbose && envVerbose) {
|
|
359
|
+
console.info(`[ns-hmr][client] invalidateModules calling __NS_DEV__.invalidateModules urls=${urls.length}`);
|
|
360
|
+
}
|
|
361
|
+
fn.call(null, urls.slice());
|
|
362
|
+
if (verbose && envVerbose) {
|
|
363
|
+
console.info(`[ns-hmr][client] invalidateModules OK urls=${urls.length}`);
|
|
364
|
+
}
|
|
131
365
|
return true;
|
|
132
366
|
}
|
|
133
367
|
catch (error) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
catch { }
|
|
139
|
-
}
|
|
368
|
+
// Real exception path — the runtime hook itself threw. Always
|
|
369
|
+
// surfaced for the same reason as the missing-hook warn above.
|
|
370
|
+
console.warn('[ns-hmr][client] __NS_DEV__.invalidateModules threw', error?.message || error);
|
|
140
371
|
return false;
|
|
141
372
|
}
|
|
142
373
|
}
|
|
143
|
-
//
|
|
374
|
+
// Eviction-set size cap for the kickstart.
|
|
144
375
|
//
|
|
145
376
|
// `__NS_HMR_KICKSTART_MAX_URLS__` is a build-time literal injected
|
|
146
377
|
// by `helpers/global-defines.ts` (default 32). It is a pure
|
|
147
378
|
// performance gate: the kickstart never affects correctness, so
|
|
148
|
-
// skipping it for large fan-out edits
|
|
149
|
-
//
|
|
379
|
+
// skipping it for large fan-out edits simply reverts the runtime to
|
|
380
|
+
// sequential `HttpFetchText`. See the doc comment on
|
|
150
381
|
// `resolveHmrKickstartMaxUrls` (in global-defines.ts) for the
|
|
151
382
|
// rationale and the empirical numbers behind the default.
|
|
152
383
|
//
|
|
@@ -156,19 +387,30 @@ function invalidateModules(urls, verbose) {
|
|
|
156
387
|
// see `undefined` and fall back to the default.
|
|
157
388
|
const KICKSTART_DEFAULT_MAX_URLS = 32;
|
|
158
389
|
const kickstartMaxUrls = (() => {
|
|
159
|
-
|
|
160
|
-
|
|
390
|
+
// Define substitution does not reach this raw-served file — fall back to
|
|
391
|
+
// the globalThis seed planted by the entry's defines-seed module.
|
|
392
|
+
const normalize = (raw) => {
|
|
161
393
|
if (typeof raw !== 'number')
|
|
162
|
-
return
|
|
394
|
+
return null;
|
|
163
395
|
if (!Number.isFinite(raw))
|
|
164
396
|
return Number.POSITIVE_INFINITY;
|
|
165
397
|
if (raw < 0)
|
|
166
|
-
return
|
|
398
|
+
return null;
|
|
167
399
|
return Math.floor(raw);
|
|
400
|
+
};
|
|
401
|
+
try {
|
|
402
|
+
const substituted = normalize(__NS_HMR_KICKSTART_MAX_URLS__);
|
|
403
|
+
if (substituted !== null)
|
|
404
|
+
return substituted;
|
|
168
405
|
}
|
|
169
|
-
catch {
|
|
170
|
-
|
|
406
|
+
catch { }
|
|
407
|
+
try {
|
|
408
|
+
const seeded = normalize(getGlobalScope().__NS_HMR_KICKSTART_MAX_URLS__);
|
|
409
|
+
if (seeded !== null)
|
|
410
|
+
return seeded;
|
|
171
411
|
}
|
|
412
|
+
catch { }
|
|
413
|
+
return KICKSTART_DEFAULT_MAX_URLS;
|
|
172
414
|
})();
|
|
173
415
|
// Decide whether to run the kickstart for a given eviction set.
|
|
174
416
|
// Exported for unit testing — callers in this module use the inline
|
|
@@ -181,8 +423,7 @@ const kickstartMaxUrls = (() => {
|
|
|
181
423
|
// - `urls.length > cap` → skip kickstart (returns false). V8 falls
|
|
182
424
|
// back to per-module synchronous fetches inside its module walk.
|
|
183
425
|
// - `cap === 0` → kickstart disabled regardless of size.
|
|
184
|
-
// - `cap === Infinity` → kickstart always eligible (
|
|
185
|
-
// behavior).
|
|
426
|
+
// - `cap === Infinity` → kickstart always eligible (no cap).
|
|
186
427
|
export function shouldRunKickstart(urlCount, maxUrls = kickstartMaxUrls) {
|
|
187
428
|
if (!Number.isFinite(urlCount) || urlCount <= 0)
|
|
188
429
|
return false;
|
|
@@ -195,14 +436,10 @@ export function shouldRunKickstart(urlCount, maxUrls = kickstartMaxUrls) {
|
|
|
195
436
|
function kickstartHmrPrefetch(urls, verbose) {
|
|
196
437
|
if (!urls || !urls.length)
|
|
197
438
|
return null;
|
|
198
|
-
const
|
|
199
|
-
const fn = g.__nsKickstartHmrPrefetch;
|
|
439
|
+
const fn = readNsRuntimeDevHostApi(globalThis).kickstartPrefetch;
|
|
200
440
|
if (typeof fn !== 'function') {
|
|
201
441
|
if (verbose && envVerbose) {
|
|
202
|
-
|
|
203
|
-
console.info(`[hmr-angular] runtime missing __nsKickstartHmrPrefetch; serial fetches will be used. urls=${urls.length}`);
|
|
204
|
-
}
|
|
205
|
-
catch { }
|
|
442
|
+
console.info(`[hmr-angular] runtime missing __NS_DEV__.kickstartPrefetch; serial fetches will be used. urls=${urls.length}`);
|
|
206
443
|
}
|
|
207
444
|
return null;
|
|
208
445
|
}
|
|
@@ -222,17 +459,17 @@ function kickstartHmrPrefetch(urls, verbose) {
|
|
|
222
459
|
}
|
|
223
460
|
catch (error) {
|
|
224
461
|
if (verbose && envVerbose) {
|
|
225
|
-
|
|
226
|
-
console.warn('[hmr-angular] __nsKickstartHmrPrefetch threw', error?.message || error);
|
|
227
|
-
}
|
|
228
|
-
catch { }
|
|
462
|
+
console.warn('[hmr-angular] __NS_DEV__.kickstartPrefetch threw', error?.message || error);
|
|
229
463
|
}
|
|
230
464
|
return null;
|
|
231
465
|
}
|
|
232
466
|
}
|
|
233
467
|
function getAngularBootstrapEntryCandidates(msg) {
|
|
234
|
-
|
|
235
|
-
//
|
|
468
|
+
// Define substitution does not reach this raw-served file; prefer the
|
|
469
|
+
// globalThis seed from the entry's defines-seed module ('app/'-rooted
|
|
470
|
+
// projects would otherwise get the wrong '/src' default).
|
|
471
|
+
const root = (typeof __NS_APP_ROOT_VIRTUAL__ === 'string' && __NS_APP_ROOT_VIRTUAL__) || (typeof getGlobalScope().__NS_APP_ROOT_VIRTUAL__ === 'string' && getGlobalScope().__NS_APP_ROOT_VIRTUAL__) || '/src';
|
|
472
|
+
// Server announces the canonical bootstrap entry as
|
|
236
473
|
// `importerEntry`, computed from `package.json#main`. Fall back to
|
|
237
474
|
// the legacy `entryCandidates` array (for older servers) and finally
|
|
238
475
|
// to a hard-coded list. All candidates must be project-relative
|
|
@@ -271,34 +508,45 @@ export async function refreshAngularBootstrapOptions(msg, options) {
|
|
|
271
508
|
return;
|
|
272
509
|
}
|
|
273
510
|
const origin = originSource.replace(/\/$/, '');
|
|
274
|
-
//
|
|
275
|
-
//
|
|
276
|
-
//
|
|
277
|
-
//
|
|
278
|
-
//
|
|
279
|
-
//
|
|
280
|
-
//
|
|
281
|
-
//
|
|
282
|
-
|
|
283
|
-
//
|
|
284
|
-
|
|
285
|
-
//
|
|
286
|
-
//
|
|
287
|
-
//
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
511
|
+
// Explicit eviction set takes precedence over URL versioning. The
|
|
512
|
+
// server walks the inverse-dep closure of the changed file
|
|
513
|
+
// (collectAngularEvictionUrls) and emits canonical /ns/m/<rel> URLs
|
|
514
|
+
// in `evictPaths`. We hand the list to the runtime before
|
|
515
|
+
// re-importing the entry; the runtime drops those entries from
|
|
516
|
+
// `g_moduleRegistry` so V8's subsequent `import(entry)` walks the
|
|
517
|
+
// dep graph and re-fetches ONLY those modules. Everything else stays
|
|
518
|
+
// hot in the cache.
|
|
519
|
+
const evictPaths = Array.isArray(msg?.evictPaths) ? msg.evictPaths.filter(isHttpUrl) : [];
|
|
520
|
+
// Diagnostic: log eviction set client-side so we can verify what
|
|
521
|
+
// the runtime is being asked to drop. Up to 32 entries are sampled
|
|
522
|
+
// so large constants edits don't swamp the console. Gated behind
|
|
523
|
+
// the standard `__NS_ENV_VERBOSE__` build define (`NS_VITE_VERBOSE`)
|
|
524
|
+
// so the lines stay silent on normal saves.
|
|
525
|
+
if (options.verbose && envVerbose) {
|
|
526
|
+
const _path = typeof msg?.path === 'string' ? msg.path : '(unknown)';
|
|
527
|
+
console.info(`[ns-hmr][client] received ns:angular-update path=${_path} evictPaths.length=${evictPaths.length} importerEntry=${msg?.importerEntry ?? '(none)'}`);
|
|
528
|
+
if (evictPaths.length) {
|
|
529
|
+
const sample = evictPaths.slice(0, 32);
|
|
530
|
+
console.info(`[ns-hmr][client] evictPaths firstN=`, sample);
|
|
531
|
+
if (evictPaths.length > sample.length) {
|
|
532
|
+
console.info(`[ns-hmr][client] evictPaths hidden=${evictPaths.length - sample.length}`);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
// Drive the apply-progress overlay through the 'evicting' frame
|
|
537
|
+
// *before* the runtime invalidate call so the user sees the count
|
|
538
|
+
// even on the cheapest stage. Eviction count also doubles as a
|
|
539
|
+
// useful debug breadcrumb in the overlay's detail line — large
|
|
540
|
+
// counts (e.g. constants edits → 100+ importers) explain why a
|
|
541
|
+
// cycle takes longer than an HTML edit.
|
|
291
542
|
setUpdateOverlayStage('evicting', {
|
|
292
543
|
detail: evictPaths.length ? `Invalidating ${evictPaths.length} module${evictPaths.length === 1 ? '' : 's'}` : 'Invalidating module cache',
|
|
293
544
|
});
|
|
294
545
|
const evicted = invalidateModules(evictPaths, options.verbose);
|
|
295
546
|
if (options.verbose && envVerbose) {
|
|
296
|
-
|
|
297
|
-
console.info(`[ns-hmr][angular] evict count=${evictPaths.length} ok=${evicted ? 'yes' : 'no'}`);
|
|
298
|
-
}
|
|
299
|
-
catch { }
|
|
547
|
+
console.info(`[ns-hmr][client] evict count=${evictPaths.length} ok=${evicted ? 'yes' : 'no'}`);
|
|
300
548
|
}
|
|
301
|
-
//
|
|
549
|
+
// Parallel HTTP prefetch for the freshly-evicted modules.
|
|
302
550
|
//
|
|
303
551
|
// Order matters here: the kickstart MUST run after the eviction so
|
|
304
552
|
// that it actually re-populates `g_prefetchCache` for the modules
|
|
@@ -307,68 +555,51 @@ export async function refreshAngularBootstrapOptions(msg, options) {
|
|
|
307
555
|
// destructively but the prior non-evicted modules sit in V8's
|
|
308
556
|
// `g_moduleRegistry`, not the prefetch cache).
|
|
309
557
|
//
|
|
310
|
-
// We only kickstart when the eviction succeeded
|
|
311
|
-
//
|
|
312
|
-
//
|
|
313
|
-
// would not match its prefetch cache lookups against the version-
|
|
314
|
-
// prefixed forms V8 will end up requesting. Better to skip the
|
|
315
|
-
// optimization than risk a confusing partial cache hit.
|
|
558
|
+
// We only kickstart when the eviction succeeded — eviction is what
|
|
559
|
+
// arms the bust-next-fetch nonce, so a kickstart without it would
|
|
560
|
+
// just re-cache the stale bodies the OS cache is still serving.
|
|
316
561
|
//
|
|
317
|
-
//
|
|
318
|
-
//
|
|
319
|
-
//
|
|
562
|
+
// `shouldRunKickstart` gates large eviction sets out of the
|
|
563
|
+
// parallel wave. A `.ts` file with deep inverse-dep fan-in
|
|
564
|
+
// (constants files, design-system enums) can produce a
|
|
320
565
|
// 200–300-URL closure that overwhelms Vite's single-threaded
|
|
321
566
|
// transform pipeline. The kickstart fan-out then makes the cycle
|
|
322
567
|
// 5–8× slower than letting V8 fetch sequentially as it walks the
|
|
323
568
|
// real forward path. The cap (default 32, override with
|
|
324
569
|
// `NS_VITE_KICKSTART_MAX_URLS`) keeps component-shaped closures
|
|
325
570
|
// (typically 5–30 URLs) on the fast path. Correctness is
|
|
326
|
-
// unaffected — V8's per-module synchronous fetch is the same
|
|
327
|
-
// path the runtime
|
|
571
|
+
// unaffected — V8's per-module synchronous fetch is the same fall-
|
|
572
|
+
// back code path the runtime has always used.
|
|
328
573
|
if (evicted && evictPaths.length > 0) {
|
|
329
574
|
if (shouldRunKickstart(evictPaths.length)) {
|
|
330
575
|
const result = kickstartHmrPrefetch(evictPaths, options.verbose);
|
|
331
576
|
if (options.verbose && envVerbose && result) {
|
|
332
|
-
|
|
333
|
-
console.info(`[ns-hmr][angular] kickstart urls=${evictPaths.length} fetched=${result.fetched} ok=${result.ok ? 'yes' : 'no'} ms=${result.ms}`);
|
|
334
|
-
}
|
|
335
|
-
catch { }
|
|
577
|
+
console.info(`[ns-hmr][angular] kickstart urls=${evictPaths.length} fetched=${result.fetched} ok=${result.ok ? 'yes' : 'no'} ms=${result.ms}`);
|
|
336
578
|
}
|
|
337
579
|
}
|
|
338
580
|
else if (options.verbose && envVerbose) {
|
|
339
|
-
|
|
340
|
-
console.info(`[ns-hmr][angular] kickstart skipped urls=${evictPaths.length} cap=${Number.isFinite(kickstartMaxUrls) ? kickstartMaxUrls : 'Infinity'} (eviction set too large; falling back to sequential fetch)`);
|
|
341
|
-
}
|
|
342
|
-
catch { }
|
|
581
|
+
console.info(`[ns-hmr][angular] kickstart skipped urls=${evictPaths.length} cap=${Number.isFinite(kickstartMaxUrls) ? kickstartMaxUrls : 'Infinity'} (eviction set too large; falling back to sequential fetch)`);
|
|
343
582
|
}
|
|
344
583
|
}
|
|
345
|
-
// URL strategy:
|
|
346
|
-
//
|
|
347
|
-
//
|
|
348
|
-
//
|
|
349
|
-
//
|
|
350
|
-
//
|
|
351
|
-
//
|
|
352
|
-
//
|
|
353
|
-
// or the runtime lacks `__nsInvalidateModules` (older runtime).
|
|
354
|
-
// Fall back to the legacy `__ns_hmr__/v<version>/` URL pattern
|
|
355
|
-
// so V8 sees a fresh URL and re-fetches the entry. The runtime
|
|
356
|
-
// canonicalizer (alpha.59) collapses the path back to the stable
|
|
357
|
-
// key, which keeps cache identity consistent across saves.
|
|
358
|
-
const versionRaw = typeof msg?.version === 'number' ? msg.version : 0;
|
|
359
|
-
const useStableUrls = evicted;
|
|
584
|
+
// URL strategy: always the STABLE canonical URL. The eviction removed
|
|
585
|
+
// the changed modules from V8's registry (and armed the runtime's
|
|
586
|
+
// bust-next-fetch nonce), so re-importing the entry under its
|
|
587
|
+
// canonical URL triggers fresh fetches for exactly the evicted
|
|
588
|
+
// modules; the rest of the graph is a cache hit. Never version or
|
|
589
|
+
// tag the URL — the runtime treats the literal URL as module
|
|
590
|
+
// identity, so a tagged re-import would mint a second module
|
|
591
|
+
// identity instead of refreshing the first.
|
|
360
592
|
let lastError;
|
|
361
|
-
//
|
|
362
|
-
//
|
|
363
|
-
//
|
|
364
|
-
//
|
|
365
|
-
//
|
|
366
|
-
// candidate (the common case).
|
|
593
|
+
// 'reimporting' is the entry point for the long tail of an HMR
|
|
594
|
+
// cycle: V8 walks the freshly-evicted graph and the iOS runtime
|
|
595
|
+
// re-fetches each node from the dev server. We announce the stage
|
|
596
|
+
// once, before the loop, so the user sees a progress jump even when
|
|
597
|
+
// the import resolves on the first candidate (the common case).
|
|
367
598
|
setUpdateOverlayStage('reimporting', {
|
|
368
599
|
detail: 'Re-importing Angular bootstrap entry',
|
|
369
600
|
});
|
|
370
601
|
for (const entry of getAngularBootstrapEntryCandidates(msg)) {
|
|
371
|
-
const url =
|
|
602
|
+
const url = `${origin}/ns/m${entry}`;
|
|
372
603
|
try {
|
|
373
604
|
g.__NS_ANGULAR_HMR_REGISTER_ONLY__ = true;
|
|
374
605
|
await importAngularBootstrapEntry(url);
|
|
@@ -382,21 +613,18 @@ export async function refreshAngularBootstrapOptions(msg, options) {
|
|
|
382
613
|
}
|
|
383
614
|
}
|
|
384
615
|
if (options.verbose && envVerbose && lastError) {
|
|
385
|
-
|
|
386
|
-
console.warn('[hmr-angular] failed to refresh Angular bootstrap entry', lastError?.message || lastError);
|
|
387
|
-
}
|
|
388
|
-
catch { }
|
|
616
|
+
console.warn('[hmr-angular] failed to refresh Angular bootstrap entry', lastError?.message || lastError);
|
|
389
617
|
}
|
|
390
618
|
}
|
|
391
619
|
export async function handleAngularHotUpdateMessage(msg, options) {
|
|
392
620
|
if (!msg || msg.type !== 'ns:angular-update') {
|
|
393
621
|
return false;
|
|
394
622
|
}
|
|
395
|
-
//
|
|
396
|
-
//
|
|
397
|
-
//
|
|
398
|
-
//
|
|
399
|
-
//
|
|
623
|
+
// Cycle mutex. See `inFlightHmrCycle` for why this is necessary. We
|
|
624
|
+
// publish `thisCycle` *before* awaiting the previous one so a third
|
|
625
|
+
// concurrent message sees the latest in-flight, not the stale
|
|
626
|
+
// previous. This serializes N concurrent updates into a single FIFO
|
|
627
|
+
// chain.
|
|
400
628
|
const previousCycle = inFlightHmrCycle;
|
|
401
629
|
let resolveCycle;
|
|
402
630
|
const thisCycle = new Promise((resolve) => {
|
|
@@ -417,15 +645,12 @@ export async function handleAngularHotUpdateMessage(msg, options) {
|
|
|
417
645
|
let tEnd = t0;
|
|
418
646
|
const filePath = typeof msg?.path === 'string' ? msg.path : '<unknown>';
|
|
419
647
|
const emitTiming = (ok, errorMessage) => {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
console.info(`[ns-hmr][angular] ${status} file=${filePath} refresh=${refreshMs}ms reboot=${rebootMs}ms total=${totalMs}ms${suffix}`);
|
|
427
|
-
}
|
|
428
|
-
catch { }
|
|
648
|
+
const refreshMs = Math.max(0, tAfterRefresh - t0);
|
|
649
|
+
const rebootMs = Math.max(0, tEnd - tAfterRefresh);
|
|
650
|
+
const totalMs = Math.max(0, tEnd - t0);
|
|
651
|
+
const status = ok ? 'ok' : 'FAILED';
|
|
652
|
+
const suffix = errorMessage ? ` error=${errorMessage}` : '';
|
|
653
|
+
console.info(`[ns-hmr][angular] ${status} file=${filePath} refresh=${refreshMs}ms reboot=${rebootMs}ms total=${totalMs}ms${suffix}`);
|
|
429
654
|
};
|
|
430
655
|
// Show the apply-progress overlay as soon as the
|
|
431
656
|
// mutex unblocks us. Posting this *after* the awaited
|
|
@@ -439,6 +664,31 @@ export async function handleAngularHotUpdateMessage(msg, options) {
|
|
|
439
664
|
setUpdateOverlayStage('received', { detail: overlayDetail });
|
|
440
665
|
try {
|
|
441
666
|
const g = globalThis;
|
|
667
|
+
// Vite-spec entry: `vite:beforeUpdate` fires as soon as the
|
|
668
|
+
// client receives an update message, BEFORE any work begins
|
|
669
|
+
// (refresh, dispose, reboot). User listeners can use this to
|
|
670
|
+
// pause animations, cancel in-flight requests, etc. Payload
|
|
671
|
+
// matches Vite's `Update[]` shape loosely — `path` is the
|
|
672
|
+
// canonical changed file, `evictPaths` is the eviction
|
|
673
|
+
// closure the server already computed.
|
|
674
|
+
const updatePayload = {
|
|
675
|
+
type: 'js-update',
|
|
676
|
+
path: typeof msg?.path === 'string' ? msg.path : null,
|
|
677
|
+
evictPaths: Array.isArray(msg?.evictPaths) ? msg.evictPaths : [],
|
|
678
|
+
timestamp: t0,
|
|
679
|
+
};
|
|
680
|
+
dispatchHotEvent(g, 'vite:beforeUpdate', { updates: [updatePayload] });
|
|
681
|
+
// Declined-module short-circuit. If any updated module called
|
|
682
|
+
// `import.meta.hot.decline()`, we MUST do a full reload per
|
|
683
|
+
// Vite spec rather than the hot-update path. `triggerFullReload`
|
|
684
|
+
// also dispatches `vite:beforeFullReload`. The reload tears the
|
|
685
|
+
// JS realm down so we don't need to do any further bookkeeping
|
|
686
|
+
// here — return early.
|
|
687
|
+
if (checkDeclinedAndReload(g, msg, options)) {
|
|
688
|
+
tEnd = Date.now();
|
|
689
|
+
emitTiming(true);
|
|
690
|
+
return true;
|
|
691
|
+
}
|
|
442
692
|
// Prefer __reboot_ng_modules__ — it properly disposes existing modules,
|
|
443
693
|
// re-bootstraps Angular inside NgZone, and sets the root view internally.
|
|
444
694
|
// __NS_ANGULAR_BOOTSTRAP__ is exposed as a secondary signal that the
|
|
@@ -447,8 +697,23 @@ export async function handleAngularHotUpdateMessage(msg, options) {
|
|
|
447
697
|
const reboot = g.__reboot_ng_modules__;
|
|
448
698
|
if (typeof reboot === 'function') {
|
|
449
699
|
if (options.verbose && envVerbose) {
|
|
450
|
-
console.
|
|
700
|
+
console.info('[ns-hmr][client] calling __reboot_ng_modules__');
|
|
451
701
|
}
|
|
702
|
+
// Pre-import reset: clear Angular's `GENERATED_COMP_IDS` map BEFORE
|
|
703
|
+
// the changed component modules are re-imported. If we don't, every
|
|
704
|
+
// touched component's `ɵɵdefineComponent` call hashes to the same
|
|
705
|
+
// id as its predecessor (selectors + className haven't changed),
|
|
706
|
+
// hits a "previousCompDefType !== componentDef.type" collision, and
|
|
707
|
+
// surfaces NG0912 "Component ID generation collision detected".
|
|
708
|
+
// The map is cleared again post-reboot as a safety net, but doing
|
|
709
|
+
// it once here suppresses the warning at the source.
|
|
710
|
+
try {
|
|
711
|
+
const preResetCompiled = g.__reset_ng_compiled_components__;
|
|
712
|
+
if (typeof preResetCompiled === 'function') {
|
|
713
|
+
preResetCompiled();
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
catch { }
|
|
452
717
|
await refreshAngularBootstrapOptions(msg, options);
|
|
453
718
|
tAfterRefresh = Date.now();
|
|
454
719
|
try {
|
|
@@ -459,11 +724,46 @@ export async function handleAngularHotUpdateMessage(msg, options) {
|
|
|
459
724
|
g.__NS_DEV_RESET_IN_PROGRESS__ = true;
|
|
460
725
|
}
|
|
461
726
|
catch { }
|
|
462
|
-
//
|
|
463
|
-
//
|
|
464
|
-
//
|
|
465
|
-
//
|
|
466
|
-
//
|
|
727
|
+
// Two-step pre-reboot cleanup. Order matters: dispose runs
|
|
728
|
+
// FIRST so user-code disposers see a still-live runtime
|
|
729
|
+
// (sockets, workers, etc.) and can issue graceful "I'm
|
|
730
|
+
// going away" messages; then we hard-terminate any worker
|
|
731
|
+
// the user didn't manually clean up.
|
|
732
|
+
//
|
|
733
|
+
// Step 1 — `import.meta.hot.dispose(cb)` callbacks
|
|
734
|
+
// ────────────────────────────────────────────────
|
|
735
|
+
// The JS hot registry (`hot-context.ts`) walks its
|
|
736
|
+
// per-module dispose map — populated by
|
|
737
|
+
// `import.meta.hot.dispose(cb)` — and invokes every
|
|
738
|
+
// callback with that module's `hot.data` object, matching
|
|
739
|
+
// the Vite spec.
|
|
740
|
+
//
|
|
741
|
+
// This is the standards-compliant cleanup hook every Vite
|
|
742
|
+
// user already knows. Apps register their intervals,
|
|
743
|
+
// listeners, sockets, store subscriptions, etc. via
|
|
744
|
+
// `import.meta.hot.dispose(...)` and they're guaranteed to
|
|
745
|
+
// fire before the next Angular reboot — no NS-specific
|
|
746
|
+
// knowledge required.
|
|
747
|
+
runHmrDisposeCallbacks(g, options);
|
|
748
|
+
// Step 2 — worker auto-terminate (defence in depth)
|
|
749
|
+
// ───────────────────────────────────────────────────
|
|
750
|
+
// Even with perfect dispose() coverage, workers spawned
|
|
751
|
+
// from constructors that re-run on Angular reboot (e.g.
|
|
752
|
+
// `new Worker(...)` inside `AppComponent`'s constructor)
|
|
753
|
+
// don't fire dispose for `app.component.ts` when only
|
|
754
|
+
// `login.component.html` changes — `app.component.ts`
|
|
755
|
+
// isn't being replaced, so its disposers don't run per
|
|
756
|
+
// Vite spec. The runtime API
|
|
757
|
+
// `__NS_DEV__.terminateAllWorkers()` doesn't care about module
|
|
758
|
+
// boundaries; it just kills every live worker in
|
|
759
|
+
// `Caches::Workers`. Falls back to the
|
|
760
|
+
// `__NS_HMR_WORKERS__` JS Set when the runtime doesn't
|
|
761
|
+
// expose the primitive.
|
|
762
|
+
terminateTrackedWorkers(g, options);
|
|
763
|
+
// 'rebooting' marks the long tail of the cycle: NgZone
|
|
764
|
+
// teardown, module re-instantiation, and resetRootView.
|
|
765
|
+
// The detail line shows refresh-so-far ms so a user can
|
|
766
|
+
// already see if the slow phase is re-import or reboot.
|
|
467
767
|
setUpdateOverlayStage('rebooting', {
|
|
468
768
|
detail: `Re-bootstrapping Angular (refresh ${Math.max(0, tAfterRefresh - t0)}ms)`,
|
|
469
769
|
});
|
|
@@ -478,33 +778,100 @@ export async function handleAngularHotUpdateMessage(msg, options) {
|
|
|
478
778
|
}
|
|
479
779
|
tEnd = Date.now();
|
|
480
780
|
emitTiming(true);
|
|
481
|
-
//
|
|
482
|
-
//
|
|
483
|
-
//
|
|
484
|
-
//
|
|
781
|
+
// Vite-spec exit: `vite:afterUpdate` fires after the update
|
|
782
|
+
// has been successfully applied. User code can re-attach
|
|
783
|
+
// any state torn down by `vite:beforeUpdate` (resume
|
|
784
|
+
// animations, re-fetch, etc.). Same payload shape as
|
|
785
|
+
// `vite:beforeUpdate` so listeners can correlate.
|
|
786
|
+
dispatchHotEvent(g, 'vite:afterUpdate', { updates: [updatePayload] });
|
|
787
|
+
// 'complete' surfaces the wall-clock total so a user gets a
|
|
788
|
+
// single-glance confirmation matching the [ns-hmr][angular]
|
|
789
|
+
// log line in the terminal. The overlay auto-hides shortly
|
|
790
|
+
// after.
|
|
485
791
|
setUpdateOverlayStage('complete', {
|
|
486
792
|
detail: `Total ${Math.max(0, tEnd - t0)}ms`,
|
|
487
793
|
});
|
|
488
794
|
return true;
|
|
489
795
|
}
|
|
796
|
+
// Reached only when the NgModule reboot path above was skipped — i.e.
|
|
797
|
+
// `g.__reboot_ng_modules__` was not a function at the time this update
|
|
798
|
+
// arrived, so no full re-bootstrap ran. (That handler is installed by
|
|
799
|
+
// `runNativeScriptAngularApp()`, so this is NOT about how the app boots;
|
|
800
|
+
// it covers the window where the handler isn't registered yet, or any
|
|
801
|
+
// update that never wires one up.) Fall back to the standard Vite
|
|
802
|
+
// leaf-module path: evict + re-import the changed module(s) so their
|
|
803
|
+
// top-level side-effects and `import.meta.hot.accept` callbacks re-run
|
|
804
|
+
// WITHOUT a full reboot. The server narrows leaf edits (no @Component/
|
|
805
|
+
// @Directive/@Pipe/@Injectable/@NgModule decorator) to just the changed
|
|
806
|
+
// file, so this is cheap. This is what makes self-accepting utility
|
|
807
|
+
// modules (e.g. a live-tuning module that posts values to native on
|
|
808
|
+
// evaluation) hot-reload at all — without it they were silently dropped
|
|
809
|
+
// here.
|
|
810
|
+
try {
|
|
811
|
+
const origin = (typeof g.__NS_HTTP_ORIGIN__ === 'string' ? g.__NS_HTTP_ORIGIN__ : '').replace(/\/$/, '');
|
|
812
|
+
let urls = Array.isArray(msg?.evictPaths) ? msg.evictPaths.filter(isHttpUrl) : [];
|
|
813
|
+
// Derive the canonical /ns/m/<rel> URL from msg.path when the server
|
|
814
|
+
// sent no evictPaths (V8 keys app modules by their extensionless URL).
|
|
815
|
+
if (!urls.length && typeof msg?.path === 'string' && origin) {
|
|
816
|
+
const rel = msg.path.replace(/^\//, '').replace(/\.(?:[mc]?[jt]sx?)$/i, '');
|
|
817
|
+
urls = [`${origin}/ns/m/${rel}`];
|
|
818
|
+
}
|
|
819
|
+
if (urls.length) {
|
|
820
|
+
setUpdateOverlayStage('reimporting', { detail: `Re-importing ${urls.length} module${urls.length === 1 ? '' : 's'}` });
|
|
821
|
+
invalidateModules(urls, options.verbose);
|
|
822
|
+
const nonce = (typeof g.__NS_HMR_IMPORT_NONCE__ === 'number' ? g.__NS_HMR_IMPORT_NONCE__ : 0) + 1;
|
|
823
|
+
g.__NS_HMR_IMPORT_NONCE__ = nonce;
|
|
824
|
+
let reimported = 0;
|
|
825
|
+
for (const u of urls) {
|
|
826
|
+
try {
|
|
827
|
+
await importAngularBootstrapEntry(`${u}${u.includes('?') ? '&' : '?'}hmr=${nonce}`);
|
|
828
|
+
reimported++;
|
|
829
|
+
}
|
|
830
|
+
catch (e) {
|
|
831
|
+
if (options.verbose) {
|
|
832
|
+
console.warn('[ns-hmr][leaf] re-import failed', u, (e && e.message) || e);
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
const ok = reimported > 0;
|
|
837
|
+
tEnd = Date.now();
|
|
838
|
+
emitTiming(ok, ok ? 'leaf-reimport' : 'leaf-reimport-failed');
|
|
839
|
+
hideUpdateOverlay();
|
|
840
|
+
return ok;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
catch (e) {
|
|
844
|
+
if (options.verbose) {
|
|
845
|
+
console.warn('[ns-hmr][leaf] fallback threw', (e && e.message) || e);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
490
848
|
if (options.verbose && envVerbose) {
|
|
491
849
|
console.warn('[hmr-angular] No Angular HMR handler found. Ensure runNativeScriptAngularApp() has been called.');
|
|
492
850
|
}
|
|
493
851
|
tEnd = Date.now();
|
|
494
852
|
emitTiming(false, 'no-reboot-handler');
|
|
495
|
-
// No reboot handler
|
|
496
|
-
//
|
|
853
|
+
// No reboot handler and nothing to re-import → hide the overlay rather
|
|
854
|
+
// than leaving stale progress on screen.
|
|
497
855
|
hideUpdateOverlay();
|
|
498
856
|
}
|
|
499
857
|
catch (error) {
|
|
500
858
|
if (options.verbose) {
|
|
501
|
-
|
|
502
|
-
console.warn('[hmr-angular] failed to handle update', (error && error.message) || error);
|
|
503
|
-
}
|
|
504
|
-
catch { }
|
|
859
|
+
console.warn('[hmr-angular] failed to handle update', (error && error.message) || error);
|
|
505
860
|
}
|
|
506
861
|
tEnd = Date.now();
|
|
507
|
-
|
|
862
|
+
const errorMessage = (error && error.message) || String(error);
|
|
863
|
+
emitTiming(false, errorMessage);
|
|
864
|
+
// Vite-spec error event — fires on any HMR cycle that throws.
|
|
865
|
+
// Payload shape mirrors Vite's `ErrorPayload`: `err: { message,
|
|
866
|
+
// stack? }` plus optional `path`. Soft-fails if no listeners.
|
|
867
|
+
dispatchHotEvent(globalThis, 'vite:error', {
|
|
868
|
+
type: 'error',
|
|
869
|
+
err: {
|
|
870
|
+
message: errorMessage,
|
|
871
|
+
stack: (error && error.stack) || undefined,
|
|
872
|
+
},
|
|
873
|
+
path: typeof msg?.path === 'string' ? msg.path : undefined,
|
|
874
|
+
});
|
|
508
875
|
// Errors → drop the overlay so the user isn't left looking
|
|
509
876
|
// at indefinite progress; the underlying error is already
|
|
510
877
|
// logged above (and surfaced via Vite's standard error
|