From 0ee0b67249bdc894421b60a25749d58b8d49f7d4 Mon Sep 17 00:00:00 2001 From: vakrilov Date: Thu, 11 Jul 2019 12:12:45 +0300 Subject: [PATCH 1/3] feat: split globals to support smaller worker chuncks --- tns-core-modules/globals/core/globals-core.ts | 25 +++ tns-core-modules/globals/core/package.json | 5 + tns-core-modules/globals/decorators.ts | 39 ++++ tns-core-modules/globals/globals.ts | 166 ++---------------- .../globals/polyfills/dialogs/dialogs.ts | 6 + .../globals/polyfills/dialogs/package.json | 5 + .../globals/polyfills/fetch/fetch.ts | 8 + .../globals/polyfills/fetch/package.json | 5 + .../polyfills/polyfill-helpers/package.json | 5 + .../polyfill-helpers/polyfill-helpers.ts | 26 +++ .../globals/polyfills/timers/package.json | 5 + .../globals/polyfills/timers/timers.ts | 6 + .../globals/polyfills/xhr/package.json | 5 + tns-core-modules/globals/polyfills/xhr/xhr.ts | 6 + tns-core-modules/xml/xml.js | 1 - 15 files changed, 157 insertions(+), 156 deletions(-) create mode 100644 tns-core-modules/globals/core/globals-core.ts create mode 100644 tns-core-modules/globals/core/package.json create mode 100644 tns-core-modules/globals/decorators.ts create mode 100644 tns-core-modules/globals/polyfills/dialogs/dialogs.ts create mode 100644 tns-core-modules/globals/polyfills/dialogs/package.json create mode 100644 tns-core-modules/globals/polyfills/fetch/fetch.ts create mode 100644 tns-core-modules/globals/polyfills/fetch/package.json create mode 100644 tns-core-modules/globals/polyfills/polyfill-helpers/package.json create mode 100644 tns-core-modules/globals/polyfills/polyfill-helpers/polyfill-helpers.ts create mode 100644 tns-core-modules/globals/polyfills/timers/package.json create mode 100644 tns-core-modules/globals/polyfills/timers/timers.ts create mode 100644 tns-core-modules/globals/polyfills/xhr/package.json create mode 100644 tns-core-modules/globals/polyfills/xhr/xhr.ts diff --git a/tns-core-modules/globals/core/globals-core.ts b/tns-core-modules/globals/core/globals-core.ts new file mode 100644 index 000000000..dfa37d4df --- /dev/null +++ b/tns-core-modules/globals/core/globals-core.ts @@ -0,0 +1,25 @@ +// Required by TypeScript compiler +import "../ts-helpers"; + +import "../register-module-helpers"; + +// This method iterates all the keys in the source exports object and copies them to the destination exports one. +// Note: the method will not check for naming collisions and will override any already existing entries in the destination exports. +global.moduleMerge = function (sourceExports: any, destExports: any) { + for (let key in sourceExports) { + destExports[key] = sourceExports[key]; + } +}; + +global.zonedCallback = function (callback: Function): Function { + if ((global).zone) { + // Zone v0.5.* style callback wrapping + return (global).zone.bind(callback); + } + if ((global).Zone) { + // Zone v0.6.* style callback wrapping + return (global).Zone.current.wrap(callback); + } else { + return callback; + } +}; diff --git a/tns-core-modules/globals/core/package.json b/tns-core-modules/globals/core/package.json new file mode 100644 index 000000000..9661fc1c7 --- /dev/null +++ b/tns-core-modules/globals/core/package.json @@ -0,0 +1,5 @@ +{ + "name" : "core", + "main" : "globals-core", + "nativescript": {} +} diff --git a/tns-core-modules/globals/decorators.ts b/tns-core-modules/globals/decorators.ts new file mode 100644 index 000000000..3ddda051b --- /dev/null +++ b/tns-core-modules/globals/decorators.ts @@ -0,0 +1,39 @@ +export function Deprecated(target: Object, key?: string | symbol, descriptor?: any) { + if (descriptor) { + const originalMethod = descriptor.value; + + descriptor.value = function (...args: any[]) { + console.log(`${key.toString()} is deprecated`); + + return originalMethod.apply(this, args); + }; + + return descriptor; + } else { + console.log(`${(target && (target).name || target)} is deprecated`); + + return target; + } +} + +global.Deprecated = Deprecated; + +export function Experimental(target: Object, key?: string | symbol, descriptor?: any) { + if (descriptor) { + const originalMethod = descriptor.value; + + descriptor.value = function (...args: any[]) { + console.log(`${key.toString()} is experimental`); + + return originalMethod.apply(this, args); + }; + + return descriptor; + } else { + console.log(`${(target && (target).name || target)} is experimental`); + + return target; + } +} + +global.Experimental = Experimental; diff --git a/tns-core-modules/globals/globals.ts b/tns-core-modules/globals/globals.ts index 28fc406cb..5058447c1 100644 --- a/tns-core-modules/globals/globals.ts +++ b/tns-core-modules/globals/globals.ts @@ -1,159 +1,15 @@ -// Required by TypeScript compiler -import "./ts-helpers"; +import "./core"; -import "./register-module-helpers"; +import "./polyfills/timers"; +import "./polyfills/dialogs"; +import "./polyfills/xhr"; +import "./polyfills/fetch"; -// This method iterates all the keys in the source exports object and copies them to the destination exports one. -// Note: the method will not check for naming collisions and will override any already existing entries in the destination exports. -global.moduleMerge = function (sourceExports: any, destExports: any) { - for (let key in sourceExports) { - destExports[key] = sourceExports[key]; - } -}; +import "./decorators"; -import * as timerModule from "../timer"; -import * as dialogsModule from "../ui/dialogs"; - -global.zonedCallback = function (callback: Function): Function { - if ((global).zone) { - // Zone v0.5.* style callback wrapping - return (global).zone.bind(callback); - } - if ((global).Zone) { - // Zone v0.6.* style callback wrapping - return (global).Zone.current.wrap(callback); - } else { - return callback; - } -}; - -global.registerModule("timer", () => require("../timer")); -global.registerModule("ui/dialogs", () => require("../ui/dialogs")); -global.registerModule("xhr", () => require("../xhr")); -global.registerModule("fetch", () => require("../fetch")); - -(global).System = { - import(path) { - return new Promise((resolve, reject) => { - try { - resolve(global.require(path)); - } catch (e) { - reject(e); - } - }); - } -}; - -function registerOnGlobalContext(name: string, module: string): void { - Object.defineProperty(global, name, { - get: function () { - // We do not need to cache require() call since it is already cached in the runtime. - let m = global.loadModule(module); - - // Redefine the property to make sure the above code is executed only once. - let resolvedValue = m[name]; - Object.defineProperty(global, name, { value: resolvedValue, configurable: true, writable: true }); - - return resolvedValue; - }, - configurable: true - }); +// This is probably not needed any more +if ((global).__snapshot || (global).__snapshotEnabled) { + // Object.assign call will fire an error when trying to write to a read-only property of an object, such as 'console' + const consoleModule = require("console").Console; + global.console = global.console || new consoleModule(); } - -let snapshotGlobals; -export function install() { - if ((global).__snapshot || (global).__snapshotEnabled) { - if (!snapshotGlobals) { - // require in snapshot mode is cheap - const timer: typeof timerModule = require("../timer"); - const dialogs: typeof dialogsModule = require("../ui/dialogs"); - const xhr = require("../xhr"); - const fetch = require("../fetch"); - - snapshotGlobals = snapshotGlobals || { - setTimeout: timer.setTimeout, - clearTimeout: timer.clearTimeout, - setInterval: timer.setInterval, - clearInterval: timer.clearInterval, - - alert: dialogs.alert, - confirm: dialogs.confirm, - prompt: dialogs.prompt, - login: dialogs.login, - action: dialogs.action, - - XMLHttpRequest: xhr.XMLHttpRequest, - FormData: xhr.FormData, - - fetch: fetch.fetch, - Headers: fetch.Headers, - Request: fetch.Request, - Response: fetch.Response, - }; - } - const consoleModule = require("../console").Console; - // Object.assign call will fire an error when trying to write to a read-only property of an object, such as 'console' - global.console = global.console || new consoleModule(); - Object.assign(global, snapshotGlobals); - } else { - registerOnGlobalContext("setTimeout", "timer"); - registerOnGlobalContext("clearTimeout", "timer"); - registerOnGlobalContext("setInterval", "timer"); - registerOnGlobalContext("clearInterval", "timer"); - - registerOnGlobalContext("alert", "ui/dialogs"); - registerOnGlobalContext("confirm", "ui/dialogs"); - registerOnGlobalContext("prompt", "ui/dialogs"); - registerOnGlobalContext("login", "ui/dialogs"); - registerOnGlobalContext("action", "ui/dialogs"); - - registerOnGlobalContext("XMLHttpRequest", "xhr"); - registerOnGlobalContext("FormData", "xhr"); - - registerOnGlobalContext("fetch", "fetch"); - registerOnGlobalContext("Headers", "fetch"); - registerOnGlobalContext("Request", "fetch"); - registerOnGlobalContext("Response", "fetch"); - } -} -install(); - -export function Deprecated(target: Object, key?: string | symbol, descriptor?: any) { - if (descriptor) { - const originalMethod = descriptor.value; - - descriptor.value = function (...args: any[]) { - console.log(`${key.toString()} is deprecated`); - - return originalMethod.apply(this, args); - }; - - return descriptor; - } else { - console.log(`${(target && (target).name || target)} is deprecated`); - - return target; - } -} - -global.Deprecated = Deprecated; - -export function Experimental(target: Object, key?: string | symbol, descriptor?: any) { - if (descriptor) { - const originalMethod = descriptor.value; - - descriptor.value = function (...args: any[]) { - console.log(`${key.toString()} is experimental`); - - return originalMethod.apply(this, args); - }; - - return descriptor; - } else { - console.log(`${(target && (target).name || target)} is experimental`); - - return target; - } -} - -global.Experimental = Experimental; diff --git a/tns-core-modules/globals/polyfills/dialogs/dialogs.ts b/tns-core-modules/globals/polyfills/dialogs/dialogs.ts new file mode 100644 index 000000000..c3dab6e54 --- /dev/null +++ b/tns-core-modules/globals/polyfills/dialogs/dialogs.ts @@ -0,0 +1,6 @@ +import "../../core"; +import { installPolyfills } from "../polyfill-helpers"; + +global.registerModule("tns-core-modules/ui/dialogs", () => require("../../../ui/dialogs")); + +installPolyfills("tns-core-modules/ui/dialogs", ["alert", "confirm", "prompt", "login", "action"]); diff --git a/tns-core-modules/globals/polyfills/dialogs/package.json b/tns-core-modules/globals/polyfills/dialogs/package.json new file mode 100644 index 000000000..c06f24f66 --- /dev/null +++ b/tns-core-modules/globals/polyfills/dialogs/package.json @@ -0,0 +1,5 @@ +{ + "name" : "dialogs", + "main" : "dialogs", + "nativescript": {} +} diff --git a/tns-core-modules/globals/polyfills/fetch/fetch.ts b/tns-core-modules/globals/polyfills/fetch/fetch.ts new file mode 100644 index 000000000..db6295ed6 --- /dev/null +++ b/tns-core-modules/globals/polyfills/fetch/fetch.ts @@ -0,0 +1,8 @@ +import "../../core"; +import "../../polyfills/xhr"; + +import { installPolyfills } from "../polyfill-helpers"; + +global.registerModule("fetch", () => require("../../../fetch")); + +installPolyfills("fetch", ["fetch", "Headers", "Request", "Response"]); diff --git a/tns-core-modules/globals/polyfills/fetch/package.json b/tns-core-modules/globals/polyfills/fetch/package.json new file mode 100644 index 000000000..cb112b14d --- /dev/null +++ b/tns-core-modules/globals/polyfills/fetch/package.json @@ -0,0 +1,5 @@ +{ + "name" : "fetch", + "main" : "fetch", + "nativescript": {} +} diff --git a/tns-core-modules/globals/polyfills/polyfill-helpers/package.json b/tns-core-modules/globals/polyfills/polyfill-helpers/package.json new file mode 100644 index 000000000..b2ad20f78 --- /dev/null +++ b/tns-core-modules/globals/polyfills/polyfill-helpers/package.json @@ -0,0 +1,5 @@ +{ + "name" : "polyfill-helpers", + "main" : "polyfill-helpers", + "nativescript": {} +} diff --git a/tns-core-modules/globals/polyfills/polyfill-helpers/polyfill-helpers.ts b/tns-core-modules/globals/polyfills/polyfill-helpers/polyfill-helpers.ts new file mode 100644 index 000000000..371f5bfea --- /dev/null +++ b/tns-core-modules/globals/polyfills/polyfill-helpers/polyfill-helpers.ts @@ -0,0 +1,26 @@ +import "../../core"; + +function registerOnGlobalContext(moduleName: string, exportName: string): void { + Object.defineProperty(global, exportName, { + get: function () { + // We do not need to cache require() call since it is already cached in the runtime. + let m = global.loadModule(moduleName); + + // Redefine the property to make sure the above code is executed only once. + let resolvedValue = m[exportName]; + Object.defineProperty(global, exportName, { value: resolvedValue, configurable: true, writable: true }); + + return resolvedValue; + }, + configurable: true + }); +} + +export function installPolyfills(moduleName: string, exportNames: string[]) { + if ((global).__snapshot || (global).__snapshotEnabled) { + const loadedModule = global.loadModule(moduleName); + exportNames.forEach(exportName => global[exportName] = loadedModule[exportName]); + } else { + exportNames.forEach(exportName => registerOnGlobalContext(moduleName, exportName)); + } +} \ No newline at end of file diff --git a/tns-core-modules/globals/polyfills/timers/package.json b/tns-core-modules/globals/polyfills/timers/package.json new file mode 100644 index 000000000..0d0cbfc66 --- /dev/null +++ b/tns-core-modules/globals/polyfills/timers/package.json @@ -0,0 +1,5 @@ +{ + "name" : "timers", + "main" : "timers", + "nativescript": {} +} diff --git a/tns-core-modules/globals/polyfills/timers/timers.ts b/tns-core-modules/globals/polyfills/timers/timers.ts new file mode 100644 index 000000000..d85fde570 --- /dev/null +++ b/tns-core-modules/globals/polyfills/timers/timers.ts @@ -0,0 +1,6 @@ +import "../../core"; +import { installPolyfills } from "../polyfill-helpers"; + +global.registerModule("timer", () => require("../../../timer")); + +installPolyfills("timer", ["setTimeout", "clearTimeout", "setInterval", "clearInterval"]); diff --git a/tns-core-modules/globals/polyfills/xhr/package.json b/tns-core-modules/globals/polyfills/xhr/package.json new file mode 100644 index 000000000..632c8051b --- /dev/null +++ b/tns-core-modules/globals/polyfills/xhr/package.json @@ -0,0 +1,5 @@ +{ + "name" : "xhr", + "main" : "xhr", + "nativescript": {} +} diff --git a/tns-core-modules/globals/polyfills/xhr/xhr.ts b/tns-core-modules/globals/polyfills/xhr/xhr.ts new file mode 100644 index 000000000..b26133b2a --- /dev/null +++ b/tns-core-modules/globals/polyfills/xhr/xhr.ts @@ -0,0 +1,6 @@ +import "../../core"; +import { installPolyfills } from "../polyfill-helpers"; + +global.registerModule("xhr", () => require("../../../xhr")); + +installPolyfills("xhr", ["XMLHttpRequest", "FormData"]); diff --git a/tns-core-modules/xml/xml.js b/tns-core-modules/xml/xml.js index 43b58ca8e..22f24476f 100644 --- a/tns-core-modules/xml/xml.js +++ b/tns-core-modules/xml/xml.js @@ -115,7 +115,6 @@ function _HandleAmpEntities(found, decimalValue, hexValue, wordValue) { } return String.fromCharCode(parseInt(hexValue, 16)); } -; var XmlParser = (function () { function XmlParser(onEvent, onError, processNamespaces) { this._processNamespaces = processNamespaces; From 9b7c7c0d20d2ef3bf6a1ea8b2a32b99cf99fe6b4 Mon Sep 17 00:00:00 2001 From: vakrilov Date: Thu, 11 Jul 2019 12:43:09 +0300 Subject: [PATCH 2/3] chore: remove unneeded console registration --- tns-core-modules/globals/globals.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tns-core-modules/globals/globals.ts b/tns-core-modules/globals/globals.ts index 5058447c1..e88a68496 100644 --- a/tns-core-modules/globals/globals.ts +++ b/tns-core-modules/globals/globals.ts @@ -6,10 +6,3 @@ import "./polyfills/xhr"; import "./polyfills/fetch"; import "./decorators"; - -// This is probably not needed any more -if ((global).__snapshot || (global).__snapshotEnabled) { - // Object.assign call will fire an error when trying to write to a read-only property of an object, such as 'console' - const consoleModule = require("console").Console; - global.console = global.console || new consoleModule(); -} From fed360d7634d3ec96a6a5bd6b3b764b83815ceb6 Mon Sep 17 00:00:00 2001 From: vakrilov Date: Fri, 2 Aug 2019 11:34:24 +0300 Subject: [PATCH 3/3] refactor: add __snapshot in d.ts and fix checks --- tns-core-modules/application/application-common.ts | 3 +-- .../globals/polyfills/polyfill-helpers/polyfill-helpers.ts | 2 +- tns-core-modules/module.d.ts | 1 + tns-core-modules/ui/frame/activity.android.ts | 2 +- tns-core-modules/xml/xml.js | 6 +++--- tns-core-modules/xml/xml.ts | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tns-core-modules/application/application-common.ts b/tns-core-modules/application/application-common.ts index 0ca6c76a1..c6bda6fe4 100644 --- a/tns-core-modules/application/application-common.ts +++ b/tns-core-modules/application/application-common.ts @@ -1,6 +1,5 @@ // Require globals first so that snapshot takes __extends function. -require("../globals"); - +import "../globals"; import { Observable, EventData } from "../data/observable"; import { View } from "../ui/core/view"; import { diff --git a/tns-core-modules/globals/polyfills/polyfill-helpers/polyfill-helpers.ts b/tns-core-modules/globals/polyfills/polyfill-helpers/polyfill-helpers.ts index 371f5bfea..e5ecd55a7 100644 --- a/tns-core-modules/globals/polyfills/polyfill-helpers/polyfill-helpers.ts +++ b/tns-core-modules/globals/polyfills/polyfill-helpers/polyfill-helpers.ts @@ -17,7 +17,7 @@ function registerOnGlobalContext(moduleName: string, exportName: string): void { } export function installPolyfills(moduleName: string, exportNames: string[]) { - if ((global).__snapshot || (global).__snapshotEnabled) { + if (global.__snapshot) { const loadedModule = global.loadModule(moduleName); exportNames.forEach(exportName => global[exportName] = loadedModule[exportName]); } else { diff --git a/tns-core-modules/module.d.ts b/tns-core-modules/module.d.ts index 748487b6b..90d58cbf1 100644 --- a/tns-core-modules/module.d.ts +++ b/tns-core-modules/module.d.ts @@ -82,6 +82,7 @@ declare namespace NodeJS { __onUncaughtError: (error: NativeScriptError) => void; __onDiscardedError: (error: NativeScriptError) => void; TNS_WEBPACK?: boolean; + __snapshot?: boolean; __requireOverride?: (name: string, dir: string) => any; } } diff --git a/tns-core-modules/ui/frame/activity.android.ts b/tns-core-modules/ui/frame/activity.android.ts index 28fdca7b5..8bfadbc56 100644 --- a/tns-core-modules/ui/frame/activity.android.ts +++ b/tns-core-modules/ui/frame/activity.android.ts @@ -2,7 +2,7 @@ import { setActivityCallbacks, AndroidActivityCallbacks } from "./frame"; import * as globals from "../../globals"; import * as appModule from "../../application"; -if ((global).__snapshot || (global).__snapshotEnabled) { +if (global.__snapshot) { globals.install(); } diff --git a/tns-core-modules/xml/xml.js b/tns-core-modules/xml/xml.js index 22f24476f..06bbf33dc 100644 --- a/tns-core-modules/xml/xml.js +++ b/tns-core-modules/xml/xml.js @@ -106,14 +106,14 @@ function _HandleAmpEntities(found, decimalValue, hexValue, wordValue) { } var res = _ampCodes.get(wordValue); if (res) { - return String.fromCharCode(res); + return String.fromCodePoint(res); } return found; } if (decimalValue) { - return String.fromCharCode(parseInt(decimalValue, 10)); + return String.fromCodePoint(parseInt(decimalValue, 10)); } - return String.fromCharCode(parseInt(hexValue, 16)); + return String.fromCodePoint(parseInt(hexValue, 16)); } var XmlParser = (function () { function XmlParser(onEvent, onError, processNamespaces) { diff --git a/tns-core-modules/xml/xml.ts b/tns-core-modules/xml/xml.ts index cc11f454f..ef4d93e9e 100644 --- a/tns-core-modules/xml/xml.ts +++ b/tns-core-modules/xml/xml.ts @@ -88,7 +88,7 @@ function _generateAmpMap(): any { } // android-specific implementation, which pre-populates the map to get it saved into the heap blob -if ((global).__snapshot) { +if (global.__snapshot) { _ampCodes = _generateAmpMap(); }