-
Notifications
You must be signed in to change notification settings - Fork 75
Description
I implemented a proxy object (source) called shape to build SVG elements, such as:
const svg = shape.svg({width: 100, height: 100}, [
shape.rect({x: 0, y: 0, height: 100, width: 100, fill: "black"}),
shape.circle({cx: 50, cy: 50, r: 40, fill: "white"}),
]);
document.body.append(svg);
A simple implementation is as follows:
shape = new Proxy({}, {get: (_, name) => () => document.createElement("name")})
But it threw an error when I defined it at the top-level:

I found that it automatically called shape.then, shape.next and shape.return. After reading the source code, I discovered actual issue: the runtime can't handle thenable and generatorish variable as expected, especially when they have function attributes:

The generatorish issue is easy to solve relatively with a stricter check in generatorish.js:
export function generatorish(value) {
if (!value) return false;
const tag = value[Symbol.toStringTag];
return tag === "Generator" || tag === "AsyncGenerator";
}
If "generatorish" is required, it is also possible to make it work with proxies like shape:
export function generatorish(value) {
return value
&& 'next' in value && typeof value.next === "function"
&& 'return' in value && typeof value.return === "function";
}
However the thenable issue is not as easy to solve, because runtime use promises to wrap the value:
// https://github.com/observablehq/runtime/blob/622a1974087f03545b5e91c8625b46874e82e4df/src/runtime.js#L231
variable._promise = variable._promise
.then(init, init)
// This will return a promise that never resolves,
// because the return value has a "then" attribute,
// which is a function but does not call resolve.
.then(define)
.then(generate);
function define(inputs) {
// ....
return definition.apply(value0, inputs); // Returns the value itself.
}
I made som attempts but failed. Before going further, I just want to confirm if I'm on the right track:
- Are these real issues? I didn't find any docs or tests that shows runtime supports thenable and generatorish variable (if I missed them, please let me know!). I think they should act like normal variables.
- If they are real issues, is fixing them necessary? This seems like a rare situation.
If they are real issues and should be fixed, I'm willing to open a PR to address them! If not, I'd love to hear suggestions to make shape compatible with Notebook. While I can modify the source code of shape to filter then, next, and return, I'd prefer not to do this solely for Notebook!
Anyway, thanks for the great work of Notebook!