Skip to content

Commit

Permalink
Merge pull request #144 from NullVoxPopuli/additional-utilities
Browse files Browse the repository at this point in the history
Introduce useHelper, update automation blueprint
  • Loading branch information
NullVoxPopuli authored Aug 29, 2021
2 parents c823ffc + c5c8669 commit dc638ac
Show file tree
Hide file tree
Showing 14 changed files with 424 additions and 34 deletions.
24 changes: 22 additions & 2 deletions .github/renovate.json5
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,16 @@
],
"automerge": true,
"masterIssue": true,
"rangeStrategy": "bump",
// bump for apps
// update-lockfile for addons/libraries
"rangeStrategy": "update-lockfile",
// From the docs:
// https://docs.renovatebot.com/configuration-options/#packagerules
// Important to know: Renovate will evaluate all packageRules and not stop once it gets a first match.
// Therefore, you should order your packageRules in order of importance so that later rules can override
// settings from earlier rules if necessary.
//
// (so if something is to be disabled, place that rule last)
"packageRules": [
////////////////////////////////////////
// Grouping namespaced packages together
Expand All @@ -17,7 +26,13 @@
{
"groupName": "Type Definitions",
"packagePatterns": ["^@types\/*"],
"schedule": ["after 9pm on sunday"],
"schedule": ["after 9pm on sunday"]
},
// This library needs to be bumped, because otherwise we would not
// receive blueprint updates whenever a release occurs
{
"packageNames": ["ember-addon-automated-ci"],
"rangeStrategy": "bump"
},
{
"groupName": "Lint Dependencies",
Expand Down Expand Up @@ -76,6 +91,11 @@
"qunit",
"npm-run-all"
]
},
{
// changing peerDependencies *at all* is a breaking change
"matchDepTypes": ["peerDependencies"],
"enabled": false
}
]
}
8 changes: 6 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,15 @@ jobs:
run: node_modules/.bin/ember try:one ${{ matrix.ember-try-scenario }} --skip-cleanup

ember-cli-update:
if: github.event_name == 'pull_request' && github.event.pusher.name == 'renovate-bot'
if: "github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && ( ! contains(toJSON(github.event.commits.*.message), '[skip ci]') )"
runs-on: ubuntu-latest
needs: [tests, try-scenarios]

steps:
- uses: actions/checkout@v2
with:
ref: ${{ github.head_ref }}
token: ${{ secrets.GitHubToken }}
token: ${{ secrets.ECU_TOKEN }}
- uses: actions/setup-node@v2
- uses: kellyselden/ember-cli-update-action@v3
with:
Expand All @@ -111,6 +111,10 @@ jobs:
with:
persist-credentials: false
- uses: volta-cli/action@v1
- uses: actions/cache@v2
with:
path: '**/node_modules'
key: ${{ runner.os }}-modules-${{ hashFiles('**/package-lock.json') }}
- run: npm install

- name: Release
Expand Down
5 changes: 1 addition & 4 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
name: Lint

# based on:
# - https://github.com/NullVoxPopuli/eslint-plugin-decorator-position/blob/master/.github/workflows/lint.yml
# - https://github.com/NullVoxPopuli/ember-autostash-modifier/blob/master/.github/workflows/ci.yml
# - https://github.com/emberjs/ember-test-helpers/blob/master/.github/workflows/ci-build.yml
on:
pull_request:
push:
# filtering branches here prevents duplicate builds from pull_request and push
branches:
- main
- master

env:
CI: true
Expand Down
43 changes: 29 additions & 14 deletions .github/workflows/types.yml
Original file line number Diff line number Diff line change
@@ -1,31 +1,46 @@
name: Types

# based on:
# - https://github.com/NullVoxPopuli/eslint-plugin-decorator-position/blob/master/.github/workflows/lint.yml
# - https://github.com/NullVoxPopuli/ember-autostash-modifier/blob/master/.github/workflows/ci.yml
# - https://github.com/emberjs/ember-test-helpers/blob/master/.github/workflows/ci-build.yml
name: "Types"
on:
pull_request:
push:
# filtering branches here prevents duplicate builds from pull_request and push
branches:
- main
- master

env:
CI: true

jobs:
types:
install_dependencies:
if: "! contains(toJSON(github.event.commits.*.message), '[skip ci]')"
name: Type Checking
name: Install Dependencies
runs-on: ubuntu-latest
timeout-minutes: 15

steps:
- uses: actions/checkout@v2
- uses: volta-cli/action@v1
- uses: actions/checkout@v2
- uses: volta-cli/action@v1
- uses: actions/cache@v2
with:
path: '**/node_modules'
key: ${{ runner.os }}-modules-${{ hashFiles('**/package-lock.json') }}
- run: npm install

- run: npm install
types:
if: "! contains(toJSON(github.event.commits.*.message), '[skip ci]')"
name: "Type Correctness"
runs-on: ubuntu-latest
timeout-minutes: 5
needs: [install_dependencies]

- name: Type Checking
# run: yarn tsc --build
run: npm run prepack
steps:
- uses: actions/checkout@v2
- uses: volta-cli/action@v1
- uses: actions/cache@v2
with:
path: '**/node_modules'
key: ${{ runner.os }}-modules-${{ hashFiles('**/package-lock.json') }}
- run: npm run prepack
# - run: yarn tsc --build
# - run: npm run prepack
# - run: npm exec tsc --build
85 changes: 85 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ An implementation of Resources in Ember.JS without decorators.
- [LifecycleResource](#lifecycleresource)
- [Functions](#function-resources)
- [Thunks](#thunks)
- [Composition](#composition)
- [Public Types](#public-types)
- [Testing](#testing)
- [Contributing](#contributing)
Expand Down Expand Up @@ -424,6 +425,90 @@ when an object is passed containing either keys: `named` or `positional`:
This is the same shape of args used throughout Ember's Helpers, Modifiers, etc
### Composition
These patterns are primarily unexplored so if you run in to any issues,
please [open a bug report / issue](https://github.com/NullVoxPopuli/ember-resources/issues/new).
Composing class-based resources is expected to "just work", as classes maintain their own state.
#### useFunction + useFunction
```js
import Component from '@glimmer/component';
import { useFunction } from 'ember-resources';

class MyComponent extends Component {
rand = useFunction(this, () => {
return useFunction(this, () => Math.random());
});
}
```
Accessing the result of `Math.random()` would be done via:
```hbs
{{this.rand.value.value}}
```
Something to note about composing resources is that if arguments passed to the
outer resource change, the inner resources are discarded entirely.
For example, you'll need to manage the inner resource's cache invalidation yourself if you want
the inner resource's behavior to be reactive based on outer arguments:
<details><summary>Example data fetching composed functions</summary>
```js
import Component from '@glimmer/component';
import { useFunction } from 'ember-resources';

class MyComponent extends Component {
@tracked id = 1;
@tracked storeName = 'blogs';

records = useFunction(this, (state, storeName) => {
let result: Array<string | undefined> = [];

if (state?.previous?.storeName === storeName) {
return state.previous.innerFunction;
}

let innerFunction = useFunction(this, (prev, id) => {
// pretend we fetched a record using the store service
let newValue = `record:${storeName}-${id}`;

result = [...(prev || []), newValue];

return result;
},
() => [this.id]
);

return new Proxy(innerFunction, {
get(target, key, receiver) {
if (key === 'previous') {
return {
innerFunction,
storeName,
};
}

return Reflect.get(target, key, receiver);
},
});
},
() => [this.storeName]
);
}
```
```hbs
{{this.records.value.value}} -- an array of "records"
```
</details>
## Public Types
Expand Down
10 changes: 5 additions & 5 deletions addon/-private/use-function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ type UseFunctionArgs<Return, Args extends unknown[]> =
* @param {Object} destroyable context, e.g.: component instance aka "this"
* @param {Function} theFunction the function to run with the return value available on .value
*/
export function useFunction<Return, Args extends unknown[]>(
export function useFunction<Return, Args extends unknown[] = unknown[]>(
...passed: NonReactiveVanilla<Return, Args>
): { value: Return };
/**
Expand All @@ -55,7 +55,7 @@ export function useFunction<Return, Args extends unknown[]>(
* @param {Function} theFunction the function to run with the return value available on .value
* @param {Function} thunk to generate / bind tracked data to the function so that the function can re-run when the tracked data updates
*/
export function useFunction<Return, Args extends unknown[]>(
export function useFunction<Return, Args extends unknown[] = unknown[]>(
...passed: VanillaArgs<Return, Args>
): { value: Return };
/**
Expand All @@ -67,7 +67,7 @@ export function useFunction<Return, Args extends unknown[]>(
* @param {Function} theFunction the function to run with the return value available on .value
* @param {Function} thunk to generate / bind tracked data to the function so that the function can re-run when the tracked data updates
*/
export function useFunction<Return, Args extends unknown[]>(
export function useFunction<Return, Args extends unknown[] = unknown[]>(
...passed: WithInitialValueArgs<Return, Args>
): { value: Return };
/**
Expand All @@ -78,11 +78,11 @@ export function useFunction<Return, Args extends unknown[]>(
* @param {Object} initialValue - a non-function that matches the shape of the eventual return value of theFunction
* @param {Function} theFunction the function to run with the return value available on .value
*/
export function useFunction<Return, Args extends unknown[]>(
export function useFunction<Return, Args extends unknown[] = unknown[]>(
...passed: NonReactiveWithInitialValue<Return, Args>
): { value: Return };

export function useFunction<Return, Args extends unknown[]>(
export function useFunction<Return, Args extends unknown[] = unknown[]>(
...passedArgs: UseFunctionArgs<Return, Args>
): { value: Return } {
let [context] = passedArgs;
Expand Down
35 changes: 35 additions & 0 deletions addon/-private/use-helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* eslint-disable @typescript-eslint/ban-types */
// typed-ember has not publihsed types for this yet
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { getValue } from '@glimmer/tracking/primitives/cache';
// typed-ember has not publihsed types for this yet
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { invokeHelper } from '@ember/helper';

import { DEFAULT_THUNK, normalizeThunk } from './utils';

import type { Cache, Thunk } from './types';
import type { helper as emberFunctionHelper } from '@ember/component/helper';
import type Helper from '@ember/component/helper';

export function useHelper(
context: object,
helper: Helper | ReturnType<typeof emberFunctionHelper>,
thunk: Thunk = DEFAULT_THUNK
) {
let resource: Cache<unknown>;

return {
get value(): unknown {
if (!resource) {
resource = invokeHelper(context, helper, () => {
return normalizeThunk(thunk);
}) as Cache<unknown>;
}

return getValue<unknown>(resource)!; // eslint-disable-line
},
};
}
1 change: 1 addition & 0 deletions addon/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export { Resource } from './-private/resources/simple';
// Public API -- for reducing consumed API surface
export { useTask } from './-private/ember-concurrency';
export { useFunction } from './-private/use-function';
export { useHelper } from './-private/use-helper';
export { useResource } from './-private/use-resource';

// Public Type Utilities
Expand Down
21 changes: 16 additions & 5 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"@typescript-eslint/parser": "^4.29.3",
"babel-eslint": "^10.1.0",
"broccoli-asset-rev": "^3.0.0",
"ember-addon-automated-ci": "^2.1.0",
"ember-auto-import": "^2.1.0",
"ember-cli": "~3.28.0",
"ember-cli-app-version": "^5.0.0",
Expand Down
Loading

0 comments on commit dc638ac

Please sign in to comment.