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 to TypeScript #491

Merged
merged 3 commits into from
May 16, 2022
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
20 changes: 18 additions & 2 deletions packages/ember-stargate/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

module.exports = {
root: true,
parser: 'babel-eslint',
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 2018,
ecmaVersion: 2021,
sourceType: 'module',
ecmaFeatures: {
legacyDecorators: true,
Expand All @@ -21,6 +21,22 @@ module.exports = {
},
rules: {},
overrides: [
// ts files
{
files: ['**/*.ts'],
extends: [
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
],
rules: {
'@typescript-eslint/explicit-module-boundary-types': 'error', // We want to be strict with types
'@typescript-eslint/explicit-function-return-type': 'error', // We want to be strict with types
'@typescript-eslint/no-unused-vars': [
'error',
{ argsIgnorePattern: '^_' },
],
},
},
// node files
{
files: [
Expand Down
3 changes: 1 addition & 2 deletions packages/ember-stargate/babel.config.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"presets": [["@babel/preset-typescript"]],
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy": true }],
"@babel/plugin-proposal-class-properties",
"@embroider/addon-dev/template-colocation-plugin"
]
}
16 changes: 9 additions & 7 deletions packages/ember-stargate/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@
"dependencies": {
"@ember/render-modifiers": "^2.0.0",
"@embroider/addon-shim": "^1.0.0",
"@glimmer/component": "^1.0.4",
"ember-resources": "^4.4.0",
"@glimmer/component": "^1.1.2",
"ember-resources": "^4.6.4",
"tracked-maps-and-sets": "^3.0.1"
},
"devDependencies": {
"@babel/core": "7.17.10",
"@babel/plugin-proposal-class-properties": "7.16.7",
"@babel/plugin-proposal-decorators": "7.17.9",
"@babel/plugin-syntax-decorators": "7.17.0",
"@babel/preset-typescript": "^7.16.7",
"@embroider/addon-dev": "1.6.0",
"@rollup/plugin-babel": "5.3.1",
"@types/ember": "^4.0.0",
"@typescript-eslint/eslint-plugin": "^5.21.0",
"@typescript-eslint/parser": "^5.21.0",
"babel-eslint": "10.1.0",
"ember-template-lint": "4.8.0",
"eslint": "7.32.0",
Expand All @@ -51,7 +51,9 @@
"eslint-plugin-prettier": "4.0.0",
"eslint-plugin-qunit": "7.2.0",
"npm-run-all": "4.1.5",
"rollup": "2.73.0"
"rollup": "2.73.0",
"rollup-plugin-ts": "^2.0.7",
"typescript": "^4.6.4"
},
"engines": {
"node": "12.* || >= 14"
Expand Down
13 changes: 10 additions & 3 deletions packages/ember-stargate/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import babel from '@rollup/plugin-babel';
import typescript from 'rollup-plugin-ts';
import { Addon } from '@embroider/addon-dev/rollup';

const addon = new Addon({
Expand All @@ -14,18 +14,25 @@ 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(['components/**/*.js', 'services/**/*.js']),
addon.publicEntrypoints(['components/**/*.ts', 'services/**/*.ts']),

// These are the modules that should get reexported into the traditional
// "app" tree. Things in here should also be in publicEntrypoints above, but
// not everything in publicEntrypoints necessarily needs to go here.
addon.appReexports(['components/**/*.js', 'services/**/*.js']),

// compile TypeScript
typescript({
transpiler: 'babel',
browserslist: false,
transpileOnly: false,
}),

// This babel config should *not* apply presets or compile away ES modules.
// It exists only to provide development niceties for you, like automatic
// template colocation.
// See `babel.config.json` for the actual Babel configuration!
babel({ babelHelpers: 'bundled' }),
// babel({ babelHelpers: 'bundled' }),

// Ensure that standalone .hbs files are properly integrated as Javascript.
addon.hbs(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,28 @@ import Component from '@glimmer/component';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import { assert } from '@ember/debug';
import type PortalService from '../services/-portal';

export default class PortalTargetComponent extends Component {
interface PortalTargetSignature {
Element: HTMLDivElement;
Args: {
name: string;
multiple?: boolean;
onChange?: (count: number) => void;
};
Blocks: { default: [number] };
}

export default class PortalTargetComponent extends Component<PortalTargetSignature> {
@service('-portal')
portalService;
portalService!: PortalService;

get count() {
get count(): number {
return this.portalService.getPortalCount(this.args.name);
}

@action
register(element) {
register(element: Element): void {
assert('PortalTargets needs a name', this.args.name);
const options = {
multiple: this.args.multiple,
Expand All @@ -22,7 +33,7 @@ export default class PortalTargetComponent extends Component {
}

@action
unregister() {
unregister(): void {
this.portalService.unregisterTarget(this.args.name);
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
import { next } from '@ember/runloop';
import { LifecycleResource, useResource } from 'ember-resources';
import { LifecycleResource, Positional, useResource } from 'ember-resources';
import type PortalService from '../services/-portal';
import type { Target } from '../services/-portal';

class PortalTrackerResource extends LifecycleResource {
class PortalTrackerResource extends LifecycleResource<Positional<[string]>> {
@service('-portal')
portalService;
portalService!: PortalService;

_target;
_target!: string;

get target() {
get target(): Target | undefined {
return this.portalService.getTarget(this._target);
}

setup() {
setup(): void {
this._target = this.args.positional[0];
next(() => this.portalService.registerPortal(this._target));
}

update() {
update(): void {
const previousTarget = this._target;
const newTarget = this.args.positional[0];
next(() => {
Expand All @@ -28,19 +30,30 @@ class PortalTrackerResource extends LifecycleResource {
this._target = newTarget;
}

teardown() {
teardown(): void {
this.portalService.unregisterPortal(this._target);
}
}

export default class PortalComponent extends Component {
interface PortalSignature {
Args: {
target: string;
renderInPlace?: boolean;
fallback?: 'inplace';
};
Blocks: { default: [] };
}

export default class PortalComponent extends Component<PortalSignature> {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore the types of ember-resources cause an error here
tracker = useResource(this, PortalTrackerResource, () => [this.args.target]);

get target() {
get target(): Target | undefined {
return this.tracker.target;
}

get renderInPlace() {
get renderInPlace(): boolean {
return (
this.args.renderInPlace === true ||
(!this.target && this.args.fallback === 'inplace')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,24 @@ import { assert } from '@ember/debug';
import { next } from '@ember/runloop';
import { TrackedMap } from 'tracked-maps-and-sets';

class TargetTracker {
name;
element;
multiple;
onChange;
interface TargetTrackerOptions {
multiple?: boolean;
onChange?: (count: number) => void;
}

export interface Target {
name: string;
element: Element;
multiple: boolean;
}

class TargetTracker implements Target {
name: string;
element: Element;
multiple: boolean;
onChange?: (count: number) => void;

constructor(name, element, options) {
constructor(name: string, element: Element, options: TargetTrackerOptions) {
this.name = name;
this.element = element;
this.multiple = options.multiple ?? false;
Expand All @@ -18,52 +29,62 @@ class TargetTracker {
}

export default class PortalService extends Service {
#targets = new TrackedMap();
#portalCount = new TrackedMap();
#targets = new TrackedMap<string, TargetTracker>();
#portalCount = new TrackedMap<string, number>();

getTarget(name) {
getTarget(name: string): Target | undefined {
return this.#targets.get(name);
}

getPortalCount(name) {
getPortalCount(name: string): number {
return this.#portalCount.get(name) ?? 0;
}

registerTarget(name, element, options) {
registerTarget(
name: string,
element: Element,
options: TargetTrackerOptions
): void {
next(this, () => {
assert(
`Portal target with name ${name} already exists`,
!this.#targets.has(name)
);

this.#targets.set(name, new TargetTracker(name, element, options));
});
}

unregisterTarget(name) {
unregisterTarget(name: string): void {
this.#targets.delete(name);
}

registerPortal(name) {
registerPortal(name: string): void {
const count = (this.#portalCount.get(name) ?? 0) + 1;
this.#portalCount.set(name, count);
const target = this.getTarget(name);
const target = this.#targets.get(name);
if (target && target.onChange) {
target.onChange(count);
}
}

unregisterPortal(name) {
unregisterPortal(name: string): void {
let count = this.#portalCount.get(name) ?? 0;
assert(
`Trying to unregister a portal "${name}" that hasn't been registered before`,
count > 0
);
count--;
this.#portalCount.set(name, count);
const target = this.getTarget(name);
const target = this.#targets.get(name);
if (target && target.onChange) {
target.onChange(count);
}
}
}

// DO NOT DELETE: this is how TypeScript knows how to look up your services.
declare module '@ember/service' {
interface Registry {
'-portal': PortalService;
}
}
15 changes: 15 additions & 0 deletions packages/ember-stargate/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "es2015",
"inlineSourceMap": true,
"inlineSources": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"strict": true,
"declaration": true
},
"include": [
"src/**/*",
]
}
Loading