vfsjs-test 1.0.20 → 1.0.21
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/main.js +19 -103
- package/package.json +1 -1
- package/vfsjs.js +23 -22
package/main.js
CHANGED
|
@@ -1,113 +1,29 @@
|
|
|
1
|
-
// main.js
|
|
2
|
-
|
|
3
|
-
window.vfs = {
|
|
4
|
-
// Write local strings straight to memory mapping keyspaces
|
|
5
|
-
add(filename, contentString, customMime = null) {
|
|
6
|
-
return window._vfsKernel.write(filename, contentString, customMime);
|
|
7
|
-
},
|
|
8
|
-
|
|
9
|
-
// Remote Proxy Asset Grabber (Requires target destination to support CORS)
|
|
10
|
-
async importRemote(localFilename, remoteUrl, customMime = null) {
|
|
11
|
-
try {
|
|
12
|
-
console.log(`[VFS Proxy] Pulling remote source stream: ${remoteUrl}`);
|
|
13
|
-
const response = await fetch(remoteUrl);
|
|
14
|
-
if (!response.ok) throw new Error(`HTTP network fault code: ${response.status}`);
|
|
15
|
-
|
|
16
|
-
const remoteTextContent = await response.text();
|
|
17
|
-
this.add(localFilename, remoteTextContent, customMime);
|
|
18
|
-
return true;
|
|
19
|
-
} catch (err) {
|
|
20
|
-
console.error(`[VFS Proxy Error] Could not map ${localFilename}:`, err);
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
};
|
|
1
|
+
// Inside main.js
|
|
25
2
|
|
|
26
3
|
async function startDeveloperWorkspace() {
|
|
27
|
-
// 1.
|
|
4
|
+
// 1. Fetch remote libraries, populate virtual files, etc.
|
|
28
5
|
const remoteLibraryUrl = 'https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.4/dist/confetti.browser.min.js';
|
|
29
|
-
|
|
30
|
-
// 2. Map the remote asset to a virtual file named "my-confetti-engine.js"
|
|
31
|
-
const importSuccess = await vfs.importRemote('my-confetti-engine.js', remoteLibraryUrl, 'text/javascript');
|
|
32
|
-
|
|
33
|
-
if (!importSuccess) {
|
|
34
|
-
console.error("Failed to fetch library from CDNJS.");
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// 3. Create the standard HTML layout referencing the newly mapped virtual file
|
|
39
|
-
// Inside main.js -> startDeveloperWorkspace()
|
|
6
|
+
await vfs.importRemote('my-confetti-engine.js', remoteLibraryUrl, 'text/javascript');
|
|
40
7
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
<head>
|
|
45
|
-
<meta charset="UTF-8">
|
|
46
|
-
<title>Scrollable Workspace Demo</title>
|
|
47
|
-
<link rel="stylesheet" href="live_theme.css?vfs=true">
|
|
48
|
-
</head>
|
|
49
|
-
<body>
|
|
50
|
-
<h2>Infrared Scrollable Core</h2>
|
|
51
|
-
<p>Scroll down! This page natively handles height overflows now.</p>
|
|
52
|
-
|
|
53
|
-
<div style="margin-top: 400px;">👇 Way down here...</div>
|
|
54
|
-
<div style="margin-top: 500px;">🎨 Keep scrolling...</div>
|
|
55
|
-
<div style="margin-top: 600px;">🚀 Deep in the VFS layout!</div>
|
|
56
|
-
|
|
57
|
-
<script src="my-confetti-engine.js?vfs=true"></script>
|
|
58
|
-
<script src="index.js?vfs=true"></script>
|
|
59
|
-
</body>
|
|
60
|
-
</html>
|
|
61
|
-
`, 'text/html');
|
|
8
|
+
// 2. Populate your script and style data maps into the active worker cache state
|
|
9
|
+
vfs.add('app.js', `console.log("App script running natively inside virtualized layout context!");`, 'text/javascript');
|
|
10
|
+
vfs.add('style.css', `body { background: #020617; color: #38bdf8; font-family: monospace; }`, 'text/css');
|
|
62
11
|
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
html { height: 100%; }
|
|
66
|
-
body {
|
|
67
|
-
margin: 0;
|
|
68
|
-
padding: 40px;
|
|
69
|
-
font-family: monospace;
|
|
70
|
-
background: linear-gradient(-45deg, #1e1b4b, #311042, #0f172a) !important;
|
|
71
|
-
color: #ffffff !important;
|
|
72
|
-
text-align: center;
|
|
73
|
-
|
|
74
|
-
/* ALLOW THE VIRTUAL BODY TO SCROLL NATURALLY */
|
|
75
|
-
min-height: 100%;
|
|
76
|
-
overflow-y: auto;
|
|
77
|
-
}
|
|
78
|
-
h2 { color: #38bdf8; }
|
|
79
|
-
`, 'text/css');
|
|
80
|
-
|
|
81
|
-
// 5. Execution Script: Call the global function initialized by the CDNJS script
|
|
82
|
-
vfs.add('index.js', `
|
|
83
|
-
console.log("Launcher script running. Invoking confetti...");
|
|
84
|
-
|
|
85
|
-
// Ensure the library attached itself to the virtual window context safely
|
|
86
|
-
if (typeof window.confetti === 'function') {
|
|
87
|
-
// Fire an endless burst of celebratory confetti particles!
|
|
88
|
-
setInterval(() => {
|
|
89
|
-
window.confetti({
|
|
90
|
-
particleCount: 50,
|
|
91
|
-
spread: 60,
|
|
92
|
-
origin: { y: 0.6 }
|
|
93
|
-
});
|
|
94
|
-
}, 1500);
|
|
95
|
-
} else {
|
|
96
|
-
console.error("Confetti engine not found in virtual window global scope.");
|
|
97
|
-
}
|
|
98
|
-
`, 'text/javascript');
|
|
99
|
-
|
|
100
|
-
// 6. Point the fullscreen viewport to the directory root
|
|
101
|
-
const viewport = document.getElementById('canvas-viewport');
|
|
102
|
-
if (viewport) {
|
|
103
|
-
viewport.src = './?vfs=true';
|
|
104
|
-
}
|
|
12
|
+
// 3. CRITICAL: The VFS is loaded, call launch() to spawn the iframe safely!
|
|
13
|
+
window._vfsKernel.launch();
|
|
105
14
|
}
|
|
106
15
|
|
|
107
16
|
// Global invocation hook listener
|
|
108
17
|
document.addEventListener('DOMContentLoaded', async () => {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
18
|
+
// Loop interval ensures window._vfsKernel is instantiated and done setting up step 1
|
|
19
|
+
const checker = setInterval(async () => {
|
|
20
|
+
if (window._vfsKernel) {
|
|
21
|
+
clearInterval(checker);
|
|
22
|
+
// Wait for the service worker confirmation to pass back up
|
|
23
|
+
const isReady = await navigator.serviceWorker.ready;
|
|
24
|
+
if (isReady) {
|
|
25
|
+
startDeveloperWorkspace();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}, 10);
|
|
113
29
|
});
|
package/package.json
CHANGED
package/vfsjs.js
CHANGED
|
@@ -1,56 +1,58 @@
|
|
|
1
|
-
// vfsjs.js - Version
|
|
1
|
+
// vfsjs.js - Version 4.0.0 (Race-Condition Proof Production Engine)
|
|
2
2
|
(function() {
|
|
3
3
|
const encoder = new TextEncoder();
|
|
4
4
|
|
|
5
5
|
const engineCore = {
|
|
6
6
|
async init() {
|
|
7
7
|
try {
|
|
8
|
-
// 1.
|
|
8
|
+
// 1. Core Service Worker Handshake
|
|
9
9
|
await navigator.serviceWorker.register('./sw.js');
|
|
10
|
-
|
|
11
|
-
// Ensure the worker is actively controlling the page before proceeding
|
|
12
10
|
if (!navigator.serviceWorker.controller) {
|
|
13
11
|
await new Promise(r => navigator.serviceWorker.addEventListener('controllerchange', r, { once: true }));
|
|
14
12
|
}
|
|
15
13
|
|
|
16
|
-
// 2. Capture the physical file's raw HTML structure exactly as it is
|
|
14
|
+
// 2. Capture the physical file's raw HTML structure exactly as it is written
|
|
17
15
|
const developerRawHtml = `<!DOCTYPE html>\n<html>${document.documentElement.innerHTML}</html>`;
|
|
18
16
|
this.write('index.html', developerRawHtml, 'text/html');
|
|
19
17
|
|
|
20
|
-
// 3.
|
|
18
|
+
// 3. Structural Reset: Wipe page visual nodes and lock outer body down solid
|
|
21
19
|
document.documentElement.innerHTML = '';
|
|
22
20
|
Object.assign(document.documentElement.style, { width: '100%', height: '100%', overflow: 'hidden', margin: '0', padding: '0' });
|
|
23
21
|
Object.assign(document.body.style, { width: '100%', height: '100%', overflow: 'hidden', margin: '0', padding: '0', background: '#020617' });
|
|
24
22
|
|
|
25
|
-
|
|
26
|
-
const iframe = document.createElement('iframe');
|
|
27
|
-
iframe.id = 'canvas-viewport';
|
|
28
|
-
Object.assign(iframe.style, {
|
|
29
|
-
position: 'absolute', top: '0', left: '0', width: '100%', height: '100%',
|
|
30
|
-
border: 'none', margin: '0', padding: '0', zIndex: '999999'
|
|
31
|
-
});
|
|
32
|
-
document.body.appendChild(iframe);
|
|
33
|
-
|
|
34
|
-
// 5. Point the canvas to the virtual root directory
|
|
35
|
-
iframe.src = './?vfs=true';
|
|
36
|
-
|
|
23
|
+
console.log("[VFS Kernel] Stage 1 Ready: Core cached. Awaiting developer vfs.add() execution...");
|
|
37
24
|
return true;
|
|
38
25
|
} catch (err) {
|
|
39
|
-
console.error("VFS
|
|
26
|
+
console.error("VFS Core Initialization Failure:", err);
|
|
40
27
|
return false;
|
|
41
28
|
}
|
|
42
29
|
},
|
|
43
30
|
|
|
31
|
+
// PHASE 2: Call this ONLY when files are completely mapped to safely spawn the iframe!
|
|
32
|
+
launch() {
|
|
33
|
+
if (document.getElementById('canvas-viewport')) return;
|
|
34
|
+
|
|
35
|
+
console.log("[VFS Kernel] Stage 2 Triggered: All assets populated. Mounting secure viewport sandbox.");
|
|
36
|
+
const iframe = document.createElement('iframe');
|
|
37
|
+
iframe.id = 'canvas-viewport';
|
|
38
|
+
Object.assign(iframe.style, {
|
|
39
|
+
position: 'absolute', top: '0', left: '0', width: '100%', height: '100%',
|
|
40
|
+
border: 'none', margin: '0', padding: '0', zIndex: '999999'
|
|
41
|
+
});
|
|
42
|
+
document.body.appendChild(iframe);
|
|
43
|
+
|
|
44
|
+
// Point to the virtual root route safely now that assets are loaded
|
|
45
|
+
iframe.src = './?vfs=true';
|
|
46
|
+
},
|
|
47
|
+
|
|
44
48
|
write(filename, contentString, customMime) {
|
|
45
49
|
if (!navigator.serviceWorker.controller) return false;
|
|
46
50
|
|
|
47
|
-
// Extract a clean relative filename path if an absolute or query-string URL slips in
|
|
48
51
|
let cleanKey = filename.split('?')[0];
|
|
49
52
|
if (cleanKey.includes('/')) {
|
|
50
53
|
cleanKey = cleanKey.split('/').pop();
|
|
51
54
|
}
|
|
52
55
|
|
|
53
|
-
// Auto-detect basic mime types if not provided
|
|
54
56
|
if (!customMime) {
|
|
55
57
|
const ext = cleanKey.split('.').pop().toLowerCase();
|
|
56
58
|
const mimeMatrix = { 'js': 'text/javascript', 'css': 'text/css', 'html': 'text/html', 'json': 'application/json' };
|
|
@@ -69,7 +71,6 @@
|
|
|
69
71
|
|
|
70
72
|
window._vfsKernel = engineCore;
|
|
71
73
|
|
|
72
|
-
// Execute immediately or when DOM structural elements are ready
|
|
73
74
|
if (document.readyState === 'loading') {
|
|
74
75
|
document.addEventListener('DOMContentLoaded', () => engineCore.init());
|
|
75
76
|
} else {
|