Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Consumption of eager shared modules #18062

Merged
merged 2 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 19 additions & 14 deletions lib/sharing/ConsumeSharedModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,26 +207,31 @@ class ConsumeSharedModule extends Module {
});
}
}
let fn = "load";
const args = [JSON.stringify(shareScope), JSON.stringify(shareKey)];

const args = [
JSON.stringify(shareScope),
JSON.stringify(shareKey),
JSON.stringify(eager)
];
if (requiredVersion) {
if (strictVersion) {
fn += "Strict";
}
if (singleton) {
fn += "Singleton";
}
args.push(stringifyHoley(requiredVersion));
fn += "VersionCheck";
} else {
if (singleton) {
fn += "Singleton";
}
}
if (fallbackCode) {
fn += "Fallback";
args.push(fallbackCode);
}

let fn;

if (requiredVersion) {
if (strictVersion) {
fn = singleton ? "loadStrictSingletonVersion" : "loadStrictVersion";
} else {
fn = singleton ? "loadSingletonVersion" : "loadVersion";
}
} else {
fn = singleton ? "loadSingleton" : "load";
}

const code = runtimeTemplate.returningFunction(`${fn}(${args.join(", ")})`);
const sources = new Map();
sources.set("consume-shared", new RawSource(code));
Expand Down
241 changes: 104 additions & 137 deletions lib/sharing/ConsumeSharedRuntimeModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,63 +95,39 @@ class ConsumeSharedRuntimeModule extends RuntimeModule {
versionLtRuntimeCode(runtimeTemplate),
rangeToStringRuntimeCode(runtimeTemplate),
satisfyRuntimeCode(runtimeTemplate),
`var ensureExistence = ${runtimeTemplate.basicFunction("scopeName, key", [
`var scope = ${RuntimeGlobals.shareScopeMap}[scopeName];`,
`if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) throw new Error("Shared module " + key + " doesn't exist in shared scope " + scopeName);`,
"return scope;"
`var exists = ${runtimeTemplate.basicFunction("scope, key", [
`return scope && ${RuntimeGlobals.hasOwnProperty}(scope, key);`
])}`,
`var get = ${runtimeTemplate.basicFunction("entry", [
"entry.loaded = 1;",
"return entry.get()"
])};`,
`var findVersion = ${runtimeTemplate.basicFunction("scope, key", [
"var versions = scope[key];",
`var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
"a, b",
["return !a || versionLt(a, b) ? b : a;"]
)}, 0);`,
"return key && versions[key]"
`var eagerOnly = ${runtimeTemplate.basicFunction("versions", [
`return Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
"filtered, version",
Template.indent([
"if (versions[version].eager) {",
Template.indent(["filtered[version] = versions[version];"]),
"}",
"return filtered;"
])
)}, {});`
])};`,
`var findSingletonVersionKey = ${runtimeTemplate.basicFunction(
"scope, key",
`var findLatestVersion = ${runtimeTemplate.basicFunction(
"scope, key, eager",
[
"var versions = scope[key];",
`return Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
"var versions = eager ? eagerOnly(scope[key]) : scope[key];",
`var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
"a, b",
["return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a;"]
)}, 0);`
]
)};`,
`var getInvalidSingletonVersionMessage = ${runtimeTemplate.basicFunction(
"scope, key, version, requiredVersion",
[
`return "Unsatisfied version " + version + " from " + (version && scope[key][version].from) + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")"`
]
)};`,
`var getSingleton = ${runtimeTemplate.basicFunction(
"scope, scopeName, key, requiredVersion",
[
"var version = findSingletonVersionKey(scope, key);",
"return get(scope[key][version]);"
]
)};`,
`var getSingletonVersion = ${runtimeTemplate.basicFunction(
"scope, scopeName, key, requiredVersion",
[
"var version = findSingletonVersionKey(scope, key);",
"if (!satisfy(requiredVersion, version)) warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));",
"return get(scope[key][version]);"
]
)};`,
`var getStrictSingletonVersion = ${runtimeTemplate.basicFunction(
"scope, scopeName, key, requiredVersion",
[
"var version = findSingletonVersionKey(scope, key);",
"if (!satisfy(requiredVersion, version)) " +
"throw new Error(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));",
"return get(scope[key][version]);"
["return !a || versionLt(a, b) ? b : a;"]
)}, 0);`,
"return key && versions[key];"
]
)};`,
`var findValidVersion = ${runtimeTemplate.basicFunction(
"scope, key, requiredVersion",
`var findSatisfyingVersion = ${runtimeTemplate.basicFunction(
"scope, key, requiredVersion, eager",
[
"var versions = scope[key];",
"var versions = eager ? eagerOnly(scope[key]) : scope[key];",
`var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
"a, b",
[
Expand All @@ -162,136 +138,127 @@ class ConsumeSharedRuntimeModule extends RuntimeModule {
"return key && versions[key]"
]
)};`,
`var findSingletonVersionKey = ${runtimeTemplate.basicFunction(
"scope, key, eager",
[
"var versions = eager ? eagerOnly(scope[key]) : scope[key];",
`return Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
"a, b",
["return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a;"]
)}, 0);`
]
)};`,
`var getInvalidSingletonVersionMessage = ${runtimeTemplate.basicFunction(
"scope, key, version, requiredVersion",
[
'return "Unsatisfied version " + version + " from " + (version && scope[key][version].from) + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")"'
]
)};`,
`var getInvalidVersionMessage = ${runtimeTemplate.basicFunction(
"scope, scopeName, key, requiredVersion",
"scope, scopeName, key, requiredVersion, eager",
[
"var versions = scope[key];",
'return "No satisfying version (" + rangeToString(requiredVersion) + ") of shared module " + key + " found in shared scope " + scopeName + ".\\n" +',
'return "No satisfying version (" + rangeToString(requiredVersion) + ")" + (eager ? " for eager consumption" : "") + " of shared module " + key + " found in shared scope " + scopeName + ".\\n" +',
`\t"Available versions: " + Object.keys(versions).map(${runtimeTemplate.basicFunction(
"key",
['return key + " from " + versions[key].from;']
)}).join(", ");`
]
)};`,
`var getValidVersion = ${runtimeTemplate.basicFunction(
"scope, scopeName, key, requiredVersion",
[
"var entry = findValidVersion(scope, key, requiredVersion);",
"if(entry) return get(entry);",
"throw new Error(getInvalidVersionMessage(scope, scopeName, key, requiredVersion));"
]
)};`,
`var warn = ${
`var fail = ${runtimeTemplate.basicFunction("msg", [
"throw new Error(msg);"
])}`,
`var failAsNotExist = ${runtimeTemplate.basicFunction("scopeName, key", [
'return fail("Shared module " + key + " doesn\'t exist in shared scope " + scopeName);'
])}`,
`var warn = /*#__PURE__*/ ${
compilation.outputOptions.ignoreBrowserWarnings
? runtimeTemplate.basicFunction("", "")
: runtimeTemplate.basicFunction("msg", [
'if (typeof console !== "undefined" && console.warn) console.warn(msg);'
])
};`,
`var warnInvalidVersion = ${runtimeTemplate.basicFunction(
"scope, scopeName, key, requiredVersion",
[
"warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion));"
]
)};`,
`var get = ${runtimeTemplate.basicFunction("entry", [
"entry.loaded = 1;",
"return entry.get()"
])};`,
`var init = ${runtimeTemplate.returningFunction(
Template.asString([
"function(scopeName, a, b, c) {",
"function(scopeName, key, eager, c, d) {",
Template.indent([
`var promise = ${RuntimeGlobals.initializeSharing}(scopeName);`,
`if (promise && promise.then) return promise.then(fn.bind(fn, scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], a, b, c));`,
`return fn(scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], a, b, c);`
// if we require eager shared, we expect it to be already loaded before it requested, no need to wait the whole scope loaded.
"if (promise && promise.then && !eager) { ",
Template.indent([
`return promise.then(fn.bind(fn, scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], key, false, c, d));`
]),
"}",
`return fn(scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], key, eager, c, d);`
]),
"}"
]),
"fn"
)};`,
"",
`var useFallback = ${runtimeTemplate.basicFunction(
"scopeName, key, fallback",
["return fallback ? fallback() : failAsNotExist(scopeName, key);"]
)}`,
`var load = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
"scopeName, scope, key",
"scopeName, scope, key, eager, fallback",
[
"ensureExistence(scopeName, key);",
"return get(findVersion(scope, key));"
"if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
"return get(findLatestVersion(scope, key, eager));"
]
)});`,
`var loadFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
"scopeName, scope, key, fallback",
`var loadVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
"scopeName, scope, key, eager, requiredVersion, fallback",
[
`return scope && ${RuntimeGlobals.hasOwnProperty}(scope, key) ? get(findVersion(scope, key)) : fallback();`
"if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
"var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager);",
"if (satisfyingVersion) return get(satisfyingVersion);",
"warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager))",
"return get(findLatestVersion(scope, key, eager));"
]
)});`,
`var loadVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
"scopeName, scope, key, version",
`var loadStrictVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
"scopeName, scope, key, eager, requiredVersion, fallback",
[
"ensureExistence(scopeName, key);",
"return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key));"
"if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
"var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager);",
"if (satisfyingVersion) return get(satisfyingVersion);",
"if (fallback) return fallback();",
"fail(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager));"
]
)});`,
`var loadSingleton = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
"scopeName, scope, key",
[
"ensureExistence(scopeName, key);",
"return getSingleton(scope, scopeName, key);"
]
)});`,
`var loadSingletonVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
"scopeName, scope, key, version",
[
"ensureExistence(scopeName, key);",
"return getSingletonVersion(scope, scopeName, key, version);"
]
)});`,
`var loadStrictVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
"scopeName, scope, key, version",
"scopeName, scope, key, eager, fallback",
[
"ensureExistence(scopeName, key);",
"return getValidVersion(scope, scopeName, key, version);"
]
)});`,
`var loadStrictSingletonVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
"scopeName, scope, key, version",
[
"ensureExistence(scopeName, key);",
"return getStrictSingletonVersion(scope, scopeName, key, version);"
]
)});`,
`var loadVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
"scopeName, scope, key, version, fallback",
[
`if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`,
"return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key));"
]
)});`,
`var loadSingletonFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
"scopeName, scope, key, fallback",
[
`if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`,
"return getSingleton(scope, scopeName, key);"
]
)});`,
`var loadSingletonVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
"scopeName, scope, key, version, fallback",
[
`if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`,
"return getSingletonVersion(scope, scopeName, key, version);"
"if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
"var version = findSingletonVersionKey(scope, key, eager);",
"return get(scope[key][version]);"
]
)});`,
`var loadStrictVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
"scopeName, scope, key, version, fallback",
`var loadSingletonVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
"scopeName, scope, key, eager, requiredVersion, fallback",
[
`var entry = scope && ${RuntimeGlobals.hasOwnProperty}(scope, key) && findValidVersion(scope, key, version);`,
`return entry ? get(entry) : fallback();`
"if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
"var version = findSingletonVersionKey(scope, key, eager);",
"if (!satisfy(requiredVersion, version)) {",
Template.indent([
"warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));"
]),
"}",
"return get(scope[key][version]);"
]
)});`,
`var loadStrictSingletonVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
"scopeName, scope, key, version, fallback",
`var loadStrictSingletonVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
"scopeName, scope, key, eager, requiredVersion, fallback",
[
`if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`,
"return getStrictSingletonVersion(scope, scopeName, key, version);"
"if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
"var version = findSingletonVersionKey(scope, key, eager);",
"if (!satisfy(requiredVersion, version)) {",
Template.indent([
"fail(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));"
]),
"}",
"return get(scope[key][version]);"
]
)});`,
"var installedModules = {};",
Expand Down
7 changes: 7 additions & 0 deletions test/configCases/container/0-eager-shared/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { emitter } from "./emitter.js";

function App() {
return emitter;
}

export default App;
9 changes: 9 additions & 0 deletions test/configCases/container/0-eager-shared/emitter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { TinyEmitter } from 'tiny-emitter'

const emitter = new TinyEmitter()

emitter.on('hello', () => console.log('hello[service]'))

export {
emitter,
}
6 changes: 6 additions & 0 deletions test/configCases/container/0-eager-shared/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
it("should allow to import exposed modules sync", () => {
return import("./App").then(({ default: App }) => {
expect(App().e.hello).toBeDefined();
});
});

Loading
Loading