| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent edec20a commit 29ef514
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,5 +1,5 @@ | |||
| 1 | - import { describe, expect, it, vi } from 'vitest'; | ||
| 2 | - import { installNavigatedPageHmrReload } from './navigate-app'; | ||
| 1 | + import { afterEach, describe, expect, it, vi } from 'vitest'; | ||
| 2 | + import { inheritAppContext, installNavigatedPageHmrReload, installVueNavigateUsingApp } from './navigate-app'; | ||
| 3 | 3 | import { readFileSync } from 'fs'; | |
| 4 | 4 | import path from 'path'; | |
| 5 | 5 | import { fileURLToPath } from 'url'; | |
@@ -42,15 +42,119 @@ describe('__nsNavigateUsingApp prop forwarding', () => { | |||
| 42 | 42 | expect(callMatch).toBeTruthy(); | |
| 43 | 43 | const argList = callMatch![1]; | |
| 44 | 44 | // Two top-level arguments: component, props | |
| 45 | - expect(argList).toContain('normalizeComponent(comp,'); | ||
| 45 | + expect(argList).toContain('normalizeComponent(target,'); | ||
| 46 | 46 | expect(argList).toMatch(/,\s*opts\s*&&\s*\(opts\s*as\s*any\)\.props\s*$/); | |
| 47 | 47 | }); | |
| 48 | 48 | ||
| 49 | 49 | it('still calls normalizeComponent so non-defineComponent inputs resolve correctly', () => { | |
| 50 | 50 | // Regression guard: a prior refactor passed `comp` directly to AppFactory | |
| 51 | 51 | // which broke <script setup> destinations. The normalizeComponent wrap | |
| 52 | 52 | // must stay in place. | |
| 53 | - expect(navigateSrc).toMatch(/AppFactory\(normalizeComponent\(comp,/); | ||
| 53 | + expect(navigateSrc).toMatch(/AppFactory\(normalizeComponent\(target,/); | ||
| 54 | + }); | ||
| 55 | + }); | ||
| 56 | + | ||
| 57 | + describe('inheritAppContext', () => { | ||
| 58 | + it('fills in components, directives, mixins and globalProperties the page app lacks, never overriding its own', () => { | ||
| 59 | + const Widget = { name: 'Widget' }; | ||
| 60 | + const Own = { name: 'Own' }; | ||
| 61 | + const mixin = { created() {} }; | ||
| 62 | + const focus = {}; | ||
| 63 | + const base = { components: { Widget, Own: { name: 'RootOwn' } }, directives: { focus }, mixins: [mixin], config: { globalProperties: { $http: 'http', $navigateTo: 'root-nav' } } }; | ||
| 64 | + const ctx: any = { components: { Own }, directives: {}, mixins: [mixin], config: { globalProperties: { $navigateTo: 'page-nav' } } }; | ||
| 65 | + inheritAppContext(ctx, base); | ||
| 66 | + expect(ctx.components.Widget).toBe(Widget); | ||
| 67 | + expect(ctx.components.Own).toBe(Own); | ||
| 68 | + expect(ctx.directives.focus).toBe(focus); | ||
| 69 | + expect(ctx.mixins).toEqual([mixin]); | ||
| 70 | + expect(ctx.config.globalProperties).toEqual({ $navigateTo: 'page-nav', $http: 'http' }); | ||
| 71 | + }); | ||
| 72 | + | ||
| 73 | + it('tolerates a missing side', () => { | ||
| 74 | + expect(() => inheritAppContext(null, { components: {} })).not.toThrow(); | ||
| 75 | + expect(() => inheritAppContext({}, null)).not.toThrow(); | ||
| 76 | + }); | ||
| 77 | + }); | ||
| 78 | + | ||
| 79 | + /** | ||
| 80 | + * Drives the installed navigator with a Vue-shaped factory: like Vue's | ||
| 81 | + * createApp, it clones a non-function root component, and the mounted root | ||
| 82 | + * instance's `type` is that clone — the object Vue's HMR `reload` mutates. | ||
| 83 | + */ | ||
| 84 | + describe('__nsNavigateUsingApp page apps', () => { | ||
| 85 | + const g: any = globalThis; | ||
| 86 | + const apps: any[] = []; | ||
| 87 | + | ||
| 88 | + function installFakeVue() { | ||
| 89 | + apps.length = 0; | ||
| 90 | + g.NSVRoot = class NSVRoot {}; | ||
| 91 | + g.createApp = vi.fn((rootComponent: any, rootProps?: any) => { | ||
| 92 | + const type = typeof rootComponent === 'function' ? rootComponent : { ...rootComponent }; | ||
| 93 | + const _context: any = { app: null, config: { globalProperties: { $navigateTo: 'page-nav' } }, mixins: [], components: {}, directives: {}, provides: {} }; | ||
| 94 | + const app: any = { | ||
| 95 | + _context, | ||
| 96 | + rootProps, | ||
| 97 | + mount: vi.fn(() => ({ $el: { nativeView: { constructor: { name: 'Page' } } }, $: { type } })), | ||
| 98 | + unmount: vi.fn(), | ||
| 99 | + }; | ||
| 100 | + _context.app = app; | ||
| 101 | + apps.push(app); | ||
| 102 | + return app; | ||
| 103 | + }); | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + function makeFrame() { | ||
| 107 | + const frame: any = { | ||
| 108 | + currentPage: null, | ||
| 109 | + replacePage: vi.fn(), | ||
| 110 | + once: vi.fn(), | ||
| 111 | + navigate: vi.fn((entry: any) => { | ||
| 112 | + const page = entry.create(); | ||
| 113 | + page.frame = frame; | ||
| 114 | + frame.currentPage = page; | ||
| 115 | + }), | ||
| 116 | + }; | ||
| 117 | + return frame; | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + afterEach(() => { | ||
| 121 | + delete g.createApp; | ||
| 122 | + delete g.NSVRoot; | ||
| 123 | + delete g.__NS_VUE_ROOT_APP__; | ||
| 124 | + }); | ||
| 125 | + | ||
| 126 | + it('inherits the root app recorded by the bridge when no app has navigated yet', () => { | ||
| 127 | + installFakeVue(); | ||
| 128 | + const Widget = { name: 'Widget' }; | ||
| 129 | + g.__NS_VUE_ROOT_APP__ = { _context: { components: { Widget }, directives: {}, mixins: [], provides: {}, config: { globalProperties: { $http: 'http' } } } }; | ||
| 130 | + installVueNavigateUsingApp(); | ||
| 131 | + g.__nsNavigateUsingApp({ name: 'Home', render: () => 'v1' }, { frame: makeFrame() }); | ||
| 132 | + expect(apps).toHaveLength(1); | ||
| 133 | + expect(apps[0]._context.components.Widget).toBe(Widget); | ||
| 134 | + expect(apps[0]._context.config.globalProperties.$http).toBe('http'); | ||
| 135 | + expect(apps[0]._context.config.globalProperties.$navigateTo).toBe('page-nav'); | ||
| 136 | + }); | ||
| 137 | + | ||
| 138 | + it('rebuilds a hot-reloaded page from the mounted type Vue mutated, not from the original component', () => { | ||
| 139 | + installFakeVue(); | ||
| 140 | + installVueNavigateUsingApp(); | ||
| 141 | + const frame = makeFrame(); | ||
| 142 | + const Home = { name: 'Home', render: () => 'v1' }; | ||
| 143 | + g.__nsNavigateUsingApp(Home, { frame }); | ||
| 144 | + const pageApp = apps[0]; | ||
| 145 | + const mountedType = pageApp.mount.mock.results[0].value.$.type; | ||
| 146 | + expect(mountedType).not.toBe(Home); | ||
| 147 | + | ||
| 148 | + // Vue's HMR reload mutates instance.type in place; the original is untouched. | ||
| 149 | + mountedType.render = () => 'v2'; | ||
| 150 | + pageApp._context.reload(); | ||
| 151 | + | ||
| 152 | + expect(frame.replacePage).toHaveBeenCalledTimes(1); | ||
| 153 | + frame.replacePage.mock.calls[0][0].create(); | ||
| 154 | + expect(apps).toHaveLength(2); | ||
| 155 | + const rebuiltFrom = g.createApp.mock.calls[1][0]; | ||
| 156 | + expect(rebuiltFrom.render()).toBe('v2'); | ||
| 157 | + expect(Home.render()).toBe('v1'); | ||
| 54 | 158 | }); | |
| 55 | 159 | }); | |
| 56 | 160 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -121,6 +121,34 @@ export function installNavigatedPageHmrReload({ app, page, rebuild }: NavigatedP | |||
| 121 | 121 | return true; | |
| 122 | 122 | } | |
| 123 | 123 | ||
| 124 | + /** | ||
| 125 | + * Copy the root app's global registrations onto a page app, keeping whatever the | ||
| 126 | + * page app already registered (nativescript-vue's own plugins, pinia). | ||
| 127 | + * @param ctx The page app's `_context`. | ||
| 128 | + * @param base The root app's `_context`. | ||
| 129 | + */ | ||
| 130 | + export function inheritAppContext(ctx: any, base: any): void { | ||
| 131 | + if (!ctx || !base) return; | ||
| 132 | + for (const key of ['components', 'directives'] as const) { | ||
| 133 | + const src = base[key] || {}; | ||
| 134 | + const dst = (ctx[key] ||= {}); | ||
| 135 | + for (const k of Object.keys(src)) { | ||
| 136 | + if (!Object.prototype.hasOwnProperty.call(dst, k)) dst[k] = src[k]; | ||
| 137 | + } | ||
| 138 | + } | ||
| 139 | + if (Array.isArray(base.mixins)) { | ||
| 140 | + const dst: any[] = (ctx.mixins ||= []); | ||
| 141 | + for (const m of base.mixins) if (!dst.includes(m)) dst.push(m); | ||
| 142 | + } | ||
| 143 | + const srcGp = base.config && base.config.globalProperties; | ||
| 144 | + if (srcGp && ctx.config) { | ||
| 145 | + const dstGp = (ctx.config.globalProperties ||= {}); | ||
| 146 | + for (const k of Object.keys(srcGp)) { | ||
| 147 | + if (!(k in dstGp)) dstGp[k] = srcGp[k]; | ||
| 148 | + } | ||
| 149 | + } | ||
| 150 | + } | ||
| 151 | + | ||
| 124 | 152 | // Deterministic navigation using the current Vue app instance rather than vendor-held rootApp. | |
| 125 | 153 | function __nsNavigateUsingApp(comp: any, opts: any = {}) { | |
| 126 | 154 | const g = getGlobalScope(); | |
@@ -143,16 +171,17 @@ function __nsNavigateUsingApp(comp: any, opts: any = {}) { | |||
| 143 | 171 | } catch {} | |
| 144 | 172 | // Build a fresh Page each time the factory is invoked to avoid reusing a Page instance | |
| 145 | 173 | // across fragment recreations (Android) or multiple frame attachments. | |
| 146 | - const buildTarget = () => { | ||
| 147 | - const existingApp = getCurrentApp(); | ||
| 174 | + const buildTarget = (target: any = comp) => { | ||
| 175 | + // Boot-time apps are only known via the bridge's createApp recording. | ||
| 176 | + const existingApp = getCurrentApp() || (g as any).__NS_VUE_ROOT_APP__ || null; | ||
| 148 | 177 | const baseProvides = (existingApp && existingApp._context && existingApp._context.provides) || {}; | |
| 149 | 178 | // Forward `opts.props` as Vue's rootProps so `$navigateTo(Comp, { props: { … } })` | |
| 150 | 179 | // reaches the destination component. nativescript-vue's stock `$navigateTo` | |
| 151 | 180 | // does the same via `createNativeView(target, options?.props, …)` → | |
| 152 | 181 | // `renderer.createApp(component, props)`. Dropping props here would surface | |
| 153 | 182 | // at the destination as `[Vue warn]: Missing required prop` and any | |
| 154 | 183 | // required-prop component would render with `undefined` bindings. | |
| 155 | - const app = AppFactory(normalizeComponent(comp, comp && (comp.__name || comp.name)), opts && (opts as any).props); | ||
| 184 | + const app = AppFactory(normalizeComponent(target, target && (target.__name || target.name)), opts && (opts as any).props); | ||
| 156 | 185 | ensurePiniaOnApp(app); | |
| 157 | 186 | try { | |
| 158 | 187 | const rh: any = resolveVendorModule('nativescript-vue/dist/runtimeHelpers'); | |
@@ -171,9 +200,14 @@ function __nsNavigateUsingApp(comp: any, opts: any = {}) { | |||
| 171 | 200 | }); | |
| 172 | 201 | } | |
| 173 | 202 | } catch {} | |
| 203 | + try { | ||
| 204 | + inheritAppContext(app?._context, existingApp && existingApp._context); | ||
| 205 | + } catch {} | ||
| 174 | 206 | const root = new RootCtor(); | |
| 175 | 207 | const vm = typeof (app as any).runWithContext === 'function' ? (app as any).runWithContext(() => (app as any).mount(root) as any) : ((app as any).mount(root) as any); | |
| 176 | 208 | setCurrentApp(app); | |
| 209 | + // HMR mutates Vue's clone of the root component, so rebuild from that. | ||
| 210 | + const mountedType = (vm && vm.$ && vm.$.type) || target; | ||
| 177 | 211 | const el = vm?.$el; | |
| 178 | 212 | const nativeView = el?.nativeView; | |
| 179 | 213 | if (!nativeView) throw new Error('navigation mount did not yield a nativeView'); | |
@@ -190,7 +224,7 @@ function __nsNavigateUsingApp(comp: any, opts: any = {}) { | |||
| 190 | 224 | page = pg; | |
| 191 | 225 | } | |
| 192 | 226 | try { | |
| 193 | - installNavigatedPageHmrReload({ app, page, rebuild: buildTarget }); | ||
| 227 | + installNavigatedPageHmrReload({ app, page, rebuild: () => buildTarget(mountedType) }); | ||
| 194 | 228 | } catch {} | |
| 195 | 229 | return page; | |
| 196 | 230 | }; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,25 @@ | |||
| 1 | + import { describe, expect, it } from 'vitest'; | ||
| 2 | + | ||
| 3 | + import { compileTemplate } from '../frameworks/vue/server/sfc-route-shared.js'; | ||
| 4 | + import { isNativeTag } from './compiler.js'; | ||
| 5 | + | ||
| 6 | + describe('NS_NATIVE_TAGS', () => { | ||
| 7 | + it('treats core views as custom elements', () => { | ||
| 8 | + expect(isNativeTag('Label')).toBe(true); | ||
| 9 | + expect(isNativeTag('GridLayout')).toBe(true); | ||
| 10 | + }); | ||
| 11 | + | ||
| 12 | + it('leaves Vue component wrappers that take slot templates to resolveComponent', () => { | ||
| 13 | + expect(isNativeTag('CollectionView')).toBe(false); | ||
| 14 | + }); | ||
| 15 | + | ||
| 16 | + // The HMR assembler compiles SFC templates with this predicate; a scoped slot on | ||
| 17 | + // a tag it calls an element makes the compiler throw and the SFC falls back to a | ||
| 18 | + // stale or synthesized render. | ||
| 19 | + it('compiles a CollectionView scoped slot with the assembler predicate', () => { | ||
| 20 | + const source = `<GridLayout><CollectionView :items="items"><template #default="{ item, index }"><Label :text="item.name" /></template></CollectionView></GridLayout>`; | ||
| 21 | + const result = compileTemplate({ source, id: 'home', filename: '/app/components/Home.vue', isProd: false, ssr: false, compilerOptions: { isCustomElement: isNativeTag } }); | ||
| 22 | + expect(result.errors).toEqual([]); | ||
| 23 | + expect(result.code).toContain('resolveComponent("CollectionView")'); | ||
| 24 | + }); | ||
| 25 | + }); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,3 +1,6 @@ | |||
| 1 | + // Tags compiled as custom elements. A tag that a Vue integration registers as a | ||
| 2 | + // COMPONENT with slot templates (e.g. @nativescript-community/ui-collectionview/vue3's | ||
| 3 | + // CollectionView) must not be listed: the compiler rejects v-slot on an element. | ||
| 1 | 4 | export const NS_NATIVE_TAGS = new Set<string>([ | |
| 2 | 5 | // Core containers/layouts | |
| 3 | 6 | 'Page', | |
@@ -19,7 +22,6 @@ export const NS_NATIVE_TAGS = new Set<string>([ | |||
| 19 | 22 | 'Image', | |
| 20 | 23 | 'Img', | |
| 21 | 24 | 'ListView', | |
| 22 | - 'CollectionView', | ||
| 23 | 25 | 'ScrollView', | |
| 24 | 26 | 'WebView', | |
| 25 | 27 | 'Switch', | |
@@ -52,7 +54,6 @@ export const NS_NATIVE_TAGS = new Set<string>([ | |||
| 52 | 54 | 'SegmentedBar', | |
| 53 | 55 | 'SegmentedBarItem', | |
| 54 | 56 | 'RadListView', | |
| 55 | - 'CollectionViewGridLayout', | ||
| 56 | 57 | 'StackLayoutBase', | |
| 57 | 58 | 'FlexboxLayoutBase', | |
| 58 | 59 | 'GridLayoutBase', | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -90,10 +90,25 @@ describe('/ns/rt bridge builder', () => { | |||
| 90 | 90 | expect(code).not.toMatch(/export const \$navigateBack = \(__ensure\(\)\.\$navigateBack\);/); | |
| 91 | 91 | expect(code).not.toMatch(/export const \$showModal = \(__ensure\(\)\.\$showModal\);/); | |
| 92 | 92 | expect(code).not.toMatch(/export const vite__injectQuery = \(__ensure\(\)\.vite__injectQuery\);/); | |
| 93 | + expect(code).not.toMatch(/export const createApp = \(__ensure\(\)\.createApp\);/); | ||
| 93 | 94 | // But the HMR-routed shims ARE present (their bodies reference __nsNavigateUsingApp). | |
| 94 | 95 | expect(code).toContain('__nsNavigateUsingApp'); | |
| 95 | - // And ordinary exports are still emitted from the same input. | ||
| 96 | - expect(code).toContain('export const createApp = (__ensure().createApp);'); | ||
| 96 | + }); | ||
| 97 | + | ||
| 98 | + // The navigator builds a fresh Vue app per page and has to inherit the root | ||
| 99 | + // app's registrations (app.component / app.use). Nothing else observes the | ||
| 100 | + // app created by app code, so the bridge's createApp records it. | ||
| 101 | + it('emits createApp as a recording wrapper that publishes the root app for the HMR navigator', () => { | ||
| 102 | + const code = buildNsRtBridgeModule({ rtVer: '0', requireGuardSnippet: '', vendorExports: ['createApp', 'ref'] }); | ||
| 103 | + const line = code.split('\n').find((l) => l.startsWith('export const createApp = ')); | ||
| 104 | + expect(line).toBeTruthy(); | ||
| 105 | + expect(line).toContain('__ensure().createApp(...a)'); | ||
| 106 | + expect(line).toContain('g.__NS_VUE_ROOT_APP__ = app'); | ||
| 107 | + expect(line).toMatch(/return app;/); | ||
| 108 | + // Ordinary exports keep the constant-binding shape and the default listing carries both. | ||
| 109 | + expect(code).toContain('export const ref = (__ensure().ref);'); | ||
| 110 | + expect(code).toMatch(/export default \{[^}]*\bcreateApp\b[^}]*\};/); | ||
| 111 | + expect(code).toMatch(/export default \{[^}]*\bref\b[^}]*\};/); | ||
| 97 | 112 | }); | |
| 98 | 113 | ||
| 99 | 114 | it('filters non-identifier names (e.g. property strings with hyphens) from the auto-emitted exports', () => { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4,7 +4,7 @@ import { enumeratePackageExports } from '../helpers/package-exports.js'; | |||
| 4 | 4 | // must not emit a plain passthrough for these names or the override would be | |
| 5 | 5 | // shadowed and navigation would silently fall back to the vendor's native | |
| 6 | 6 | // version (which doesn't know about the HMR app navigator). | |
| 7 | - const NSV_SHIM_OVERRIDES: ReadonlySet<string> = new Set(['$navigateTo', '$navigateBack', '$showModal', 'vite__injectQuery']); | ||
| 7 | + const NSV_SHIM_OVERRIDES: ReadonlySet<string> = new Set(['createApp', '$navigateTo', '$navigateBack', '$showModal', 'vite__injectQuery']); | ||
| 8 | 8 | ||
| 9 | 9 | // Bridge-internal identifiers that would clash with the emitted preamble if | |
| 10 | 10 | // the vendor package happens to publish a colliding name. | |
@@ -45,11 +45,12 @@ export interface NsRtBridgeOptions { | |||
| 45 | 45 | * `__nsVendorRegistry`), and the bridge resolves the same `nativescript-vue` | |
| 46 | 46 | * record everyone else uses. | |
| 47 | 47 | * | |
| 48 | - * HMR-specific shims (`$navigateTo`, `$navigateBack`, `$showModal`) and the | ||
| 49 | - * Vite client polyfill (`vite__injectQuery`) are emitted as overrides that | ||
| 50 | - * replace the would-be passthrough — those exports route through the HMR | ||
| 51 | - * navigator instead of the vendor's native version, so the bridge must | ||
| 52 | - * provide the override, not the discovered original. | ||
| 48 | + * HMR-specific shims (`$navigateTo`, `$navigateBack`, `$showModal`), the | ||
| 49 | + * root-app recording `createApp`, and the Vite client polyfill | ||
| 50 | + * (`vite__injectQuery`) are emitted as overrides that replace the would-be | ||
| 51 | + * passthrough — those exports route through the HMR navigator (or feed it) | ||
| 52 | + * instead of the vendor's native version, so the bridge must provide the | ||
| 53 | + * override, not the discovered original. | ||
| 53 | 54 | */ | |
| 54 | 55 | export function buildNsRtBridgeModule(options: NsRtBridgeOptions): string { | |
| 55 | 56 | // Sort for stable output — useful for diffing the served bridge across requests. | |
@@ -62,7 +63,7 @@ export function buildNsRtBridgeModule(options: NsRtBridgeOptions): string { | |||
| 62 | 63 | const passthroughNames = Array.from(passthrough).sort(); | |
| 63 | 64 | ||
| 64 | 65 | const passthroughExports = passthroughNames.map((n) => `export const ${n} = (__ensure().${n});`).join('\n'); | |
| 65 | - const defaultListing = passthroughNames.concat(['$navigateTo', '$navigateBack', '$showModal', 'vite__injectQuery']).join(', '); | ||
| 66 | + const defaultListing = passthroughNames.concat(['createApp', '$navigateTo', '$navigateBack', '$showModal', 'vite__injectQuery']).join(', '); | ||
| 66 | 67 | ||
| 67 | 68 | const code = | |
| 68 | 69 | `// [ns-rt][v2.4] NativeScript-Vue runtime bridge (module-scoped cache, no globals)\n` + | |
@@ -124,6 +125,9 @@ export function buildNsRtBridgeModule(options: NsRtBridgeOptions): string { | |||
| 124 | 125 | // Await the client strategy before declaring the navigator missing. | |
| 125 | 126 | `function __navigateNow(a) { try { return g.__nsNavigateUsingApp(...a); } catch (e) { console.error('[ns-rt] $navigateTo app navigator error', e); throw e; } }\n` + | |
| 126 | 127 | `function __navigatorMissing() { console.error('[ns-rt] $navigateTo unavailable: app navigator missing'); throw new Error('$navigateTo unavailable: app navigator missing'); }\n` + | |
| 128 | + // The app's registrations (app.component/use) live on this instance; the | ||
| 129 | + // HMR navigator copies them onto every page app it builds. | ||
| 130 | + `export const createApp = (...a) => { const app = __ensure().createApp(...a); try { g.__NS_VUE_ROOT_APP__ = app; } catch {} return app; };\n` + | ||
| 127 | 131 | `export const $navigateBack = (...a) => { const vm = (__cached_vm || (void __ensure(), __cached_vm)); const rt = __ensure(); const impl = (vm && (vm.$navigateBack || (vm.default && vm.default.$navigateBack))) || (rt && (rt.$navigateBack || (rt.runtimeHelpers && rt.runtimeHelpers.navigateBack))); let res; try { const via = (impl && (impl === (vm && vm.$navigateBack) || impl === (vm && vm.default && vm.default.$navigateBack))) ? 'vm' : (impl ? 'rt' : 'none'); } catch {} try { if (typeof impl === 'function') res = impl(...a); } catch {} try { const top = (g && g.Frame && g.Frame.topmost && g.Frame.topmost()); if (!res && top && top.canGoBack && top.canGoBack()) { res = top.goBack(); } } catch {} try { const hook = g && (g.__NS_HMR_ON_NAVIGATE_BACK || g.__NS_HMR_ON_BACK || g.__nsAttemptBackRemount); if (typeof hook === 'function') hook(); } catch {} return res; }\n` + | |
| 128 | 132 | `export const $showModal = (...a) => { const vm = (__cached_vm || (void __ensure(), __cached_vm)); const rt = __ensure(); const impl = (vm && (vm.$showModal || (vm.default && vm.default.$showModal))) || (rt && (rt.$showModal || (rt.runtimeHelpers && rt.runtimeHelpers.showModal))); try { if (typeof impl === 'function') return impl(...a); } catch (e) { } return undefined; }\n` + | |
| 129 | 133 | // Vite client polyfill — see the comment in websocket.ts for full rationale. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -108,6 +108,7 @@ declare global { | |||
| 108 | 108 | var __NS_HMR_WORKER_TRACKING_INSTALLED__: boolean | undefined; | |
| 109 | 109 | var __NS_UPDATE_ANGULAR_APP_OPTIONS__: any; | |
| 110 | 110 | var __nsNavigateUsingApp: any; | |
| 111 | + var __NS_VUE_ROOT_APP__: any; | ||
| 111 | 112 | var __NS_CLIENT_STRATEGY_READY__: Promise<void> | undefined; | |
| 112 | 113 | var __NS_CLIENT_STRATEGY_RESOLVE__: (() => void) | undefined; | |
| 113 | 114 | var __nsRequire: any; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments