ember-source 6.3.0-alpha.2 → 6.3.0-alpha.3

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.
Files changed (28) hide show
  1. package/build-metadata.json +3 -3
  2. package/dist/ember-template-compiler.js +2 -2
  3. package/dist/ember-testing.js +1 -1
  4. package/dist/ember.debug.js +305 -71
  5. package/dist/ember.prod.js +258 -69
  6. package/dist/packages/@ember/-internals/glimmer/index.js +2 -2
  7. package/dist/packages/@ember/application/index.js +2 -2
  8. package/dist/packages/@ember/application/instance.js +1 -1
  9. package/dist/packages/@ember/component/helper.js +1 -1
  10. package/dist/packages/@ember/component/index.js +1 -1
  11. package/dist/packages/@ember/engine/index.js +2 -2
  12. package/dist/packages/@ember/helper/index.js +1 -1
  13. package/dist/packages/@ember/modifier/index.js +1 -1
  14. package/dist/packages/@ember/renderer/index.js +1 -1
  15. package/dist/packages/@ember/routing/index.js +1 -1
  16. package/dist/packages/@ember/routing/route.js +46 -4
  17. package/dist/packages/@ember/template/index.js +1 -1
  18. package/dist/packages/ember/barrel.js +1 -1
  19. package/dist/packages/ember/version.js +1 -1
  20. package/dist/packages/ember-testing/lib/initializers.js +1 -1
  21. package/dist/packages/shared-chunks/{index-C7oKNWrX.js → index-4KqgXTKl.js} +256 -64
  22. package/dist/packages/shared-chunks/{setup-registry-CFRLjlg1.js → setup-registry-ziuiqoKc.js} +1 -1
  23. package/docs/data.json +94 -76
  24. package/package.json +2 -2
  25. package/types/stable/@ember/-internals/glimmer/lib/component-managers/outlet.d.ts +14 -21
  26. package/types/stable/@ember/-internals/glimmer/lib/component-managers/route-template.d.ts +78 -0
  27. package/types/stable/@ember/-internals/glimmer/lib/utils/outlet.d.ts +3 -2
  28. package/types/stable/index.d.ts +1 -0
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "6.3.0-alpha.2",
2
+ "version": "6.3.0-alpha.3",
3
3
  "buildType": "tag",
4
- "SHA": "7c742a2195dbb9014bc1b134a4dba52b8cbc1ecc",
5
- "assetPath": "/tag/shas/7c742a2195dbb9014bc1b134a4dba52b8cbc1ecc.tgz"
4
+ "SHA": "77200c1aea9b214d4027b0734d9198f20ca2587d",
5
+ "assetPath": "/tag/shas/77200c1aea9b214d4027b0734d9198f20ca2587d.tgz"
6
6
  }
@@ -5,7 +5,7 @@
5
5
  * Portions Copyright 2008-2011 Apple Inc. All rights reserved.
6
6
  * @license Licensed under MIT license
7
7
  * See https://raw.github.com/emberjs/ember.js/master/LICENSE
8
- * @version 6.3.0-alpha.2
8
+ * @version 6.3.0-alpha.3
9
9
  */
10
10
  /* eslint-disable no-var */
11
11
  /* globals global globalThis self */
@@ -15651,7 +15651,7 @@ var define, require;
15651
15651
  }, Symbol.toStringTag, { value: 'Module' });
15652
15652
 
15653
15653
  // this file gets replaced with the real value during the build
15654
- const version = '6.3.0-alpha.2';
15654
+ const version = '6.3.0-alpha.3';
15655
15655
 
