@mantou/gem 2.2.14 → 2.2.15
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/dist/gem.js +7 -7
- package/dist/gem.mjs +7 -7
- package/elements/base/link.d.ts.map +1 -1
- package/elements/base/link.js +6 -3
- package/elements/base/link.js.map +1 -1
- package/elements/base/modal-factory.d.ts +1 -1
- package/elements/base/modal-factory.d.ts.map +1 -1
- package/elements/base/use.d.ts.map +1 -1
- package/elements/base/use.js +11 -0
- package/elements/base/use.js.map +1 -1
- package/helper/hmr.d.ts +3 -2
- package/helper/hmr.d.ts.map +1 -1
- package/helper/hmr.js +95 -23
- package/helper/hmr.js.map +1 -1
- package/helper/i18n.d.ts +2 -1
- package/helper/i18n.d.ts.map +1 -1
- package/helper/i18n.js +9 -1
- package/helper/i18n.js.map +1 -1
- package/helper/theme.d.ts.map +1 -1
- package/helper/theme.js +3 -1
- package/helper/theme.js.map +1 -1
- package/lib/decorators.d.ts.map +1 -1
- package/lib/decorators.js +4 -3
- package/lib/decorators.js.map +1 -1
- package/lib/history.d.ts +10 -7
- package/lib/history.d.ts.map +1 -1
- package/lib/history.js +20 -16
- package/lib/history.js.map +1 -1
- package/lib/lit-html.d.ts +15 -0
- package/lib/lit-html.d.ts.map +1 -1
- package/lib/lit-html.js +3 -1
- package/lib/lit-html.js.map +1 -1
- package/lib/reactive.d.ts +4 -1
- package/lib/reactive.d.ts.map +1 -1
- package/lib/reactive.js +41 -18
- package/lib/reactive.js.map +1 -1
- package/lib/server.d.ts +14 -0
- package/lib/server.d.ts.map +1 -0
- package/lib/server.js +43 -0
- package/lib/server.js.map +1 -0
- package/lib/store.d.ts +10 -1
- package/lib/store.d.ts.map +1 -1
- package/lib/store.js +36 -9
- package/lib/store.js.map +1 -1
- package/lib/utils.d.ts +2 -2
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +20 -7
- package/lib/utils.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/src/elements/base/link.ts +5 -3
- package/src/elements/base/use.ts +11 -0
- package/src/helper/hmr.ts +105 -37
- package/src/helper/i18n.ts +12 -1
- package/src/helper/theme.ts +3 -1
- package/src/lib/decorators.ts +4 -3
- package/src/lib/history.ts +20 -16
- package/src/lib/lit-html.ts +3 -1
- package/src/lib/reactive.ts +40 -18
- package/src/lib/server.ts +45 -0
- package/src/lib/store.ts +40 -9
- package/src/lib/utils.ts +22 -7
- package/src/lib/version.ts +1 -1
- package/src/test/gem-element/basic.test.ts +20 -0
- package/src/test/store.test.ts +12 -0
package/lib/server.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** 服务端渲染时不执行副作用,同步更新 */
|
|
2
|
+
export declare const isServer: boolean;
|
|
3
|
+
/**
|
|
4
|
+
* SSR 时返回当前请求中 `key` 对应的值,第一次访问时使用 `init` 创建,
|
|
5
|
+
* 不在请求中(包括客户端)时返回 `key` 本身
|
|
6
|
+
*/
|
|
7
|
+
export declare const getRequestValue: <T extends object>(key: T, init: () => T) => T;
|
|
8
|
+
/**
|
|
9
|
+
* SSR 时对象的读写转到当前请求的副本上,副本在第一次访问时从原对象浅复制
|
|
10
|
+
*
|
|
11
|
+
* 嵌套的对象没有复制,原地修改会影响所有请求,应该替换顶层属性,例如 `store({ list: [...store.list, item] })`
|
|
12
|
+
*/
|
|
13
|
+
export declare const isolate: <T extends object>(target: T) => T;
|
|
14
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/lib/server.ts"],"names":[],"mappings":"AASA,wBAAwB;AACxB,eAAO,MAAM,QAAQ,SAAoB,CAAC;AAE1C;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAO3D,CAAC;AAEjB;;;;GAIG;AACH,eAAO,MAAM,OAAO,EAAE,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,KAAK,CAcjC,CAAC"}
|
package/lib/server.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// SSR 相关的功能都在这里
|
|
2
|
+
//
|
|
3
|
+
// `@mantou/gem-ssr` 在加载 Gem 前提供 `__GEM_SSR__`,返回当前请求的作用域,
|
|
4
|
+
// 客户端构建时 `unplugin-gem` 把 `globalThis.__GEM_SSR__` 替换成 `undefined`,SSR 代码会被压缩移除
|
|
5
|
+
const { get, set, has, deleteProperty, defineProperty, getOwnPropertyDescriptor, ownKeys } = Reflect;
|
|
6
|
+
const getRequestScope = globalThis.__GEM_SSR__;
|
|
7
|
+
/** 服务端渲染时不执行副作用,同步更新 */
|
|
8
|
+
export const isServer = !!getRequestScope;
|
|
9
|
+
/**
|
|
10
|
+
* SSR 时返回当前请求中 `key` 对应的值,第一次访问时使用 `init` 创建,
|
|
11
|
+
* 不在请求中(包括客户端)时返回 `key` 本身
|
|
12
|
+
*/
|
|
13
|
+
export const getRequestValue = getRequestScope
|
|
14
|
+
? (key, init) => {
|
|
15
|
+
const scope = getRequestScope();
|
|
16
|
+
if (!scope)
|
|
17
|
+
return key;
|
|
18
|
+
if (!scope.has(key))
|
|
19
|
+
scope.set(key, init());
|
|
20
|
+
return scope.get(key);
|
|
21
|
+
}
|
|
22
|
+
: (key) => key;
|
|
23
|
+
/**
|
|
24
|
+
* SSR 时对象的读写转到当前请求的副本上,副本在第一次访问时从原对象浅复制
|
|
25
|
+
*
|
|
26
|
+
* 嵌套的对象没有复制,原地修改会影响所有请求,应该替换顶层属性,例如 `store({ list: [...store.list, item] })`
|
|
27
|
+
*/
|
|
28
|
+
export const isolate = getRequestScope
|
|
29
|
+
? (target) => {
|
|
30
|
+
const copy = () => ({ ...target });
|
|
31
|
+
const current = () => getRequestValue(target, copy);
|
|
32
|
+
return new Proxy(target, {
|
|
33
|
+
get: (_, key) => get(current(), key),
|
|
34
|
+
set: (_, key, value) => set(current(), key, value),
|
|
35
|
+
has: (_, key) => has(current(), key),
|
|
36
|
+
deleteProperty: (_, key) => deleteProperty(current(), key),
|
|
37
|
+
defineProperty: (_, key, descriptor) => defineProperty(current(), key, descriptor),
|
|
38
|
+
getOwnPropertyDescriptor: (_, key) => getOwnPropertyDescriptor(current(), key),
|
|
39
|
+
ownKeys: () => ownKeys(current()),
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
: (target) => target;
|
|
43
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/lib/server.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,EAAE;AACF,0DAA0D;AAC1D,gFAAgF;AAEhF,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,cAAc,EAAE,cAAc,EAAE,wBAAwB,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;AAErG,MAAM,eAAe,GAA0D,UAAkB,CAAC,WAAW,CAAC;AAE9G,wBAAwB;AACxB,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC,eAAe,CAAC;AAE1C;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAmD,eAAe;IAC5F,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;QACZ,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;QAChC,IAAI,CAAC,KAAK;YAAE,OAAO,GAAG,CAAC;QACvB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IACH,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC;AAEjB;;;;GAIG;AACH,MAAM,CAAC,MAAM,OAAO,GAAuC,eAAe;IACxE,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE;QACT,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACpD,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE;YACvB,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC;YACpC,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC;YAClD,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC;YACpC,cAAc,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC;YAC1D,cAAc,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,UAAU,CAAC;YAClF,wBAAwB,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,wBAAwB,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC;YAC9E,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;SAClC,CAAC,CAAC;IACL,CAAC;IACH,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC"}
|
package/lib/store.d.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { type Updater } from './utils';
|
|
2
2
|
export type Store<T = any> = Updater<T>;
|
|
3
|
-
|
|
3
|
+
/** SSR 时当前请求中更新过的有 key 的 store,供 `@mantou/gem-ssr` 使用 */
|
|
4
|
+
export declare const _getUpdatedStores: () => Map<any, any>;
|
|
5
|
+
declare let restoreStore: ((key: string) => object | undefined) | undefined;
|
|
6
|
+
/** 设置客户端恢复 store 的方法,供 `@mantou/gem-ssr` 使用 */
|
|
7
|
+
export declare function _setStoreRestorer(restorer: typeof restoreStore): void;
|
|
8
|
+
/**
|
|
9
|
+
* 创建 store,`key` 用来在 SSR 时同步服务端的值,`swc-plugin-gem` 的 `ssr` 选项会为模块顶层的 store 自动添加
|
|
10
|
+
*/
|
|
11
|
+
export declare function createStore<T = any>(originStore: T, key?: string): ((value?: Partial<T>) => void) & Omit<{
|
|
4
12
|
name: never;
|
|
5
13
|
apply: never;
|
|
6
14
|
call: never;
|
|
@@ -14,4 +22,5 @@ export declare function createStore<T = any>(originStore: T): ((value?: Partial<
|
|
|
14
22
|
[Symbol.metadata]: never;
|
|
15
23
|
}, keyof T> & T;
|
|
16
24
|
export declare function connect(store: Store<any>, func: () => void): () => boolean | undefined;
|
|
25
|
+
export {};
|
|
17
26
|
//# sourceMappingURL=store.d.ts.map
|
package/lib/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/lib/store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/lib/store.ts"],"names":[],"mappings":"AACA,OAAO,EAA4C,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAEjF,MAAM,MAAM,KAAK,CAAC,CAAC,GAAG,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;AAUxC,yDAAyD;AACzD,eAAO,MAAM,iBAAiB,qBAAwD,CAAC;AAGvF,QAAA,IAAI,YAAY,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;AAEpE,+CAA+C;AAC/C,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,OAAO,YAAY,QAE9D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,GAAG,GAAG,EAAE,WAAW,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,aAIzB,OAAO,CAAC,CAAC,CAAC;;;;;;;;;;;;gBAcjD;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,IAAI,6BAK1D"}
|
package/lib/store.js
CHANGED
|
@@ -1,17 +1,44 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getRequestValue, isolate, isServer } from './server';
|
|
2
|
+
import { addMicrotask, assignState, createUpdater } from './utils';
|
|
2
3
|
/**@internal */
|
|
3
4
|
export const _StoreListenerMap = new WeakMap();
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
const createListeners = () => new Set();
|
|
6
|
+
// SSR 时当前请求中更新过的有 key 的 store,渲染后输出到页面中
|
|
7
|
+
const updatedStores = new Map();
|
|
8
|
+
/** SSR 时当前请求中更新过的有 key 的 store,供 `@mantou/gem-ssr` 使用 */
|
|
9
|
+
export const _getUpdatedStores = () => getRequestValue(updatedStores, () => new Map());
|
|
10
|
+
// 客户端读取服务端渲染时 store 的值
|
|
11
|
+
let restoreStore;
|
|
12
|
+
/** 设置客户端恢复 store 的方法,供 `@mantou/gem-ssr` 使用 */
|
|
13
|
+
export function _setStoreRestorer(restorer) {
|
|
14
|
+
restoreStore = restorer;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 创建 store,`key` 用来在 SSR 时同步服务端的值,`swc-plugin-gem` 的 `ssr` 选项会为模块顶层的 store 自动添加
|
|
18
|
+
*/
|
|
19
|
+
export function createStore(originStore, key) {
|
|
20
|
+
const listeners = createListeners();
|
|
21
|
+
// SSR 时每个请求使用独立的值
|
|
22
|
+
const store = isolate(createUpdater(originStore, (value) => {
|
|
23
|
+
assignState(store, value);
|
|
24
|
+
listeners.forEach(addMicrotask);
|
|
25
|
+
if (!isServer)
|
|
26
|
+
return;
|
|
27
|
+
// SSR 时请求中添加的监听器只属于当前请求,其他请求更新 store 时不会触发
|
|
28
|
+
getRequestValue(listeners, createListeners).forEach(addMicrotask);
|
|
29
|
+
const updated = _getUpdatedStores();
|
|
30
|
+
// 不在请求中时更新的是全局的值,客户端也一样
|
|
31
|
+
if (key && updated !== updatedStores)
|
|
32
|
+
updated.set(key, store);
|
|
33
|
+
}));
|
|
34
|
+
if (key && restoreStore)
|
|
35
|
+
assignState(store, restoreStore(key));
|
|
36
|
+
_StoreListenerMap.set(store, listeners);
|
|
11
37
|
return store;
|
|
12
38
|
}
|
|
13
39
|
export function connect(store, func) {
|
|
14
|
-
const
|
|
40
|
+
const storeListeners = _StoreListenerMap.get(store);
|
|
41
|
+
const listeners = storeListeners && getRequestValue(storeListeners, createListeners);
|
|
15
42
|
listeners?.add(func);
|
|
16
43
|
return () => listeners?.delete(func);
|
|
17
44
|
}
|
package/lib/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/lib/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAgB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/lib/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAgB,MAAM,SAAS,CAAC;AAIjF,eAAe;AACf,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,OAAO,EAA+B,CAAC;AAE5E,MAAM,eAAe,GAAG,GAAG,EAAE,CAAC,IAAI,GAAG,EAAc,CAAC;AAEpD,wCAAwC;AACxC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAsB,CAAC;AAEpD,yDAAyD;AACzD,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,EAAE,CAAC,eAAe,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;AAEvF,uBAAuB;AACvB,IAAI,YAA+D,CAAC;AAEpE,+CAA+C;AAC/C,MAAM,UAAU,iBAAiB,CAAC,QAA6B;IAC7D,YAAY,GAAG,QAAQ,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAU,WAAc,EAAE,GAAY;IAC/D,MAAM,SAAS,GAAG,eAAe,EAAE,CAAC;IACpC,kBAAkB;IAClB,MAAM,KAAK,GAAG,OAAO,CACnB,aAAa,CAAC,WAAW,EAAE,CAAC,KAAkB,EAAE,EAAE;QAChD,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC1B,SAAS,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAChC,IAAI,CAAC,QAAQ;YAAE,OAAO;QACtB,2CAA2C;QAC3C,eAAe,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAClE,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;QACpC,wBAAwB;QACxB,IAAI,GAAG,IAAI,OAAO,KAAK,aAAa;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAChE,CAAC,CAAC,CACH,CAAC;IACF,IAAI,GAAG,IAAI,YAAY;QAAE,WAAW,CAAC,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,iBAAiB,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACxC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,KAAiB,EAAE,IAAgB;IACzD,MAAM,cAAc,GAAG,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,cAAc,IAAI,eAAe,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;IACrF,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IACrB,OAAO,GAAG,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC"}
|
package/lib/utils.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
declare function
|
|
2
|
-
export declare function addMicrotask(func: () => void, method?: typeof queueMicrotask): void;
|
|
1
|
+
export declare function addMicrotask(func: () => void): void;
|
|
3
2
|
type OverrideFn = {
|
|
4
3
|
name: never;
|
|
5
4
|
apply: never;
|
|
@@ -13,6 +12,7 @@ type OverrideFn = {
|
|
|
13
12
|
[Symbol.hasInstance]: never;
|
|
14
13
|
[Symbol.metadata]: never;
|
|
15
14
|
};
|
|
15
|
+
export declare function assignState(state: any, payload: any): void;
|
|
16
16
|
export declare function createUpdater<T, Fn = (payload?: Partial<T>) => any>(initState: T, fn: Fn): Fn & Omit<OverrideFn, keyof T> & T;
|
|
17
17
|
export type Updater<T, Fn = (payload?: Partial<T>) => any> = ReturnType<typeof createUpdater<T, Fn>>;
|
|
18
18
|
export declare function absoluteLocation(currentPath?: string, relativePath?: string): string;
|
package/lib/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/lib/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/lib/utils.ts"],"names":[],"mappings":"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"}
|
package/lib/utils.js
CHANGED
|
@@ -1,17 +1,30 @@
|
|
|
1
|
-
|
|
1
|
+
import { getRequestValue } from './server';
|
|
2
|
+
const { assign, fromEntries, entries, keys, defineProperty, hasOwn } = Object;
|
|
2
3
|
// 用原生 Chrome 找不到调用栈
|
|
3
4
|
function queueMicrotask(cb) {
|
|
4
5
|
Promise.resolve().then(cb);
|
|
5
6
|
}
|
|
6
7
|
const microtaskSet = new Set();
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
const createMicrotaskSet = () => new Set();
|
|
9
|
+
export function addMicrotask(func) {
|
|
10
|
+
// SSR 时不同请求的同一个函数都需要执行
|
|
11
|
+
const taskSet = getRequestValue(microtaskSet, createMicrotaskSet);
|
|
12
|
+
if (taskSet.has(func))
|
|
9
13
|
return;
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
queueMicrotask(() => {
|
|
15
|
+
taskSet.delete(func);
|
|
12
16
|
func();
|
|
13
17
|
});
|
|
14
|
-
|
|
18
|
+
taskSet.add(func);
|
|
19
|
+
}
|
|
20
|
+
// 删除后继承的 `name` `length` 只读,直接赋值会报错,需要先定义成自有属性
|
|
21
|
+
export function assignState(state, payload) {
|
|
22
|
+
for (const key of ['name', 'length']) {
|
|
23
|
+
if (payload && hasOwn(payload, key)) {
|
|
24
|
+
defineProperty(state, key, { value: payload[key], writable: true, enumerable: true, configurable: true });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
assign(state, payload);
|
|
15
28
|
}
|
|
16
29
|
// 注意 typeof state === 'function' 但是没有 Function 的方法和属性
|
|
17
30
|
export function createUpdater(initState, fn) {
|
|
@@ -20,7 +33,7 @@ export function createUpdater(initState, fn) {
|
|
|
20
33
|
// setPrototypeOf(state, null);
|
|
21
34
|
delete state.name;
|
|
22
35
|
delete state.length;
|
|
23
|
-
|
|
36
|
+
assignState(state, initState);
|
|
24
37
|
// ts 不允许直接 Omit 掉 Fn 上的属性
|
|
25
38
|
// 只能利用 ts plugin 移除多余的自动完成项
|
|
26
39
|
return state;
|
package/lib/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/lib/utils.ts"],"names":[],"mappings":"AAAA,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/lib/utils.ts"],"names":[],"mappings":"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"}
|
package/lib/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version = "2.2.
|
|
1
|
+
export declare const version = "2.2.15";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/lib/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const version = '2.2.
|
|
1
|
+
export const version = '2.2.15';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
package/package.json
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
} from '../../lib/decorators';
|
|
15
15
|
import { css, GemElement, html } from '../../lib/element';
|
|
16
16
|
import { basePathStore, history } from '../../lib/history';
|
|
17
|
+
import { isServer } from '../../lib/server';
|
|
17
18
|
import { absoluteLocation } from '../../lib/utils';
|
|
18
19
|
import type { RouteItem, RouteOptions } from './route';
|
|
19
20
|
import { createHistoryParams, createPath, matchPath } from './route';
|
|
@@ -125,9 +126,10 @@ export class GemLinkElement extends GemElement {
|
|
|
125
126
|
|
|
126
127
|
#getHint = () => {
|
|
127
128
|
const locationString = this._getLocationString();
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
if (isExternal(locationString)) return locationString;
|
|
130
|
+
const url = new URL(history.basePath + locationString, location.origin);
|
|
131
|
+
// 客户端输出完整 URL 便于打印,服务端(尤其是预渲染)的 origin 不可靠,使用根相对路径
|
|
132
|
+
return isServer ? url.pathname + url.search + url.hash : url.toString();
|
|
131
133
|
};
|
|
132
134
|
|
|
133
135
|
#preload = () => {
|
package/src/elements/base/use.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { adoptedStyle, attribute, property, shadow, state, template } from '../../lib/decorators';
|
|
2
2
|
import { css, GemElement, html } from '../../lib/reactive';
|
|
3
|
+
import { isServer } from '../../lib/server';
|
|
3
4
|
|
|
4
5
|
const styles = css`
|
|
5
6
|
:host(:where(:not([hidden]))) {
|
|
@@ -14,6 +15,7 @@ const styles = css`
|
|
|
14
15
|
`;
|
|
15
16
|
|
|
16
17
|
const eleCache = new Map<string, HTMLTemplateElement>();
|
|
18
|
+
const stringsCache = new Map<string, TemplateStringsArray>();
|
|
17
19
|
/**
|
|
18
20
|
* svg 中的 `<use>` 不能穿透 ShadowDOM,
|
|
19
21
|
* 此元素用来模拟 `<use>`,
|
|
@@ -31,6 +33,15 @@ export class GemUseElement extends GemElement {
|
|
|
31
33
|
|
|
32
34
|
#getContent = () => {
|
|
33
35
|
const ele = this.element || (this.selector ? (this.root || document).querySelector(this.selector) : null);
|
|
36
|
+
// SSR 没有 DOM,把字符串作为静态模版输出
|
|
37
|
+
if (typeof ele === 'string' && isServer) {
|
|
38
|
+
let strings = stringsCache.get(ele);
|
|
39
|
+
if (!strings) {
|
|
40
|
+
strings = Object.assign([ele], { raw: [ele] });
|
|
41
|
+
stringsCache.set(ele, strings);
|
|
42
|
+
}
|
|
43
|
+
return html(strings);
|
|
44
|
+
}
|
|
34
45
|
if (typeof ele === 'string') {
|
|
35
46
|
let temp = eleCache.get(ele);
|
|
36
47
|
if (!temp) {
|
package/src/helper/hmr.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { attribute, boolattribute, emitter, globalemitter, numattribute, property, state } from '../lib/decorators';
|
|
2
|
+
import { ChildPart, type TemplateResult } from '../lib/lit-html';
|
|
2
3
|
import { GemElement, type Metadata, UpdateToken } from '../lib/reactive';
|
|
3
4
|
import type { Store } from '../lib/store';
|
|
5
|
+
import { camelToKebabCase } from '../lib/utils';
|
|
4
6
|
import { Logger } from './logger';
|
|
5
7
|
|
|
6
8
|
const logger = new Logger('HMR');
|
|
@@ -41,37 +43,23 @@ function getHmrMethodKeys(obj: any) {
|
|
|
41
43
|
return Object.getOwnPropertyNames(obj).filter((key) => key.startsWith('_hmr_'));
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
/**
|
|
46
|
+
/** 连接的 store 必须是同一对象,否则元素订阅的是老 store */
|
|
45
47
|
function checkMetadataNeedReload({ mode, penetrable, noBlocking, observedStores }: Metadata, newMetadata: Metadata) {
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
stores?.map((store) => JSON.stringify({ ...store }, (_, v) => (typeof v === 'function' ? v.toString() : v))),
|
|
49
|
-
);
|
|
48
|
+
const isSameStores = (a: Store<any>[] = [], b: Store<any>[] = []) =>
|
|
49
|
+
a.length === b.length && a.every((store, i) => store === b[i]);
|
|
50
50
|
if (
|
|
51
51
|
mode !== newMetadata.mode ||
|
|
52
52
|
penetrable !== newMetadata.penetrable ||
|
|
53
53
|
noBlocking !== newMetadata.noBlocking ||
|
|
54
|
-
|
|
54
|
+
!isSameStores(observedStores, newMetadata.observedStores)
|
|
55
55
|
) {
|
|
56
56
|
return true;
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
/**
|
|
61
|
-
function checkClassNeedReload(existed: CustomElementConstructor, newClass: CustomElementConstructor) {
|
|
62
|
-
if (
|
|
63
|
-
getHmrMethodKeys(existed).join() !== getHmrMethodKeys(newClass).join() ||
|
|
64
|
-
getHmrMethodKeys(existed.prototype).join() !== getHmrMethodKeys(newClass.prototype).join()
|
|
65
|
-
) {
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/** 不支持删减实例其他字段,因为新实例总是使用老 Class 定义 */
|
|
60
|
+
/** 不支持删减实例其他字段、有装饰器的函数成员和构造函数,因为新实例总是使用老 Class 定义 */
|
|
71
61
|
function checkFieldsNeedReload({ instanceFields }: ReturnType<typeof getFields>) {
|
|
72
|
-
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
62
|
+
return [instanceFields.other, instanceFields.ctor].some((diff) => diff?.add.length || diff?.remove.length);
|
|
75
63
|
}
|
|
76
64
|
|
|
77
65
|
function diffArr<T>(oldList: T[], newList: T[], fn: (i: T) => string = (e) => String(e)) {
|
|
@@ -98,10 +86,15 @@ function diffRecord<T>(oldRecord: Partial<Record<string, T[]>>, newRecord: Parti
|
|
|
98
86
|
return diffArr(oldKeys, newKeys);
|
|
99
87
|
}
|
|
100
88
|
|
|
101
|
-
type HasFieldsRecordClass = { _defined_fields_?: [string, string, boolean][] };
|
|
89
|
+
type HasFieldsRecordClass = { _defined_fields_?: [string, string, boolean, string?][] };
|
|
102
90
|
function getFields(existed: CustomElementConstructor, newClass: CustomElementConstructor) {
|
|
103
91
|
const translate = (cls: HasFieldsRecordClass) => {
|
|
104
|
-
const fieldList = (cls._defined_fields_ || []).map(([name, type, isStatic]) => ({
|
|
92
|
+
const fieldList = (cls._defined_fields_ || []).map(([name, type, isStatic, shadow]) => ({
|
|
93
|
+
name,
|
|
94
|
+
type,
|
|
95
|
+
isStatic,
|
|
96
|
+
shadow,
|
|
97
|
+
}));
|
|
105
98
|
const fieldGroup = Object.groupBy(fieldList, ({ isStatic }) => (isStatic ? 'staticFields' : 'instanceFields'));
|
|
106
99
|
const groupBy = (list: typeof fieldGroup.staticFields) => Object.groupBy(list || [], ({ type }) => type);
|
|
107
100
|
return {
|
|
@@ -146,6 +139,44 @@ const descMap = {
|
|
|
146
139
|
globalemitter,
|
|
147
140
|
};
|
|
148
141
|
|
|
142
|
+
const attrTypes = new Set(['attribute', 'boolattribute', 'numattribute']);
|
|
143
|
+
|
|
144
|
+
/** 新增 attribute 的初始值本应在构造时读取,但新实例仍由老类构造,改为首次读取时从 DOM 获取 */
|
|
145
|
+
function lazyInitAttribute(proto: any, prop: string) {
|
|
146
|
+
const { get, set } = Object.getOwnPropertyDescriptor(proto, prop)!;
|
|
147
|
+
const attr = camelToKebabCase(prop);
|
|
148
|
+
Reflect.defineProperty(proto, prop, {
|
|
149
|
+
configurable: true,
|
|
150
|
+
set,
|
|
151
|
+
get() {
|
|
152
|
+
if (get!.call(this) === undefined) set!.call(this, this.getAttribute(attr));
|
|
153
|
+
return get!.call(this);
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** 新增的箭头函数字段不会被老类构造,首次访问时为实例(静态字段为类)创建代理 */
|
|
159
|
+
function defineLazyFn(target: any, name: string, shadow: string) {
|
|
160
|
+
Reflect.defineProperty(target, name, {
|
|
161
|
+
configurable: true,
|
|
162
|
+
get() {
|
|
163
|
+
const fn = (...args: any[]) => this[shadow](...args);
|
|
164
|
+
setProperty(this, name, fn);
|
|
165
|
+
return fn;
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** 函数成员的代理只调用影子方法,可以直接复制到老类上 */
|
|
171
|
+
function updateFnMembers(oldTarget: any, newTarget: any, diffs: ReturnType<typeof getFields>['staticFields']) {
|
|
172
|
+
const { method, fn } = diffs;
|
|
173
|
+
method?.add.concat(method.some).forEach(({ name }) => {
|
|
174
|
+
Reflect.defineProperty(oldTarget, name, Object.getOwnPropertyDescriptor(newTarget, name)!);
|
|
175
|
+
});
|
|
176
|
+
fn?.add.forEach(({ name, shadow }) => defineLazyFn(oldTarget, name, shadow!));
|
|
177
|
+
[method?.remove, fn?.remove].forEach((list) => list?.forEach(({ name }) => deleteProperty(oldTarget, name)));
|
|
178
|
+
}
|
|
179
|
+
|
|
149
180
|
function setArrValue<T>(obj: any, field: string, val: T[] = []) {
|
|
150
181
|
if (!Object.getOwnPropertyDescriptor(obj, field)) {
|
|
151
182
|
setProperty(obj, field, val);
|
|
@@ -159,18 +190,43 @@ function setArrValue<T>(obj: any, field: string, val: T[] = []) {
|
|
|
159
190
|
declare global {
|
|
160
191
|
interface Window {
|
|
161
192
|
_hmrClassRegistry: Map<string, any>;
|
|
162
|
-
_hmrRegisterClass: (name: string) => (cls: HasFieldsRecordClass, ctx: ClassDecoratorContext) =>
|
|
193
|
+
_hmrRegisterClass: (name: string) => (cls: HasFieldsRecordClass, ctx: ClassDecoratorContext) => any;
|
|
194
|
+
_hmrKeep: <T>(key: string, fn: () => T) => T;
|
|
163
195
|
}
|
|
164
196
|
}
|
|
165
197
|
|
|
166
198
|
if (typeof window !== 'undefined' && nativeDefineElement && !window._hmrClassRegistry) {
|
|
167
199
|
window._hmrClassRegistry = new Map();
|
|
200
|
+
|
|
201
|
+
// 模块重新执行时复用模块顶层的 store
|
|
202
|
+
const keptValues = new Map<string, any>();
|
|
203
|
+
window._hmrKeep = (key, fn) => {
|
|
204
|
+
if (!keptValues.has(key)) keptValues.set(key, fn());
|
|
205
|
+
return keptValues.get(key);
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
// 模块重新执行后模板字符串是新对象,内容相同时使用老对象,以便复用已渲染的 DOM
|
|
209
|
+
const canonicalStrings = new Map<string, TemplateStringsArray>();
|
|
210
|
+
const stringsMap = new WeakMap<TemplateStringsArray, TemplateStringsArray>();
|
|
211
|
+
const { _$getTemplate } = ChildPart.prototype;
|
|
212
|
+
ChildPart.prototype._$getTemplate = function (result: TemplateResult) {
|
|
213
|
+
let strings = stringsMap.get(result.strings);
|
|
214
|
+
if (!strings) {
|
|
215
|
+
const key = `${result.type}:${result.strings.join('\0')}`;
|
|
216
|
+
strings = canonicalStrings.get(key) || result.strings;
|
|
217
|
+
canonicalStrings.set(key, strings);
|
|
218
|
+
stringsMap.set(result.strings, strings);
|
|
219
|
+
}
|
|
220
|
+
result.strings = strings;
|
|
221
|
+
return _$getTemplate.call(this, result);
|
|
222
|
+
};
|
|
223
|
+
|
|
168
224
|
window._hmrRegisterClass =
|
|
169
225
|
(name: string) =>
|
|
170
226
|
(cls: HasFieldsRecordClass, { addInitializer }: ClassDecoratorContext) => {
|
|
171
|
-
|
|
172
|
-
const existed = window._hmrClassRegistry.get(name);
|
|
227
|
+
const existed = window._hmrClassRegistry.get(name);
|
|
173
228
|
|
|
229
|
+
addInitializer(() => {
|
|
174
230
|
if (!existed) {
|
|
175
231
|
window._hmrClassRegistry.set(name, cls);
|
|
176
232
|
return;
|
|
@@ -182,7 +238,7 @@ if (typeof window !== 'undefined' && nativeDefineElement && !window._hmrClassReg
|
|
|
182
238
|
while (current) {
|
|
183
239
|
const [oldClass, newClass] = current;
|
|
184
240
|
if (oldClass === newClass || current.some((e) => e === GemElement || e === Function.prototype)) break;
|
|
185
|
-
if (current.some((e) => !e)
|
|
241
|
+
if (current.some((e) => !e)) {
|
|
186
242
|
location.reload();
|
|
187
243
|
return;
|
|
188
244
|
}
|
|
@@ -246,10 +302,17 @@ if (typeof window !== 'undefined' && nativeDefineElement && !window._hmrClassReg
|
|
|
246
302
|
}
|
|
247
303
|
});
|
|
248
304
|
remove.forEach((prop) => {
|
|
249
|
-
|
|
305
|
+
if (type in descMap) {
|
|
306
|
+
setProperty(element, prop.name, undefined);
|
|
307
|
+
}
|
|
250
308
|
});
|
|
251
309
|
});
|
|
252
310
|
});
|
|
311
|
+
instanceFieldsEntries.forEach(([type, { add }]) => {
|
|
312
|
+
if (attrTypes.has(type)) add.forEach((prop) => lazyInitAttribute(oldClass.prototype, prop.name));
|
|
313
|
+
});
|
|
314
|
+
updateFnMembers(oldClass, newClass, fields.staticFields);
|
|
315
|
+
updateFnMembers(oldClass.prototype, newClass.prototype, fields.instanceFields);
|
|
253
316
|
// 删除的属性在 proto 上添加占位符
|
|
254
317
|
instanceFieldsEntries.forEach(([type, { remove }]) => {
|
|
255
318
|
remove.forEach((prop) => {
|
|
@@ -269,23 +332,25 @@ if (typeof window !== 'undefined' && nativeDefineElement && !window._hmrClassReg
|
|
|
269
332
|
setArrValue(oldMetadata, 'adoptedStyleSheets', newMetadata.adoptedStyleSheets);
|
|
270
333
|
setArrValue(oldClass, '_defined_fields_', newClass._defined_fields_);
|
|
271
334
|
|
|
335
|
+
// 全部替换,让所有方法都引用新模块的变量
|
|
272
336
|
[
|
|
273
337
|
[oldClass, newClass],
|
|
274
338
|
[oldClass.prototype, newClass.prototype],
|
|
275
339
|
].forEach(([existedObj, newObj]) => {
|
|
276
|
-
|
|
277
|
-
existedObj,
|
|
278
|
-
Object.fromEntries(
|
|
279
|
-
getHmrMethodKeys(newObj)
|
|
280
|
-
.filter((key) => existedObj[key].toString() !== newObj[key].toString())
|
|
281
|
-
.map((key) => [key, newObj[key]]),
|
|
282
|
-
),
|
|
283
|
-
);
|
|
340
|
+
getHmrMethodKeys(newObj).forEach((key) => (existedObj[key] = newObj[key]));
|
|
284
341
|
});
|
|
285
342
|
|
|
286
343
|
current = [getPrototypeOf(oldClass), getPrototypeOf(newClass)];
|
|
287
344
|
}
|
|
288
345
|
});
|
|
346
|
+
|
|
347
|
+
if (!existed) return;
|
|
348
|
+
|
|
349
|
+
// 新类未注册,构造时使用老类,例如 `new MyElement()`
|
|
350
|
+
const proxy: any = new Proxy(cls, {
|
|
351
|
+
construct: (_, args, newTarget) => Reflect.construct(existed, args, newTarget === proxy ? existed : newTarget),
|
|
352
|
+
});
|
|
353
|
+
return proxy;
|
|
289
354
|
};
|
|
290
355
|
|
|
291
356
|
window.customElements.define = (name: string, cls: CustomElementConstructor) => {
|
|
@@ -301,8 +366,11 @@ if (typeof window !== 'undefined' && nativeDefineElement && !window._hmrClassReg
|
|
|
301
366
|
logger.info(`<${name}> update,`, { cls });
|
|
302
367
|
|
|
303
368
|
updateElement(name, (element) => {
|
|
304
|
-
// 触发样式更新,支持 Light DOM
|
|
305
|
-
element.
|
|
369
|
+
// 触发样式更新,支持 Light DOM;不移动元素,避免失去焦点和滚动位置
|
|
370
|
+
if (element.isConnected) {
|
|
371
|
+
(element as GemElement).disconnectedCallback();
|
|
372
|
+
(element as GemElement).connectedCallback();
|
|
373
|
+
}
|
|
306
374
|
// 重新渲染
|
|
307
375
|
(element as any)[UpdateToken]?.();
|
|
308
376
|
});
|
package/src/helper/i18n.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { RouteTrigger } from '../elements/base/route';
|
|
|
2
2
|
import type { UpdateHistoryParams } from '../lib/history';
|
|
3
3
|
import type { TemplateResult } from '../lib/lit-html';
|
|
4
4
|
import { html, UpdateToken } from '../lib/reactive';
|
|
5
|
+
import { isolate } from '../lib/server';
|
|
5
6
|
import { GemError } from '../lib/utils';
|
|
6
7
|
import { logger } from './logger';
|
|
7
8
|
|
|
@@ -65,13 +66,23 @@ interface I18nOptions<T> {
|
|
|
65
66
|
export class I18n<T = Record<string, Msg>> implements RouteTrigger {
|
|
66
67
|
resources: Resources<T>;
|
|
67
68
|
fallbackLanguage: string;
|
|
68
|
-
currentLanguage: string;
|
|
69
69
|
cache?: boolean | 'manual';
|
|
70
70
|
cachePrefix = 'gem-i18n';
|
|
71
71
|
urlParamsType?: 'path' | 'querystring' | 'ccTLD' | 'gTLD';
|
|
72
72
|
urlParamsName?: string;
|
|
73
73
|
onChange?: (currentLanguage: string) => void;
|
|
74
74
|
|
|
75
|
+
// SSR 时每个请求使用独立的语言
|
|
76
|
+
#state = isolate({ currentLanguage: '' });
|
|
77
|
+
|
|
78
|
+
get currentLanguage() {
|
|
79
|
+
return this.#state.currentLanguage;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
set currentLanguage(lang: string) {
|
|
83
|
+
this.#state.currentLanguage = lang;
|
|
84
|
+
}
|
|
85
|
+
|
|
75
86
|
// 兼容 `<gem-route>`
|
|
76
87
|
replace = ({ path }: UpdateHistoryParams) => this.setLanguage(path!);
|
|
77
88
|
getParams = () => ({ path: this.currentLanguage });
|