Introduce bun:sql

This commit is contained in:
Jarred Sumner
2023-10-09 01:11:24 -07:00
parent 3809d8f5a0
commit 71ddfcf7c1
14 changed files with 1942 additions and 1490 deletions

View File

@@ -36,6 +36,7 @@ static constexpr ASCIILiteral builtinModuleNamesSortedLength[] = {
"cluster"_s,
"console"_s,
"process"_s,
"bun:sql"_s,
"bun:wrap"_s,
"punycode"_s,
"bun:test"_s,
@@ -83,16 +84,17 @@ static constexpr ASCIILiteral builtinModuleNamesSortedLength[] = {
namespace Bun {
bool isBuiltinModule(const String &namePossiblyWithNodePrefix) {
String name = namePossiblyWithNodePrefix;
if (name.startsWith("node:"_s))
name = name.substringSharingImpl(5);
bool isBuiltinModule(const String& namePossiblyWithNodePrefix)
{
String name = namePossiblyWithNodePrefix;
if (name.startsWith("node:"_s))
name = name.substringSharingImpl(5);
for (auto &builtinModule : builtinModuleNamesSortedLength) {
if (name == builtinModule)
return true;
}
return false;
for (auto& builtinModule : builtinModuleNamesSortedLength) {
if (name == builtinModule)
return true;
}
return false;
}
} // namespace Bun

View File

@@ -2050,6 +2050,7 @@ pub const ModuleLoader = struct {
// These are defined in src/js/*
.@"bun:ffi" => return jsSyntheticModule(.@"bun:ffi", specifier),
.@"bun:sql" => return jsSyntheticModule(.@"bun:sql", specifier),
.@"bun:sqlite" => return jsSyntheticModule(.@"bun:sqlite", specifier),
.@"detect-libc" => return jsSyntheticModule(if (Environment.isLinux) .@"detect-libc/linux" else .@"detect-libc", specifier),
.@"node:assert" => return jsSyntheticModule(.@"node:assert", specifier),
@@ -2222,6 +2223,7 @@ pub const HardcodedModule = enum {
@"bun:ffi",
@"bun:jsc",
@"bun:main",
@"bun:sql",
@"bun:sqlite",
@"detect-libc",
@"node:assert",
@@ -2295,7 +2297,9 @@ pub const HardcodedModule = enum {
.{ "bun:ffi", HardcodedModule.@"bun:ffi" },
.{ "bun:jsc", HardcodedModule.@"bun:jsc" },
.{ "bun:main", HardcodedModule.@"bun:main" },
.{ "bun:sql", HardcodedModule.@"bun:sql" },
.{ "bun:sqlite", HardcodedModule.@"bun:sqlite" },
.{ "detect-libc", HardcodedModule.@"detect-libc" },
.{ "node-fetch", HardcodedModule.@"node-fetch" },
.{ "isomorphic-fetch", HardcodedModule.@"isomorphic-fetch" },
@@ -2506,6 +2510,7 @@ pub const HardcodedModule = enum {
.{ "bun:ffi", .{ .path = "bun:ffi" } },
.{ "bun:jsc", .{ .path = "bun:jsc" } },
.{ "bun:sqlite", .{ .path = "bun:sqlite" } },
.{ "bun:sql", .{ .path = "bun:sql" } },
.{ "bun:wrap", .{ .path = "bun:wrap" } },
.{ "ffi", .{ .path = "bun:ffi" } },

View File

@@ -34,6 +34,7 @@ static constexpr ASCIILiteral builtinModuleNames[] = {
"bun"_s,
"bun:ffi"_s,
"bun:jsc"_s,
"bun:sql"_s,
"bun:sqlite"_s,
"bun:wrap"_s,
"child_process"_s,

322
src/js/bun/sql.ts Normal file
View File

@@ -0,0 +1,322 @@
const queryStatus_active = 1 << 1;
const queryStatus_cancelled = 1 << 2;
const queryStatus_error = 1 << 3;
const queryStatus_executed = 1 << 4;
const rawMode_values = 1;
const rawMode_objects = 2;
const _resolve = Symbol("resolve");
const _reject = Symbol("reject");
const _handle = Symbol("handle");
const _run = Symbol("run");
const _queryStatus = Symbol("status");
const _handler = Symbol("handler");
const PublicPromise = Promise;
const { PostgresSQLConnection, PostgresSQLQuery, PostgresSQLStatement, init } = $lazy("bun:sql");
const { escapeString, escapeIdentifier } = PostgresSQLConnection;
class Query extends PublicPromise {
[_resolve];
[_reject];
[_handle];
[_handler];
[_queryStatus] = 0;
constructor(handle, handler) {
var resolve_, reject_;
super((resolve, reject) => {
resolve_ = resolve;
reject_ = reject;
});
this[_resolve] = resolve_;
this[_reject] = reject_;
this[_handle] = handle;
this[_handler] = handler;
this[_queryStatus] = handle ? 0 : queryStatus_cancelled;
}
async [_run]() {
const { [_handle]: handle, [_handler]: handler, [_queryStatus]: status } = this;
if (status & (queryStatus_executed | queryStatus_cancelled)) {
return;
}
this[_queryStatus] |= queryStatus_executed;
await 1;
return handler(this, handle);
}
get active() {
return (this[_queryStatus] & queryStatus_active) !== 0;
}
set active(value) {
const status = this[_queryStatus];
if (status & (queryStatus_cancelled | queryStatus_error)) {
return;
}
if (value) {
this[_queryStatus] |= queryStatus_active;
} else {
this[_queryStatus] &= ~queryStatus_active;
}
}
get cancelled() {
return (this[_queryStatus] & queryStatus_cancelled) !== 0;
}
resolve(x) {
this[_queryStatus] &= ~queryStatus_active;
return this[_resolve](x);
}
reject(x) {
this[_queryStatus] &= ~queryStatus_active;
this[_queryStatus] |= queryStatus_error;
return this[_resolve](x);
}
cancel() {
var status = this[_queryStatus];
if (status & queryStatus_cancelled) {
return this;
}
this[_queryStatus] |= queryStatus_cancelled;
if (status & queryStatus_executed) {
this[_handle].cancel();
}
return this;
}
execute() {
this[_run]();
return this;
}
raw() {
this[_handle].raw = rawMode_objects;
return this;
}
values() {
this[_handle].raw = rawMode_values;
return this;
}
then() {
this[_run]();
return super.then(...arguments);
}
catch() {
this[_run]();
return super.catch(...arguments);
}
finally() {
this[_run]();
return super.finally(...arguments);
}
}
Object.defineProperty(Query.prototype, Symbol.species, { value: PublicPromise });
Object.defineProperty(Query.prototype, Symbol.toStringTag, { value: "Query" });
init(Query.prototype.resolve, Query.prototype.reject);
function createConnection({ hostname, port, username, password, tls, query }, onConnected, onClose) {
return new PostgresSQLConnection(hostname, port, username, password, tls, query, onConnected, onClose);
}
function normalizeStrings(strings) {
if ($isJSArray(strings)) {
return strings.join("?");
}
return strings + "";
}
function loadOptions(o) {
var hostname, port, username, password, database, tls, url, query, adapter;
const env = Bun.env;
if (typeof o === "undefined" || (typeof o === "string" && o?.length === 0)) {
const urlString = env.POSTGRES_URL || env.DATABASE_URL || env.PGURL || env.PG_URL;
if (urlString) {
o = urlString;
}
}
if (typeof o === "string") {
url = new URL(o);
({ hostname, port, username, password, protocol: adapter } = o = url);
if (adapter[adapter.length - 1] === ":") {
adapter = adapter.slice(0, -1);
}
const queryObject = url.searchParams.toJSON();
query = "";
for (const key in queryObject) {
query += `${encodeURIComponent(key)}=${encodeURIComponent(queryObject[key])} `;
}
query = query.trim();
}
if (!o) {
o = {};
}
hostname ||= o.hostname || o.host || env.PGHOST || "localhost";
port ||= Number(o.port || env.PGPORT || 5432);
username ||= o.username || o.user || env.PGUSERNAME || env.PGUSER || env.USER || env.USERNAME || "postgres";
database ||= o.database || o.db || (url?.pathname ?? "").slice(1) || env.PGDATABASE || username;
password ||= o.password || o.pass || env.PGPASSWORD || "";
tls ||= o.tls || o.ssl;
adapter ||= o.adapter || "postgres";
if (!Number.isSafeInteger(port) || port < 1 || port > 65535) {
throw new Error(`Invalid port: ${port}`);
}
if (adapter && !(adapter === "postgres" || adapter === "postgresql")) {
throw new Error(`Unsupported adapter: ${adapter}. Only \"postgres\" is supported for now`);
}
return { hostname, port, username, password, database, tls, query };
}
function SQL(o) {
var connection,
connected = false,
connecting = false,
closed = false,
onConnect: any[] = [],
connectionInfo = loadOptions(o);
function connectedHandler(query, handle, err) {
if (err) {
return query.reject(err);
}
if (!connected) {
return query.reject(new Error("Not connected"));
}
if (query.cancelled) {
return query.reject(new Error("Query cancelled"));
}
handle.run(connection, query);
}
function pendingConnectionHandler(query, handle) {
onConnect.push(err => connectedHandler(query, handle, err));
if (!connecting) {
connecting = true;
connection = createConnection(connectionInfo, onConnected, onClose);
}
}
function closedConnectionHandler(query, handle) {
query.reject(new Error("Connection closed"));
}
function onConnected(err) {
connected = !err;
for (const handler of onConnect) {
handler(err);
}
onConnect = [];
}
function onClose(err) {
closed = true;
onConnected(err);
}
function connectedSQL(strings, values) {
return new Query(connection.query(normalizeStrings(strings), values), closedConnectionHandler);
}
function closedSQL(strings, values) {
return new Query(undefined, closedConnectionHandler);
}
function pendingSQL(strings, values) {
return new Query(new PostgresSQLQuery(normalizeStrings(strings), values), pendingConnectionHandler);
}
function sql(strings, ...values) {
if (closed) {
return closedSQL(strings, values);
}
if (connected) {
return connectedSQL(strings, values);
}
return pendingSQL(strings, values);
}
sql.connect = () => {
if (closed) {
return Promise.reject(new Error("Connection closed"));
}
if (connected) {
return Promise.resolve(sql);
}
var { resolve, reject, promise } = Promise.withResolvers();
onConnect.push(err => (err ? reject(err) : resolve(sql)));
if (!connecting) {
connecting = true;
connection = createConnection(connectionInfo, onConnected, onClose);
}
return promise;
};
sql.close = () => {
if (closed) {
return Promise.resolve();
}
var { resolve, promise } = Promise.withResolvers();
onConnect.push(resolve);
connection.close();
return promise;
};
sql.flush = () => {
if (closed || !connected) {
return;
}
connection.flush();
};
return sql;
}
var lazyDefaultSQL;
var defaultSQLObject = function sql(strings, ...values) {
if (!lazyDefaultSQL) {
lazyDefaultSQL = SQL(undefined);
Object.assign(defaultSQLObject, lazyDefaultSQL);
exportsObject.default = exportsObject.sql = lazyDefaultSQL;
}
return lazyDefaultSQL(strings, ...values);
};
var exportsObject = {
sql: defaultSQLObject,
default: defaultSQLObject,
SQL,
Query,
};
export default exportsObject;

View File

@@ -6,6 +6,9 @@ JSValue InternalModuleRegistry::createInternalModuleById(JSGlobalObject* globalO
case Field::BunFFI: {
INTERNAL_MODULE_REGISTRY_GENERATE(globalObject, vm, "bun:ffi"_s, "bun/ffi.js"_s, InternalModuleRegistryConstants::BunFFICode, "builtin://bun/ffi"_s);
}
case Field::BunSql: {
INTERNAL_MODULE_REGISTRY_GENERATE(globalObject, vm, "bun:sql"_s, "bun/sql.js"_s, InternalModuleRegistryConstants::BunSqlCode, "builtin://bun/sql"_s);
}
case Field::BunSqlite: {
INTERNAL_MODULE_REGISTRY_GENERATE(globalObject, vm, "bun:sqlite"_s, "bun/sqlite.js"_s, InternalModuleRegistryConstants::BunSqliteCode, "builtin://bun/sqlite"_s);
}

View File

@@ -1,63 +1,64 @@
BunFFI = 0,
BunSqlite = 1,
InternalDebugger = 2,
InternalFSCpSync = 3,
InternalFSCp = 4,
InternalPrimordials = 5,
InternalShared = 6,
InternalUtilInspect = 7,
NodeAssert = 8,
NodeAssertStrict = 9,
NodeAsyncHooks = 10,
NodeChildProcess = 11,
NodeCluster = 12,
NodeConsole = 13,
NodeCrypto = 14,
NodeDgram = 15,
NodeDiagnosticsChannel = 16,
NodeDNS = 17,
NodeDNSPromises = 18,
NodeDomain = 19,
NodeEvents = 20,
NodeFS = 21,
NodeFSPromises = 22,
NodeHttp = 23,
NodeHttp2 = 24,
NodeHttps = 25,
NodeInspector = 26,
NodeNet = 27,
NodeOS = 28,
NodePathPosix = 29,
NodePath = 30,
NodePathWin32 = 31,
NodePerfHooks = 32,
NodePunycode = 33,
NodeQuerystring = 34,
NodeReadline = 35,
NodeReadlinePromises = 36,
NodeRepl = 37,
NodeStreamConsumers = 38,
NodeStream = 39,
NodeStreamPromises = 40,
NodeStreamWeb = 41,
NodeTimers = 42,
NodeTimersPromises = 43,
NodeTLS = 44,
NodeTraceEvents = 45,
NodeTty = 46,
NodeUrl = 47,
NodeUtil = 48,
NodeV8 = 49,
NodeVM = 50,
NodeWasi = 51,
NodeWorkerThreads = 52,
NodeZlib = 53,
ThirdpartyDepd = 54,
ThirdpartyDetectLibc = 55,
ThirdpartyDetectLibcLinux = 56,
ThirdpartyIsomorphicFetch = 57,
ThirdpartyNodeFetch = 58,
ThirdpartyUndici = 59,
ThirdpartyVercelFetch = 60,
ThirdpartyWS = 61,
BunSql = 1,
BunSqlite = 2,
InternalDebugger = 3,
InternalFSCpSync = 4,
InternalFSCp = 5,
InternalPrimordials = 6,
InternalShared = 7,
InternalUtilInspect = 8,
NodeAssert = 9,
NodeAssertStrict = 10,
NodeAsyncHooks = 11,
NodeChildProcess = 12,
NodeCluster = 13,
NodeConsole = 14,
NodeCrypto = 15,
NodeDgram = 16,
NodeDiagnosticsChannel = 17,
NodeDNS = 18,
NodeDNSPromises = 19,
NodeDomain = 20,
NodeEvents = 21,
NodeFS = 22,
NodeFSPromises = 23,
NodeHttp = 24,
NodeHttp2 = 25,
NodeHttps = 26,
NodeInspector = 27,
NodeNet = 28,
NodeOS = 29,
NodePathPosix = 30,
NodePath = 31,
NodePathWin32 = 32,
NodePerfHooks = 33,
NodePunycode = 34,
NodeQuerystring = 35,
NodeReadline = 36,
NodeReadlinePromises = 37,
NodeRepl = 38,
NodeStreamConsumers = 39,
NodeStream = 40,
NodeStreamPromises = 41,
NodeStreamWeb = 42,
NodeTimers = 43,
NodeTimersPromises = 44,
NodeTLS = 45,
NodeTraceEvents = 46,
NodeTty = 47,
NodeUrl = 48,
NodeUtil = 49,
NodeV8 = 50,
NodeVM = 51,
NodeWasi = 52,
NodeWorkerThreads = 53,
NodeZlib = 54,
ThirdpartyDepd = 55,
ThirdpartyDetectLibc = 56,
ThirdpartyDetectLibcLinux = 57,
ThirdpartyIsomorphicFetch = 58,
ThirdpartyNodeFetch = 59,
ThirdpartyUndici = 60,
ThirdpartyVercelFetch = 61,
ThirdpartyWS = 62,

View File

@@ -1 +1 @@
#define BUN_INTERNAL_MODULE_COUNT 62
#define BUN_INTERNAL_MODULE_COUNT 63

File diff suppressed because one or more lines are too long

View File

@@ -12,67 +12,68 @@ pub const ResolvedSourceTag = enum(u32) {
// Built in modules are loaded through InternalModuleRegistry by numerical ID.
// In this enum are represented as `(1 << 9) & id`
@"bun:ffi" = 512,
@"bun:sqlite" = 513,
@"internal:debugger" = 514,
@"internal:fs/cp-sync" = 515,
@"internal:fs/cp" = 516,
@"internal:primordials" = 517,
@"internal:shared" = 518,
@"internal:util/inspect" = 519,
@"node:assert" = 520,
@"node:assert/strict" = 521,
@"node:async_hooks" = 522,
@"node:child_process" = 523,
@"node:cluster" = 524,
@"node:console" = 525,
@"node:crypto" = 526,
@"node:dgram" = 527,
@"node:diagnostics_channel" = 528,
@"node:dns" = 529,
@"node:dns/promises" = 530,
@"node:domain" = 531,
@"node:events" = 532,
@"node:fs" = 533,
@"node:fs/promises" = 534,
@"node:http" = 535,
@"node:http2" = 536,
@"node:https" = 537,
@"node:inspector" = 538,
@"node:net" = 539,
@"node:os" = 540,
@"node:path/posix" = 541,
@"node:path" = 542,
@"node:path/win32" = 543,
@"node:perf_hooks" = 544,
@"node:punycode" = 545,
@"node:querystring" = 546,
@"node:readline" = 547,
@"node:readline/promises" = 548,
@"node:repl" = 549,
@"node:stream/consumers" = 550,
@"node:stream" = 551,
@"node:stream/promises" = 552,
@"node:stream/web" = 553,
@"node:timers" = 554,
@"node:timers/promises" = 555,
@"node:tls" = 556,
@"node:trace_events" = 557,
@"node:tty" = 558,
@"node:url" = 559,
@"node:util" = 560,
@"node:v8" = 561,
@"node:vm" = 562,
@"node:wasi" = 563,
@"node:worker_threads" = 564,
@"node:zlib" = 565,
@"depd" = 566,
@"detect-libc" = 567,
@"detect-libc/linux" = 568,
@"isomorphic-fetch" = 569,
@"node-fetch" = 570,
@"undici" = 571,
@"vercel_fetch" = 572,
@"ws" = 573,
@"bun:sql" = 513,
@"bun:sqlite" = 514,
@"internal:debugger" = 515,
@"internal:fs/cp-sync" = 516,
@"internal:fs/cp" = 517,
@"internal:primordials" = 518,
@"internal:shared" = 519,
@"internal:util/inspect" = 520,
@"node:assert" = 521,
@"node:assert/strict" = 522,
@"node:async_hooks" = 523,
@"node:child_process" = 524,
@"node:cluster" = 525,
@"node:console" = 526,
@"node:crypto" = 527,
@"node:dgram" = 528,
@"node:diagnostics_channel" = 529,
@"node:dns" = 530,
@"node:dns/promises" = 531,
@"node:domain" = 532,
@"node:events" = 533,
@"node:fs" = 534,
@"node:fs/promises" = 535,
@"node:http" = 536,
@"node:http2" = 537,
@"node:https" = 538,
@"node:inspector" = 539,
@"node:net" = 540,
@"node:os" = 541,
@"node:path/posix" = 542,
@"node:path" = 543,
@"node:path/win32" = 544,
@"node:perf_hooks" = 545,
@"node:punycode" = 546,
@"node:querystring" = 547,
@"node:readline" = 548,
@"node:readline/promises" = 549,
@"node:repl" = 550,
@"node:stream/consumers" = 551,
@"node:stream" = 552,
@"node:stream/promises" = 553,
@"node:stream/web" = 554,
@"node:timers" = 555,
@"node:timers/promises" = 556,
@"node:tls" = 557,
@"node:trace_events" = 558,
@"node:tty" = 559,
@"node:url" = 560,
@"node:util" = 561,
@"node:v8" = 562,
@"node:vm" = 563,
@"node:wasi" = 564,
@"node:worker_threads" = 565,
@"node:zlib" = 566,
@"depd" = 567,
@"detect-libc" = 568,
@"detect-libc/linux" = 569,
@"isomorphic-fetch" = 570,
@"node-fetch" = 571,
@"undici" = 572,
@"vercel_fetch" = 573,
@"ws" = 574,
// Native modules run through a different system using ESM registry.
@"bun" = 1024,
@"bun:jsc" = 1025,

View File

@@ -11,67 +11,68 @@ enum SyntheticModuleType : uint32_t {
// In this enum are represented as `(1 << 9) & id`
InternalModuleRegistryFlag = 1 << 9,
BunFFI = 512,
BunSqlite = 513,
InternalDebugger = 514,
InternalFSCpSync = 515,
InternalFSCp = 516,
InternalPrimordials = 517,
InternalShared = 518,
InternalUtilInspect = 519,
NodeAssert = 520,
NodeAssertStrict = 521,
NodeAsyncHooks = 522,
NodeChildProcess = 523,
NodeCluster = 524,
NodeConsole = 525,
NodeCrypto = 526,
NodeDgram = 527,
NodeDiagnosticsChannel = 528,
NodeDNS = 529,
NodeDNSPromises = 530,
NodeDomain = 531,
NodeEvents = 532,
NodeFS = 533,
NodeFSPromises = 534,
NodeHttp = 535,
NodeHttp2 = 536,
NodeHttps = 537,
NodeInspector = 538,
NodeNet = 539,
NodeOS = 540,
NodePathPosix = 541,
NodePath = 542,
NodePathWin32 = 543,
NodePerfHooks = 544,
NodePunycode = 545,
NodeQuerystring = 546,
NodeReadline = 547,
NodeReadlinePromises = 548,
NodeRepl = 549,
NodeStreamConsumers = 550,
NodeStream = 551,
NodeStreamPromises = 552,
NodeStreamWeb = 553,
NodeTimers = 554,
NodeTimersPromises = 555,
NodeTLS = 556,
NodeTraceEvents = 557,
NodeTty = 558,
NodeUrl = 559,
NodeUtil = 560,
NodeV8 = 561,
NodeVM = 562,
NodeWasi = 563,
NodeWorkerThreads = 564,
NodeZlib = 565,
ThirdpartyDepd = 566,
ThirdpartyDetectLibc = 567,
ThirdpartyDetectLibcLinux = 568,
ThirdpartyIsomorphicFetch = 569,
ThirdpartyNodeFetch = 570,
ThirdpartyUndici = 571,
ThirdpartyVercelFetch = 572,
ThirdpartyWS = 573,
BunSql = 513,
BunSqlite = 514,
InternalDebugger = 515,
InternalFSCpSync = 516,
InternalFSCp = 517,
InternalPrimordials = 518,
InternalShared = 519,
InternalUtilInspect = 520,
NodeAssert = 521,
NodeAssertStrict = 522,
NodeAsyncHooks = 523,
NodeChildProcess = 524,
NodeCluster = 525,
NodeConsole = 526,
NodeCrypto = 527,
NodeDgram = 528,
NodeDiagnosticsChannel = 529,
NodeDNS = 530,
NodeDNSPromises = 531,
NodeDomain = 532,
NodeEvents = 533,
NodeFS = 534,
NodeFSPromises = 535,
NodeHttp = 536,
NodeHttp2 = 537,
NodeHttps = 538,
NodeInspector = 539,
NodeNet = 540,
NodeOS = 541,
NodePathPosix = 542,
NodePath = 543,
NodePathWin32 = 544,
NodePerfHooks = 545,
NodePunycode = 546,
NodeQuerystring = 547,
NodeReadline = 548,
NodeReadlinePromises = 549,
NodeRepl = 550,
NodeStreamConsumers = 551,
NodeStream = 552,
NodeStreamPromises = 553,
NodeStreamWeb = 554,
NodeTimers = 555,
NodeTimersPromises = 556,
NodeTLS = 557,
NodeTraceEvents = 558,
NodeTty = 559,
NodeUrl = 560,
NodeUtil = 561,
NodeV8 = 562,
NodeVM = 563,
NodeWasi = 564,
NodeWorkerThreads = 565,
NodeZlib = 566,
ThirdpartyDepd = 567,
ThirdpartyDetectLibc = 568,
ThirdpartyDetectLibcLinux = 569,
ThirdpartyIsomorphicFetch = 570,
ThirdpartyNodeFetch = 571,
ThirdpartyUndici = 572,
ThirdpartyVercelFetch = 573,
ThirdpartyWS = 574,
// Native modules run through the same system, but with different underlying initializers.
// They also have bit 10 set to differentiate them from JS builtins.

File diff suppressed because one or more lines are too long

1
src/js/private.d.ts vendored
View File

@@ -172,6 +172,7 @@ interface BunLazyModules {
ReadableState: Function;
};
sqlite: any;
"bun:sql": any;
"vm": {
createContext: Function;
isContext: Function;

File diff suppressed because it is too large Load Diff