15656
15656
  const emberVersion = /*#__PURE__*/Object.defineProperty({
15657
15657
  __proto__: null,
@@ -5,7 +5,7 @@
5
5
  * Portions Copyright 2008-2011 Apple Inc. All rights reserved.
6
6
  * @license Licensed under MIT license
7
7
  * See https://raw.github.com/emberjs/ember.js/master/LICENSE
8
- * @version 6.3.0-alpha.2
8
+ * @version 6.3.0-alpha.3
9
9
  */
10
10
  /* eslint-disable no-var */
11
11
  /* globals global globalThis self */
@@ -5,7 +5,7 @@
5
5
  * Portions Copyright 2008-2011 Apple Inc. All rights reserved.
6
6
  * @license Licensed under MIT license
7
7
  * See https://raw.github.com/emberjs/ember.js/master/LICENSE
8
- * @version 6.3.0-alpha.2
8
+ * @version 6.3.0-alpha.3
9
9
  */
10
10
  /* eslint-disable no-var */
11
11
  /* globals global globalThis self */
@@ -3379,7 +3379,7 @@ var define, require;
3379
3379
  }, Symbol.toStringTag, { value: 'Module' });
3380
3380
 
3381
3381
  // this file gets replaced with the real value during the build
3382
- const Version = '6.3.0-alpha.2';
3382
+ const Version = '6.3.0-alpha.3';
3383
3383
 
3384
3384
  const emberVersion = /*#__PURE__*/Object.defineProperty({
3385
3385
  __proto__: null,
@@ -5301,7 +5301,7 @@ var define, require;
5301
5301
  function hasInternalModifierManager(definition) {
5302
5302
  return void 0 !== getManager(MODIFIER_MANAGERS, definition);
5303
5303
  }
5304
- const CAPABILITIES$4 = {
5304
+ const CAPABILITIES$5 = {
5305
5305
  dynamicLayout: !1,
5306
5306
  dynamicTag: !1,
5307
5307
  prepareArgs: !1,
@@ -5436,7 +5436,7 @@ var define, require;
5436
5436
  return null;
5437
5437
  }
5438
5438
  getCapabilities() {
5439
- return CAPABILITIES$4;
5439
+ return CAPABILITIES$5;
5440
5440
  }
5441
5441
  }
5442
5442
 
@@ -19750,7 +19750,7 @@ var define, require;
19750
19750
  let item = vm.stack.peek().next();
19751
19751
  null !== item ? vm.registerItem(vm.enterItem(item)) : vm.goto(breaks);
19752
19752
  });
