https://codesandbox.io/s/cool-jennings-if0m4?file=/src/index.js
/** @jsx createElement */
import { createElement, Copy } from "@bikeshaving/crank";
import { renderer } from "@bikeshaving/crank/dom";
async function* WTF() {
for await (const _ of this) {
yield <div>Hello</div>;
yield <Copy />;
}
}
Throws the error: Unknown tag: Symbol(crank.Copy).
Internal jargon: This means that Copy elements are being turned into HostNodes and the intrinsic function on the renderer is being called with the symbol. Need to figure out why this is happening.
If anyone wants to try and fix this I’m happy to pair via some medium to guide them along (requires some advanced promise lore). Might require some explanation of Crank internals I dunno. If not I’ll probably have a fix soon.
This issue is unrelated to async generators. It occurs for any function returning <Copy/> in the sandbox environment, e.g. https://codesandbox.io/s/happy-engelbart-eujqg?file=/src/index.js
Stepping through the render function in the sandbox revealed that the comparison if (tag !== Copy) always returns false. The variable tag evaluates to Symbol("Copy") in the debugger but doesn't have the same reference as the symbol constant.

I don't understand the in-browser build system well enough to find a solution but I'd guess it's related to how the source files are compiled in web workers and the final JS runs on the main thread. You might consider packaging an ES5 bundle for browser environments like this.
I couldn't reproduce this issue either in the local test environment or in a quick Create React App I threw together.
It's also worth noting that simply renderer.render(<Copy />, document.body) will produce the same error. In this case it might be worth failing with a more descriptive error, like "you can't use copy outside an element which has already rendered once. Or maybe exposing Copy exclusively to a re-rendered element via context, e.g.
function *MyComponent() {
yield <div />;
for (const { Copy } of this) {
return <Copy />;
}
}
Thanks for the example. Will investigate further.
@wmadden We may need to use something like Symbol.for then. Can you tell me which browser you’re using?
I'm using Chrome Version 81.0.4044.122 (Official Build) (64-bit).
Is it actually important that the magic tags like <Copy/> are symbols? It's kinda cool but it doesn't seem to offer any advantages, and it makes typing them impossible.
@wmadden Typing them being impossible is a TypeScript thing, which reminds me that we should open a TypeScript issue for allowing symbols for element tags so we don’t have to keep hacking around it. TypeScript’s symbol support is pretty lacking. React actually uses symbols as tags too (Fragment and Suspense are both symbols).
@brainkim can you elaborate on what you need that's missing from typescript?
@monodop Currently with JSX, the tag can only be a specified component class, a function, or a string. I need the typescript team to also allow symbols (a lot of JSX libraries do this already)
@brainkim's right, it's just a missing feature from TypeScript unfortunately. But @brainkim what's the value of using a Symbol instead of e.g. a function?
@wmadden This is how we distinguish intrinsic elements from component elements. Component elements are functions, while intrinsic elements are strings or symbols. Intrinsic elements are defined by the renderer, execute synchronously, and execute in a post-order walk of the rendered tree (what React would call the commit phase).
Understood.
In any case I think this issue is related exclusively to this sandbox environment, I can't see any way that it's possible for the symbol reference to be different in the renderer and the code that calls it and I couldn't reproduce it in any other environment.
As a quick proof of concept you could try replacing the symbol with a string to see if it solves the problem in the sandbox, since it'd be compared for equality rather than by reference. That would indicate the issue is to do with the sandbox's build system. But regardless I wouldn't say that's a good motivation to avoid using symbols for intrinsic tags.
I think this problem's probably not worth a lot of effort to solve for the time being unless it crops up in other environments. I only started looking at it cause it was labeled "good first issue" and I wanted to help 🤷‍♂️
@wmadden Yeah as it turns out I use Symbol.for for every symbol except for Copy woops. Dunno what’s going on with CodeSandbox dependencies but don’t have the time to debug it right now. Fix is on the way. Thanks for the help.
Fixed in 0.1.2