Skip to content

Commit

Permalink
Convert helpers to .ts and expose their types (#559)
Browse files Browse the repository at this point in the history
  • Loading branch information
machty authored Feb 6, 2024
1 parent e7e133f commit 54e1052
Show file tree
Hide file tree
Showing 18 changed files with 176 additions and 28 deletions.
1 change: 1 addition & 0 deletions packages/ember-concurrency/.eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

# compiled output
/dist/
/declarations/
/tmp/

# dependencies
Expand Down
12 changes: 12 additions & 0 deletions packages/ember-concurrency/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# The authoritative copies of these live in the monorepo root (because they're
# more useful on github that way), but the build copies them into here so they
# will also appear in published NPM packages.
/README.md
/LICENSE.md

# compiled output
/dist
/declarations

# npm/pnpm/yarn pack output
*.tgz
2 changes: 1 addition & 1 deletion packages/ember-concurrency/async-arrow-task-transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ function convertFunctionExpressionIntoGenerator(
state._buildTaskImport = addNamed(
state.root,
'buildTask',
'ember-concurrency/-private/async-arrow-runtime',
'ember-concurrency/async-arrow-runtime',
);
}

Expand Down
8 changes: 8 additions & 0 deletions packages/ember-concurrency/babel.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
// template colocation.
{
"plugins": [
[
"@babel/plugin-transform-typescript",
{
"allExtensions": true,
"onlyRemoveTypeImports": true,
"allowDeclareFields": true
}
],
"@embroider/addon-dev/template-colocation-plugin",
[
"babel-plugin-ember-template-compilation",
Expand Down
33 changes: 28 additions & 5 deletions packages/ember-concurrency/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"version": "4.0.0-beta.1",
"description": "Improved concurrency/async primitives for Ember.js",
"scripts": {
"build": "rollup --config",
"build": "concurrently 'npm:build:*'",
"build:js": "rollup --config",
"build:types": "glint --declaration && cp src/index.d.ts declarations/index.d.ts",
"lint": "concurrently 'npm:lint:*(!fix)' --names 'lint:'",
"lint:fix": "concurrently 'npm:lint:*:fix' --names 'fix:'",
"lint:hbs": "ember-template-lint .",
Expand All @@ -12,7 +14,10 @@
"lint:eslint:fix": "eslint . --fix",
"lint:prettier": "prettier . --cache --check",
"lint:prettier:fix": "prettier . --write",
"start": "rollup --config --watch",
"lint:types": "glint",
"start": "concurrently 'npm:start:*'",
"start:js": "rollup --config --watch --no-watch.clearScreen",
"start:types": "glint --declaration --watch",
"test": "echo 'Addon does not have tests, run tests in test-app'",
"prepare": "pnpm build"
},
Expand All @@ -24,11 +29,15 @@
"engines": {
"node": "16.* || >= 18"
},
"types": "./addon/index.d.ts",
"devDependencies": {
"@babel/core": "^7.23.9",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-proposal-decorators": "^7.23.9",
"@babel/plugin-transform-typescript": "^7.23.6",
"@glint/core": "^1.3.0",
"@glint/environment-ember-loose": "^1.3.0",
"@glint/environment-ember-template-imports": "^1.3.0",
"@glint/template": "^1.3.0",
"@embroider/addon-dev": "^4.2.0",
"@rollup/plugin-babel": "^6.0.4",
"@tsconfig/ember": "^3.0.3",
Expand All @@ -43,6 +52,7 @@
"eslint-plugin-qunit": "^7.3.4",
"prettier": "^3.1.0",
"rollup": "^4.9.6",
"rollup-plugin-copy": "^3.5.0",
"typescript": "^5.3.3"
},
"files": [
Expand All @@ -51,11 +61,24 @@
"async-arrow-task-transform.js"
],
"exports": {
".": "./dist/index.js",
"./*": "./dist/*",
".": {
"types": "./declarations/index.d.ts",
"default": "./dist/index.js"
},
"./*": {
"types": "./declarations/*.d.ts",
"default": "./dist/*.js"
},
"./addon-main.js": "./addon-main.cjs",
"./async-arrow-task-transform": "./async-arrow-task-transform.js"
},
"typesVersions": {
"*": {
"*": [
"declarations/*"
]
}
},
"keywords": [
"ember-addon",
"concurrency",
Expand Down
11 changes: 10 additions & 1 deletion packages/ember-concurrency/rollup.config.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import babel from "@rollup/plugin-babel";
import copy from "rollup-plugin-copy";
import { Addon } from "@embroider/addon-dev/rollup";

const addon = new Addon({
Expand All @@ -14,7 +15,7 @@ export default {
plugins: [
// These are the modules that users should be able to import from your
// addon. Anything not listed here may get optimized away.
addon.publicEntrypoints(["index.js", "**/*.js"]),
addon.publicEntrypoints(["**/*.js", "index.js", "template-registry.js"]),

// These are the modules that should get reexported into the traditional
// "app" tree. Things in here should also be in publicEntrypoints above, but
Expand Down Expand Up @@ -42,5 +43,13 @@ export default {

// Remove leftover build artifacts when starting a new build.
addon.clean(),

// Copy Readme and License into published package
copy({
targets: [
{ src: "../../README.md", dest: "." },
{ src: "../../LICENSE.md", dest: "." },
],
}),
],
};
2 changes: 2 additions & 0 deletions packages/ember-concurrency/src/-private/task-public-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
} from './task-decorators';
import { assert } from '@ember/debug';

/** @typedef {import('./task-group').TaskGroup} TaskGroup */

/**
* TODO: update docs to reflect both old and new ES6 styles
*
Expand Down
1 change: 1 addition & 0 deletions packages/ember-concurrency/src/async-arrow-runtime.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { buildTask } from './-private/async-arrow-runtime';
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { helper } from '@ember/component/helper';
import { assert } from '@ember/debug';
import { taskHelperClosure } from '../-private/helpers';
import type { Task } from '../index';

const CANCEL_REASON = "the 'cancel-all' template helper was invoked";

export function cancelHelper(args) {
type CancelAllParams = [task: Task<any, any[]>];

export function cancelHelper(args: CancelAllParams) {
let cancelable = args[0];
if (!cancelable || typeof cancelable.cancelAll !== 'function') {
assert(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { helper } from '@ember/component/helper';
import { assert } from '@ember/debug';
import { taskHelperClosure } from '../-private/helpers';
import type { Task } from '../index';

function maybeReportError(onError) {
return function (e) {
function maybeReportError(
onError: (error: unknown) => void | null | undefined,
) {
return function (e: unknown) {
if (typeof onError === 'function') {
onError(e);
} else if (onError === null) {
Expand All @@ -17,11 +20,13 @@ function maybeReportError(onError) {
};
}

export function performHelper(args, hash) {
type PerformParams = [task: Task<any, any[]>, ...args: any[]];

export function performHelper(args: PerformParams, hash: any) {
let perform = taskHelperClosure('perform', 'perform', args, hash);

if (hash && typeof hash.onError !== 'undefined') {
return function (...innerArgs) {
return function (...innerArgs: any[]) {
try {
let taskInstance = perform(...innerArgs);
return taskInstance.catch(maybeReportError(hash.onError));
Expand Down
7 changes: 0 additions & 7 deletions packages/ember-concurrency/src/helpers/task.js

This file was deleted.

13 changes: 13 additions & 0 deletions packages/ember-concurrency/src/helpers/task.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { helper } from '@ember/component/helper';
import type { Task } from '../index';

type TaskParams = [task: Task<any, any[]>, ...args: any[]];

function taskHelper(positional: TaskParams) {
let [task, ...args] = positional;

// @ts-expect-errors _curry isn't typed yet
return task._curry(...args);
}

export default helper(taskHelper);
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Add any types here that you need for local development only.
// These will *not* be published as part of your addon, so be careful that your published code does not rely on them!
import 'ember-source/types';
import 'ember-source/types/preview';
import '@glint/environment-ember-loose';
import '@glint/environment-ember-template-imports';

declare module '@glint/environment-ember-loose/registry' {
// Remove this once entries have been added! 👇
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export default interface Registry {
// Add any registry entries from other addons here that your addon itself uses (in non-strict mode templates)
// See https://typed-ember.gitbook.io/glint/using-glint/ember/using-addons
}
}
2 changes: 1 addition & 1 deletion packages/test-app/snippets/ts/basic-example.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Component from '@ember/component';
import { task, timeout } from 'ember-concurrency';
import { task, timeout } from '../../../ember-concurrency/declarations';

export default class extends Component {
myTask = task(async (ms: number) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/test-app/snippets/ts/typing-task.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Component from '@glimmer/component';
import { task, timeout } from 'ember-concurrency';
import type { Task } from 'ember-concurrency';
import { task, timeout } from '../../../ember-concurrency/declarations';
import type { Task } from '../../../ember-concurrency/declarations';

// Define a Type task that takes a single number argument and returns a string
type MyTaskType = Task<string, [number]>;
Expand Down
6 changes: 3 additions & 3 deletions packages/test-app/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
"paths": {
"test-app/tests/*": ["tests/*"],
"test-app/*": ["app/*"],
"*": ["types/*"],
"ember-concurrency": ["../ember-concurrency/src/index.d.ts"]
"*": ["types/*"]
}
}
},
"exclude": ["snippets"]
}
14 changes: 14 additions & 0 deletions packages/test-app/types-tests/ember-concurrency-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,13 @@ import {
enqueueTask,
keepLatestTask,
} from 'ember-concurrency';

import perform from 'ember-concurrency/helpers/perform';
import curryTask from 'ember-concurrency/helpers/task';
import cancelAll from 'ember-concurrency/helpers/cancel-all';

import { expectTypeOf as expect } from 'expect-type';
import { FunctionBasedHelperInstance, helper } from '@ember/component/helper';

declare type TestCallback = () => void | Promise<void>;
declare function module(description: string, callback: TestCallback): void;
Expand Down Expand Up @@ -312,6 +318,14 @@ module('unit tests', () => {
}
});

test('imported helpers', () => {
// @ts-expect-error
perform([]);

// let a = {} as Task<any, any[]>;
// perform([a], {});
});

test('EncapsulatedTaskState', () => {
{
let d = {};
Expand Down
Loading

0 comments on commit 54e1052

Please sign in to comment.