Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ export default [
},
},
{
files: ['packages/@glimmer/validator/**/*.ts'],
files: ['packages/@glimmer/signals/**/*.ts'],
rules: {
'@typescript-eslint/no-deprecated': 'off',
'@typescript-eslint/no-unnecessary-condition': 'off',
Expand Down
1 change: 0 additions & 1 deletion lib/index.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ const shim = addonV1Shim(path.join(__dirname, '..'), {
'./dist/dev/packages/@glimmer/tracking/index.js',
'./dist/dev/packages/@glimmer/tracking/primitives/cache/index.js',
'./dist/dev/packages/@glimmer/util/index.js',
'./dist/dev/packages/@glimmer/validator/index.js',
'./dist/dev/packages/@glimmer/vm/index.js',
'./dist/dev/packages/@glimmer/wire-format/index.js',
'./dist/dev/packages/@simple-dom/document/index.js',
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,6 @@
"@glimmer/tracking/index.js": "ember-source/@glimmer/tracking/index.js",
"@glimmer/tracking/primitives/cache/index.js": "ember-source/@glimmer/tracking/primitives/cache/index.js",
"@glimmer/util/index.js": "ember-source/@glimmer/util/index.js",
"@glimmer/validator/index.js": "ember-source/@glimmer/validator/index.js",
"@glimmer/vm/index.js": "ember-source/@glimmer/vm/index.js",
"@glimmer/wire-format/index.js": "ember-source/@glimmer/wire-format/index.js",
"@simple-dom/document/index.js": "ember-source/@simple-dom/document/index.js",
Expand Down
10 changes: 5 additions & 5 deletions packages/@ember/-internals/glimmer/lib/base-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { RuntimeOpImpl } from '@glimmer/program/lib/opcode';
import { clientBuilder } from '@glimmer/runtime/lib/vm/element-builder';
import { inTransaction, runtimeOptions } from '@glimmer/runtime/lib/environment';
import { renderComponent as glimmerRenderComponent } from '@glimmer/runtime/lib/render';
import { CURRENT_TAG, validateTag, valueForTag } from '@glimmer/validator/lib/validators';
import { writeCount } from '@glimmer/signals/lib/tags';
import type { SimpleDocument, SimpleElement } from '@simple-dom/interface';
import { hasDOM } from '../../browser-environment';
import { EmberEnvironmentDelegate } from './environment';
Expand Down Expand Up @@ -295,7 +295,7 @@ export class RendererState {
* and that run loop throws the same error again.
*/
if (!completedWithoutError) {
this.#lastRevision = valueForTag(CURRENT_TAG);
this.#lastRevision = writeCount();
}
this.#inRenderTransaction = false;
}
Expand Down Expand Up @@ -342,7 +342,7 @@ export class RendererState {
root.render();
}

this.#lastRevision = valueForTag(CURRENT_TAG);
this.#lastRevision = writeCount();
});
} while (roots.length > initialRootsLength);

Expand Down Expand Up @@ -386,12 +386,12 @@ export class RendererState {
* True when there is nothing to render:
* no roots, or no tracked value changed after the last render.
*
* `CURRENT_TAG` stands for every tag,
* `writeCount()` changes with a write to any tag,
* so one changed value anywhere in the app makes every renderer invalid.
* Each root then finds out for itself if the change applies to it.
*/
isValid(): boolean {
return this.#roots.length === 0 || validateTag(CURRENT_TAG, this.#lastRevision);
return this.#roots.length === 0 || this.#lastRevision === writeCount();
}

revalidate(): void {
Expand Down
32 changes: 17 additions & 15 deletions packages/@ember/-internals/glimmer/lib/component-managers/curly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,15 @@ import { reifyPositional } from '@glimmer/runtime/lib/vm/arguments';
import { EMPTY_ARRAY } from '@glimmer/util/lib/array-utils';
import { unwrapTemplate } from './unwrap-template';
import {
beginTrackFrame,
beginFrame,
beginUntrackFrame,
consumeFrame,
consumeTag,
endTrackFrame,
createFrame,
endFrame,
endUntrackFrame,
} from '@glimmer/validator/lib/tracking';
import { validateTag, valueForTag } from '@glimmer/validator/lib/validators';
isFrameStale,
} from '@glimmer/signals/lib/tags';
import type Component from '../component';
import type { DynamicScope } from '../renderer';
import type RuntimeResolver from '../resolver';
Expand Down Expand Up @@ -275,9 +277,11 @@ export default class CurlyComponentManager
// copy of the Arguments object that is safe to hold on to between renders.
let capturedArgs = args.named.capture();

beginTrackFrame();
let argsFrame = createFrame();

beginFrame(argsFrame);
let props = processComponentArgs(capturedArgs);
let argsTag = endTrackFrame();
endFrame();

// Alias `id` argument to `elementId` property on the component instance.
aliasIdToElementId(args, props);
Expand Down Expand Up @@ -341,7 +345,7 @@ export default class CurlyComponentManager
let bucket = new ComponentStateBucket(
component,
capturedArgs,
argsTag,
argsFrame,
finalizer,
hasWrappedElement,
isInteractive
Expand All @@ -362,7 +366,7 @@ export default class CurlyComponentManager
endUntrackFrame();

// consume every argument so we always run again
consumeTag(bucket.argsTag);
consumeFrame(bucket.argsFrame);
consumeTag(component[DIRTY_TAG]);

return bucket;
Expand Down Expand Up @@ -440,18 +444,16 @@ export default class CurlyComponentManager
}

update(bucket: ComponentStateBucket): void {
let { component, args, argsTag, argsRevision, isInteractive } = bucket;
let { component, args, argsFrame, isInteractive } = bucket;

bucket.finalizer = _instrumentStart('render.component', rerenderInstrumentDetails, component);

beginUntrackFrame();

if (args !== null && !validateTag(argsTag, argsRevision)) {
beginTrackFrame();
if (args !== null && isFrameStale(argsFrame)) {
beginFrame(argsFrame);
let props = processComponentArgs(args);
argsTag = bucket.argsTag = endTrackFrame();

bucket.argsRevision = valueForTag(argsTag);
endFrame();

component[IS_DISPATCHING_ATTRS] = true;
component.setProperties(props);
Expand All @@ -468,7 +470,7 @@ export default class CurlyComponentManager

endUntrackFrame();

consumeTag(argsTag);
consumeFrame(argsFrame);
consumeTag(component[DIRTY_TAG]);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import type {
} from '@glimmer/interfaces';
import type { Nullable } from '@ember/-internals/utility-types';
import { capabilityFlagsFrom } from '@glimmer/manager/lib/util/capabilities';
import { CONSTANT_TAG } from '@glimmer/validator/lib/validators';
import { consumeTag } from '@glimmer/validator/lib/tracking';
import { consumeTag, createFrame } from '@glimmer/signals/lib/tags';
import type Component from '../component';
import type { DynamicScope } from '../renderer';
import ComponentStateBucket from '../utils/curly-component-state-bucket';
Expand Down Expand Up @@ -66,7 +65,7 @@ class RootComponentManager extends CurlyComponentManager {
let bucket = new ComponentStateBucket(
component,
null,
CONSTANT_TAG,
createFrame(),
finalizer,
hasWrappedElement,
isInteractive
Expand Down
2 changes: 1 addition & 1 deletion packages/@ember/-internals/glimmer/lib/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { setInternalComponentManager } from '@glimmer/manager/lib/internal/api';
import { isUpdatableRef, updateRef } from '@glimmer/reference/lib/reference';
import { normalizeProperty } from '@glimmer/runtime/lib/dom/props';
import type { DirtyableTag } from '@glimmer/interfaces';
import { createTag, DIRTY_TAG as dirtyTag } from '@glimmer/validator/lib/validators';
import { createTag, dirtyTag } from '@glimmer/signals/lib/tags';
import type { SimpleElement } from '@simple-dom/interface';
import {
BOUNDS,
Expand Down
2 changes: 1 addition & 1 deletion packages/@ember/-internals/glimmer/lib/components/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { type Opaque } from '@ember/-internals/utility-types';
import { assert, warn } from '@ember/debug';
import { action } from '@ember/object';
import { valueForRef } from '@glimmer/reference/lib/reference';
import { untrack } from '@glimmer/validator/lib/tracking';
import { untrack } from '@glimmer/signals/lib/tags';
import InputTemplate from '../templates/input';
import AbstractInput, { valueFrom } from './abstract-input';
import { type OpaqueInternalComponentConstructor, opaquify } from './internal';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { setComponentTemplate } from '@glimmer/manager/lib/public/template';
import { setInternalComponentManager } from '@glimmer/manager/lib/internal/api';
import type { Reference } from '@glimmer/reference/lib/reference';
import { createConstRef, isConstRef, valueForRef } from '@glimmer/reference/lib/reference';
import { untrack } from '@glimmer/validator/lib/tracking';
import { untrack } from '@glimmer/signals/lib/tags';

function NOOP(): void {}

Expand Down
4 changes: 2 additions & 2 deletions packages/@ember/-internals/glimmer/lib/components/link-to.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import { service } from '@ember/service';
import { DEBUG } from '@glimmer/env';
import type { Maybe } from '@glimmer/interfaces';
import type { Nullable } from '@ember/-internals/utility-types';
import { consumeTag, createCache, getValue, untrack } from '@glimmer/validator/lib/tracking';
import { tagFor } from '@glimmer/validator/lib/meta';
import { consumeTag, createCache, getValue, untrack } from '@glimmer/signals/lib/tags';
import { tagFor } from '@glimmer/signals/lib/meta';
import type { Transition } from 'router_js';
import LinkToTemplate from '../templates/link-to';
import InternalComponent, { type OpaqueInternalComponentConstructor, opaquify } from './internal';
Expand Down
2 changes: 1 addition & 1 deletion packages/@ember/-internals/glimmer/lib/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { schedule, _backburner } from '@ember/runloop';
import { DEBUG } from '@glimmer/env';
import setGlobalContext from '@glimmer/global-context';
import type { EnvironmentDelegate } from '@glimmer/runtime/lib/environment';
import { debug } from '@glimmer/validator/lib/debug';
import { debug } from '@glimmer/signals/lib/debug';
import toIterator from './utils/iterator';
import { isHTMLSafe } from './utils/string';
import toBool from './utils/to-bool';
Expand Down
3 changes: 1 addition & 2 deletions packages/@ember/-internals/glimmer/lib/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import type { Arguments, HelperManager } from '@glimmer/interfaces';
import { helperCapabilities } from '@glimmer/manager/lib/public/helper';
import { setHelperManager } from '@glimmer/manager/lib/public/api';
import type { DirtyableTag } from '@glimmer/interfaces';
import { consumeTag } from '@glimmer/validator/lib/tracking';
import { createTag, DIRTY_TAG as dirtyTag } from '@glimmer/validator/lib/validators';
import { consumeTag, createTag, dirtyTag } from '@glimmer/signals/lib/tags';
import { IS_CLASSIC_HELPER } from './helper-brand';

export { isClassicHelper } from './helper-brand';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { isObject } from '@ember/-internals/utils/lib/spec';
import { assert } from '@ember/debug';
import type { CapturedArguments } from '@glimmer/interfaces';
import { createComputeRef, valueForRef } from '@glimmer/reference/lib/reference';
import { consumeTag } from '@glimmer/validator/lib/tracking';
import { consumeTag } from '@glimmer/signals/lib/tags';
import { internalHelper } from './internal-helper';

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/@ember/-internals/glimmer/lib/helpers/each-in.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { isProxy } from '@ember/-internals/utils/lib/is_proxy';
import { assert } from '@ember/debug';
import type { CapturedArguments } from '@glimmer/interfaces';
import { createComputeRef, valueForRef } from '@glimmer/reference/lib/reference';
import { consumeTag } from '@glimmer/validator/lib/tracking';
import { consumeTag } from '@glimmer/signals/lib/tags';
import { internalHelper } from './internal-helper';

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ import { registerDestructor } from '@glimmer/destroyable';
import type { CapturedNamedArguments } from '@glimmer/interfaces';
import type { Reference } from '@glimmer/reference/lib/reference';
import { createConstRef } from '@glimmer/reference/lib/reference';
import type { Revision } from '@glimmer/validator/lib/validators';
import type { Tag } from '@glimmer/interfaces';
import { beginUntrackFrame, endUntrackFrame } from '@glimmer/validator/lib/tracking';
import { valueForTag } from '@glimmer/validator/lib/validators';
import { beginUntrackFrame, endUntrackFrame } from '@glimmer/signals/lib/tags';
import type { TagNode } from '@glimmer/signals/lib/tags';
import type Component from '../component';

type Finalizer = () => void;
Expand All @@ -30,18 +28,16 @@ function NOOP() {}
export default class ComponentStateBucket {
public classRef: Reference | null = null;
public rootRef: Reference<Component>;
public argsRevision: Revision;

constructor(
public component: Component,
public args: CapturedNamedArguments | null,
public argsTag: Tag,
public argsFrame: TagNode,
public finalizer: Finalizer,
public hasWrappedElement: boolean,
public isInteractive: boolean
) {
this.classRef = null;
this.argsRevision = args === null ? 0 : valueForTag(argsTag);
this.rootRef = createConstRef(component, 'this');

registerDestructor(this, () => this.willDestroy(), true);
Expand Down
4 changes: 2 additions & 2 deletions packages/@ember/-internals/glimmer/lib/utils/iterator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { isEmberArray } from '@ember/array/-internals';
import { isObject } from '@ember/-internals/utils/lib/spec';
import type { Nullable } from '@ember/-internals/utility-types';
import type { IteratorDelegate } from '@glimmer/reference/lib/iterable';
import { consumeTag, isTracking } from '@glimmer/validator/lib/tracking';
import { tagFor } from '@glimmer/validator/lib/meta';
import { consumeTag, isTracking } from '@glimmer/signals/lib/tags';
import { tagFor } from '@glimmer/signals/lib/meta';
import { EachInWrapper } from '../helpers/each-in';
import type { NativeArray } from '@ember/array';

Expand Down
2 changes: 1 addition & 1 deletion packages/@ember/-internals/glimmer/lib/utils/to-bool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { get } from '@ember/-internals/metal/lib/property_get';
import { tagForProperty } from '@ember/-internals/metal/lib/tags';
import isArray from '@ember/array/lib/is-array';
import { isProxy } from '@ember/-internals/utils/lib/is_proxy';
import { consumeTag } from '@glimmer/validator/lib/tracking';
import { consumeTag } from '@glimmer/signals/lib/tags';

export default function toBool(predicate: unknown): boolean {
if (isProxy(predicate)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { set } from '@ember/object';
import { getOwner } from '@ember/-internals/owner';
import Service, { service } from '@ember/service';
import { DEBUG } from '@glimmer/env';
import { getValue } from '@glimmer/validator';
import { getValue } from '@glimmer/signals';
import { destroy, isDestroyed, registerDestructor } from '@glimmer/destroyable';
import { invokeHelper } from '@glimmer/runtime';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from 'internal-test-helpers';
import { setProperties } from '@ember/object';
import { uniqueId, invokeHelper } from '@ember/helper';
import { getValue } from '@glimmer/validator';
import { getValue } from '@glimmer/signals';

moduleFor(
'Helpers test: {{unique-id}} JS',
Expand Down
27 changes: 15 additions & 12 deletions packages/@ember/-internals/meta/lib/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import toString from '@ember/-internals/utils/lib/to-string';
import { assert } from '@ember/debug';
import { isDestroyed } from '@glimmer/destroyable';
import { DEBUG } from '@glimmer/env';
import type { Revision } from '@glimmer/validator/lib/validators';
import type { UpdatableTag } from '@glimmer/interfaces';

type ObjMap<T> = { [key: string]: T };
Expand Down Expand Up @@ -99,7 +98,7 @@ export class Meta {
/** @internal */
_values: ObjMap<unknown> | undefined;
/** @internal */
_revisions: ObjMap<Revision> | undefined;
_cached: ObjMap<boolean> | undefined;
/** @internal */
source: object;
/** @internal */
Expand Down Expand Up @@ -127,7 +126,7 @@ export class Meta {
this._mixins = undefined;
this._lazyChains = undefined;
this._values = undefined;
this._revisions = undefined;
this._cached = undefined;

// initial value for all flags right now is false
// see FLAGS const for detailed list of flags used
Expand Down Expand Up @@ -170,7 +169,7 @@ export class Meta {
}

/** @internal */
_getOrCreateOwnMap(key: '_values' | '_revisions' | '_lazyChains') {
_getOrCreateOwnMap(key: '_values' | '_cached' | '_lazyChains') {
return this[key] || (this[key] = Object.create(null));
}

Expand Down Expand Up @@ -221,18 +220,22 @@ export class Meta {
values[key] = value;
}

/** @internal */
revisionFor(key: string): Revision | undefined {
let revisions = this._revisions;
/**
* `true` when `valueFor` holds a computed value for the key.
*
* The value is valid while the tag of the property is fresh.
*
* @internal
*/
hasCacheFor(key: string): boolean {
let cached = this._cached;

return revisions !== undefined ? revisions[key] : undefined;
return cached !== undefined && cached[key] === true;
}

/** @internal */
setRevisionFor(key: string, revision: Revision | undefined) {
let revisions = this._getOrCreateOwnMap('_revisions');

revisions[key] = revision;
setCachedFor(key: string, isCached: boolean) {
this._getOrCreateOwnMap('_cached')[key] = isCached;
}

/** @internal */
Expand Down
1 change: 1 addition & 0 deletions packages/@ember/-internals/metal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export {
} from './lib/observer';
export { default as inject, DEBUG_INJECTION_FUNCTIONS } from './lib/injected_property';
export { tagForProperty, tagForObject, markObjectAsDirty } from './lib/tags';
export { consumeTag } from '@glimmer/signals/lib/tags';
export { tracked, TrackedDescriptor } from './lib/tracked';
export { cached } from './lib/cached';
export { createCache, getValue, isConst } from './lib/cache';
Expand Down
Loading
Loading