Skip to content

Commit

Permalink
Relax args validation, and remove getOwner requirement (#2)
Browse files Browse the repository at this point in the history
The previous args validation was too strict, and did not permit passing proxies like `this.args`. With this relaxation, the full set of parent component args can now be easily passed down to the child.

Passing an empty object as the owner for `curry()` seems to work ok, and matches [usage in `glimmer-vm`](https://github.com/glimmerjs/glimmer-vm/blob/5507a1febc/packages/%40glimmer-workspace/integration-tests/lib/modes/jit/register.ts#L171). So we can drop the awkward `getOwner()` requirement.
  • Loading branch information
davidtaylorhq authored Jan 30, 2025
1 parent 1d99db7 commit 49290a6
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 107 deletions.
37 changes: 19 additions & 18 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,24 @@ jobs:
- name: Run Tests
run: pnpm test

floating:
name: "Floating Dependencies"
runs-on: ubuntu-latest
timeout-minutes: 10
# floating:
# name: "Floating Dependencies"
# runs-on: ubuntu-latest
# timeout-minutes: 10

steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- name: Install Dependencies
run: pnpm install --no-lockfile
- name: Run Tests
run: pnpm test
# steps:
# - uses: actions/checkout@v4
# - uses: pnpm/action-setup@v3
# with:
# version: 9
# - uses: actions/setup-node@v4
# with:
# node-version: 22
# cache: pnpm
# - name: Install Dependencies
# run: pnpm install --no-lockfile
# - name: Run Tests
# run: pnpm test

try-scenarios:
name: ${{ matrix.try-scenario }}
Expand All @@ -64,11 +64,12 @@ jobs:
try-scenario:
- ember-lts-4.12
- ember-lts-5.4
- ember-lts-5.12
- ember-release
- ember-beta
- ember-canary
- embroider-safe
- embroider-optimized
# - embroider-optimized

steps:
- uses: actions/checkout@v4
Expand Down
15 changes: 6 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ ember install ember-curry-component

```gjs
import Component from "@glimmer/component";
import { getOwner } from "@ember/owner";
import curryComponent from "ember-curry-component";
import SomeOtherComponent from "./some-other-component";
Expand All @@ -23,7 +22,7 @@ class MyComponent extends Component {
const args = {
name: "David"
};
return curryComponent(SomeOtherComponent, args, getOwner(this))
return curryComponent(SomeOtherComponent, args)
}
<template>
Expand All @@ -36,7 +35,6 @@ class MyComponent extends Component {

```gjs
import Component from "@glimmer/component";
import { getOwner } from "@ember/owner";
import curryComponent from "ember-curry-component";
import SomeOtherComponent from "./some-other-component";
Expand All @@ -50,7 +48,7 @@ class MyComponent extends Component {
return instance.name;
}
};
return curryComponent(SomeOtherComponent, args, getOwner(this));
return curryComponent(SomeOtherComponent, args);
}
<template>
Expand All @@ -64,7 +62,6 @@ When `this.name` is reassigned, the `@name` argument on the curried component wi

```gjs
import Component from "@glimmer/component";
import { getOwner } from "@ember/owner";
import curryComponent from "ember-curry-component";
import SomeOtherComponent from "./some-other-component";
Expand All @@ -75,7 +72,7 @@ class MyComponent extends Component {
const args = {
name: this.name
};
return curryComponent(SomeOtherComponent, args, getOwner(this));
return curryComponent(SomeOtherComponent, args);
}
<template>
Expand All @@ -87,7 +84,7 @@ When `this.name` is reassigned, the `curriedComponent` getter will be invalidate

### As a helper

In `.gjs`/`.gjs` files, the curryComponent helper can be used directly in a template. In this case, the owner does not need to be passed explicitly.
In `.gjs`/`.gjs` files, the curryComponent helper can be used directly in a template.

```gjs
import SomeOtherComponent from "./some-other-component";
Expand All @@ -107,13 +104,13 @@ In `<template>`, curried components cannot be rendered from the local scope. Thi

```gjs
// Do not copy!
const curried = curryComponent(MyComponent, args, owner)
const curried = curryComponent(MyComponent, args)
<template><curried /></template>
```
You must wrap the invocation in `{{#let}}` instead:
```gjs
// Do not copy!
const curried = curryComponent(MyComponent, args, owner)
const curried = curryComponent(MyComponent, args)
<template>
{{#let curried as |myComponent|}}
<myComponent />
Expand Down
2 changes: 1 addition & 1 deletion ember-curry-component/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ember-curry-component",
"version": "0.1.0",
"version": "0.2.0",
"description": "Like Ember's builtin `(component)` helper, but with dynamic arguments, and JS compatibility",
"keywords": [
"ember-addon"
Expand Down
26 changes: 11 additions & 15 deletions ember-curry-component/src/index.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,28 @@
import { createComputeRef, createConstRef } from '@glimmer/reference';
import { createComputeRef } from '@glimmer/reference';
import { createCapturedArgs, curry, EMPTY_POSITIONAL } from '@glimmer/runtime';
import { dict } from '@glimmer/util';
import * as vm from '@glimmer/vm';

// CurriedType only made available in vm from Ember 5.6.0. Fallback to hardcoded value.
const ComponentCurriedType = vm.CurriedType?.Component || 0;

export default function curryComponent(componentKlass, namedArgs, owner) {
/**
* Curry a component with named arguments.
*
* @param {Component} componentKlass - The component class to curry
* @param {Object} namedArgs - Named arguments to curry the component with. The set of keys must be static, but the values can be dynamic (e.g. getters, or a Proxy)
*/
export default function curryComponent(componentKlass, namedArgs) {
let namedDict = dict();

if (!(typeof namedArgs === 'object' && namedArgs.constructor === Object)) {
throw 'Named arguments must be a simple object';
}

for (const [key, descriptor] of Object.entries(
Object.getOwnPropertyDescriptors(namedArgs),
)) {
if (descriptor.get) {
namedDict[key] = createComputeRef(() => namedArgs[key]);
} else {
namedDict[key] = createConstRef(namedArgs[key]);
}
for (const key of Object.keys(namedArgs)) {
namedDict[key] = createComputeRef(() => namedArgs[key]);
}

return curry(
ComponentCurriedType,
componentKlass,
owner,
{},
createCapturedArgs(namedDict, EMPTY_POSITIONAL),
false,
);
Expand Down
18 changes: 18 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions test-app/config/ember-try.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ module.exports = async function () {
},
},
},
{
name: "ember-lts-5.12",
npm: {
devDependencies: {
"ember-source": "~5.12.0",
},
},
},
{
name: "ember-release",
npm: {
Expand Down
3 changes: 3 additions & 0 deletions test-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,8 @@
},
"ember": {
"edition": "octane"
},
"dependencies": {
"ember-async-data": "^1.0.3"
}
}
Loading

0 comments on commit 49290a6

Please sign in to comment.