Skip to content

Commit

Permalink
Merge branch 'master' into advance-rfc-0637
Browse files Browse the repository at this point in the history
  • Loading branch information
ef4 authored Oct 13, 2023
2 parents b0cff13 + e26f276 commit 781a418
Show file tree
Hide file tree
Showing 18 changed files with 280 additions and 93 deletions.
21 changes: 5 additions & 16 deletions .github/actions/find-added-or-modified-rfcs/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,20 @@ outputs:
value: ${{ steps.modified-rfc.outputs.path }}
modified-rfcs-count:
description: "The count of how many RFCs were added or modified"
value: ${{ steps.counts.outputs.all_changed }}
value: ${{ steps.rfcs.outputs.all_changed_files_count }}
added-rfcs-count:
description: "The count of how many RFCs that were added"
value: ${{ steps.counts.outputs.added }}
value: ${{ steps.rfcs.outputs.added_files_count }}

runs:
using: "composite"
steps:
- name: Find added or modified RFCs
id: rfcs
uses: tj-actions/changed-files@v31
uses: tj-actions/changed-files@v39
with:
path: 'text'
json: 'true'
sha: ${{ inputs.sha }}
base_sha: ${{ inputs.base-sha }}

- name: Get counts of changed and added RFCs
id: counts
shell: bash
run: |
changed_len=`echo "${{ steps.rfcs.outputs.all_changed_files }}" | jq '. | length'`
echo "all_changed=$changed_len" >> $GITHUB_OUTPUT
added_len=`echo "${{ steps.rfcs.outputs.added_files }}" | jq '. | length'`
echo "added=$added_len" >> $GITHUB_OUTPUT
files: text
json: true

- name: Find modified or added RFC info
id: modified-rfc
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/advance-rfc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ jobs:
- name: RFCs Added or Changed
id: rfcs
uses: ./.github/actions/find-added-or-modified-rfcs
with:
base-sha: ${{ github.event.before }}

- name: Fail if more than 1 RFC is added or modified
if: steps.rfcs.outputs.modified-rfcs-count > 1
Expand Down
9 changes: 1 addition & 8 deletions .github/workflows/newly-added-rfcs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@ on:
paths:
- 'text/*.md'

concurrency:
# Events within 5 minutes are not guaranteed to run in order, and so when removing S-Proposed and adding S-Exploring
# we can't guarantee that the run of the workflow will be the one where S-Exploring is added. Adding `github.event_name`
# to the concurrency allows both workflows to complete and the PR to eventually have successful checks.
group: newly-added-rfc-${{ github.head_ref || github.ref }}-${{ github.event_name }}
cancel-in-progress: true

jobs:
check-rfcs:
name: Does PR add RFCs?
Expand Down Expand Up @@ -76,7 +69,7 @@ jobs:
- name: Fail if more than 1 RFC is added or modified
if: ${{ needs.check-rfcs.outputs.rfcs-changed > 1}}
run: |
echo "::error::More than 1 RFC is added in this PR; will be unable to automatically open PRs for advancement"
echo "::error::More than 1 RFC is added or modified in this PR; will be unable to automatically open PRs for advancement"
exit 1
frontmatter-stage-is-accepted:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/open-advancement-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ jobs:
uses: peter-evans/[email protected]
with:
token: ${{ secrets.personal-access-token }}
commit-message: "Advance RFC {{ inputs.rfc-number }} to Stage ${{ inputs.new-stage }}"
commit-message: "Advance RFC ${{ inputs.rfc-number }} to Stage ${{ inputs.new-stage }}"
add-paths: 'text'
branch: "advance-rfc-${{ inputs.rfc-number }}"
title: "Advance RFC #${{ inputs.rfc-number}} `${{ steps.pr-variables.outputs.title }}` to Stage ${{ steps.pr-variables.outputs.pretty-stage }}"
Expand Down
Binary file added images/ember_test.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/npm_test.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions text/0566-memo-decorator.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
---
stage: released # FIXME: This may be recommended
stage: recommended
start-date: 2019-12-22T00:00:00.000Z
release-date: 2021-12-28T00:00:00.000Z
release-versions:
ember-source: v4.1.0

teams:
- framework
prs:
accepted: https://github.com/emberjs/rfcs/pull/566
accepted: 'https://github.com/emberjs/rfcs/pull/566'
recommended: 'https://github.com/emberjs/rfcs/pull/914'
project-link:
---

Expand Down
6 changes: 4 additions & 2 deletions text/0724-road-to-typescript.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
stage: accepted
stage: released
start-date: 2021-03-11T00:00:00.000Z
release-date:
release-versions:
Expand All @@ -10,7 +10,9 @@ teams:
- learning
- steering
prs:
accepted: https://github.com/emberjs/rfcs/pull/724
accepted: 'https://github.com/emberjs/rfcs/pull/724'
ready-for-release: 'https://github.com/emberjs/rfcs/pull/869'
released: 'https://github.com/emberjs/rfcs/pull/948'
project-link:
---

Expand Down
11 changes: 7 additions & 4 deletions text/0730-semver-for-ts.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
stage: accepted
stage: recommended
start-date: 2021-03-23T00:00:00.000Z
release-date:
release-versions:
Expand All @@ -9,7 +9,10 @@ teams:
- data
- cli
prs:
accepted: https://github.com/emberjs/rfcs/pull/730
accepted: 'https://github.com/emberjs/rfcs/pull/730'
ready-for-release: 'https://github.com/emberjs/rfcs/pull/875'
released: 'https://github.com/emberjs/rfcs/pull/949'
recommended: 'https://github.com/emberjs/rfcs/pull/951'
project-link:
---

Expand Down Expand Up @@ -461,7 +464,7 @@ For functions which return or accept user-constructible types, the rules specifi

- a function (including a class constructor or methods) argument *requires a more specific ("narrower") type*, for example if it previously accepted `string | number` but now requires `string`—since the user will have to change some calls to the function ([playground][narrower-argument])

- a function (including a class constructor or method) *returns a less specific ("wider") type*, for example if it previously returned `string` but now returns `string | null`—since the user's existing handling of the return value will be wrong in some cases ([playground][wider-return]).
- a function (including a class constructor or method) *returns a less specific ("wider") type*, for example if it previously returned `string` but now returns `string |`—since the user's existing handling of the return value will be wrong in some cases ([playground][wider-return]).

This includes widening from a *type guard* to a more general check. For example:

Expand Down Expand Up @@ -621,7 +624,7 @@ Bug fix/patch releases to TypeScript (as described above under [Bug fixes](#bug-

Type-checking in TypeScript behaves differently under different “strictness” settings, and the compiler adds more strictness settings over time. Changes to types which are not breaking under looser compiler settings may be breaking under stricter compiler settings.

For example: a package with `strictNullChecks: false` could make a function return type nullable without the compiler reporting it within the package or the package’s type tests. However, as described above, this is a breaking change for consumers which have `strictNullChecks: true`. (By contrast, a *consumer* may disable strictness settings safely: code which type-checks under a stricter setting also type-checks under a less strict setting.) Likewise, with `noUncheckedIndexedAccess: false`, an author could change a type `SomeObj` from `{ a: string }` to `{ [key: string]: string }` and accessing `someObj.a.length` would now error.
For example: a package with `strictNullChecks: false` could make a function return typeable without the compiler reporting it within the package or the package’s type tests. However, as described above, this is a breaking change for consumers which have `strictNullChecks: true`. (By contrast, a *consumer* may disable strictness settings safely: code which type-checks under a stricter setting also type-checks under a less strict setting.) Likewise, with `noUncheckedIndexedAccess: false`, an author could change a type `SomeObj` from `{ a: string }` to `{ [key: string]: string }` and accessing `someObj.a.length` would now error.

Accordingly, conforming packages must use `strict: true` in their compiler settings. Additionally, communities may define further strictness settings to which they commit to conform which include “pedantic” strictness settings like `noUncheckedIndexedAccess`. For example, the Ember community might commit to a set of *additional* strictness flags it supports for its own types for any LTS release, published in Ember’s own TypeScript documentation.

Expand Down
9 changes: 6 additions & 3 deletions text/0740-ember-data-deprecate-non-strict-relationships.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
---
stage: accepted # FIXME: This may be a further stage
stage: released
start-date: 2021-04-23T00:00:00.000Z
release-date:
release-date: 2023-09-19T00:00:00.000Z
release-versions:
ember-data: 5.3.0
teams:
- data
prs:
accepted: https://github.com/emberjs/rfcs/pull/740
accepted: 'https://github.com/emberjs/rfcs/pull/740'
ready-for-release: 'https://github.com/emberjs/rfcs/pull/910'
released: 'https://github.com/emberjs/rfcs/pull/967'
project-link:
---

Expand Down
8 changes: 4 additions & 4 deletions text/0743-ember-data-deprecate-legacy-imports.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
stage: accepted
start-date: 2021-04-23
stage: ready-for-release
start-date: 2021-04-23T00:00:00.000Z
release-date:
release-versions:
teams:
- data
prs:
accepted: https://github.com/emberjs/rfcs/pull/743

accepted: 'https://github.com/emberjs/rfcs/pull/743'
ready-for-release: 'https://github.com/emberjs/rfcs/pull/947'
---

# EmberData | Deprecate Legacy Imports
Expand Down
12 changes: 7 additions & 5 deletions text/0774-implicit-record-route-loading.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
---
stage: accepted
start-date: 2021-11-14
release-date:
stage: released
start-date: 2021-11-14T00:00:00.000Z
release-date:
release-versions:
teams: # delete teams that aren't relevant
teams:
- framework
prs:
accepted: https://github.com/emberjs/rfcs/pull/774
accepted: 'https://github.com/emberjs/rfcs/pull/774'
ready-for-release: 'https://github.com/emberjs/rfcs/pull/900'
released: 'https://github.com/emberjs/rfcs/pull/955'
---

# Deprecate Implicit Record Loading in Routes
Expand Down
53 changes: 25 additions & 28 deletions text/0800-ts-adoption-plan.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
stage: accepted
stage: recommended
start-date: 2022-02-24T00:00:00.000Z
release-date:
release-versions:
Expand All @@ -9,7 +9,10 @@ teams:
- cli
- learning
prs:
accepted: https://github.com/emberjs/rfcs/pull/800
accepted: 'https://github.com/emberjs/rfcs/pull/800'
ready-for-release: 'https://github.com/emberjs/rfcs/pull/868'
released: 'https://github.com/emberjs/rfcs/pull/950'
recommended: 'https://github.com/emberjs/rfcs/pull/953'
project-link:
---

Expand Down Expand Up @@ -316,7 +319,7 @@ Like browsers and Node, TypeScript regularly introduces new features which are a
- `const` assertions and higher-order inference for functions, which was key to enabling Glint (3.4)
- assertion functions, allowing more useful typing of `assert` (3.7)
- the `declare` modifier, allowing safe declaration of injections and CPs (3.7)
- spec compatibility for class fields, optional chaining,. and nullish coalescing (3.7)
- spec compatibility for class fields, optional chaining,. andish coalescing (3.7)
- spec compatibility for top-level `await` (3.8)
- variadic tuple types and labeled tuple elements (4.0, improved in 4.2)
- template literal types (4.1)
Expand Down Expand Up @@ -539,36 +542,42 @@ For the classic DI system, we no longer require (or benefit from) string key-bas
}
```
With the introduction of full support for native classes and decorators in Octane, there is no need for this (and it was rather janky to begin with!). Accordingly, we will simply remove support for these two type registries entirely:
With the introduction of full support for native classes and decorators in Octane, and given the current status of the decorators implementation in TypeScript, this does not provide type inference. However, these kinds of type registries can still provide two benefits for consumers:
- The service `Registry` in `@ember/service`
- The controller `Registry` in `@ember/controller`
1. When renaming a service injection, like `@service('session') sessionService;`, or using its full name, like `@service('shared@session') session;`, the registry can still check that the resolved name is one that is registered.
The decorators will continue to accept a string key, but will not validate that against a registry, since decorators cannot change the types of the items they decorator in TypeScript.[^reintroduce]
2. It can be used with the other things in the DI system, e.g. making `Owner.lookup('service:session')` type safe, and thereby making things like `this.owner.lookup('service:session')` in tests automatically be well-typed.
For Ember Data, there is considerably more ongoing need for registry-style APIs. `Store.findRecord` isn’t going anywhere any time soon, for example, and it *requires* some kind of registry to make `this.store.findRecord('user', 1)` correctly return a `User` model. Many other APIs within Ember Data similarly require registries for type safety. Thus, Ember Data will need its own dedicated design for handling those, and this RFC leaves those for the Ember Data team to address in a dedicated RFC.
The `@service` decorator will therefore continue to accept a string key, and will validate that against a registry, even though decorators cannot change the types of the items they decorate in TypeScript today. Additionally, the registry will be integrated into `Owner` types so that it can be used more generally. Moreover, the design for an `Owner` registry should allow others to integrate in the same way.
Controller injection, by contrast with service injection, is decreasingly used across the ecosystem and not generally recommended, and we expect it to be deprecated during Ember v6. Accordingly, we will *keep* support for the service registry while dropping support for the controller registry. (Given an appropriate design for `Owner`, end users could reimplement this if they so chose.)
[^reintroduce]: We could conceivably reintroduce a registry of this form in the future if that limitation on decorators in TypeScript changes, so that `@service('session') declare session;` would have the right type without needing an explicit type annotation, but that would need to be well-motivated on the merits, and there are actually advantages to having explicit type imports for the static analyzability of the code. The combination of Embroider and other future design moves we might make for the design system, for example [this experiment by pzuraq](https://github.com/pzuraq/ember-totally-not-module-based-services), may make other directions more appealing than the registry approach.
Future designs for services and dependency injection more generally will need to be written to account for the capabilities of TypeScript’s implementation of Stage 3 decorators as they grow and change over time.
For Ember Data, there is considerably more ongoing need for registry-style APIs. `Store.findRecord` isn’t going anywhere any time soon, for example, and it *requires* some kind of registry to make `this.store.findRecord('user', 1)` correctly return a `User` model. Many other APIs within Ember Data similarly require registries for type safety. Thus, Ember Data will need its own dedicated design for handling those, and this RFC leaves those for the Ember Data team to address in a dedicated RFC.
### CLI Integration
We will introduce a new `--typescript` (`-ts`) flag for the `ember new` and `ember addon` commands, allowing users to opt into TypeScript when generating a new project. Using this flag will:
- Install Ember TypeScript integration tooling, today consisting simply of `ember-cli-typescript` and its generators.
- Set the `isTypeScriptProject` option for `.ember-cli` (introduced in [RFC #0776][rfc-0776]) to `true`, so that blueprints are generated with TypeScript by default in the project.
- Configure linting:
- In the`.eslintrc.js` blueprint:
- use `@typescript-eslint/parser` instead of the Babel ESLint parser
- include `@typescript-eslint` in the `plugins` key
- include `plugin:@typescript-eslint/recommended` in the `extends` key
- Install the `@typescript-eslint` dependencies instead of of the Babel ESLint dependencies in `package.json`
- Use `@typescript-eslint/parser` instead of the Babel ESLint parser.
- Include `@typescript-eslint` in the `plugins` key.
- Include `plugin:@typescript-eslint/recommended` in the `extends` key.
- Install the `@typescript-eslint` dependencies instead of, or in addition to (as appropriate), the Babel ESLint dependencies in `package.json`.
- Configure [Glint][glint] for type checking and, for addons, emitting type declarations during build.
- Create `tsconfig.json` files and generate their `compilerOptions.paths`.
- Configure `ember-cli-babel` to include the TypeScript transform. (This may just be an “out of the box” setting so it always works and does not require configuration!)
- Set up packages with scripts to do type checking and, in the case of v1 addons, emitting type declarations using `glint`.
[rfc-0776]: https://emberjs.github.io/rfcs/0776-typescript-blueprints.html
We will also update the Glimmer Component blueprint in the Ember.js repo to include [the component’s signature][rfc-0748], so that it can be used by TypeScript.
We will *not* be eliminating `ember-cli-typescript` as part of this process, because it remains a useful home for some of the tooling, and may remain a useful configuration point in the future, for example when we incorporate [Glint][glint] into official Ember tooling. In this design, only the pieces which are *necessarily* shared will be hoisted into `ember-cli` itself, with the other pieces remaining in `ember-cli-typescript`. For example, the blueprint for generating `tsconfig.json` files should remain in `ember-cli-typescript`.
We will be sunsetting `ember-cli-typescript` as part of this process. It was a valuable and needful part of the ecosystem when we did *not* have official support, but now it duplicates other sources of configuration and tooling, making maintenance needlessly more complicated. All of its capabilities can be managed more cleanly in other projects: `ember-source` and other addons can ship blueprints which support both TypeScript and JavaScript, `ember-cli-babel` and other build tools can manage transpilation, and `glint` supports end-to-end type checking.
[glint]: https://github.com/typed-ember/glint
Expand Down Expand Up @@ -822,16 +831,4 @@ This would be a reasonable approach—and was in fact what the other Typed Ember
## Unresolved questions
- How should we support opting into TypeScript support after starting a project? Today, users do this by running `ember install ember-cli-typescript` and getting its updates to blueprints etc.—but that will not be as obvious in this design, and even if we continue to use that as the mechanism, we need to document it and decide which parts `ember-cli-typescript` is responsible for and which it is not.
- Which, if any, blueprints need to be updated besides the Glimmer Component blueprint, in the absence of type registries for Service and Controller classes?
- Did we miss any Classic features for which we need to specify what we will and will not provide?
- Should we ship an `ember-ultra-strict` mode initially, and if so what additional flags should it include?
- Is specifying Ember Data’s registries a blocker for adopting this RFC?
- Do we need an appendix to this RFC specifying user-constructibility and import location for existing interfaces like `Transition` and `RouteInfo`?
- Should we do the work to introduce a “simplified” presentation of the types for JavaScript users in our API docs, which (for example) removes generics and replaces `unknown` with `any` or similar, to avoid requiring JavaScript users to understand those TypeScript details?
None!
8 changes: 5 additions & 3 deletions text/0812-tracked-built-ins.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
---
stage: ready-for-release
stage: released
start-date: 2022-03-29T00:00:00.000Z
release-date:
release-date: 2023-01-21T00:00:00.000Z
release-versions:
ember-cli: v4.10.0
teams:
- cli
- learning
prs:
accepted: 'https://github.com/emberjs/rfcs/pull/812'
ready-for-release: 'https://github.com/emberjs/rfcs/pull/886'
released: 'https://github.com/emberjs/rfcs/pull/937'
project-link:
---

Expand Down Expand Up @@ -347,4 +349,4 @@ on the impact of the API churn on existing apps, etc.
[guides-pojos]: https://guides.emberjs.com/release/in-depth-topics/autotracking-in-depth/#toc_plain-old-javascript-objects-pojos
[guides-arrays]: https://guides.emberjs.com/release/in-depth-topics/autotracking-in-depth/#toc_arrays
[global-objects-map]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
[global-objects-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
[global-objects-array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
Loading

0 comments on commit 781a418

Please sign in to comment.