Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert helpers to .ts and expose their types #559

Merged
merged 16 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading