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 +2 -0
- package/dist/index.d.ts +28 -14
- package/dist/index.js +207 -51
- package/dist/index.mjs +200 -46
- package/package.json +10 -5
package/README.md
CHANGED
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
|
|
20
|
-
declare function
|
|
21
|
-
declare
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
|
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 {
|
|
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
|
-
|
|
35
|
+
Base: () => Base,
|
|
36
|
+
WebPhecda: () => WebPhecda,
|
|
37
|
+
bindMethod: () => bindMethod,
|
|
32
38
|
defaultWebInject: () => defaultWebInject,
|
|
33
39
|
emitter: () => emitter,
|
|
34
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
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(
|
|
103
|
-
function
|
|
104
|
-
|
|
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(
|
|
107
|
-
|
|
108
|
-
|
|
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(
|
|
111
|
-
function
|
|
112
|
-
|
|
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(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
313
|
+
Base,
|
|
314
|
+
WebPhecda,
|
|
315
|
+
bindMethod,
|
|
156
316
|
defaultWebInject,
|
|
157
317
|
emitter,
|
|
158
|
-
|
|
159
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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(
|
|
66
|
-
function
|
|
67
|
-
|
|
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(
|
|
70
|
-
|
|
71
|
-
|
|
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(
|
|
74
|
-
function
|
|
75
|
-
|
|
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(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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(
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
274
|
+
Base,
|
|
275
|
+
WebPhecda,
|
|
276
|
+
bindMethod,
|
|
118
277
|
defaultWebInject,
|
|
119
278
|
emitter,
|
|
120
|
-
|
|
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": "
|
|
4
|
-
"description": "provide
|
|
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": {
|