@substrate/connect
Advanced tools
Comparing version 0.7.3 to 0.7.4
@@ -5,2 +5,12 @@ # Changelog | ||
## 0.7.4 - 2022-05-05 | ||
### Added | ||
- Added an optional configuration to `smoldot-light/createScClient` that allows customizing the maximum log level to use while the client is in use, allowing for better debuggability. ([#1027](https://github.com/paritytech/substrate-connect/pull/1027)) | ||
### Changed | ||
- Debug logs are no longer printed in the console. This should considerably decrease the number of messages being printed. ([#1027](https://github.com/paritytech/substrate-connect/pull/1027)) | ||
## 0.7.3 - 2022-05-02 | ||
@@ -7,0 +17,0 @@ |
@@ -24,3 +24,3 @@ export * from "./types.js"; | ||
*/ | ||
export declare const createScClient: () => import("./types.js").ScClient; | ||
export declare const createScClient: (config?: import("./smoldot-light.js").Config | undefined) => import("./types.js").ScClient; | ||
//# sourceMappingURL=index.d.ts.map |
import { ScClient } from "./types.js"; | ||
/** | ||
* Configuration that can be passed to {createScClient}. | ||
*/ | ||
export interface Config { | ||
/** | ||
* The client prints logs in the console. By default, only log levels 1, 2, and 3 (corresponding | ||
* respectively to ERROR, WARN, and INFO) are printed. | ||
* | ||
* In order to more easily debug problems, you can pass 4 (DEBUG) or more. | ||
* | ||
* This setting is only taken into account between the moment when you use this chain to add a | ||
* chain for the first time, and the moment when all the chains that you have added have been | ||
* removed. | ||
* | ||
* If {createScClient} is called multiple times with multiple different log levels, the highest | ||
* value will be used. | ||
*/ | ||
maxLogLevel?: number; | ||
} | ||
/** | ||
* Returns a {ScClient} that connects to chains by executing a light client directly | ||
@@ -9,3 +28,3 @@ * from JavaScript. | ||
*/ | ||
export declare const createScClient: () => ScClient; | ||
export declare const createScClient: (config?: Config | undefined) => ScClient; | ||
//# sourceMappingURL=smoldot-light.d.ts.map |
@@ -10,18 +10,77 @@ import { getSpec } from "./specs/index.js"; | ||
}; | ||
let clientNumReferences = 0; | ||
const clientReferences = []; // Note that this can't be a set, as the same config is added/removed multiple times | ||
let clientPromise = null; | ||
const getClientAndIncRef = () => { | ||
let clientReferencesMaxLogLevel = 3; | ||
const getClientAndIncRef = (config) => { | ||
if (config.maxLogLevel && config.maxLogLevel > clientReferencesMaxLogLevel) | ||
clientReferencesMaxLogLevel = config.maxLogLevel; | ||
if (clientPromise) { | ||
clientNumReferences += 1; | ||
return clientPromise; | ||
clientReferences.push(config); | ||
if (clientPromise instanceof Promise) | ||
return clientPromise; | ||
else | ||
return Promise.resolve(clientPromise); | ||
} | ||
clientPromise = getStart().then((start) => start({ | ||
const newClientPromise = getStart().then((start) => start({ | ||
forbidTcp: true, | ||
forbidNonLocalWs: true, | ||
maxLogLevel: 4 /* no debug/trace messages */, | ||
cpuRateLimit: 0.5, // Politely limit the CPU usage of the smoldot background worker. | ||
maxLogLevel: 9999999, | ||
cpuRateLimit: 0.5, | ||
logCallback: (level, target, message) => { | ||
if (level > clientReferencesMaxLogLevel) | ||
return; | ||
// The first parameter of the methods of `console` has some printf-like substitution | ||
// capabilities. We don't really need to use this, but not using it means that the logs | ||
// might not get printed correctly if they contain `%`. | ||
if (level <= 1) { | ||
console.error("[%s] %s", target, message); | ||
} | ||
else if (level === 2) { | ||
console.warn("[%s] %s", target, message); | ||
} | ||
else if (level === 3) { | ||
console.info("[%s] %s", target, message); | ||
} | ||
else if (level === 4) { | ||
console.debug("[%s] %s", target, message); | ||
} | ||
else { | ||
console.trace("[%s] %s", target, message); | ||
} | ||
}, | ||
})); | ||
clientNumReferences += 1; | ||
clientPromise = newClientPromise; | ||
newClientPromise.then((client) => { | ||
// Make sure that the client we have just created is still desired | ||
if (clientPromise === newClientPromise) | ||
clientPromise = client; | ||
else | ||
client.terminate(); | ||
// Note that if clientPromise != newClientPromise we know for sure that the client that we | ||
// return isn't going to be used. We would rather not return a terminated client, but this | ||
// isn't possible for type check reasons. | ||
return client; | ||
}); | ||
clientReferences.push(config); | ||
return clientPromise; | ||
}; | ||
// Must be passed the exact same object as was passed to {getClientAndIncRef} | ||
const decRef = (config) => { | ||
const idx = clientReferences.indexOf(config); | ||
if (idx === -1) | ||
throw new Error("Internal error within smoldot-light"); | ||
clientReferences.splice(idx, 1); | ||
// Update `clientReferencesMaxLogLevel` | ||
// Note how it is set back to 3 if there is no reference anymore | ||
clientReferencesMaxLogLevel = 3; | ||
for (const cfg of clientReferences.values()) { | ||
if (cfg.maxLogLevel && cfg.maxLogLevel > clientReferencesMaxLogLevel) | ||
clientReferencesMaxLogLevel = cfg.maxLogLevel; | ||
} | ||
if (clientReferences.length === 0) { | ||
if (clientPromise && !(clientPromise instanceof Promise)) | ||
clientPromise.terminate(); | ||
clientPromise = null; | ||
} | ||
}; | ||
const transformErrors = (thunk) => { | ||
@@ -49,6 +108,7 @@ try { | ||
*/ | ||
export const createScClient = () => { | ||
export const createScClient = (config) => { | ||
const configOrDefault = config || { maxLogLevel: 3 }; | ||
const chains = new Map(); | ||
const addChain = async (chainSpec, jsonRpcCallback) => { | ||
const client = await getClientAndIncRef(); | ||
const client = await getClientAndIncRef(configOrDefault); | ||
try { | ||
@@ -67,13 +127,11 @@ const internalChain = await client.addChain({ | ||
remove: () => { | ||
if (chains.has(chain)) { | ||
try { | ||
transformErrors(() => { | ||
internalChain.remove(); | ||
}); | ||
} | ||
finally { | ||
chains.delete(chain); | ||
if (--clientNumReferences === 0) { | ||
clientPromise = null; | ||
client.terminate(); | ||
return; | ||
} | ||
decRef(configOrDefault); | ||
} | ||
transformErrors(() => { | ||
internalChain.remove(); | ||
}); | ||
}, | ||
@@ -85,6 +143,3 @@ }; | ||
catch (error) { | ||
if (--clientNumReferences === 0) { | ||
clientPromise = null; | ||
client.terminate(); | ||
} | ||
decRef(configOrDefault); | ||
throw error; | ||
@@ -97,3 +152,3 @@ } | ||
// happen in parallel | ||
getClientAndIncRef(); | ||
getClientAndIncRef(configOrDefault); | ||
try { | ||
@@ -104,6 +159,3 @@ const spec = await getSpec(supposedChain); | ||
finally { | ||
if (--clientNumReferences === 0) { | ||
clientPromise === null || clientPromise === void 0 ? void 0 : clientPromise.then((client) => client.terminate()); | ||
clientPromise = null; | ||
} | ||
decRef(configOrDefault); | ||
} | ||
@@ -110,0 +162,0 @@ }; |
{ | ||
"name": "@substrate/connect", | ||
"version": "0.7.3", | ||
"version": "0.7.4", | ||
"description": "Substrate-connect to Smoldot clients. Using either substrate extension with predefined clients or an internal smoldot client based on chainSpecs provided.", | ||
@@ -34,3 +34,6 @@ "author": "Parity Team <admin@parity.io>", | ||
"eventemitter3": "^4.0.7" | ||
}, | ||
"devDependencies": { | ||
"eslint": "^8.14.0" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
2632305
1
36
720