Open evoactivity opened 2 months ago
Is the template supposed to have access to things on the proxy?
Which 'this' should refer to in a static initializer block?
Is the template supposed to have access to things on the proxy?
Not really, but I don't think it matters all that much.
Which 'this' should refer to in a static initializer block?
The static block is part of the component definition.
// this example is not from my repro repo, but it's easier to grab
// the compiled source for a component from a vite enabled app
import { tracked } from "/node_modules/.vite/deps/@glimmer_tracking.js?v=d293af4a";
import { job, thing, that } from "/app/components/styles.module.css";
import { on } from "/node_modules/.vite/deps/ember-source_@ember_modifier_index__js.js?v=d293af4a";
import { setComponentTemplate } from "/node_modules/.vite/deps/ember-source_@ember_component_index__js.js?v=d293af4a";
import { createTemplateFactory } from "/node_modules/.vite/deps/ember-source_@ember_template-factory_index__js.js?v=d293af4a";
let template__imports__ = null;
template__imports__ = new class _Imports {
static {
dt7948.g(this.prototype, "on", [tracked], function () {
return on;
});
}
#on = (dt7948.i(this, "on"), void 0);
}()
const concat = (...args1) => args1.join(" ");
let MyComponent = class MyComponent extends Component {
static {
dt7948.g(this.prototype, "count", [tracked], function () {
return 0;
});
}
#count = (dt7948.i(this, "count"), void 0);
classList = concat(job, thing, that);
thing = 2;
handleClick = () => {
this.count += 1;
this.thing += 1;
};
static {
setComponentTemplate(createTemplateFactory(
/*
<div class={{this.classList}}>
<h1>Tests {{this.count}}</h1>
<button type="button" {{on "click" this.handleClick}}>Click me</button>
</div>
*/
{
"id": "Hg3FL3Xg",
"block": "[[[1,\"\\n \"],[10,0],[15,0,[30,0,[\"classList\"]]],[12],[1,\"\\n \"],[10,\"h1\"],[12],[1,\"Tests \"],[1,[30,0,[\"count\"]]],[13],[1,\"\\n \"],[11,\"button\"],[24,4,\"button\"],[4,[32,0,[\"on\"]],[\"click\",[30,0,[\"handleClick\"]]],null],[12],[1,\"Click me\"],[13],[1,\"\\n \"],[13],[1,\"\\n \"]],[],false,[]]",
"moduleName": "/Users/liam/Work/ember-vite/my-fancy-app/app/components/my-component.gjs",
"scope": () => [template__imports__],
"isStrictMode": true
}), this);
}
};
const ___ProxyClass = new Proxy(MyComponent, {
// my stuff here
});
export default ___ProxyClass;
It looks like you need to proxy or set the prototype on your resulting proxied thing.
Tho, why proxy at all?
Because proxying will be the most ergonamic way (that I can think of) to augment state persistence for components with hot module replacement. Can simply inject the proxy at the end of the file as part of the build process without needing to rewrite the component definition, just need to rewrite the default export.
Ah i see, that's a reasonable low level thing to want these for.
So, i think we may just need to tweak the object returned from proxy so that the prototype is the same as the class.
And then, if you're storing state in the proxy, i need to think on that for a bit
State has to be stored externally to the module itself, since HMR will rebuild the whole thing and reload it will all get thrown away if stored locally.
You can see my current implementation here, it's just defined in the component file whilst I poke around to see what works, before I attempt to do anything babel/vite transform related.
With a co-located component it's possible to proxy the component and everything works as it should.
When using a template tag, the template fails to render, no errors are logged.
In the generated code for the colocated component the setComponentTemplate is applied to the proxy.
This doesn't appear to be the case for a template tag component.
Reproduction repo https://github.com/evoactivity/ember-proxy-template-tag/