@microsoft/dotnet-js-interop
Advanced tools
Comparing version 5.0.0-preview.8.20414.8 to 5.0.0-rc.1.20451.17
@@ -35,2 +35,29 @@ export declare module DotNet { | ||
/** | ||
* Creates a JavaScript object reference that can be passed to .NET via interop calls. | ||
* | ||
* @param jsObject The JavaScript Object used to create the JavaScript object reference. | ||
* @returns The JavaScript object reference (this will be the same instance as the given object). | ||
* @throws Error if the given value is not an Object. | ||
*/ | ||
function createJSObjectReference(jsObject: any): any; | ||
/** | ||
* Disposes the given JavaScript object reference. | ||
* | ||
* @param jsObjectReference The JavaScript Object reference. | ||
*/ | ||
function disposeJSObjectReference(jsObjectReference: any): void; | ||
/** | ||
* Parses the given JSON string using revivers to restore args passed from .NET to JS. | ||
* | ||
* @param json The JSON stirng to parse. | ||
*/ | ||
function parseJsonWithRevivers(json: string): any; | ||
/** | ||
* Represents the type of result expected from a JS interop call. | ||
*/ | ||
enum JSCallResultType { | ||
Default = 0, | ||
JSObjectReference = 1 | ||
} | ||
/** | ||
* Represents the ability to dispatch calls from JavaScript to a .NET runtime. | ||
@@ -76,2 +103,3 @@ */ | ||
* @param identifier Identifies the globally-reachable function to be returned. | ||
* @param targetInstanceId The instance ID of the target JS object. | ||
* @returns A Function instance. | ||
@@ -81,2 +109,8 @@ */ | ||
/** | ||
* Disposes the JavaScript object reference with the specified object ID. | ||
* | ||
* @param id The ID of the JavaScript object reference. | ||
*/ | ||
disposeJSObjectReferenceById: typeof disposeJSObjectReferenceById; | ||
/** | ||
* Invokes the specified synchronous JavaScript function. | ||
@@ -86,5 +120,7 @@ * | ||
* @param argsJson JSON representation of arguments to be passed to the function. | ||
* @param resultType The type of result expected from the JS interop call. | ||
* @param targetInstanceId The instance ID of the target JS object. | ||
* @returns JSON representation of the invocation result. | ||
*/ | ||
invokeJSFromDotNet: (identifier: string, argsJson: string) => string | null; | ||
invokeJSFromDotNet: (identifier: string, argsJson: string, resultType: JSCallResultType, targetInstanceId: number) => string | null; | ||
/** | ||
@@ -96,4 +132,6 @@ * Invokes the specified synchronous or asynchronous JavaScript function. | ||
* @param argsJson JSON representation of arguments to be passed to the function. | ||
* @param resultType The type of result expected from the JS interop call. | ||
* @param targetInstanceId The ID of the target JS object instance. | ||
*/ | ||
beginInvokeJSFromDotNet: (asyncHandle: number, identifier: string, argsJson: string) => void; | ||
beginInvokeJSFromDotNet: (asyncHandle: number, identifier: string, argsJson: string, resultType: JSCallResultType, targetInstanceId: number) => void; | ||
/** | ||
@@ -107,3 +145,4 @@ * Receives notification that an async call from JS to .NET has completed. | ||
}; | ||
function findJSFunction(identifier: string): Function; | ||
function findJSFunction(identifier: string, targetInstanceId: number): Function; | ||
function disposeJSObjectReferenceById(id: number): void; | ||
} |
@@ -1,11 +0,59 @@ | ||
"use strict"; | ||
// This is a single-file self-contained module to avoid the need for a Webpack build | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var DotNet; | ||
export var DotNet; | ||
(function (DotNet) { | ||
var _a; | ||
window.DotNet = DotNet; // Ensure reachable from anywhere | ||
var jsonRevivers = []; | ||
var JSObject = /** @class */ (function () { | ||
function JSObject(_jsObject) { | ||
this._jsObject = _jsObject; | ||
this._cachedFunctions = new Map(); | ||
} | ||
JSObject.prototype.findFunction = function (identifier) { | ||
var cachedFunction = this._cachedFunctions.get(identifier); | ||
if (cachedFunction) { | ||
return cachedFunction; | ||
} | ||
var result = this._jsObject; | ||
var lastSegmentValue; | ||
identifier.split('.').forEach(function (segment) { | ||
if (segment in result) { | ||
lastSegmentValue = result; | ||
result = result[segment]; | ||
} | ||
else { | ||
throw new Error("Could not find '" + identifier + "' ('" + segment + "' was undefined)."); | ||
} | ||
}); | ||
if (result instanceof Function) { | ||
result = result.bind(lastSegmentValue); | ||
this._cachedFunctions.set(identifier, result); | ||
return result; | ||
} | ||
else { | ||
throw new Error("The value '" + identifier + "' is not a function."); | ||
} | ||
}; | ||
JSObject.prototype.getWrappedObject = function () { | ||
return this._jsObject; | ||
}; | ||
return JSObject; | ||
}()); | ||
var jsObjectIdKey = "__jsObjectId"; | ||
var pendingAsyncCalls = {}; | ||
var cachedJSFunctions = {}; | ||
var windowJSObjectId = 0; | ||
var cachedJSObjectsById = (_a = {}, | ||
_a[windowJSObjectId] = new JSObject(window), | ||
_a); | ||
cachedJSObjectsById[windowJSObjectId]._cachedFunctions.set('import', function (url) { | ||
// In most cases developers will want to resolve dynamic imports relative to the base HREF. | ||
// However since we're the one calling the import keyword, they would be resolved relative to | ||
// this framework bundle URL. Fix this by providing an absolute URL. | ||
if (typeof url === 'string' && url.startsWith('./')) { | ||
url = document.baseURI + url.substr(2); | ||
} | ||
return import(/* webpackIgnore: true */ url); | ||
}); | ||
var nextAsyncCallId = 1; // Start at 1 because zero signals "no response needed" | ||
var nextJsObjectId = 1; // Start at 1 because zero is reserved for "window" | ||
var dotNetDispatcher = null; | ||
@@ -63,2 +111,49 @@ /** | ||
DotNet.invokeMethodAsync = invokeMethodAsync; | ||
/** | ||
* Creates a JavaScript object reference that can be passed to .NET via interop calls. | ||
* | ||
* @param jsObject The JavaScript Object used to create the JavaScript object reference. | ||
* @returns The JavaScript object reference (this will be the same instance as the given object). | ||
* @throws Error if the given value is not an Object. | ||
*/ | ||
function createJSObjectReference(jsObject) { | ||
var _a; | ||
if (jsObject && typeof jsObject === 'object') { | ||
cachedJSObjectsById[nextJsObjectId] = new JSObject(jsObject); | ||
var result = (_a = {}, | ||
_a[jsObjectIdKey] = nextJsObjectId, | ||
_a); | ||
nextJsObjectId++; | ||
return result; | ||
} | ||
else { | ||
throw new Error("Cannot create a JSObjectReference from the value '" + jsObject + "'."); | ||
} | ||
} | ||
DotNet.createJSObjectReference = createJSObjectReference; | ||
/** | ||
* Disposes the given JavaScript object reference. | ||
* | ||
* @param jsObjectReference The JavaScript Object reference. | ||
*/ | ||
function disposeJSObjectReference(jsObjectReference) { | ||
var id = jsObjectReference && jsObjectReference[jsObjectIdKey]; | ||
if (typeof id === 'number') { | ||
disposeJSObjectReferenceById(id); | ||
} | ||
} | ||
DotNet.disposeJSObjectReference = disposeJSObjectReference; | ||
/** | ||
* Parses the given JSON string using revivers to restore args passed from .NET to JS. | ||
* | ||
* @param json The JSON stirng to parse. | ||
*/ | ||
function parseJsonWithRevivers(json) { | ||
return json ? JSON.parse(json, function (key, initialValue) { | ||
// Invoke each reviver in order, passing the output from the previous reviver, | ||
// so that each one gets a chance to transform the value | ||
return jsonRevivers.reduce(function (latestValue, reviver) { return reviver(key, latestValue); }, initialValue); | ||
}) : null; | ||
} | ||
DotNet.parseJsonWithRevivers = parseJsonWithRevivers; | ||
function invokePossibleInstanceMethod(assemblyName, methodIdentifier, dotNetObjectId, args) { | ||
@@ -113,2 +208,10 @@ var dispatcher = getRequiredDispatcher(); | ||
/** | ||
* Represents the type of result expected from a JS interop call. | ||
*/ | ||
var JSCallResultType; | ||
(function (JSCallResultType) { | ||
JSCallResultType[JSCallResultType["Default"] = 0] = "Default"; | ||
JSCallResultType[JSCallResultType["JSObjectReference"] = 1] = "JSObjectReference"; | ||
})(JSCallResultType = DotNet.JSCallResultType || (DotNet.JSCallResultType = {})); | ||
/** | ||
* Receives incoming calls from .NET and dispatches them to JavaScript. | ||
@@ -121,2 +224,3 @@ */ | ||
* @param identifier Identifies the globally-reachable function to be returned. | ||
* @param targetInstanceId The instance ID of the target JS object. | ||
* @returns A Function instance. | ||
@@ -126,2 +230,8 @@ */ | ||
/** | ||
* Disposes the JavaScript object reference with the specified object ID. | ||
* | ||
* @param id The ID of the JavaScript object reference. | ||
*/ | ||
disposeJSObjectReferenceById: disposeJSObjectReferenceById, | ||
/** | ||
* Invokes the specified synchronous JavaScript function. | ||
@@ -131,6 +241,9 @@ * | ||
* @param argsJson JSON representation of arguments to be passed to the function. | ||
* @param resultType The type of result expected from the JS interop call. | ||
* @param targetInstanceId The instance ID of the target JS object. | ||
* @returns JSON representation of the invocation result. | ||
*/ | ||
invokeJSFromDotNet: function (identifier, argsJson) { | ||
var result = findJSFunction(identifier).apply(null, parseJsonWithRevivers(argsJson)); | ||
invokeJSFromDotNet: function (identifier, argsJson, resultType, targetInstanceId) { | ||
var returnValue = findJSFunction(identifier, targetInstanceId).apply(null, parseJsonWithRevivers(argsJson)); | ||
var result = createJSCallResult(returnValue, resultType); | ||
return result === null || result === undefined | ||
@@ -146,8 +259,10 @@ ? null | ||
* @param argsJson JSON representation of arguments to be passed to the function. | ||
* @param resultType The type of result expected from the JS interop call. | ||
* @param targetInstanceId The ID of the target JS object instance. | ||
*/ | ||
beginInvokeJSFromDotNet: function (asyncHandle, identifier, argsJson) { | ||
beginInvokeJSFromDotNet: function (asyncHandle, identifier, argsJson, resultType, targetInstanceId) { | ||
// Coerce synchronous functions into async ones, plus treat | ||
// synchronous exceptions the same as async ones | ||
var promise = new Promise(function (resolve) { | ||
var synchronousResultOrPromise = findJSFunction(identifier).apply(null, parseJsonWithRevivers(argsJson)); | ||
var synchronousResultOrPromise = findJSFunction(identifier, targetInstanceId).apply(null, parseJsonWithRevivers(argsJson)); | ||
resolve(synchronousResultOrPromise); | ||
@@ -159,3 +274,3 @@ }); | ||
// Not using "await" because it codegens a lot of boilerplate | ||
promise.then(function (result) { return getRequiredDispatcher().endInvokeJSFromDotNet(asyncHandle, true, JSON.stringify([asyncHandle, true, result], argReplacer)); }, function (error) { return getRequiredDispatcher().endInvokeJSFromDotNet(asyncHandle, false, JSON.stringify([asyncHandle, false, formatError(error)])); }); | ||
promise.then(function (result) { return getRequiredDispatcher().endInvokeJSFromDotNet(asyncHandle, true, JSON.stringify([asyncHandle, true, createJSCallResult(result, resultType)], argReplacer)); }, function (error) { return getRequiredDispatcher().endInvokeJSFromDotNet(asyncHandle, false, JSON.stringify([asyncHandle, false, formatError(error)])); }); | ||
} | ||
@@ -174,9 +289,2 @@ }, | ||
}; | ||
function parseJsonWithRevivers(json) { | ||
return json ? JSON.parse(json, function (key, initialValue) { | ||
// Invoke each reviver in order, passing the output from the previous reviver, | ||
// so that each one gets a chance to transform the value | ||
return jsonRevivers.reduce(function (latestValue, reviver) { return reviver(key, latestValue); }, initialValue); | ||
}) : null; | ||
} | ||
function formatError(error) { | ||
@@ -190,28 +298,14 @@ if (error instanceof Error) { | ||
} | ||
function findJSFunction(identifier) { | ||
if (Object.prototype.hasOwnProperty.call(cachedJSFunctions, identifier)) { | ||
return cachedJSFunctions[identifier]; | ||
function findJSFunction(identifier, targetInstanceId) { | ||
var targetInstance = cachedJSObjectsById[targetInstanceId]; | ||
if (targetInstance) { | ||
return targetInstance.findFunction(identifier); | ||
} | ||
var result = window; | ||
var resultIdentifier = 'window'; | ||
var lastSegmentValue; | ||
identifier.split('.').forEach(function (segment) { | ||
if (segment in result) { | ||
lastSegmentValue = result; | ||
result = result[segment]; | ||
resultIdentifier += '.' + segment; | ||
} | ||
else { | ||
throw new Error("Could not find '" + segment + "' in '" + resultIdentifier + "'."); | ||
} | ||
}); | ||
if (result instanceof Function) { | ||
result = result.bind(lastSegmentValue); | ||
cachedJSFunctions[identifier] = result; | ||
return result; | ||
} | ||
else { | ||
throw new Error("The value '" + resultIdentifier + "' is not a function."); | ||
throw new Error("JS object instance with ID " + targetInstanceId + " does not exist (has it been disposed?)."); | ||
} | ||
} | ||
function disposeJSObjectReferenceById(id) { | ||
delete cachedJSObjectsById[id]; | ||
} | ||
var DotNetObject = /** @class */ (function () { | ||
@@ -252,6 +346,30 @@ function DotNetObject(_id) { | ||
}); | ||
attachReviver(function reviveJSObjectReference(key, value) { | ||
if (value && typeof value === 'object' && value.hasOwnProperty(jsObjectIdKey)) { | ||
var id = value[jsObjectIdKey]; | ||
var jsObject = cachedJSObjectsById[id]; | ||
if (jsObject) { | ||
return jsObject.getWrappedObject(); | ||
} | ||
else { | ||
throw new Error("JS object instance with ID " + id + " does not exist (has it been disposed?)."); | ||
} | ||
} | ||
// Unrecognized - let another reviver handle it | ||
return value; | ||
}); | ||
function createJSCallResult(returnValue, resultType) { | ||
switch (resultType) { | ||
case JSCallResultType.Default: | ||
return returnValue; | ||
case JSCallResultType.JSObjectReference: | ||
return createJSObjectReference(returnValue); | ||
default: | ||
throw new Error("Invalid JS call result type '" + resultType + "'."); | ||
} | ||
} | ||
function argReplacer(key, value) { | ||
return value instanceof DotNetObject ? value.serializeAsArg() : value; | ||
} | ||
})(DotNet = exports.DotNet || (exports.DotNet = {})); | ||
})(DotNet || (DotNet = {})); | ||
//# sourceMappingURL=Microsoft.JSInterop.js.map |
{ | ||
"name": "@microsoft/dotnet-js-interop", | ||
"version": "5.0.0-preview.8.20414.8", | ||
"version": "5.0.0-rc.1.20451.17", | ||
"description": "Provides abstractions and features for interop between .NET and JavaScript code.", | ||
@@ -5,0 +5,0 @@ "main": "dist/Microsoft.JSInterop.js", |
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
35793
507
0