Skip to content

Commit f726bf4

Browse files
authored
feat: devtools support (#563)
feat(devtools): add `addEvent` feat(devtools): add `useDevtoolsInpector`
1 parent 9b7fc77 commit f726bf4

File tree

23 files changed

+1049
-99
lines changed

23 files changed

+1049
-99
lines changed

docs/api/vue-composable.api.md

Lines changed: 114 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@
33
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
44
55
```ts
6+
import { App } from "@vue/runtime-core";
67
import { ComputedRef } from "@vue/runtime-core";
8+
import { CustomInspectorNode } from "@vue/devtools-api";
9+
import { CustomInspectorOptions } from "@vue/devtools-api";
10+
import { CustomInspectorState } from "@vue/devtools-api";
711
import { DeepReadonly } from "@vue/runtime-core";
12+
import { DevtoolsPluginApi } from "@vue/devtools-api";
813
import { InjectionKey } from "@vue/runtime-core";
914
import { Plugin as Plugin_2 } from "@vue/runtime-core";
1015
import { provide } from "@vue/runtime-core";
1116
import { Ref } from "@vue/runtime-core";
17+
import { TimelineEvent } from "@vue/devtools-api";
1218
import { UnwrapRef } from "@vue/runtime-core";
1319

1420
// @public (undocumented)
@@ -350,6 +356,68 @@ export function deepClone<T extends object = object>(
350356
...sources: T[]
351357
): T;
352358

359+
// @public (undocumented)
360+
export interface DevtoolInspectorNode extends CustomInspectorNode {
361+
// (undocumented)
362+
children: DevtoolInspectorNode[];
363+
// (undocumented)
364+
state: CustomInspectorState;
365+
}
366+
367+
// @public (undocumented)
368+
export interface DevtoolInspectorNodeState {
369+
// (undocumented)
370+
"register module": RefTyped<DevtoolInspectorNodeStateValue>[];
371+
// (undocumented)
372+
"unregister module": RefTyped<DevtoolInspectorNodeStateValue>[];
373+
// (undocumented)
374+
"vuex bindings": RefTyped<DevtoolInspectorNodeStateValue>[];
375+
// (undocumented)
376+
$attrs: RefTyped<DevtoolInspectorNodeStateValue>[];
377+
// (undocumented)
378+
$refs: RefTyped<DevtoolInspectorNodeStateValue>[];
379+
// (undocumented)
380+
[key: string]: RefTyped<DevtoolInspectorNodeStateValue>[];
381+
// (undocumented)
382+
computed: RefTyped<DevtoolInspectorNodeStateValue>[];
383+
// (undocumented)
384+
getters: RefTyped<DevtoolInspectorNodeStateValue>[];
385+
// (undocumented)
386+
mutation: RefTyped<DevtoolInspectorNodeStateValue>[];
387+
// (undocumented)
388+
props: RefTyped<DevtoolInspectorNodeStateValue>[];
389+
// (undocumented)
390+
setup: RefTyped<DevtoolInspectorNodeStateValue>[];
391+
// (undocumented)
392+
state: RefTyped<DevtoolInspectorNodeStateValue>[];
393+
// (undocumented)
394+
undefined: RefTyped<DevtoolInspectorNodeStateValue>[];
395+
}
396+
397+
// @public (undocumented)
398+
export interface DevtoolInspectorNodeStateValue {
399+
// (undocumented)
400+
editable: boolean;
401+
// (undocumented)
402+
objectType: string;
403+
// (undocumented)
404+
type: string;
405+
// (undocumented)
406+
value: any;
407+
}
408+
409+
// @public (undocumented)
410+
export type DevtoolsInpectorNodeFilter = (
411+
search: string,
412+
nodes: DevtoolInspectorNode[]
413+
) => DevtoolInspectorNode[];
414+
415+
// @public (undocumented)
416+
export type DevtoolsInpectorStateFilter = (
417+
search: string,
418+
state: CustomInspectorState
419+
) => CustomInspectorState;
420+
353421
// Warning: (ae-forgotten-export) The symbol "RetryDelayFactory" needs to be exported by the entry point index.d.ts
354422
//
355423
// @public (undocumented)
@@ -384,6 +452,9 @@ export function getCssVariableFor(
384452
name: string
385453
): CssVariable;
386454

455+
// @public
456+
export function getDevtools(): DevtoolsPluginApi | undefined;
457+
387458
// @public (undocumented)
388459
export const hydrationPlugin: Plugin_2;
389460

@@ -891,7 +962,7 @@ export const enum RefSharedMessageType {
891962
// (undocumented)
892963
SYNC = 1,
893964
// (undocumented)
894-
UPDATE = 2
965+
UPDATE = 2,
895966
}
896967

897968
// @public (undocumented)
@@ -969,6 +1040,9 @@ export function setCssVariableFor(
9691040
value: CssVariable
9701041
): void;
9711042

1043+
// @public
1044+
export function setDevtools(app: App, api: DevtoolsPluginApi): void;
1045+
9721046
// @public
9731047
export function setI18n<
9741048
T extends i18nDefinition<TMessage>,
@@ -985,7 +1059,7 @@ export const enum SharedRefMind {
9851059
// (undocumented)
9861060
HIVE = 0,
9871061
// (undocumented)
988-
MASTER = 1
1062+
MASTER = 1,
9891063
}
9901064

9911065
// @public (undocumented)
@@ -1054,6 +1128,7 @@ export interface UndoOperation {
10541128
export interface UndoOptions<T> {
10551129
clone: (entry: T) => T;
10561130
deep: boolean;
1131+
devtoolId?: string;
10571132
maxLength: number;
10581133
}
10591134

@@ -1277,6 +1352,31 @@ export function useDebounce<T extends Procedure>(
12771352
options?: Options
12781353
): T;
12791354

1355+
// @public (undocumented)
1356+
export const UseDevtoolsApp: (app: App, id?: string, label?: string) => void;
1357+
1358+
// @public (undocumented)
1359+
export function useDevtoolsInpector(
1360+
options: CustomInspectorOptions & {
1361+
nodeFilter?: DevtoolsInpectorNodeFilter;
1362+
stateFilter?: DevtoolsInpectorStateFilter;
1363+
},
1364+
nodeList?: DevtoolInspectorNode[]
1365+
): {
1366+
nodes: Ref<DevtoolInspectorNode[]>;
1367+
};
1368+
1369+
// @public (undocumented)
1370+
export function useDevtoolsTimelineLayer(
1371+
id: string,
1372+
label: string,
1373+
color: number
1374+
): {
1375+
id: string;
1376+
addEvent: (event: TimelineEvent, all?: boolean | undefined) => any;
1377+
pushEvent: (event: Omit<TimelineEvent, "time">) => any;
1378+
};
1379+
12801380
// @public (undocumented)
12811381
export function useEvent<K extends keyof DocumentEventMap>(
12821382
el: RefTyped<Document>,
@@ -1352,6 +1452,7 @@ export function useFetch<T = any>(
13521452

13531453
// @public (undocumented)
13541454
export interface UseFetchOptions {
1455+
devtoolId?: boolean | string;
13551456
isJson?: boolean;
13561457
parseImmediate?: boolean;
13571458
unmountCancel?: boolean;
@@ -2069,6 +2170,17 @@ export const VERSION: string;
20692170
// @public (undocumented)
20702171
export const VUE_VERSION: "2" | "3";
20712172

2173+
// @public (undocumented)
2174+
export const VueComposableDevtools: {
2175+
install(
2176+
app: App,
2177+
options?: {
2178+
id: string;
2179+
label: string;
2180+
}
2181+
): void;
2182+
};
2183+
20722184
// @public (undocumented)
20732185
export interface WebSocketReturn {
20742186
// (undocumented)

examples/vue-composable-example/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
"lint": "vue-cli-service lint"
99
},
1010
"dependencies": {
11-
"@vue-composable/axios": "^1.0.0-beta.1",
12-
"vue": "^2.6.11",
13-
"vue-composable": "^1.0.0-beta.1"
11+
"@vue-composable/axios": "^1.0.0-beta.5",
12+
"vue": "^2.6.12",
13+
"vue-composable": "^1.0.0-beta.5"
1414
},
1515
"devDependencies": {
1616
"@vue/cli-plugin-babel": "4.4.6",

examples/vue-composable-example/yarn.lock

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,12 +1151,12 @@
11511151
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8"
11521152
integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==
11531153

1154-
"@vue-composable/axios@^1.0.0-beta.1":
1155-
version "1.0.0-beta.3"
1156-
resolved "https://registry.yarnpkg.com/@vue-composable/axios/-/axios-1.0.0-beta.3.tgz#5e50a1cf15a1efbb02339a659835eefb40546ccf"
1157-
integrity sha512-sPkivRnWvYd4TsDia3ivpqxiw4UKCac9t3SuarJHBGJbw1l2LG2G6XT9LNdkHCIDe4yxqh09OGXqyO3P6jNMYg==
1154+
"@vue-composable/axios@^1.0.0-beta.5":
1155+
version "1.0.0-beta.5"
1156+
resolved "https://registry.yarnpkg.com/@vue-composable/axios/-/axios-1.0.0-beta.5.tgz#aea2c1f3a934ffe689a3c32a0e939b118b79b32c"
1157+
integrity sha512-RIH325JtgcVLifXB+eT0tQyPl6uTyVipoXcor+lULAi5XIkHZa9OluRs8sRXCWrx2ByQIb+FUhnxuTBnRKJiqg==
11581158
dependencies:
1159-
vue-composable "^1.0.0-beta.3"
1159+
vue-composable "^1.0.0-beta.5"
11601160

11611161
"@vue/babel-helper-vue-jsx-merge-props@^1.0.0":
11621162
version "1.0.0"
@@ -7887,10 +7887,10 @@ vm-browserify@^1.0.1:
78877887
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
78887888
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
78897889

7890-
vue-composable@^1.0.0-beta.1, vue-composable@^1.0.0-beta.3:
7891-
version "1.0.0-beta.3"
7892-
resolved "https://registry.yarnpkg.com/vue-composable/-/vue-composable-1.0.0-beta.3.tgz#ba442d24768b8a452dc4b313f42840ef8ecd3d99"
7893-
integrity sha512-PZ19JR3/aZc/PPDZhJC9X4oytSo7eDpoKku6cHQX4OHAGRxg7Cqb/rDt7mbZk3zCIb3GD6jpR3Qm8HqliV745Q==
7890+
vue-composable@^1.0.0-beta.5:
7891+
version "1.0.0-beta.5"
7892+
resolved "https://registry.yarnpkg.com/vue-composable/-/vue-composable-1.0.0-beta.5.tgz#3de1ee9dbd1768c575d06a3657c1b7234df9e49c"
7893+
integrity sha512-AsuyLdUhbsdYlnDC7Se3207j8WXNoy0/9hwGmkuxJE5QIylOTd6vkg4nyJ8j+vTL740nEofVwnwsH20W0pc2jw==
78947894

78957895
vue-hot-reload-api@^2.3.0:
78967896
version "2.3.4"
@@ -7929,10 +7929,10 @@ vue-template-es2015-compiler@^1.9.0:
79297929
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
79307930
integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==
79317931

7932-
vue@^2.6.11:
7933-
version "2.6.11"
7934-
resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5"
7935-
integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ==
7932+
vue@^2.6.12:
7933+
version "2.6.12"
7934+
resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.12.tgz#f5ebd4fa6bd2869403e29a896aed4904456c9123"
7935+
integrity sha512-uhmLFETqPPNyuLLbsKz6ioJ4q7AZHzD8ZVFNATNyICSZouqP2Sz0rotWQC8UNBF6VGSCs5abnKJoStA6JbCbfg==
79367936

79377937
watchpack@^1.6.0:
79387938
version "1.6.0"

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
"lodash.camelcase": "^4.3.0",
8585
"minimist": "^1.2.5",
8686
"mock-socket": "^9.0.3",
87+
"prettier": "^2.1.1",
8788
"rimraf": "^3.0.2",
8889
"rollup": "^2.26.10",
8990
"rollup-plugin-terser": "^7.0.2",

packages/vue-composable/README.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,103 @@ Check our [documentation](https://pikax.me/vue-composable/)
151151

152152
This is a monorepo project, please check [packages](packages/)
153153

154+
## Devtools
155+
156+
There's some experimental devtools support starting from `1.0.0-beta.6`, only available for `vue-next` and `devtools beta 6`.
157+
158+
- [devtools beta chrome](https://chrome.google.com/webstore/detail/vuejs-devtools/ljjemllljcmogpfapbkkighbhhppjdbg)
159+
160+
### Install plugin
161+
162+
To use devtools you need to install the plugin first:
163+
164+
```ts
165+
import { createApp } from "vue";
166+
import { VueComposableDevtools } from "vue-composable";
167+
import App from "./App.vue";
168+
169+
const app = createApp(App);
170+
app.use(VueComposableDevtools);
171+
// or
172+
app.use(VueComposableDevtools, {
173+
id: "vue-composable",
174+
label: "devtool composables",
175+
});
176+
177+
app.mount("#app");
178+
```
179+
180+
### Timeline events
181+
182+
To add timeline events:
183+
184+
```ts
185+
const id = "vue-composable";
186+
const label = "Test events";
187+
const color = 0x92a2bf;
188+
189+
const { addEvent, pushEvent } = useDevtoolsTimelineLayer(
190+
id,
191+
description,
192+
color
193+
);
194+
195+
// adds event to a specific point in the timeline
196+
addEvent({
197+
time: Date.now(),
198+
data: {
199+
// data object
200+
},
201+
meta: {
202+
// meta object
203+
},
204+
});
205+
206+
// adds event with `time: Date.now()`
207+
pushEvent({
208+
data: {
209+
// data object
210+
},
211+
meta: {
212+
// meta object
213+
},
214+
});
215+
```
216+
217+
### Inspector
218+
219+
Allows to create a new inpector for your data.
220+
221+
> I'm still experimenting on how to expose this API on a composable, this will likely to change in the future, suggestions are welcome.
222+
223+
```ts
224+
useDevtoolsInpector(
225+
{
226+
id: "vue-composable",
227+
label: "test vue-composable",
228+
},
229+
// list of nodes, this can be reactive
230+
[
231+
{
232+
id: "test",
233+
label: "test - vue-composable",
234+
depth: 0,
235+
state: {
236+
composable: [
237+
{
238+
editable: false,
239+
key: "count",
240+
objectType: "Ref",
241+
type: "setup",
242+
value: myRefValue,
243+
},
244+
],
245+
},
246+
},
247+
]
248+
);
249+
```
250+
154251
## Contributing
155252

156253
You can contribute raising issues and by helping out with code.

0 commit comments

Comments
 (0)