@playfast/reform-profiler 1.1.0 → 1.2.1
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.
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/noop.d.ts +23 -0
- package/dist/noop.d.ts.map +1 -0
- package/dist/noop.js +41 -0
- package/dist/noop.js.map +1 -0
- package/dist/profileScene.d.ts +12 -0
- package/dist/profileScene.d.ts.map +1 -0
- package/dist/profileScene.js +32 -0
- package/dist/profileScene.js.map +1 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +2 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/noop.d.ts +5 -0
- package/dist/react/noop.d.ts.map +1 -0
- package/dist/react/noop.js +3 -0
- package/dist/react/noop.js.map +1 -0
- package/dist/react/overlay.d.ts +5 -0
- package/dist/react/overlay.d.ts.map +1 -0
- package/dist/react/overlay.js +70 -0
- package/dist/react/overlay.js.map +1 -0
- package/dist/react/styles.d.ts +23 -0
- package/dist/react/styles.d.ts.map +1 -0
- package/dist/react/styles.js +91 -0
- package/dist/react/styles.js.map +1 -0
- package/dist/recorder.d.ts +38 -0
- package/dist/recorder.d.ts.map +1 -0
- package/dist/recorder.js +82 -0
- package/dist/recorder.js.map +1 -0
- package/dist/registry.d.ts +12 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +57 -0
- package/dist/registry.js.map +1 -0
- package/dist/report.d.ts +3 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +48 -0
- package/dist/report.js.map +1 -0
- package/dist/trace.d.ts +36 -0
- package/dist/trace.d.ts.map +1 -0
- package/dist/trace.js +58 -0
- package/dist/trace.js.map +1 -0
- package/package.json +26 -8
- package/src/profiler.test.ts +30 -8
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { makeProfiler, type ProfileKind, type ProfileRecord, type ProfilerHandle, type ProfilerOptionsExternalApi, type ProfileSnapshot, type ProfileStat, } from './recorder.js';
|
|
2
|
+
export { type CapturedProfiledScene, type ProfiledScene, profileScene } from './profileScene.js';
|
|
3
|
+
export { type ChromeTrace, type ChromeTraceEvent, toChromeTrace, traceJson } from './trace.js';
|
|
4
|
+
export { formatReport } from './report.js';
|
|
5
|
+
export { claimOverlay, listProfilers, type ProfilerRegistration, profilersVersion, registerProfiler, releaseOverlay, subscribeProfilers, } from './registry.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,0BAA0B,EAC/B,KAAK,eAAe,EACpB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,KAAK,qBAAqB,EAAE,KAAK,aAAa,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7F,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EACL,YAAY,EACZ,aAAa,EACb,KAAK,oBAAoB,EACzB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,GACnB,MAAM,YAAY,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { makeProfiler, } from './recorder.js';
|
|
2
|
+
export { profileScene } from './profileScene.js';
|
|
3
|
+
export { toChromeTrace, traceJson } from './trace.js';
|
|
4
|
+
export { formatReport } from './report.js';
|
|
5
|
+
export { claimOverlay, listProfilers, profilersVersion, registerProfiler, releaseOverlay, subscribeProfilers, } from './registry.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,GAOb,MAAM,YAAY,CAAA;AACnB,OAAO,EAAkD,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7F,OAAO,EAA2C,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EACL,YAAY,EACZ,aAAa,EAEb,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,GACnB,MAAM,YAAY,CAAA"}
|
package/dist/noop.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type CapturedScene, type Scene, type UiContract } from '@playfast/reform';
|
|
2
|
+
import type { CapturedProfiledScene, ProfiledScene } from './profileScene.js';
|
|
3
|
+
import type { ProfilerHandle, ProfilerOptionsExternalApi } from './recorder.js';
|
|
4
|
+
import type { ProfilerRegistration } from './registry.js';
|
|
5
|
+
import type { ChromeTrace } from './trace.js';
|
|
6
|
+
export type { ProfileKind, ProfileRecord, ProfilerHandle, ProfilerOptionsExternalApi, ProfileSnapshot, ProfileStat, } from './recorder.js';
|
|
7
|
+
export type { CapturedProfiledScene, ProfiledScene } from './profileScene.js';
|
|
8
|
+
export type { ChromeTrace, ChromeTraceEvent } from './trace.js';
|
|
9
|
+
export type { ProfilerRegistration } from './registry.js';
|
|
10
|
+
export declare const noopProfiler: ProfilerHandle;
|
|
11
|
+
export declare const makeProfiler: (_options?: ProfilerOptionsExternalApi) => ProfilerHandle;
|
|
12
|
+
export declare function profileScene<C extends UiContract, S extends ReadonlyArray<unknown>, Services, P, N extends string, Identity>(base: CapturedScene<C, S, Services, P, N, Identity>, _options?: ProfilerOptionsExternalApi): CapturedProfiledScene<C, S, Services, P, N, Identity>;
|
|
13
|
+
export declare function profileScene<C extends UiContract, S extends ReadonlyArray<unknown>>(base: Scene<C, S>, _options?: ProfilerOptionsExternalApi): ProfiledScene<C, S>;
|
|
14
|
+
export declare const toChromeTrace: (_profiler: ProfilerHandle) => ChromeTrace;
|
|
15
|
+
export declare const traceJson: (_profiler: ProfilerHandle) => string;
|
|
16
|
+
export declare const formatReport: (_profiler: ProfilerHandle) => string;
|
|
17
|
+
export declare const registerProfiler: (_registration: ProfilerRegistration) => (() => void);
|
|
18
|
+
export declare const listProfilers: () => ReadonlyArray<ProfilerRegistration>;
|
|
19
|
+
export declare const subscribeProfilers: (_listener: () => void) => (() => void);
|
|
20
|
+
export declare const profilersVersion: () => number;
|
|
21
|
+
export declare const claimOverlay: (_owner: object) => boolean;
|
|
22
|
+
export declare const releaseOverlay: (_owner: object) => void;
|
|
23
|
+
//# sourceMappingURL=noop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noop.d.ts","sourceRoot":"","sources":["../src/noop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAElF,OAAO,KAAK,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC1E,OAAO,KAAK,EAAE,cAAc,EAAE,0BAA0B,EAAmB,MAAM,YAAY,CAAA;AAC7F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAI1C,YAAY,EACV,WAAW,EACX,aAAa,EACb,cAAc,EACd,0BAA0B,EAC1B,eAAe,EACf,WAAW,GACZ,MAAM,YAAY,CAAA;AACnB,YAAY,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC1E,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAC5D,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAetD,eAAO,MAAM,YAAY,EAAE,cAO1B,CAAA;AAED,eAAO,MAAM,YAAY,GAAI,WAAU,0BAA+B,KAAG,cAC3D,CAAA;AAgBd,wBAAgB,YAAY,CAC1B,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,aAAa,CAAC,OAAO,CAAC,EAChC,QAAQ,EACR,CAAC,EACD,CAAC,SAAS,MAAM,EAChB,QAAQ,EAER,IAAI,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,EACnD,QAAQ,CAAC,EAAE,0BAA0B,GACpC,qBAAqB,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAA;AACxD,wBAAgB,YAAY,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,aAAa,CAAC,OAAO,CAAC,EACjF,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EACjB,QAAQ,CAAC,EAAE,0BAA0B,GACpC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AActB,eAAO,MAAM,aAAa,GAAI,WAAW,cAAc,KAAG,WAAyB,CAAA;AAEnF,eAAO,MAAM,SAAS,GAAI,WAAW,cAAc,KAAG,MACT,CAAA;AAE7C,eAAO,MAAM,YAAY,GAAI,WAAW,cAAc,KAAG,MAAY,CAAA;AAErE,eAAO,MAAM,gBAAgB,GAC1B,eAAe,oBAAoB,KAAG,CAAC,MAAM,IAAI,CAC1C,CAAA;AAEV,eAAO,MAAM,aAAa,QAAO,aAAa,CAAC,oBAAoB,CAAO,CAAA;AAE1E,eAAO,MAAM,kBAAkB,GAC5B,WAAW,MAAM,IAAI,KAAG,CAAC,MAAM,IAAI,CAC5B,CAAA;AAEV,eAAO,MAAM,gBAAgB,QAAO,MAAW,CAAA;AAE/C,eAAO,MAAM,YAAY,GAAI,QAAQ,MAAM,KAAG,OAAgB,CAAA;AAE9D,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,KAAG,IAAU,CAAA"}
|
package/dist/noop.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {} from '@playfast/reform';
|
|
2
|
+
import { noopInstrumentation } from '@playfast/reform/internal';
|
|
3
|
+
const emptySnapshot = {
|
|
4
|
+
events: new Map(),
|
|
5
|
+
reducers: new Map(),
|
|
6
|
+
states: new Map(),
|
|
7
|
+
calcs: new Map(),
|
|
8
|
+
queries: new Map(),
|
|
9
|
+
procedures: new Map(),
|
|
10
|
+
renders: new Map(),
|
|
11
|
+
frames: { count: 0, totalMs: 0 },
|
|
12
|
+
records: [],
|
|
13
|
+
dropped: 0,
|
|
14
|
+
};
|
|
15
|
+
export const noopProfiler = {
|
|
16
|
+
...noopInstrumentation,
|
|
17
|
+
label: 'noop',
|
|
18
|
+
snapshot: () => emptySnapshot,
|
|
19
|
+
clear: () => { },
|
|
20
|
+
subscribe: () => () => { },
|
|
21
|
+
getVersion: () => 0,
|
|
22
|
+
};
|
|
23
|
+
export const makeProfiler = (_options = {}) => noopProfiler;
|
|
24
|
+
const profileCapturedScene = (base) => ({
|
|
25
|
+
scene: base,
|
|
26
|
+
profiler: noopProfiler,
|
|
27
|
+
});
|
|
28
|
+
export function profileScene(base, _options = {}) {
|
|
29
|
+
return base.capture((exactScene) => profileCapturedScene(exactScene));
|
|
30
|
+
}
|
|
31
|
+
const emptyTrace = { traceEvents: [], displayTimeUnit: 'ms' };
|
|
32
|
+
export const toChromeTrace = (_profiler) => emptyTrace;
|
|
33
|
+
export const traceJson = (_profiler) => '{"traceEvents":[],"displayTimeUnit":"ms"}';
|
|
34
|
+
export const formatReport = (_profiler) => '';
|
|
35
|
+
export const registerProfiler = (_registration) => () => { };
|
|
36
|
+
export const listProfilers = () => [];
|
|
37
|
+
export const subscribeProfilers = (_listener) => () => { };
|
|
38
|
+
export const profilersVersion = () => 0;
|
|
39
|
+
export const claimOverlay = (_owner) => false;
|
|
40
|
+
export const releaseOverlay = (_owner) => { };
|
|
41
|
+
//# sourceMappingURL=noop.js.map
|
package/dist/noop.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noop.js","sourceRoot":"","sources":["../src/noop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmD,MAAM,kBAAkB,CAAA;AAClF,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAoB/D,MAAM,aAAa,GAAoB;IACrC,MAAM,EAAE,IAAI,GAAG,EAAE;IACjB,QAAQ,EAAE,IAAI,GAAG,EAAE;IACnB,MAAM,EAAE,IAAI,GAAG,EAAE;IACjB,KAAK,EAAE,IAAI,GAAG,EAAE;IAChB,OAAO,EAAE,IAAI,GAAG,EAAE;IAClB,UAAU,EAAE,IAAI,GAAG,EAAE;IACrB,OAAO,EAAE,IAAI,GAAG,EAAE;IAClB,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE;IAChC,OAAO,EAAE,EAAE;IACX,OAAO,EAAE,CAAC;CACX,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAmB;IAC1C,GAAG,mBAAmB;IACtB,KAAK,EAAE,MAAM;IACb,QAAQ,EAAE,GAAG,EAAE,CAAC,aAAa;IAC7B,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;IACf,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC;IACzB,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;CACpB,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,WAAuC,EAAE,EAAkB,EAAE,CACxF,YAAY,CAAA;AAEd,MAAM,oBAAoB,GAAG,CAQ3B,IAAmD,EACI,EAAE,CAAC,CAAC;IAC3D,KAAK,EAAE,IAAI;IACX,QAAQ,EAAE,YAAY;CACvB,CAAC,CAAA;AAiBF,MAAM,UAAU,YAAY,CAC1B,IAAiB,EACjB,WAAuC,EAAE;IAEzC,OAAO,IAAI,CAAC,OAAO,CACjB,CACE,UAAyD,EACpC,EAAE,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAC3D,CAAA;AACH,CAAC;AAED,MAAM,UAAU,GAAgB,EAAE,WAAW,EAAE,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,CAAA;AAE1E,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,SAAyB,EAAe,EAAE,CAAC,UAAU,CAAA;AAEnF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,SAAyB,EAAU,EAAE,CAC7D,2CAA2C,CAAA;AAE7C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,SAAyB,EAAU,EAAE,CAAC,EAAE,CAAA;AAErE,MAAM,CAAC,MAAM,gBAAgB,GAC3B,CAAC,aAAmC,EAAgB,EAAE,CACtD,GAAG,EAAE,GAAE,CAAC,CAAA;AAEV,MAAM,CAAC,MAAM,aAAa,GAAG,GAAwC,EAAE,CAAC,EAAE,CAAA;AAE1E,MAAM,CAAC,MAAM,kBAAkB,GAC7B,CAAC,SAAqB,EAAgB,EAAE,CACxC,GAAG,EAAE,GAAE,CAAC,CAAA;AAEV,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAW,EAAE,CAAC,CAAC,CAAA;AAE/C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAc,EAAW,EAAE,CAAC,KAAK,CAAA;AAE9D,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAAc,EAAQ,EAAE,GAAE,CAAC,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type CapturedScene, type Scene, type UiContract } from '@playfast/reform';
|
|
2
|
+
import { type ProfilerHandle, type ProfilerOptionsExternalApi } from './recorder.js';
|
|
3
|
+
export interface ProfiledScene<C extends UiContract = UiContract, S extends ReadonlyArray<unknown> = ReadonlyArray<unknown>> {
|
|
4
|
+
readonly scene: Scene<C, S>;
|
|
5
|
+
readonly profiler: ProfilerHandle;
|
|
6
|
+
}
|
|
7
|
+
export interface CapturedProfiledScene<C extends UiContract, S extends ReadonlyArray<unknown>, Services, P, N extends string, Identity> extends ProfiledScene<C, S> {
|
|
8
|
+
readonly scene: CapturedScene<C, S, Services, P, N, Identity>;
|
|
9
|
+
}
|
|
10
|
+
export declare function profileScene<C extends UiContract, S extends ReadonlyArray<unknown>, Services, P, N extends string, Identity>(base: CapturedScene<C, S, Services, P, N, Identity>, options?: ProfilerOptionsExternalApi): CapturedProfiledScene<C, S, Services, P, N, Identity>;
|
|
11
|
+
export declare function profileScene<C extends UiContract, S extends ReadonlyArray<unknown>>(base: Scene<C, S>, options?: ProfilerOptionsExternalApi): ProfiledScene<C, S>;
|
|
12
|
+
//# sourceMappingURL=profileScene.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profileScene.d.ts","sourceRoot":"","sources":["../src/profileScene.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAAiB,KAAK,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAEjG,OAAO,EAAgB,KAAK,cAAc,EAAE,KAAK,0BAA0B,EAAE,MAAM,YAAY,CAAA;AAG/F,MAAM,WAAW,aAAa,CAC5B,CAAC,SAAS,UAAU,GAAG,UAAU,EACjC,CAAC,SAAS,aAAa,CAAC,OAAO,CAAC,GAAG,aAAa,CAAC,OAAO,CAAC;IAEzD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC3B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;CAClC;AAED,MAAM,WAAW,qBAAqB,CACpC,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,aAAa,CAAC,OAAO,CAAC,EAChC,QAAQ,EACR,CAAC,EACD,CAAC,SAAS,MAAM,EAChB,QAAQ,CACR,SAAQ,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAA;CAC9D;AAoDD,wBAAgB,YAAY,CAC1B,CAAC,SAAS,UAAU,EACpB,CAAC,SAAS,aAAa,CAAC,OAAO,CAAC,EAChC,QAAQ,EACR,CAAC,EACD,CAAC,SAAS,MAAM,EAChB,QAAQ,EAER,IAAI,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,EACnD,OAAO,CAAC,EAAE,0BAA0B,GACnC,qBAAqB,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAA;AACxD,wBAAgB,YAAY,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,aAAa,CAAC,OAAO,CAAC,EACjF,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EACjB,OAAO,CAAC,EAAE,0BAA0B,GACnC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Effect, Layer } from 'effect';
|
|
2
|
+
import { profiledScene } from '@playfast/reform';
|
|
3
|
+
import {} from '@playfast/reform/internal';
|
|
4
|
+
import { makeProfiler } from './recorder.js';
|
|
5
|
+
import { registerProfiler } from './registry.js';
|
|
6
|
+
const makeLifecycle = (profiler) => Layer.scopedDiscard(Effect.acquireRelease(Effect.sync(() => registerProfiler({ label: profiler.label, handle: profiler })), (unregister) => Effect.sync(unregister)));
|
|
7
|
+
const withLifecycle = (base, lifecycle) => {
|
|
8
|
+
const captured = {
|
|
9
|
+
kind: 'Scene',
|
|
10
|
+
composition: base.composition,
|
|
11
|
+
// Lifecycle on the first provide layer tracks the runtime's build/dispose scope.
|
|
12
|
+
provide: base.provide.map((layer, index) => index === 0 ? Layer.merge(layer, lifecycle) : layer),
|
|
13
|
+
...(base.boot === undefined ? {} : { boot: base.boot }),
|
|
14
|
+
...(base.instrumentation === undefined ? {} : { instrumentation: base.instrumentation }),
|
|
15
|
+
capture: (capture) => capture(captured),
|
|
16
|
+
captureAny: (capture) => capture(captured),
|
|
17
|
+
};
|
|
18
|
+
return captured;
|
|
19
|
+
};
|
|
20
|
+
const profileCapturedScene = (base, profiler, lifecycle) => ({
|
|
21
|
+
scene: withLifecycle(profiledScene(base, profiler), lifecycle),
|
|
22
|
+
profiler,
|
|
23
|
+
});
|
|
24
|
+
export function profileScene(base, options = {}) {
|
|
25
|
+
const profiler = makeProfiler({
|
|
26
|
+
label: options.label ?? base.composition.manifest.title,
|
|
27
|
+
...(options.capacity !== undefined ? { capacity: options.capacity } : {}),
|
|
28
|
+
});
|
|
29
|
+
const lifecycle = makeLifecycle(profiler);
|
|
30
|
+
return base.capture((exactScene) => profileCapturedScene(exactScene, profiler, lifecycle));
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=profileScene.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profileScene.js","sourceRoot":"","sources":["../src/profileScene.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AACtC,OAAO,EAAsB,aAAa,EAA+B,MAAM,kBAAkB,CAAA;AACjG,OAAO,EAA2C,MAAM,2BAA2B,CAAA;AACnF,OAAO,EAAE,YAAY,EAAwD,MAAM,YAAY,CAAA;AAC/F,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAqB7C,MAAM,aAAa,GAAG,CAAC,QAAwB,EAAE,EAAE,CACjD,KAAK,CAAC,aAAa,CACjB,MAAM,CAAC,cAAc,CACnB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,EAChF,CAAC,UAAU,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CACxC,CACF,CAAA;AAEH,MAAM,aAAa,GAAG,CAQpB,IAAmD,EACnD,SAA2C,EACI,EAAE;IACjD,MAAM,QAAQ,GAAkD;QAC9D,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,iFAAiF;QACjF,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CACzC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CACpD;QACD,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC;QACxF,OAAO,EAAE,CAAS,OAAmC,EAAU,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC;QACnF,UAAU,EAAE,CAAS,OAAgC,EAAU,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC;KACpF,CAAA;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA;AAED,MAAM,oBAAoB,GAAG,CAQ3B,IAAmD,EACnD,QAAwB,EACxB,SAA2C,EACY,EAAE,CAAC,CAAC;IAC3D,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAC9D,QAAQ;CACT,CAAC,CAAA;AAiBF,MAAM,UAAU,YAAY,CAC1B,IAAiB,EACjB,UAAsC,EAAE;IAExC,MAAM,QAAQ,GAAG,YAAY,CAAC;QAC5B,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK;QACvD,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1E,CAAC,CAAA;IACF,MAAM,SAAS,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAA;IACzC,OAAO,IAAI,CAAC,OAAO,CACjB,CACE,UAAyD,EACpC,EAAE,CAAC,oBAAoB,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC,CAChF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noop.d.ts","sourceRoot":"","sources":["../../src/react/noop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,eAAO,MAAM,cAAc,QAAO,SAAiB,CAAA;AAEnD,eAAO,MAAM,aAAa,GAAI,WAAW,cAAc,KAAG,IAAU,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noop.js","sourceRoot":"","sources":["../../src/react/noop.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,cAAc,GAAG,GAAc,EAAE,CAAC,IAAI,CAAA;AAEnD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,SAAyB,EAAQ,EAAE,GAAE,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/react/overlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,aAAa,CAAA;AAyB9D,eAAO,MAAM,aAAa,GAAI,UAAU,cAAc,KAAG,IAQxD,CAAA;AAkGD,eAAO,MAAM,cAAc,QAAO,SAoEjC,CAAA"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react';
|
|
3
|
+
import { claimOverlay, listProfilers, profilersVersion, releaseOverlay, subscribeProfilers, } from '../registry.js';
|
|
4
|
+
import { traceJson } from '../trace.js';
|
|
5
|
+
import { bodyStyle, buttonStyle, cellStyle, headerStyle, nameCellStyle, palette, panelStyle, pillStyle, rootStyle, sectionTitleStyle, tableStyle, tabStyle, } from './styles.js';
|
|
6
|
+
// Plain React (not reform) so the profiler does not profile itself.
|
|
7
|
+
export const downloadTrace = (profiler) => {
|
|
8
|
+
const blob = new Blob([traceJson(profiler)], { type: 'application/json' });
|
|
9
|
+
const url = URL.createObjectURL(blob);
|
|
10
|
+
const anchor = document.createElement('a');
|
|
11
|
+
anchor.href = url;
|
|
12
|
+
anchor.download = `reform-trace-${profiler.label}.json`;
|
|
13
|
+
anchor.click();
|
|
14
|
+
URL.revokeObjectURL(url);
|
|
15
|
+
};
|
|
16
|
+
const sortedRows = (stats) => [...stats.entries()]
|
|
17
|
+
.map(([name, stat]) => ({ name, stat }))
|
|
18
|
+
.toSorted((left, right) => right.stat.totalMs - left.stat.totalMs || right.stat.count - left.stat.count);
|
|
19
|
+
const MS_DECIMALS = 2;
|
|
20
|
+
const formatMs = (durationMs) => durationMs.toFixed(MS_DECIMALS);
|
|
21
|
+
const avgMs = (stat) => formatMs(stat.count === 0 ? 0 : stat.totalMs / stat.count);
|
|
22
|
+
const Section = ({ title, rows, timed }) => {
|
|
23
|
+
if (rows.length === 0) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
return (_jsxs("div", { children: [_jsx("div", { style: sectionTitleStyle, children: title }), _jsxs("table", { style: tableStyle, children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { style: nameCellStyle, children: "name" }), _jsx("th", { style: cellStyle, children: "count" }), timed ? _jsx("th", { style: cellStyle, children: "total ms" }) : null, timed ? _jsx("th", { style: cellStyle, children: "avg ms" }) : null] }) }), _jsx("tbody", { children: rows.map((row) => (_jsxs("tr", { children: [_jsx("td", { style: nameCellStyle, children: row.name }), _jsx("td", { style: cellStyle, children: row.stat.count }), timed ? _jsx("td", { style: cellStyle, children: formatMs(row.stat.totalMs) }) : null, timed ? _jsx("td", { style: cellStyle, children: avgMs(row.stat) }) : null] }, row.name))) })] })] }));
|
|
27
|
+
};
|
|
28
|
+
const DroppedNote = ({ count }) => {
|
|
29
|
+
if (count === 0) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return (_jsxs("div", { style: { color: palette.dim }, children: ["(", count, " early records evicted from the ring buffer)"] }));
|
|
33
|
+
};
|
|
34
|
+
const ProfilerBody = ({ profiler }) => {
|
|
35
|
+
const subscribe = useCallback((onStoreChange) => profiler.subscribe(onStoreChange), [profiler]);
|
|
36
|
+
const getVersion = useCallback(() => profiler.getVersion(), [profiler]);
|
|
37
|
+
useSyncExternalStore(subscribe, getVersion, getVersion);
|
|
38
|
+
const snapshot = profiler.snapshot();
|
|
39
|
+
const frameRows = snapshot.frames.count === 0 ? [] : [{ name: 'frame', stat: snapshot.frames }];
|
|
40
|
+
return (_jsxs("div", { style: bodyStyle, children: [_jsx(Section, { title: "Renders", rows: sortedRows(snapshot.renders), timed: true }), _jsx(Section, { title: "Events", rows: sortedRows(snapshot.events), timed: false }), _jsx(Section, { title: "Reducers", rows: sortedRows(snapshot.reducers), timed: true }), _jsx(Section, { title: "State updates", rows: sortedRows(snapshot.states), timed: false }), _jsx(Section, { title: "Calcs", rows: sortedRows(snapshot.calcs), timed: true }), _jsx(Section, { title: "Queries", rows: sortedRows(snapshot.queries), timed: true }), _jsx(Section, { title: "Procedures", rows: sortedRows(snapshot.procedures), timed: true }), _jsx(Section, { title: "Frames", rows: frameRows, timed: true }), _jsx(DroppedNote, { count: snapshot.dropped })] }));
|
|
41
|
+
};
|
|
42
|
+
export const ReformProfiler = () => {
|
|
43
|
+
const owner = useRef({}).current;
|
|
44
|
+
const [claimed, setClaimed] = useState(false);
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
setClaimed(claimOverlay(owner));
|
|
47
|
+
const unsubscribe = subscribeProfilers(() => setClaimed(claimOverlay(owner)));
|
|
48
|
+
return () => {
|
|
49
|
+
unsubscribe();
|
|
50
|
+
releaseOverlay(owner);
|
|
51
|
+
};
|
|
52
|
+
}, [owner]);
|
|
53
|
+
const registryVersion = useSyncExternalStore(subscribeProfilers, profilersVersion, profilersVersion);
|
|
54
|
+
const registrations = listProfilers();
|
|
55
|
+
const [expanded, setExpanded] = useState(false);
|
|
56
|
+
const [tab, setTab] = useState(0);
|
|
57
|
+
void registryVersion;
|
|
58
|
+
if (!claimed || registrations.length === 0) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
const selected = registrations[Math.min(tab, registrations.length - 1)];
|
|
62
|
+
if (selected === undefined) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
if (!expanded) {
|
|
66
|
+
return (_jsx("div", { style: rootStyle, children: _jsx("button", { type: "button", style: pillStyle, onClick: () => setExpanded(true), children: "\u26A1 reform profiler" }) }));
|
|
67
|
+
}
|
|
68
|
+
return (_jsx("div", { style: rootStyle, children: _jsxs("div", { style: panelStyle, children: [_jsxs("div", { style: headerStyle, children: [_jsx("span", { style: { color: palette.accent, fontWeight: 600 }, children: "\u26A1 reform" }), registrations.map((registration, index) => (_jsx("button", { type: "button", style: tabStyle(registration === selected), onClick: () => setTab(index), children: registration.label }, registration.label + String(index)))), _jsx("span", { style: { flex: 1 } }), _jsx("button", { type: "button", style: buttonStyle, onClick: () => downloadTrace(selected.handle), children: "export" }), _jsx("button", { type: "button", style: buttonStyle, onClick: () => selected.handle.clear(), children: "clear" }), _jsx("button", { type: "button", style: buttonStyle, onClick: () => setExpanded(false), children: "\u00D7" })] }), _jsx(ProfilerBody, { profiler: selected.handle })] }) }));
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=overlay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlay.js","sourceRoot":"","sources":["../../src/react/overlay.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CSSProperties } from 'react';
|
|
2
|
+
interface Palette {
|
|
3
|
+
readonly bg: string;
|
|
4
|
+
readonly panel: string;
|
|
5
|
+
readonly border: string;
|
|
6
|
+
readonly text: string;
|
|
7
|
+
readonly dim: string;
|
|
8
|
+
readonly accent: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const palette: Palette;
|
|
11
|
+
export declare const rootStyle: CSSProperties;
|
|
12
|
+
export declare const pillStyle: CSSProperties;
|
|
13
|
+
export declare const panelStyle: CSSProperties;
|
|
14
|
+
export declare const headerStyle: CSSProperties;
|
|
15
|
+
export declare const buttonStyle: CSSProperties;
|
|
16
|
+
export declare const tabStyle: (active: boolean) => CSSProperties;
|
|
17
|
+
export declare const bodyStyle: CSSProperties;
|
|
18
|
+
export declare const tableStyle: CSSProperties;
|
|
19
|
+
export declare const cellStyle: CSSProperties;
|
|
20
|
+
export declare const nameCellStyle: CSSProperties;
|
|
21
|
+
export declare const sectionTitleStyle: CSSProperties;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/react/styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAE1C,UAAU,OAAO;IACf,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,eAAO,MAAM,OAAO,EAAE,OAOrB,CAAA;AAED,eAAO,MAAM,SAAS,EAAE,aASvB,CAAA;AAED,eAAO,MAAM,SAAS,EAAE,aASvB,CAAA;AAED,eAAO,MAAM,UAAU,EAAE,aAUxB,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,aAOzB,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,aASzB,CAAA;AAED,eAAO,MAAM,QAAQ,GAAI,QAAQ,OAAO,KAAG,aAIzC,CAAA;AAEF,eAAO,MAAM,SAAS,EAAE,aAGvB,CAAA;AAED,eAAO,MAAM,UAAU,EAAE,aAIxB,CAAA;AAED,eAAO,MAAM,SAAS,EAAE,aAKvB,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,aAO3B,CAAA;AAED,eAAO,MAAM,iBAAiB,EAAE,aAI/B,CAAA"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
export const palette = {
|
|
2
|
+
bg: '#16181d',
|
|
3
|
+
panel: '#1d2026',
|
|
4
|
+
border: '#31353d',
|
|
5
|
+
text: '#d7dae0',
|
|
6
|
+
dim: '#8a8f98',
|
|
7
|
+
accent: '#e8a33d',
|
|
8
|
+
};
|
|
9
|
+
export const rootStyle = {
|
|
10
|
+
position: 'fixed',
|
|
11
|
+
right: 12,
|
|
12
|
+
bottom: 12,
|
|
13
|
+
zIndex: 2147483000,
|
|
14
|
+
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
|
|
15
|
+
fontSize: 11,
|
|
16
|
+
lineHeight: 1.5,
|
|
17
|
+
color: palette.text,
|
|
18
|
+
};
|
|
19
|
+
export const pillStyle = {
|
|
20
|
+
background: palette.bg,
|
|
21
|
+
border: `1px solid ${palette.border}`,
|
|
22
|
+
borderRadius: 999,
|
|
23
|
+
padding: '4px 12px',
|
|
24
|
+
cursor: 'pointer',
|
|
25
|
+
color: palette.accent,
|
|
26
|
+
fontSize: 11,
|
|
27
|
+
fontFamily: 'inherit',
|
|
28
|
+
};
|
|
29
|
+
export const panelStyle = {
|
|
30
|
+
background: palette.bg,
|
|
31
|
+
border: `1px solid ${palette.border}`,
|
|
32
|
+
borderRadius: 8,
|
|
33
|
+
width: 420,
|
|
34
|
+
maxHeight: '60vh',
|
|
35
|
+
display: 'flex',
|
|
36
|
+
flexDirection: 'column',
|
|
37
|
+
overflow: 'hidden',
|
|
38
|
+
boxShadow: '0 8px 24px rgba(0,0,0,0.5)',
|
|
39
|
+
};
|
|
40
|
+
export const headerStyle = {
|
|
41
|
+
display: 'flex',
|
|
42
|
+
alignItems: 'center',
|
|
43
|
+
gap: 8,
|
|
44
|
+
padding: '6px 10px',
|
|
45
|
+
borderBottom: `1px solid ${palette.border}`,
|
|
46
|
+
background: palette.panel,
|
|
47
|
+
};
|
|
48
|
+
export const buttonStyle = {
|
|
49
|
+
background: 'transparent',
|
|
50
|
+
border: `1px solid ${palette.border}`,
|
|
51
|
+
borderRadius: 4,
|
|
52
|
+
color: palette.text,
|
|
53
|
+
padding: '1px 8px',
|
|
54
|
+
cursor: 'pointer',
|
|
55
|
+
fontSize: 11,
|
|
56
|
+
fontFamily: 'inherit',
|
|
57
|
+
};
|
|
58
|
+
export const tabStyle = (active) => ({
|
|
59
|
+
...buttonStyle,
|
|
60
|
+
borderColor: active ? palette.accent : palette.border,
|
|
61
|
+
color: active ? palette.accent : palette.dim,
|
|
62
|
+
});
|
|
63
|
+
export const bodyStyle = {
|
|
64
|
+
overflowY: 'auto',
|
|
65
|
+
padding: '4px 10px 10px',
|
|
66
|
+
};
|
|
67
|
+
export const tableStyle = {
|
|
68
|
+
width: '100%',
|
|
69
|
+
borderCollapse: 'collapse',
|
|
70
|
+
marginBottom: 8,
|
|
71
|
+
};
|
|
72
|
+
export const cellStyle = {
|
|
73
|
+
padding: '1px 6px 1px 0',
|
|
74
|
+
textAlign: 'right',
|
|
75
|
+
whiteSpace: 'nowrap',
|
|
76
|
+
color: palette.dim,
|
|
77
|
+
};
|
|
78
|
+
export const nameCellStyle = {
|
|
79
|
+
...cellStyle,
|
|
80
|
+
textAlign: 'left',
|
|
81
|
+
width: '100%',
|
|
82
|
+
color: palette.text,
|
|
83
|
+
overflowWrap: 'anywhere',
|
|
84
|
+
whiteSpace: 'normal',
|
|
85
|
+
};
|
|
86
|
+
export const sectionTitleStyle = {
|
|
87
|
+
color: palette.accent,
|
|
88
|
+
margin: '8px 0 2px',
|
|
89
|
+
fontWeight: 600,
|
|
90
|
+
};
|
|
91
|
+
//# sourceMappingURL=styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../src/react/styles.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type Instrumentation } from '@playfast/reform/internal';
|
|
2
|
+
export type ProfileKind = 'event' | 'reducer' | 'state' | 'calc' | 'query' | 'procedure' | 'render' | 'frame';
|
|
3
|
+
export interface ProfileRecord {
|
|
4
|
+
readonly kind: ProfileKind;
|
|
5
|
+
readonly name: string;
|
|
6
|
+
readonly detail: string;
|
|
7
|
+
readonly start: number;
|
|
8
|
+
readonly dur: number;
|
|
9
|
+
}
|
|
10
|
+
export interface ProfileStat {
|
|
11
|
+
readonly count: number;
|
|
12
|
+
readonly totalMs: number;
|
|
13
|
+
}
|
|
14
|
+
export interface ProfileSnapshot {
|
|
15
|
+
readonly events: ReadonlyMap<string, ProfileStat>;
|
|
16
|
+
readonly reducers: ReadonlyMap<string, ProfileStat>;
|
|
17
|
+
readonly states: ReadonlyMap<string, ProfileStat>;
|
|
18
|
+
readonly calcs: ReadonlyMap<string, ProfileStat>;
|
|
19
|
+
readonly queries: ReadonlyMap<string, ProfileStat>;
|
|
20
|
+
readonly procedures: ReadonlyMap<string, ProfileStat>;
|
|
21
|
+
readonly renders: ReadonlyMap<string, ProfileStat>;
|
|
22
|
+
readonly frames: ProfileStat;
|
|
23
|
+
readonly records: ReadonlyArray<ProfileRecord>;
|
|
24
|
+
readonly dropped: number;
|
|
25
|
+
}
|
|
26
|
+
export interface ProfilerOptionsExternalApi {
|
|
27
|
+
readonly label?: string;
|
|
28
|
+
readonly capacity?: number;
|
|
29
|
+
}
|
|
30
|
+
export interface ProfilerHandle extends Instrumentation {
|
|
31
|
+
readonly label: string;
|
|
32
|
+
readonly snapshot: () => ProfileSnapshot;
|
|
33
|
+
readonly clear: () => void;
|
|
34
|
+
readonly subscribe: (listener: () => void) => () => void;
|
|
35
|
+
readonly getVersion: () => number;
|
|
36
|
+
}
|
|
37
|
+
export declare const makeProfiler: (options?: ProfilerOptionsExternalApi) => ProfilerHandle;
|
|
38
|
+
//# sourceMappingURL=recorder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../src/recorder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAA+B,MAAM,2BAA2B,CAAA;AAE7F,MAAM,MAAM,WAAW,GACnB,OAAO,GACP,SAAS,GACT,OAAO,GACP,MAAM,GACN,OAAO,GACP,WAAW,GACX,QAAQ,GACR,OAAO,CAAA;AAEX,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IACjD,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IACnD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IACjD,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IAChD,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IAClD,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IACrD,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IAClD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,aAAa,CAAC,CAAA;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,cAAe,SAAQ,eAAe;IACrD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,eAAe,CAAA;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;IACxD,QAAQ,CAAC,UAAU,EAAE,MAAM,MAAM,CAAA;CAClC;AAMD,eAAO,MAAM,YAAY,GAAI,UAAS,0BAA+B,KAAG,cA+FvE,CAAA"}
|
package/dist/recorder.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { makeScheduler } from '@playfast/reform/internal';
|
|
2
|
+
const zeroStat = { count: 0, totalMs: 0 };
|
|
3
|
+
const DEFAULT_CAPACITY = 50_000;
|
|
4
|
+
export const makeProfiler = (options = {}) => {
|
|
5
|
+
const capacity = Math.max(1, options.capacity ?? DEFAULT_CAPACITY);
|
|
6
|
+
const label = options.label ?? 'reform';
|
|
7
|
+
// Fixed ring: written % capacity is next slot; aggregates keep full tally when records evict.
|
|
8
|
+
const emptyBuffer = () => Array.from({ length: capacity }, () => undefined);
|
|
9
|
+
const cursor = { buffer: emptyBuffer(), written: 0, version: 0 };
|
|
10
|
+
const stats = {
|
|
11
|
+
event: new Map(),
|
|
12
|
+
reducer: new Map(),
|
|
13
|
+
state: new Map(),
|
|
14
|
+
calc: new Map(),
|
|
15
|
+
query: new Map(),
|
|
16
|
+
procedure: new Map(),
|
|
17
|
+
render: new Map(),
|
|
18
|
+
frame: new Map(),
|
|
19
|
+
};
|
|
20
|
+
const listeners = new Set();
|
|
21
|
+
const scheduler = makeScheduler();
|
|
22
|
+
const notify = () => {
|
|
23
|
+
cursor.version += 1;
|
|
24
|
+
scheduler.schedule(listeners);
|
|
25
|
+
};
|
|
26
|
+
const record = (entry) => {
|
|
27
|
+
cursor.buffer[cursor.written % capacity] = entry;
|
|
28
|
+
cursor.written += 1;
|
|
29
|
+
const bucket = stats[entry.kind];
|
|
30
|
+
const prev = bucket.get(entry.name) ?? zeroStat;
|
|
31
|
+
bucket.set(entry.name, { count: prev.count + 1, totalMs: prev.totalMs + entry.dur });
|
|
32
|
+
notify();
|
|
33
|
+
};
|
|
34
|
+
const instant = (site) => record({ ...site, start: performance.now(), dur: 0 });
|
|
35
|
+
const span = (site) => {
|
|
36
|
+
const start = performance.now();
|
|
37
|
+
return () => record({ ...site, start, dur: performance.now() - start });
|
|
38
|
+
};
|
|
39
|
+
const snapshot = () => {
|
|
40
|
+
const size = Math.min(cursor.written, capacity);
|
|
41
|
+
const first = cursor.written - size;
|
|
42
|
+
const records = Array.from({ length: size }, (_, index) => cursor.buffer[(first + index) % capacity]).filter((candidate) => candidate !== undefined);
|
|
43
|
+
return {
|
|
44
|
+
events: new Map(stats.event),
|
|
45
|
+
reducers: new Map(stats.reducer),
|
|
46
|
+
states: new Map(stats.state),
|
|
47
|
+
calcs: new Map(stats.calc),
|
|
48
|
+
queries: new Map(stats.query),
|
|
49
|
+
procedures: new Map(stats.procedure),
|
|
50
|
+
renders: new Map(stats.render),
|
|
51
|
+
frames: stats.frame.get('frame') ?? zeroStat,
|
|
52
|
+
records,
|
|
53
|
+
dropped: first,
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
return {
|
|
57
|
+
label,
|
|
58
|
+
snapshot,
|
|
59
|
+
clear: () => {
|
|
60
|
+
cursor.buffer = emptyBuffer();
|
|
61
|
+
cursor.written = 0;
|
|
62
|
+
Object.values(stats).forEach((bucket) => bucket.clear());
|
|
63
|
+
notify();
|
|
64
|
+
},
|
|
65
|
+
subscribe: (listener) => {
|
|
66
|
+
listeners.add(listener);
|
|
67
|
+
return () => {
|
|
68
|
+
listeners.delete(listener);
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
getVersion: () => cursor.version,
|
|
72
|
+
eventDispatched: (tag, priority) => instant({ kind: 'event', name: tag, detail: priority }),
|
|
73
|
+
reducerRun: (name, eventTag) => span({ kind: 'reducer', name, detail: eventTag }),
|
|
74
|
+
stateUpdated: (name) => instant({ kind: 'state', name, detail: '' }),
|
|
75
|
+
calcRecomputed: (name) => span({ kind: 'calc', name, detail: '' }),
|
|
76
|
+
queryRun: (name) => span({ kind: 'query', name, detail: '' }),
|
|
77
|
+
procedureRun: (name, channel, eventTag) => span({ kind: 'procedure', name, detail: `${channel}:${eventTag}` }),
|
|
78
|
+
uiRendered: (composition) => span({ kind: 'render', name: composition, detail: '' }),
|
|
79
|
+
frame: (eventCount) => span({ kind: 'frame', name: 'frame', detail: String(eventCount) }),
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=recorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorder.js","sourceRoot":"","sources":["../src/recorder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ProfilerHandle } from './recorder.js';
|
|
2
|
+
export interface ProfilerRegistration {
|
|
3
|
+
readonly label: string;
|
|
4
|
+
readonly handle: ProfilerHandle;
|
|
5
|
+
}
|
|
6
|
+
export declare const registerProfiler: (registration: ProfilerRegistration) => (() => void);
|
|
7
|
+
export declare const listProfilers: () => ReadonlyArray<ProfilerRegistration>;
|
|
8
|
+
export declare const subscribeProfilers: (listener: () => void) => (() => void);
|
|
9
|
+
export declare const profilersVersion: () => number;
|
|
10
|
+
export declare const claimOverlay: (owner: object) => boolean;
|
|
11
|
+
export declare const releaseOverlay: (owner: object) => void;
|
|
12
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAIhD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAA;CAChC;AA4BD,eAAO,MAAM,gBAAgB,GAAI,cAAc,oBAAoB,KAAG,CAAC,MAAM,IAAI,CAqBhF,CAAA;AAED,eAAO,MAAM,aAAa,QAAO,aAAa,CAAC,oBAAoB,CACH,CAAA;AAEhE,eAAO,MAAM,kBAAkB,GAAI,UAAU,MAAM,IAAI,KAAG,CAAC,MAAM,IAAI,CAKpE,CAAA;AAED,eAAO,MAAM,gBAAgB,QAAO,MAA+B,CAAA;AAGnE,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,KAAG,OAM5C,CAAA;AAED,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,KAAG,IAK9C,CAAA"}
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { GlobalValue, Option } from 'effect';
|
|
2
|
+
const state = GlobalValue.globalValue(Symbol.for('reform-profiler/registry'), () => ({
|
|
3
|
+
entries: new Map(),
|
|
4
|
+
listeners: new Set(),
|
|
5
|
+
version: { current: 0 },
|
|
6
|
+
overlay: { owner: Option.none() },
|
|
7
|
+
}));
|
|
8
|
+
const notify = () => {
|
|
9
|
+
state.version.current += 1;
|
|
10
|
+
[...state.listeners].forEach((listener) => listener());
|
|
11
|
+
};
|
|
12
|
+
export const registerProfiler = (registration) => {
|
|
13
|
+
const existing = state.entries.get(registration.handle);
|
|
14
|
+
state.entries.set(registration.handle, {
|
|
15
|
+
registration,
|
|
16
|
+
count: existing === undefined ? 1 : existing.count + 1,
|
|
17
|
+
});
|
|
18
|
+
if (existing === undefined) {
|
|
19
|
+
notify();
|
|
20
|
+
}
|
|
21
|
+
return () => {
|
|
22
|
+
const current = state.entries.get(registration.handle);
|
|
23
|
+
if (current === undefined) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (current.count <= 1) {
|
|
27
|
+
state.entries.delete(registration.handle);
|
|
28
|
+
notify();
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
state.entries.set(registration.handle, { ...current, count: current.count - 1 });
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export const listProfilers = () => [...state.entries.values()].map((entry) => entry.registration);
|
|
36
|
+
export const subscribeProfilers = (listener) => {
|
|
37
|
+
state.listeners.add(listener);
|
|
38
|
+
return () => {
|
|
39
|
+
state.listeners.delete(listener);
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
export const profilersVersion = () => state.version.current;
|
|
43
|
+
// First mounted overlay claims render; later instances no-op until claim released.
|
|
44
|
+
export const claimOverlay = (owner) => {
|
|
45
|
+
if (Option.isNone(state.overlay.owner)) {
|
|
46
|
+
state.overlay.owner = Option.some(owner);
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
return Option.contains(state.overlay.owner, owner);
|
|
50
|
+
};
|
|
51
|
+
export const releaseOverlay = (owner) => {
|
|
52
|
+
if (Option.contains(state.overlay.owner, owner)) {
|
|
53
|
+
state.overlay.owner = Option.none();
|
|
54
|
+
notify();
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/report.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,YAAY,CAAA;AAiD7D,eAAO,MAAM,YAAY,GAAI,UAAU,cAAc,KAAG,MAqBvD,CAAA"}
|
package/dist/report.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const sortedRows = (stats) => [...stats.entries()]
|
|
2
|
+
.map(([name, stat]) => ({ name, stat }))
|
|
3
|
+
.toSorted((left, right) => right.stat.totalMs - left.stat.totalMs || right.stat.count - left.stat.count);
|
|
4
|
+
const MS_DECIMALS = 2;
|
|
5
|
+
const formatMs = (durationMs) => durationMs.toFixed(MS_DECIMALS);
|
|
6
|
+
const COUNT_WIDTH = 7;
|
|
7
|
+
const TOTAL_WIDTH = 9;
|
|
8
|
+
const AVG_WIDTH = 8;
|
|
9
|
+
const ruleOverhead = '── '.length + ' '.length;
|
|
10
|
+
const section = ({ title, rows, timed }) => {
|
|
11
|
+
if (rows.length === 0) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
const nameWidth = Math.max('name'.length, ...rows.map((row) => row.name.length));
|
|
15
|
+
const header = timed
|
|
16
|
+
? `${'name'.padEnd(nameWidth)} ${'count'.padStart(COUNT_WIDTH)} ${'total ms'.padStart(TOTAL_WIDTH)} ${'avg ms'.padStart(AVG_WIDTH)}`
|
|
17
|
+
: `${'name'.padEnd(nameWidth)} ${'count'.padStart(COUNT_WIDTH)}`;
|
|
18
|
+
const lines = rows.map((row) => timed
|
|
19
|
+
? `${row.name.padEnd(nameWidth)} ${String(row.stat.count).padStart(COUNT_WIDTH)} ${formatMs(row.stat.totalMs).padStart(TOTAL_WIDTH)} ${formatMs(row.stat.count === 0 ? 0 : row.stat.totalMs / row.stat.count).padStart(AVG_WIDTH)}`
|
|
20
|
+
: `${row.name.padEnd(nameWidth)} ${String(row.stat.count).padStart(COUNT_WIDTH)}`);
|
|
21
|
+
return [
|
|
22
|
+
`── ${title} ${'─'.repeat(Math.max(0, header.length - title.length - ruleOverhead))}`,
|
|
23
|
+
header,
|
|
24
|
+
...lines,
|
|
25
|
+
'',
|
|
26
|
+
];
|
|
27
|
+
};
|
|
28
|
+
export const formatReport = (profiler) => {
|
|
29
|
+
const snapshot = profiler.snapshot();
|
|
30
|
+
const frameRows = snapshot.frames.count === 0 ? [] : [{ name: 'frame', stat: snapshot.frames }];
|
|
31
|
+
const dropped = snapshot.dropped === 0
|
|
32
|
+
? []
|
|
33
|
+
: [`(${snapshot.dropped} early records evicted from the ring buffer)`, ''];
|
|
34
|
+
return [
|
|
35
|
+
`reform profile — ${profiler.label}`,
|
|
36
|
+
'',
|
|
37
|
+
...section({ title: 'Events', rows: sortedRows(snapshot.events), timed: false }),
|
|
38
|
+
...section({ title: 'Reducers', rows: sortedRows(snapshot.reducers), timed: true }),
|
|
39
|
+
...section({ title: 'State updates', rows: sortedRows(snapshot.states), timed: false }),
|
|
40
|
+
...section({ title: 'Calcs', rows: sortedRows(snapshot.calcs), timed: true }),
|
|
41
|
+
...section({ title: 'Queries', rows: sortedRows(snapshot.queries), timed: true }),
|
|
42
|
+
...section({ title: 'Procedures', rows: sortedRows(snapshot.procedures), timed: true }),
|
|
43
|
+
...section({ title: 'Renders', rows: sortedRows(snapshot.renders), timed: true }),
|
|
44
|
+
...section({ title: 'Frames', rows: frameRows, timed: true }),
|
|
45
|
+
...dropped,
|
|
46
|
+
].join('\n');
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,GAAG,CAAC,KAAuC,EAAsB,EAAE,CACjF,CAAC,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;KACjB,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAO,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;KAC5C,QAAQ,CACP,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAC9F,CAAA;AAEL,MAAM,WAAW,GAAG,CAAC,CAAA;AACrB,MAAM,QAAQ,GAAG,CAAC,UAAkB,EAAU,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;AAEhF,MAAM,WAAW,GAAG,CAAC,CAAA;AACrB,MAAM,WAAW,GAAG,CAAC,CAAA;AACrB,MAAM,SAAS,GAAG,CAAC,CAAA;AACnB,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAA;AAQ9C,MAAM,OAAO,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAW,EAAyB,EAAE;IACzE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,CAAA;IACX,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;IAChF,MAAM,MAAM,GAAG,KAAK;QAClB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,UAAU,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;QACvI,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAA;IACnE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAC7B,KAAK;QACH,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;QACtO,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CACrF,CAAA;IACD,OAAO;QACL,MAAM,KAAK,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,YAAY,CAAC,CAAC,EAAE;QACrF,MAAM;QACN,GAAG,KAAK;QACR,EAAE;KACH,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,QAAwB,EAAU,EAAE;IAC/D,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAA;IACpC,MAAM,SAAS,GACb,QAAQ,CAAC,MAAM,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;IAC/E,MAAM,OAAO,GACX,QAAQ,CAAC,OAAO,KAAK,CAAC;QACpB,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,OAAO,8CAA8C,EAAE,EAAE,CAAC,CAAA;IAC9E,OAAO;QACL,oBAAoB,QAAQ,CAAC,KAAK,EAAE;QACpC,EAAE;QACF,GAAG,OAAO,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAChF,GAAG,OAAO,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACnF,GAAG,OAAO,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACvF,GAAG,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QAC7E,GAAG,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACjF,GAAG,OAAO,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACvF,GAAG,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACjF,GAAG,OAAO,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QAC7D,GAAG,OAAO;KACX,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACd,CAAC,CAAA"}
|
package/dist/trace.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ProfilerHandle } from './recorder.js';
|
|
2
|
+
export type ChromeTraceEvent = {
|
|
3
|
+
readonly ph: 'X';
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly cat: string;
|
|
6
|
+
readonly ts: number;
|
|
7
|
+
readonly dur: number;
|
|
8
|
+
readonly pid: number;
|
|
9
|
+
readonly tid: number;
|
|
10
|
+
readonly args: Readonly<Record<string, string>>;
|
|
11
|
+
} | {
|
|
12
|
+
readonly ph: 'i';
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly cat: string;
|
|
15
|
+
readonly ts: number;
|
|
16
|
+
readonly pid: number;
|
|
17
|
+
readonly tid: number;
|
|
18
|
+
readonly s: 't';
|
|
19
|
+
readonly args: Readonly<Record<string, string>>;
|
|
20
|
+
} | {
|
|
21
|
+
readonly ph: 'M';
|
|
22
|
+
readonly name: 'process_name' | 'thread_name';
|
|
23
|
+
readonly ts: 0;
|
|
24
|
+
readonly pid: number;
|
|
25
|
+
readonly tid: number;
|
|
26
|
+
readonly args: {
|
|
27
|
+
readonly name: string;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export interface ChromeTrace {
|
|
31
|
+
readonly traceEvents: ReadonlyArray<ChromeTraceEvent>;
|
|
32
|
+
readonly displayTimeUnit: 'ms';
|
|
33
|
+
}
|
|
34
|
+
export declare const toChromeTrace: (profiler: ProfilerHandle) => ChromeTrace;
|
|
35
|
+
export declare const traceJson: (profiler: ProfilerHandle) => string;
|
|
36
|
+
//# sourceMappingURL=trace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../src/trace.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,cAAc,EAAE,MAAM,YAAY,CAAA;AAE7D,MAAM,MAAM,gBAAgB,GACxB;IACE,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAA;IAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAChD,GACD;IACE,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAA;IAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAA;IACf,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAChD,GACD;IACE,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAA;IAChB,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,aAAa,CAAA;IAC7C,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAA;IACd,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CACzC,CAAA;AAEL,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAA;IACrD,QAAQ,CAAC,eAAe,EAAE,IAAI,CAAA;CAC/B;AAkBD,eAAO,MAAM,aAAa,GAAI,UAAU,cAAc,KAAG,WA0CxD,CAAA;AAED,eAAO,MAAM,SAAS,GAAI,UAAU,cAAc,KAAG,MAEZ,CAAA"}
|
package/dist/trace.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const lanes = {
|
|
2
|
+
frame: { tid: 1, title: 'frames' },
|
|
3
|
+
event: { tid: 2, title: 'events' },
|
|
4
|
+
reducer: { tid: 3, title: 'reducers' },
|
|
5
|
+
state: { tid: 4, title: 'state updates' },
|
|
6
|
+
calc: { tid: 5, title: 'calcs' },
|
|
7
|
+
query: { tid: 6, title: 'queries' },
|
|
8
|
+
procedure: { tid: 7, title: 'procedures' },
|
|
9
|
+
render: { tid: 8, title: 'renders' },
|
|
10
|
+
};
|
|
11
|
+
const instantKinds = new Set(['event', 'state']);
|
|
12
|
+
const pid = 1;
|
|
13
|
+
const US_PER_MS = 1000;
|
|
14
|
+
export const toChromeTrace = (profiler) => {
|
|
15
|
+
const { records } = profiler.snapshot();
|
|
16
|
+
const meta = [
|
|
17
|
+
{
|
|
18
|
+
ph: 'M',
|
|
19
|
+
name: 'process_name',
|
|
20
|
+
ts: 0,
|
|
21
|
+
pid,
|
|
22
|
+
tid: 0,
|
|
23
|
+
args: { name: `reform: ${profiler.label}` },
|
|
24
|
+
},
|
|
25
|
+
...Object.values(lanes).map((lane) => ({
|
|
26
|
+
ph: 'M',
|
|
27
|
+
name: 'thread_name',
|
|
28
|
+
ts: 0,
|
|
29
|
+
pid,
|
|
30
|
+
tid: lane.tid,
|
|
31
|
+
args: { name: lane.title },
|
|
32
|
+
})),
|
|
33
|
+
];
|
|
34
|
+
const body = records.map((record) => {
|
|
35
|
+
const startUs = record.start * US_PER_MS;
|
|
36
|
+
const cat = record.kind;
|
|
37
|
+
const tid = lanes[record.kind].tid;
|
|
38
|
+
const args = record.detail === '' ? {} : { detail: record.detail };
|
|
39
|
+
const complete = {
|
|
40
|
+
ph: 'X',
|
|
41
|
+
name: record.name,
|
|
42
|
+
cat,
|
|
43
|
+
ts: startUs,
|
|
44
|
+
dur: record.dur * US_PER_MS,
|
|
45
|
+
pid,
|
|
46
|
+
tid,
|
|
47
|
+
args,
|
|
48
|
+
};
|
|
49
|
+
return instantKinds.has(record.kind)
|
|
50
|
+
? { ph: 'i', name: record.name, cat, ts: startUs, pid, tid, s: 't', args }
|
|
51
|
+
: complete;
|
|
52
|
+
});
|
|
53
|
+
return { traceEvents: [...meta, ...body], displayTimeUnit: 'ms' };
|
|
54
|
+
};
|
|
55
|
+
export const traceJson = (profiler) =>
|
|
56
|
+
// oxlint-disable-next-line reform-rules/no-json-parse-stringify -- Trace Event Format is a foreign wire format consumed by Chrome DevTools/Perfetto, not Schema-typed data
|
|
57
|
+
JSON.stringify(toChromeTrace(profiler));
|
|
58
|
+
//# sourceMappingURL=trace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace.js","sourceRoot":"","sources":["../src/trace.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playfast/reform-profiler",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Performance profiler for reform scenes — a recording Instrumentation, Chrome DevTools trace export, terminal reports, and a React overlay. Dev builds get the real recorder; prod builds resolve to no-op stubs.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"devtools",
|
|
@@ -19,22 +19,39 @@
|
|
|
19
19
|
"directory": "packages/reform-profiler"
|
|
20
20
|
},
|
|
21
21
|
"files": [
|
|
22
|
+
"dist",
|
|
22
23
|
"src",
|
|
23
24
|
"README.md"
|
|
24
25
|
],
|
|
25
26
|
"type": "module",
|
|
26
27
|
"sideEffects": false,
|
|
28
|
+
"main": "./dist/noop.js",
|
|
29
|
+
"types": "./dist/noop.d.ts",
|
|
27
30
|
"exports": {
|
|
28
31
|
"./package.json": "./package.json",
|
|
29
32
|
".": {
|
|
30
|
-
"
|
|
31
|
-
|
|
33
|
+
"playfast-src": {
|
|
34
|
+
"development": "./src/index.ts",
|
|
35
|
+
"default": "./src/noop.ts"
|
|
36
|
+
},
|
|
37
|
+
"development": "./dist/index.js",
|
|
38
|
+
"types": "./dist/noop.d.ts",
|
|
39
|
+
"default": "./dist/noop.js"
|
|
32
40
|
},
|
|
33
41
|
"./react": {
|
|
34
|
-
"
|
|
35
|
-
|
|
42
|
+
"playfast-src": {
|
|
43
|
+
"development": "./src/react/index.ts",
|
|
44
|
+
"default": "./src/react/noop.ts"
|
|
45
|
+
},
|
|
46
|
+
"development": "./dist/react/index.js",
|
|
47
|
+
"types": "./dist/react/noop.d.ts",
|
|
48
|
+
"default": "./dist/react/noop.js"
|
|
36
49
|
},
|
|
37
|
-
"./recorder":
|
|
50
|
+
"./recorder": {
|
|
51
|
+
"playfast-src": "./src/index.ts",
|
|
52
|
+
"types": "./dist/index.d.ts",
|
|
53
|
+
"default": "./dist/index.js"
|
|
54
|
+
}
|
|
38
55
|
},
|
|
39
56
|
"publishConfig": {
|
|
40
57
|
"access": "public"
|
|
@@ -42,12 +59,13 @@
|
|
|
42
59
|
"scripts": {
|
|
43
60
|
"clean": "rm -rf dist .tsbuildinfo",
|
|
44
61
|
"check": "tsc --noEmit",
|
|
45
|
-
"build": "tsc -p tsconfig.build.json",
|
|
62
|
+
"build": "rm -rf dist .tsbuildinfo && tsc -p tsconfig.build.json && bun ../../scripts/fix-esm-extensions.ts dist",
|
|
46
63
|
"test": "vitest run",
|
|
47
64
|
"test:watch": "vitest",
|
|
48
65
|
"coverage": "vitest run --coverage",
|
|
49
66
|
"lint": "oxlint src",
|
|
50
|
-
"lint:fix": "oxlint --fix src"
|
|
67
|
+
"lint:fix": "oxlint --fix src",
|
|
68
|
+
"prepack": "bun run build"
|
|
51
69
|
},
|
|
52
70
|
"peerDependencies": {
|
|
53
71
|
"@playfast/reform": "*",
|
package/src/profiler.test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Schema as S } from 'effect'
|
|
1
|
+
import { Effect, Option, Schema as S } from 'effect'
|
|
2
2
|
import { expect, test } from 'vitest'
|
|
3
3
|
import {
|
|
4
4
|
Composition,
|
|
@@ -16,13 +16,19 @@ import {
|
|
|
16
16
|
ui,
|
|
17
17
|
} from '@playfast/reform'
|
|
18
18
|
import { Layer } from 'effect'
|
|
19
|
+
import { until } from '@playfast/reform/testkit/flight.testkit'
|
|
19
20
|
import { makeProfiler } from './recorder'
|
|
20
21
|
import { profileScene } from './profileScene'
|
|
21
22
|
import { listProfilers } from './registry'
|
|
22
23
|
import { toChromeTrace, traceJson } from './trace'
|
|
23
24
|
import { formatReport } from './report'
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
// The recorder coalesces on the reform scheduler's queueMicrotask; a microtask
|
|
27
|
+
// queued after it therefore runs once every pending flush has drained.
|
|
28
|
+
const flushed = (): Promise<void> => new Promise((resolve) => queueMicrotask(() => resolve()))
|
|
29
|
+
|
|
30
|
+
const reaches = <A>(read: () => A, predicate: (value: A) => boolean): Promise<A> =>
|
|
31
|
+
Effect.runPromise(until(read, predicate))
|
|
26
32
|
|
|
27
33
|
test('aggregates count and time per name, per kind', () => {
|
|
28
34
|
const profiler = makeProfiler({ label: 'agg' })
|
|
@@ -76,11 +82,11 @@ test('subscribers are notified once per burst (coalesced)', async () => {
|
|
|
76
82
|
profiler.eventDispatched('a', 'High')
|
|
77
83
|
profiler.eventDispatched('b', 'High')
|
|
78
84
|
profiler.eventDispatched('c', 'High')
|
|
79
|
-
await
|
|
85
|
+
await flushed()
|
|
80
86
|
expect(calls.count).toBe(1)
|
|
81
87
|
unsubscribe()
|
|
82
88
|
profiler.eventDispatched('d', 'High')
|
|
83
|
-
await
|
|
89
|
+
await flushed()
|
|
84
90
|
expect(calls.count).toBe(1)
|
|
85
91
|
})
|
|
86
92
|
|
|
@@ -151,9 +157,15 @@ test('profileScene records engine activity through makeAppRuntime and registers
|
|
|
151
157
|
|
|
152
158
|
runtime.boot()
|
|
153
159
|
runtime.dispatch('High', Event.construct(Bumped, {}))
|
|
154
|
-
await settle()
|
|
155
160
|
|
|
156
|
-
const snapshot =
|
|
161
|
+
const snapshot = await reaches(
|
|
162
|
+
() => profiler.snapshot(),
|
|
163
|
+
(taken) =>
|
|
164
|
+
(taken.events.get('ProfilerBumped')?.count ?? 0) >= 2 &&
|
|
165
|
+
(taken.reducers.get('ProfilerBump')?.count ?? 0) >= 2 &&
|
|
166
|
+
(taken.states.get('profiler-count')?.count ?? 0) >= 2 &&
|
|
167
|
+
taken.frames.count >= 1,
|
|
168
|
+
)
|
|
157
169
|
expect(snapshot.events.get('ProfilerBumped')?.count).toBe(2)
|
|
158
170
|
expect(snapshot.reducers.get('ProfilerBump')?.count).toBe(2)
|
|
159
171
|
expect(snapshot.states.get('profiler-count')?.count).toBe(2)
|
|
@@ -164,13 +176,23 @@ test('profileScene records engine activity through makeAppRuntime and registers
|
|
|
164
176
|
expect(report).toContain('ProfilerBump')
|
|
165
177
|
|
|
166
178
|
runtime.dispose()
|
|
167
|
-
await
|
|
179
|
+
await reaches(
|
|
180
|
+
() => listProfilers().map((entry) => entry.handle),
|
|
181
|
+
(handles) => !handles.includes(profiler),
|
|
182
|
+
)
|
|
168
183
|
expect(listProfilers().map((entry) => entry.handle)).not.toContain(profiler)
|
|
169
184
|
|
|
170
185
|
const before = profiler.snapshot().events.get('ProfilerBumped')?.count
|
|
171
186
|
const plain = makeAppRuntime(baseScene)
|
|
187
|
+
// The plain runtime's own count landing proves its frame ran; the profiler must not have seen it.
|
|
188
|
+
const plainCount = Option.getOrThrow(
|
|
189
|
+
plain.readOption(StateGroup.select(States, 'profiler-count').store),
|
|
190
|
+
)
|
|
172
191
|
plain.dispatch('High', Event.construct(Bumped, {}))
|
|
173
|
-
await
|
|
192
|
+
await reaches(
|
|
193
|
+
() => plainCount.get(),
|
|
194
|
+
(count) => count === 1,
|
|
195
|
+
)
|
|
174
196
|
expect(profiler.snapshot().events.get('ProfilerBumped')?.count).toBe(before)
|
|
175
197
|
plain.dispose()
|
|
176
198
|
})
|