phecda-web 2.0.1 → 2.0.3

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.
@@ -0,0 +1,98 @@
1
+ import { Events, Construct } from 'phecda-core';
2
+ export * from 'phecda-core';
3
+ import * as mitt from 'mitt';
4
+ import { Handler, WildcardHandler } from 'mitt';
5
+
6
+ interface PhecdaEmitter {
7
+ on<N extends keyof Events>(eventName: N, cb: (args: Events[N]) => void): void;
8
+ off<N extends keyof Events>(eventName: N, cb?: (args: Events[N]) => void): void;
9
+ emit<N extends keyof Events>(eventName: N, param: Events[N]): void;
10
+ }
11
+ type DeepPartial<T> = {
12
+ [K in keyof T]?: DeepPartial<T[K]>;
13
+ };
14
+
15
+ declare const emitter: PhecdaEmitter;
16
+ declare function defaultWebInject(): void;
17
+
18
+ declare function wait(...instances: InstanceType<Construct>[]): Promise<any[]>;
19
+ declare const phecdaNamespace: Map<string, WebPhecda>;
20
+ declare function setDefaultPhecda(namespace: string, phecda: WebPhecda): void;
21
+ /**
22
+ * for cases that not in ssr
23
+ */
24
+ declare function getDefaultPhecda(namespace: string): WebPhecda | undefined;
25
+ declare function delDefaultPhecda(namespace: string): boolean;
26
+ declare function bindMethod(instance: any, wrapper?: (instance: any, key: PropertyKey) => Function): any;
27
+ interface InternalEvents {
28
+ Instantiate: {
29
+ tag: PropertyKey;
30
+ };
31
+ Reset: {
32
+ tag: PropertyKey;
33
+ };
34
+ Initialize: {
35
+ tag: PropertyKey;
36
+ };
37
+ Patch: {
38
+ tag: PropertyKey;
39
+ data: any;
40
+ };
41
+ Synonym: {
42
+ tag: PropertyKey;
43
+ };
44
+ Hmr: {
45
+ tag: PropertyKey;
46
+ };
47
+ Unmount: {
48
+ tag: PropertyKey;
49
+ };
50
+ Load: {
51
+ data: any;
52
+ };
53
+ [key: string | symbol]: any;
54
+ }
55
+ declare class WebPhecda {
56
+ protected namespace: string;
57
+ protected parseModule: <Instance = any>(instance: Instance) => Instance;
58
+ /**
59
+ * for ssr or manual inject
60
+ */
61
+ memory: Record<string, any>;
62
+ state: Record<string | symbol, any>;
63
+ modelMap: WeakMap<object, any>;
64
+ emitter: mitt.Emitter<InternalEvents>;
65
+ constructor(namespace: string, parseModule: <Instance = any>(instance: Instance) => Instance);
66
+ /**
67
+ * Initialize a module that has not been created yet, and return it directly if it is cached.
68
+ */
69
+ init<Model extends Construct>(model: Model): InstanceType<Model>;
70
+ patch<Model extends Construct>(model: Model, data: DeepPartial<InstanceType<Model>>): void;
71
+ wait(...modelOrTag: (Construct | PropertyKey)[]): Promise<any[]>;
72
+ get<Model extends Construct>(modelOrTag: Model | PropertyKey): InstanceType<Model>;
73
+ getModel(tag: PropertyKey): Construct;
74
+ reset<Model extends Construct>(model: Model): InstanceType<Model> | undefined;
75
+ unmount(modelOrTag: Construct | PropertyKey): Promise<void>;
76
+ unmountAll(): Promise<void[]>;
77
+ has(modelOrTag: Construct | PropertyKey): boolean;
78
+ serialize(): string;
79
+ load(str: string): void;
80
+ emit<Key extends keyof InternalEvents>(type: Key, event?: InternalEvents[Key]): void;
81
+ on<Key extends keyof InternalEvents>(type: Key, handler: Handler<InternalEvents[Key]>): void;
82
+ on(type: '*', handler: WildcardHandler<InternalEvents>): void;
83
+ }
84
+
85
+ declare class Base {
86
+ private readonly __UNMOUNT_SYMBOL__;
87
+ private readonly __PROMISE_SYMBOL__;
88
+ constructor();
89
+ get tag(): PropertyKey;
90
+ then(cb: () => void, reject?: (e: any) => void): Promise<void>;
91
+ on<Key extends keyof Events>(type: Key, handler: (arg: Events[Key]) => void): void;
92
+ emit<Key extends keyof Events>(type: Key, param: Events[Key]): void;
93
+ off<Key extends keyof Events>(type: Key, handler?: (arg: Events[Key]) => void): void;
94
+ private onUnmount;
95
+ private _unmount;
96
+ }
97
+
98
+ export { Base, type DeepPartial, type PhecdaEmitter, WebPhecda, bindMethod, defaultWebInject, delDefaultPhecda, emitter, getDefaultPhecda, phecdaNamespace, setDefaultPhecda, wait };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { Events, Construct } from 'phecda-core';
2
2
  export * from 'phecda-core';
