Skip to content

Commit 9307366

Browse files
committed
provide debug utlities for inspector via event communication
1 parent 12106b7 commit 9307366

File tree

8 files changed

+159
-3
lines changed

8 files changed

+159
-3
lines changed

packages/@ember/-internals/metal/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ export {
7070
} from './lib/observer';
7171
export { default as inject, DEBUG_INJECTION_FUNCTIONS } from './lib/injected_property';
7272
export { tagForProperty, tagForObject, markObjectAsDirty } from './lib/tags';
73-
export { tracked, TrackedDescriptor } from './lib/tracked';
74-
export { cached } from './lib/cached';
73+
export { tracked, TrackedDescriptor, isTrackedProperty } from './lib/tracked';
74+
export { cached, isCachedProperty } from './lib/cached';
7575
export { createCache, getValue, isConst } from './lib/cache';
7676

7777
export {

packages/@ember/-internals/metal/lib/cached.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import { DEBUG } from '@glimmer/env';
55
import { createCache, getValue } from '@glimmer/validator';
66

7+
const CacheMap = new WeakMap();
8+
79
/**
810
* @decorator
911
*
@@ -84,7 +86,7 @@ import { createCache, getValue } from '@glimmer/validator';
8486
the subsequent cache invalidations of the `@cached` properties who were
8587
using this `trackedProp`.
8688
87-
Remember that setting tracked data should only be done during initialization,
89+
Remember that setting tracked data should only be done during initialization,
8890
or as the result of a user action. Setting tracked data during render
8991
(such as in a getter), is not supported.
9092
@@ -111,6 +113,8 @@ export const cached: MethodDecorator = (...args: any[]) => {
111113
throwCachedGetterOnlyError(key);
112114
}
113115

116+
CacheMap.set(target, [...(CacheMap.get(target) || []), key]);
117+
114118
const caches = new WeakMap();
115119
const getter = descriptor.get;
116120

@@ -144,3 +148,7 @@ function throwCachedInvalidArgsError(args: unknown[] = []): never {
144148
)}), which is not supported. Dependencies are automatically tracked, so you can just use ${'`@cached`'}`
145149
);
146150
}
151+
152+
export function isCachedProperty(object: object, prop: string) {
153+
return (CacheMap.get(object) || []).includes(prop);
154+
}

packages/@ember/-internals/metal/lib/tracked.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,7 @@ export class TrackedDescriptor {
200200
this._set.call(obj, value);
201201
}
202202
}
203+
204+
export function isTrackedProperty(object: object, prop: string): boolean {
205+
return metaFor(object).peekDescriptors(prop) instanceof TrackedDescriptor;
206+
}

packages/@ember/-internals/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,5 @@ export {
3232
setupMandatorySetter,
3333
teardownMandatorySetter,
3434
setWithMandatorySetter,
35+
isMandatorySetter,
3536
} from './lib/mandatory-setter';

packages/@ember/-internals/utils/lib/mandatory-setter.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ export let setupMandatorySetter:
99
export let teardownMandatorySetter: ((obj: object, keyName: string | symbol) => void) | undefined;
1010
export let setWithMandatorySetter: ((obj: object, keyName: string, value: any) => void) | undefined;
1111

12+
export let isMandatorySetter: ((obj: object, keyName: string) => boolean) | undefined;
13+
1214
type PropertyDescriptorWithMeta = PropertyDescriptor & { hadOwnProperty?: boolean };
1315

1416
function isElementKey(key: string | number | symbol) {
@@ -93,6 +95,11 @@ if (DEBUG) {
9395
});
9496
};
9597

98+
isMandatorySetter = function (obj: object, keyName: string) {
99+
let setters = MANDATORY_SETTERS.get(obj);
100+
return setters !== undefined && setters[keyName] !== undefined;
101+
};
102+
96103
teardownMandatorySetter = function (obj: object, keyName: string | symbol) {
97104
let setters = MANDATORY_SETTERS.get(obj);
98105

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// required for inspector
2+
import { isTesting } from './lib/testing';
3+
import { _backburner, cancel, debounce, join, later, scheduleOnce } from '@ember/runloop';
4+
import { cacheFor, guidFor } from '@ember/object/internals';
5+
import { default as MutableArray } from '@ember/array/mutable';
6+
import { default as Namespace } from '@ember/application/namespace';
7+
import { default as MutableEnumerable } from '@ember/enumerable/mutable';
8+
import { NativeArray } from '@ember/array';
9+
import { ControllerMixin } from '@ember/controller';
10+
import { default as CoreObject } from '@ember/object/core';
11+
import { default as Application } from '@ember/application';
12+
import { default as EmberComponent } from '@ember/component';
13+
import { default as Observable } from '@ember/object/observable';
14+
import { default as Evented } from '@ember/object/evented';
15+
import { default as PromiseProxyMixin } from '@ember/object/promise-proxy-mixin';
16+
import { default as EmberObject } from '@ember/object';
17+
import { default as VERSION } from 'ember/version';
18+
import {
19+
ComputedProperty,
20+
isComputed,
21+
descriptorForProperty,
22+
descriptorForDecorator,
23+
tagForProperty,
24+
libraries,
25+
} from '@ember/-internals/metal';
26+
import { isMandatorySetter } from '@ember/-internals/utils';
27+
import { meta } from '@ember/-internals/meta';
28+
import { ActionHandler, TargetActionSupport } from '@ember/-internals/runtime';
29+
import {
30+
ViewStateSupport,
31+
ViewMixin,
32+
ActionSupport,
33+
ClassNamesSupport,
34+
ChildViewsSupport,
35+
CoreView,
36+
} from '@ember/-internals/views';
37+
import { set, get } from '@ember/object';
38+
import { isTrackedProperty } from '@ember/-internals/metal';
39+
import { isCachedProperty } from '@ember/-internals/metal';
40+
import { default as inspect } from './lib/inspect';
41+
import { subscribe } from '../instrumentation';
42+
import { default as captureRenderTree } from './lib/capture-render-tree';
43+
import { registerHandler as registerDeprecationHandler } from './lib/deprecate';
44+
import * as GlimmerValidator from '@glimmer/validator';
45+
import * as GlimmerRuntime from '@glimmer/runtime';
46+
import { getOwner } from '@ember/owner';
47+
import RSVP from 'rsvp';
48+
import Service from '@ember/service';
49+
import { ENV } from '@ember/-internals/environment';
50+
51+
export function setupInspectorSupport() {
52+
if (typeof window !== 'undefined' && window.addEventListener) {
53+
window.addEventListener(
54+
'ember-inspector-debug-request',
55+
() => {
56+
const event = new CustomEvent('ember-inspector-debug-response', {
57+
detail: {
58+
utils: {
59+
libraries,
60+
},
61+
runloop: {
62+
_backburner,
63+
cancel,
64+
debounce,
65+
join,
66+
later,
67+
scheduleOnce,
68+
},
69+
object: {
70+
cacheFor,
71+
guidFor,
72+
getOwner,
73+
set,
74+
get,
75+
},
76+
debug: {
77+
isComputed,
78+
isTrackedProperty,
79+
isCachedProperty,
80+
descriptorForProperty,
81+
descriptorForDecorator,
82+
isMandatorySetter,
83+
meta,
84+
captureRenderTree,
85+
isTesting,
86+
inspect,
87+
registerDeprecationHandler,
88+
tagForProperty,
89+
},
90+
classes: {
91+
ActionHandler,
92+
Service,
93+
ComputedProperty,
94+
EmberObject,
95+
MutableArray,
96+
Namespace,
97+
MutableEnumerable,
98+
NativeArray,
99+
TargetActionSupport,
100+
ControllerMixin,
101+
CoreObject,
102+
Application,
103+
EmberComponent,
104+
Observable,
105+
Evented,
106+
PromiseProxyMixin,
107+
RSVP,
108+
},
109+
VERSION,
110+
ENV,
111+
instrumentation: {
112+
subscribe,
113+
},
114+
Views: {
115+
ViewStateSupport,
116+
ViewMixin,
117+
ActionSupport,
118+
ClassNamesSupport,
119+
ChildViewsSupport,
120+
CoreView,
121+
},
122+
glimmer: {
123+
runtime: GlimmerRuntime,
124+
validator: GlimmerValidator,
125+
},
126+
},
127+
});
128+
window.dispatchEvent(event);
129+
},
130+
false
131+
);
132+
}
133+
}

packages/@ember/debug/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"exports": {
66
".": "./index.ts",
77
"./container-debug-adapter": "./container-debug-adapter.ts",
8+
"./ember-inspector": "./ember-inspector.ts",
89
"./data-adapter": "./data-adapter.ts"
910
},
1011
"dependencies": {

packages/ember/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { meta as internalMeta } from '@ember/-internals/meta';
1313
import * as metal from '@ember/-internals/metal';
1414
import { FEATURES as EmberFEATURES, isEnabled } from '@ember/canary-features';
1515
import * as EmberDebug from '@ember/debug';
16+
import { setupInspectorSupport } from '@ember/debug/ember-inspector';
1617
import { assert as emberAssert, captureRenderTree } from '@ember/debug';
1718
import Backburner from 'backburner.js';
1819
import EmberController, {
@@ -745,6 +746,7 @@ function defineEmberTestingLazyLoad(key: 'Test' | 'setupForTesting') {
745746
defineEmberTestingLazyLoad('Test');
746747
defineEmberTestingLazyLoad('setupForTesting');
747748

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

0 commit comments

Comments
 (0)