@nativescript/vite 0.0.1-alpha.1 → 0.0.1-alpha.2

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.
Files changed (55) hide show
  1. package/dist/configuration/base.js +134 -36
  2. package/dist/helpers/external-configs.js +1 -1
  3. package/dist/helpers/global-defines.d.ts +1 -0
  4. package/dist/helpers/global-defines.js +2 -0
  5. package/dist/helpers/main-entry-hmr-includes.d.ts +1 -0
  6. package/dist/helpers/main-entry-hmr-includes.js +18 -0
  7. package/dist/helpers/main-entry.d.ts +2 -2
  8. package/dist/helpers/main-entry.js +58 -94
  9. package/dist/helpers/module-runner-patch.d.ts +3 -0
  10. package/dist/helpers/module-runner-patch.js +65 -0
  11. package/dist/helpers/ns-cli-plugins.d.ts +1 -14
  12. package/dist/helpers/ns-cli-plugins.js +54 -107
  13. package/dist/helpers/package-platform-aliases.d.ts +1 -1
  14. package/dist/helpers/package-platform-aliases.js +4 -4
  15. package/dist/helpers/ts-config-paths.d.ts +1 -1
  16. package/dist/helpers/ts-config-paths.js +3 -3
  17. package/dist/hmr/client-vue.d.ts +6 -0
  18. package/dist/hmr/client-vue.js +563 -0
  19. package/dist/hmr/component-tracker.d.ts +23 -0
  20. package/dist/hmr/component-tracker.js +193 -0
  21. package/dist/hmr/css-handler.d.ts +4 -0
  22. package/dist/hmr/css-handler.js +77 -0
  23. package/dist/hmr/message-handler.d.ts +1 -0
  24. package/dist/hmr/message-handler.js +590 -0
  25. package/dist/hmr/nsv-hooks.d.ts +2 -0
  26. package/dist/hmr/nsv-hooks.js +481 -0
  27. package/dist/hmr/plugin-vue.d.ts +2 -0
  28. package/dist/hmr/plugin-vue.js +38 -0
  29. package/dist/hmr/plugins/index.d.ts +1 -0
  30. package/dist/hmr/plugins/index.js +16 -0
  31. package/dist/hmr/plugins/plugin-vue.d.ts +2 -0
  32. package/dist/hmr/plugins/plugin-vue.js +41 -0
  33. package/dist/hmr/plugins/websocket-vue.d.ts +2 -0
  34. package/dist/hmr/plugins/websocket-vue.js +882 -0
  35. package/dist/hmr/runtime-vue.d.ts +13 -0
  36. package/dist/hmr/runtime-vue.js +2306 -0
  37. package/dist/hmr/types.d.ts +24 -0
  38. package/dist/hmr/types.js +2 -0
  39. package/dist/hmr/websocket-vue.d.ts +2 -0
  40. package/dist/hmr/websocket-vue.js +875 -0
  41. package/dist/shims/node-module.d.ts +5 -0
  42. package/dist/shims/node-module.js +12 -0
  43. package/package.json +2 -1
  44. package/dist/configuration/old-without-merge-base.d.ts +0 -13
  45. package/dist/configuration/old-without-merge-base.js +0 -249
  46. package/dist/helpers/side-effects.d.ts +0 -14
  47. package/dist/helpers/side-effects.js +0 -69
  48. package/dist/hmr/hmr-angular.d.ts +0 -1
  49. package/dist/hmr/hmr-angular.js +0 -34
  50. package/dist/hmr/hmr-bridge.d.ts +0 -18
  51. package/dist/hmr/hmr-bridge.js +0 -154
  52. package/dist/hmr/hmr-client.d.ts +0 -5
  53. package/dist/hmr/hmr-client.js +0 -93
  54. package/dist/hmr/hmr-server.d.ts +0 -20
  55. package/dist/hmr/hmr-server.js +0 -179