19753
- const CAPABILITIES$3 = {
19753
+ const CAPABILITIES$4 = {
19754
19754
  dynamicLayout: !1,
19755
19755
  dynamicTag: !1,
19756
19756
  prepareArgs: !1,
@@ -19767,7 +19767,7 @@ var define, require;
19767
19767
  };
19768
19768
  class TemplateOnlyComponentManager {
19769
19769
  getCapabilities() {
19770
- return CAPABILITIES$3;
19770
+ return CAPABILITIES$4;
19771
19771
  }
19772
19772
  getDebugName({
19773
19773
  name: name
@@ -21899,7 +21899,7 @@ var define, require;
21899
21899
  (!(constructor) && assert$1(`[BUG] Invalid internal component constructor: ${opaque}`, constructor));
21900
21900
  return constructor;
21901
21901
  }
21902
- const CAPABILITIES$2 = {
21902
+ const CAPABILITIES$3 = {
21903
21903
  dynamicLayout: false,
21904
21904
  dynamicTag: false,
21905
21905
  prepareArgs: false,
@@ -21916,7 +21916,7 @@ var define, require;
21916
21916
  };
21917
21917
  class InternalManager {
21918
21918
  getCapabilities() {
21919
- return CAPABILITIES$2;
21919
+ return CAPABILITIES$3;
21920
21920
  }
21921
21921
  create(owner, definition, args, _env, _dynamicScope, caller) {
21922
21922
  (!(isConstRef(caller)) && assert$1('caller must be const', isConstRef(caller)));
@@ -27406,7 +27406,7 @@ var define, require;
27406
27406
  object: `${def.name}:main`
27407
27407
  };
27408
27408
  }
27409
- const CAPABILITIES$1 = {
27409
+ const CAPABILITIES$2 = {
27410
27410
  dynamicLayout: false,
27411
27411
  dynamicTag: false,
27412
27412
  prepareArgs: false,
@@ -27421,27 +27421,34 @@ var define, require;
27421
27421
  willDestroy: false,
27422
27422
  hasSubOwner: false
27423
27423
  };
27424
+ const CAPABILITIES_MASK$1 = capabilityFlagsFrom(CAPABILITIES$2);
27424
27425
  class OutletComponentManager {
27425
27426
  create(_owner, definition, _args, env, dynamicScope) {
27426
27427
  let parentStateRef = dynamicScope.get('outletState');
27427
27428
  let currentStateRef = definition.ref;
27429
+
27430
+ // This is the actual primary responsibility of the outlet component –
27431
+ // it represents the switching from one route component/template into
27432
+ // the next. The rest only exists to support the debug render tree and
27433
+ // the old-school (and unreliable) instrumentation.
27428
27434
  dynamicScope.set('outletState', currentStateRef);
27429
27435
  let state = {
27430
- self: createConstRef(definition.controller, 'this'),
27431
27436
  finalize: _instrumentStart('render.outlet', instrumentationPayload$1, definition)
27432
27437
  };
27433
27438
  if (env.debugRenderTree !== undefined) {
27434
- state.outletBucket = {};
27435
27439
  let parentState = valueForRef(parentStateRef);
27436
- let parentOwner = parentState && parentState.render && parentState.render.owner;
27437
- let currentOwner = valueForRef(currentStateRef).render.owner;
27440
+ let parentOwner = parentState?.render?.owner;
27441
+ let currentState = valueForRef(currentStateRef);
27442
+ let currentOwner = currentState?.render?.owner;
27438
27443
  if (parentOwner && parentOwner !== currentOwner) {
27439
27444
  (!(currentOwner instanceof EngineInstance) && assert$1('Expected currentOwner to be an EngineInstance', currentOwner instanceof EngineInstance));
27440
- let mountPoint = currentOwner.mountPoint;
27441
- state.engine = currentOwner;
27445
+ let {
27446
+ mountPoint
27447
+ } = currentOwner;
27442
27448
  if (mountPoint) {
27443
- state.engineBucket = {
27444
- mountPoint
27449
+ state.engine = {
27450
+ mountPoint,
27451
+ instance: currentOwner
27445
27452
  };
27446
27453
  }
27447
27454
  }
@@ -27451,13 +27458,12 @@ var define, require;
27451
27458
  getDebugName({
27452
27459
  name
27453
27460
  }) {
27454
- return name;
27461
+ return `{{outlet}} for ${name}`;
27455
27462
  }
27456
- getDebugCustomRenderTree(definition, state, args) {
27463
+ getDebugCustomRenderTree(_definition, state) {
27457
27464
  let nodes = [];
27458
- (!(state.outletBucket) && assert$1('[BUG] outletBucket must be set', state.outletBucket));
27459
27465
  nodes.push({
27460
- bucket: state.outletBucket,
27466
+ bucket: state,
27461
27467
  type: 'outlet',
27462
27468
  // "main" used to be the outlet name, keeping it around for compatibility
27463
27469
  name: 'main',
@@ -27465,33 +27471,23 @@ var define, require;
27465
27471
  instance: undefined,
27466
27472
  template: undefined
27467
27473
  });
27468
- if (state.engineBucket) {
27474
+ if (state.engine) {
27469
27475
  nodes.push({
27470
- bucket: state.engineBucket,
27476
+ bucket: state.engine,
27471
27477
  type: 'engine',
27472
- name: state.engineBucket.mountPoint,
27478
+ name: state.engine.mountPoint,
27473
27479
  args: EMPTY_ARGS,
27474
- instance: state.engine,
27480
+ instance: state.engine.instance,
27475
27481
  template: undefined
27476
27482
  });
27477
27483
  }
27478
- nodes.push({
27479
- bucket: state,
27480
- type: 'route-template',
27481
- name: definition.name,
27482
- args: args,
27483
- instance: definition.controller,
27484
- template: unwrapTemplate(definition.template).moduleName
27485
- });
27486
27484
  return nodes;
27487
27485
  }
27488
27486
  getCapabilities() {
27489
- return CAPABILITIES$1;
27487
+ return CAPABILITIES$2;
27490
27488
  }
27491
- getSelf({
27492
- self
27493
- }) {
27494
- return self;
27489
+ getSelf() {
27490
+ return UNDEFINED_REFERENCE;
27495
27491
  }
27496
27492
  didCreate() {}
27497
27493
  didUpdate() {}
@@ -27504,23 +27500,30 @@ var define, require;
27504
27500
  }
27505
27501
  }
27506
27502
  const OUTLET_MANAGER = new OutletComponentManager();
27507
- class OutletComponentDefinition {
27503
+ const OUTLET_COMPONENT_TEMPLATE = templateFactory(
27504
+ /*
27505
+ <@Component @controller={{@controller}} @model={{@model}} />
27506
+ */
27507
+ {
27508
+ "id": "tiv/fOHO",
27509
+ "block": "[[[8,[30,1],null,[[\"@controller\",\"@model\"],[[30,2],[30,3]]],null]],[\"@Component\",\"@controller\",\"@model\"],false,[]]",
27510
+ "moduleName": "/home/runner/work/ember.js/ember.js/packages/@ember/-internals/glimmer/lib/component-managers/outlet.ts",
27511
+ "isStrictMode": true
27512
+ });
27513
+ class OutletComponent {
27508
27514
  // handle is not used by this custom definition
27509
27515
  handle = -1;
27510
- resolvedName;
27516
+ resolvedName = null;
27517
+ manager = OUTLET_MANAGER;
27518
+ capabilities = CAPABILITIES_MASK$1;
27511
27519
  compilable;
27512
- capabilities;
27513
- constructor(state, manager = OUTLET_MANAGER) {
27520
+ constructor(owner, state) {
27514
27521
  this.state = state;
27515
- this.manager = manager;
27516
- let capabilities = manager.getCapabilities();
27517
- this.capabilities = capabilityFlagsFrom(capabilities);
27518
- this.compilable = capabilities.wrapped ? unwrapTemplate(state.template).asWrappedLayout() : unwrapTemplate(state.template).asLayout();
27519
- this.resolvedName = state.name;
27522
+ this.compilable = unwrapTemplate(OUTLET_COMPONENT_TEMPLATE(owner)).asLayout();
27520
27523
  }
27521
27524
  }
27522
27525
  function createRootOutlet(outletView) {
27523
- return new OutletComponentDefinition(outletView.state);
27526
+ return new OutletComponent(outletView.owner, outletView.state);
27524
27527
  }
27525
27528
 
27526
27529
  class RootComponentManager extends CurlyComponentManager {
@@ -37079,17 +37082,59 @@ var define, require;
37079
37082
  let controller = owner.lookup(`controller:${route.controllerName || name}`);
37080
37083
  (!(controller instanceof Controller) && assert$1('Expected an instance of controller', controller instanceof Controller));
37081
37084
  let model = route.currentModel;
37082
- let template = owner.lookup(`template:${route.templateName || name}`);
37085
+ let templateFactoryOrComponent = owner.lookup(`template:${route.templateName || name}`);
37086
+
37087
+ // Now we support either a component or a template to be returned by this
37088
+ // resolver call, but if it's a `TemplateFactory`, we need to instantiate
37089
+ // it into a `Template`, since that's what `RenderState` wants. We can't
37090
+ // easily change it, it's intimate API used by @ember/test-helpers and the
37091
+ // like. We could compatibly allow `Template` | `TemplateFactory`, and that's
37092
+ // what it used to do but we _just_ went through deprecations to get that
37093
+ // removed. It's also not ideal since once you mix the two types, they are
37094
+ // not exactly easy to tell apart.
37095
+ //
37096
+ // It may also be tempting to just normalize `Template` into `RouteTemplate`
37097
+ // here, and we could. However, this is not the only entrypoint where this
37098
+ // `RenderState` is made – @ember/test-helpers punches through an impressive
37099
+ // amount of private API to set it directly, and this feature would also be
37100
+ // useful for them. So, even if we had normalized here, we'd still have to
37101
+ // check and do that again during render anyway.
37102
+ let template;
37103
+ if (templateFactoryOrComponent) {
37104
+ if (hasInternalComponentManager(templateFactoryOrComponent)) {
37105
+ template = templateFactoryOrComponent;
37106
+ } else {
37107
+ if (typeof templateFactoryOrComponent !== 'function') {
37108
+ let label;
37109
+ try {
37110
+ label = `\`${String(templateFactoryOrComponent)}\``;
37111
+ } catch {
37112
+ label = 'an unknown object';
37113
+ }
37114
+ (assert$1(`Failed to render the ${name} route, expected ` + `\`template:${route.templateName || name}\` to resolve into ` + `a component or a \`TemplateFactory\`, got: ${label}. ` + `Most likely an improperly defined class or an invalid module export.`));
37115
+ }
37116
+ template = templateFactoryOrComponent(owner);
37117
+ }
37118
+ } else {
37119
+ // default `{{outlet}}`
37120
+ template = route._topLevelViewTemplate(owner);
37121
+ }
37083
37122
  let render = {
37084
37123
  owner,
37085
37124
  name,
37086
37125
  controller,
37087
37126
  model,
37088
- template: template?.(owner) ?? route._topLevelViewTemplate(owner)
37127
+ template
37089
37128
  };
37090
37129
  {
37091
37130
  let LOG_VIEW_LOOKUPS = get$2(route._router, 'namespace.LOG_VIEW_LOOKUPS');
37092
- if (LOG_VIEW_LOOKUPS && !template) {
37131
+ // This is covered by tests and the existing code was deliberately
37132
+ // targeting the value prior to normalization, but is this message actually
37133
+ // accurate? It seems like we will always default the `{{outlet}}` template
37134
+ // so I'm not sure about "Nothing will be rendered?" (who consumes these
37135
+ // logs anyway? as lookups happen more infrequently now I doubt this is all
37136
+ // that useful)
37137
+ if (LOG_VIEW_LOOKUPS && !templateFactoryOrComponent) {
37093
37138
  info(`Could not find "${name}" template. Nothing will be rendered`, {
37094
37139
  fullName: `template:${name}`
37095
37140
  });
@@ -39588,7 +39633,7 @@ var define, require;
39588
39633
  prefixRouteNameArg
39589
39634
  }, Symbol.toStringTag, { value: 'Module' });
39590
39635
 
39591
- const CAPABILITIES = {
39636
+ const CAPABILITIES$1 = {
39592
39637
  dynamicLayout: true,
39593
39638
  dynamicTag: false,
39594
39639
  prepareArgs: false,
@@ -39609,7 +39654,7 @@ var define, require;
39609
39654
  return unwrapTemplate(templateFactory(state.engine)).asLayout();
39610
39655
  }
39611
39656
  getCapabilities() {
39612
- return CAPABILITIES;
39657
+ return CAPABILITIES$1;
39613
39658
  }
39614
39659
  getOwner(state) {
39615
39660
  return state.engine;
@@ -39710,7 +39755,7 @@ var define, require;
39710
39755
  state;
39711
39756
  manager = MOUNT_MANAGER;
39712
39757
  compilable = null;
39713
- capabilities = capabilityFlagsFrom(CAPABILITIES);
39758
+ capabilities = capabilityFlagsFrom(CAPABILITIES$1);
39714
39759
  constructor(resolvedName) {
39715
39760
  this.resolvedName = resolvedName;
39716
39761
  this.state = {
@@ -39795,6 +39840,110 @@ var define, require;
39795
39840
  });
39796
39841
  });
39797
39842
 
39843
+ const CAPABILITIES = {
39844
+ dynamicLayout: false,
39845
+ dynamicTag: false,
39846
+ prepareArgs: false,
39847
+ createArgs: true,
39848
+ attributeHook: false,
39849
+ elementHook: false,
39850
+ createCaller: false,
39851
+ dynamicScope: false,
39852
+ updateHook: false,
39853
+ createInstance: true,
39854
+ wrapped: false,
39855
+ willDestroy: false,
39856
+ hasSubOwner: false
39857
+ };
39858
+ const CAPABILITIES_MASK = capabilityFlagsFrom(CAPABILITIES);
39859
+ class RouteTemplateManager {
39860
+ create(_owner, _definition, args) {
39861
+ let self = args.named.get('controller');
39862
+ {
39863
+ self = createDebugAliasRef('this', self);
39864
+ }
39865
+ let controller = valueForRef(self);
39866
+ return {
39867
+ self,
39868
+ controller
39869
+ };
39870
+ }
39871
+ getSelf({
39872
+ self
39873
+ }) {
39874
+ return self;
39875
+ }
39876
+ getDebugName({
39877
+ name
39878
+ }) {
39879
+ return `route-template (${name})`;
39880
+ }
39881
+ getDebugCustomRenderTree({
39882
+ name,
39883
+ templateName
39884
+ }, state, args) {
39885
+ return [{
39886
+ bucket: state,
39887
+ type: 'route-template',
39888
+ name,
39889
+ args,
39890
+ instance: state.controller,
39891
+ template: templateName
39892
+ }];
39893
+ }
39894
+ getCapabilities() {
39895
+ return CAPABILITIES;
39896
+ }
39897
+ didRenderLayout() {}
39898
+ didUpdateLayout() {}
39899
+ didCreate() {}
39900
+ didUpdate() {}
39901
+ getDestroyable() {
39902
+ return null;
39903
+ }
39904
+ }
39905
+ const ROUTE_TEMPLATE_MANAGER = new RouteTemplateManager();
39906
+
39907
+ /**
39908
+ * This "upgrades" a route template into a invocable component. Conceptually
39909
+ * it can be 1:1 for each unique `Template`, but it's also cheap to construct,
39910
+ * so unless the stability is desirable for other reasons, it's probably not
39911
+ * worth caching this.
39912
+ */
39913
+ class RouteTemplate {
39914
+ // handle is not used by this custom definition
39915
+ handle = -1;
39916
+ resolvedName;
39917
+ state;
39918
+ manager = ROUTE_TEMPLATE_MANAGER;
39919
+ capabilities = CAPABILITIES_MASK;
39920
+ compilable;
39921
+ constructor(name, template) {
39922
+ let unwrapped = unwrapTemplate(template);
39923
+ // TODO This actually seems inaccurate – it ultimately came from the
39924
+ // outlet's name. Also, setting this overrides `getDebugName()` in that
39925
+ // message. Is that desirable?
39926
+ this.resolvedName = name;
39927
+ this.state = {
39928
+ name,
39929
+ templateName: unwrapped.moduleName
39930
+ };
39931
+ this.compilable = unwrapped.asLayout();
39932
+ }
39933
+ }
39934
+
39935
+ // TODO a lot these fields are copied from the adjacent existing components
39936
+ // implementation, haven't looked into who cares about `ComponentDefinition`
39937
+ // and if it is appropriate here. It seems like this version is intended to
39938
+ // be used with `curry` which probably isn't necessary here. It could be the
39939
+ // case that we just want to do something more similar to `InternalComponent`
39940
+ // (the one we used to implement `Input` and `LinkTo`). For now it follows
39941
+ // the same pattern to get things going.
39942
+ function makeRouteTemplate(owner, name, template) {
39943
+ let routeTemplate = new RouteTemplate(name, template);
39944
+ return curry(CurriedTypes.Component, routeTemplate, owner, null, true);
39945
+ }
39946
+
39798
39947
  /**
39799
39948
  The `{{outlet}}` helper lets you specify where a child route will render in
39800
39949
  your template. An important use of the `{{outlet}}` helper is in your
@@ -39827,15 +39976,77 @@ var define, require;
39827
39976
  return state?.outlets?.main;
39828
39977
  });
39829
39978
  let lastState = null;
39830
- let definition = null;
39979
+ let outlet = null;
39831
39980
  return createComputeRef(() => {
39832
39981
  let outletState = valueForRef(outletRef);
39833
39982
  let state = stateFor(outletRef, outletState);
39834
- if (!validate(state, lastState)) {
39983
+
39984
+ // This code is deliberately using the behavior in glimmer-vm where in
39985
+ // <@Component />, the component is considered stabled via `===`, and
39986
+ // will continue to re-render in-place as long as the `===` holds, but
39987
+ // when it changes to a different object, it teardown the old component
39988
+ // (running destructors, etc), and render the component in its place (or
39989
+ // nothing if the new value is nullish. Here we are carefully exploiting
39990
+ // that fact, and returns the same stable object so long as it is the
39991
+ // same route, but return a different one when the route changes. On the
39992
+ // other hand, changing the model only intentionally do not teardown the
39993
+ // component and instead re-render in-place.
39994
+ if (!isStable(state, lastState)) {
39835
39995
  lastState = state;
39836
39996
  if (state !== null) {
39997
+ // If we are crossing an engine mount point, this is how the owner
39998
+ // gets switched.
39999
+ let outletOwner = outletState?.render?.owner ?? owner;
39837
40000
  let named = dict();
39838
40001
 
40002
+ // Here we either have a raw template that needs to be normalized,
40003
+ // or a component that we can render as-is. `RouteTemplate` upgrades
40004
+ // the template into a component so we can have a unified code path.
40005
+ // We still store the original `template` value, because we rely on
40006
+ // its identity for the stability check, and the `RouteTemplate`
40007
+ // wrapper doesn't dedup for us.
40008
+ let template = state.template;
40009
+ let component;
40010
+ if (hasInternalComponentManager(template)) {
40011
+ component = template;
40012
+ } else {
40013
+ {
40014
+ // We don't appear to have a standard way or a brand to check, but for the
40015
+ // purpose of avoiding obvious user errors, this probably gets you close
40016
+ // enough.
40017
+ let isTemplate = template => {
40018
+ if (template === null || typeof template !== 'object') {
40019
+ return false;
40020
+ } else {
40021
+ let t = template;
40022
+ return t.result === 'ok' || t.result === 'error';
40023
+ }
40024
+ };
40025
+
40026
+ // We made it past the `TemplateFactory` instantiation before
40027
+ // getting here, so either we got unlucky where the invalid type
40028
+ // happens to be a function that didn't mind taking owner as an
40029
+ // argument, or this was directly set by something like test
40030
+ // helpers.
40031
+ if (!isTemplate(template)) {
40032
+ let label;
40033
+ try {
40034
+ label = `\`${String(template)}\``;
40035
+ } catch {
40036
+ label = 'an unknown object';
40037
+ }
40038
+ (assert$1(`Failed to render the \`${state.name}\` route: expected ` + `a component or Template object, but got ${label}.`));
40039
+ }
40040
+ }
40041
+ component = makeRouteTemplate(outletOwner, state.name, template);
40042
+ }
40043
+
40044
+ // Component is stable for the lifetime of the outlet
40045
+ named['Component'] = createConstRef(component, '@Component');
40046
+
40047
+ // Controller is stable for the lifetime of the outlet
40048
+ named['controller'] = createConstRef(state.controller, '@controller');
40049
+
39839
40050
  // Create a ref for the model
39840
40051
  let modelRef = childRefFromParts(outletRef, ['render', 'model']);
39841
40052
 
@@ -39858,12 +40069,14 @@ var define, require;
39858
40069
  named['model'] = createDebugAliasRef('@model', named['model']);
39859
40070
  }
39860
40071
  let args = createCapturedArgs(named, EMPTY_POSITIONAL);
39861
- definition = curry(CurriedTypes.Component, new OutletComponentDefinition(state), outletState?.render?.owner ?? owner, args, true);
40072
+
40073
+ // Package up everything
40074
+ outlet = curry(CurriedTypes.Component, new OutletComponent(owner, state), outletOwner, args, true);
39862
40075
  } else {
39863
- definition = null;
40076
+ outlet = null;
39864
40077
  }
39865
40078
  }
39866
- return definition;
40079
+ return outlet;
39867
40080
  });
39868
40081
  });
39869
40082
  function stateFor(ref, outlet) {
@@ -39871,20 +40084,19 @@ var define, require;
39871
40084
  let render = outlet.render;
39872
40085
  if (render === undefined) return null;
39873
40086
  let template = render.template;
39874
- if (template === undefined) return null;
40087
+ // The type doesn't actually allow for `null`, but if we make it past this
40088
+ // point it is really important that we have _something_ to render. We could
40089
+ // assert, but that is probably overly strict for very little to gain.
40090
+ if (template === undefined || template === null) return null;
39875
40091
  return {
39876
40092
  ref,
39877
40093
  name: render.name,
39878
40094
  template,
39879
- controller: render.controller,
39880
- model: render.model
40095
+ controller: render.controller
39881
40096
  };
39882
40097
  }
39883
- function validate(state, lastState) {
39884
- if (state === null) {
39885
- return lastState === null;
39886
- }
39887
- if (lastState === null) {
40098
+ function isStable(state, lastState) {
40099
+ if (state === null || lastState === null) {
39888
40100
  return false;
39889
40101
  }
39890
40102
  return state.template === lastState.template && state.controller === lastState.controller;
@@ -40126,8 +40338,7 @@ var define, require;
40126
40338
  ref,
40127
40339
  name: TOP_LEVEL_NAME,
40128
40340
  template,
40129
- controller: undefined,
40130
- model: undefined
40341
+ controller: undefined
40131
40342
  };
40132
40343
  }
40133
40344
  appendTo(selector) {
@@ -40376,8 +40587,31 @@ var define, require;
40376
40587
  // renderer HOOKS
40377
40588
 
40378
40589
  appendOutletView(view, target) {
40379
- let definition = createRootOutlet(view);
40380
- this._appendDefinition(view, curry(CurriedTypes.Component, definition, view.owner, null, true), target);
40590
+ // TODO: This bypasses the {{outlet}} syntax so logically duplicates
40591
+ // some of the set up code. Since this is all internal (or is it?),
40592
+ // we can refactor this to do something more direct/less convoluted
40593
+ // and with less setup, but get it working first
40594
+ let outlet = createRootOutlet(view);
40595
+ let {
40596
+ name,
40597
+ /* controller, */template
40598
+ } = view.state;
40599
+ let named = dict();
40600
+ named['Component'] = createConstRef(makeRouteTemplate(view.owner, name, template), '@Component');
40601
+
40602
+ // TODO: is this guaranteed to be undefined? It seems to be the
40603
+ // case in the `OutletView` class. Investigate how much that class
40604
+ // exists as an internal implementation detail only, or if it was
40605
+ // used outside of core. As far as I can tell, test-helpers uses
40606
+ // it but only for `setOutletState`.
40607
+ // named['controller'] = createConstRef(controller, '@controller');
40608
+ // Update: at least according to the debug render tree tests, we
40609
+ // appear to always expect this to be undefined. Not a definitive
40610
+ // source by any means, but is useful evidence
40611
+ named['controller'] = UNDEFINED_REFERENCE;
40612
+ named['model'] = UNDEFINED_REFERENCE;
40613
+ let args = createCapturedArgs(named, EMPTY_POSITIONAL);
40614
+ this._appendDefinition(view, curry(CurriedTypes.Component, outlet, view.owner, args, true), target);
40381
40615
  }
40382
40616
  appendTo(view, target) {
40383
40617
  let definition = new RootComponentDefinition(view);