phecda-web 1.0.1 → 2.0.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/README.md CHANGED
@@ -3,3 +3,5 @@
3
3
  Fulfill `phecda-core` standard (`Storage/Watcher`);
4
4
 
5
5
  Work for `phecda-vue`/`phecda-react`
6
+
7
+ Using `Proxy` and `emitDecoratorMetadata`
package/dist/index.d.ts CHANGED
@@ -1,35 +1,49 @@
1
1
  import { Events, Construct } from 'phecda-core';
2
2
  export * from 'phecda-core';
3
3
 
4
- interface ActiveInstance {
5
- state: Record<string | symbol, any>;
6
- origin: WeakMap<any, any>;
7
- cache: WeakMap<any, any>;
8
- [key: string]: any;
9
- }
10
4
  interface PhecdaEmitter {
11
5
  on<N extends keyof Events>(eventName: N, cb: (args: Events[N]) => void): void;
12
6
  off<N extends keyof Events>(eventName: N, cb?: (args: Events[N]) => void): void;
13
7
  emit<N extends keyof Events>(eventName: N, param: Events[N]): void;
14
8
  }
9
+ type DeepPartial<T> = {
10
+ [K in keyof T]?: DeepPartial<T[K]>;
11
+ };
15
12
 
16
13
  declare const emitter: PhecdaEmitter;
17
14
  declare function defaultWebInject(): void;
18
15
 
19
- declare function waitUntilInit(...instances: InstanceType<Construct>[]): Promise<any[]>;
20
- declare function resetActiveInstance(instance?: ActiveInstance): void;
21
- declare function getActiveInstance(): ActiveInstance;
22
- declare function serializeState(): any;
23
- declare function isModuleLoad(model: Construct): boolean;
24
- declare function unmountModule(model: Construct | PropertyKey): Promise<void>;
16
+ declare function wait(...instances: InstanceType<Construct>[]): Promise<any[]>;
17
+ declare function bindMethod(instance: any): any;
18
+ declare class WebPhecda {
19
+ protected parseModule: <Instance = any>(instance: Instance) => Instance;
20
+ origin: Record<string, any>;
21
+ state: Record<string | symbol, any>;
22
+ modelMap: WeakMap<object, any>;
23
+ constructor(parseModule: <Instance = any>(instance: Instance) => Instance);
24
+ init<Model extends Construct>(model: Model): InstanceType<Model>;
25
+ patch<Model extends Construct>(model: Model, data: DeepPartial<InstanceType<Model>>): void;
26
+ wait(...modelOrTag: (Construct | PropertyKey)[]): Promise<any[]>;
27
+ get<Model extends Construct>(model: Model): InstanceType<Model>;
28
+ has<Model extends Construct>(model: Model): boolean;
29
+ reset<Model extends Construct>(model: Model): InstanceType<Model> | undefined;
30
+ unmount(modelOrTag: Construct | PropertyKey): Promise<void>;
31
+ unmountAll(): Promise<void[]>;
32
+ ismount(modelOrTag: Construct | PropertyKey): boolean;
33
+ serialize(): string;
34
+ load(str: string): void;
35
+ }
25
36
 
26
- declare class P {
37
+ declare class Base {
27
38
  constructor();
28
39
  get tag(): PropertyKey;
29
40
  then(cb: () => void, reject?: (e: any) => void): any;
30
41
  on<Key extends keyof Events>(type: Key, handler: (arg: Events[Key]) => void): void;
31
42
  emit<Key extends keyof Events>(type: Key, param: Events[Key]): void;
32
43
  off<Key extends keyof Events>(type: Key, handler?: (arg: Events[Key]) => void): void;
44
+ private readonly __UNMOUNT_SYMBOL__;
45
+ private onUnmount;
46
+ private _unmount;
33
47
  }
34
48
 
35
- export { ActiveInstance, P, PhecdaEmitter, defaultWebInject, emitter, getActiveInstance, isModuleLoad, resetActiveInstance, serializeState, unmountModule, waitUntilInit };
49
+ export { Base, DeepPartial, PhecdaEmitter, WebPhecda, bindMethod, defaultWebInject, emitter, wait };
package/dist/index.js CHANGED
@@ -20,6 +20,10 @@ var __copyProps = (to, from, except, desc) => {
20
20
  };
21
21
  var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
22
22
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
+ // If the importer is in node compatibility mode or this is not an ESM
24
+ // file that has been converted to a CommonJS file using a Babel-
25
+ // compatible transform (i.e. "__esModule" has not been set), then set
26
+ // "default" to the CommonJS "module.exports" for node compatibility.
23
27
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
24
28
  mod
25
29
  ));