@@ -0,0 +1,590 @@
1
+ // Message handling and routing
2
+ import { handleCssUpdates, handleCustomCss } from './css-handler';
3
+ import { ensureVueHMRRuntimeEnhanced } from './runtime-vue';
4
+ import { setupNativeScriptVueHooks } from './nsv-hooks';
5
+ const VERBOSE = !!globalThis.__NS_ENV_VERBOSE__;
6
+ export function handleMessage(data, httpOrigin) {
7
+ let message;
8
+ try {
9
+ message = JSON.parse(data);
10
+ }
11
+ catch {
12
+ return;
13
+ }
14
+ if (VERBOSE) {
15
+ console.info('[ns-hmr] Received message:', {
16
+ type: message.type,
17
+ event: message.event,
18
+ hasData: !!message.data,
19
+ hasUpdates: !!message.updates,
20
+ dataKeys: message.data ? Object.keys(message.data) : []
21
+ });
22
+ }
23
+ // Handle custom CSS events for live apply
24
+ if (message.type === 'custom' && message.event === 'ns:css' && message.data) {
25
+ try {
26
+ const cssText = message.data.css;
27
+ handleCustomCss(cssText);
28
+ }
29
+ catch (e) {
30
+ console.warn('[ns-hmr] Custom CSS apply failed:', e?.message || String(e));
31
+ }
32
+ return;
33
+ }
34
+ // Handle Vue SFC template rerender payloads from the server
35
+ if (message.type === 'custom' && message.event === 'ns:vue-template' && message.data) {
36
+ try {
37
+ const payload = message.data;
38
+ if (!payload?.src)
39
+ return;
40
+ // Proactively ensure NS-Vue hooks are applied so instances are registered
41
+ try {
42
+ const g = globalThis;
43
+ if (!g.__NS_VUE_HOOKS_APPLIED__) {
44
+ if (VERBOSE)
45
+ console.info('[ns-hmr] NS-Vue hooks not applied before vue-template; applying now');
46
+ setupNativeScriptVueHooks();
47
+ try {
48
+ if (VERBOSE)
49
+ console.info('[ns-hmr] Applied NS-Vue hooks on-demand for vue-template; flag now:', !!g.__NS_VUE_HOOKS_APPLIED__);
50
+ }
51
+ catch { }
52
+ }
53
+ }
54
+ catch { }
55
+ try {
56
+ const idsPreview = Array.isArray(payload.ids) ? payload.ids.join(', ') : (payload.id || '(none)');
57
+ console.info('[ns-hmr] ns:vue-template received; ids:', idsPreview);
58
+ }
59
+ catch { }
60
+ applyVueTemplateRerender(payload);
61
+ }
62
+ catch (e) {
63
+ console.warn('[ns-hmr] Vue template apply failed:', e?.message || String(e));
64
+ }
65
+ return;
66
+ }
67
+ // Disable ad-hoc Vue code delivery to favor Vite ModuleRunner path
68
+ if (message.type === 'custom' && message.event === 'ns:vue-component' && message.data) {
69
+ if (VERBOSE)
70
+ console.info('[ns-hmr] Ignoring ns:vue-component (prefer standard Vite update)');
71
+ return;
72
+ }
73
+ // Ignore custom file-changed for Vue and rely on standard Vite update payloads
74
+ if (message.type === 'custom' && message.event === 'file-changed' && message.data && message.data.file) {
75
+ const filePath = String(message.data.file || '');
76
+ if (/\.vue(\?|$)/.test(filePath)) {
77
+ if (VERBOSE)
78
+ console.info('[ns-hmr] Ignoring custom file-changed for .vue; waiting for Vite update');
79
+ return;
80
+ }
81
+ // For non-vue, nothing to do here
82
+ return;
83
+ }
84
+ // Handle Vite update events
85
+ if (message.type === 'update' && Array.isArray(message.updates)) {
86
+ // Handle CSS updates
87
+ const cssUpdates = message.updates.filter((u) => u && u.type === 'css-update');
88
+ if (cssUpdates.length) {
89
+ handleCssUpdates(cssUpdates, httpOrigin);
90
+ }
91
+ // Handle Vue updates by delegating to the ModuleRunner-based client.
92
+ handleUpdateEvents(message.updates);
93
+ }
94
+ }
95
+ function handleUpdateEvents(updates) {
96
+ let handledVueUpdates = 0;
97
+ if (VERBOSE)
98
+ console.info('[ns-hmr] Processing updates:', updates.length);
99
+ for (const update of updates) {
100
+ const path = update.path || update.acceptedPath || '';
101
+ if (VERBOSE)
102
+ console.info('[ns-hmr] Checking update:', { path, type: update.type });
103
+ // Enhanced Vue update detection
104
+ if (isVueUpdate(path, update)) {
105
+ if (VERBOSE)
106
+ console.info('[ns-hmr] Identified as Vue update:', path);
107
+ // Defer to Vite ModuleRunner-based client (built into dist runtime) to apply .vue HMR
108
+ // Avoid triggering our manual fallback which can cause restart.
109
+ handledVueUpdates++;
110
+ if (VERBOSE)
111
+ console.info('[ns-hmr] Delegating .vue update to ModuleRunner pipeline');
112
+ }
113
+ else {
114
+ if (VERBOSE)
115
+ console.info('[ns-hmr] Not a Vue update:', path);
116
+ }
117
+ }
118
+ if (VERBOSE)
119
+ console.info(`[ns-hmr] Handled ${handledVueUpdates} Vue update(s)`);
120
+ }
121
+ function isVueUpdate(path, update) {
122
+ // Check for .vue files
123
+ if (/\.vue(\?|$)/.test(path)) {
124
+ return true;
125
+ }
126
+ // Check for Vue-related query parameters that indicate Vue SFC parts
127
+ if (path.includes('vue&type=')) {
128
+ return true;
129
+ }
130
+ // Check update type for Vue-specific updates
131
+ if (update.type === 'vue-reload' || update.type === 'vue-rerender') {
132
+ return true;
133
+ }
134
+ return false;
135
+ }
136
+ // Note: Custom Vue update helpers removed. We intentionally rely on Vite's
137
+ // standard 'update' flow handled by the ModuleRunner in the full runtime client.
138
+ function applyVueTemplateRerender(payload) {
139
+ const g = globalThis;
140
+ // Try to ensure Vue HMR runtime is present/enhanced before we proceed
141
+ const runtime = ensureVueHMRRuntimeEnhanced() || g.__VUE_HMR_RUNTIME__;
142
+ const hasRuntime = !!(runtime && typeof runtime.rerender === 'function');
143
+ if (!hasRuntime) {
144
+ console.info('[ns-hmr] Vue HMR runtime not ready; will attempt direct instance patch and retry later');
145
+ // Cache and retry a few times in case runtime appears after startup
146
+ try {
147
+ g.__NS_LAST_VUE_TEMPLATE__ = payload;
148
+ scheduleVueTemplateRetry(payload, 5);
149
+ }
150
+ catch { }
151
+ }
152
+ try {
153
+ // Build a function in a sandbox with helpers bound to NS-Vue/Vue exports
154
+ const vueBase = safeRequire('vue') || {};
155
+ const nsvBase = safeRequire('nativescript-vue') || {};
156
+ // Merge to prefer NS-Vue overrides but fill missing helpers from Vue
157
+ const nsVue = Object.assign({}, vueBase, nsvBase);
158
+ // Ensure common helper aliases exist on the object (underscore vs non-underscore and synonyms)
159
+ const aliasPairs = [
160
+ // underscore <-> plain
161
+ ['_resolveComponent', 'resolveComponent'],
162
+ ['_openBlock', 'openBlock'],
163
+ ['_createBlock', 'createBlock'],
164
+ ['_createElementBlock', 'createElementBlock'],
165
+ ['_createVNode', 'createVNode'],
166
+ ['_createElementVNode', 'createElementVNode'],
167
+ ['_toDisplayString', 'toDisplayString'],
168
+ ['_withCtx', 'withCtx'],
169
+ ['_unref', 'unref'],
170
+ ['_Fragment', 'Fragment'],
171
+ ['_createTextVNode', 'createTextVNode'],
172
+ ];
173
+ const synonymPairs = [
174
+ // createElementBlock <-> createBlock
175
+ ['createElementBlock', 'createBlock'],
176
+ ['createElementVNode', 'createVNode'],
177
+ ];
178
+ const appliedShims = [];
179
+ const ensureAlias = (to, from) => {
180
+ try {
181
+ if (typeof nsVue[to] === 'undefined' && typeof nsVue[from] !== 'undefined') {
182
+ nsVue[to] = nsVue[from];
183
+ appliedShims.push({ to, from });
184
+ }
185
+ }
186
+ catch { }
187
+ };
188
+ // 1) Fill underscore/plain in both directions
189
+ for (const [a, b] of aliasPairs) {
190
+ ensureAlias(a, b);
191
+ ensureAlias(b, a);
192
+ }
193
+ // 2) Fill synonyms
194
+ for (const [a, b] of synonymPairs) {
195
+ ensureAlias(a, b);
196
+ ensureAlias(b, a);
197
+ // Also cover underscore variants for synonyms
198
+ ensureAlias(`_${a}`, `_${b}`);
199
+ ensureAlias(`_${b}`, `_${a}`);
200
+ }
201
+ if (VERBOSE && appliedShims.length) {
202
+ try {
203
+ console.info('[ns-hmr] Applied helper shims:', appliedShims);
204
+ }
205
+ catch { }
206
+ }
207
+ // As a last resort, provide a shim for resolveComponent from the running app context
208
+ const getAppComponent = (n) => {
209
+ try {
210
+ const app = globalThis.__NS_VUE_APP__;
211
+ // Vue 3 app context registry
212
+ const c1 = app && app._context && app._context.components && app._context.components[n];
213
+ if (c1)
214
+ return c1;
215
+ // Some runtimes might store registered components under app.component registry
216
+ const c2 = app && app.component && app.component(n);
217
+ if (c2)
218
+ return c2;
219
+ // Try via root instance appContext
220
+ const root = globalThis.__NS_VUE_ROOT_INSTANCE__;
221
+ const internal = root && (root.$ || root);
222
+ const appCtx = internal && (internal.appContext || internal.app?._context);
223
+ const c3 = appCtx && appCtx.components && appCtx.components[n];
224
+ if (c3)
225
+ return c3;
226
+ }
227
+ catch { }
228
+ return null;
229
+ };
230
+ const shimResolve = (name) => {
231
+ const comp = getAppComponent(name);
232
+ if (VERBOSE) {
233
+ try {
234
+ console.info('[ns-hmr] shim resolveComponent', { name, found: !!comp, type: comp ? typeof comp : 'null' });
235
+ }
236
+ catch { }
237
+ }
238
+ // Return component if found, otherwise fall back to name (some renderers handle string types)
239
+ return comp || name;
240
+ };
241
+ if (typeof nsVue.resolveComponent !== 'function' && typeof nsVue._resolveComponent !== 'function') {
242
+ nsVue.resolveComponent = shimResolve;
243
+ nsVue._resolveComponent = shimResolve;
244
+ }
245
+ else if (typeof nsVue.resolveComponent !== 'function' && typeof nsVue._resolveComponent === 'function') {
246
+ nsVue.resolveComponent = nsVue._resolveComponent;
247
+ }
248
+ else if (typeof nsVue._resolveComponent !== 'function' && typeof nsVue.resolveComponent === 'function') {
249
+ nsVue._resolveComponent = nsVue.resolveComponent;
250
+ }
251
+ // Minimal safe fallbacks for helpers to prevent runtime aborts
252
+ const appliedFallbacks = [];
253
+ const ensureFunc = (key, fn) => {
254
+ try {
255
+ if (typeof nsVue[key] !== 'function') {
256
+ nsVue[key] = fn;
257
+ appliedFallbacks.push(key);
258
+ }
259
+ }
260
+ catch { }
261
+ };
262
+ // Base creators using either Vue's createVNode or h
263
+ const baseCreateVNode = nsVue.createVNode || nsVue._createVNode || nsVue.h || null;
264
+ const createVNodeLike = (type, props, children) => {
265
+ try {
266
+ if (typeof nsVue.createVNode === 'function')
267
+ return nsVue.createVNode(type, props, children);
268
+ if (typeof nsVue._createVNode === 'function')
269
+ return nsVue._createVNode(type, props, children);
270
+ if (typeof nsVue.h === 'function')
271
+ return nsVue.h(type, props, children);
272
+ }
273
+ catch { }
274
+ return { type, props: props || null, children };
275
+ };
276
+ const createTextVNodeLike = (text) => {
277
+ try {
278
+ if (typeof nsVue.createTextVNode === 'function')
279
+ return nsVue.createTextVNode(text);
280
+ if (typeof nsVue._createTextVNode === 'function')
281
+ return nsVue._createTextVNode(text);
282
+ // Fallback: wrap string children; many renderers accept plain strings as children
283
+ }
284
+ catch { }
285
+ return String(text);
286
+ };
287
+ ensureFunc('_openBlock', () => { });
288
+ ensureFunc('openBlock', () => { });
289
+ ensureFunc('_withCtx', (fn) => fn);
290
+ ensureFunc('withCtx', (fn) => fn);
291
+ ensureFunc('_createVNode', createVNodeLike);
292
+ ensureFunc('createVNode', createVNodeLike);
293
+ ensureFunc('_createElementVNode', createVNodeLike);
294
+ ensureFunc('createElementVNode', createVNodeLike);
295
+ ensureFunc('_createBlock', createVNodeLike);
296
+ ensureFunc('createBlock', createVNodeLike);
297
+ ensureFunc('_createElementBlock', createVNodeLike);
298
+ ensureFunc('createElementBlock', createVNodeLike);
299
+ ensureFunc('_createTextVNode', createTextVNodeLike);
300
+ ensureFunc('createTextVNode', createTextVNodeLike);
301
+ ensureFunc('_toDisplayString', (v) => {
302
+ try {
303
+ return nsVue.toDisplayString ? nsVue.toDisplayString(v) : String(v);
304
+ }
305
+ catch {
306
+ return String(v);
307
+ }
308
+ });
309
+ ensureFunc('toDisplayString', (v) => {
310
+ try {
311
+ return nsVue.toDisplayString ? nsVue.toDisplayString(v) : String(v);
312
+ }
313
+ catch {
314
+ return String(v);
315
+ }
316
+ });
317
+ ensureFunc('_unref', (v) => (v && typeof v === 'object' && 'value' in v ? v.value : v));
318
+ ensureFunc('unref', (v) => (v && typeof v === 'object' && 'value' in v ? v.value : v));
319
+ if (appliedFallbacks.length) {
320
+ try {
321
+ console.info('[ns-hmr] Applied helper fallbacks:', appliedFallbacks);
322
+ }
323
+ catch { }
324
+ }
325
+ // Log helper presence/types for critical helpers
326
+ try {
327
+ const keys = ['_resolveComponent', 'resolveComponent', '_openBlock', 'openBlock', '_createBlock', 'createBlock', '_createElementBlock', 'createElementBlock', '_createVNode', 'createVNode', '_createElementVNode', 'createElementVNode', '_withCtx', 'withCtx', '_unref', 'unref', '_createTextVNode', 'createTextVNode'];
328
+ const status = {};
329
+ for (const k of keys) {
330
+ const v = nsVue[k];
331
+ status[k] = typeof v;
332
+ }
333
+ console.info('[ns-hmr] Helper status:', status);
334
+ }
335
+ catch { }
336
+ // Enumerate available helper function names so we see clearly what's in scope
337
+ try {
338
+ const allKeys = Object.keys(nsVue).sort();
339
+ const funcKeys = allKeys.filter((k) => typeof nsVue[k] === 'function');
340
+ const underscoredCount = funcKeys.filter((k) => k.startsWith('_')).length;
341
+ const sample = funcKeys.slice(0, 80);
342
+ console.info('[ns-hmr] NSVUE function keys (sample):', { count: funcKeys.length, underscoredCount, sample });
343
+ }
344
+ catch { }
345
+ const helperNames = Array.isArray(payload.helpers) ? payload.helpers : [];
346
+ const localNames = Array.isArray(payload.locals) && payload.locals.length === helperNames.length ? payload.locals : helperNames;
347
+ try {
348
+ console.info('[ns-hmr] Payload expected helpers:', helperNames);
349
+ }
350
+ catch { }
351
+ // Generate declarations for each helper alias to avoid using dynamic argument names
352
+ const decls = [];
353
+ const missing = [];
354
+ const presentDiag = [];
355
+ for (let i = 0; i < helperNames.length; i++) {
356
+ const orig = helperNames[i];
357
+ const local = localNames[i] || orig;
358
+ // Declare all locals to avoid ReferenceError during eval
359
+ // We bind to NSVUE[orig] at runtime; if missing, value will be undefined
360
+ decls.push(`const ${local} = NSVUE && Object.prototype.hasOwnProperty.call(NSVUE, ${JSON.stringify(orig)}) ? NSVUE[${JSON.stringify(orig)}] : undefined;`);
361
+ if (!(orig in nsVue))
362
+ missing.push(`${orig} as ${local}`);
363
+ else {
364
+ try {
365
+ presentDiag.push({ name: orig, local, typeof: typeof nsVue[orig] });
366
+ }
367
+ catch { }
368
+ }
369
+ // Also add an alias declaration for underscore/non-underscore variant if not the same
370
+ const altLocal = local.startsWith('_') ? local.slice(1) : ('_' + local);
371
+ if (altLocal !== local) {
372
+ decls.push(`const ${altLocal} = (typeof ${local} !== 'undefined') ? ${local} : (NSVUE && (NSVUE[${JSON.stringify(orig)}] ?? NSVUE[${JSON.stringify(altLocal.replace(/^_/, ''))}]));`);
373
+ }
374
+ }
375
+ if (missing.length) {
376
+ if (VERBOSE)
377
+ console.info('[ns-hmr] Missing helpers in nativescript-vue:', missing.join(', '));
378
+ }
379
+ if (VERBOSE) {
380
+ try {
381
+ console.info('[ns-hmr] Helper bindings:', presentDiag);
382
+ }
383
+ catch { }
384
+ }
385
+ // Determine if payload.src already includes a full 'function render' or 'const render =' declaration
386
+ const hasFullRender = /\bfunction\s+render\s*\(|\bconst\s+render\s*=/.test(payload.src);
387
+ const lines = [
388
+ `'use strict';`,
389
+ ...decls,
390
+ ];
391
+ if (hasFullRender) {
392
+ lines.push(payload.src);
393
+ }
394
+ else {
395
+ lines.push(payload.src);
396
+ }
397
+ lines.push(`return render;`);
398
+ const body = lines.join('\n');
399
+ // Inspect tokens present in the body to know which helpers the render expects
400
+ try {
401
+ const tokenReport = {
402
+ hasResolveComponent: /\b_?resolveComponent\b/.test(body),
403
+ hasOpenBlock: /\b_?openBlock\b/.test(body),
404
+ hasCreateBlock: /\b_?create(Block|ElementBlock)\b/.test(body),
405
+ hasCreateVNode: /\b_?create(VNode|ElementVNode)\b/.test(body),
406
+ hasWithCtx: /\b_?withCtx\b/.test(body),
407
+ hasToDisplayString: /\b_?toDisplayString\b/.test(body),
408
+ };
409
+ console.info('[ns-hmr] Render token usage:', tokenReport);
410
+ }
411
+ catch { }
412
+ // Ensure critical helpers like resolveComponent exist
413
+ try {
414
+ if (typeof nsVue._resolveComponent === 'undefined' && typeof nsVue.resolveComponent === 'function') {
415
+ nsVue._resolveComponent = nsVue.resolveComponent.bind(nsVue);
416
+ }
417
+ if (typeof nsVue.resolveComponent === 'undefined' && typeof nsVue._resolveComponent === 'function') {
418
+ nsVue.resolveComponent = nsVue._resolveComponent.bind(nsVue);
419
+ }
420
+ }
421
+ catch { }
422
+ const factory = new Function('NSVUE', body);
423
+ let newRender = factory(nsVue);
424
+ // If compile emitted a render that expects global helpers under different names, shim them
425
+ if (typeof newRender !== 'function') {
426
+ if (VERBOSE)
427
+ console.info('[ns-hmr] Evaluated render is not a function; aborting');
428
+ return;
429
+ }
430
+ // Introspect the compiled render to confirm which helpers it will call
431
+ try {
432
+ const srcStr = Function.prototype.toString.call(newRender);
433
+ console.info('[ns-hmr] New render tokens:', {
434
+ len: srcStr.length,
435
+ openBlock: /\b_?openBlock\b/.test(srcStr),
436
+ createBlock: /\b_?create(Block|ElementBlock)\b/.test(srcStr),
437
+ resolveComponent: /\b_?resolveComponent\b/.test(srcStr),
438
+ withCtx: /\b_?withCtx\b/.test(srcStr),
439
+ });
440
+ }
441
+ catch { }
442
+ // If runtime is unavailable, cache and retry later to avoid direct instance patch side-effects
443
+ if (!hasRuntime && typeof newRender === 'function') {
444
+ try {
445
+ g.__NS_LAST_VUE_TEMPLATE__ = payload;
446
+ scheduleVueTemplateRetry(payload, 5);
447
+ }
448
+ catch { }
449
+ return;
450
+ }
451
+ // Build candidate ids with useful variations (with/without query, absolute/relative, with/without ?vue)
452
+ const baseIds = Array.isArray(payload.ids) && payload.ids.length ? payload.ids.slice() : (payload.id ? [payload.id] : []);
453
+ const candidatesSet = new Set();
454
+ const addVariants = (id) => {
455
+ if (!id)
456
+ return;
457
+ const norm = String(id).replace(/\\/g, '/');
458
+ const noQuery = norm.split('?')[0];
459
+ const withVueQ = noQuery + '?vue';
460
+ const relFromSrc = noQuery.replace(/^.*?\/src\//, '/src/');
461
+ const relNoLead = relFromSrc.replace(/^\//, '');
462
+ [norm, noQuery, withVueQ, relFromSrc, relNoLead, relNoLead + '?vue'].forEach((v) => v && candidatesSet.add(v));
463
+ };
464
+ baseIds.forEach(addVariants);
465
+ const candidates = Array.from(candidatesSet);
466
+ try {
467
+ console.info('[ns-hmr] id candidates ->', candidates);
468
+ }
469
+ catch { }
470
+ if (typeof newRender === 'function' && candidates.length) {
471
+ let applied = false;
472
+ // Use a more conservative approach: add delay and readiness checks
473
+ // This prevents the "entry.create" errors by ensuring native views are ready
474
+ const req = globalThis.require;
475
+ const vueMod = req && (() => { try {
476
+ return req('vue');
477
+ }
478
+ catch {
479
+ return null;
480
+ } })();
481
+ const nextTick = vueMod && vueMod.nextTick;
482
+ const doRerender = () => {
483
+ // Rerender-only for template changes; avoid partial reloads that can break component state
484
+ for (const id of candidates) {
485
+ try {
486
+ console.info('[ns-hmr] Attempting Vue template rerender for', id);
487
+ globalThis.__NS_LAST_RERENDER_ID__ = id;
488
+ runtime.rerender(id, newRender);
489
+ applied = true;
490
+ console.info('[ns-hmr] Applied Vue template rerender for', id);
491
+ break;
492
+ }
493
+ catch (e) {
494
+ console.info('[ns-hmr] Rerender attempt failed for', id, e?.message || String(e));
495
+ }
496
+ }
497
+ if (!applied) {
498
+ console.info('[ns-hmr] No matching Vue HMR record for ids:', candidates.join(', '));
499
+ // Fuzzy match: try to find a record id by suffix match against path
500
+ try {
501
+ const path = String(payload.path || '');
502
+ const base = path.split('?')[0].replace(/\\/g, '/');
503
+ const baseRel = base.replace(/^.*?\/src\//, '/src/');
504
+ const suffixes = Array.from(new Set([
505
+ baseRel,
506
+ baseRel + '?vue',
507
+ (baseRel || '').replace(/^\//, ''),
508
+ (baseRel || '').replace(/^\//, '') + '?vue',
509
+ (base.split('/').pop() || ''),
510
+ (base.split('/').pop() || '') + '?vue'
511
+ ].filter(Boolean)));
512
+ const map = runtime.map || runtime.records || {};
513
+ const keys = map && typeof map.keys === 'function'
514
+ ? Array.from(map.keys())
515
+ : (map && typeof map === 'object' ? Object.keys(map) : []);
516
+ try {
517
+ console.info('[ns-hmr] Vue HMR record keys:', keys);
518
+ }
519
+ catch { }
520
+ for (const key of keys) {
521
+ const k = String(key);
522
+ if (suffixes.some((s) => k.endsWith(s))) {
523
+ try {
524
+ console.info('[ns-hmr] Fuzzy match rerender for', k);
525
+ runtime.rerender(k, newRender);
526
+ applied = true;
527
+ console.info('[ns-hmr] Applied Vue template rerender for', k);
528
+ break;
529
+ }
530
+ catch (e) {
531
+ console.info('[ns-hmr] Fuzzy rerender failed for', k, e?.message || String(e));
532
+ }
533
+ }
534
+ }
535
+ }
536
+ catch { }
537
+ if (!applied) {
538
+ console.info('[ns-hmr] Could not find a matching Vue HMR record by fuzzy path; skipping direct instance patch (avoid double update)');
539
+ }
540
+ }
541
+ };
542
+ // Use nextTick if available to ensure proper timing
543
+ if (typeof nextTick === 'function') {
544
+ nextTick(() => {
545
+ // Add a small additional delay to let any pending native view operations complete
546
+ setTimeout(doRerender, 16);
547
+ });
548
+ }
549
+ else {
550
+ // Fallback with delay
551
+ setTimeout(doRerender, 32);
552
+ }
553
+ }
554
+ }
555
+ catch (e) {
556
+ console.warn('[ns-hmr] Failed to eval Vue template render:', e?.message || String(e));
557
+ }
558
+ }
559
+ function scheduleVueTemplateRetry(payload, attempts) {
560
+ const g = globalThis;
561
+ if (attempts <= 0)
562
+ return;
563
+ setTimeout(() => {
564
+ const rt = ensureVueHMRRuntimeEnhanced() || g.__VUE_HMR_RUNTIME__;
565
+ if (!rt || typeof rt.rerender !== 'function') {
566
+ console.info('[ns-hmr] Vue HMR runtime still not ready; attempts left:', attempts - 1);
567
+ scheduleVueTemplateRetry(payload, attempts - 1);
568
+ return;
569
+ }
570
+ try {
571
+ console.info('[ns-hmr] Retrying Vue template apply');
572
+ applyVueTemplateRerender(payload);
573
+ }
574
+ catch (e) {
575
+ console.info('[ns-hmr] Retry failed:', e?.message || String(e));
576
+ scheduleVueTemplateRetry(payload, attempts - 1);
577
+ }
578
+ }, 250);
579
+ }
580
+ // Direct instance patch removed to avoid interfering with Vue HMR scheduler
581
+ function safeRequire(name) {
582
+ try {
583
+ // In NativeScript runtime, require is available globally
584
+ const req = globalThis.require || null;
585
+ if (req)
586
+ return req(name);
587
+ }
588
+ catch { }
589
+ return null;
590
+ }
@@ -0,0 +1,2 @@
1
+ export declare function setupNativeScriptVueHooks(): void;
2
+ export default setupNativeScriptVueHooks;