Skip to content

Commit

Permalink
Introduce in-devtools state changes and other improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
wszerad committed Feb 2, 2021
1 parent 232a891 commit c022027
Show file tree
Hide file tree
Showing 11 changed files with 126 additions and 74 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,6 @@ Decorator, if the method performs any async operation should be decorated with (

## Events

* ActionEvent = Action
* PatchEvent = Patch
* ActionEvent = some async activities (trigger PatchEvens or SetEvents)
* PatchEvent = grouped values change
* SetEvent = directly value change
12 changes: 8 additions & 4 deletions example/shop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,16 @@ class Shop {
}

@Action()
buy() {
async buy() {
this.sending = true;
this.clearCart();
window.setTimeout(() => {
this.sending = false;
}, 1000);

return new Promise((res, rej) => {
window.setTimeout(() => {
this.sending = false;
res(true);
}, 3000);
})
}
}

Expand Down
35 changes: 22 additions & 13 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "widok",
"version": "0.5.2",
"version": "0.5.3",
"description": "Vue3 simple store",
"author": "[email protected]",
"license": "MIT",
Expand Down Expand Up @@ -36,7 +36,7 @@
"build": "vite build && tsc"
},
"dependencies": {
"@vue/devtools-api": "^6.0.0-beta.3"
"@vue/devtools-api": "^6.0.0-beta.6"
},
"peerDependencies": {
"vue": "^3.0.0",
Expand All @@ -46,7 +46,7 @@
"typescript": "^4.1.3",
"@types/node": "^14.14.10",
"eslint": "^7.14.0",
"vite": "^2.0.0-beta.59",
"vite": "^2.0.0-beta.61",
"vue": "^3.0.5",
"@vitejs/plugin-vue": "^1.1.3",
"@vue/compiler-sfc": "^3.0.5",
Expand Down
11 changes: 2 additions & 9 deletions src/Controller.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { ActionEvent } from './types/ActionEvent';
import { PatchEvent } from './types/PatchEvent';
import { StoreEvent } from './types/StoreEvent';
import { Subscription } from './utils/Subscription';

export class Controller<T> extends Subscription<ActionEvent | PatchEvent> {
export class Controller<T> extends Subscription<StoreEvent> {
mutating = false;
replacing = false;
store: T;
Expand All @@ -16,10 +15,4 @@ export class Controller<T> extends Subscription<ActionEvent | PatchEvent> {
setup(store: T) {
this.store = store;
}

replaceState(state: T) {
this.replacing = true;
Object.assign(this.store, state);
this.replacing = false;
}
}
15 changes: 9 additions & 6 deletions src/types/ActionEvent.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { StoreEvent } from './StoreEvent';

export class ActionEvent<T = any> {
constructor(
public name: string,
public payload: T,
public type = 'Action',
) {}
export class ActionEvent<T = any> extends StoreEvent<T> {
finished = false;
type = 'Action'

end() {
this.finished = true;
return this;
}
}
9 changes: 3 additions & 6 deletions src/types/PatchEvent.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { StoreEvent } from './StoreEvent';

export class PatchEvent<T = any> {
constructor(
public name: string,
public payload: T,
public type = 'Patch',
) {}
export class PatchEvent<T = any> extends StoreEvent<T> {
type = 'Patch';
}
9 changes: 3 additions & 6 deletions src/types/SetEvent.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { StoreEvent } from './StoreEvent';

export class SetEvent<T = any> {
constructor(
public name: string,
public payload: T,
public type = 'Set',
) {}
export class SetEvent<T = any> extends StoreEvent<T> {
type = 'Set';
}
11 changes: 11 additions & 0 deletions src/types/StoreEvent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
let uuid = 0;

export abstract class StoreEvent<T = any> {
constructor(
public name: string,
public payload: T,
public uid: number = uuid++
) {}

abstract type: string;
}
78 changes: 54 additions & 24 deletions src/utils/devtools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { setupDevtoolsPlugin } from '@vue/devtools-api';
import { App } from 'vue';
import { Controller } from '../Controller';
import { ControllerCollector } from '../ControllerCollector';
import { ActionEvent } from '../types/ActionEvent';
import { CreateControllerEvent } from '../types/CreateControllerEvent';
import { PatchEvent } from '../types/PatchEvent';
import { SetEvent } from '../types/SetEvent';
import { StoreEvent } from '../types/StoreEvent';

function formatPayload(payload: any[]) {
if (payload.length < 2) {
Expand All @@ -11,39 +15,46 @@ function formatPayload(payload: any[]) {
return payload;
}

const stateType = '🌄 Widok';

export function addDevtools(app: App, collector: ControllerCollector) {
setupDevtoolsPlugin(
{
id: 'widok',
label: 'Widok',
packageName: 'widok',
homepage: 'https://github.com/wszerad/widok',
componentStateTypes: [
stateType
],
app,
},
(api) => {
api.on.inspectComponent((payload, ctx) => {
if (payload.instanceData) {
collector.controllers.forEach(controller => {
payload.instanceData.state.push({
type: '🌄 Widok',
key: controller.name,
editable: false,
value: controller.store,
});
});
}
});
// api.on.inspectComponent((payload, ctx) => {
// if (payload.instanceData) {
// collector.controllers.forEach(controller => {
// payload.instanceData.state.push({
// type: stateType,
// key: controller.name,
// editable: true,
// value: controller.store,
// });
// });
// }
// });

const layerId = 'widok:events';
const inspectorId = 'widok';

api.addTimelineLayer({
id: layerId,
label: `🌄 Widok`,
label: stateType,
color: 0xe5df88,
});

api.addInspector({
id: inspectorId,
label: 'Widok',
label: stateType,
icon: 'terrain',
treeFilterPlaceholder: 'Search stores',
});
Expand All @@ -55,18 +66,20 @@ export function addDevtools(app: App, collector: ControllerCollector) {
api.sendInspectorState(inspectorId);

const payload = formatPayload(event.payload);
const finishedAction = event instanceof ActionEvent && event.finished;

api.addTimelineEvent({
layerId: layerId,
event: {
groupId: event.uid,
time: Date.now(),
title: withEventTitlePrefix(event),
data: {
store: controller.name,
name: event.name,
type: event.type,
...(payload !== undefined ? { payload } : {})
},
// TODO: remove when fixed
meta: {},
name: event.name,
...(!finishedAction && payload !== undefined ? { payload } : {})
}
},
});
});
Expand Down Expand Up @@ -108,7 +121,7 @@ export function addDevtools(app: App, collector: ControllerCollector) {
.map(key => {
return {
key,
editable: false,
editable: true,
value: controller.store[key]
};
})
Expand All @@ -117,13 +130,30 @@ export function addDevtools(app: App, collector: ControllerCollector) {
}
});

// TODO add edit option
// api.on.editInspectorState(payload => {
// console.log(payload);
// });
api.on.editInspectorState(payload => {
if (payload.app === app && payload.inspectorId === inspectorId) {
const controller = collector.controllers.get(payload.nodeId);

if (controller) {
payload.set(controller.store, payload.path, payload.state.value);
}
}
});

// @ts-ignore
api.notifyComponentUpdate();
}
);
}

function withEventTitlePrefix(event: StoreEvent) {
if (event instanceof ActionEvent) {
return `${event.finished ? '🟧' : '🟠'} ${event.name}`;
}
if (event instanceof PatchEvent) {
return `🟢 ${event.name}`;
}
if (event instanceof SetEvent) {
return `🟡 ${event.name}`;
}
}
10 changes: 9 additions & 1 deletion src/utils/prototypeOverwrite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,15 @@ export function prototypeOverwrite(proto: object, target: object, controller: Co
Object.defineProperty(target, key, {
value(...payload) {
const ret = descriptor.value.call(this, ...payload);
controller.next(new ActionEvent(action || key, payload));
const event = new ActionEvent(action || key, payload)
controller.next(event);

if (ret instanceof Promise) {
ret.finally(() => {
controller.next(event.end());
});
}

return ret;
}
});
Expand Down

0 comments on commit c022027

Please sign in to comment.