@nativescript/vite 0.0.1-alpha.0 → 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.
- package/dist/configuration/base.js +178 -71
- package/dist/helpers/external-configs.js +1 -1
- package/dist/helpers/global-defines.d.ts +1 -0
- package/dist/helpers/global-defines.js +2 -0
- package/dist/helpers/main-entry-hmr-includes.d.ts +1 -0
- package/dist/helpers/main-entry-hmr-includes.js +18 -0
- package/dist/helpers/main-entry.d.ts +3 -3
- package/dist/helpers/main-entry.js +61 -54
- package/dist/helpers/module-runner-patch.d.ts +3 -0
- package/dist/helpers/module-runner-patch.js +65 -0
- package/dist/helpers/ns-cli-plugins.d.ts +4 -14
- package/dist/helpers/ns-cli-plugins.js +124 -101
- package/dist/helpers/package-platform-aliases.d.ts +1 -1
- package/dist/helpers/package-platform-aliases.js +4 -4
- package/dist/helpers/preserve-imports.d.ts +2 -0
- package/dist/helpers/preserve-imports.js +19 -0
- package/dist/helpers/ts-config-paths.d.ts +1 -1
- package/dist/helpers/ts-config-paths.js +6 -4
- package/dist/hmr/client-vue.d.ts +6 -0
- package/dist/hmr/client-vue.js +563 -0
- package/dist/hmr/component-tracker.d.ts +23 -0
- package/dist/hmr/component-tracker.js +193 -0
- package/dist/hmr/css-handler.d.ts +4 -0
- package/dist/hmr/css-handler.js +77 -0
- package/dist/hmr/message-handler.d.ts +1 -0
- package/dist/hmr/message-handler.js +590 -0
- package/dist/hmr/nsv-hooks.d.ts +2 -0
- package/dist/hmr/nsv-hooks.js +481 -0
- package/dist/hmr/plugin-vue.d.ts +2 -0
- package/dist/hmr/plugin-vue.js +38 -0
- package/dist/hmr/plugins/index.d.ts +1 -0
- package/dist/hmr/plugins/index.js +16 -0
- package/dist/hmr/plugins/plugin-vue.d.ts +2 -0
- package/dist/hmr/plugins/plugin-vue.js +41 -0
- package/dist/hmr/plugins/websocket-vue.d.ts +2 -0
- package/dist/hmr/plugins/websocket-vue.js +882 -0
- package/dist/hmr/runtime-vue.d.ts +13 -0
- package/dist/hmr/runtime-vue.js +2306 -0
- package/dist/hmr/types.d.ts +24 -0
- package/dist/hmr/types.js +2 -0
- package/dist/hmr/websocket-vue.d.ts +2 -0
- package/dist/hmr/websocket-vue.js +875 -0
- package/dist/shims/node-module.d.ts +5 -0
- package/dist/shims/node-module.js +12 -0
- package/package.json +2 -1
- package/dist/configuration/old-without-merge-base.d.ts +0 -13
- package/dist/configuration/old-without-merge-base.js +0 -249
- package/dist/hmr/hmr-angular.d.ts +0 -1
- package/dist/hmr/hmr-angular.js +0 -34
- package/dist/hmr/hmr-bridge.d.ts +0 -18
- package/dist/hmr/hmr-bridge.js +0 -154
- package/dist/hmr/hmr-client.d.ts +0 -5
- package/dist/hmr/hmr-client.js +0 -93
- package/dist/hmr/hmr-server.d.ts +0 -20
- package/dist/hmr/hmr-server.js +0 -179
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// Component tracking utility for Vue HMR
|
|
2
|
+
// Helps track and manage Vue component instances in the NativeScript visual tree
|
|
3
|
+
const VERBOSE = false;
|
|
4
|
+
class NativeScriptVueComponentTracker {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.instanceMap = new Map();
|
|
7
|
+
this.fileToIdMap = new Map();
|
|
8
|
+
}
|
|
9
|
+
registerComponent(id, instance) {
|
|
10
|
+
if (!this.instanceMap.has(id)) {
|
|
11
|
+
this.instanceMap.set(id, new Set());
|
|
12
|
+
}
|
|
13
|
+
this.instanceMap.get(id).add(instance);
|
|
14
|
+
// Track file-to-ID mapping
|
|
15
|
+
const file = this.extractFileFromInstance(instance);
|
|
16
|
+
if (file) {
|
|
17
|
+
if (!this.fileToIdMap.has(file)) {
|
|
18
|
+
this.fileToIdMap.set(file, new Set());
|
|
19
|
+
}
|
|
20
|
+
this.fileToIdMap.get(file).add(id);
|
|
21
|
+
}
|
|
22
|
+
if (VERBOSE) {
|
|
23
|
+
console.info('[ns-hmr][tracker] Registered component:', { id, file, instanceCount: this.instanceMap.get(id).size });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
unregisterComponent(id, instance) {
|
|
27
|
+
const instances = this.instanceMap.get(id);
|
|
28
|
+
if (instances) {
|
|
29
|
+
instances.delete(instance);
|
|
30
|
+
if (instances.size === 0) {
|
|
31
|
+
this.instanceMap.delete(id);
|
|
32
|
+
// Clean up file mapping
|
|
33
|
+
const file = this.extractFileFromInstance(instance);
|
|
34
|
+
if (file) {
|
|
35
|
+
const ids = this.fileToIdMap.get(file);
|
|
36
|
+
if (ids) {
|
|
37
|
+
ids.delete(id);
|
|
38
|
+
if (ids.size === 0) {
|
|
39
|
+
this.fileToIdMap.delete(file);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (VERBOSE) {
|
|
46
|
+
console.info('[ns-hmr][tracker] Unregistered component:', { id, remainingCount: instances?.size || 0 });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
getInstances(id) {
|
|
50
|
+
const instances = this.instanceMap.get(id);
|
|
51
|
+
return instances ? Array.from(instances) : [];
|
|
52
|
+
}
|
|
53
|
+
getAllInstances() {
|
|
54
|
+
const result = new Map();
|
|
55
|
+
for (const [id, instances] of this.instanceMap) {
|
|
56
|
+
result.set(id, Array.from(instances));
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
findInstancesByFile(file) {
|
|
61
|
+
const instances = [];
|
|
62
|
+
const normalizedFile = this.normalizeFilePath(file);
|
|
63
|
+
// Direct file lookup
|
|
64
|
+
const ids = this.fileToIdMap.get(normalizedFile);
|
|
65
|
+
if (ids) {
|
|
66
|
+
for (const id of ids) {
|
|
67
|
+
instances.push(...this.getInstances(id));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Fallback: search through all instances
|
|
71
|
+
if (instances.length === 0) {
|
|
72
|
+
for (const [id, instanceSet] of this.instanceMap) {
|
|
73
|
+
for (const instance of instanceSet) {
|
|
74
|
+
const instanceFile = this.extractFileFromInstance(instance);
|
|
75
|
+
if (instanceFile && this.filesMatch(instanceFile, normalizedFile)) {
|
|
76
|
+
instances.push(instance);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (VERBOSE && instances.length > 0) {
|
|
82
|
+
console.info('[ns-hmr][tracker] Found instances by file:', { file: normalizedFile, count: instances.length });
|
|
83
|
+
}
|
|
84
|
+
return instances;
|
|
85
|
+
}
|
|
86
|
+
extractFileFromInstance(instance) {
|
|
87
|
+
// Try different ways to extract the file path from a Vue instance
|
|
88
|
+
try {
|
|
89
|
+
// Method 1: Check instance type
|
|
90
|
+
if (instance.type && instance.type.__file) {
|
|
91
|
+
return this.normalizeFilePath(instance.type.__file);
|
|
92
|
+
}
|
|
93
|
+
// Method 2: Check internal instance
|
|
94
|
+
if (instance.$ && instance.$.type && instance.$.type.__file) {
|
|
95
|
+
return this.normalizeFilePath(instance.$.type.__file);
|
|
96
|
+
}
|
|
97
|
+
// Method 3: Check component options
|
|
98
|
+
if (instance.__file) {
|
|
99
|
+
return this.normalizeFilePath(instance.__file);
|
|
100
|
+
}
|
|
101
|
+
// Method 4: Check parent component
|
|
102
|
+
if (instance.parent && instance.parent.type && instance.parent.type.__file) {
|
|
103
|
+
return this.normalizeFilePath(instance.parent.type.__file);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
if (VERBOSE) {
|
|
108
|
+
console.warn('[ns-hmr][tracker] Failed to extract file from instance:', error?.message);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
normalizeFilePath(file) {
|
|
114
|
+
// Remove query parameters and fragments
|
|
115
|
+
let normalized = file.split('?')[0].split('#')[0];
|
|
116
|
+
// Normalize path separators
|
|
117
|
+
normalized = normalized.replace(/\\/g, '/');
|
|
118
|
+
// Remove leading slash if present
|
|
119
|
+
if (normalized.startsWith('/')) {
|
|
120
|
+
normalized = normalized.slice(1);
|
|
121
|
+
}
|
|
122
|
+
return normalized;
|
|
123
|
+
}
|
|
124
|
+
filesMatch(file1, file2) {
|
|
125
|
+
const norm1 = this.normalizeFilePath(file1);
|
|
126
|
+
const norm2 = this.normalizeFilePath(file2);
|
|
127
|
+
// Exact match
|
|
128
|
+
if (norm1 === norm2) {
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
// Check if one is a suffix of the other (for different path prefixes)
|
|
132
|
+
if (norm1.endsWith(norm2) || norm2.endsWith(norm1)) {
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
// Check basename match for simple cases
|
|
136
|
+
const base1 = norm1.split('/').pop() || '';
|
|
137
|
+
const base2 = norm2.split('/').pop() || '';
|
|
138
|
+
return base1 === base2 && base1.length > 0;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// Global component tracker instance
|
|
142
|
+
const componentTracker = new NativeScriptVueComponentTracker();
|
|
143
|
+
// Expose tracker globally for debugging
|
|
144
|
+
globalThis.__NS_VUE_COMPONENT_TRACKER__ = componentTracker;
|
|
145
|
+
// Hook into Vue component lifecycle
|
|
146
|
+
export function setupComponentTracking() {
|
|
147
|
+
try {
|
|
148
|
+
const gAny = globalThis;
|
|
149
|
+
// Try to hook into Vue's component creation
|
|
150
|
+
if (gAny.__VUE_HMR_RUNTIME__) {
|
|
151
|
+
const originalCreateRecord = gAny.__VUE_HMR_RUNTIME__.createRecord;
|
|
152
|
+
gAny.__VUE_HMR_RUNTIME__.createRecord = function (id, initialDef) {
|
|
153
|
+
const result = originalCreateRecord.call(this, id, initialDef);
|
|
154
|
+
// Track this component definition
|
|
155
|
+
if (VERBOSE) {
|
|
156
|
+
console.info('[ns-hmr][tracker] Vue component record created:', id);
|
|
157
|
+
}
|
|
158
|
+
return result;
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
// // Try to hook into nativescript-vue's component mounting
|
|
162
|
+
// Instead of modifying the module, we'll use Vue's global API hooks
|
|
163
|
+
// and listen for component registrations through the Vue HMR runtime
|
|
164
|
+
if (VERBOSE) {
|
|
165
|
+
console.info('[ns-hmr][tracker] Using Vue HMR runtime hooks for component tracking');
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
console.warn('[ns-hmr][tracker] Failed to setup component tracking:', error?.message);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function extractComponentId(instance) {
|
|
173
|
+
try {
|
|
174
|
+
// Extract ID from instance, similar to extractFileFromInstance
|
|
175
|
+
if (instance.type && instance.type.__file) {
|
|
176
|
+
return instance.type.__file;
|
|
177
|
+
}
|
|
178
|
+
if (instance.$ && instance.$.type && instance.$.type.__file) {
|
|
179
|
+
return instance.$.type.__file;
|
|
180
|
+
}
|
|
181
|
+
if (instance.__file) {
|
|
182
|
+
return instance.__file;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
// Ignore extraction errors
|
|
187
|
+
}
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
// Auto-setup component tracking
|
|
191
|
+
setupComponentTracking();
|
|
192
|
+
export { componentTracker };
|
|
193
|
+
export default componentTracker;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function applyCssText(cssText: string): void;
|
|
2
|
+
export declare function fetchText(url: string): Promise<string>;
|
|
3
|
+
export declare function handleCssUpdates(cssUpdates: any[], httpOrigin: string): Promise<void>;
|
|
4
|
+
export declare function handleCustomCss(cssText: string): void;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Application, Frame } from "@nativescript/core";
|
|
2
|
+
const VERBOSE = !!globalThis.__NS_ENV_VERBOSE__;
|
|
3
|
+
// CSS helper function
|
|
4
|
+
export function applyCssText(cssText) {
|
|
5
|
+
if (typeof cssText !== "string" || !cssText.length)
|
|
6
|
+
return;
|
|
7
|
+
try {
|
|
8
|
+
if (Application.addCss) {
|
|
9
|
+
Application.addCss(cssText);
|
|
10
|
+
if (VERBOSE)
|
|
11
|
+
console.info("[ns-hmr] Applied app CSS");
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
const topFrame = Frame.topmost?.();
|
|
15
|
+
const curPage = topFrame?.currentPage;
|
|
16
|
+
curPage.addCss(cssText);
|
|
17
|
+
if (VERBOSE)
|
|
18
|
+
console.info("[ns-hmr] Applied page CSS");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
catch (e) {
|
|
22
|
+
console.warn("[ns-hmr] CSS apply failed:", e?.message || String(e));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// Fetch helper
|
|
26
|
+
export async function fetchText(url) {
|
|
27
|
+
try {
|
|
28
|
+
const g = globalThis;
|
|
29
|
+
if (typeof g.fetch === "function") {
|
|
30
|
+
const res = await g.fetch(url);
|
|
31
|
+
return await res.text();
|
|
32
|
+
}
|
|
33
|
+
// Fallback to NativeScript Http if available
|
|
34
|
+
const Http = g.Http;
|
|
35
|
+
if (Http && Http.getString) {
|
|
36
|
+
return await Http.getString(url);
|
|
37
|
+
}
|
|
38
|
+
if (VERBOSE)
|
|
39
|
+
console.warn("[ns-hmr] No fetch method available");
|
|
40
|
+
return "";
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
console.warn("[ns-hmr] Fetch failed:", e?.message || String(e));
|
|
44
|
+
return "";
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Handle CSS updates from Vite
|
|
48
|
+
export async function handleCssUpdates(cssUpdates, httpOrigin) {
|
|
49
|
+
for (const update of cssUpdates) {
|
|
50
|
+
try {
|
|
51
|
+
const path = update.path || update.acceptedPath || "";
|
|
52
|
+
if (!path || !httpOrigin)
|
|
53
|
+
continue;
|
|
54
|
+
// Compose URL like the Vite client (ensure raw content and cache-bust)
|
|
55
|
+
const hasQuery = path.includes("?");
|
|
56
|
+
const tParam = `t=${encodeURIComponent(String(update.timestamp || Date.now()))}`;
|
|
57
|
+
const directParam = hasQuery ? "&direct=1" : "?direct=1";
|
|
58
|
+
const tSuffix = (hasQuery ? "&" : "?") + tParam;
|
|
59
|
+
const url = httpOrigin + path + directParam + tSuffix;
|
|
60
|
+
if (VERBOSE)
|
|
61
|
+
console.info("[ns-hmr] Fetching CSS:", url);
|
|
62
|
+
const cssText = await fetchText(url);
|
|
63
|
+
if (cssText) {
|
|
64
|
+
applyCssText(cssText);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
console.warn("[ns-hmr] CSS update fetch/apply failed:", e?.message || String(e));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Handle custom CSS events
|
|
73
|
+
export function handleCustomCss(cssText) {
|
|
74
|
+
if (typeof cssText === "string" && cssText.length) {
|
|
75
|
+
applyCssText(cssText);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function handleMessage(data: string, httpOrigin: string): void;
|