amateras 0.10.1 → 0.10.2

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.
Files changed (174) hide show
  1. package/README.md +29 -25
  2. package/build/core.js +1 -0
  3. package/build/css.js +1 -0
  4. package/build/for.js +1 -0
  5. package/build/i18n.js +1 -0
  6. package/build/idb.js +1 -0
  7. package/build/if.js +1 -0
  8. package/build/import-map.js +1 -0
  9. package/build/markdown.js +1 -0
  10. package/build/match.js +1 -0
  11. package/build/meta.js +1 -0
  12. package/build/prefetch.js +1 -0
  13. package/build/router.js +1 -0
  14. package/build/signal.js +1 -0
  15. package/build/ui.js +1 -0
  16. package/build/widget.js +1 -0
  17. package/package.json +7 -5
  18. package/packages/core/package.json +19 -0
  19. package/packages/core/src/env.browser.ts +21 -0
  20. package/packages/core/src/env.node.ts +21 -0
  21. package/packages/core/src/global.ts +5 -0
  22. package/packages/core/src/index.ts +184 -0
  23. package/packages/core/src/lib/hmr.ts +145 -0
  24. package/packages/core/src/lib/symbols.ts +2 -0
  25. package/packages/core/src/structure/ElementProto.ts +95 -0
  26. package/packages/core/src/structure/GlobalState.ts +9 -0
  27. package/packages/core/src/structure/NodeProto.ts +18 -0
  28. package/packages/core/src/structure/Proto.ts +90 -0
  29. package/packages/core/src/structure/ProxyProto.ts +20 -0
  30. package/packages/core/src/structure/TextProto.ts +22 -0
  31. package/packages/core/src/structure/WidgetEvent.ts +17 -0
  32. package/packages/css/README.md +128 -0
  33. package/packages/css/package.json +15 -0
  34. package/packages/css/src/ext/colors/amber.ts +25 -0
  35. package/packages/css/src/ext/colors/blackwhite.ts +13 -0
  36. package/packages/css/src/ext/colors/blue.ts +25 -0
  37. package/packages/css/src/ext/colors/cyan.ts +25 -0
  38. package/packages/css/src/ext/colors/emerald.ts +25 -0
  39. package/packages/css/src/ext/colors/fuchsia.ts +25 -0
  40. package/packages/css/src/ext/colors/gray.ts +25 -0
  41. package/packages/css/src/ext/colors/green.ts +25 -0
  42. package/packages/css/src/ext/colors/indigo.ts +25 -0
  43. package/packages/css/src/ext/colors/lime.ts +25 -0
  44. package/packages/css/src/ext/colors/neutral.ts +25 -0
  45. package/packages/css/src/ext/colors/orange.ts +25 -0
  46. package/packages/css/src/ext/colors/pink.ts +25 -0
  47. package/packages/css/src/ext/colors/purple.ts +25 -0
  48. package/packages/css/src/ext/colors/red.ts +25 -0
  49. package/packages/css/src/ext/colors/rose.ts +25 -0
  50. package/packages/css/src/ext/colors/sky.ts +25 -0
  51. package/packages/css/src/ext/colors/slate.ts +25 -0
  52. package/packages/css/src/ext/colors/stone.ts +25 -0
  53. package/packages/css/src/ext/colors/teal.ts +25 -0
  54. package/packages/css/src/ext/colors/violet.ts +25 -0
  55. package/packages/css/src/ext/colors/yellow.ts +25 -0
  56. package/packages/css/src/ext/colors/zinc.ts +25 -0
  57. package/packages/css/src/ext/colors.ts +23 -0
  58. package/packages/css/src/ext/keyframes.ts +37 -0
  59. package/packages/css/src/ext/property.ts +68 -0
  60. package/packages/css/src/ext/variable.ts +51 -0
  61. package/packages/css/src/index.ts +103 -0
  62. package/packages/css/src/lib/cache.ts +27 -0
  63. package/packages/css/src/lib/colorAssign.ts +6 -0
  64. package/packages/css/src/lib/createRule.ts +31 -0
  65. package/packages/css/src/lib/utils.ts +1 -0
  66. package/packages/css/src/structure/$CSS.ts +4 -0
  67. package/packages/css/src/structure/$CSSKeyframes.ts +13 -0
  68. package/packages/css/src/structure/$CSSProperty.ts +21 -0
  69. package/packages/css/src/structure/$CSSRule.ts +39 -0
  70. package/packages/css/src/structure/$CSSVariable.ts +34 -0
  71. package/packages/css/src/types.ts +300 -0
  72. package/packages/for/package.json +15 -0
  73. package/packages/for/src/global.ts +7 -0
  74. package/packages/for/src/index.ts +15 -0
  75. package/packages/for/src/structure/For.ts +74 -0
  76. package/packages/hmr/package.json +13 -0
  77. package/packages/hmr/src/index.ts +27 -0
  78. package/packages/i18n/README.md +73 -0
  79. package/packages/i18n/package.json +15 -0
  80. package/packages/i18n/src/index.ts +78 -0
  81. package/packages/i18n/src/structure/I18n.ts +51 -0
  82. package/packages/i18n/src/structure/I18nDictionary.ts +31 -0
  83. package/packages/i18n/src/structure/I18nTranslation.ts +51 -0
  84. package/packages/i18n/src/types.ts +77 -0
  85. package/packages/idb/README.md +127 -0
  86. package/packages/idb/package.json +16 -0
  87. package/packages/idb/src/core.ts +6 -0
  88. package/packages/idb/src/index.ts +17 -0
  89. package/packages/idb/src/lib/$IDBRequest.ts +8 -0
  90. package/packages/idb/src/structure/$IDB.ts +63 -0
  91. package/packages/idb/src/structure/$IDBCursor.ts +34 -0
  92. package/packages/idb/src/structure/$IDBIndex.ts +48 -0
  93. package/packages/idb/src/structure/$IDBStore.ts +103 -0
  94. package/packages/idb/src/structure/$IDBStoreBase.ts +30 -0
  95. package/packages/idb/src/structure/$IDBTransaction.ts +38 -0
  96. package/packages/idb/src/structure/builder/$IDBBuilder.ts +229 -0
  97. package/packages/idb/src/structure/builder/$IDBStoreBuilder.ts +100 -0
  98. package/packages/if/package.json +15 -0
  99. package/packages/if/src/global.ts +15 -0
  100. package/packages/if/src/index.ts +51 -0
  101. package/packages/if/src/structure/Condition.ts +44 -0
  102. package/packages/if/src/structure/ConditionStatement.ts +25 -0
  103. package/packages/if/src/structure/Else.ts +6 -0
  104. package/packages/if/src/structure/ElseIf.ts +6 -0
  105. package/packages/if/src/structure/If.ts +6 -0
  106. package/packages/markdown/README.md +53 -0
  107. package/packages/markdown/package.json +15 -0
  108. package/packages/markdown/src/index.ts +3 -0
  109. package/packages/markdown/src/lib/type.ts +26 -0
  110. package/packages/markdown/src/lib/util.ts +21 -0
  111. package/packages/markdown/src/structure/Markdown.ts +57 -0
  112. package/packages/markdown/src/structure/MarkdownLexer.ts +111 -0
  113. package/packages/markdown/src/structure/MarkdownParser.ts +34 -0
  114. package/packages/markdown/src/syntax/alert.ts +46 -0
  115. package/packages/markdown/src/syntax/blockquote.ts +35 -0
  116. package/packages/markdown/src/syntax/bold.ts +11 -0
  117. package/packages/markdown/src/syntax/code.ts +11 -0
  118. package/packages/markdown/src/syntax/codeblock.ts +44 -0
  119. package/packages/markdown/src/syntax/heading.ts +14 -0
  120. package/packages/markdown/src/syntax/horizontalRule.ts +11 -0
  121. package/packages/markdown/src/syntax/image.ts +23 -0
  122. package/packages/markdown/src/syntax/italic.ts +11 -0
  123. package/packages/markdown/src/syntax/link.ts +46 -0
  124. package/packages/markdown/src/syntax/list.ts +121 -0
  125. package/packages/markdown/src/syntax/table.ts +67 -0
  126. package/packages/markdown/src/syntax/text.ts +19 -0
  127. package/packages/match/package.json +15 -0
  128. package/packages/match/src/global.ts +14 -0
  129. package/packages/match/src/index.ts +33 -0
  130. package/packages/match/src/structure/Case.ts +15 -0
  131. package/packages/match/src/structure/Default.ts +12 -0
  132. package/packages/match/src/structure/Match.ts +78 -0
  133. package/packages/meta/package.json +14 -0
  134. package/packages/meta/src/index.ts +36 -0
  135. package/packages/meta/src/lib/resolveMeta.ts +27 -0
  136. package/packages/meta/src/types.ts +36 -0
  137. package/packages/prefetch/package.json +14 -0
  138. package/packages/prefetch/src/index.ts +70 -0
  139. package/packages/router/README.md +18 -0
  140. package/packages/router/package.json +16 -0
  141. package/packages/router/src/global.ts +22 -0
  142. package/packages/router/src/index.ts +106 -0
  143. package/packages/router/src/structure/Link.ts +17 -0
  144. package/packages/router/src/structure/NavLink.ts +19 -0
  145. package/packages/router/src/structure/Page.ts +30 -0
  146. package/packages/router/src/structure/Route.ts +123 -0
  147. package/packages/router/src/structure/RouteGroup.ts +24 -0
  148. package/packages/router/src/structure/RouteNode.ts +54 -0
  149. package/packages/router/src/structure/RouteSlot.ts +34 -0
  150. package/packages/router/src/structure/Router.ts +192 -0
  151. package/packages/router/src/structure/RouterConstructor.ts +18 -0
  152. package/packages/router/src/types.ts +41 -0
  153. package/packages/signal/README.md +93 -0
  154. package/packages/signal/package.json +15 -0
  155. package/packages/signal/src/index.ts +97 -0
  156. package/packages/signal/src/lib/track.ts +18 -0
  157. package/packages/signal/src/structure/Signal.ts +59 -0
  158. package/packages/ui/package.json +14 -0
  159. package/packages/ui/src/index.ts +4 -0
  160. package/packages/ui/src/lib/slideshowAnimations.ts +39 -0
  161. package/packages/ui/src/structure/Radio.ts +77 -0
  162. package/packages/ui/src/structure/Slide.ts +11 -0
  163. package/packages/ui/src/structure/Slideshow.ts +99 -0
  164. package/packages/utils/package.json +18 -0
  165. package/packages/utils/src/global.ts +39 -0
  166. package/packages/utils/src/index.bun.ts +3 -0
  167. package/packages/utils/src/index.ts +2 -0
  168. package/packages/utils/src/lib/debugger.ts +14 -0
  169. package/packages/utils/src/lib/utils.ts +119 -0
  170. package/packages/utils/src/structure/UID.ts +18 -0
  171. package/packages/widget/README.md +29 -0
  172. package/packages/widget/package.json +14 -0
  173. package/packages/widget/src/index.ts +82 -0
  174. package/packages/widget/src/structure/Widget.ts +42 -0
