Skip to content

Commit cf10dc3

Browse files
committed
fix(api): remove many unnecessary methods
Remove the experimental E.C chaining proxy. Remove setting, deleting, has methods. Fixes #41
1 parent 8d10e1c commit cf10dc3

File tree

5 files changed

+39
-283
lines changed

5 files changed

+39
-283
lines changed

packages/eventual-send/src/E.js

+5-92
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
/* global globalThis window */
1+
/* global SES */
22
// eslint-disable-next-line spaced-comment
33
/// <reference path="index.d.ts" />
4-
// Shim globalThis when we don't have it.
5-
if (typeof globalThis === 'undefined') {
6-
const myGlobal = typeof window === 'undefined' ? global : window;
7-
myGlobal.globalThis = myGlobal;
8-
}
94

10-
const harden = (globalThis.SES && globalThis.SES.harden) || Object.freeze;
5+
const harden = (typeof SES !== 'undefined' && SES.harden) || Object.freeze;
116

127
const readOnlyProxy = {
138
set(_target, _prop, _value) {
@@ -57,103 +52,21 @@ function EProxyHandler(x, HandledPromise) {
5752
export default function makeE(HandledPromise) {
5853
function E(x) {
5954
const handler = EProxyHandler(x, HandledPromise);
60-
return harden(new Proxy({}, handler));
55+
return harden(new Proxy(() => {}, handler));
6156
}
6257

63-
const makeEGetterProxy = (x, wrap = o => o) =>
64-
new Proxy(Object.create(null), {
65-
...readOnlyProxy,
66-
has(_target, _prop) {
67-
return true;
68-
},
69-
get(_target, prop) {
70-
return wrap(HandledPromise.get(x, prop));
71-
},
72-
});
73-
74-
const makeEDeleterProxy = (x, wrap = o => o) =>
58+
const makeEGetterProxy = x =>
7559
new Proxy(Object.create(null), {
7660
...readOnlyProxy,
7761
has(_target, _prop) {
7862
return true;
7963
},
8064
get(_target, prop) {
81-
return wrap(HandledPromise.delete(x, prop));
82-
},
83-
});
84-
85-
const makeEHasProxy = (x, wrap = o => o) =>
86-
new Proxy(Object.create(null), {
87-
...readOnlyProxy,
88-
has(_target, _prop) {
89-
return true;
90-
},
91-
get(_target, prop) {
92-
return wrap(HandledPromise.has(x, prop));
93-
},
94-
});
95-
96-
const makeESetterProxy = (x, wrap = o => o) =>
97-
new Proxy(Object.create(null), {
98-
...readOnlyProxy,
99-
has(_target, _prop) {
100-
return true;
101-
},
102-
get(_target, prop) {
103-
return harden(value => wrap(HandledPromise.set(x, prop, value)));
104-
},
105-
});
106-
107-
const makeEMethodProxy = (x, wrap = o => o) =>
108-
new Proxy((..._args) => {}, {
109-
...readOnlyProxy,
110-
has(_target, _prop) {
111-
return true;
112-
},
113-
get(_target, prop) {
114-
return harden((...args) =>
115-
wrap(HandledPromise.applyMethod(x, prop, args)),
116-
);
117-
},
118-
apply(_target, _thisArg, args = []) {
119-
return wrap(HandledPromise.applyFunction(x, args));
65+
return HandledPromise.get(x, prop);
12066
},
12167
});
12268

12369
E.G = o => makeEGetterProxy(o);
124-
E.H = o => makeEHasProxy(o);
125-
E.D = o => makeEDeleterProxy(o);
126-
E.S = o => makeESetterProxy(o);
127-
E.M = o => makeEMethodProxy(o);
128-
129-
const EChain = x =>
130-
harden({
131-
get G() {
132-
// Return getter.
133-
return makeEGetterProxy(x, EChain);
134-
},
135-
get D() {
136-
// Return deleter.
137-
return makeEDeleterProxy(x, EChain);
138-
},
139-
get H() {
140-
// Return has.
141-
return makeEHasProxy(x, EChain);
142-
},
143-
get S() {
144-
// Return setter.
145-
return makeESetterProxy(x, EChain);
146-
},
147-
get M() {
148-
// Return method-caller.
149-
return makeEMethodProxy(x, EChain);
150-
},
151-
get P() {
152-
// Return as promise.
153-
return Promise.resolve(x);
154-
},
155-
});
15670

157-
E.C = EChain;
15871
return harden(E);
15972
}

packages/eventual-send/src/index.d.ts

+14-46
Original file line numberDiff line numberDiff line change
@@ -21,47 +21,13 @@ interface HandledPromiseConstructor {
2121

2222
declare const HandledPromise: HandledPromiseConstructor;
2323

24-
interface ESingleMethod<U> {
25-
[prop: Property]: (...args) => U;
24+
interface ESingleMethod {
25+
(...args: unknown[]): Promise<unknown>;
26+
[prop: Property]: (...args) => Promise<unknown>;
2627
}
2728

28-
interface EChain<T = unknown> {
29-
M: EChainMethod<EChain<T>>;
30-
G: EChainGet<EChain<T>>;
31-
S: EChainSet<EChain<T>>;
32-
D: EChainDelete<EChain<boolean>>;
33-
P: Promise<T>;
34-
sendOnly: EChainSendOnly;
35-
}
36-
37-
interface EChainSendOnly {
38-
M: EChainMethod<void>;
39-
G: EChainGet<void>;
40-
S: EChainSet<void>;
41-
D: EChainDelete<void>;
42-
}
43-
44-
interface EChainMethod<U> {
45-
(...args: unknown[]): U;
46-
[prop: Property]: (...args: unknown) => U;
47-
}
48-
49-
interface EChainGet<U> {
50-
[prop: Property]: U;
51-
}
52-
53-
interface EChainSet<U> {
54-
/**
55-
* Eventually set the prop property.
56-
*/
57-
[prop: Property]: (value: unknown) => U;
58-
}
59-
60-
interface EChainDelete<U> {
61-
/**
62-
* Eventually delete the prop property.
63-
*/
64-
[prop: Property]: U is void ? U : EChain<boolean>;
29+
interface ESingleGet {
30+
[prop: Property]: Promise<unknown>;
6531
}
6632

6733
interface EProxy {
@@ -74,16 +40,18 @@ interface EProxy {
7440
* @param {*} x target for method call
7541
* @returns {ESingleMethod} method call proxy
7642
*/
77-
(x: unknown): ESingleMethod<Promise<unknown>>;
78-
sendOnly: (x: unknown) => ESingleMethod<void>;
43+
(x: unknown): ESingleMethod;
44+
sendOnly: (x: unknown) => ESingleMethod;
7945
/**
80-
* E.C(x) returns a chain where operations are selected by
81-
* uppercase single-letter selectors.
46+
* E.G(x) returns a proxy on which you can get arbitrary properties.
47+
* Each of these properties returns a promise. The property will be
48+
* taken from whatever 'x' designates (or resolves to) in a future turn,
49+
* not this one.
8250
*
83-
* @param {*} x target for first operation
84-
* @returns {EChain}
51+
* @param {*} x target for property get
52+
* @returns {ESingleGet} property get proxy
8553
*/
86-
C(x: unknown): EChain;
54+
G(x: unknown): ESingleGet;
8755
}
8856

8957
export const E: EProxy;

packages/eventual-send/src/index.js

+17-45
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* global globalThis */
1+
/* global HandledPromise SES globalThis window */
22

33
import makeE from './E';
44

@@ -8,18 +8,27 @@ import makeE from './E';
88
// import { HandledPromise, E } from '@agoric/eventual-send';
99
// ...
1010

11-
// TODO: Maybe rename the global HandledPromise to something only the tildot rewriter uses.
12-
if (!globalThis.HandledPromise) {
11+
// eslint-disable-next-line import/no-mutable-exports
12+
let hp;
13+
if (typeof HandledPromise === 'undefined') {
1314
/* eslint-disable no-use-before-define */
15+
if (typeof globalThis === 'undefined') {
16+
const myGlobal = typeof window === 'undefined' ? global : window;
17+
myGlobal.globalThis = window;
18+
}
19+
1420
// Install the shim as best we can.
1521
maybeExtendPromise(Promise);
1622
globalThis.HandledPromise = makeHandledPromise(Promise);
23+
hp = globalThis.HandledPromise;
1724
/* eslint-enable no-use-before-define */
25+
} else {
26+
hp = HandledPromise;
1827
}
1928

2029
// Provide a handled platform Promise if SES has not run.
21-
export const { HandledPromise } = globalThis;
22-
export const E = makeE(HandledPromise);
30+
export { hp as HandledPromise };
31+
export const E = makeE(hp);
2332

2433
// the following methods (makeHandledPromise and maybeExtendPromise) are part
2534
// of the shim, and will not be exported by the module once the feature
@@ -28,36 +37,17 @@ export const E = makeE(HandledPromise);
2837
// Create HandledPromise static methods as a bridge from v0.2.4
2938
// to new proposal support (wavy dot's infrastructure).
3039
export function makeHandledPromise(EPromise) {
31-
const harden = (globalThis.SES && globalThis.SES.harden) || Object.freeze;
40+
const harden = (typeof SES !== 'undefined' && SES.harden) || Object.freeze;
3241

33-
// TODO: Use HandledPromise.resolve to store our weakmap, and
34-
// install it on Promise.resolve.
42+
// TODO: Use HandledPromise.resolve to store our weakmap, instead of
43+
// monkey-patching Promise.resolve.
3544
const staticMethods = {
3645
get(target, key) {
3746
return EPromise.resolve(target).get(key);
3847
},
3948
getSendOnly(target, key) {
4049
EPromise.resolve(target).get(key);
4150
},
42-
has(target, key) {
43-
return EPromise.resolve(target).has(key);
44-
},
45-
hasSendOnly(target, key) {
46-
EPromise.resolve(target).has(key);
47-
},
48-
set(target, key, val) {
49-
return EPromise.resolve(target).put(key, val);
50-
},
51-
setSendOnly(target, key, val) {
52-
EPromise.resolve(target).put(key, val);
53-
},
54-
// TODO: Change HandledPromise.delete to HandledPromise.deleteProperty
55-
delete(target, key) {
56-
return EPromise.resolve(target).delete(key);
57-
},
58-
deleteSendOnly(target, key) {
59-
EPromise.resolve(target).delete(key);
60-
},
6151
applyFunction(target, args) {
6252
return EPromise.resolve(target).post(undefined, args);
6353
},
@@ -161,18 +151,6 @@ export function maybeExtendPromise(Promise) {
161151
return handle(this, 'GET', key);
162152
},
163153

164-
has(key) {
165-
return handle(this, 'HAS', key);
166-
},
167-
168-
put(key, val) {
169-
return handle(this, 'PUT', key, val);
170-
},
171-
172-
delete(key) {
173-
return handle(this, 'DELETE', key);
174-
},
175-
176154
post(optKey, args) {
177155
return handle(this, 'POST', optKey, args);
178156
},
@@ -261,9 +239,6 @@ export function maybeExtendPromise(Promise) {
261239

262240
unfulfilledHandler = {
263241
GET: makePostponed('get'),
264-
HAS: makePostponed('has'),
265-
PUT: makePostponed('put'),
266-
DELETE: makePostponed('delete'),
267242
POST: makePostponed('post'),
268243
};
269244
}
@@ -391,9 +366,6 @@ export function maybeExtendPromise(Promise) {
391366

392367
forwardingHandler = {
393368
GET: makeForwarder('GET', (o, key) => o[key]),
394-
HAS: makeForwarder('HAS', (o, key) => key in o),
395-
PUT: makeForwarder('PUT', (o, key, val) => (o[key] = val)),
396-
DELETE: makeForwarder('DELETE', (o, key) => delete o[key]),
397369
POST: makeForwarder('POST', (o, optKey, args) => {
398370
if (optKey === undefined || optKey === null) {
399371
return o(...args);

packages/eventual-send/test/test-e.js

+3-46
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ test('E method calls', async t => {
1818
}
1919
});
2020

21-
test('E.* shortcuts', async t => {
21+
test('E shortcuts', async t => {
2222
try {
2323
const x = {
2424
name: 'buddy',
@@ -32,56 +32,13 @@ test('E.* shortcuts', async t => {
3232
return `${greeting}, ${this.name}!`;
3333
},
3434
};
35-
t.equal(await E.M(x).hello('Hello'), 'Hello, buddy!', 'method call works');
35+
t.equal(await E(x).hello('Hello'), 'Hello, buddy!', 'method call works');
3636
t.equal(
37-
await E.M(await E.G(await E.G(x).y).fn)(4),
37+
await E(await E.G(await E.G(x).y).fn)(4),
3838
8,
3939
'anonymous method works',
4040
);
4141
t.equal(await E.G(x).val, 123, 'property get');
42-
t.equal(await E.S(x).val(999), 999, 'property set');
43-
t.equal(x.val, 999, 'property set works');
44-
t.equal(await E.D(x).val, true, 'property delete');
45-
t.equal(x.val, undefined, 'delete worked');
46-
await t.rejects(
47-
E.D(await E.G(x).y).val2,
48-
TypeError,
49-
'property delete fails',
50-
);
51-
t.equal(x.y.val2, 456, 'delete failed');
52-
} catch (e) {
53-
t.isNot(e, e, 'unexpected exception');
54-
} finally {
55-
t.end();
56-
}
57-
});
58-
59-
test('E.C chains', async t => {
60-
try {
61-
const x = {
62-
name: 'buddy',
63-
val: 123,
64-
y: Object.freeze({
65-
val2: 456,
66-
name2: 'holly',
67-
fn: n => 2 * n,
68-
}),
69-
hello(greeting) {
70-
return `${greeting}, ${this.name}!`;
71-
},
72-
};
73-
const xC = E.C(x);
74-
t.equal(await xC.M.hello('Hello').P, 'Hello, buddy!', 'method call works');
75-
t.equal(await xC.G.y.G.fn.M(4).P, 8, 'anonymous method works');
76-
t.equal(await xC.G.val.P, 123, 'property get');
77-
t.equal(await xC.S.val(999).P, 999, 'property set');
78-
t.equal(await xC.H.val.P, true, 'property has');
79-
t.equal(await xC.H.notval.P, false, 'missing property has not');
80-
t.equal(x.val, 999, 'property set works');
81-
t.equal(await xC.D.val.P, true, 'property delete');
82-
t.equal(x.val, undefined, 'delete worked');
83-
await t.rejects(xC.G.y.D.val2.P, TypeError, 'property delete fails');
84-
t.equal(x.y.val2, 456, 'delete failed');
8542
} catch (e) {
8643
t.isNot(e, e, 'unexpected exception');
8744
} finally {

0 commit comments

Comments
 (0)