Skip to content

Commit

Permalink
provide debug utlities for inspector via event communication
Browse files Browse the repository at this point in the history
  • Loading branch information
patricklx committed Feb 8, 2024
1 parent 12106b7 commit 208881f
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 3 deletions.
4 changes: 2 additions & 2 deletions packages/@ember/-internals/metal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ export {
} from './lib/observer';
export { default as inject, DEBUG_INJECTION_FUNCTIONS } from './lib/injected_property';
export { tagForProperty, tagForObject, markObjectAsDirty } from './lib/tags';
export { tracked, TrackedDescriptor } from './lib/tracked';
export { cached } from './lib/cached';
export { tracked, TrackedDescriptor, isTrackedProperty } from './lib/tracked';
export { cached, isCachedProperty } from './lib/cached';
export { createCache, getValue, isConst } from './lib/cache';

export {
Expand Down
10 changes: 9 additions & 1 deletion packages/@ember/-internals/metal/lib/cached.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import { DEBUG } from '@glimmer/env';
import { createCache, getValue } from '@glimmer/validator';

const CacheMap = new WeakMap();

/**
* @decorator
*
Expand Down Expand Up @@ -84,7 +86,7 @@ import { createCache, getValue } from '@glimmer/validator';
the subsequent cache invalidations of the `@cached` properties who were
using this `trackedProp`.
Remember that setting tracked data should only be done during initialization,
Remember that setting tracked data should only be done during initialization,
or as the result of a user action. Setting tracked data during render
(such as in a getter), is not supported.
Expand All @@ -111,6 +113,8 @@ export const cached: MethodDecorator = (...args: any[]) => {
throwCachedGetterOnlyError(key);
}

CacheMap.set(target, [...(CacheMap.get(target) || []), key]);

const caches = new WeakMap();
const getter = descriptor.get;

Expand Down Expand Up @@ -144,3 +148,7 @@ function throwCachedInvalidArgsError(args: unknown[] = []): never {
)}), which is not supported. Dependencies are automatically tracked, so you can just use ${'`@cached`'}`
);
}

export function isCachedProperty(object: object, prop: string) {
return (CacheMap.get(object) || []).includes(prop);
}
4 changes: 4 additions & 0 deletions packages/@ember/-internals/metal/lib/tracked.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,7 @@ export class TrackedDescriptor {
this._set.call(obj, value);
}
}

export function isTrackedProperty(object: object, prop: string): boolean {
return metaFor(object).peekDescriptors(prop) instanceof TrackedDescriptor;
}
1 change: 1 addition & 0 deletions packages/@ember/-internals/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ export {
setupMandatorySetter,
teardownMandatorySetter,
setWithMandatorySetter,
isMandatorySetter,
} from './lib/mandatory-setter';
7 changes: 7 additions & 0 deletions packages/@ember/-internals/utils/lib/mandatory-setter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export let setupMandatorySetter:
export let teardownMandatorySetter: ((obj: object, keyName: string | symbol) => void) | undefined;
export let setWithMandatorySetter: ((obj: object, keyName: string, value: any) => void) | undefined;

export let isMandatorySetter: ((obj: object, keyName: string) => boolean) | undefined;

type PropertyDescriptorWithMeta = PropertyDescriptor & { hadOwnProperty?: boolean };

function isElementKey(key: string | number | symbol) {
Expand Down Expand Up @@ -93,6 +95,11 @@ if (DEBUG) {
});
};

isMandatorySetter = function (obj: object, keyName: string) {
let setters = MANDATORY_SETTERS.get(obj);
return setters !== undefined && setters[keyName] !== undefined;
};

teardownMandatorySetter = function (obj: object, keyName: string | symbol) {
let setters = MANDATORY_SETTERS.get(obj);

Expand Down
123 changes: 123 additions & 0 deletions packages/@ember/debug/ember-inspector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// required for inspector
import { isTesting } from './lib/testing';
import { _backburner, cancel, debounce, join, later, scheduleOnce } from '@ember/runloop';
import { cacheFor, guidFor } from '@ember/object/internals';
import { default as MutableArray } from '@ember/array/mutable';
import { default as Namespace } from '@ember/application/namespace';
import { default as MutableEnumerable } from '@ember/enumerable/mutable';
import { NativeArray } from '@ember/array';
import { ControllerMixin } from '@ember/controller';
import { default as CoreObject } from '@ember/object/core';
import { default as Application } from '@ember/application';
import { default as EmberComponent } from '@ember/component';
import { default as Observable } from '@ember/object/observable';
import { default as Evented } from '@ember/object/evented';
import { default as PromiseProxyMixin } from '@ember/object/promise-proxy-mixin';
import { default as EmberObject } from '@ember/object';
import { default as VERSION } from 'ember/version';
import {
ComputedProperty,
isComputed,
descriptorForProperty,
descriptorForDecorator,
tagForProperty,
} from '@ember/-internals/metal';
import { isMandatorySetter } from '@ember/-internals/utils';
import { meta } from '@ember/-internals/meta';
import { TargetActionSupport } from '@ember/-internals/runtime';
import {
ViewStateSupport,
ViewMixin,
ActionSupport,
ClassNamesSupport,
ChildViewsSupport,
CoreView,
} from '@ember/-internals/views';
import { set, get } from '@ember/object';
import { isTrackedProperty } from '@ember/-internals/metal';
import { isCachedProperty } from '@ember/-internals/metal';
import { default as inspect } from './lib/inspect';
import { subscribe } from '../instrumentation';
import { default as captureRenderTree } from './lib/capture-render-tree';
import { registerHandler as registerDeprecationHandler } from './lib/deprecate';
import * as GlimmerValidator from '@glimmer/validator';
import * as GlimmerRuntime from '@glimmer/runtime';
import { getOwner } from '@ember/owner';
import RSVP from 'rsvp';

export function setupInspectorSupport() {
if (typeof window !== 'undefined' && window.addEventListener) {
window.addEventListener(
'ember-inspector-debug-request',
() => {
const event = new CustomEvent('ember-inspector-debug-response', {
detail: {
runloop: {
_backburner,
cancel,
debounce,
join,
later,
scheduleOnce,
},
object: {
cacheFor,
guidFor,
getOwner,
set,
get,
meta,
},
debug: {
isComputed,
isTrackedProperty,
isCachedProperty,
descriptorForProperty,
descriptorForDecorator,
isMandatorySetter,
meta,
captureRenderTree,
isTesting,
inspect,
registerDeprecationHandler,
tagForProperty,
ComputedProperty,
},
classes: {
EmberObject,
MutableArray,
Namespace,
MutableEnumerable,
NativeArray,
TargetActionSupport,
ControllerMixin,
CoreObject,
Application,
EmberComponent,
Observable,
Evented,
PromiseProxyMixin,
},
VERSION,
instrumentation: {
subscribe,
},
Views: {
ViewStateSupport,
ViewMixin,
ActionSupport,
ClassNamesSupport,
ChildViewsSupport,
CoreView,
},
GlimmerValidator,
GlimmerRuntime,
RSVP,
},
});
window.dispatchEvent(event);
},
false
);
}
}
1 change: 1 addition & 0 deletions packages/@ember/debug/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"exports": {
".": "./index.ts",
"./container-debug-adapter": "./container-debug-adapter.ts",
"./ember-inspector": "./ember-inspector.ts",
"./data-adapter": "./data-adapter.ts"
},
"dependencies": {
Expand Down
2 changes: 2 additions & 0 deletions packages/ember/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { meta as internalMeta } from '@ember/-internals/meta';
import * as metal from '@ember/-internals/metal';
import { FEATURES as EmberFEATURES, isEnabled } from '@ember/canary-features';
import * as EmberDebug from '@ember/debug';
import { setupInspectorSupport } from '@ember/debug/ember-inspector';
import { assert as emberAssert, captureRenderTree } from '@ember/debug';
import Backburner from 'backburner.js';
import EmberController, {
Expand Down Expand Up @@ -745,6 +746,7 @@ function defineEmberTestingLazyLoad(key: 'Test' | 'setupForTesting') {
defineEmberTestingLazyLoad('Test');
defineEmberTestingLazyLoad('setupForTesting');

setupInspectorSupport();
// @ts-expect-error Per types, runLoadHooks requires a second parameter. Should we loosen types?
applicationRunLoadHooks('Ember');

Expand Down

0 comments on commit 208881f

Please sign in to comment.