3
+ import * as mitt from 'mitt';
4
+ import { Handler, WildcardHandler } from 'mitt';
3
5
 
4
6
  interface PhecdaEmitter {
5
7
  on<N extends keyof Events>(eventName: N, cb: (args: Events[N]) => void): void;
@@ -14,36 +16,83 @@ declare const emitter: PhecdaEmitter;
14
16
  declare function defaultWebInject(): void;
15
17
 
16
18
  declare function wait(...instances: InstanceType<Construct>[]): Promise<any[]>;
17
- declare function bindMethod(instance: any): any;
19
+ declare const phecdaNamespace: Map<string, WebPhecda>;
20
+ declare function setDefaultPhecda(namespace: string, phecda: WebPhecda): void;
21
+ /**
22
+ * for cases that not in ssr
23
+ */
24
+ declare function getDefaultPhecda(namespace: string): WebPhecda | undefined;
25
+ declare function delDefaultPhecda(namespace: string): boolean;
26
+ declare function bindMethod(instance: any, wrapper?: (instance: any, key: PropertyKey) => Function): any;
27
+ interface InternalEvents {
28
+ Instantiate: {
29
+ tag: PropertyKey;
30
+ };
31
+ Reset: {
32
+ tag: PropertyKey;
33
+ };
34
+ Initialize: {
35
+ tag: PropertyKey;
36
+ };
37
+ Patch: {
38
+ tag: PropertyKey;
39
+ data: any;
40
+ };
41
+ Synonym: {
42
+ tag: PropertyKey;
43
+ };
44
+ Hmr: {
45
+ tag: PropertyKey;
46
+ };
47
+ Unmount: {
48
+ tag: PropertyKey;
49
+ };
50
+ Load: {
51
+ data: any;
52
+ };
53
+ [key: string | symbol]: any;
54
+ }
18
55
  declare class WebPhecda {
56
+ protected namespace: string;
19
57
  protected parseModule: <Instance = any>(instance: Instance) => Instance;
20
- origin: Record<string, any>;
58
+ /**
59
+ * for ssr or manual inject
60
+ */
61
+ memory: Record<string, any>;
21
62
  state: Record<string | symbol, any>;
22
63
  modelMap: WeakMap<object, any>;
23
- constructor(parseModule: <Instance = any>(instance: Instance) => Instance);
64
+ emitter: mitt.Emitter<InternalEvents>;
65
+ constructor(namespace: string, parseModule: <Instance = any>(instance: Instance) => Instance);
66
+ /**
67
+ * Initialize a module that has not been created yet, and return it directly if it is cached.
68
+ */
24
69
  init<Model extends Construct>(model: Model): InstanceType<Model>;
25
70
  patch<Model extends Construct>(model: Model, data: DeepPartial<InstanceType<Model>>): void;
26
71
  wait(...modelOrTag: (Construct | PropertyKey)[]): Promise<any[]>;
27
- get<Model extends Construct>(model: Model): InstanceType<Model>;
28
- has<Model extends Construct>(model: Model): boolean;
72
+ get<Model extends Construct>(modelOrTag: Model | PropertyKey): InstanceType<Model>;
73
+ getModel(tag: PropertyKey): Construct;
29
74
  reset<Model extends Construct>(model: Model): InstanceType<Model> | undefined;
30
75
  unmount(modelOrTag: Construct | PropertyKey): Promise<void>;
31
76
  unmountAll(): Promise<void[]>;
32
- ismount(modelOrTag: Construct | PropertyKey): boolean;
77
+ has(modelOrTag: Construct | PropertyKey): boolean;
33
78
  serialize(): string;
34
79
  load(str: string): void;
80
+ emit<Key extends keyof InternalEvents>(type: Key, event?: InternalEvents[Key]): void;
81
+ on<Key extends keyof InternalEvents>(type: Key, handler: Handler<InternalEvents[Key]>): void;
82
+ on(type: '*', handler: WildcardHandler<InternalEvents>): void;
35
83
  }
36
84
 
37
85
  declare class Base {
86
+ private readonly __UNMOUNT_SYMBOL__;
87
+ private readonly __PROMISE_SYMBOL__;
38
88
  constructor();
39
89
  get tag(): PropertyKey;
40
- then(cb: () => void, reject?: (e: any) => void): any;
90
+ then(cb: () => void, reject?: (e: any) => void): Promise<void>;
41
91
  on<Key extends keyof Events>(type: Key, handler: (arg: Events[Key]) => void): void;
42
92
  emit<Key extends keyof Events>(type: Key, param: Events[Key]): void;
43
93
  off<Key extends keyof Events>(type: Key, handler?: (arg: Events[Key]) => void): void;
44
- private readonly __UNMOUNT_SYMBOL__;
45
94
  private onUnmount;
46
95
  private _unmount;
47
96
  }
48
97
 
49
- export { Base, DeepPartial, PhecdaEmitter, WebPhecda, bindMethod, defaultWebInject, emitter, wait };
98
+ export { Base, type DeepPartial, type PhecdaEmitter, WebPhecda, bindMethod, defaultWebInject, delDefaultPhecda, emitter, getDefaultPhecda, phecdaNamespace, setDefaultPhecda, wait };
package/dist/index.js CHANGED
@@ -36,19 +36,21 @@ __export(src_exports, {
36
36
  WebPhecda: () => WebPhecda,
37
37
  bindMethod: () => bindMethod,
38
38
  defaultWebInject: () => defaultWebInject,
39
+ delDefaultPhecda: () => delDefaultPhecda,
39
40
  emitter: () => emitter,
41
+ getDefaultPhecda: () => getDefaultPhecda,
42
+ phecdaNamespace: () => phecdaNamespace,
43
+ setDefaultPhecda: () => setDefaultPhecda,
40
44
  wait: () => wait
41
45
  });
42
46
  module.exports = __toCommonJS(src_exports);
43
47
  __reExport(src_exports, require("phecda-core"), module.exports);
44
48
 
45
- // src/plugin.ts
49
+ // src/inject.ts
46
50
  var import_phecda_core = require("phecda-core");
47
51
  var import_mitt = __toESM(require("mitt"));
48
52
  var emitter = (0, import_mitt.default)();
49
53
  function defaultWebInject() {
50
- if (typeof window === "undefined")
51
- return;
52
54
  if (!(0, import_phecda_core.getInject)("watcher")) {
53
55
  (0, import_phecda_core.setInject)("watcher", ({ eventName, instance, key, options }) => {
54
56
  const fn = typeof instance[key] === "function" ? instance[key].bind(instance) : (v) => instance[key] = v;
@@ -74,8 +76,7 @@ function defaultWebInject() {
74
76
  instance[key] = data;
75
77
  } else {
76
78
  for (const i in data) {
77
- if (i)
78
- instance[i] = data[i];
79
+ if (i) instance[i] = data[i];
79
80
  }
80
81
  }
81
82
  }
@@ -91,6 +92,7 @@ __name(defaultWebInject, "defaultWebInject");
91
92
  // src/core.ts
92
93
  var import_phecda_core2 = require("phecda-core");
93
94
  var import_reflect_metadata = require("reflect-metadata");
95
+ var import_mitt2 = __toESM(require("mitt"));
94
96
 
95
97
  // src/utils.ts
96
98
  function isObject(o) {
@@ -99,8 +101,7 @@ function isObject(o) {
99
101
  __name(isObject, "isObject");
100
102
  function deepMerge(target, patchToApply) {
101
103
  for (const key in patchToApply) {
102
- if (!patchToApply.hasOwnProperty(key))
103
- continue;
104
+ if (!patchToApply.hasOwnProperty(key)) continue;
104
105
  const subPatch = patchToApply[key];
105
106
  const targetValue = target[key];
106
107
  if (isObject(targetValue) && isObject(subPatch) && target.hasOwnProperty(key)) {
@@ -115,22 +116,34 @@ __name(deepMerge, "deepMerge");
115
116
 
116
117
  // src/core.ts
117
118
  function wait(...instances) {
118
- return Promise.all(instances.map((i) => i._promise));
119
+ return Promise.all(instances.map((i) => i.__PROMISE_SYMBOL__));
119
120
  }
120
121
  __name(wait, "wait");
121
122
  function getParamtypes(Model, key) {
122
123
  return Reflect.getMetadata("design:paramtypes", Model, key);
123
124
  }
124
125
  __name(getParamtypes, "getParamtypes");
126
+ var phecdaNamespace = /* @__PURE__ */ new Map();
127
+ function setDefaultPhecda(namespace, phecda) {
128
+ phecdaNamespace.set(namespace, phecda);
129
+ }
130
+ __name(setDefaultPhecda, "setDefaultPhecda");
131
+ function getDefaultPhecda(namespace) {
132
+ return phecdaNamespace.get(namespace);
133
+ }
134
+ __name(getDefaultPhecda, "getDefaultPhecda");
135
+ function delDefaultPhecda(namespace) {
136
+ return phecdaNamespace.delete(namespace);
137
+ }
138
+ __name(delDefaultPhecda, "delDefaultPhecda");
125
139
  var bindCache = /* @__PURE__ */ new WeakMap();
126
- function bindMethod(instance) {
140
+ function bindMethod(instance, wrapper) {
127
141
  if (!bindCache.has(instance)) {
128
142
  const cache = /* @__PURE__ */ new WeakMap();
129
143
  bindCache.set(instance, new Proxy(instance, {
130
144
  get(target, p) {
131
145
  if (typeof target[p] === "function" && !target[p].toString().startsWith("(")) {
132
- if (!cache.has(target[p]))
133
- cache.set(target[p], target[p].bind(target));
146
+ if (!cache.has(target[p])) cache.set(target[p], wrapper ? wrapper(target, p) : target[p].bind(target));
134
147
  return cache.get(target[p]);
135
148
  }
136
149
  return target[p];
@@ -141,49 +154,72 @@ function bindMethod(instance) {
141
154
  }
142
155
  __name(bindMethod, "bindMethod");
143
156
  var WebPhecda = class {
157
+ static {
158
+ __name(this, "WebPhecda");
159
+ }
160
+ namespace;
144
161
  parseModule;
145
- origin;
162
+ /**
163
+ * for ssr or manual inject
164
+ */
165
+ memory;
146
166
  state;
147
167
  modelMap;
148
- constructor(parseModule) {
168
+ emitter;
169
+ constructor(namespace, parseModule) {
170
+ this.namespace = namespace;
149
171
  this.parseModule = parseModule;
150
- this.origin = {};
172
+ this.memory = {};
151
173
  this.state = {};
152
174
  this.modelMap = /* @__PURE__ */ new WeakMap();
153
- defaultWebInject();
175
+ this.emitter = (0, import_mitt2.default)();
176
+ if (typeof window !== "undefined") {
177
+ defaultWebInject();
178
+ setDefaultPhecda(namespace, this);
179
+ }
154
180
  }
155
- // Initialize a module that has not been created yet, and return it directly if it is cached.
181
+ /**
182
+ * Initialize a module that has not been created yet, and return it directly if it is cached.
183
+ */
156
184
  init(model) {
157
185
  const tag = (0, import_phecda_core2.getTag)(model);
158
186
  const initModel = /* @__PURE__ */ __name(() => {
159
187
  const paramtypes = getParamtypes(model);
160
188
  let instance2;
189
+ this.emit("Instantiate", {
190
+ tag
191
+ });
161
192
  if (paramtypes) {
162
193
  const paramtypesInstances = [];
163
- for (const i in paramtypes)
164
- paramtypesInstances[i] = this.init(paramtypes[i]);
194
+ for (const i in paramtypes) paramtypesInstances[i] = this.init(paramtypes[i]);
165
195
  instance2 = this.parseModule(new model(...paramtypesInstances));
166
196
  } else {
167
197
  instance2 = this.parseModule(new model());
168
198
  }
169
- if (tag in this.origin) {
170
- Object.assign(instance2, this.origin[tag]);
171
- delete this.origin[tag];
199
+ if (tag in this.memory) Object.assign(instance2, this.memory[tag]);
200
+ if (typeof window !== "undefined") {
201
+ this.emit("Initialize", {
202
+ tag
203
+ });
204
+ instance2.__PROMISE_SYMBOL__ = (0, import_phecda_core2.invokeHandler)("init", instance2);
172
205
  }
173
- if (typeof window !== "undefined")
174
- instance2._promise = (0, import_phecda_core2.invokeHandler)("init", instance2);
175
206
  return instance2;
176
207
  }, "initModel");
177
208
  const { state, modelMap: map } = this;
178
- if ((0, import_phecda_core2.get)(model.prototype, "isolate"))
179
- return initModel();
209
+ if ((0, import_phecda_core2.get)(model.prototype, "isolate")) return initModel();
180
210
  if (tag in state) {
181
211
  if (process.env.NODE_ENV === "development") {
182
- if (map.get(state[tag]) === model)
183
- return state[tag];
212
+ if (map.get(state[tag]) === model) return state[tag];
213
+ else this.emit("Hmr", {
214
+ tag
215
+ });
184
216
  } else {
185
- if (map.get(state[tag]) !== model)
217
+ if (map.get(state[tag]) !== model) {
218
+ this.emit("Synonym", {
219
+ tag
220
+ });
186
221
  console.warn(`Synonym model: Module taged "${String(tag)}" has been loaded before, so won't load Module "${model.name}"`);
222
+ }
187
223
  return state[tag];
188
224
  }
189
225
  }
@@ -195,93 +231,111 @@ var WebPhecda = class {
195
231
  patch(model, data) {
196
232
  const tag = (0, import_phecda_core2.getTag)(model);
197
233
  const { state } = this;
234
+ this.emit("Patch", {
235
+ tag,
236
+ data
237
+ });
198
238
  deepMerge(state[tag], data);
199
239
  }
200
240
  wait(...modelOrTag) {
201
- const { state } = this;
202
241
  return Promise.all(modelOrTag.map((i) => {
203
- if (typeof i === "function")
204
- i = (0, import_phecda_core2.getTag)(i);
205
- return state[i]._promise;
242
+ if (typeof i === "function") i = (0, import_phecda_core2.getTag)(i);
243
+ return this.get(i).__PROMISE_SYMBOL__;
206
244
  }));
207
245
  }
208
- get(model) {
246
+ get(modelOrTag) {
209
247
  const { state } = this;
210
- return state[(0, import_phecda_core2.getTag)(model)];
248
+ const tag = typeof modelOrTag === "function" ? (0, import_phecda_core2.getTag)(modelOrTag) : modelOrTag;
249
+ return state[tag];
211
250
  }
212
- has(model) {
251
+ getModel(tag) {
213
252
  const { state } = this;
214
- return (0, import_phecda_core2.getTag)(model) in state;
253
+ return this.modelMap.get(state[tag]);
215
254
  }
216
255
  reset(model) {
217
256
  const { state } = this;
218
257
  const tag = (0, import_phecda_core2.getTag)(model);
219
- if (!(tag in state))
220
- return this.init(model);
258
+ if (!(tag in state)) return this.init(model);
259
+ this.emit("Reset", {
260
+ tag
261
+ });
221
262
  const instance = this.init(model);
222
263
  const newInstance = new model();
223
264
  Object.assign(instance, newInstance);
224
265
  for (const key in instance) {
225
- if (!(key in newInstance))
226
- delete instance[key];
266
+ if (!(key in newInstance)) delete instance[key];
227
267
  }
228
268
  }
229
269
  async unmount(modelOrTag) {
230
270
  const tag = typeof modelOrTag === "function" ? (0, import_phecda_core2.getTag)(modelOrTag) : modelOrTag;
271
+ if (!this.has(tag)) return;
272
+ this.emit("Unmount", {
273
+ tag
274
+ });
231
275
  const { state } = this;
232
- await (0, import_phecda_core2.invokeHandler)("unmount", state[tag]);
276
+ await (0, import_phecda_core2.invokeHandler)("unmount", this.get(tag));
233
277
  delete state[tag];
234
278
  }
235
279
  async unmountAll() {
236
280
  const { state } = this;
237
281
  return Promise.all(Object.keys(state).map((tag) => this.unmount(tag)));
238
282
  }
239
- ismount(modelOrTag) {
283
+ has(modelOrTag) {
240
284
  const { state } = this;
241
285
  const tag = typeof modelOrTag === "function" ? (0, import_phecda_core2.getTag)(modelOrTag) : modelOrTag;
242
- if (tag in state)
243
- return true;
286
+ if (tag in state) return true;
244
287
  return false;
245
288
  }
246
289
  serialize() {
247
290
  const { state } = this;
248
291
  return JSON.stringify(state, (_key, value) => {
249
- if (this.modelMap.has(value))
250
- return null;
292
+ if (this.modelMap.has(value)) return null;
251
293
  });
252
294
  }
253
295
  load(str) {
254
- this.origin = JSON.parse(str);
296
+ const state = JSON.parse(str);
297
+ this.emit("Load", {
298
+ data: state
299
+ });
300
+ for (const tag in state) {
301
+ if (tag in this.state) Object.assign(this.state[tag], state[tag]);
302
+ else this.memory[tag] = state[tag];
303
+ }
304
+ }
305
+ emit(type, event) {
306
+ this.emitter.emit(type, event);
307
+ }
308
+ on(type, handler) {
309
+ this.emitter.on(type, handler);
255
310
  }
256
311
  };
257
- __name(WebPhecda, "WebPhecda");
258
312
 
259
313
  // src/base.ts
260
314
  var import_phecda_core3 = require("phecda-core");
261
315
  function _ts_decorate(decorators, target, key, desc) {
262
316
  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;
317
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
318
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
269
319
  return c > 3 && r && Object.defineProperty(target, key, r), r;
270
320
  }
271
321
  __name(_ts_decorate, "_ts_decorate");
272
322
  function _ts_metadata(k, v) {
273
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
274
- return Reflect.metadata(k, v);
323
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
275
324
  }
276
325
  __name(_ts_metadata, "_ts_metadata");
277
326
  var Base = class {
327
+ static {
328
+ __name(this, "Base");
329
+ }
330
+ __UNMOUNT_SYMBOL__ = [];
331
+ __PROMISE_SYMBOL__;
278
332
  constructor() {
279
333
  }
280
334
  get tag() {
281
335
  return (0, import_phecda_core3.getTag)(this);
282
336
  }
283
337
  then(cb, reject) {
284
- return this._promise.then(cb, reject);
338
+ return this.__PROMISE_SYMBOL__.then(cb, reject);
285
339
  }
286
340
  on(type, handler) {
287
341
  emitter.on(type, handler);
@@ -293,7 +347,6 @@ var Base = class {
293
347
  off(type, handler) {
294
348
  emitter.off(type, handler);
295
349
  }
296
- __UNMOUNT_SYMBOL__ = [];
297
350
  onUnmount(cb) {
298
351
  this.__UNMOUNT_SYMBOL__.push(cb);
299
352
  }
@@ -301,7 +354,6 @@ var Base = class {
301
354
  return Promise.all(this.__UNMOUNT_SYMBOL__.map((fn) => fn()));
302
355
  }
303
356
  };
304
- __name(Base, "Base");
305
357
  _ts_decorate([
306
358
  import_phecda_core3.Unmount,
307
359
  _ts_metadata("design:type", Function),
@@ -314,7 +366,11 @@ _ts_decorate([
314
366
  WebPhecda,
315
367
  bindMethod,
316
368
  defaultWebInject,
369
+ delDefaultPhecda,
317
370
  emitter,
371
+ getDefaultPhecda,
372
+ phecdaNamespace,
373
+ setDefaultPhecda,
318
374
  wait,
319
375
  ...require("phecda-core")
320
376
  });
package/dist/index.mjs CHANGED
@@ -4,13 +4,11 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
4
4
  // src/index.ts
5
5
  export * from "phecda-core";
6
6
 
7
- // src/plugin.ts
7
+ // src/inject.ts
8
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;
14
12
  if (!getInject("watcher")) {
15
13
  setInject("watcher", ({ eventName, instance, key, options }) => {
16
14
  const fn = typeof instance[key] === "function" ? instance[key].bind(instance) : (v) => instance[key] = v;
@@ -36,8 +34,7 @@ function defaultWebInject() {
36
34
  instance[key] = data;
37
35
  } else {
38
36
  for (const i in data) {
39
- if (i)
40
- instance[i] = data[i];
37
+ if (i) instance[i] = data[i];
41
38
  }
42
39
  }
43
40
  }
@@ -53,6 +50,7 @@ __name(defaultWebInject, "defaultWebInject");
53
50
  // src/core.ts
54
51
  import { get, getTag, invokeHandler } from "phecda-core";
55
52
  import "reflect-metadata";
53
+ import mitt2 from "mitt";
56
54
 
57
55
  // src/utils.ts
58
56
  function isObject(o) {
@@ -61,8 +59,7 @@ function isObject(o) {
61
59
  __name(isObject, "isObject");
62
60
  function deepMerge(target, patchToApply) {
63
61
  for (const key in patchToApply) {
64
- if (!patchToApply.hasOwnProperty(key))
65
- continue;
62
+ if (!patchToApply.hasOwnProperty(key)) continue;
66
63
  const subPatch = patchToApply[key];
67
64
  const targetValue = target[key];
68
65
  if (isObject(targetValue) && isObject(subPatch) && target.hasOwnProperty(key)) {
@@ -77,22 +74,34 @@ __name(deepMerge, "deepMerge");
77
74
 
78
75
  // src/core.ts
79
76
  function wait(...instances) {
80
- return Promise.all(instances.map((i) => i._promise));
77
+ return Promise.all(instances.map((i) => i.__PROMISE_SYMBOL__));
81
78
  }
82
79
  __name(wait, "wait");
83
80
  function getParamtypes(Model, key) {
84
81
  return Reflect.getMetadata("design:paramtypes", Model, key);
85
82
  }
86
83
  __name(getParamtypes, "getParamtypes");
84
+ var phecdaNamespace = /* @__PURE__ */ new Map();
85
+ function setDefaultPhecda(namespace, phecda) {
86
+ phecdaNamespace.set(namespace, phecda);
87
+ }
88
+ __name(setDefaultPhecda, "setDefaultPhecda");
89
+ function getDefaultPhecda(namespace) {
90
+ return phecdaNamespace.get(namespace);
91
+ }
92
+ __name(getDefaultPhecda, "getDefaultPhecda");
93
+ function delDefaultPhecda(namespace) {
94
+ return phecdaNamespace.delete(namespace);
95
+ }
96
+ __name(delDefaultPhecda, "delDefaultPhecda");
87
97
  var bindCache = /* @__PURE__ */ new WeakMap();
88
- function bindMethod(instance) {
98
+ function bindMethod(instance, wrapper) {
89
99
  if (!bindCache.has(instance)) {
90
100
  const cache = /* @__PURE__ */ new WeakMap();
91
101
  bindCache.set(instance, new Proxy(instance, {
92
102
  get(target, p) {
93
103
  if (typeof target[p] === "function" && !target[p].toString().startsWith("(")) {
94
- if (!cache.has(target[p]))
95
- cache.set(target[p], target[p].bind(target));
104
+ if (!cache.has(target[p])) cache.set(target[p], wrapper ? wrapper(target, p) : target[p].bind(target));
96
105
  return cache.get(target[p]);
97
106
  }
98
107
  return target[p];
@@ -103,49 +112,72 @@ function bindMethod(instance) {
103
112
  }
104
113
  __name(bindMethod, "bindMethod");
105
114
  var WebPhecda = class {
115
+ static {
116
+ __name(this, "WebPhecda");
117
+ }
118
+ namespace;
106
119
  parseModule;
107
- origin;
120
+ /**
121
+ * for ssr or manual inject
122
+ */
123
+ memory;
108
124
  state;
109
125
  modelMap;
110
- constructor(parseModule) {
126
+ emitter;
127
+ constructor(namespace, parseModule) {
128
+ this.namespace = namespace;
111
129
  this.parseModule = parseModule;
112
- this.origin = {};
130
+ this.memory = {};
113
131
  this.state = {};
114
132
  this.modelMap = /* @__PURE__ */ new WeakMap();
115
- defaultWebInject();
133
+ this.emitter = mitt2();
134
+ if (typeof window !== "undefined") {
135
+ defaultWebInject();
136
+ setDefaultPhecda(namespace, this);
137
+ }
116
138
  }
117
- // Initialize a module that has not been created yet, and return it directly if it is cached.
139
+ /**
140
+ * Initialize a module that has not been created yet, and return it directly if it is cached.
141
+ */
118
142
  init(model) {
119
143
  const tag = getTag(model);
120
144
  const initModel = /* @__PURE__ */ __name(() => {
121
145
  const paramtypes = getParamtypes(model);
122
146
  let instance2;
147
+ this.emit("Instantiate", {
148
+ tag
149
+ });
123
150
  if (paramtypes) {
124
151
  const paramtypesInstances = [];
125
- for (const i in paramtypes)
126
- paramtypesInstances[i] = this.init(paramtypes[i]);
152
+ for (const i in paramtypes) paramtypesInstances[i] = this.init(paramtypes[i]);
127
153
  instance2 = this.parseModule(new model(...paramtypesInstances));
128
154
  } else {
129
155
  instance2 = this.parseModule(new model());
130
156
  }
131
- if (tag in this.origin) {
132
- Object.assign(instance2, this.origin[tag]);
133
- delete this.origin[tag];
157
+ if (tag in this.memory) Object.assign(instance2, this.memory[tag]);
158
+ if (typeof window !== "undefined") {
159
+ this.emit("Initialize", {
160
+ tag
161
+ });
162
+ instance2.__PROMISE_SYMBOL__ = invokeHandler("init", instance2);
134
163
  }
135
- if (typeof window !== "undefined")
136
- instance2._promise = invokeHandler("init", instance2);
137
164
  return instance2;
138
165
  }, "initModel");
139
166
  const { state, modelMap: map } = this;
140
- if (get(model.prototype, "isolate"))
141
- return initModel();
167
+ if (get(model.prototype, "isolate")) return initModel();
142
168
  if (tag in state) {
143
169
  if (process.env.NODE_ENV === "development") {
144
- if (map.get(state[tag]) === model)
145
- return state[tag];
170
+ if (map.get(state[tag]) === model) return state[tag];
171
+ else this.emit("Hmr", {
172
+ tag
173
+ });
146
174
  } else {
147
- if (map.get(state[tag]) !== model)
175
+ if (map.get(state[tag]) !== model) {
176
+ this.emit("Synonym", {
177
+ tag
178
+ });
148
179
  console.warn(`Synonym model: Module taged "${String(tag)}" has been loaded before, so won't load Module "${model.name}"`);
180
+ }
149
181
  return state[tag];
150
182
  }
151
183
  }
@@ -157,93 +189,111 @@ var WebPhecda = class {
157
189
  patch(model, data) {
158
190
  const tag = getTag(model);
159
191
  const { state } = this;
192
+ this.emit("Patch", {
193
+ tag,
194
+ data
195
+ });
160
196
  deepMerge(state[tag], data);
161
197
  }
162
198
  wait(...modelOrTag) {
163
- const { state } = this;
164
199
  return Promise.all(modelOrTag.map((i) => {
165
- if (typeof i === "function")
166
- i = getTag(i);
167
- return state[i]._promise;
200
+ if (typeof i === "function") i = getTag(i);
201
+ return this.get(i).__PROMISE_SYMBOL__;
168
202
  }));
169
203
  }
170
- get(model) {
204
+ get(modelOrTag) {
171
205
  const { state } = this;
172
- return state[getTag(model)];
206
+ const tag = typeof modelOrTag === "function" ? getTag(modelOrTag) : modelOrTag;
207
+ return state[tag];
173
208
  }
174
- has(model) {
209
+ getModel(tag) {
175
210
  const { state } = this;
176
- return getTag(model) in state;
211
+ return this.modelMap.get(state[tag]);
177
212
  }
178
213
  reset(model) {
179
214
  const { state } = this;
180
215
  const tag = getTag(model);
181
- if (!(tag in state))
182
- return this.init(model);
216
+ if (!(tag in state)) return this.init(model);
217
+ this.emit("Reset", {
218
+ tag
219
+ });
183
220
  const instance = this.init(model);
184
221
  const newInstance = new model();
185
222
  Object.assign(instance, newInstance);
186
223
  for (const key in instance) {
187
- if (!(key in newInstance))
188
- delete instance[key];
224
+ if (!(key in newInstance)) delete instance[key];
189
225
  }
190
226
  }
191
227
  async unmount(modelOrTag) {
192
228
  const tag = typeof modelOrTag === "function" ? getTag(modelOrTag) : modelOrTag;
229
+ if (!this.has(tag)) return;
230
+ this.emit("Unmount", {
231
+ tag
232
+ });
193
233
  const { state } = this;
194
- await invokeHandler("unmount", state[tag]);
234
+ await invokeHandler("unmount", this.get(tag));
195
235
  delete state[tag];
196
236
  }
197
237
  async unmountAll() {
198
238
  const { state } = this;
199
239
  return Promise.all(Object.keys(state).map((tag) => this.unmount(tag)));
200
240
  }
201
- ismount(modelOrTag) {
241
+ has(modelOrTag) {
202
242
  const { state } = this;
203
243
  const tag = typeof modelOrTag === "function" ? getTag(modelOrTag) : modelOrTag;
204
- if (tag in state)
205
- return true;
244
+ if (tag in state) return true;
206
245
  return false;
207
246
  }
208
247
  serialize() {
209
248
  const { state } = this;
210
249
  return JSON.stringify(state, (_key, value) => {
211
- if (this.modelMap.has(value))
212
- return null;
250
+ if (this.modelMap.has(value)) return null;
213
251
  });
214
252
  }
215
253
  load(str) {
216
- this.origin = JSON.parse(str);
254
+ const state = JSON.parse(str);
255
+ this.emit("Load", {
256
+ data: state
257
+ });
258
+ for (const tag in state) {
259
+ if (tag in this.state) Object.assign(this.state[tag], state[tag]);
260
+ else this.memory[tag] = state[tag];
261
+ }
262
+ }
263
+ emit(type, event) {
264
+ this.emitter.emit(type, event);
265
+ }
266
+ on(type, handler) {
267
+ this.emitter.on(type, handler);
217
268
  }
218
269
  };
219
- __name(WebPhecda, "WebPhecda");
220
270
 
221
271
  // src/base.ts
222
272
  import { Unmount, getTag as getTag2 } from "phecda-core";
223
273
  function _ts_decorate(decorators, target, key, desc) {
224
274
  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;
275
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
276
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
231
277
  return c > 3 && r && Object.defineProperty(target, key, r), r;
232
278
  }
233
279
  __name(_ts_decorate, "_ts_decorate");
234
280
  function _ts_metadata(k, v) {
235
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
236
- return Reflect.metadata(k, v);
281
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
237
282
  }
238
283
  __name(_ts_metadata, "_ts_metadata");
239
284
  var Base = class {
285
+ static {
286
+ __name(this, "Base");
287
+ }
288
+ __UNMOUNT_SYMBOL__ = [];
289
+ __PROMISE_SYMBOL__;
240
290
  constructor() {
241
291
  }
242
292
  get tag() {
243
293
  return getTag2(this);
244
294
  }
245
295
  then(cb, reject) {
246
- return this._promise.then(cb, reject);
296
+ return this.__PROMISE_SYMBOL__.then(cb, reject);
247
297
  }
248
298
  on(type, handler) {
249
299
  emitter.on(type, handler);
@@ -255,7 +305,6 @@ var Base = class {
255
305
  off(type, handler) {
256
306
  emitter.off(type, handler);
257
307
  }
258
- __UNMOUNT_SYMBOL__ = [];
259
308
  onUnmount(cb) {
260
309
  this.__UNMOUNT_SYMBOL__.push(cb);
261
310
  }
@@ -263,7 +312,6 @@ var Base = class {
263
312
  return Promise.all(this.__UNMOUNT_SYMBOL__.map((fn) => fn()));
264
313
  }
265
314
  };
266
- __name(Base, "Base");
267
315
  _ts_decorate([
268
316
  Unmount,
269
317
  _ts_metadata("design:type", Function),
@@ -275,6 +323,10 @@ export {
275
323
  WebPhecda,
276
324
  bindMethod,
277
325
  defaultWebInject,
326
+ delDefaultPhecda,
278
327
  emitter,
328
+ getDefaultPhecda,
329
+ phecdaNamespace,
330
+ setDefaultPhecda,
279
331
  wait
280
332
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phecda-web",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "using proxy, provide phecda function to web app",
5
5
  "author": "fgsreally",
6
6
  "license": "MIT",
@@ -21,7 +21,7 @@
21
21
  "phecda-core": "3.0.0"
22
22
  },
23
23
  "devDependencies": {
24
- "tsup": "^6.5.0"
24
+ "tsup": "^8.1.0"
25
25
  },
26
26
  "scripts": {
27
27
  "build": "tsup",