-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
67 lines (55 loc) · 1.88 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import { App } from '@vue/devtools-api';
import { reactive } from 'vue';
import { Controller } from './src/Controller';
import { ControllerCollector } from './src/ControllerCollector';
import { CreateControllerEvent } from './src/types/CreateControllerEvent';
import { ReplaceControllerEvent } from './src/types/ReplaceControllerEvent';
import { addDevtools } from './src/utils/devtools';
import { prototypeOverwrite } from './src/utils/prototypeOverwrite';
import { valueObserver } from './src/utils/valueObserver';
export { Action } from './src/decorators/Action';
export { Patch } from './src/decorators/Patch';
export function createWidok() {
const collector = new ControllerCollector();
let initialized = false;
let appInstance: App = null;
function setupDevtools() {
if (appInstance && !initialized) {
addDevtools(appInstance, collector);
initialized = true;
}
}
function defineStore<T extends object>(StateFactory: { new (): T }, name?: string): T {
name = name || StateFactory.name;
const existingController = collector.controllers.get(name);
const proto = StateFactory.prototype;
// @ts-ignore
const isHotReplacement = (import.meta?.hot || typeof(module) !== 'undefined' && module?.hot) && existingController;
const controller = isHotReplacement
? existingController
: new Controller<T>(name);
let instance: T;
class State extends (StateFactory as any) {
constructor() {
super();
instance = reactive(this) as T;
valueObserver(instance, controller);
controller.setup(instance);
collector.next(
isHotReplacement
? new ReplaceControllerEvent(controller)
: new CreateControllerEvent(controller)
);
}
}
prototypeOverwrite(proto, State.prototype, controller);
new State();
setupDevtools();
return instance;
}
defineStore.install = (app: App) => {
appInstance = app;
setupDevtools();
}
return defineStore;
}