@@ -0,0 +1,99 @@
1
+ import { ElementProto } from "@amateras/core";
2
+ import { _null } from "@amateras/utils";
3
+ import { Slide } from "./Slide";
4
+
5
+ export interface SlideshowOptions {
6
+ /**第一个播放的位置 */
7
+ index?: number;
8
+ /**Slide 间隔时间,单位为秒 */
9
+ interval?: number;
10
+ /**是否自动播放 */
11
+ autoplay?: boolean;
12
+ /**动画函数 */
13
+ animation?: SlideshowAnimationHandle;
14
+ }
15
+
16
+ export class Slideshow extends ElementProto {
17
+ declare __child__: Slide;
18
+ slide: Slide | null = _null;
19
+ index: number;
20
+ timer: NodeJS.Timeout | null = _null;
21
+ interval: number;
22
+ autoplay: boolean;
23
+ animation: SlideshowAnimationHandle | null;
24
+ #passed = 0;
25
+ constructor({index, interval, autoplay, animation, ...props}: $.Props<SlideshowOptions>, layout?: $.Layout<Slideshow>) {
26
+ super('slideshow', props, layout);
27
+ this.index = index ?? 0;
28
+ this.interval = interval ?? 5;
29
+ this.autoplay = autoplay ?? false;
30
+ this.animation = animation ?? _null;
31
+ this.disposers.add(() => this.pause());
32
+ this.ondom(() => {
33
+ if (this.autoplay) this.play();
34
+ })
35
+ }
36
+
37
+ static {
38
+ $.style(Slideshow, 'slideshow{display:block;position:relative;overflow:clip}')
39
+ }
40
+
41
+ override build(): this {
42
+ super.build();
43
+ this.switch(this.index);
44
+ return this;
45
+ }
46
+
47
+ override toString(): string {
48
+ return this.parseHTML({children: this.slide?.toString()});
49
+ }
50
+
51
+ override toDOM(children = true): HTMLElement[] {
52
+ super.toDOM(false);
53
+ if (children && this.slide) this.node?.append(...this.slide.toDOM());
54
+ return [this.node!]
55
+ }
56
+
57
+ play() {
58
+ this.timer = setInterval(() => {
59
+ this.#passed++;
60
+ if (this.#passed >= this.interval * 100) {
61
+ this.next();
62
+ this.#passed = 0;
63
+ }
64
+ }, 10);
65
+ }
66
+
67
+ pause() {
68
+ if (this.timer) clearTimeout(this.timer);
69
+ }
70
+
71
+ next() {
72
+ let size = this.children.length;
73
+ let nextIndex = this.index + 1;
74
+ if (nextIndex >= size) nextIndex = 0;
75
+ this.switch(nextIndex);
76
+ }
77
+
78
+ prev() {
79
+ let size = this.children.length;
80
+ let prevIndex = this.index - 1;
81
+ if (prevIndex <= 0) prevIndex = size - 1;
82
+ this.switch(prevIndex);
83
+ }
84
+
85
+ switch(index: number) {
86
+ this.index = index;
87
+ let slide = this.children.at(index);
88
+ if (this.slide === slide) return;
89
+ if (!slide) return;
90
+ if (this.animation) this.animation(this, slide, this.slide);
91
+ else {
92
+ slide.parent = this;
93
+ this.slide = slide;
94
+ this.node?.replaceChildren(...slide.toDOM());
95
+ }
96
+ }
97
+ }
98
+
99
+ export type SlideshowAnimationHandle = (slideshow: Slideshow, newSlide: Slide, oldSlide: Slide | null) => void;
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "@amateras/utils",
3
+ "peerDependencies": {
4
+ "@amateras/core": "workspace:*"
5
+ },
6
+ "imports": {
7
+ "#structure/*": "./src/structure/*.ts",
8
+ "#lib/*": "./src/lib/*.ts",
9
+ "#node/*": "./src/node/*.ts"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "browser": "./src/index.ts",
14
+ "bun": "./src/index.bun.ts",
15
+ "default": "./src/index.ts"
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,39 @@
1
+ declare global {
2
+ type Nullish = null | undefined;
3
+ type OrArray<T> = T | T[];
4
+ type OrMatrix<T> = T | OrMatrix<T>[];
5
+ type OrPromise<T> = T | Promise<T>;
6
+ type OrNullish<T> = T | Nullish;
7
+ type Constructor<T = any> = abstract new (...args: any[]) => T;
8
+ type Mutable<T> = {
9
+ -readonly [P in keyof T]: T[P];
10
+ }
11
+ type AsyncFunction<T> = (...args: any[]) => Promise<T>;
12
+ type Ok<D> = [data: D, err: null];
13
+ type Err<E> = [data: null, err: E]
14
+ type Result<D, E> = Ok<D> | Err<E>
15
+ type Repeat<T, N extends number, Acc extends T[] = []> =
16
+ Acc['length'] extends 500
17
+ ? T[]
18
+ : Acc['length'] extends N
19
+ ? Acc
20
+ : Repeat<T, N, [...Acc, T]>;
21
+ type Prettify<T> = {
22
+ [K in keyof T]: T[K];
23
+ } & {};
24
+ type Narrow<T> = T extends boolean ? boolean : T;
25
+ type ValueOf<T> = T[keyof T];
26
+ type RequiredKeys<T> = {
27
+ [K in keyof T]-?: {} extends Pick<T, K> ? never : K;
28
+ }[keyof T];
29
+ type RemoveIndexSignature<T> = {
30
+ [K in keyof T as string extends K
31
+ ? never
32
+ : number extends K
33
+ ? never
34
+ : symbol extends K
35
+ ? never
36
+ : K
37
+ ]: T[K];
38
+ };
39
+ }
@@ -0,0 +1,3 @@
1
+ import "#lib/debugger";
2
+ export * from "#lib/utils";
3
+ export * from "#structure/UID";
@@ -0,0 +1,2 @@
1
+ export * from "#lib/utils";
2
+ export * from "#structure/UID";
@@ -0,0 +1,14 @@
1
+
2
+ declare global {
3
+ export import debug = Debug
4
+ }
5
+
6
+ export namespace Debug {
7
+ export const generateHeapsnapshot = async () => {
8
+ let snapshot = Bun.generateHeapSnapshot('v8');
9
+ let size = await Bun.write(`./heapsnapshot/${new Date().toISOString()}.heapsnapshot`, snapshot);
10
+ return size
11
+ }
12
+ }
13
+
14
+ global.debug = Debug;
@@ -0,0 +1,119 @@
1
+ import { onclient } from '@amateras/core';
2
+ import '../global';
3
+
4
+ // Value
5
+ export const _null = null;
6
+ export const _undefined = undefined;
7
+ // Object
8
+ const _Object = Object;
9
+ export const _Object_fromEntries = _Object.fromEntries;
10
+ export const _Object_entries = _Object.entries;
11
+ export const _Object_assign = _Object.assign;
12
+ export const _Object_values = _Object.values;
13
+ export const _Object_defineProperty = _Object.defineProperty;
14
+ export const _Object_getOwnPropertyDescriptors = _Object.getOwnPropertyDescriptors;
15
+ // Array
16
+ const _Array = Array;
17
+ export const _Array_from = _Array.from;
18
+ interface forEach {
19
+ <T>(arr: Array<T>, fn: (value: T, index: number, array: Array<T>) => Promise<void>): Promise<void>;
20
+ <T>(arr: Array<T>, fn: (value: T, index: number, array: Array<T>) => void): void;
21
+ <T>(set: Set<T>, fn: (value: T, index: number, set: Set<T>) => Promise<void>): void;
22
+ <T>(set: Set<T>, fn: (value: T, index: number, set: Set<T>) => void): void;
23
+ <T extends WeakKey>(set: WeakSet<T>, fn: (value: T, index: number, set: WeakSet<T>) => Promise<void>): void;
24
+ <T extends WeakKey>(set: WeakSet<T>, fn: (value: T, index: number, set: WeakSet<T>) => void): void;
25
+ <T>(list: Array<T> | Set<T>, fn: (value: T, index: number, set: Array<T> | Set<T>) => Promise<void>): void;
26
+ <T>(list: Array<T> | Set<T>, fn: (value: T, index: number, set: Array<T> | Set<T>) => void): void;
27
+ <K, V>(map: Map<K, V>, fn: (value: [K, V], index: number, map: Map<K, V>) => Promise<void>): void;
28
+ <K, V>(map: Map<K, V>, fn: (value: [K, V], index: number, map: Map<K, V>) => void): void;
29
+ <N extends Node>(set: NodeListOf<N>, fn: (value: N, index: number, parent: NodeListOf<N>) => Promise<void>): void;
30
+ <N extends Node>(set: NodeListOf<N>, fn: (value: N, index: number, parent: NodeListOf<N>) => void): void;
31
+ }
32
+ export const forEach: forEach = async (arr: any, fn: any) => {
33
+ let i = 0;
34
+ let asyncHandle = async () => { for (let item of arr) { await fn(item, i, arr); i++; } };
35
+ let handle = () => { for (let item of arr) { fn(item, i, arr); i++; } };
36
+ return isAsyncFunction(fn) ? asyncHandle() : handle();
37
+ };
38
+ interface map {
39
+ <T, R>(arr: Array<T>, fn: (value: T, index: number, array: Array<T>) => R): R[];
40
+ <T, R>(set: Set<T>, fn: (value: T, index: number, set: Set<T>) => R): R[];
41
+ <T extends WeakKey>(set: WeakSet<T>, fn: (value: T, index: number, set: WeakSet<T>) => Promise<void>): T[];
42
+ <T extends WeakKey>(set: WeakSet<T>, fn: (value: T, index: number, set: WeakSet<T>) => void): T[];
43
+ <T, R>(list: Array<T> | Set<T>, fn: (value: T, index: number, set: Array<T> | Set<T>) => R): R[];
44
+ <K, V, R>(map: Map<K, V>, fn: (value: [K, V], index: number, map: Map<K, V>) => R): R[];
45
+ <N extends Node, R>(set: NodeListOf<N>, fn: (value: N, index: number, parent: NodeListOf<N>) => R): R[];
46
+ }
47
+ export const map: map = (arr: any, fn: any) => _Array_from(arr).map(fn);
48
+
49
+ // type check
50
+ export const _typeof = (target: any, type: 'string' | 'number' | 'object' | 'boolean' | 'function' | 'bigint' | 'symbol' | 'undefined') => typeof target === type;
51
+ export const isEqual = <T, V>(target: T, args: V[]): target is V & T => args.includes(target as any);
52
+ export const isString = (target: any): target is string => _typeof(target, 'string');
53
+ export const isBoolean = (target: any): target is boolean => _typeof(target, 'boolean');
54
+ export const isNumber = (target: any): target is number => _typeof(target, 'number');
55
+ export const isObject = (target: any): target is object => _typeof(target, 'object');
56
+ export const isFunction = (target: any): target is Function => _typeof(target, 'function');
57
+ export const isAsyncFunction = (target: any): target is AsyncFunction<Awaited<ReturnType<typeof target>>> => _instanceof(target, (async () => 0).constructor as any)
58
+ export const isUndefined = (target: any): target is undefined => target === undefined;
59
+ export const isNull = (target: any): target is null => target === _null;
60
+ export const isArray = _Array.isArray;
61
+ export const _instanceof = <T extends (abstract new (...args: any[]) => any)[]>(target: any, ...instance: T): target is InstanceType<T[number]> => !!instance.find(i => target instanceof i);
62
+ export const is = <T extends abstract new (...args: any[]) => any>(target: any, instance: T): InstanceType<T> | null => _instanceof(target, instance) ? target : _null;
63
+ // JSON
64
+ export const _JSON_stringify = JSON.stringify;
65
+ export const _JSON_parse = JSON.parse;
66
+ // String
67
+ export const startsWith = (target: string, ...str: string[]) => !!str.find(s => target.startsWith(s));
68
+ // String & Array
69
+ interface slice {
70
+ (target: string, start?: number, end?: number): string;
71
+ <T>(target: Array<T>, start?: number, end?: number): T[];
72
+ }
73
+ export const slice: slice = (target: any, start?: number, end?: number) => target.slice(start, end);
74
+ // Function
75
+ export const _bind = <T extends Function>(target: T, obj: Object): T => target.bind(obj);
76
+ // Promise
77
+ export const _Promise = Promise;
78
+
79
+ // utils function
80
+ export const debounce = () => {
81
+ let timer: number;
82
+ return (fn: Function, timeout: number) => {
83
+ if (timer) clearTimeout(timer);
84
+ timer = setTimeout(fn, timeout);
85
+ }
86
+ }
87
+
88
+ const LOWER = 'abcdefghijklmnopqrstuvwxyz';
89
+ const UPPER = LOWER.toUpperCase();
90
+ export interface RandomIdOptions {
91
+ length?: number;
92
+ lettercase?: 'any' | 'lower' | 'upper';
93
+ }
94
+ export const randomId = (options?: RandomIdOptions): string => {
95
+ options = {length: 5, lettercase: 'any', ...options};
96
+ const char = options.lettercase === 'any' ? LOWER + UPPER : options.lettercase === 'lower' ? LOWER : UPPER;
97
+ return _Array_from({length: options.length as number}, (_, i) => char[Math.round(Math.random() * char.length)]).join('');
98
+ }
99
+
100
+ export const sleep = async (ms: number) => new _Promise(resolve => setTimeout(resolve, ms));
101
+
102
+ export const toArray = <T>(item: OrArray<T>): T[] => _instanceof(item, Array) ? item : [item];
103
+
104
+ export const trycatch = <D>(callback: () => D): Result<D, Error> => {
105
+ try {
106
+ return [callback(), _null];
107
+ } catch (err) {
108
+ return [_null, _instanceof(err, Error) ? err : new Error(_JSON_stringify(err))];
109
+ }
110
+ }
111
+
112
+ export const uppercase = (str: string, start?: number, end?: number) => `${slice(str, 0, start)}${slice(str, start, end).toUpperCase()}${end ? slice(str, end) : ''}`
113
+ const _URL = URL;
114
+ export const toURL = (path: string | URL) => {
115
+ if (_instanceof(path, _URL)) return path;
116
+ if (startsWith(path, 'http')) return new _URL(path);
117
+ if (onclient()) return new _URL(startsWith(path, origin) ? path : origin+path);
118
+ else return new _URL('https://localhost' + path)
119
+ }
@@ -0,0 +1,18 @@
1
+ import { randomId, type RandomIdOptions } from "#lib/utils";
2
+ import type { Proto } from "@amateras/core";
3
+
4
+ export class UID {
5
+ static map = new Map<string, Set<string>>();
6
+
7
+ static generate(key: string, options?: RandomIdOptions): string {
8
+ const set = UID.map.get(key) ?? new Set();
9
+ const id = randomId(options);
10
+ if (set.has(id)) return UID.generate(key);
11
+ return id;
12
+ }
13
+
14
+ static persistInProto(proto: Proto, key: string, options?: RandomIdOptions) {
15
+ const id = UID.generate(key, options);
16
+ proto.disposers.add(() => UID.map.get(key)?.delete(id))
17
+ }
18
+ }
@@ -0,0 +1,29 @@
1
+ # Amateras Widget
2
+ Widget 是组件化需要的重要模块,能够帮助开发者便利地编写组件代码。每个组件能够保存自己的数据仓库(Store),并且能将数据传达到指定的子组件中。
3
+
4
+ ## 使用方式
5
+ 使用组件函数 `$.widget` 定义组件原型构造器(Widget Constructor)。
6
+ ```ts
7
+ import 'amateras';
8
+ import 'amateras/widget';
9
+
10
+ // 定义组件构造器
11
+ const App = $.widget((props: {name: string}) => ({
12
+ // 组建的模板函数
13
+ layout() {
14
+ $('h1', () => `Hello ${props.name}!`)
15
+ }
16
+ }))
17
+
18
+ // 创建组件
19
+ const $app = $(App, {name: 'Amateras'});
20
+
21
+ // 构建并渲染组件
22
+ $.render($app, () => document.body);
23
+
24
+ // 输出:<h1>Hello Amateras!</h1>
25
+ ```
26
+
27
+ ## 文档
28
+ 1. [组件基础](/docs/Widget.md)
29
+ 2. [组件数据仓库](/docs/Widget.md)
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "@amateras/widget",
3
+ "peerDependencies": {
4
+ "@amateras/core": "workspace:*",
5
+ "@amateras/utils": "workspace:*"
6
+ },
7
+ "imports": {
8
+ "#structure/*": "./src/structure/*.ts",
9
+ "#lib/*": "./src/lib/*.ts"
10
+ },
11
+ "exports": {
12
+ ".": "./src/index.ts"
13
+ }
14
+ }
@@ -0,0 +1,82 @@
1
+ import { Proto } from "@amateras/core";
2
+ import { _Object_assign } from "@amateras/utils";
3
+ import { WidgetConstructor, type Widget } from "./structure/Widget";
4
+
5
+ export type WidgetChildrenLayout<$$ extends Constructor | null> = (proto: $$ extends Constructor ? InstanceType<$$> : undefined) => void;
6
+ export type WidgetConstructLayout<$$ extends Constructor | null, Store> = (
7
+ context: {
8
+ store: Store,
9
+ children: (
10
+ ...args:
11
+ $$ extends Constructor
12
+ ? [proto: InstanceType<$$>]
13
+ : []
14
+ ) => void
15
+ }
16
+ ) => void;
17
+
18
+ type WidgetInitLayoutStore<ParentStore, Store> =
19
+ ParentStore extends Record<string, any>
20
+ ? Store extends Record<string, any>
21
+ ? Prettify<ParentStore & Store>
22
+ : ParentStore
23
+ : Store extends Record<string, any>
24
+ ? Store
25
+ : {}
26
+
27
+ export type WidgetInit<$$ extends Constructor | null = null, Store = any, Ancestors = Widget[], ParentStore = any> =
28
+ | {
29
+ ancestors?: Ancestors,
30
+ store?: Store,
31
+ $$?: $$,
32
+ layout: WidgetConstructLayout<$$, WidgetInitLayoutStore<ParentStore, Store>>
33
+ }
34
+
35
+ type MergeAncestorStore<T extends any[]> =
36
+ MergeUnionType<
37
+ T extends Array<infer W>
38
+ ? W extends Widget<any, any, infer Store>
39
+ ? Store
40
+ : never
41
+ : never
42
+ >
43
+
44
+ type MergeUnionType<U> =
45
+ (
46
+ U extends any
47
+ ? (k: U) => void
48
+ : never
49
+ ) extends (k: infer I) => void
50
+ ? I
51
+ : never;
52
+
53
+ type WidgetCraftArguments<$$ extends Constructor | null, Props> =
54
+ RequiredKeys<Props> extends never
55
+ ? [children?: WidgetChildrenLayout<$$>] | [props?: $.Props<Props>, children?: WidgetChildrenLayout<$$>]
56
+ : [props: $.Props<Props>, children?: WidgetChildrenLayout<$$>]
57
+
58
+ declare global {
59
+ export function $<$$ extends Constructor | null, Props = never>(
60
+ widget: Widget<$$, Props>,
61
+ ...args: WidgetCraftArguments<$$, Props>
62
+ ): Proto;
63
+
64
+ export namespace $ {
65
+ export function widget<
66
+ Props extends $.Props,
67
+ Store,
68
+ Ancestors,
69
+ ParentStore extends MergeAncestorStore<Ancestors extends any[] ? Ancestors : []>,
70
+ $$ extends Constructor | null = null
71
+ >(init: (props: Props) => WidgetInit<$$, Store, Ancestors, ParentStore>): Widget<$$, Props, Store>;
72
+ }
73
+ }
74
+
75
+ _Object_assign($, {
76
+ widget(arg1: any) {
77
+ let Widget = WidgetConstructor(arg1);
78
+ return Widget;
79
+ }
80
+ })
81
+
82
+ export * from "#structure/Widget";
@@ -0,0 +1,42 @@
1
+ import { symbol_ProtoType } from "@amateras/core";
2
+ import { Proto } from "@amateras/core";
3
+ import { _Object_assign, forEach } from "@amateras/utils";
4
+ import type { WidgetChildrenLayout, WidgetInit } from "..";
5
+
6
+ export const WidgetConstructor = <$$ extends Constructor | null, Props, Store>
7
+ (init: (props: Props) => WidgetInit) => {
8
+ let stores = new WeakMap<Proto, Store>();
9
+ return class extends Proto {
10
+ declare static props: Props;
11
+ declare static store: Store;
12
+ static override [symbol_ProtoType] = 'Widget';
13
+ static stores = stores;
14
+
15
+ constructor(...args: Props extends unknown ? [] : [Props, WidgetChildrenLayout<$$>]) {
16
+ super(() => {
17
+ let props = args[0] ?? {};
18
+ let children = args[1];
19
+ let {store, layout, ancestors} = init(props as Props);
20
+ if (!store) store = {};
21
+ if (ancestors) forEach(ancestors, ancestor => {
22
+ let ancestorProto = this.findAbove(proto => proto.constructor === ancestor && proto);
23
+ if (ancestorProto) {
24
+ let ancestorStore = ancestor.stores.get(ancestorProto);
25
+ _Object_assign(store, ancestorStore);
26
+ }
27
+ });
28
+ stores.set(this, store);
29
+ //@ts-ignore
30
+ layout({store, children: (proto) => children?.(proto)});
31
+ });
32
+ }
33
+ }
34
+ }
35
+
36
+ export interface Widget<$$ extends Constructor | null = any, Props = any, Store = any> {
37
+ new(...args: Props extends unknown ? [] : [Props]): Proto;
38
+ props: Props;
39
+ store: Store;
40
+ stores: WeakMap<Proto, Store>
41
+ layout: ($$: $$) => void
42
+ }