sliftutils 0.1.1
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/.cursorrules +161 -0
- package/.eslintrc.js +38 -0
- package/.vscode/settings.json +39 -0
- package/bundler/buffer.js +2370 -0
- package/bundler/bundleEntry.ts +32 -0
- package/bundler/bundleEntryCaller.ts +8 -0
- package/bundler/bundleRequire.ts +244 -0
- package/bundler/bundleWrapper.ts +115 -0
- package/bundler/bundler.ts +72 -0
- package/bundler/flattenSourceMaps.ts +0 -0
- package/bundler/sourceMaps.ts +261 -0
- package/misc/environment.ts +11 -0
- package/misc/types.ts +3 -0
- package/misc/zip.ts +37 -0
- package/package.json +24 -0
- package/spec.txt +33 -0
- package/storage/CachedStorage.ts +32 -0
- package/storage/DelayedStorage.ts +30 -0
- package/storage/DiskCollection.ts +272 -0
- package/storage/FileFolderAPI.tsx +427 -0
- package/storage/IStorage.ts +40 -0
- package/storage/IndexedDBFileFolderAPI.ts +170 -0
- package/storage/JSONStorage.ts +35 -0
- package/storage/PendingManager.tsx +63 -0
- package/storage/PendingStorage.ts +47 -0
- package/storage/PrivateFileSystemStorage.ts +192 -0
- package/storage/StorageObservable.ts +122 -0
- package/storage/TransactionStorage.ts +485 -0
- package/storage/fileSystemPointer.ts +81 -0
- package/storage/storage.d.ts +41 -0
- package/tsconfig.json +31 -0
- package/web/DropdownCustom.tsx +150 -0
- package/web/FullscreenModal.tsx +75 -0
- package/web/GenericFormat.tsx +186 -0
- package/web/Input.tsx +350 -0
- package/web/InputLabel.tsx +288 -0
- package/web/InputPicker.tsx +158 -0
- package/web/LocalStorageParam.ts +56 -0
- package/web/SyncedController.ts +405 -0
- package/web/SyncedLoadingIndicator.tsx +37 -0
- package/web/Table.tsx +188 -0
- package/web/URLParam.ts +84 -0
- package/web/asyncObservable.ts +40 -0
- package/web/colors.tsx +14 -0
- package/web/mobxTyped.ts +29 -0
- package/web/modal.tsx +18 -0
- package/web/observer.tsx +35 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { bundle } from "./bundler";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
|
|
5
|
+
function getCommandLineArg(name: string) {
|
|
6
|
+
let index = process.argv.indexOf(name);
|
|
7
|
+
if (index === -1) return null;
|
|
8
|
+
return process.argv[index + 1];
|
|
9
|
+
}
|
|
10
|
+
async function main() {
|
|
11
|
+
let entryPoint = getCommandLineArg("--entryPoint");
|
|
12
|
+
if (!entryPoint) {
|
|
13
|
+
throw new Error("No entry point provided");
|
|
14
|
+
}
|
|
15
|
+
require("../" + entryPoint);
|
|
16
|
+
|
|
17
|
+
let name = path.basename(entryPoint);
|
|
18
|
+
if (name.endsWith(".ts") || name.endsWith(".tsx")) {
|
|
19
|
+
name = name.split(".").slice(0, -1).join(".");
|
|
20
|
+
}
|
|
21
|
+
name += ".js";
|
|
22
|
+
|
|
23
|
+
let modules = Object.values(require.cache).filter(x => x?.id !== module.id);
|
|
24
|
+
|
|
25
|
+
let bundled = await bundle({
|
|
26
|
+
modules,
|
|
27
|
+
rootPath: path.resolve("."),
|
|
28
|
+
entryPoints: [entryPoint],
|
|
29
|
+
});
|
|
30
|
+
await fs.promises.writeFile(`./build-extension/${name}`, bundled.bundle);
|
|
31
|
+
}
|
|
32
|
+
main().catch(console.error).finally(() => process.exit());
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import child_process from "child_process";
|
|
2
|
+
import { runPromise } from "socket-function/src/runPromise";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export async function bundleEntryCaller(entryPoint: string, args = "") {
|
|
6
|
+
let command = "yarn typenode ./bundler/bundleEntry.ts --entryPoint " + entryPoint + " " + args;
|
|
7
|
+
await runPromise(command);
|
|
8
|
+
}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { SerializedModule } from "./bundleWrapper";
|
|
2
|
+
|
|
3
|
+
// Sets globalThis.require = ..., utilizing registeredModules (from bundleWrapper.ts) when require is called
|
|
4
|
+
export interface BundleRequireConfig {
|
|
5
|
+
rootPath: string;
|
|
6
|
+
}
|
|
7
|
+
export function bundleRequire(config: BundleRequireConfig) {
|
|
8
|
+
globalThis.process = globalThis.process || {
|
|
9
|
+
env: {
|
|
10
|
+
NODE_ENV: "production",
|
|
11
|
+
},
|
|
12
|
+
versions: {},
|
|
13
|
+
on: () => { },
|
|
14
|
+
};
|
|
15
|
+
(globalThis as any).window = (globalThis as any).window || globalThis;
|
|
16
|
+
(globalThis as any).global = (globalThis as any).global || globalThis;
|
|
17
|
+
(globalThis as any).setImmediate = (globalThis as any).setImmediate || globalThis.setTimeout;
|
|
18
|
+
|
|
19
|
+
// Set document, so isNode checks return false.
|
|
20
|
+
(globalThis as any).document = (globalThis as any).document || {};
|
|
21
|
+
(globalThis as any).BOOTED_EDGE_NODE = undefined;
|
|
22
|
+
|
|
23
|
+
const builtInModuleExports = {
|
|
24
|
+
worker_threads: {
|
|
25
|
+
isMainThread: true,
|
|
26
|
+
},
|
|
27
|
+
util: {
|
|
28
|
+
// https://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor
|
|
29
|
+
inherits(constructor: any, superConstructor: any) {
|
|
30
|
+
Object.setPrototypeOf(constructor.prototype, superConstructor.prototype);
|
|
31
|
+
},
|
|
32
|
+
TextDecoder: TextDecoder,
|
|
33
|
+
TextEncoder: TextEncoder,
|
|
34
|
+
},
|
|
35
|
+
buffer: { Buffer },
|
|
36
|
+
stream: {
|
|
37
|
+
// HACK: Needed to get SAX JS to work correctly.
|
|
38
|
+
Stream: function () { },
|
|
39
|
+
Transform: function () { },
|
|
40
|
+
|
|
41
|
+
Writable: function () { },
|
|
42
|
+
},
|
|
43
|
+
timers: {
|
|
44
|
+
// TODO: Add all members of timers
|
|
45
|
+
setImmediate: globalThis.setImmediate,
|
|
46
|
+
},
|
|
47
|
+
child_process: {},
|
|
48
|
+
events: class EventEmitter { },
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// Just path.resolve (but needs to be reimplemented, because we can't use imports)
|
|
52
|
+
function pathResolve(...paths: string[]): string {
|
|
53
|
+
// Start with empty path segments array
|
|
54
|
+
let segments: string[] = [];
|
|
55
|
+
let isWindowsPath = false;
|
|
56
|
+
|
|
57
|
+
paths = paths.map(x => x.replace(/\\/g, "/"));
|
|
58
|
+
|
|
59
|
+
// Process each path argument
|
|
60
|
+
for (const path of paths) {
|
|
61
|
+
// Check for Windows drive letter (e.g., C:/)
|
|
62
|
+
if (/^[A-Za-z]:/.test(path)) {
|
|
63
|
+
isWindowsPath = true;
|
|
64
|
+
// Remove drive letter for processing
|
|
65
|
+
const withoutDrive = path.slice(2);
|
|
66
|
+
if (withoutDrive.startsWith("/")) {
|
|
67
|
+
segments = [path.slice(0, 2)]; // Keep drive letter and reset segments
|
|
68
|
+
} else {
|
|
69
|
+
// If no leading slash, keep current segments (relative to current drive path)
|
|
70
|
+
if (segments.length === 0 || !segments[0].match(/^[A-Za-z]:/)) {
|
|
71
|
+
segments = [path.slice(0, 2)];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Add the rest of the path parts
|
|
75
|
+
segments.push(...withoutDrive.split("/").filter(x => x));
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// If absolute path, reset segments but keep drive letter if present
|
|
80
|
+
if (path.startsWith("/")) {
|
|
81
|
+
if (isWindowsPath && segments.length > 0 && segments[0].match(/^[A-Za-z]:/)) {
|
|
82
|
+
const drive = segments[0];
|
|
83
|
+
segments = [drive];
|
|
84
|
+
} else {
|
|
85
|
+
segments = [];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Split path into segments and process each
|
|
90
|
+
const pathParts = path.split("/").filter(x => x);
|
|
91
|
+
for (const part of pathParts) {
|
|
92
|
+
if (part === "..") {
|
|
93
|
+
// Don't pop off the drive letter
|
|
94
|
+
if (segments.length > (isWindowsPath ? 1 : 0)) {
|
|
95
|
+
segments.pop();
|
|
96
|
+
}
|
|
97
|
+
} else if (part !== ".") {
|
|
98
|
+
// Add segment if not current directory marker
|
|
99
|
+
segments.push(part);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Combine segments into final path
|
|
105
|
+
let result = segments.join("/");
|
|
106
|
+
if (!isWindowsPath) {
|
|
107
|
+
result = "/" + result;
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
function dirname(path: string): string {
|
|
112
|
+
return path.split("/").slice(0, -1).join("/");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const requireCache: { [id: string]: NodeJS.Module } = {};
|
|
116
|
+
|
|
117
|
+
let rootModule = createModule({
|
|
118
|
+
parentModule: undefined,
|
|
119
|
+
resolveAbsolutePath: config.rootPath + "/rootPlaceholder",
|
|
120
|
+
});
|
|
121
|
+
globalThis.require = rootModule.require as any;
|
|
122
|
+
|
|
123
|
+
function createModule(config: {
|
|
124
|
+
parentModule: NodeJS.Module | undefined;
|
|
125
|
+
resolveAbsolutePath: string;
|
|
126
|
+
}): NodeJS.Module {
|
|
127
|
+
const { parentModule, resolveAbsolutePath } = config;
|
|
128
|
+
let cached = requireCache[resolveAbsolutePath];
|
|
129
|
+
if (cached) {
|
|
130
|
+
return cached;
|
|
131
|
+
}
|
|
132
|
+
let serialized = globalThis.registeredModules?.[resolveAbsolutePath];
|
|
133
|
+
|
|
134
|
+
let newModule: NodeJS.Module = {
|
|
135
|
+
id: resolveAbsolutePath,
|
|
136
|
+
filename: resolveAbsolutePath,
|
|
137
|
+
exports: {},
|
|
138
|
+
parent: parentModule,
|
|
139
|
+
children: [],
|
|
140
|
+
isPreloading: false,
|
|
141
|
+
loaded: false,
|
|
142
|
+
path: dirname(resolveAbsolutePath),
|
|
143
|
+
paths: serialized?.paths || [],
|
|
144
|
+
require,
|
|
145
|
+
load,
|
|
146
|
+
} as any;
|
|
147
|
+
newModule.exports.default = newModule.exports;
|
|
148
|
+
if (parentModule) {
|
|
149
|
+
parentModule.children.push(newModule);
|
|
150
|
+
}
|
|
151
|
+
for (let [key, value] of Object.entries(serialized?.moduleFields || {})) {
|
|
152
|
+
if (key in newModule) continue;
|
|
153
|
+
(newModule as any)[key] = value;
|
|
154
|
+
}
|
|
155
|
+
resolve.paths = (request: string) => [];
|
|
156
|
+
|
|
157
|
+
requireCache[newModule.id] = newModule;
|
|
158
|
+
require.resolve = resolve;
|
|
159
|
+
require.cache = requireCache;
|
|
160
|
+
require.main = newModule;
|
|
161
|
+
require.extensions = "extension not implemented yet" as any;
|
|
162
|
+
|
|
163
|
+
// Resolves file extensions
|
|
164
|
+
function innerResolve(path: string): string {
|
|
165
|
+
let candidates = [
|
|
166
|
+
path,
|
|
167
|
+
path + ".js",
|
|
168
|
+
path + ".ts",
|
|
169
|
+
path + ".tsx",
|
|
170
|
+
];
|
|
171
|
+
for (let candidate of candidates) {
|
|
172
|
+
let registered = globalThis.registeredModules?.[candidate];
|
|
173
|
+
if (registered) {
|
|
174
|
+
return registered.id;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return path;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function resolve(path: string): string {
|
|
181
|
+
path = path.replace(/\\/g, "/");
|
|
182
|
+
if (path.startsWith(".")) {
|
|
183
|
+
return innerResolve(pathResolve(newModule.path, path));
|
|
184
|
+
}
|
|
185
|
+
// We need to search all paths
|
|
186
|
+
for (let searchRoot of serialized?.paths || []) {
|
|
187
|
+
let candidate = innerResolve(pathResolve(searchRoot, path));
|
|
188
|
+
let registered = globalThis.registeredModules?.[candidate];
|
|
189
|
+
if (registered) {
|
|
190
|
+
return registered.id;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// It is probably "fs" or something like that
|
|
194
|
+
return path;
|
|
195
|
+
// debugger;
|
|
196
|
+
// throw new Error(`Module ${path} not found`);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function require(path: string) {
|
|
200
|
+
if (path in builtInModuleExports) {
|
|
201
|
+
return builtInModuleExports[path as keyof typeof builtInModuleExports];
|
|
202
|
+
}
|
|
203
|
+
let resolved = resolve(path);
|
|
204
|
+
let subModule = createModule({
|
|
205
|
+
parentModule: newModule,
|
|
206
|
+
resolveAbsolutePath: resolved,
|
|
207
|
+
}) as any;
|
|
208
|
+
subModule.load(newModule.filename);
|
|
209
|
+
return subModule.exports;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function load() {
|
|
213
|
+
if (newModule.loaded) return;
|
|
214
|
+
// NOTE: Set loaded immediately, in case we have a circular dependency
|
|
215
|
+
newModule.loaded = true;
|
|
216
|
+
|
|
217
|
+
if (serialized) {
|
|
218
|
+
serialized.moduleFnc(newModule.exports, require, newModule, newModule.filename, newModule.path);
|
|
219
|
+
} else {
|
|
220
|
+
// If we are being imported by the root module, we need to throw an error
|
|
221
|
+
if (!config.parentModule?.parent) {
|
|
222
|
+
debugger;
|
|
223
|
+
throw new Error(`Could not find required module ${JSON.stringify(config.resolveAbsolutePath)}, have ${JSON.stringify(Object.keys(globalThis.registeredModules || {}))}`);
|
|
224
|
+
}
|
|
225
|
+
newModule.exports = new Proxy(
|
|
226
|
+
{},
|
|
227
|
+
{
|
|
228
|
+
get(target, property) {
|
|
229
|
+
if (property === "__esModule") return undefined;
|
|
230
|
+
if (property === "default") return newModule.exports;
|
|
231
|
+
|
|
232
|
+
console.warn(
|
|
233
|
+
`Module ${newModule.filename} is not available (are you missing "module.allowclient = true"?). Tried to access ${String(property)}.`
|
|
234
|
+
);
|
|
235
|
+
return undefined;
|
|
236
|
+
},
|
|
237
|
+
}
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return newModule;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { cache } from "socket-function/src/caching";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
|
|
5
|
+
const getPackageJsonPath = cache((directory: string): string | undefined => {
|
|
6
|
+
if (!directory.includes("/") && !directory.includes("\\")) {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
let packageJsonPath = path.resolve(directory, "package.json");
|
|
10
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
11
|
+
return packageJsonPath;
|
|
12
|
+
}
|
|
13
|
+
return getPackageJsonPath(path.dirname(directory));
|
|
14
|
+
});
|
|
15
|
+
const getMainPath = cache((directory: string): string | undefined => {
|
|
16
|
+
let packageJsonPath = getPackageJsonPath(directory);
|
|
17
|
+
if (!packageJsonPath) return undefined;
|
|
18
|
+
let packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
19
|
+
let dir = path.dirname(packageJsonPath);
|
|
20
|
+
let mainName = packageJson.main;
|
|
21
|
+
if (!mainName) {
|
|
22
|
+
if (fs.existsSync(path.resolve(dir, "index.js"))) {
|
|
23
|
+
mainName = "index.js";
|
|
24
|
+
} else if (fs.existsSync(path.resolve(dir, "index.ts"))) {
|
|
25
|
+
mainName = "index.ts";
|
|
26
|
+
} else if (fs.existsSync(path.resolve(dir, "index.tsx"))) {
|
|
27
|
+
mainName = "index.tsx";
|
|
28
|
+
} else {
|
|
29
|
+
mainName = "index.js";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
let mainPath = path.resolve(dir, mainName);
|
|
33
|
+
return mainPath;
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
// Wraps the module so it registers itself when the returned code is evaluated
|
|
38
|
+
// - See https://nodejs.org/api/modules.html#the-module-wrapper
|
|
39
|
+
export function wrapModule(module: NodeJS.Module): string {
|
|
40
|
+
let contents = (module as any).moduleContents || "/* No contents */";
|
|
41
|
+
|
|
42
|
+
// NOTE: debugName only matters during module evaluation. After that the sourcemap should work.
|
|
43
|
+
let debugName = module.filename
|
|
44
|
+
.replace(/\\/g, "/")
|
|
45
|
+
.split("/")
|
|
46
|
+
.slice(-1)[0]
|
|
47
|
+
.replace(/\./g, "_")
|
|
48
|
+
.replace(/[^a-zA-Z_]/g, "");
|
|
49
|
+
|
|
50
|
+
let wrapped = `(function ${debugName}(exports, require, module, __filename, __dirname) { ${contents}
|
|
51
|
+
})`;
|
|
52
|
+
|
|
53
|
+
let moduleFields: { [flag: string]: unknown; } = {};
|
|
54
|
+
for (let [key, value] of Object.entries(module)) {
|
|
55
|
+
if (typeof value === "function") continue;
|
|
56
|
+
if (typeof value === "boolean") {
|
|
57
|
+
moduleFields[key] = value;
|
|
58
|
+
} else if (typeof value === "string" && value.length < 150) {
|
|
59
|
+
moduleFields[key] = value;
|
|
60
|
+
} else if (typeof value === "number") {
|
|
61
|
+
moduleFields[key] = value;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let isModuleMain: string | undefined;
|
|
66
|
+
let dirname = path.dirname(module.filename);
|
|
67
|
+
let packageJsonPath = getPackageJsonPath(dirname);
|
|
68
|
+
if (packageJsonPath) {
|
|
69
|
+
let mainPath = getMainPath(dirname);
|
|
70
|
+
if (mainPath?.replaceAll("\\", "/") === module.filename.replaceAll("\\", "/")) {
|
|
71
|
+
// Then we are the main of the module
|
|
72
|
+
isModuleMain = path.dirname(packageJsonPath).replaceAll("\\", "/");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// NOTE: We can't have new lines, or they break source maps
|
|
77
|
+
let objWrapped = `{`
|
|
78
|
+
+ ` id: ${JSON.stringify(module.id.replaceAll("\\", "/"))},`
|
|
79
|
+
+ ` filename: ${JSON.stringify(module.filename.replaceAll("\\", "/"))},`
|
|
80
|
+
+ ` isModuleMain: ${JSON.stringify(isModuleMain)},`
|
|
81
|
+
+ ` paths: ${JSON.stringify(module.paths.map(p => p.replaceAll("\\", "/")))},`
|
|
82
|
+
+ ` moduleFields: ${JSON.stringify(moduleFields)},`
|
|
83
|
+
+ ` moduleFnc: ${wrapped}`
|
|
84
|
+
+ ` }`;
|
|
85
|
+
|
|
86
|
+
function initModule(serialized: SerializedModule) {
|
|
87
|
+
globalThis.registeredModules = globalThis.registeredModules || {};
|
|
88
|
+
globalThis.registeredModules[serialized.id] = serialized;
|
|
89
|
+
if (serialized.isModuleMain) {
|
|
90
|
+
globalThis.registeredModules[serialized.isModuleMain] = serialized;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return `;(${initModule.toString().replaceAll("\n", " ")})(${objWrapped});`;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
declare global {
|
|
98
|
+
var registeredModules: { [id: string]: SerializedModule; } | undefined;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface SerializedModule {
|
|
102
|
+
id: string;
|
|
103
|
+
filename: string;
|
|
104
|
+
|
|
105
|
+
// The main main we represent. Ex, "/ai3/node_modules/typesafecss"
|
|
106
|
+
isModuleMain?: string;
|
|
107
|
+
|
|
108
|
+
// Paths which the require function searches for non-relative imports
|
|
109
|
+
paths: string[];
|
|
110
|
+
|
|
111
|
+
// Fields to be set on the module, when it is created
|
|
112
|
+
moduleFields: { [flag: string]: unknown; };
|
|
113
|
+
|
|
114
|
+
moduleFnc: (exports: any, require: any, module: any, __filename: string, __dirname: string) => unknown;
|
|
115
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { sha256 } from "js-sha256";
|
|
2
|
+
import { bundleRequire, BundleRequireConfig } from "./bundleRequire";
|
|
3
|
+
import { wrapModule } from "./bundleWrapper";
|
|
4
|
+
import { addToInProgressSourceMap, encodeSourceMapLineComment, finalizeInProgressSourceMap, getInProgressSourceMap, InProgressSourceMap, removeSourceMap } from "./sourceMaps";
|
|
5
|
+
import fs from "fs";
|
|
6
|
+
|
|
7
|
+
export async function bundle(config: {
|
|
8
|
+
modules: (typeof require.cache[""])[];
|
|
9
|
+
rootPath: string;
|
|
10
|
+
entryPoints: string[];
|
|
11
|
+
}): Promise<{
|
|
12
|
+
bundle: string;
|
|
13
|
+
}> {
|
|
14
|
+
const { modules, rootPath, entryPoints } = config;
|
|
15
|
+
|
|
16
|
+
// NOTE: We COULD use an "index source map", which contains other sourcemaps
|
|
17
|
+
// and gives offsets for them. However... tooling support will is better
|
|
18
|
+
// for regular sourcemaps, and it's more flexible.
|
|
19
|
+
|
|
20
|
+
let inProgressSourceMap: InProgressSourceMap = {
|
|
21
|
+
sources: [],
|
|
22
|
+
mappings: [],
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
let code = "";
|
|
26
|
+
let curLineCount = 0;
|
|
27
|
+
for (let module of modules) {
|
|
28
|
+
if (!module) continue;
|
|
29
|
+
|
|
30
|
+
let newCode = wrapModule(module);
|
|
31
|
+
|
|
32
|
+
let { sourceMap, code: newCode2 } = removeSourceMap(newCode);
|
|
33
|
+
newCode = newCode2;
|
|
34
|
+
if (sourceMap) {
|
|
35
|
+
let inProgress = getInProgressSourceMap(sourceMap);
|
|
36
|
+
for (let mapping of inProgress.mappings) {
|
|
37
|
+
mapping.generatedLine += curLineCount;
|
|
38
|
+
}
|
|
39
|
+
addToInProgressSourceMap(inProgressSourceMap, inProgress);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
code += newCode + "\n";
|
|
43
|
+
curLineCount += (newCode.match(/\n/g) || []).length + 1;
|
|
44
|
+
}
|
|
45
|
+
code += "\n/* Inlined buffer implementation: */\n";
|
|
46
|
+
code += `\n;\n${fs.readFileSync(__dirname + "/buffer.js").toString()}\n;\n`;
|
|
47
|
+
code += `\n;globalThis.__BUNDLE_HASH__ = ${JSON.stringify(sha256(code))};`;
|
|
48
|
+
let bundleConfig: BundleRequireConfig = {
|
|
49
|
+
rootPath,
|
|
50
|
+
};
|
|
51
|
+
code += `;(${bundleRequire.toString()})(${JSON.stringify(bundleConfig)});`;
|
|
52
|
+
// Delay the initial requires, so our extension can boot and we can debug startup errors
|
|
53
|
+
code += "\n;setTimeout(() => {";
|
|
54
|
+
for (let entryPoint of entryPoints) {
|
|
55
|
+
code += `\n;globalThis.require(${JSON.stringify(entryPoint)});`;
|
|
56
|
+
}
|
|
57
|
+
code += "\n;});";
|
|
58
|
+
code += "\n" + encodeSourceMapLineComment(finalizeInProgressSourceMap(inProgressSourceMap));
|
|
59
|
+
return {
|
|
60
|
+
bundle: code,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
declare global {
|
|
65
|
+
var __BUNDLE_HASH__: string | undefined;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function extractBundleHash(code: string) {
|
|
69
|
+
let match = code.match(/;globalThis.__BUNDLE_HASH__ = "([^"]+)";/);
|
|
70
|
+
if (!match) return undefined;
|
|
71
|
+
return match[1];
|
|
72
|
+
}
|
|
File without changes
|