Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

libkernel

Package Overview
Dependencies
Maintainers
1
Versions
127
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

libkernel - npm Package Compare versions

Comparing version 0.0.48 to 0.0.49

2

dist/index.d.ts

@@ -1,2 +0,2 @@

export { init, newKernelQuery } from './init';
export { init, postKernelQuery } from './init';
export { testMessage, callModule, upload, padAndEncrypt } from './messages';

@@ -1,2 +0,2 @@

export { init, newKernelQuery } from './init';
export { init, postKernelQuery } from './init';
export { testMessage, callModule, upload, padAndEncrypt } from './messages';
export declare function log(...inputs: any): void;
export declare function logErr(...inputs: any): void;
export declare function composeErr(...inputs: any): string;
export declare function newKernelQuery(data: any, update: Function): [Function, Promise<any>];
export declare function postKernelQuery(kernelQuery: any): Promise<any>;
export declare function init(): Promise<string>;

@@ -10,42 +10,34 @@ // log provides a wrapper for console.log that prefixes 'libkernel'.

}
// composeErr takes a series of inputs and composes them into a single string.
// Each element will be separated by a newline. If the input is not a string,
// it will be transformed into a string with JSON.stringify.
//
// Any object that cannot be stringified will be skipped, though an error will
// be logged.
export function composeErr(...inputs) {
let result = "";
for (let i = 0; i < inputs.length; i++) {
// Prepend a newline if this isn't the first element.
if (i !== 0) {
result += "\n";
}
// Strings can be added without modification.
if (typeof inputs[i] === "string") {
result += inputs[i];
continue;
}
// Everything else needs to be stringified, log an error if it
// fails.
try {
let str = JSON.stringify(inputs[i]);
result += str;
}
catch (_a) {
logErr("unable to stringify input to composeErr");
}
}
return result;
}
// Establish a hashmap for matching queries to their responses by their nonces.
// nextNonce needs to start at '1' because '0' is reserved for the bridgeTest
// method performed at init.
const namespace = "libkernel-v0";
var initialized;
var bridgeExists;
var bridgeAvailable;
var blockForBridge = new Promise((resolve, reject) => {
bridgeAvailable = { resolve, reject };
});
// Establish a system for matching messages to the kernel with responses from
// the kernel. The nonce is incremented every time a new message is sent, and
// the queries object is used as a hashmap that maps a given message nonce to
// the {resolve, reject} of a promise that will be resolved/rejected when a
// response to the corresponding message is provided.
var nextNonce = 1;
var queries = new Object();
// postKernelQuery will send a postMessage to the kernel, handling details like
// the nonce and the resolve/reject upon receiving a response. The inputs are a
// resolve and reject function of a promise that should be resolved when the
// response is received, and the message that is going to the kernel itself.
export function postKernelQuery(kernelQuery) {
return new Promise((resolve, reject) => {
let nonce = nextNonce;
nextNonce++;
queries[nonce] = { resolve, reject };
window.postMessage({
method: "kernelQuery",
nonce,
kernelQuery,
}, window.location.origin);
});
}
// handleBridgeResponse will handle a response from the bridge indicating that
// the bridge is working. This needs to be declared before the remaining bridge
// variables because they need to reference it as a handler.
function handleBridgeResponse(resolve, reject, data) {
// the bridge is working.
function handleBridgeResponse(data) {
// Check whether the timeout for the bridge has already fired. If so,

@@ -55,3 +47,2 @@ // log that the bridge is available but late.

logErr("received late signal from bridge");
reject("received late signal from bridge");
return;

@@ -61,119 +52,69 @@ }

// Check whether the version is available in the data.
if ("version" in data) {
resolve(data.version);
if (!("version" in data)) {
bridgeAvailable.resolve("bridge did not report a version");
}
else {
resolve("bridge did not report a version");
bridgeAvailable.resolve(data.version);
}
}
// Establish a system to test if the bridge script is running. bridgeExists is
// a boolean which establishes whether or not we have already determinied if
// the bridge eixsts, bridgeAvailable is the {resolve, reject} object for a
// promise, and the blockForBridge will resolve/reject when we have determined
// if the bridge exists.
//
// The init() function will use a timeout to decide that the bridge does not
// exist, the hanelMessage function will look for a method called
// "bridgeTestResponse" to determine that the bridge does exist. The init
// script needs to send the bridge a "bridgeTestQuery" message so the bridge
// knows to respond.
var initialized;
var bridgeExists;
var bridgeAvailable;
var blockForBridge = new Promise((resolve, reject) => {
bridgeAvailable = { resolve, reject, update: null, handle: handleBridgeResponse };
});
// newKernelQuery will send a postMessage to the kernel, handling details like
// the nonce and the resolve/reject upon receiving a response.
//
// The first return value is a function that can be called to send a
// 'queryUpdate' to the kernel for that nonce.
export function newKernelQuery(data, update) {
let nonce = nextNonce;
nextNonce++;
let sendUpdate = function (data) {
queryUpdate(nonce, data);
};
let p = new Promise((resolve, reject) => {
queries[nonce] = { resolve, reject, update, handle: handleKernelResponse };
window.postMessage({
namespace,
method: "newKernelQuery",
nonce,
data,
});
});
return [sendUpdate, p];
}
// queryUpdate is a function that can be called to send a queryUpdate to an
// existing query.
function queryUpdate(nonce, data) {
window.postMessage({
namespace,
method: "queryUpdate",
nonce,
data,
});
}
// handleKernelResponse will parse the kernel's response from the bridge and
// resolve/reject the promise associated with the nonce.
function handleKernelResponse(resolve, reject, data) {
resolve(data);
}
// handleMessage will handle a message from the kernel, using the response to
// resolve the appropriate promise in the set of queries.
function handleMessage(event) {
// Check the message source.
if (event.source !== window) {
function handleKernelResponse(event) {
// Check that we have a promise for the provided nonce.
if (!(event.data.nonce in queries)) {
logErr("nonce of kernelResponse not found\n", event, "\n", queries);
return;
}
// Check that this message is a response targeting libkernel.
if (event.data.namespace !== namespace) {
let result = queries[event.data.nonce];
delete queries[event.data.nonce];
// Check the status and then resolve or reject accordingly.
if (!("response" in event.data) || !("queryStatus" in event.data.response)) {
logErr("malformed kernel response\n", event);
return;
}
if (!("method" in event.data) || typeof event.data.method !== "string") {
logErr("received message targeting our namespace with malformed method", event.data);
return;
if (event.data.response.queryStatus === "resolve") {
result.resolve(event.data.response);
}
if (event.data.method !== "response" && event.data.method !== "responseUpdate") {
// We don't log here because that would catch outbound messages
// from ourself.
else if (event.data.response.queryStatus === "reject") {
result.reject(event.data.response);
}
else {
logErr("malformed queryStatus");
}
}
// handleKernelResponseErr is a special handler for situations where the
// content script was unable to communicate with the background script.
function handleKernelResponseErr(event) {
let reject = queries[event.data.nonce];
delete queries[event.data.nonce];
if (!("err" in event.data) || typeof event.data.err !== "string") {
logErr("malformed error received from bridge");
return;
}
// Check that we have a nonce for this message.
if (!(event.data.nonce in queries)) {
logErr("message received with no matching nonce\n", event.data, "\n", queries);
logErr(event.data.err);
reject(event.data.err);
}
// handleMessage will handle a message from the kernel, using the response to
// resolve the appropriate promise in the set of queries.
function handleMessage(event) {
// Check the message source.
if (event.source !== window) {
return;
}
// If this is a responseUpdate, pass the data to the update handler.
if (event.data.method === "responseUpdate") {
let handler = queries[event.data.nonce];
if (!("update" in handler) || typeof handler.update !== "function") {
logErr("responseUpdate received, but no update method defined in handler");
return;
}
if (!("data" in event.data)) {
logErr("responseUpdate received, but no data provided: " + JSON.stringify(event.data));
return;
}
handler.update(event.data.data);
// Check that this message is a kernelResponse.
if (!("data" in event) || !("method" in event.data)) {
return;
}
// The method is "response", meaning the query is closed out can can be
// deleted.
let handler = queries[event.data.nonce];
delete queries[event.data.nonce];
if (!("err" in event.data)) {
handler.reject("no err field provided in response: " + JSON.stringify(event.data));
if (event.data.method === "bridgeTestResponse") {
handleBridgeResponse(event.data);
return;
}
if (event.data.err !== null) {
handler.reject("response to bridge contained an error: " + event.data.err);
if (event.data.method === "kernelResponse") {
handleKernelResponse(event);
return;
}
if (!("data" in event.data)) {
handler.reject("no data field provided in query: " + JSON.stringify(event.data));
if (event.data.method === "kernelResponseErr") {
handleKernelResponseErr(event);
return;
}
handler.handle(handler.resolve, handler.reject, event.data.data);
}

@@ -192,10 +133,9 @@ // init will add an event listener for messages from the kernel bridge. It is

window.addEventListener("message", handleMessage);
// Send a message checking if the bridge is alive and responding. The
// nonce '0' is kept available explicitly for this purpose.
// Send a message checking if the bridge is alive and responding. We
// use a fake nonce because we don't care about the nonce for the
// bridge.
window.postMessage({
namespace,
method: "bridgeTestQuery",
nonce: 0,
method: "test",
});
queries[0] = bridgeAvailable;
// After 2 seconds, check whether the bridge has responded. If not,

@@ -206,3 +146,3 @@ // fail the bridge.

bridgeExists = false;
bridgeAvailable.reject("bridge unavailable, need skynet extension");
bridgeAvailable.reject(new Error("bridge unavailable, need skynet extension"));
logErr("bridge did not respond after 2 seconds");

@@ -209,0 +149,0 @@ }

export declare function testMessage(): Promise<string>;
export declare function callModule(module: string, method: string, data: any): Promise<any>;
export declare function callModule(module: string, moduleMethod: string, moduleInput: any): Promise<any>;
export declare function upload(filename: string, fileData: Uint8Array): Promise<string>;
export declare function padAndEncrypt(filepath: string, fileData: Uint8Array): Promise<string>;

@@ -1,3 +0,2 @@

import { logErr, composeErr, init, newKernelQuery } from './init';
const noBridge = "the bridge failed to initialize (do you have the Skynet browser extension?)";
import { logErr, init, postKernelQuery } from './init';
// testMessage will send a test message to the kernel, ensuring that basic

@@ -18,27 +17,12 @@ // kernel communications are working. The promise will resolve to the version

.then(x => {
// Send a 'test' message to the kernel, which is a
// method with no parameters.
//
// The first return value of newKernelQuery is ignored
// because it is an update function that we can call if
// we wish to provide new information to the query via
// a 'queryUpdate'. The 'test' method does not support
// any queryUpdates.
//
// The second input of newKernelQuery is passed as
// null, it's usually a handler function to accept
// 'responseUpdate' messages from the kernel related to
// the query. The 'test' method doesn't have any
// 'responseUpdates', so there is no need to create an
// updateHandler.
let [_, query] = newKernelQuery({
method: "test",
}, null);
// We use nested promises instead of promise chaining
// because promise chaining didn't provide enough
// control over handling the error. We like wrapping
// our errors to help indicate exactly which part of
// the code has gone wrong, and that nuance gets lost
// with promise chaining.
query.then(response => {
// Send a 'requestTest' message to the kernel. The
// request test message uniquely doesn't have any other
// parameters.
postKernelQuery({
kernelMethod: "requestTest",
})
// We use nested promises instead of promise chaining
// because promise chaining didn't provide enough
// control over handling the error.
.then(response => {
if (!("version" in response)) {

@@ -50,5 +34,9 @@ resolve("kernel did not report a version");

})
.catch(err => {
let cErr = composeErr("newKernelQuery failed", err);
reject(cErr);
.catch(response => {
if (!("err" in response) || typeof response.err !== "string") {
logErr("unrecognized response in postKernelQuery catch", response);
reject("unrecognized repsonse");
return;
}
reject(response.err);
});

@@ -60,5 +48,4 @@ })

// the browser extension.
let cErr = composeErr(noBridge, err);
logErr(cErr);
reject(cErr);
logErr("bridge is not initialized:", err);
reject(err);
});

@@ -70,30 +57,21 @@ });

// handled for the user.
//
// callModule can only be used for query-response communications, there is no
// support for sending queryUpdate messages or receiving responseUpdate
// messages. If you need those, use 'connectModule' instead.
export function callModule(module, method, data) {
export function callModule(module, moduleMethod, moduleInput) {
return new Promise((resolve, reject) => {
init()
.then(x => {
let [_, query] = newKernelQuery({
method: "moduleCall",
data: {
module,
method,
data,
}
}, null);
query.then(response => {
return postKernelQuery({
kernelMethod: "moduleCall",
module,
moduleMethod,
moduleInput,
})
.then(response => {
resolve(response);
})
.catch(err => {
let cErr = composeErr("moduleCall query to kernel failed", err);
reject(err);
.catch(response => {
reject(response);
});
})
.catch(err => {
let cErr = composeErr(noBridge, err);
logErr(cErr);
reject(cErr);
reject(err);
});

@@ -115,3 +93,3 @@ });

.then(x => {
let [_, query] = newKernelQuery({
return postKernelQuery({
kernelMethod: "moduleCall",

@@ -124,8 +102,8 @@ module: "AQCS3RHbDlk00IdICFEI1rKZp-VNsnsKWC0n7K-taoAuog",

},
}, null);
query.then(response => {
})
.then(response => {
resolve(response.output);
})
.catch(err => {
reject(err);
.catch(response => {
reject(response.err);
});

@@ -149,3 +127,3 @@ })

.then(x => {
let [_, query] = newKernelQuery({
postKernelQuery({
kernelMethod: "moduleCall",

@@ -158,4 +136,4 @@ module: "AQAs00kS6OKUd-FIWj9qdJLArCiEDMVgYBSkaetuTF-MsQ",

},
}, null);
query.then(response => {
})
.then(response => {
resolve(response.output);

@@ -162,0 +140,0 @@ })

{
"name": "libkernel",
"version": "0.0.48",
"version": "0.0.49",
"description": "helper library to interact with the skynet kernel",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc