ember-source 7.3.0-beta.1 → 7.4.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "7.3.0-beta.1",
2
+ "version": "7.4.0-alpha.1",
3
3
  "buildType": "tag",
4
- "SHA": "af217de50750d379c8839dbc3ece21b7ec33c4e5",
5
- "assetPath": "/tag/shas/af217de50750d379c8839dbc3ece21b7ec33c4e5.tgz"
4
+ "SHA": "bb24a186bb850fd38035f4b6975bc7a979c17761",
5
+ "assetPath": "/tag/shas/bb24a186bb850fd38035f4b6975bc7a979c17761.tgz"
6
6
  }
@@ -1,5 +1,5 @@
1
1
  export { t as template, a as templateCacheCounters } from '../../../shared-chunks/index-BYUSIu_W.js';
2
- export { O as OutletView, R as Renderer, a as RootTemplate, s as setupApplicationRegistry, b as setupEngineRegistry } from '../../../shared-chunks/setup-registry-Dp5dtaLa.js';
2
+ export { O as OutletView, R as Renderer, a as RootTemplate, s as setupApplicationRegistry, b as setupEngineRegistry } from '../../../shared-chunks/setup-registry-Ci8Af2Bz.js';
3
3
  export { I as Input, T as Textarea } from '../../../shared-chunks/textarea-DvS6Xmdh.js';
4
4
  export { LinkTo } from '../../routing/index.js';
5
5
  export { default as Component, setComponentManager } from '../../component/index.js';
@@ -12,7 +12,7 @@ export { i as isSerializationFirstNode } from '../../../shared-chunks/rehydrate-
12
12
  export { NodeDOMTreeConstruction } from '../../../@glimmer/node/index.js';
13
13
  export { e as element } from '../../../shared-chunks/element-Cgoi4ldD.js';
14
14
  export { u as uniqueId } from '../../../shared-chunks/unique-id-Csxuh1I7.js';
15
- export { _ as _resetRenderers, r as renderComponent, a as renderSettled } from '../../../shared-chunks/index-B5gBbO_p.js';
15
+ export { _ as _resetRenderers, r as renderComponent, a as renderSettled } from '../../../shared-chunks/index-Bv9SQpEx.js';
16
16
  export { c as componentCapabilities, m as modifierCapabilities } from '../../../shared-chunks/api-BlZDPg1n.js';
17
17
 
18
18
  // STATE within a module is frowned upon, this exists
@@ -23,7 +23,7 @@ import BucketCache from '../routing/lib/cache.js';
23
23
  import ApplicationInstance from './instance.js';
24
24
  import Engine, { buildInitializerMethod } from '../engine/index.js';
25
25
  import { privatize } from '../-internals/container/index.js';
26
- import { s as setupApplicationRegistry } from '../../shared-chunks/setup-registry-Dp5dtaLa.js';
26
+ import { s as setupApplicationRegistry } from '../../shared-chunks/setup-registry-Ci8Af2Bz.js';
27
27
  import RouterService from '../routing/router-service.js';
28
28
  import { assert } from '../debug/lib/assert.js';
29
29
 
@@ -21,7 +21,7 @@ import '../../shared-chunks/hash-BFu91gtE.js';
21
21
  import '../../shared-chunks/get-zsePWrJL.js';
22
22
  import '../../shared-chunks/on-CVIjn2C-.js';
23
23
  import '../../shared-chunks/template-only-Cu639ICT.js';
24
- import { a as renderSettled } from '../../shared-chunks/index-B5gBbO_p.js';
24
+ import { a as renderSettled } from '../../shared-chunks/index-Bv9SQpEx.js';
25
25
  import '../../shared-chunks/unique-id-Csxuh1I7.js';
26
26
  import '../runloop/index.js';
27
27
  import EmberRouter from '../routing/router.js';
@@ -13,7 +13,7 @@ import '../../route-recognizer/index.js';
13
13
  import '../../shared-chunks/rsvp-aLN_pQtn.js';
14
14
  import '../../shared-chunks/unrecognized-url-error-cXUp-SK3.js';
15
15
  import RoutingService from '../routing/lib/routing-service.js';
16
- import { b as setupEngineRegistry } from '../../shared-chunks/setup-registry-Dp5dtaLa.js';
16
+ import { b as setupEngineRegistry } from '../../shared-chunks/setup-registry-Ci8Af2Bz.js';
17
17
  import RegistryProxyMixin from '../-internals/runtime/lib/mixins/registry_proxy.js';
18
18
  import { StrictResolver } from './lib/strict-resolver.js';
19
19
  import { assert } from '../debug/lib/assert.js';
@@ -1 +1 @@
1
- export { r as renderComponent, a as renderSettled } from '../../shared-chunks/index-B5gBbO_p.js';
1
+ export { r as renderComponent, a as renderSettled } from '../../shared-chunks/index-Bv9SQpEx.js';
@@ -1,4 +1,4 @@
1
1
  // this file gets replaced with the real value during the build
2
- const VERSION = '7.3.0-beta.1';
2
+ const VERSION = '7.4.0-alpha.1';
3
3
 
4
4
  export { VERSION as default };
@@ -296,8 +296,8 @@ const trackArray = internalHelper(({
296
296
 
297
297
  There are two special values for `key`:
298
298
 
299
+ * `@identity` - The item in the array itself. This is the default.
299
300
  * `@index` - The index of the item in the array.
300
- * `@identity` - The item in the array itself.
301
301
 
302
302
  ### {{else}} condition
303
303
 
@@ -410,6 +410,30 @@ const trackArray = internalHelper(({
410
410
 
411
411
  `#each-in` is a keyword and does not need to be imported.
412
412
 
413
+ ### Specifying Keys
414
+
415
+ Like `{{#each}}`, `{{#each-in}}` accepts a `key` option to decide which DOM
416
+ elements can be reused between renders. Since `{{#each-in}}` yields two block
417
+ params, the special values pick which one is used:
418
+
419
+ * `@identity` - The second block param: the property's value. This is the
420
+ default. Changing a value replaces that entry's DOM instead of updating it
421
+ in place.
422
+ * `@key` - The first block param: the property name, or for a `Map`, its key.
423
+
424
+ Any other string is a path, looked up on the value: `key="id"` keys each entry
425
+ by its `value.id`.
426
+
427
+ For example, `@key` keeps each entry's DOM as its score changes, so anything
428
+ stateful inside it — focus, a running transition, a component instance — survives
429
+ the update:
430
+
431
+ ```handlebars
432
+ {{#each-in this.scores key="@key" as |player score|}}
433
+ <PlayerScore @name={{player}} @score={{score}} />
434
+ {{/each-in}}
435
+ ```
436
+
413
437
  @method each-in
414
438
  @static
415
439
  @noimport
@@ -20,7 +20,7 @@ import { _instrumentStart } from '../@ember/instrumentation/index.js';
20
20
  import { c as capabilityFlagsFrom } from './capabilities-CajW4QjE.js';
21
21
  import { C as CONSTANT_TAG, c as consumeTag, D as DIRTY_TAG$1, r as createTag } from './cache-DGDPVCpC.js';
22
22
  import { assert } from '../@ember/debug/lib/assert.js';
23
- import { R as ResolverImpl, B as BaseRenderer, e as errorLoopTransaction } from './index-B5gBbO_p.js';
23
+ import { R as ResolverImpl, B as BaseRenderer, e as errorLoopTransaction } from './index-Bv9SQpEx.js';
24
24
  import { generateControllerFactory } from '../@ember/routing/lib/generate_controller.js';
25
25
  import { i as internalHelper } from './internal-helper-CKrni0b_.js';
26
26
  import { c as hasInternalComponentManager } from './api-DuLOZMO_.js';
@@ -1,5 +1,5 @@
1
1
  export { t as template, a as templateCacheCounters } from '../../../shared-chunks/index-kwuZeaNz.js';
2
- export { O as OutletView, R as Renderer, a as RootTemplate, s as setupApplicationRegistry, b as setupEngineRegistry } from '../../../shared-chunks/setup-registry-DI1Agp-0.js';
2
+ export { O as OutletView, R as Renderer, a as RootTemplate, s as setupApplicationRegistry, b as setupEngineRegistry } from '../../../shared-chunks/setup-registry-DeyoFe6Q.js';
3
3
  export { I as Input, T as Textarea } from '../../../shared-chunks/textarea-B-sssXGa.js';
4
4
  export { LinkTo } from '../../routing/index.js';
5
5
  export { default as Component, setComponentManager } from '../../component/index.js';
@@ -11,7 +11,7 @@ export { i as isSerializationFirstNode } from '../../../shared-chunks/rehydrate-
11
11
  export { NodeDOMTreeConstruction } from '../../../@glimmer/node/index.js';
12
12
  export { e as element } from '../../../shared-chunks/element-BmBjPjkQ.js';
13
13
  export { u as uniqueId } from '../../../shared-chunks/unique-id-BJb1p8EG.js';
14
- export { _ as _resetRenderers, r as renderComponent, a as renderSettled } from '../../../shared-chunks/index-C4VEqlp7.js';
14
+ export { _ as _resetRenderers, r as renderComponent, a as renderSettled } from '../../../shared-chunks/index-D8cl-pfl.js';
15
15
  export { c as componentCapabilities, m as modifierCapabilities } from '../../../shared-chunks/api-B_poQGXS.js';
16
16
 
17
17
  // STATE within a module is frowned upon, this exists
@@ -23,7 +23,7 @@ import BucketCache from '../routing/lib/cache.js';
23
23
  import ApplicationInstance from './instance.js';
24
24
  import Engine, { buildInitializerMethod } from '../engine/index.js';
25
25
  import { privatize } from '../-internals/container/index.js';
26
- import { s as setupApplicationRegistry } from '../../shared-chunks/setup-registry-DI1Agp-0.js';
26
+ import { s as setupApplicationRegistry } from '../../shared-chunks/setup-registry-DeyoFe6Q.js';
27
27
  import RouterService from '../routing/router-service.js';
28
28
 
29
29
  /**
@@ -16,7 +16,7 @@ import '../../shared-chunks/hash-BitfXhCx.js';
16
16
  import '../../shared-chunks/get-CEjFJzGs.js';
17
17
  import '../../shared-chunks/on-ov4KAucw.js';
18
18
  import '../../shared-chunks/template-only-DKNcKM5b.js';
19
- import { a as renderSettled } from '../../shared-chunks/index-C4VEqlp7.js';
19
+ import { a as renderSettled } from '../../shared-chunks/index-D8cl-pfl.js';
20
20
  import '../../shared-chunks/unique-id-BJb1p8EG.js';
21
21
  import '../runloop/index.js';
22
22
  import '../routing/router.js';
@@ -11,7 +11,7 @@ import '../../route-recognizer/index.js';
11
11
  import '../../shared-chunks/rsvp-aLN_pQtn.js';
12
12
  import '../../shared-chunks/unrecognized-url-error-xC654tCo.js';
13
13
  import RoutingService from '../routing/lib/routing-service.js';
14
- import { b as setupEngineRegistry } from '../../shared-chunks/setup-registry-DI1Agp-0.js';
14
+ import { b as setupEngineRegistry } from '../../shared-chunks/setup-registry-DeyoFe6Q.js';
15
15
  import RegistryProxyMixin from '../-internals/runtime/lib/mixins/registry_proxy.js';
16
16
  import { StrictResolver } from './lib/strict-resolver.js';
17
17
 
@@ -1 +1 @@
1
- export { r as renderComponent, a as renderSettled } from '../../shared-chunks/index-C4VEqlp7.js';
1
+ export { r as renderComponent, a as renderSettled } from '../../shared-chunks/index-D8cl-pfl.js';
@@ -1,4 +1,4 @@
1
1
  // this file gets replaced with the real value during the build
2
- const VERSION = '7.3.0-beta.1';
2
+ const VERSION = '7.4.0-alpha.1';
3
3
 
4
4
  export { VERSION as default };
@@ -268,8 +268,8 @@ const trackArray = internalHelper(({
268
268
 
269
269
  There are two special values for `key`:
270
270
 
271
+ * `@identity` - The item in the array itself. This is the default.
271
272
  * `@index` - The index of the item in the array.
272
- * `@identity` - The item in the array itself.
273
273
 
274
274
  ### {{else}} condition
275
275
 
@@ -382,6 +382,30 @@ const trackArray = internalHelper(({
382
382
 
383
383
  `#each-in` is a keyword and does not need to be imported.
384
384
 
385
+ ### Specifying Keys
386
+
387
+ Like `{{#each}}`, `{{#each-in}}` accepts a `key` option to decide which DOM
388
+ elements can be reused between renders. Since `{{#each-in}}` yields two block
389
+ params, the special values pick which one is used:
390
+
391
+ * `@identity` - The second block param: the property's value. This is the
392
+ default. Changing a value replaces that entry's DOM instead of updating it
393
+ in place.
394
+ * `@key` - The first block param: the property name, or for a `Map`, its key.
395
+
396
+ Any other string is a path, looked up on the value: `key="id"` keys each entry
397
+ by its `value.id`.
398
+
399
+ For example, `@key` keeps each entry's DOM as its score changes, so anything
400
+ stateful inside it — focus, a running transition, a component instance — survives
401
+ the update:
402
+
403
+ ```handlebars
404
+ {{#each-in this.scores key="@key" as |player score|}}
405
+ <PlayerScore @name={{player}} @score={{score}} />
406
+ {{/each-in}}
407
+ ```
408
+
385
409
  @method each-in
386
410
  @static
387
411
  @noimport
@@ -18,7 +18,7 @@ import { g as getFactoryFor } from './container-BYOnjnwz.js';
18
18
  import { _instrumentStart } from '../@ember/instrumentation/index.js';
19
19
  import { c as capabilityFlagsFrom } from './capabilities-BuVYh-vx.js';
20
20
  import { C as CONSTANT_TAG, c as consumeTag, D as DIRTY_TAG$1, r as createTag } from './cache-CofLhaS4.js';
21
- import { R as ResolverImpl, B as BaseRenderer, e as errorLoopTransaction } from './index-C4VEqlp7.js';
21
+ import { R as ResolverImpl, B as BaseRenderer, e as errorLoopTransaction } from './index-D8cl-pfl.js';
22
22
  import { generateControllerFactory } from '../@ember/routing/lib/generate_controller.js';
23
23
  import { i as internalHelper } from './internal-helper-Bz1lpDXr.js';
24
24
  import { c as hasInternalComponentManager } from './api-DlJKfm_f.js';
package/docs/data.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "name": "The Ember API",
4
4
  "description": "The Ember API: a framework for building ambitious web applications",
5
5
  "url": "https://emberjs.com/",
6
- "version": "7.3.0-beta.1"
6
+ "version": "7.4.0-alpha.1"
7
7
  },
8
8
  "files": {
9
9
  "node_modules/rsvp/lib/rsvp/promise/all.js": {
@@ -6428,7 +6428,7 @@
6428
6428
  {
6429
6429
  "file": "packages/@ember/-internals/glimmer/lib/helpers/each-in.ts",
6430
6430
  "line": 13,
6431
- "description": "The `{{#each}}` keyword loops over elements in a collection. It is an extension\nof the base Handlebars `{{#each}}` helper.\n\nThe default behavior of `{{#each}}` is to yield its inner block once for every\nitem in an array passing the item as the first block parameter.\n\n```gjs {data-filename=\"app/components/developer-list.gjs\"}\nimport Component from '@glimmer/component';\n\nexport default class DeveloperList extends Component {\n developers = [\n { name: 'Yehuda' },\n { name: 'Tom' },\n { name: 'Paul' },\n ];\n\n <template>\n <ul>\n {{#each this.developers as |person|}}\n <li>Hello, {{person.name}}!</li>\n {{/each}}\n </ul>\n </template>\n}\n```\n\nThe same rules apply to arrays of primitives:\n\n```gjs {data-filename=\"app/components/developer-names.gjs\"}\nimport Component from '@glimmer/component';\n\nexport default class DeveloperNames extends Component {\n developerNames = ['Yehuda', 'Tom', 'Paul'];\n\n <template>\n <ul>\n {{#each this.developerNames as |name|}}\n <li>Hello, {{name}}!</li>\n {{/each}}\n </ul>\n </template>\n}\n```\n\n`{{#each}}` also supports native JavaScript [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set)\nvalues and other iterables:\n\n```gjs {data-filename=\"app/components/developer-set.gjs\"}\nimport Component from '@glimmer/component';\n\nexport default class DeveloperSet extends Component {\n developers = new Set([\n { name: 'Yehuda' },\n { name: 'Tom' },\n { name: 'Paul' },\n ]);\n\n <template>\n <ul>\n {{#each this.developers as |person|}}\n <li>Hello, {{person.name}}!</li>\n {{/each}}\n </ul>\n </template>\n}\n```\n\nDuring iteration, the index of each item in the array is provided as a second\nblock parameter:\n\n```gjs {data-filename=\"app/components/developer-list-with-index.gjs\"}\nimport Component from '@glimmer/component';\n\nexport default class DeveloperListWithIndex extends Component {\n developers = [\n { name: 'Yehuda' },\n { name: 'Tom' },\n { name: 'Paul' },\n ];\n\n <template>\n <ul>\n {{#each this.developers as |person index|}}\n <li>Hello, {{person.name}}! You're number {{index}} in line</li>\n {{/each}}\n </ul>\n </template>\n}\n```\n\n`#each` is a keyword and does not need to be imported.\n\n### Specifying Keys\n\nIn order to improve rendering speed, Ember will try to reuse the DOM elements\nwhere possible. Specifically, if the same item is present in the array both\nbefore and after the change, its DOM output will be reused.\n\nThe `key` option is used to tell Ember how to determine if the items in the\narray being iterated over with `{{#each}}` has changed between renders. By\ndefault the item's object identity is used.\n\nThis is usually sufficient, so in most cases, the `key` option is simply not\nneeded. However, in some rare cases, the objects' identities may change even\nthough they represent the same underlying data.\n\nFor example, mapping over `people` produces a new array of new objects on each\nrender. Use `key` so Ember can match items across those renders:\n\n```gjs {data-filename=\"app/components/mapped-developers.gjs\"}\nimport Component from '@glimmer/component';\n\nexport default class MappedDevelopers extends Component {\n people = [\n { name: 'Yehuda' },\n { name: 'Tom' },\n { name: 'Paul' },\n ];\n\n get developers() {\n return this.people.map((person) => {\n return { ...person, type: 'developer' };\n });\n }\n\n <template>\n <ul>\n {{#each this.developers key=\"name\" as |person|}}\n <li>Hello, {{person.name}}!</li>\n {{/each}}\n </ul>\n </template>\n}\n```\n\nBy doing so, Ember will use the value of the property specified (`person.name`\nin the example) to find a \"match\" from the previous render. That is, if Ember\nhas previously seen an object from the `developers` array with a matching\nname, its DOM elements will be re-used.\n\nThere are two special values for `key`:\n\n * `@index` - The index of the item in the array.\n * `@identity` - The item in the array itself.\n\n### {{else}} condition\n\n`{{#each}}` can have a matching `{{else}}`. The contents of this block will render\nif the collection is empty.\n\n```gjs {data-filename=\"app/components/available-developers.gjs\"}\nimport Component from '@glimmer/component';\n\nexport default class AvailableDevelopers extends Component {\n developers = [];\n\n <template>\n <ul>\n {{#each this.developers as |person|}}\n <li>{{person.name}} is available!</li>\n {{else}}\n <li>Sorry, nobody is available for this task.</li>\n {{/each}}\n </ul>\n </template>\n}\n```",
6431
+ "description": "The `{{#each}}` keyword loops over elements in a collection. It is an extension\nof the base Handlebars `{{#each}}` helper.\n\nThe default behavior of `{{#each}}` is to yield its inner block once for every\nitem in an array passing the item as the first block parameter.\n\n```gjs {data-filename=\"app/components/developer-list.gjs\"}\nimport Component from '@glimmer/component';\n\nexport default class DeveloperList extends Component {\n developers = [\n { name: 'Yehuda' },\n { name: 'Tom' },\n { name: 'Paul' },\n ];\n\n <template>\n <ul>\n {{#each this.developers as |person|}}\n <li>Hello, {{person.name}}!</li>\n {{/each}}\n </ul>\n </template>\n}\n```\n\nThe same rules apply to arrays of primitives:\n\n```gjs {data-filename=\"app/components/developer-names.gjs\"}\nimport Component from '@glimmer/component';\n\nexport default class DeveloperNames extends Component {\n developerNames = ['Yehuda', 'Tom', 'Paul'];\n\n <template>\n <ul>\n {{#each this.developerNames as |name|}}\n <li>Hello, {{name}}!</li>\n {{/each}}\n </ul>\n </template>\n}\n```\n\n`{{#each}}` also supports native JavaScript [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set)\nvalues and other iterables:\n\n```gjs {data-filename=\"app/components/developer-set.gjs\"}\nimport Component from '@glimmer/component';\n\nexport default class DeveloperSet extends Component {\n developers = new Set([\n { name: 'Yehuda' },\n { name: 'Tom' },\n { name: 'Paul' },\n ]);\n\n <template>\n <ul>\n {{#each this.developers as |person|}}\n <li>Hello, {{person.name}}!</li>\n {{/each}}\n </ul>\n </template>\n}\n```\n\nDuring iteration, the index of each item in the array is provided as a second\nblock parameter:\n\n```gjs {data-filename=\"app/components/developer-list-with-index.gjs\"}\nimport Component from '@glimmer/component';\n\nexport default class DeveloperListWithIndex extends Component {\n developers = [\n { name: 'Yehuda' },\n { name: 'Tom' },\n { name: 'Paul' },\n ];\n\n <template>\n <ul>\n {{#each this.developers as |person index|}}\n <li>Hello, {{person.name}}! You're number {{index}} in line</li>\n {{/each}}\n </ul>\n </template>\n}\n```\n\n`#each` is a keyword and does not need to be imported.\n\n### Specifying Keys\n\nIn order to improve rendering speed, Ember will try to reuse the DOM elements\nwhere possible. Specifically, if the same item is present in the array both\nbefore and after the change, its DOM output will be reused.\n\nThe `key` option is used to tell Ember how to determine if the items in the\narray being iterated over with `{{#each}}` has changed between renders. By\ndefault the item's object identity is used.\n\nThis is usually sufficient, so in most cases, the `key` option is simply not\nneeded. However, in some rare cases, the objects' identities may change even\nthough they represent the same underlying data.\n\nFor example, mapping over `people` produces a new array of new objects on each\nrender. Use `key` so Ember can match items across those renders:\n\n```gjs {data-filename=\"app/components/mapped-developers.gjs\"}\nimport Component from '@glimmer/component';\n\nexport default class MappedDevelopers extends Component {\n people = [\n { name: 'Yehuda' },\n { name: 'Tom' },\n { name: 'Paul' },\n ];\n\n get developers() {\n return this.people.map((person) => {\n return { ...person, type: 'developer' };\n });\n }\n\n <template>\n <ul>\n {{#each this.developers key=\"name\" as |person|}}\n <li>Hello, {{person.name}}!</li>\n {{/each}}\n </ul>\n </template>\n}\n```\n\nBy doing so, Ember will use the value of the property specified (`person.name`\nin the example) to find a \"match\" from the previous render. That is, if Ember\nhas previously seen an object from the `developers` array with a matching\nname, its DOM elements will be re-used.\n\nThere are two special values for `key`:\n\n * `@identity` - The item in the array itself. This is the default.\n * `@index` - The index of the item in the array.\n\n### {{else}} condition\n\n`{{#each}}` can have a matching `{{else}}`. The contents of this block will render\nif the collection is empty.\n\n```gjs {data-filename=\"app/components/available-developers.gjs\"}\nimport Component from '@glimmer/component';\n\nexport default class AvailableDevelopers extends Component {\n developers = [];\n\n <template>\n <ul>\n {{#each this.developers as |person|}}\n <li>{{person.name}} is available!</li>\n {{else}}\n <li>Sorry, nobody is available for this task.</li>\n {{/each}}\n </ul>\n </template>\n}\n```",
6432
6432
  "itemtype": "method",
6433
6433
  "name": "each",
6434
6434
  "static": 1,
@@ -6441,7 +6441,7 @@
6441
6441
  {
6442
6442
  "file": "packages/@ember/-internals/glimmer/lib/helpers/each-in.ts",
6443
6443
  "line": 189,
6444
- "description": "The `{{#each-in}}` keyword loops over properties on an object, or entries in a\nnative JavaScript [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map).\n\nFor example, given this component definition:\n\n```gjs {data-filename=\"app/components/developer-details.gjs\"}\nimport Component from '@glimmer/component';\nimport { tracked } from '@glimmer/tracking';\n\nexport default class DeveloperDetails extends Component {\n @tracked developer = {\n name: 'Shelly Sails',\n age: 42,\n };\n\n <template>\n <ul>\n {{#each-in this.developer as |key value|}}\n <li>{{key}}: {{value}}</li>\n {{/each-in}}\n </ul>\n </template>\n}\n```\n\nThis template would display all properties on the `developer`\nobject in a list, outputting their name and age:\n\n```html\n<ul>\n <li>name: Shelly Sails</li>\n <li>age: 42</li>\n</ul>\n```\n\nThe same pattern works with a `Map`:\n\n```gjs {data-filename=\"app/components/developer-map.gjs\"}\nimport Component from '@glimmer/component';\n\nexport default class DeveloperMap extends Component {\n map = new Map([\n ['name', 'Shelly Sails'],\n ['age', 42],\n ]);\n\n <template>\n <ul>\n {{#each-in this.map as |key value|}}\n <li>{{key}}: {{value}}</li>\n {{/each-in}}\n </ul>\n </template>\n}\n```\n\nWhen a `Map` uses object keys, you can pass `key=\"@identity\"` to explicitly\ntrack entries across re-renders using the JavaScript identity of each key:\n\n```gjs {data-filename=\"app/components/object-keyed-map.gjs\"}\nimport Component from '@glimmer/component';\n\nexport default class ObjectKeyedMap extends Component {\n map = new Map([\n [{ name: 'one' }, 'foo'],\n [{ name: 'two' }, 'bar'],\n ]);\n\n <template>\n <ul>\n {{#each-in this.map key=\"@identity\" as |key value|}}\n <li>{{key.name}}: {{value}}</li>\n {{/each-in}}\n </ul>\n </template>\n}\n```\n\n`#each-in` is a keyword and does not need to be imported.",
6444
+ "description": "The `{{#each-in}}` keyword loops over properties on an object, or entries in a\nnative JavaScript [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map).\n\nFor example, given this component definition:\n\n```gjs {data-filename=\"app/components/developer-details.gjs\"}\nimport Component from '@glimmer/component';\nimport { tracked } from '@glimmer/tracking';\n\nexport default class DeveloperDetails extends Component {\n @tracked developer = {\n name: 'Shelly Sails',\n age: 42,\n };\n\n <template>\n <ul>\n {{#each-in this.developer as |key value|}}\n <li>{{key}}: {{value}}</li>\n {{/each-in}}\n </ul>\n </template>\n}\n```\n\nThis template would display all properties on the `developer`\nobject in a list, outputting their name and age:\n\n```html\n<ul>\n <li>name: Shelly Sails</li>\n <li>age: 42</li>\n</ul>\n```\n\nThe same pattern works with a `Map`:\n\n```gjs {data-filename=\"app/components/developer-map.gjs\"}\nimport Component from '@glimmer/component';\n\nexport default class DeveloperMap extends Component {\n map = new Map([\n ['name', 'Shelly Sails'],\n ['age', 42],\n ]);\n\n <template>\n <ul>\n {{#each-in this.map as |key value|}}\n <li>{{key}}: {{value}}</li>\n {{/each-in}}\n </ul>\n </template>\n}\n```\n\nWhen a `Map` uses object keys, you can pass `key=\"@identity\"` to explicitly\ntrack entries across re-renders using the JavaScript identity of each key:\n\n```gjs {data-filename=\"app/components/object-keyed-map.gjs\"}\nimport Component from '@glimmer/component';\n\nexport default class ObjectKeyedMap extends Component {\n map = new Map([\n [{ name: 'one' }, 'foo'],\n [{ name: 'two' }, 'bar'],\n ]);\n\n <template>\n <ul>\n {{#each-in this.map key=\"@identity\" as |key value|}}\n <li>{{key.name}}: {{value}}</li>\n {{/each-in}}\n </ul>\n </template>\n}\n```\n\n`#each-in` is a keyword and does not need to be imported.\n\n### Specifying Keys\n\nLike `{{#each}}`, `{{#each-in}}` accepts a `key` option to decide which DOM\nelements can be reused between renders. Since `{{#each-in}}` yields two block\nparams, the special values pick which one is used:\n\n * `@identity` - The second block param: the property's value. This is the\n default. Changing a value replaces that entry's DOM instead of updating it\n in place.\n * `@key` - The first block param: the property name, or for a `Map`, its key.\n\nAny other string is a path, looked up on the value: `key=\"id\"` keys each entry\nby its `value.id`.\n\nFor example, `@key` keeps each entry's DOM as its score changes, so anything\nstateful inside it — focus, a running transition, a component instance — survives\nthe update:\n\n```handlebars\n{{#each-in this.scores key=\"@key\" as |player score|}}\n <PlayerScore @name={{player}} @score={{score}} />\n{{/each-in}}\n```",
6445
6445
  "itemtype": "method",
6446
6446
  "name": "each-in",
6447
6447
  "static": 1,
package/package.json CHANGED
@@ -1,15 +1,24 @@
1
1
  {
2
2
  "name": "ember-source",
3
- "version": "7.3.0-beta.1",
3
+ "version": "7.4.0-alpha.1",
4
4
  "description": "A JavaScript framework for creating ambitious web applications",
5
- "type": "module",
5
+ "keywords": [
6
+ "ember-addon"
7
+ ],
8
+ "homepage": "https://emberjs.com/",
9
+ "bugs": {
10
+ "url": "https://github.com/emberjs/ember.js/issues"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/emberjs/ember.js.git"
15
+ },
16
+ "license": "MIT",
6
17
  "sideEffects": [
7
18
  "./dist/*/packages/ember-testing/index.js",
8
19
  "./dist/*/packages/@ember/-internals/runtime/lib/ext/rsvp.js"
9
20
  ],
10
- "keywords": [
11
- "ember-addon"
12
- ],
21
+ "type": "module",
13
22
  "exports": {
14
23
  "./*": {
15
24
  "development": "./dist/dev/packages/*",
@@ -21,12 +30,17 @@
21
30
  },
22
31
  "./package.json": "./package.json"
23
32
  },
24
- "homepage": "https://emberjs.com/",
25
- "bugs": {
26
- "url": "https://github.com/emberjs/ember.js/issues"
27
- },
28
- "license": "MIT",
29
33
  "main": "lib/index.cjs",
34
+ "typesVersions": {
35
+ "*": {
36
+ "types": [
37
+ "types/stable"
38
+ ],
39
+ "types/preview": [
40
+ "types/preview"
41
+ ]
42
+ }
43
+ },
30
44
  "files": [
31
45
  "build-metadata.json",
32
46
  "blueprints",
@@ -35,19 +49,14 @@
35
49
  "lib",
36
50
  "types/stable"
37
51
  ],
38
- "repository": {
39
- "type": "git",
40
- "url": "git+https://github.com/emberjs/ember.js.git"
41
- },
42
52
  "scripts": {
43
53
  "actions-up": "pnpm dlx actions-up",
44
54
  "bench": "node ./bin/benchmark.mjs",
45
55
  "bench:precompile": "node --expose-gc bin/precompile.bench.mjs",
56
+ "build": "npm-run-all build:*",
46
57
  "build:js": "rollup --config",
47
58
  "build:types": "node types/publish.mjs",
48
- "build": "npm-run-all build:*",
49
59
  "docs": "ember ember-cli-yuidoc",
50
- "start": "vite dev",
51
60
  "lint": "npm-run-all --continue-on-error --aggregate-output --parallel \"lint:!(fix)\"",
52
61
  "lint:docs": "qunit tests/docs/coverage-test.cjs",
53
62
  "lint:eslint": "eslint --report-unused-disable-directives --cache .",
@@ -55,16 +64,20 @@
55
64
  "lint:fix": "npm-run-all lint:*:fix",
56
65
  "lint:format": "prettier --check .",
57
66
  "lint:format:fix": "prettier --write .",
67
+ "start": "vite dev",
58
68
  "test": "testem ci -f testem.cjs --host 127.0.0.1 --port 13141",
59
69
  "test:blueprints": "pnpm --filter ember-test-node-blueprints test:node",
70
+ "test:browserstack": "node bin/run-browserstack-tests.cjs",
60
71
  "test:node": "qunit tests/node/**/*-test.cjs",
61
72
  "test:node:vitest": "pnpm --filter ember-test-node-vitest test:node",
62
- "test:browserstack": "node bin/run-browserstack-tests.cjs",
63
73
  "test:wip": "vite build --mode development --minify false && testem ci",
64
- "type-check:internals": "tsc --noEmit",
74
+ "type-check": "npm-run-all type-check:*",
65
75
  "type-check:handlebars": "tsc --noEmit --project packages/@handlebars/parser/tsconfig.json",
66
- "type-check:types": "tsc --noEmit --project type-tests",
67
- "type-check": "npm-run-all type-check:*"
76
+ "type-check:internals": "tsc --noEmit",
77
+ "type-check:types": "tsc --noEmit --project type-tests"
78
+ },
79
+ "resolutions": {
80
+ "socket.io": "^4.7.0"
68
81
  },
69
82
  "dependencies": {
70
83
  "@babel/core": "^7.24.4",
@@ -135,6 +148,7 @@
135
148
  "prettier": "^3.5.3",
136
149
  "qunit": "^2.19.4",
137
150
  "recast": "^0.22.0",
151
+ "release-plan": "^0.19.0",
138
152
  "resolve.exports": "^2.0.3",
139
153
  "rollup": "^4.57.1",
140
154
  "router_js": "workspace:*",
@@ -147,33 +161,34 @@
147
161
  "typescript-eslint": "^8.59.2",
148
162
  "vite": "^7.0.0"
149
163
  },
150
- "resolutions": {
151
- "socket.io": "^4.7.0"
164
+ "peerDependencies": {
165
+ "@glimmer/component": ">= 1.1.2"
166
+ },
167
+ "packageManager": "pnpm@10.33.2",
168
+ "engines": {
169
+ "node": ">= 20.19"
170
+ },
171
+ "release-plan": {
172
+ "ignore": true
152
173
  },
153
174
  "pnpm": {
154
- "overrides": {
155
- "rollup": "^4.2.0",
156
- "ember-cli-htmlbars": "^7.0.0",
157
- "babel-plugin-ember-template-compilation": "^4.0.0",
158
- "ember-cli-babel": "^8.3.1",
159
- "testem": "^3.20.1"
160
- },
161
175
  "onlyBuiltDependencies": [
162
176
  "@swc/core",
163
177
  "core-js",
164
178
  "esbuild"
165
179
  ],
180
+ "overrides": {
181
+ "babel-plugin-ember-template-compilation": "^4.0.0",
182
+ "ember-cli-babel": "^8.3.1",
183
+ "ember-cli-htmlbars": "^7.0.0",
184
+ "rollup": "^4.2.0",
185
+ "testem": "^3.20.1"
186
+ },
166
187
  "patchedDependencies": {
167
188
  "@tracerbench/core@8.0.1": "patches/@tracerbench__core@8.0.1.patch",
168
189
  "agadoo": "patches/agadoo.patch"
169
190
  }
170
191
  },
171
- "peerDependencies": {
172
- "@glimmer/component": ">= 1.1.2"
173
- },
174
- "engines": {
175
- "node": ">= 20.19"
176
- },
177
192
  "ember-addon": {
178
193
  "after": "ember-cli-legacy-blueprints",
179
194
  "type": "addon",
@@ -359,20 +374,9 @@
359
374
  "rsvp/index.js": "ember-source/rsvp/index.js"
360
375
  }
361
376
  },
362
- "typesVersions": {
363
- "*": {
364
- "types": [
365
- "types/stable"
366
- ],
367
- "types/preview": [
368
- "types/preview"
369
- ]
370
- }
371
- },
372
- "packageManager": "pnpm@10.33.2",
373
- "_originalVersion": "7.3.0-beta.1",
377
+ "_originalVersion": "7.4.0-alpha.1",
374
378
  "_versionPreviouslyCalculated": true,
375
379
  "publishConfig": {
376
- "tag": "beta"
380
+ "tag": "alpha"
377
381
  }
378
382
  }
@@ -142,8 +142,8 @@ declare module '@ember/-internals/glimmer/lib/helpers/each-in' {
142
142
 
143
143
  There are two special values for `key`:
144
144
 
145
+ * `@identity` - The item in the array itself. This is the default.
145
146
  * `@index` - The index of the item in the array.
146
- * `@identity` - The item in the array itself.
147
147
 
148
148
  ### {{else}} condition
149
149
 
@@ -255,6 +255,30 @@ declare module '@ember/-internals/glimmer/lib/helpers/each-in' {
255
255
 
256
256
  `#each-in` is a keyword and does not need to be imported.
257
257
 
258
+ ### Specifying Keys
259
+
260
+ Like `{{#each}}`, `{{#each-in}}` accepts a `key` option to decide which DOM
261
+ elements can be reused between renders. Since `{{#each-in}}` yields two block
262
+ params, the special values pick which one is used:
263
+
264
+ * `@identity` - The second block param: the property's value. This is the
265
+ default. Changing a value replaces that entry's DOM instead of updating it
266
+ in place.
267
+ * `@key` - The first block param: the property name, or for a `Map`, its key.
268
+
269
+ Any other string is a path, looked up on the value: `key="id"` keys each entry
270
+ by its `value.id`.
271
+
272
+ For example, `@key` keeps each entry's DOM as its score changes, so anything
273
+ stateful inside it — focus, a running transition, a component instance — survives
274
+ the update:
275
+
276
+ ```handlebars
277
+ {{#each-in this.scores key="@key" as |player score|}}
278
+ <PlayerScore @name={{player}} @score={{score}} />
279
+ {{/each-in}}
280
+ ```
281
+
258
282
  @method each-in
259
283
  @static
260
284
  @noimport