@@ -28,15 +32,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
28
32
  // src/index.ts
29
33
  var src_exports = {};
30
34
  __export(src_exports, {
31
- P: () => P,
35
+ Base: () => Base,
36
+ WebPhecda: () => WebPhecda,
37
+ bindMethod: () => bindMethod,
32
38
  defaultWebInject: () => defaultWebInject,
33
39
  emitter: () => emitter,
34
- getActiveInstance: () => getActiveInstance,
35
- isModuleLoad: () => isModuleLoad,
36
- resetActiveInstance: () => resetActiveInstance,
37
- serializeState: () => serializeState,
38
- unmountModule: () => unmountModule,
39
- waitUntilInit: () => waitUntilInit
40
+ wait: () => wait
40
41
  });
41
42
  module.exports = __toCommonJS(src_exports);
42
43
  __reExport(src_exports, require("phecda-core"), module.exports);
@@ -46,6 +47,8 @@ var import_phecda_core = require("phecda-core");
46
47
  var import_mitt = __toESM(require("mitt"));
47
48
  var emitter = (0, import_mitt.default)();
48
49
  function defaultWebInject() {
50
+ if (typeof window === "undefined")
51
+ return;
49
52
  if (!(0, import_phecda_core.getInject)("watcher")) {
50
53
  (0, import_phecda_core.setInject)("watcher", ({ eventName, instance, key, options }) => {
51
54
  const fn = typeof instance[key] === "function" ? instance[key].bind(instance) : (v) => instance[key] = v;
@@ -87,50 +90,191 @@ __name(defaultWebInject, "defaultWebInject");
87
90
 
88
91
  // src/core.ts
89
92
  var import_phecda_core2 = require("phecda-core");
90
- function waitUntilInit(...instances) {
91
- return Promise.all(instances.map((i) => i._promise));
92
- }
93
- __name(waitUntilInit, "waitUntilInit");
94
- var activeInstance;
95
- function resetActiveInstance(instance) {
96
- activeInstance = instance || {
97
- state: {},
98
- origin: /* @__PURE__ */ new WeakMap(),
99
- cache: /* @__PURE__ */ new WeakMap()
100
- };
93
+ var import_reflect_metadata = require("reflect-metadata");
94
+
95
+ // src/utils.ts
96
+ function isObject(o) {
97
+ return Object.prototype.toString.call(o) === "[object Object]";
101
98
  }
102
- __name(resetActiveInstance, "resetActiveInstance");
103
- function getActiveInstance() {
104
- return activeInstance;
99
+ __name(isObject, "isObject");
100
+ function deepMerge(target, patchToApply) {
101
+ for (const key in patchToApply) {
102
+ if (!patchToApply.hasOwnProperty(key))
103
+ continue;
104
+ const subPatch = patchToApply[key];
105
+ const targetValue = target[key];
106
+ if (isObject(targetValue) && isObject(subPatch) && target.hasOwnProperty(key)) {
107
+ target[key] = deepMerge(targetValue, subPatch);
108
+ } else {
109
+ target[key] = subPatch;
110
+ }
111
+ }
112
+ return target;
105
113
  }
106
- __name(getActiveInstance, "getActiveInstance");
107
- function serializeState() {
108
- return JSON.parse(JSON.stringify(activeInstance.state));
114
+ __name(deepMerge, "deepMerge");
115
+
116
+ // src/core.ts
117
+ function wait(...instances) {
118
+ return Promise.all(instances.map((i) => i._promise));
109
119
  }
110
- __name(serializeState, "serializeState");
111
- function isModuleLoad(model) {
112
- const { origin, state } = getActiveInstance();
113
- const tag = (0, import_phecda_core2.getTag)(model);
114
- if (tag in state) {
115
- if (origin.get(state[tag]) !== model)
116
- throw new Error(`Synonym module: Module taged "${String(tag)}" (but not "${model.name}") has been loaded before`);
117
- return true;
118
- }
119
- return false;
120
+ __name(wait, "wait");
121
+ function getParamtypes(Model, key) {
122
+ return Reflect.getMetadata("design:paramtypes", Model, key);
120
123
  }
121
- __name(isModuleLoad, "isModuleLoad");
122
- async function unmountModule(model) {
123
- if (typeof model === "object")
124
- model = (0, import_phecda_core2.getTag)(model);
125
- const { state } = getActiveInstance();
126
- await (0, import_phecda_core2.invokeHandler)("unmount", state[model]);
127
- delete state[model];
124
+ __name(getParamtypes, "getParamtypes");
125
+ var bindCache = /* @__PURE__ */ new WeakMap();
126
+ function bindMethod(instance) {
127
+ if (!bindCache.has(instance)) {
128
+ const cache = /* @__PURE__ */ new WeakMap();
129
+ bindCache.set(instance, new Proxy(instance, {
130
+ get(target, p) {
131
+ if (typeof target[p] === "function" && !target[p].toString().startsWith("(")) {
132
+ if (!cache.has(target[p]))
133
+ cache.set(target[p], target[p].bind(target));
134
+ return cache.get(target[p]);
135
+ }
136
+ return target[p];
137
+ }
138
+ }));
139
+ }
140
+ return bindCache.get(instance);
128
141
  }
129
- __name(unmountModule, "unmountModule");
142
+ __name(bindMethod, "bindMethod");
143
+ var WebPhecda = class {
144
+ parseModule;
145
+ origin;
146
+ state;
147
+ modelMap;
148
+ constructor(parseModule) {
149
+ this.parseModule = parseModule;
150
+ this.origin = {};
151
+ this.state = {};
152
+ this.modelMap = /* @__PURE__ */ new WeakMap();
153
+ defaultWebInject();
154
+ }
155
+ // Initialize a module that has not been created yet, and return it directly if it is cached.
156
+ init(model) {
157
+ const tag = (0, import_phecda_core2.getTag)(model);
158
+ const initModel = /* @__PURE__ */ __name(() => {
159
+ const paramtypes = getParamtypes(model);
160
+ let instance2;
161
+ if (paramtypes) {
162
+ const paramtypesInstances = [];
163
+ for (const i in paramtypes)
164
+ paramtypesInstances[i] = this.init(paramtypes[i]);
165
+ instance2 = this.parseModule(new model(...paramtypesInstances));
166
+ } else {
167
+ instance2 = this.parseModule(new model());
168
+ }
169
+ if (tag in this.origin) {
170
+ Object.assign(instance2, this.origin[tag]);
171
+ delete this.origin[tag];
172
+ }
173
+ if (typeof window !== "undefined")
174
+ instance2._promise = (0, import_phecda_core2.invokeHandler)("init", instance2);
175
+ return instance2;
176
+ }, "initModel");
177
+ const { state, modelMap: map } = this;
178
+ if ((0, import_phecda_core2.get)(model.prototype, "isolate"))
179
+ return initModel();
180
+ if (tag in state) {
181
+ if (process.env.NODE_ENV === "development") {
182
+ if (map.get(state[tag]) === model)
183
+ return state[tag];
184
+ } else {
185
+ if (map.get(state[tag]) !== model)
186
+ console.warn(`Synonym model: Module taged "${String(tag)}" has been loaded before, so won't load Module "${model.name}"`);
187
+ return state[tag];
188
+ }
189
+ }
190
+ const instance = initModel();
191
+ state[tag] = instance;
192
+ map.set(instance, model);
193
+ return instance;
194
+ }
195
+ patch(model, data) {
196
+ const tag = (0, import_phecda_core2.getTag)(model);
197
+ const { state } = this;
198
+ deepMerge(state[tag], data);
199
+ }
200
+ wait(...modelOrTag) {
201
+ const { state } = this;
202
+ return Promise.all(modelOrTag.map((i) => {
203
+ if (typeof i === "function")
204
+ i = (0, import_phecda_core2.getTag)(i);
205
+ return state[i]._promise;
206
+ }));
207
+ }
208
+ get(model) {
209
+ const { state } = this;
210
+ return state[(0, import_phecda_core2.getTag)(model)];
211
+ }
212
+ has(model) {
213
+ const { state } = this;
214
+ return (0, import_phecda_core2.getTag)(model) in state;
215
+ }
216
+ reset(model) {
217
+ const { state } = this;
218
+ const tag = (0, import_phecda_core2.getTag)(model);
219
+ if (!(tag in state))
220
+ return this.init(model);
221
+ const instance = this.init(model);
222
+ const newInstance = new model();
223
+ Object.assign(instance, newInstance);
224
+ for (const key in instance) {
225
+ if (!(key in newInstance))
226
+ delete instance[key];
227
+ }
228
+ }
229
+ async unmount(modelOrTag) {
230
+ const tag = typeof modelOrTag === "function" ? (0, import_phecda_core2.getTag)(modelOrTag) : modelOrTag;
231
+ const { state } = this;
232
+ await (0, import_phecda_core2.invokeHandler)("unmount", state[tag]);
233
+ delete state[tag];
234
+ }
235
+ async unmountAll() {
236
+ const { state } = this;
237
+ return Promise.all(Object.keys(state).map((tag) => this.unmount(tag)));
238
+ }
239
+ ismount(modelOrTag) {
240
+ const { state } = this;
241
+ const tag = typeof modelOrTag === "function" ? (0, import_phecda_core2.getTag)(modelOrTag) : modelOrTag;
242
+ if (tag in state)
243
+ return true;
244
+ return false;
245
+ }
246
+ serialize() {
247
+ const { state } = this;
248
+ return JSON.stringify(state, (_key, value) => {
249
+ if (this.modelMap.has(value))
250
+ return null;
251
+ });
252
+ }
253
+ load(str) {
254
+ this.origin = JSON.parse(str);
255
+ }
256
+ };
257
+ __name(WebPhecda, "WebPhecda");
130
258
 
131
259
  // src/base.ts
132
260
  var import_phecda_core3 = require("phecda-core");
133
- var P = class {
261
+ function _ts_decorate(decorators, target, key, desc) {
262
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
263
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
264
+ r = Reflect.decorate(decorators, target, key, desc);
265
+ else
266
+ for (var i = decorators.length - 1; i >= 0; i--)
267
+ if (d = decorators[i])
268
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
269
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
270
+ }
271
+ __name(_ts_decorate, "_ts_decorate");
272
+ function _ts_metadata(k, v) {
273
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
274
+ return Reflect.metadata(k, v);
275
+ }
276
+ __name(_ts_metadata, "_ts_metadata");
277
+ var Base = class {
134
278
  constructor() {
135
279
  }
136
280
  get tag() {
@@ -141,6 +285,7 @@ var P = class {
141
285
  }
142
286
  on(type, handler) {
143
287
  emitter.on(type, handler);
288
+ this.onUnmount(() => emitter.off(type, handler));
144
289
  }
145
290
  emit(type, param) {
146
291
  emitter.emit(type, param);
@@ -148,17 +293,28 @@ var P = class {
148
293
  off(type, handler) {
149
294
  emitter.off(type, handler);
150
295
  }
296
+ __UNMOUNT_SYMBOL__ = [];
297
+ onUnmount(cb) {
298
+ this.__UNMOUNT_SYMBOL__.push(cb);
299
+ }
300
+ _unmount() {
301
+ return Promise.all(this.__UNMOUNT_SYMBOL__.map((fn) => fn()));
302
+ }
151
303
  };
152
- __name(P, "P");
304
+ __name(Base, "Base");
305
+ _ts_decorate([
306
+ import_phecda_core3.Unmount,
307
+ _ts_metadata("design:type", Function),
308
+ _ts_metadata("design:paramtypes", []),
309
+ _ts_metadata("design:returntype", void 0)
310
+ ], Base.prototype, "_unmount", null);
153
311
  // Annotate the CommonJS export names for ESM import in node:
154
312
  0 && (module.exports = {
155
- P,
313
+ Base,
314
+ WebPhecda,
315
+ bindMethod,
156
316
  defaultWebInject,
157
317
  emitter,
158
- getActiveInstance,
159
- isModuleLoad,
160
- resetActiveInstance,
161
- serializeState,
162
- unmountModule,
163
- waitUntilInit
318
+ wait,
319
+ ...require("phecda-core")
164
320
  });
package/dist/index.mjs CHANGED
@@ -9,6 +9,8 @@ import { getInject, setInject } from "phecda-core";
9
9
  import mitt from "mitt";
10
10
  var emitter = mitt();
11
11
  function defaultWebInject() {
12
+ if (typeof window === "undefined")
13
+ return;
12
14
  if (!getInject("watcher")) {
13
15
  setInject("watcher", ({ eventName, instance, key, options }) => {
14
16
  const fn = typeof instance[key] === "function" ? instance[key].bind(instance) : (v) => instance[key] = v;
@@ -49,51 +51,192 @@ function defaultWebInject() {
49
51
  __name(defaultWebInject, "defaultWebInject");
50
52
 
51
53
  // src/core.ts
52
- import { getTag, invokeHandler } from "phecda-core";
53
- function waitUntilInit(...instances) {
54
- return Promise.all(instances.map((i) => i._promise));
55
- }
56
- __name(waitUntilInit, "waitUntilInit");
57
- var activeInstance;
58
- function resetActiveInstance(instance) {
59
- activeInstance = instance || {
60
- state: {},
61
- origin: /* @__PURE__ */ new WeakMap(),
62
- cache: /* @__PURE__ */ new WeakMap()
63
- };
54
+ import { get, getTag, invokeHandler } from "phecda-core";
55
+ import "reflect-metadata";
56
+
57
+ // src/utils.ts
58
+ function isObject(o) {
59
+ return Object.prototype.toString.call(o) === "[object Object]";
64
60
  }
65
- __name(resetActiveInstance, "resetActiveInstance");
66
- function getActiveInstance() {
67
- return activeInstance;
61
+ __name(isObject, "isObject");
62
+ function deepMerge(target, patchToApply) {
63
+ for (const key in patchToApply) {
64
+ if (!patchToApply.hasOwnProperty(key))
65
+ continue;
66
+ const subPatch = patchToApply[key];
67
+ const targetValue = target[key];
68
+ if (isObject(targetValue) && isObject(subPatch) && target.hasOwnProperty(key)) {
69
+ target[key] = deepMerge(targetValue, subPatch);
70
+ } else {
71
+ target[key] = subPatch;
72
+ }
73
+ }
74
+ return target;
68
75
  }
69
- __name(getActiveInstance, "getActiveInstance");
70
- function serializeState() {
71
- return JSON.parse(JSON.stringify(activeInstance.state));
76
+ __name(deepMerge, "deepMerge");
77
+
78
+ // src/core.ts
79
+ function wait(...instances) {
80
+ return Promise.all(instances.map((i) => i._promise));
72
81
  }
73
- __name(serializeState, "serializeState");
74
- function isModuleLoad(model) {
75
- const { origin, state } = getActiveInstance();
76
- const tag = getTag(model);
77
- if (tag in state) {
78
- if (origin.get(state[tag]) !== model)
79
- throw new Error(`Synonym module: Module taged "${String(tag)}" (but not "${model.name}") has been loaded before`);
80
- return true;
81
- }
82
- return false;
82
+ __name(wait, "wait");
83
+ function getParamtypes(Model, key) {
84
+ return Reflect.getMetadata("design:paramtypes", Model, key);
83
85
  }
84
- __name(isModuleLoad, "isModuleLoad");
85
- async function unmountModule(model) {
86
- if (typeof model === "object")
87
- model = getTag(model);
88
- const { state } = getActiveInstance();
89
- await invokeHandler("unmount", state[model]);
90
- delete state[model];
86
+ __name(getParamtypes, "getParamtypes");
87
+ var bindCache = /* @__PURE__ */ new WeakMap();
88
+ function bindMethod(instance) {
89
+ if (!bindCache.has(instance)) {
90
+ const cache = /* @__PURE__ */ new WeakMap();
91
+ bindCache.set(instance, new Proxy(instance, {
92
+ get(target, p) {
93
+ if (typeof target[p] === "function" && !target[p].toString().startsWith("(")) {
94
+ if (!cache.has(target[p]))
95
+ cache.set(target[p], target[p].bind(target));
96
+ return cache.get(target[p]);
97
+ }
98
+ return target[p];
99
+ }
100
+ }));
101
+ }
102
+ return bindCache.get(instance);
91
103
  }
92
- __name(unmountModule, "unmountModule");
104
+ __name(bindMethod, "bindMethod");
105
+ var WebPhecda = class {
106
+ parseModule;
107
+ origin;
108
+ state;
109
+ modelMap;
110
+ constructor(parseModule) {
111
+ this.parseModule = parseModule;
112
+ this.origin = {};
113
+ this.state = {};
114
+ this.modelMap = /* @__PURE__ */ new WeakMap();
115
+ defaultWebInject();
116
+ }
117
+ // Initialize a module that has not been created yet, and return it directly if it is cached.
118
+ init(model) {
119
+ const tag = getTag(model);
120
+ const initModel = /* @__PURE__ */ __name(() => {
121
+ const paramtypes = getParamtypes(model);
122
+ let instance2;
123
+ if (paramtypes) {
124
+ const paramtypesInstances = [];
125
+ for (const i in paramtypes)
126
+ paramtypesInstances[i] = this.init(paramtypes[i]);
127
+ instance2 = this.parseModule(new model(...paramtypesInstances));
128
+ } else {
129
+ instance2 = this.parseModule(new model());
130
+ }
131
+ if (tag in this.origin) {
132
+ Object.assign(instance2, this.origin[tag]);
133
+ delete this.origin[tag];
134
+ }
135
+ if (typeof window !== "undefined")
136
+ instance2._promise = invokeHandler("init", instance2);
137
+ return instance2;
138
+ }, "initModel");
139
+ const { state, modelMap: map } = this;
140
+ if (get(model.prototype, "isolate"))
141
+ return initModel();
142
+ if (tag in state) {
143
+ if (process.env.NODE_ENV === "development") {
144
+ if (map.get(state[tag]) === model)
145
+ return state[tag];
146
+ } else {
147
+ if (map.get(state[tag]) !== model)
148
+ console.warn(`Synonym model: Module taged "${String(tag)}" has been loaded before, so won't load Module "${model.name}"`);
149
+ return state[tag];
150
+ }
151
+ }
152
+ const instance = initModel();
153
+ state[tag] = instance;
154
+ map.set(instance, model);
155
+ return instance;
156
+ }
157
+ patch(model, data) {
158
+ const tag = getTag(model);
159
+ const { state } = this;
160
+ deepMerge(state[tag], data);
161
+ }
162
+ wait(...modelOrTag) {
163
+ const { state } = this;
164
+ return Promise.all(modelOrTag.map((i) => {
165
+ if (typeof i === "function")
166
+ i = getTag(i);
167
+ return state[i]._promise;
168
+ }));
169
+ }
170
+ get(model) {
171
+ const { state } = this;
172
+ return state[getTag(model)];
173
+ }
174
+ has(model) {
175
+ const { state } = this;
176
+ return getTag(model) in state;
177
+ }
178
+ reset(model) {
179
+ const { state } = this;
180
+ const tag = getTag(model);
181
+ if (!(tag in state))
182
+ return this.init(model);
183
+ const instance = this.init(model);
184
+ const newInstance = new model();
185
+ Object.assign(instance, newInstance);
186
+ for (const key in instance) {
187
+ if (!(key in newInstance))
188
+ delete instance[key];
189
+ }
190
+ }
191
+ async unmount(modelOrTag) {
192
+ const tag = typeof modelOrTag === "function" ? getTag(modelOrTag) : modelOrTag;
193
+ const { state } = this;
194
+ await invokeHandler("unmount", state[tag]);
195
+ delete state[tag];
196
+ }
197
+ async unmountAll() {
198
+ const { state } = this;
199
+ return Promise.all(Object.keys(state).map((tag) => this.unmount(tag)));
200
+ }
201
+ ismount(modelOrTag) {
202
+ const { state } = this;
203
+ const tag = typeof modelOrTag === "function" ? getTag(modelOrTag) : modelOrTag;
204
+ if (tag in state)
205
+ return true;
206
+ return false;
207
+ }
208
+ serialize() {
209
+ const { state } = this;
210
+ return JSON.stringify(state, (_key, value) => {
211
+ if (this.modelMap.has(value))
212
+ return null;
213
+ });
214
+ }
215
+ load(str) {
216
+ this.origin = JSON.parse(str);
217
+ }
218
+ };
219
+ __name(WebPhecda, "WebPhecda");
93
220
 
94
221
  // src/base.ts
95
- import { getTag as getTag2 } from "phecda-core";
96
- var P = class {
222
+ import { Unmount, getTag as getTag2 } from "phecda-core";
223
+ function _ts_decorate(decorators, target, key, desc) {
224
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
225
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
226
+ r = Reflect.decorate(decorators, target, key, desc);
227
+ else
228
+ for (var i = decorators.length - 1; i >= 0; i--)
229
+ if (d = decorators[i])
230
+ r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
231
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
232
+ }
233
+ __name(_ts_decorate, "_ts_decorate");
234
+ function _ts_metadata(k, v) {
235
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
236
+ return Reflect.metadata(k, v);
237
+ }
238
+ __name(_ts_metadata, "_ts_metadata");
239
+ var Base = class {
97
240
  constructor() {
98
241
  }
99
242
  get tag() {
@@ -104,6 +247,7 @@ var P = class {
104
247
  }
105
248
  on(type, handler) {
106
249
  emitter.on(type, handler);
250
+ this.onUnmount(() => emitter.off(type, handler));
107
251
  }
108
252
  emit(type, param) {
109
253
  emitter.emit(type, param);
@@ -111,16 +255,26 @@ var P = class {
111
255
  off(type, handler) {
112
256
  emitter.off(type, handler);
113
257
  }
258
+ __UNMOUNT_SYMBOL__ = [];
259
+ onUnmount(cb) {
260
+ this.__UNMOUNT_SYMBOL__.push(cb);
261
+ }
262
+ _unmount() {
263
+ return Promise.all(this.__UNMOUNT_SYMBOL__.map((fn) => fn()));
264
+ }
114
265
  };
115
- __name(P, "P");
266
+ __name(Base, "Base");
267
+ _ts_decorate([
268
+ Unmount,
269
+ _ts_metadata("design:type", Function),
270
+ _ts_metadata("design:paramtypes", []),
271
+ _ts_metadata("design:returntype", void 0)
272
+ ], Base.prototype, "_unmount", null);
116
273
  export {
117
- P,
274
+ Base,
275
+ WebPhecda,
276
+ bindMethod,
118
277
  defaultWebInject,
119
278
  emitter,
120
- getActiveInstance,
121
- isModuleLoad,
122
- resetActiveInstance,
123
- serializeState,
124
- unmountModule,
125
- waitUntilInit
279
+ wait
126
280
  };
package/package.json CHANGED
@@ -1,18 +1,23 @@
1
1
  {
2
2
  "name": "phecda-web",
3
- "version": "1.0.1",
4
- "description": "provide web function for phecda",
3
+ "version": "2.0.1",
4
+ "description": "using proxy, provide phecda function to web app",
5
+ "author": "fgsreally",
6
+ "license": "MIT",
7
+ "repository": "https://github.com/fgsreally/phecda/tree/main/packages/web",
8
+ "keywords": [
9
+ "phecda",
10
+ "web"
11
+ ],
5
12
  "main": "dist/index.js",
6
13
  "module": "dist/index.mjs",
7
14
  "types": "dist/index.d.ts",
8
- "keywords": [],
9
- "author": "",
10
15
  "files": [
11
16
  "dist"
12
17
  ],
13
- "license": "MIT",
14
18
  "dependencies": {
15
19
  "mitt": "^3.0.0",
20
+ "reflect-metadata": "^0.1.13",
16
21
  "phecda-core": "3.0.0"
17
22
  },
18
23
  "devDependencies": {