@endo/eventual-send
Advanced tools
Comparing version 0.14.8 to 0.15.0
@@ -6,2 +6,21 @@ # Change Log | ||
## [0.15.0](https://github.com/endojs/endo/compare/@endo/eventual-send@0.14.8...@endo/eventual-send@0.15.0) (2022-04-12) | ||
### ⚠ BREAKING CHANGES | ||
* **far:** rename `Remote` to `FarRef` | ||
### Features | ||
* **far:** rename `Remote` to `FarRef` ([7bde2bf](https://github.com/endojs/endo/commit/7bde2bf28e88935606564cebd1b8d284cd70e4ef)) | ||
### Bug Fixes | ||
* **eventual-send:** evolve types based on marshal requirements ([ff388fa](https://github.com/endojs/endo/commit/ff388fa2f81446c1ae02618b78771dc17ce5c74b)) | ||
* **eventual-send:** unwrap promises more fully ([6ba799f](https://github.com/endojs/endo/commit/6ba799f77e8d55530ecd7617c3ccad22324bade2)) | ||
### [0.14.8](https://github.com/endojs/endo/compare/@endo/eventual-send@0.14.7...@endo/eventual-send@0.14.8) (2022-03-07) | ||
@@ -8,0 +27,0 @@ |
{ | ||
"name": "@endo/eventual-send", | ||
"version": "0.14.8", | ||
"version": "0.15.0", | ||
"description": "Extend a Promise class to implement the eventual-send API", | ||
@@ -16,3 +16,3 @@ "type": "module", | ||
"lint": "yarn lint:types && yarn lint:eslint", | ||
"lint:types": "tsc -p jsconfig.test.json", | ||
"lint:types": "tsc", | ||
"lint:eslint": "eslint '**/*.js'" | ||
@@ -31,6 +31,7 @@ }, | ||
"devDependencies": { | ||
"@endo/lockdown": "^0.1.9", | ||
"@endo/ses-ava": "^0.2.21", | ||
"@endo/lockdown": "^0.1.10", | ||
"@endo/ses-ava": "^0.2.22", | ||
"ava": "^3.12.1", | ||
"c8": "^7.7.3" | ||
"c8": "^7.7.3", | ||
"tsd": "^0.19.1" | ||
}, | ||
@@ -66,3 +67,3 @@ "keywords": [ | ||
}, | ||
"gitHead": "9ddd58b4a26755cdba9403b0cb042b2067c69832" | ||
"gitHead": "59e511891ab67f4fa52d67141510974e22362134" | ||
} |
@@ -101,3 +101,3 @@ // @ts-check | ||
E.when = (x, onfulfilled = undefined, onrejected = undefined) => { | ||
E.when = (x, onfulfilled, onrejected) => { | ||
const [onsuccess, onfailure] = trackTurns([onfulfilled, onrejected]); | ||
@@ -104,0 +104,0 @@ return HandledPromise.resolve(x).then(onsuccess, onfailure); |
@@ -396,3 +396,3 @@ // @ts-check | ||
/** @type {import('.').HandledPromiseStaticMethods} */ | ||
/** @type {import('.').HandledPromiseStaticMethods & Pick<PromiseConstructor, 'resolve'>} */ | ||
const staticMethods = { | ||
@@ -399,0 +399,0 @@ get(target, prop) { |
@@ -1,14 +0,39 @@ | ||
/* eslint-disable no-shadow,no-use-before-define,no-var,vars-on-top */ | ||
// Type definitions for eventual-send | ||
// TODO: Add jsdocs. | ||
type Property = string | number | symbol; | ||
/** | ||
* @file Type definitions for @agoric/eventual-send | ||
* | ||
* Some useful background knowledge: | ||
* | ||
* `Omit<T, U>` means to return a record type `T2` which has none of the properties whose keys are part of `U`. | ||
* `Omit<{a: 1, b: 2, c: 3}, 'b'>` is the type `{a: 1, c: 3}`. | ||
* | ||
* `Pick<T, U>` means to return a record type `T2` which has only the properties whose keys are part of `U`. | ||
* `Pick<{a: 1, b: 2, c: 3}, 'b'>` is the type `{b: 2}`. | ||
* | ||
* `PromiseLike<T>` is a thenable which resolves to `T`. | ||
* | ||
* `Promise<PromiseLike<T>>` doesn't handle recursion and is distinct from `T`. | ||
* | ||
* `Unpromise<PromiseLike<T>>` strips off just one layer and is just `T`. `Unpromise<PromiseLike<PromiseLIke<T>>` is `PromiseLike<T>`. | ||
* | ||
* `Awaited<PromiseLike<T>>` recurses, and is just `T`. | ||
* `Awaited<PromiseLike<PromiseLike<T>>>` is just `T` as well. | ||
* | ||
* @see {@link https://www.typescriptlang.org/docs/handbook/2/generics.html#handbook-content} | ||
* @see {@link https://www.typescriptlang.org/docs/handbook/2/conditional-types.html} | ||
*/ | ||
type ERef<T> = PromiseLike<T> | T; | ||
export type Callable = (...args: any[]) => any; | ||
// Same as https://github.com/microsoft/TypeScript/issues/31394 | ||
export type ERef<T> = PromiseLike<T> | T; | ||
export declare const EmptyObj: {}; | ||
// Type for an object that must only be invoked with E. It supports a given | ||
// interface but declares all the functions as asyncable. | ||
export type EOnly<T> = T extends (...args: infer P) => infer R | ||
? (...args: P) => ERef<R> | EOnly<R> | ||
: T extends Record<string | number | symbol, Function> | ||
? (...args: P) => ERef<Awaited<R>> | EOnly<Awaited<R>> | ||
: T extends Record<PropertyKey, Callable> | ||
? ERef< | ||
@@ -21,35 +46,82 @@ { | ||
type FilteredKeys<T, U> = { | ||
/** | ||
* Return a union of property names/symbols/numbers P for which the record element T[P]'s type extends U. | ||
* | ||
* Given const x = { a: 123, b: 'hello', c: 42, 49: () => {}, 53: 67 }, | ||
* | ||
* FilteredKeys<typeof x, number> is the type 'a' | 'c' | 53. | ||
* FilteredKeys<typeof x, string> is the type 'b'. | ||
* FilteredKeys<typeof x, 42 | 67> is the type 'c' | 53. | ||
* FilteredKeys<typeof x, boolean> is the type never. | ||
*/ | ||
export type FilteredKeys<T, U> = { | ||
[P in keyof T]: T[P] extends U ? P : never; | ||
}[keyof T]; | ||
type DataOnly<T> = Omit<T, FilteredKeys<T, Function>>; | ||
type FunctionOnly<T> = Pick<T, FilteredKeys<T, Function>> & | ||
(T extends Function ? (...args: Parameters<T>) => ReturnType<T> : {}); | ||
/** | ||
* `DataOnly<T>` means to return a record type `T2` consisting only of properties that are *not* functions. | ||
*/ | ||
export type DataOnly<T> = Omit<T, FilteredKeys<T, Callable>>; | ||
interface Remotable<T> { | ||
__Remote__: T; | ||
// Nominal type to carry the local and remote interfaces of a Remotable. | ||
export declare class RemotableBrand<L, R> { | ||
// The local properties of the object. | ||
private localProperties: L; | ||
// The type of all the remotely-callable functions. | ||
private remoteCallable: R; | ||
} | ||
type Remote<Primary, Local = DataOnly<Primary>> = ERef< | ||
Local & Remotable<Primary> | ||
/** | ||
* Creates a type that accepts both near and marshalled references that were | ||
* returned from `Remotable` or `Far`, and also promises for such references. | ||
*/ | ||
export type FarRef<Primary, Local = DataOnly<Primary>> = ERef< | ||
Local & RemotableBrand<Local, Primary> | ||
>; | ||
type Unpromise<T> = T extends ERef<infer U> ? U : T; | ||
type Parameters<T> = T extends (...args: infer T) => any ? T : any; | ||
type ReturnType<T> = T extends (...args: any[]) => infer T ? T : any; | ||
/** | ||
* `PickCallable<T>` means to return a single root callable or a record type | ||
* consisting only of properties that are functions. | ||
*/ | ||
export type PickCallable<T> = T extends Callable | ||
? (...args: Parameters<T>) => ReturnType<T> // a root callable, no methods | ||
: Pick<T, FilteredKeys<T, Callable>>; // any callable methods | ||
interface EHandler<T> { | ||
get?: (p: T, name: Property, returnedP?: Promise<unknown>) => any; | ||
getSendOnly?: (p: T, name: Property) => void; | ||
applyFunction?: (p: T, args: unknown[], returnedP?: Promise<unknown>) => any; | ||
/** | ||
* `RemoteFunctions<T>` means to return the functions and properties that are remotely callable. | ||
*/ | ||
export type RemoteFunctions<T> = T extends RemotableBrand<infer L, infer R> // if a given T is some remote interface R | ||
? PickCallable<R> // then use the function properties of R | ||
: Awaited<T> extends RemotableBrand<infer L, infer R> // otherwise, if the final resolution of T is some remote interface R | ||
? PickCallable<R> // then use the function properties of R | ||
: T extends PromiseLike<infer U> | ||
? Awaited<T> // otherwise, use the final resolution of that T | ||
: T; | ||
export type LocalRecord<T> = T extends RemotableBrand<infer L, infer R> | ||
? L | ||
: Awaited<T> extends RemotableBrand<infer L, infer R> | ||
? L | ||
: T extends PromiseLike<infer U> | ||
? Awaited<T> | ||
: T; | ||
export interface EHandler<T> { | ||
get?: (p: T, name: PropertyKey, returnedP?: Promise<unknown>) => unknown; | ||
getSendOnly?: (p: T, name: PropertyKey) => void; | ||
applyFunction?: ( | ||
p: T, | ||
args: unknown[], | ||
returnedP?: Promise<unknown>, | ||
) => unknown; | ||
applyFunctionSendOnly?: (p: T, args: unknown[]) => void; | ||
applyMethod?: ( | ||
p: T, | ||
name: Property | undefined, | ||
name: PropertyKey | undefined, | ||
args: unknown[], | ||
returnedP?: Promise<unknown>, | ||
) => any; | ||
) => unknown; | ||
applyMethodSendOnly?: ( | ||
p: T, | ||
name: Property | undefined, | ||
name: PropertyKey | undefined, | ||
args: unknown[], | ||
@@ -59,3 +131,11 @@ ) => void; | ||
type HandledExecutor<R> = ( | ||
export type ResolveWithPresenceOptionsBag<T extends Object> = { | ||
proxy?: { | ||
handler: ProxyHandler<T>; | ||
target: unknown; | ||
revokerCallback?: (revoker: () => void) => void; | ||
}; | ||
}; | ||
export type HandledExecutor<R> = ( | ||
resolveHandled: (value?: R) => void, | ||
@@ -69,13 +149,3 @@ rejectHandled: (reason?: unknown) => void, | ||
type ResolveWithPresenceOptionsBag<T extends Object> = { | ||
proxy?: { | ||
handler: ProxyHandler<T>; | ||
target: unknown; | ||
revokerCallback?: (revoker: () => void) => void; | ||
}; | ||
}; | ||
declare interface HandledPromiseStaticMethods { | ||
resolve<T>(x: T): Promise<Awaited<T>>; | ||
resolve(): Promise<undefined>; | ||
applyFunction(target: unknown, args: unknown[]): Promise<unknown>; | ||
@@ -85,11 +155,15 @@ applyFunctionSendOnly(target: unknown, args: unknown[]): void; | ||
target: unknown, | ||
prop: Property | undefined, | ||
prop: PropertyKey | undefined, | ||
args: unknown[], | ||
): Promise<unknown>; | ||
applyMethodSendOnly(target: unknown, prop: Property, args: unknown[]): void; | ||
get(target: unknown, prop: Property): Promise<unknown>; | ||
getSendOnly(target: unknown, prop: Property): void; | ||
applyMethodSendOnly( | ||
target: unknown, | ||
prop: PropertyKey, | ||
args: unknown[], | ||
): void; | ||
get(target: unknown, prop: PropertyKey): Promise<unknown>; | ||
getSendOnly(target: unknown, prop: PropertyKey): void; | ||
} | ||
declare interface HandledPromiseConstructor | ||
export interface HandledPromiseConstructor | ||
extends PromiseConstructor, | ||
@@ -104,39 +178,55 @@ HandledPromiseStaticMethods { | ||
declare var HandledPromise: HandledPromiseConstructor; | ||
declare namespace global { | ||
// eslint-disable-next-line vars-on-top,no-var | ||
var HandledPromise: HandledPromiseConstructor; | ||
} | ||
declare function makeHandledPromise(): HandledPromiseConstructor; | ||
export declare const HandledPromise: HandledPromiseConstructor; | ||
/** | ||
* "E" short for "Eventual", what we call something that has to return a promise. | ||
*/ | ||
type ECallable<T extends Callable> = ReturnType<T> extends PromiseLike<infer U> | ||
? T // function already returns a promise | ||
: (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>; // make it return a promise | ||
/* Types for E proxy calls. */ | ||
type ESingleMethod<T> = { | ||
readonly [P in keyof T]: ( | ||
...args: Parameters<T[P]> | ||
) => Promise<Awaited<ReturnType<T[P]>>>; | ||
/** | ||
* Transform each function in T to return a promise | ||
*/ | ||
type EMethods<T> = { | ||
readonly [P in keyof T]: T[P] extends Callable ? ECallable<T[P]> : never; | ||
}; | ||
type ESingleCall<T> = T extends Function | ||
? ((...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>) & | ||
ESingleMethod<Required<T>> | ||
: ESingleMethod<Required<T>>; | ||
type ESingleGet<T> = { | ||
readonly [P in keyof T]: Promise<Awaited<T[P]>>; | ||
type ECallableOrMethods<T> = T extends Callable | ||
? ECallable<T> & EMethods<Required<T>> | ||
: EMethods<Required<T>>; | ||
type EGetters<T> = { | ||
readonly [P in keyof T]: T[P] extends PromiseLike<infer U> | ||
? T[P] | ||
: Promise<Awaited<T[P]>>; | ||
}; | ||
/* Same types for send-only. */ | ||
type ESingleMethodOnly<T> = { | ||
readonly [P in keyof T]: (...args: Parameters<T[P]>) => void; | ||
type ESendOnlyCallable<T extends Callable> = ( | ||
...args: Parameters<T> | ||
) => Promise<void>; | ||
type ESendOnlyMethods<T> = { | ||
readonly [P in keyof T]: T[P] extends Callable | ||
? ESendOnlyCallable<T[P]> | ||
: never; | ||
}; | ||
type ESingleCallOnly<T> = T extends Function | ||
? ((...args: Parameters<T>) => void) & ESingleMethodOnly<T> | ||
: ESingleMethodOnly<T>; | ||
type ESingleGetOnly<T> = { | ||
readonly [P in keyof T]: void; | ||
}; | ||
type ESendOnlyCallableOrMethods<T> = T extends Callable | ||
? ESendOnlyCallable<T> & ESendOnlyMethods<Required<T>> | ||
: ESendOnlyMethods<Required<T>>; | ||
interface ESendOnly { | ||
<T>(x: T): ESingleCallOnly<Awaited<T>>; | ||
<T>(x: T): ESendOnlyCallableOrMethods<RemoteFunctions<T>>; | ||
} | ||
// Generic on the proxy target {T} | ||
interface EProxy { | ||
@@ -149,12 +239,6 @@ /** | ||
* | ||
* @param {*} x target for method/function call | ||
* @returns {ESingleCall} method/function call proxy | ||
* @param x target for method/function call | ||
* @returns method/function call proxy | ||
*/ | ||
<T>(x: T): ESingleCall< | ||
T extends Remotable<infer U> | ||
? FunctionOnly<U> | ||
: Awaited<T> extends Remotable<infer U> | ||
? FunctionOnly<U> | ||
: Awaited<T> | ||
>; | ||
<T>(x: T): ECallableOrMethods<RemoteFunctions<T>>; | ||
@@ -167,14 +251,6 @@ /** | ||
* | ||
* @param {*} x target for property get | ||
* @returns {ESingleGet} property get proxy | ||
* @param x target for property get | ||
* @returns property get proxy | ||
*/ | ||
readonly get: <T>( | ||
x: T, | ||
) => ESingleGet< | ||
T extends Remotable<infer U> | ||
? DataOnly<U> | ||
: Awaited<T> extends Remotable<infer U> | ||
? DataOnly<U> | ||
: Awaited<T> | ||
>; | ||
readonly get: <T>(x: T) => EGetters<LocalRecord<T>>; | ||
@@ -181,0 +257,0 @@ /** |
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
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
80726
14
1153
5