diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000000..3f38641bd1a --- /dev/null +++ b/.npmrc @@ -0,0 +1,5 @@ +# super strict mode +auto-install-peers=false +resolve-peers-from-workspace-root=false + + diff --git a/lib/index.js b/lib/index.js index 5a1a043dfb8..36ac10b24c3 100644 --- a/lib/index.js +++ b/lib/index.js @@ -8,7 +8,7 @@ const buildDebugMacroPlugin = require('./build-debug-macro-plugin'); const buildStripClassCallcheckPlugin = require('./build-strip-class-callcheck-plugin'); const injectBabelHelpers = require('./transforms/inject-babel-helpers').injectBabelHelpers; const debugTree = require('broccoli-debug').buildDebugCallback('ember-source:addon'); -const vmBabelPlugins = require('@glimmer/vm-babel-plugins'); +const { default: vmBabelPlugins } = require('@glimmer/vm-babel-plugins'); const Overrides = require('./overrides'); const SilentError = require('silent-error'); const SupportedBrowsers = require('./browsers'); @@ -156,10 +156,6 @@ module.exports = { babelHelperPlugin, buildDebugMacroPlugin(!isProduction), ...vmBabelPlugins({ isDebug: !isProduction }), - [ - require.resolve('@babel/plugin-transform-block-scoping'), - { throwIfClosureRequired: true }, - ], ], }), }; diff --git a/package.json b/package.json index 3d0044223e3..a4560658016 100644 --- a/package.json +++ b/package.json @@ -55,25 +55,25 @@ }, "dependencies": { "@babel/helper-module-imports": "^7.16.7", - "@babel/plugin-transform-block-scoping": "^7.22.5", "@ember/edition-utils": "^1.2.0", - "@glimmer/compiler": "0.84.3", + "@glimmer/compiler": "0.85.13", "@glimmer/component": "^1.1.2", - "@glimmer/destroyable": "0.84.3", + "@glimmer/destroyable": "0.85.13", "@glimmer/env": "^0.1.7", - "@glimmer/global-context": "0.84.3", - "@glimmer/interfaces": "0.84.3", - "@glimmer/manager": "0.84.3", - "@glimmer/node": "0.84.3", - "@glimmer/opcode-compiler": "0.84.3", - "@glimmer/owner": "0.84.3", - "@glimmer/program": "0.84.3", - "@glimmer/reference": "0.84.3", - "@glimmer/runtime": "0.84.3", - "@glimmer/syntax": "0.84.3", - "@glimmer/util": "0.84.3", - "@glimmer/validator": "0.84.3", - "@glimmer/vm-babel-plugins": "0.84.3", + "@glimmer/global-context": "0.85.13", + "@glimmer/interfaces": "0.85.13", + "@glimmer/manager": "0.85.13", + "@glimmer/node": "0.85.13", + "@glimmer/opcode-compiler": "0.85.13", + "@glimmer/owner": "0.85.13", + "@glimmer/program": "0.85.13", + "@glimmer/reference": "0.85.13", + "@glimmer/runtime": "0.85.13", + "@glimmer/syntax": "0.85.13", + "@glimmer/util": "0.85.13", + "@glimmer/validator": "0.85.13", + "@glimmer/vm": "0.85.13", + "@glimmer/vm-babel-plugins": "0.85.13", "@simple-dom/interface": "^1.4.0", "babel-plugin-debug-macros": "^0.3.4", "babel-plugin-filter-imports": "^4.0.0", @@ -173,6 +173,11 @@ "resolutions": { "socket.io": "^4.7.0" }, + "pnpm": { + "overrides": { + "rollup": "^4.2.0" + } + }, "peerDependencies": { "@glimmer/component": "^1.1.2" }, @@ -194,6 +199,6 @@ }, "volta": { "node": "16.20.0", - "pnpm": "8.7.6" + "pnpm": "8.10.0" } } diff --git a/packages/@ember/-internals/glimmer/lib/component-managers/curly.ts b/packages/@ember/-internals/glimmer/lib/component-managers/curly.ts index e29c7d176d4..23d004c28f5 100644 --- a/packages/@ember/-internals/glimmer/lib/component-managers/curly.ts +++ b/packages/@ember/-internals/glimmer/lib/component-managers/curly.ts @@ -6,6 +6,7 @@ import { } from '@ember/-internals/owner'; import { enumerableSymbol, guidFor } from '@ember/-internals/utils'; import { addChildView, setElementView, setViewElement } from '@ember/-internals/views'; +import type { Nullable } from '@ember/-internals/utility-types'; import { assert, debugFreeze } from '@ember/debug'; import { _instrumentStart } from '@ember/instrumentation'; import { DEBUG } from '@glimmer/env'; @@ -17,7 +18,6 @@ import type { ElementOperations, Environment, InternalComponentCapabilities, - Option, PreparedArguments, TemplateFactory, VMArguments, @@ -154,7 +154,7 @@ export default class CurlyComponentManager return this.templateFor(bucket.component); } - getTagName(state: ComponentStateBucket): Option { + getTagName(state: ComponentStateBucket): Nullable { let { component, hasWrappedElement } = state; if (!hasWrappedElement) { @@ -168,7 +168,7 @@ export default class CurlyComponentManager return CURLY_CAPABILITIES; } - prepareArgs(ComponentClass: ComponentFactory, args: VMArguments): Option { + prepareArgs(ComponentClass: ComponentFactory, args: VMArguments): Nullable { if (args.named.has('__ARGS__')) { assert( '[BUG] cannot pass both __ARGS__ and positional arguments', @@ -467,7 +467,7 @@ export default class CurlyComponentManager } } - getDestroyable(bucket: ComponentStateBucket): Option { + getDestroyable(bucket: ComponentStateBucket): Nullable { return bucket; } } diff --git a/packages/@ember/-internals/glimmer/lib/component-managers/mount.ts b/packages/@ember/-internals/glimmer/lib/component-managers/mount.ts index 8fad1b2f9d7..068d30c8fbf 100644 --- a/packages/@ember/-internals/glimmer/lib/component-managers/mount.ts +++ b/packages/@ember/-internals/glimmer/lib/component-managers/mount.ts @@ -10,7 +10,6 @@ import type { Destroyable, Environment, InternalComponentCapabilities, - Option, TemplateFactory, VMArguments, WithCreateInstance, @@ -18,6 +17,7 @@ import type { WithDynamicLayout, WithSubOwner, } from '@glimmer/interfaces'; +import type { Nullable } from '@ember/-internals/utility-types'; import { capabilityFlagsFrom } from '@glimmer/manager'; import type { Reference } from '@glimmer/reference'; import { createConstRef, valueForRef } from '@glimmer/reference'; @@ -149,7 +149,7 @@ class MountManager return self; } - getDestroyable(bucket: EngineState): Option { + getDestroyable(bucket: EngineState): Nullable { return bucket.engine; } diff --git a/packages/@ember/-internals/glimmer/lib/component-managers/outlet.ts b/packages/@ember/-internals/glimmer/lib/component-managers/outlet.ts index f914687b421..39cf2cfd29c 100644 --- a/packages/@ember/-internals/glimmer/lib/component-managers/outlet.ts +++ b/packages/@ember/-internals/glimmer/lib/component-managers/outlet.ts @@ -8,18 +8,18 @@ import type { CapturedArguments, CompilableProgram, ComponentDefinition, + CapabilityMask, CustomRenderNode, Destroyable, Environment, InternalComponentCapabilities, - InternalComponentCapability, - Option, Template, VMArguments, WithCreateInstance, WithCustomDebugRenderTree, WithDynamicTagName, } from '@glimmer/interfaces'; +import type { Nullable } from '@ember/-internals/utility-types'; import { capabilityFlagsFrom } from '@glimmer/manager'; import type { Reference } from '@glimmer/reference'; import { createConstRef, valueForRef } from '@glimmer/reference'; @@ -179,7 +179,7 @@ class OutletComponentManager didUpdateLayout() {} - getDestroyable(): Option { + getDestroyable(): Nullable { return null; } } @@ -195,7 +195,7 @@ export class OutletComponentDefinition public resolvedName: string; public compilable: CompilableProgram; - public capabilities: InternalComponentCapability; + public capabilities: CapabilityMask; constructor( public state: OutletDefinitionState, diff --git a/packages/@ember/-internals/glimmer/lib/component-managers/root.ts b/packages/@ember/-internals/glimmer/lib/component-managers/root.ts index 96039c6ef3f..00aca8f633c 100644 --- a/packages/@ember/-internals/glimmer/lib/component-managers/root.ts +++ b/packages/@ember/-internals/glimmer/lib/component-managers/root.ts @@ -6,10 +6,10 @@ import type { ComponentDefinition, Environment, InternalComponentCapabilities, - Option, Owner, VMArguments, } from '@glimmer/interfaces'; +import type { Nullable } from '@ember/-internals/utility-types'; import { capabilityFlagsFrom } from '@glimmer/manager'; import { CONSTANT_TAG, consumeTag } from '@glimmer/validator'; import type Component from '../component'; @@ -32,7 +32,7 @@ class RootComponentManager extends CurlyComponentManager { create( _owner: Owner, _state: unknown, - _args: Option, + _args: Nullable, { isInteractive }: Environment, dynamicScope: DynamicScope ) { diff --git a/packages/@ember/-internals/glimmer/lib/components/link-to.ts b/packages/@ember/-internals/glimmer/lib/components/link-to.ts index 97c119a10f2..f5110758a4e 100644 --- a/packages/@ember/-internals/glimmer/lib/components/link-to.ts +++ b/packages/@ember/-internals/glimmer/lib/components/link-to.ts @@ -8,7 +8,8 @@ import { flaggedInstrument } from '@ember/instrumentation'; import { action } from '@ember/object'; import { service } from '@ember/service'; import { DEBUG } from '@glimmer/env'; -import type { Maybe, Option } from '@glimmer/interfaces'; +import type { Maybe } from '@glimmer/interfaces'; +import type { Nullable } from '@ember/-internals/utility-types'; import { consumeTag, createCache, getValue, tagFor, untrack } from '@glimmer/validator'; import type { Transition } from 'router_js'; import LinkToTemplate from '../templates/link-to'; @@ -31,7 +32,7 @@ function isPresent(value: Maybe): value is T { interface QueryParams { isQueryParams: true; - values: Option<{}>; + values: Nullable<{}>; } function isQueryParams(value: unknown): value is QueryParams { @@ -473,7 +474,7 @@ class _LinkTo extends InternalComponent { return this.isActiveForState(this.routing.currentState as Maybe); } - private get willBeActive(): Option { + private get willBeActive(): Nullable { let current = this.routing.currentState; let target = this.routing.targetState; @@ -585,7 +586,7 @@ class _LinkTo extends InternalComponent { let { prototype } = _LinkTo; -let descriptorFor = (target: object, property: string): Option => { +let descriptorFor = (target: object, property: string): Nullable => { if (target) { return ( Object.getOwnPropertyDescriptor(target, property) || diff --git a/packages/@ember/-internals/glimmer/lib/environment.ts b/packages/@ember/-internals/glimmer/lib/environment.ts index 90c2f27ca88..ffa77980ad5 100644 --- a/packages/@ember/-internals/glimmer/lib/environment.ts +++ b/packages/@ember/-internals/glimmer/lib/environment.ts @@ -9,7 +9,7 @@ import { schedule, _backburner } from '@ember/runloop'; import { DEBUG } from '@glimmer/env'; import setGlobalContext from '@glimmer/global-context'; import type { EnvironmentDelegate } from '@glimmer/runtime'; -import { setTrackingTransactionEnv } from '@glimmer/validator'; +import { debug } from '@glimmer/validator'; import toIterator from './utils/iterator'; import { isHTMLSafe } from './utils/string'; import toBool from './utils/to-bool'; @@ -92,7 +92,7 @@ setGlobalContext({ }); if (DEBUG) { - setTrackingTransactionEnv?.({ + debug?.setTrackingTransactionEnv?.({ debugMessage(obj, keyName) { let dirtyString = keyName ? `\`${keyName}\` on \`${getDebugName?.(obj)}\`` diff --git a/packages/@ember/-internals/glimmer/lib/helpers/action.ts b/packages/@ember/-internals/glimmer/lib/helpers/action.ts index d803e5c98f2..8f2423972ab 100644 --- a/packages/@ember/-internals/glimmer/lib/helpers/action.ts +++ b/packages/@ember/-internals/glimmer/lib/helpers/action.ts @@ -10,10 +10,9 @@ import { DEBUG } from '@glimmer/env'; import type { CapturedArguments } from '@glimmer/interfaces'; import type { Reference } from '@glimmer/reference'; import { createUnboundRef, isInvokableRef, updateRef, valueForRef } from '@glimmer/reference'; -import { _WeakSet } from '@glimmer/util'; import { internalHelper } from './internal-helper'; -export const ACTIONS = new _WeakSet(); +export const ACTIONS = new WeakSet(); /** The `{{action}}` helper provides a way to pass triggers for behavior (usually @@ -299,7 +298,12 @@ export default internalHelper((args: CapturedArguments): Reference => } else { fn = makeDynamicClosureAction( valueForRef(context) as object, + // SAFETY: glimmer-vm should expose narrowing utilities for references + // as is, `target` is still `Reference`. + // however, we never even tried to narrow `target`, so this is potentially risky code. target!, + // SAFETY: glimmer-vm should expose narrowing utilities for references + // as is, `action` is still `Reference` action, processArgs, debugKey @@ -349,27 +353,23 @@ function makeArgsProcessor(valuePathRef: Reference | false, actionArgsRef: Refer function makeDynamicClosureAction( context: object, - targetRef: Reference, - actionRef: Reference, + targetRef: Reference, + actionRef: Reference, processArgs: (args: unknown[]) => unknown[], debugKey: string ) { + const action = valueForRef(actionRef); + // We don't allow undefined/null values, so this creates a throw-away action to trigger the assertions if (DEBUG) { - makeClosureAction( - context, - valueForRef(targetRef), - valueForRef(actionRef), - processArgs, - debugKey - ); + makeClosureAction(context, valueForRef(targetRef), action, processArgs, debugKey); } return (...args: any[]) => { return makeClosureAction( context, valueForRef(targetRef), - valueForRef(actionRef), + action, processArgs, debugKey )(...args); @@ -377,18 +377,18 @@ function makeDynamicClosureAction( } interface MaybeActionHandler { - actions?: Record; + actions?: Record; } function makeClosureAction( context: object, - target: MaybeActionHandler, - action: string | AnyFn, + target: unknown, + action: unknown | null | undefined | string | Function, processArgs: (args: unknown[]) => unknown[], debugKey: string ) { let self: object; - let fn: AnyFn; + let fn: Function; assert( `Action passed is null or undefined in (action) from ${target}.`, @@ -396,10 +396,15 @@ function makeClosureAction( ); if (typeof action === 'string') { + assert('target must be an object', target !== null && typeof target === 'object'); self = target; - fn = (target.actions && target.actions[action as string])!; - - assert(`An action named '${action}' was not found in ${target}`, Boolean(fn)); + let value = (target as { actions?: Record }).actions?.[action]; + assert(`An action named '${action}' was not found in ${target}`, Boolean(value)); + assert( + `An action named '${action}' was found in ${target}, but is not a function`, + typeof value === 'function' + ); + fn = value; } else if (typeof action === 'function') { self = context; fn = action; @@ -417,7 +422,7 @@ function makeClosureAction( return (...args: any[]) => { let payload = { target: self, args, label: '@glimmer/closure-action' }; return flaggedInstrument('interaction.ember-action', payload, () => { - return join(self, fn, ...processArgs(args)); + return join(self, fn as AnyFn, ...processArgs(args)); }); }; } diff --git a/packages/@ember/-internals/glimmer/lib/helpers/unique-id.ts b/packages/@ember/-internals/glimmer/lib/helpers/unique-id.ts index 211f4192963..edf1d29eeab 100644 --- a/packages/@ember/-internals/glimmer/lib/helpers/unique-id.ts +++ b/packages/@ember/-internals/glimmer/lib/helpers/unique-id.ts @@ -30,7 +30,12 @@ import { createConstRef } from '@glimmer/reference'; import { internalHelper } from './internal-helper'; export default internalHelper((): Reference => { - return createConstRef(uniqueId(), 'unique-id'); + // SAFETY: glimmer-vm should change the signature of createUnboundRef to use a generic + // so that the type param to `Reference` can infer from the first argument. + // + // NOTE: constRef is an optimization so we don't let the VM create extra wrappers, + // tracking frames, etc. + return createConstRef(uniqueId(), 'unique-id') as Reference; }); // From https://gist.github.com/selfish/fef2c0ba6cdfe07af76e64cecd74888b diff --git a/packages/@ember/-internals/glimmer/lib/renderer.ts b/packages/@ember/-internals/glimmer/lib/renderer.ts index 3b036cd9a2e..1c9c0e44469 100644 --- a/packages/@ember/-internals/glimmer/lib/renderer.ts +++ b/packages/@ember/-internals/glimmer/lib/renderer.ts @@ -16,15 +16,16 @@ import type { DynamicScope as GlimmerDynamicScope, ElementBuilder, Environment, - Option, RenderResult, RuntimeContext, Template, TemplateFactory, } from '@glimmer/interfaces'; -import { CurriedType } from '@glimmer/interfaces'; + +import { CurriedType } from '@glimmer/vm'; +import type { Nullable } from '@ember/-internals/utility-types'; import { programCompilationContext } from '@glimmer/opcode-compiler'; -import { artifacts } from '@glimmer/program'; +import { artifacts, RuntimeOpImpl } from '@glimmer/program'; import type { Reference } from '@glimmer/reference'; import { createConstRef, UNDEFINED_REFERENCE, valueForRef } from '@glimmer/reference'; import type { CurriedValue } from '@glimmer/runtime'; @@ -54,7 +55,7 @@ import OutletView from './views/outlet'; export type IBuilder = (env: Environment, cursor: Cursor) => ElementBuilder; export interface View { - parentView: Option; + parentView: Nullable; renderer: Renderer; tagName: string | null; elementId: string | null; @@ -335,7 +336,11 @@ export class Renderer { let sharedArtifacts = artifacts(); - this._context = programCompilationContext(sharedArtifacts, resolver); + this._context = programCompilationContext( + sharedArtifacts, + resolver, + (heap) => new RuntimeOpImpl(heap) + ); let runtimeEnvironmentDelegate = new EmberEnvironmentDelegate(owner, env.isInteractive); this._runtime = runtimeContext( @@ -459,7 +464,7 @@ export class Renderer { this._clearAllRoots(); } - getElement(view: View): Option { + getElement(view: View): Nullable { if (this._isInteractive) { return getViewElement(view); } else { diff --git a/packages/@ember/-internals/glimmer/lib/resolver.ts b/packages/@ember/-internals/glimmer/lib/resolver.ts index 9496140c0fa..5ad07efc0c4 100644 --- a/packages/@ember/-internals/glimmer/lib/resolver.ts +++ b/packages/@ember/-internals/glimmer/lib/resolver.ts @@ -9,12 +9,12 @@ import type { CompileTimeResolver, HelperDefinitionState, ModifierDefinitionState, - Option, ResolvedComponentDefinition, RuntimeResolver, Template, TemplateFactory, } from '@glimmer/interfaces'; +import type { Nullable } from '@ember/-internals/utility-types'; import { getComponentTemplate, getInternalComponentManager, @@ -30,7 +30,6 @@ import { templateOnlyComponent, TEMPLATE_ONLY_COMPONENT_MANAGER, } from '@glimmer/runtime'; -import { _WeakSet } from '@glimmer/util'; import { isCurlyManager } from './component-managers/curly'; import { CLASSIC_HELPER_MANAGER, isClassicHelper } from './helper'; import { default as disallowDynamicResolution } from './helpers/-disallow-dynamic-resolution'; @@ -56,7 +55,7 @@ function instrumentationPayload(name: string) { function componentFor( name: string, owner: InternalOwner -): Option | object> { +): Nullable | object> { let fullName = `component:${name}` as const; return owner.factoryFor(fullName) || null; } @@ -65,7 +64,7 @@ function layoutFor( name: string, owner: InternalOwner, options?: RegisterOptions -): Option