vasille-web 7.0.0-rc.3 → 7.0.0

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 (210) hide show
  1. package/README.md +32 -16
  2. package/build/dev/communication.d.ts +9 -0
  3. package/build/dev/css-injector.d.ts +14 -0
  4. package/build/dev/css-injector.js +37 -0
  5. package/build/dev/css.d.ts +3 -0
  6. package/build/dev/css.js +32 -0
  7. package/build/dev/index.d.ts +55 -0
  8. package/build/dev/index.js +64 -0
  9. package/build/dev/inspector.d.ts +18 -0
  10. package/build/dev/inspector.js +226 -0
  11. package/build/dev/mount.d.ts +11 -0
  12. package/build/dev/mount.js +91 -0
  13. package/build/dev/router.d.ts +23 -0
  14. package/build/dev/router.js +67 -0
  15. package/build/dev/runner.d.ts +34 -0
  16. package/build/dev/runner.js +128 -0
  17. package/build/shadow/css.d.ts +23 -0
  18. package/build/shadow/css.js +77 -0
  19. package/build/shadow/index.d.ts +3 -0
  20. package/build/shadow/index.js +3 -0
  21. package/build/shadow/lib.d.ts +11 -0
  22. package/build/shadow/lib.js +145 -0
  23. package/build/shadow/types.d.ts +31 -0
  24. package/build/ssg/awaited.d.ts +3 -0
  25. package/build/ssg/awaited.js +24 -0
  26. package/build/ssg/css.d.ts +8 -0
  27. package/build/ssg/css.js +36 -0
  28. package/build/ssg/index.d.ts +21 -0
  29. package/build/ssg/index.js +37 -0
  30. package/build/ssg/router.d.ts +17 -0
  31. package/build/ssg/router.js +59 -0
  32. package/build/ssg/runner.d.ts +56 -0
  33. package/build/ssg/runner.js +337 -0
  34. package/build/types/index.d.ts +9 -0
  35. package/build/types/index.js +1 -0
  36. package/build/web/css/index.d.ts +21 -0
  37. package/build/web/css/index.js +53 -0
  38. package/build/web/css/lib.d.ts +10 -0
  39. package/build/web/css/lib.js +75 -0
  40. package/build/web/index.d.ts +6 -0
  41. package/build/web/index.js +6 -0
  42. package/{types → build/web/jsx}/jsx-runtime.d.ts +6 -6
  43. package/build/web/jsx/spec/css.d.ts +7 -0
  44. package/build/web/jsx/spec/css.js +1 -0
  45. package/{types → build/web/jsx}/spec/html.d.ts +1 -1
  46. package/build/web/jsx/spec/html.js +1 -0
  47. package/build/web/mount.d.ts +19 -0
  48. package/{lib/index.js → build/web/mount.js} +25 -20
  49. package/build/web/router/router.d.ts +45 -0
  50. package/build/web/router/router.js +131 -0
  51. package/build/web/runner/binding/attribute.d.ts +16 -0
  52. package/build/web/runner/binding/attribute.js +30 -0
  53. package/build/web/runner/binding/binding.d.ts +20 -0
  54. package/build/web/runner/binding/binding.js +28 -0
  55. package/build/web/runner/binding/class.d.ts +9 -0
  56. package/build/web/runner/binding/class.js +32 -0
  57. package/build/web/runner/binding/property.d.ts +16 -0
  58. package/build/web/runner/binding/property.js +20 -0
  59. package/build/web/runner/binding/style.d.ts +17 -0
  60. package/build/web/runner/binding/style.js +32 -0
  61. package/build/web/runner/runner.d.ts +45 -0
  62. package/build/web/runner/runner.js +176 -0
  63. package/coverage/clover.xml +754 -0
  64. package/coverage/coverage-final.json +20 -0
  65. package/coverage/lcov-report/base.css +224 -0
  66. package/coverage/lcov-report/block-navigation.js +87 -0
  67. package/coverage/lcov-report/dev/css-injector.ts.html +250 -0
  68. package/coverage/lcov-report/dev/css.ts.html +220 -0
  69. package/coverage/lcov-report/dev/index.html +131 -0
  70. package/coverage/lcov-report/favicon.png +0 -0
  71. package/coverage/lcov-report/index.html +221 -0
  72. package/coverage/lcov-report/prettify.css +1 -0
  73. package/coverage/lcov-report/prettify.js +2 -0
  74. package/coverage/lcov-report/shadow/css.ts.html +382 -0
  75. package/coverage/lcov-report/shadow/index.html +131 -0
  76. package/coverage/lcov-report/shadow/lib.ts.html +670 -0
  77. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  78. package/coverage/lcov-report/sorter.js +210 -0
  79. package/coverage/lcov-report/ssg/awaited.ts.html +169 -0
  80. package/coverage/lcov-report/ssg/css.ts.html +223 -0
  81. package/coverage/lcov-report/ssg/index.html +176 -0
  82. package/coverage/lcov-report/ssg/index.ts.html +370 -0
  83. package/coverage/lcov-report/ssg/router.ts.html +388 -0
  84. package/coverage/lcov-report/ssg/runner.ts.html +1405 -0
  85. package/coverage/lcov-report/web/css/index.html +131 -0
  86. package/coverage/lcov-report/web/css/index.ts.html +313 -0
  87. package/coverage/lcov-report/web/css/lib.ts.html +352 -0
  88. package/coverage/lcov-report/web/index.html +116 -0
  89. package/coverage/lcov-report/web/index.ts.html +574 -0
  90. package/coverage/lcov-report/web/mount.ts.html +454 -0
  91. package/coverage/lcov-report/web/router/index.html +116 -0
  92. package/coverage/lcov-report/web/router/router.ts.html +784 -0
  93. package/coverage/lcov-report/web/runner/binding/attribute.ts.html +190 -0
  94. package/coverage/lcov-report/web/runner/binding/binding.ts.html +193 -0
  95. package/coverage/lcov-report/web/runner/binding/class.ts.html +199 -0
  96. package/coverage/lcov-report/web/runner/binding/index.html +176 -0
  97. package/coverage/lcov-report/web/runner/binding/property.ts.html +154 -0
  98. package/coverage/lcov-report/web/runner/binding/style.ts.html +205 -0
  99. package/coverage/lcov-report/web/runner/index.html +116 -0
  100. package/coverage/lcov-report/web/runner/runner.ts.html +835 -0
  101. package/coverage/lcov.info +1554 -0
  102. package/jest.config.cjs +37 -0
  103. package/package.json +91 -60
  104. package/test/api/dev.test.ts +5 -0
  105. package/test/api/import-list.ts +106 -0
  106. package/test/api/shadow.test.ts +5 -0
  107. package/test/api/ssg.test.ts +5 -0
  108. package/test/api/web.test.ts +5 -0
  109. package/test/css/css-dev.test.ts +103 -0
  110. package/test/css/css.test.ts +27 -0
  111. package/test/mount/exported-web-router.test.ts +63 -0
  112. package/test/mount/modal-no-ctx.test.ts +14 -0
  113. package/test/mount/modal-which-throws.test.ts +33 -0
  114. package/test/mount/modal-with-slot.test.ts +39 -0
  115. package/test/mount/modal.test.ts +34 -0
  116. package/test/mount/prompt-error.test.ts +44 -0
  117. package/test/mount/prompt-timeout.test.ts +53 -0
  118. package/test/mount/prompt-which-trows.test.ts +33 -0
  119. package/test/mount/prompt.test.ts +44 -0
  120. package/test/page.ts +16 -0
  121. package/test/router/empty-router.test.ts +21 -0
  122. package/test/router/page.ts +19 -0
  123. package/test/router/router.test.ts +774 -0
  124. package/test/router/v7.test.ts +129 -0
  125. package/test/runner/destruction.test.ts +113 -0
  126. package/test/runner/runner.test.ts +403 -0
  127. package/test/shadow/components/Component.ts +72 -0
  128. package/test/shadow/css.test.ts +68 -0
  129. package/test/shadow/page.ts +21 -0
  130. package/test/shadow/shadow.test.ts +71 -0
  131. package/test/ssg/awaited/awaited.test.ts +11 -0
  132. package/test/ssg/awaited/element.test.ts +6 -0
  133. package/test/ssg/awaited/element.tsx +10 -0
  134. package/test/ssg/awaited/element.tsx.html +12 -0
  135. package/test/ssg/awaited/embed.test.ts +6 -0
  136. package/test/ssg/awaited/embed.tsx +14 -0
  137. package/test/ssg/awaited/embed.tsx.html +16 -0
  138. package/test/ssg/awaited/text.test.ts +6 -0
  139. package/test/ssg/awaited/text.tsx +8 -0
  140. package/test/ssg/awaited/text.tsx.html +7 -0
  141. package/test/ssg/awaited/throw-sync.tsx +10 -0
  142. package/test/ssg/awaited/throw-sync.tsx.html +7 -0
  143. package/test/ssg/awaited/throw.tsx +13 -0
  144. package/test/ssg/awaited/throw.tsx.html +7 -0
  145. package/test/ssg/compose/compose.test.ts +25 -0
  146. package/test/ssg/compose/modal.tsx +29 -0
  147. package/test/ssg/compose/modal.tsx.html +16 -0
  148. package/test/ssg/compose/view.tsx +35 -0
  149. package/test/ssg/compose/view.tsx.html +12 -0
  150. package/test/ssg/core/core.test.ts +31 -0
  151. package/test/ssg/core/div-embed.tsx +7 -0
  152. package/test/ssg/core/div-embed.tsx.html +9 -0
  153. package/test/ssg/core/div-with-class.tsx +5 -0
  154. package/test/ssg/core/div-with-class.tsx.html +9 -0
  155. package/test/ssg/core/div-with-text.tsx +5 -0
  156. package/test/ssg/core/div-with-text.tsx.html +9 -0
  157. package/test/ssg/core/div.tsx +5 -0
  158. package/test/ssg/core/div.tsx.html +7 -0
  159. package/test/ssg/core/text-join.tsx +9 -0
  160. package/test/ssg/core/text-join.tsx.html +10 -0
  161. package/test/ssg/core/text.tsx +5 -0
  162. package/test/ssg/core/text.tsx.html +7 -0
  163. package/test/ssg/css/css.test.ts +6 -0
  164. package/test/ssg/css/css.tsx +34 -0
  165. package/test/ssg/css/css.tsx.html +28 -0
  166. package/test/ssg/extra-tags/body.tsx +6 -0
  167. package/test/ssg/extra-tags/body.tsx.html +7 -0
  168. package/test/ssg/extra-tags/extra-tags.test.ts +11 -0
  169. package/test/ssg/extra-tags/head.tsx +9 -0
  170. package/test/ssg/extra-tags/head.tsx.html +12 -0
  171. package/test/ssg/markdown/blocks.tsx +12 -0
  172. package/test/ssg/markdown/blocks.tsx.md +12 -0
  173. package/test/ssg/markdown/css.tsx +11 -0
  174. package/test/ssg/markdown/css.tsx.md +1 -0
  175. package/test/ssg/markdown/external.tsx +7 -0
  176. package/test/ssg/markdown/external.tsx.md +3 -0
  177. package/test/ssg/markdown/heading.tsx +12 -0
  178. package/test/ssg/markdown/heading.tsx.md +13 -0
  179. package/test/ssg/markdown/hybrid.tsx +15 -0
  180. package/test/ssg/markdown/hybrid.tsx.md +11 -0
  181. package/test/ssg/markdown/lists.tsx +26 -0
  182. package/test/ssg/markdown/lists.tsx.md +16 -0
  183. package/test/ssg/markdown/markdown.test.ts +41 -0
  184. package/test/ssg/markdown/stylish.tsx +19 -0
  185. package/test/ssg/markdown/stylish.tsx.md +15 -0
  186. package/test/ssg/markdown/table.tsx +32 -0
  187. package/test/ssg/markdown/table.tsx.md +11 -0
  188. package/test/ssg/router/embed.html +7 -0
  189. package/test/ssg/router/embed.tsx +5 -0
  190. package/test/ssg/router/file-html.tsx +5 -0
  191. package/test/ssg/router/file.html +7 -0
  192. package/test/ssg/router/index.html +7 -0
  193. package/test/ssg/router/index.tsx +5 -0
  194. package/test/ssg/router/router.test.ts +26 -0
  195. package/test/ssg/run-test.ts +33 -0
  196. package/test/ssg/runner/attr.tsx +7 -0
  197. package/test/ssg/runner/attr.tsx.html +7 -0
  198. package/test/ssg/runner/class.tsx +8 -0
  199. package/test/ssg/runner/class.tsx.html +7 -0
  200. package/test/ssg/runner/runner.test.ts +16 -0
  201. package/test/ssg/runner/style.tsx +19 -0
  202. package/test/ssg/runner/style.tsx.html +7 -0
  203. package/test/tsconfig.json +20 -0
  204. package/lib/dev.js +0 -109
  205. package/types/dev.d.ts +0 -10
  206. package/types/index.d.ts +0 -21
  207. package/types/spec/css.d.ts +0 -7
  208. /package/{lib/spec/css.js → build/dev/communication.js} +0 -0
  209. /package/{lib/spec/html.js → build/shadow/types.js} +0 -0
  210. /package/{lib → build/web/jsx}/jsx-runtime.js +0 -0
@@ -0,0 +1,91 @@
1
+ import { devRouterApp } from "./router.js";
2
+ import { devDynamicalModule, DevFragment, devMountApp, DevPortalNode, errorToString, inspector, toDevValue, } from "vasille/dev";
3
+ import { modal, Prompt } from "../web/index.js";
4
+ import { DevWebRunner } from "./runner.js";
5
+ function createPortal(node, declaration, usage, name) {
6
+ const portal = new DevPortalNode(document.body, node.runner, declaration, usage, name);
7
+ node.child(portal);
8
+ return portal;
9
+ }
10
+ export function devModal(modalFn, declaration, name) {
11
+ const fragments = new Map();
12
+ const run = function (parent, input, usage) {
13
+ modal(modalFn, node => {
14
+ const portal = createPortal(node, declaration, usage, name);
15
+ const event = {
16
+ position: usage,
17
+ target: portal.id,
18
+ };
19
+ inspector.eventTrigger({
20
+ eventName: "open",
21
+ time: Date.now(),
22
+ ...event,
23
+ });
24
+ portal.runOnDestroy(() => {
25
+ inspector.eventTrigger({
26
+ eventName: "close",
27
+ time: Date.now(),
28
+ ...event,
29
+ });
30
+ });
31
+ return portal;
32
+ })(input, parent, undefined);
33
+ };
34
+ const renderer = (input, node, slot, usage) => {
35
+ if (!node) {
36
+ throw new Error("Vasille: Modal context is missing");
37
+ }
38
+ const frag = new DevFragment(node.runner, null, null, name, {});
39
+ if (!input.slot && slot) {
40
+ input.slot = slot;
41
+ }
42
+ node.child(frag);
43
+ fragments.set(frag, { props: input, node: frag, usage });
44
+ run(frag, input, usage);
45
+ };
46
+ return devDynamicalModule(renderer, fragments, run);
47
+ }
48
+ export function devPrompt(modal, declaration, name) {
49
+ let target;
50
+ return new Prompt(modal, (node, extra) => {
51
+ const portal = createPortal(node, declaration, extra[1], name);
52
+ target = portal.id;
53
+ inspector.eventTrigger({
54
+ eventName: "open",
55
+ time: Date.now(),
56
+ target: target,
57
+ });
58
+ return portal;
59
+ }, {
60
+ resolve(data) {
61
+ if (inspector && target) {
62
+ inspector.eventTrigger({
63
+ eventName: "close",
64
+ time: Date.now(),
65
+ target,
66
+ result: {
67
+ value: toDevValue(data),
68
+ },
69
+ });
70
+ }
71
+ },
72
+ reject(err) {
73
+ if (inspector && target) {
74
+ inspector.eventTrigger({
75
+ eventName: "close",
76
+ time: Date.now(),
77
+ target,
78
+ result: {
79
+ error: errorToString(err),
80
+ },
81
+ });
82
+ }
83
+ },
84
+ });
85
+ }
86
+ export function webDevMountApp(element, component, input, inspector) {
87
+ return devMountApp(element, component, new DevWebRunner(window.document), input, inspector);
88
+ }
89
+ export function webDevRouterApp(init, element, inspector) {
90
+ return devRouterApp(element, window, window.location, init, inspector);
91
+ }
@@ -0,0 +1,23 @@
1
+ import { DevFragment, Inspector, StaticPosition } from "vasille/dev";
2
+ import { Fragment, IRunner, ScreenProps } from "vasille";
3
+ import { WebRouter, WebRouterInitialization } from "../web/router/router.js";
4
+ import { DevWebTagOptions } from "./runner.js";
5
+ export declare function devScreen<Node, Element, TagOptions extends object, Route extends string>(renderer: (node: DevFragment<Node, Element, TagOptions>, input: ScreenProps<Route>) => Promise<void>, declaration: StaticPosition, name: string): (props: ScreenProps<Route>, ctx?: Fragment<Node, Element, TagOptions, IRunner<Node, Element, TagOptions>>) => Promise<void>;
6
+ export declare class DevWebRouter<Routes extends string> extends WebRouter<Routes> {
7
+ constructor(window: Window, location: Location, node: Fragment<Node, Element, DevWebTagOptions, IRunner<Node, Element, DevWebTagOptions>>, init: WebRouterInitialization<Routes>);
8
+ goTo(url: string): void;
9
+ ajax(url: string): void;
10
+ load(url: string): Promise<void>;
11
+ reload(): void;
12
+ protected targetByUrl(url: string): {
13
+ url: string;
14
+ path: string;
15
+ query: import("vasille").QueryParams;
16
+ hash: string;
17
+ target: {
18
+ screen: import("vasille").Screen<Node, Element, import("../types/index.js").WebTagOptions, Routes>;
19
+ } | undefined;
20
+ params: object;
21
+ };
22
+ }
23
+ export declare function devRouterApp<Routes extends string>(node: Element, window: Window, location: Location, init: WebRouterInitialization<Routes>, inspector: Inspector): import("vasille/dev").DevAppNode<Node, Element, DevWebTagOptions>;
@@ -0,0 +1,67 @@
1
+ import { DevFragment, inspector, devMountApp } from "vasille/dev";
2
+ import { createScreen } from "vasille";
3
+ import { WebRouter } from "../web/router/router.js";
4
+ import { DevWebRunner } from "./runner.js";
5
+ export function devScreen(renderer, declaration, name) {
6
+ return createScreen(renderer, (node, props) => new DevFragment(node.runner, declaration, null, name, props));
7
+ }
8
+ let targetLookUpResultId = 0;
9
+ export class DevWebRouter extends WebRouter {
10
+ constructor(window, location, node, init) {
11
+ super(window, location, node, init);
12
+ const data = Date.now();
13
+ Object.keys(init.routes).forEach(path => {
14
+ inspector.registeredRoute({ path });
15
+ });
16
+ this.$currentUrl.on(value => {
17
+ inspector.routerStateChange({ name: "currentUrl", value, time: Date.now() });
18
+ });
19
+ this.$loadingUrl.on(value => {
20
+ inspector.routerStateChange({ name: "loadingUrl", value, time: Date.now() });
21
+ });
22
+ }
23
+ goTo(url) {
24
+ inspector.routerActionCall({ name: "goTo", path: url, time: Date.now() });
25
+ super.goTo(url);
26
+ }
27
+ ajax(url) {
28
+ inspector.routerActionCall({ name: "ajax", path: url, time: Date.now() });
29
+ super.ajax(url);
30
+ }
31
+ load(url) {
32
+ inspector.routerActionCall({ name: "load", path: url, time: Date.now() });
33
+ return super.load(url);
34
+ }
35
+ reload() {
36
+ inspector.routerActionCall({ name: "reload", path: this.$currentUrl.V, time: Date.now() });
37
+ super.reload();
38
+ }
39
+ targetByUrl(url) {
40
+ const result = super.targetByUrl(url);
41
+ const id = ++targetLookUpResultId;
42
+ inspector.routerTargetResult({
43
+ id: id,
44
+ url: result.url,
45
+ path: result.path,
46
+ hash: result.hash,
47
+ params: result.params,
48
+ targetFound: !!result.target,
49
+ time: Date.now(),
50
+ });
51
+ Object.entries(result.query).forEach(([name, values]) => {
52
+ values.forEach(value => {
53
+ inspector.routerTargetResultQueryArg({ id, name, value });
54
+ });
55
+ });
56
+ return result;
57
+ }
58
+ }
59
+ export function devRouterApp(node, window, location, init, inspector) {
60
+ const runner = new DevWebRunner(window.document);
61
+ return devMountApp(node, (_data, node) => {
62
+ const router = new DevWebRouter(window, location, node, init);
63
+ Object.defineProperty(runner, "router", {
64
+ value: router,
65
+ });
66
+ }, runner, {}, inspector);
67
+ }
@@ -0,0 +1,34 @@
1
+ import { WebRunner, WebTag, WebTagOptions, WebTextNode } from "../web/runner/runner.js";
2
+ import { StaticPosition } from "vasille/dev";
3
+ import { IRunner, TextProps } from "vasille";
4
+ export interface DevWebTagOptions extends WebTagOptions {
5
+ usage?: StaticPosition;
6
+ }
7
+ export declare class PositionedText {
8
+ text: unknown;
9
+ position: StaticPosition;
10
+ constructor(text: unknown, position: StaticPosition);
11
+ }
12
+ export declare function positionedText(text: unknown, position: StaticPosition): PositionedText;
13
+ export declare class DevWebTextNode extends WebTextNode<DevWebTagOptions, DevWebRunner> {
14
+ id: number;
15
+ constructor(input: TextProps, runner: DevWebRunner, deep: number, usage: StaticPosition);
16
+ destroy(deep: number, keepNodes?: boolean): void;
17
+ compose(): void;
18
+ }
19
+ export declare function remapObject<Before, After>(obj: {
20
+ [k: string]: Before;
21
+ } | undefined, transform: (v: Before) => After): {
22
+ [k: string]: After;
23
+ };
24
+ export declare class DevWebTag extends WebTag<DevWebTagOptions, DevWebRunner> {
25
+ id: number;
26
+ constructor(options: DevWebTagOptions, runner: DevWebRunner, deep: number, tagName: string, usage: StaticPosition | undefined);
27
+ applyOptions(options: DevWebTagOptions): void;
28
+ destroy(deep: number, keepNodes?: boolean): void;
29
+ compose(): void;
30
+ }
31
+ export declare class DevWebRunner extends WebRunner<DevWebTagOptions> implements IRunner<Node, Element, DevWebTagOptions> {
32
+ textNode(deep: number, text: unknown): WebTextNode<DevWebTagOptions, DevWebRunner>;
33
+ tag(deep: number, tagName: string, input: DevWebTagOptions, cb?: ((ctx: DevWebTag) => void) | undefined): DevWebTag;
34
+ }
@@ -0,0 +1,128 @@
1
+ import { WebRunner, WebTag, WebTextNode } from "../web/runner/runner.js";
2
+ import { getPosition, inspector, processDevObject, provideId, toDevIdOrValue } from "vasille/dev";
3
+ import { CssStyleInjector } from "../web/css/index.js";
4
+ export class PositionedText {
5
+ constructor(text, position) {
6
+ this.text = text;
7
+ this.position = position;
8
+ }
9
+ }
10
+ export function positionedText(text, position) {
11
+ return new PositionedText(text, position);
12
+ }
13
+ export class DevWebTextNode extends WebTextNode {
14
+ constructor(input, runner, deep, usage) {
15
+ super(input, runner, deep);
16
+ this.id = provideId();
17
+ inspector.createNode({
18
+ id: this.id,
19
+ time: Date.now(),
20
+ text: toDevIdOrValue(input.text),
21
+ position: usage,
22
+ });
23
+ }
24
+ destroy(deep, keepNodes) {
25
+ inspector.destroy({ id: this.id, time: Date.now() });
26
+ super.destroy(deep, keepNodes);
27
+ }
28
+ compose() {
29
+ super.compose();
30
+ Object.defineProperty(this.node, "vasille", { value: this.id, configurable: false, enumerable: false });
31
+ }
32
+ }
33
+ export function remapObject(obj, transform) {
34
+ const r = {};
35
+ for (const key in obj) {
36
+ r[key] = transform(obj[key]);
37
+ }
38
+ return r;
39
+ }
40
+ export class DevWebTag extends WebTag {
41
+ constructor(options, runner, deep, tagName, usage) {
42
+ super(options, runner, tagName, deep);
43
+ const id = (this.id = provideId());
44
+ inspector.createTag({
45
+ id: this.id,
46
+ time: Date.now(),
47
+ tagName: tagName,
48
+ usage: usage,
49
+ });
50
+ if (options.k) {
51
+ inspector.tagCallback({
52
+ id: id,
53
+ value: toDevIdOrValue(options.k),
54
+ });
55
+ }
56
+ if (options.d) {
57
+ inspector.tagOnDestroy({
58
+ id: id,
59
+ value: toDevIdOrValue(options.d),
60
+ });
61
+ }
62
+ processDevObject(options.a, (key, value) => {
63
+ inspector.tagAttr({
64
+ id: id,
65
+ name: key,
66
+ value: value,
67
+ });
68
+ });
69
+ if (options.c) {
70
+ for (const item of options.c) {
71
+ const value = item instanceof CssStyleInjector ? item.inject() : item;
72
+ inspector.tagClass({ id: id, value: toDevIdOrValue(value) });
73
+ }
74
+ }
75
+ processDevObject(options.s, (name, value) => {
76
+ inspector.tagStyle({ id, name, value });
77
+ });
78
+ processDevObject(options.e, (name, value) => {
79
+ inspector.tagEvent({ id, name, value });
80
+ });
81
+ processDevObject(options.b, (name, value) => {
82
+ inspector.tagBind({ id, name, value });
83
+ });
84
+ }
85
+ applyOptions(options) {
86
+ if (options.e) {
87
+ for (const [key, handler] of Object.entries(options.e)) {
88
+ const userHandler = handler instanceof Array ? handler[0] : handler;
89
+ const evOptions = handler instanceof Array ? handler[1] : {};
90
+ options.e[key] = [
91
+ ev => {
92
+ inspector.eventTrigger({
93
+ target: this.id,
94
+ eventName: key,
95
+ time: Date.now(),
96
+ position: getPosition(handler[0]),
97
+ });
98
+ userHandler(ev);
99
+ },
100
+ evOptions,
101
+ ];
102
+ }
103
+ }
104
+ super.applyOptions(options);
105
+ }
106
+ destroy(deep, keepNodes) {
107
+ inspector.destroy({ id: this.id, time: Date.now() });
108
+ super.destroy(deep, keepNodes);
109
+ }
110
+ compose() {
111
+ super.compose();
112
+ Object.defineProperty(this.node, "vasille", { value: this.id, configurable: false, enumerable: false });
113
+ }
114
+ }
115
+ export class DevWebRunner extends WebRunner {
116
+ textNode(deep, text) {
117
+ if (text instanceof PositionedText) {
118
+ return new DevWebTextNode({ text: text.text }, this, deep, text.position);
119
+ }
120
+ return new WebTextNode({ text: text }, this, deep);
121
+ }
122
+ tag(deep, tagName, input, cb) {
123
+ if (cb) {
124
+ input.l = cb;
125
+ }
126
+ return new DevWebTag(input, this, deep, tagName, input.usage);
127
+ }
128
+ }
@@ -0,0 +1,23 @@
1
+ import { CssStyleInjector } from "../web/css/index.js";
2
+ export declare class StyleSheetsManager {
3
+ protected readonly sheets: CSSStyleSheet[];
4
+ protected readonly classes: Set<string>;
5
+ addRoot(root: ShadowRoot): void;
6
+ get(index: number): CSSStyleSheet | undefined;
7
+ has(className: string): boolean;
8
+ add(className: string): void;
9
+ }
10
+ export declare class ShadowCssStyleInjector extends CssStyleInjector {
11
+ protected manager: StyleSheetsManager | undefined;
12
+ protected staticName: string | null;
13
+ protected rules: (string | [number, string])[];
14
+ constructor(rules: (string | [number, string])[]);
15
+ link(manager?: StyleSheetsManager): void;
16
+ protected generateClassName(): string;
17
+ protected insertRule(rule: string | [number, string], className: string): void;
18
+ }
19
+ export declare function shadowStyleSheet<T extends {
20
+ [k: string]: (string | [number, string])[];
21
+ }>(styles: T): {
22
+ [K in keyof T]: ShadowCssStyleInjector;
23
+ };
@@ -0,0 +1,77 @@
1
+ import { CssStyleInjector, laptopMaxWidth, mobileMaxWidth, tabletMaxWidth } from "../web/css/index.js";
2
+ export class StyleSheetsManager {
3
+ constructor() {
4
+ this.sheets = [];
5
+ this.classes = new Set();
6
+ }
7
+ addRoot(root) {
8
+ /* istanbul ignore else */
9
+ if (this.sheets.length === 0) {
10
+ this.sheets.push(new CSSStyleSheet({ media: "" }), new CSSStyleSheet({ media: `(max-width:${mobileMaxWidth}px)` }), new CSSStyleSheet({ media: `(min-width:${mobileMaxWidth}px) and (max-width:${tabletMaxWidth}px)` }), new CSSStyleSheet({ media: `(min-width:${tabletMaxWidth}px) and (max-width:${laptopMaxWidth}px)` }), new CSSStyleSheet({ media: "(prefers-color-scheme:dark)" }), new CSSStyleSheet({ media: "(prefers-color-scheme:light)" }));
11
+ }
12
+ root.adoptedStyleSheets = this.sheets;
13
+ }
14
+ get(index) {
15
+ return this.sheets[index];
16
+ }
17
+ has(className) {
18
+ const has = this.classes.has(className);
19
+ this.classes.add(className);
20
+ return has;
21
+ }
22
+ add(className) {
23
+ this.classes.add(className);
24
+ }
25
+ }
26
+ export class ShadowCssStyleInjector extends CssStyleInjector {
27
+ constructor(rules) {
28
+ super(rules);
29
+ this.staticName = null;
30
+ this.rules = [...rules];
31
+ }
32
+ link(manager) {
33
+ /* istanbul ignore else */
34
+ if (this.manager !== manager) {
35
+ this.manager = manager;
36
+ if (this.staticName && !manager?.has(this.staticName)) {
37
+ this.className = null;
38
+ /* istanbul ignore else */
39
+ if (this.styles.length === 0) {
40
+ this.styles.push(...this.rules);
41
+ }
42
+ }
43
+ else {
44
+ this.className = this.staticName;
45
+ }
46
+ }
47
+ }
48
+ generateClassName() {
49
+ const name = this.staticName ?? super.generateClassName();
50
+ this.manager?.add(name);
51
+ return (this.staticName = name);
52
+ }
53
+ insertRule(rule, className) {
54
+ const index = typeof rule === "string" ? 0 : rule[0];
55
+ const value = typeof rule === "string" ? rule : rule[1];
56
+ const sheet = this.manager?.get(index);
57
+ try {
58
+ if (sheet) {
59
+ sheet.insertRule(value.replace("{}", className), sheet.cssRules.length);
60
+ }
61
+ else {
62
+ super.insertRule(rule, className);
63
+ }
64
+ }
65
+ catch (e) {
66
+ // ignore css related errors
67
+ void e;
68
+ }
69
+ }
70
+ }
71
+ export function shadowStyleSheet(styles) {
72
+ const result = {};
73
+ for (const key in styles) {
74
+ result[key] = new ShadowCssStyleInjector(styles[key]);
75
+ }
76
+ return result;
77
+ }
@@ -0,0 +1,3 @@
1
+ export { context, impute, receive, share, expr, bind, watch, set, Delay, For, Slot, Watch, awaited, store, model, setModel, mapModel, arrayModel, Switch, setErrorHandler, match, calculate, ref, ensure, view, modal, screen, page, mount, prompt, safe, routerApp, setLaptopMaxWidth, setMobileMaxWidth, setTabletMaxWidth, Zombie, toFieldRef, toDeepFieldRef, safeInit, abortSignal, safeLive, ArrayModelView, showPrompt, effect, ArrayView, MapModelView, SetModelView, QueuedRender, debounced, receiveOptional, Prompt, SteelContext, Model, safeState, live, state, } from "../web/index.js";
2
+ export { shadow as compose, shadow as component } from "./lib.js";
3
+ export { shadowStyleSheet as styleSheet } from "./css.js";
@@ -0,0 +1,3 @@
1
+ export { context, impute, receive, share, expr, bind, watch, set, Delay, For, Slot, Watch, awaited, store, model, setModel, mapModel, arrayModel, Switch, setErrorHandler, match, calculate, ref, ensure, view, modal, screen, page, mount, prompt, safe, routerApp, setLaptopMaxWidth, setMobileMaxWidth, setTabletMaxWidth, Zombie, toFieldRef, toDeepFieldRef, safeInit, abortSignal, safeLive, ArrayModelView, showPrompt, effect, ArrayView, MapModelView, SetModelView, QueuedRender, debounced, receiveOptional, Prompt, SteelContext, Model, safeState, live, state, } from "../web/index.js";
2
+ export { shadow as compose, shadow as component } from "./lib.js";
3
+ export { shadowStyleSheet as styleSheet } from "./css.js";
@@ -0,0 +1,11 @@
1
+ import { WebTagOptions } from "../web/runner/runner.js";
2
+ import { Fragment } from "vasille";
3
+ declare const any = 0;
4
+ declare const string = 1;
5
+ declare const number = 2;
6
+ declare const boolean = 3;
7
+ interface PropsDeclaration {
8
+ [key: string]: typeof string | typeof number | typeof boolean | typeof any;
9
+ }
10
+ export declare function shadow(renderer: (node: Fragment<Node, Element, WebTagOptions>, input: object) => unknown, name: string, props: PropsDeclaration): void;
11
+ export {};
@@ -0,0 +1,145 @@
1
+ import { WebRunner, WebTag } from "../web/runner/runner.js";
2
+ import { ShadowCssStyleInjector, StyleSheetsManager } from "./css.js";
3
+ import { AppNode, Fragment, IValue, ref, Reference } from "vasille";
4
+ const any = 0;
5
+ const string = 1;
6
+ const number = 2;
7
+ const boolean = 3;
8
+ class ShadowTag extends WebTag {
9
+ applyOptions(options) {
10
+ if (options.c) {
11
+ for (const className of options.c) {
12
+ if (className instanceof ShadowCssStyleInjector) {
13
+ className.link(this.runner.styles);
14
+ }
15
+ }
16
+ }
17
+ super.applyOptions(options);
18
+ }
19
+ }
20
+ class ShadowFragment extends Fragment {
21
+ constructor(app) {
22
+ super(app.runner, app.sDeep + 1);
23
+ this.parent = app;
24
+ }
25
+ }
26
+ class ShadowRunner extends WebRunner {
27
+ constructor(document, styles) {
28
+ super(document);
29
+ this.styles = styles;
30
+ }
31
+ tag(deep, tagName, input, cb) {
32
+ if (cb) {
33
+ input.l = cb;
34
+ }
35
+ return new ShadowTag(input, this, tagName, deep);
36
+ }
37
+ }
38
+ function toKebabCase(propName) {
39
+ let index = propName.startsWith("$") ? 1 : 0;
40
+ let name = propName[index].toLowerCase();
41
+ for (index++; index < propName.length; index++) {
42
+ const curr = propName[index];
43
+ if (curr === curr.toUpperCase()) {
44
+ name += "-";
45
+ }
46
+ name += curr.toLowerCase();
47
+ }
48
+ return name;
49
+ }
50
+ function readRef(ref) {
51
+ if (ref instanceof IValue) {
52
+ return ref.V;
53
+ }
54
+ return ref;
55
+ }
56
+ function matchAndSet(o, key, value) {
57
+ if (key.startsWith("$")) {
58
+ if (value instanceof Reference) {
59
+ o[key] = value;
60
+ }
61
+ else {
62
+ o[key].V = value;
63
+ }
64
+ }
65
+ else {
66
+ o[key] = readRef(value);
67
+ }
68
+ }
69
+ export function shadow(renderer, name, props) {
70
+ var _a;
71
+ const observableAttributes = [];
72
+ const attributesNamesMap = new Map();
73
+ const styleManager = new StyleSheetsManager();
74
+ for (const key in props) {
75
+ if (props[key]) {
76
+ const attributeName = toKebabCase(key);
77
+ observableAttributes.push(attributeName);
78
+ attributesNamesMap.set(attributeName, key);
79
+ }
80
+ }
81
+ customElements.define(name, (_a = class extends HTMLElement {
82
+ constructor() {
83
+ super();
84
+ const entityProps = (this.props = {});
85
+ const entityEvents = (this.events = {});
86
+ for (const key in props) {
87
+ const isEvent = key.startsWith("on");
88
+ const isReactive = key.startsWith("$");
89
+ const container = isEvent ? entityEvents : entityProps;
90
+ Object.defineProperty(this, isReactive ? key.slice(1) : key, {
91
+ get: () => readRef(container[key]),
92
+ set: (value) => matchAndSet(container, key, value),
93
+ });
94
+ if (isReactive) {
95
+ entityProps[key] = ref(void 0);
96
+ }
97
+ if (isEvent) {
98
+ const kebab = toKebabCase(key);
99
+ const eventName = kebab[2] === "-" ? kebab.slice(3) : kebab.slice(2);
100
+ entityProps[key] = (...args) => {
101
+ this.dispatchEvent(new CustomEvent(eventName, { detail: args[0] }));
102
+ return entityEvents[key]?.(...args);
103
+ };
104
+ }
105
+ }
106
+ const shadowRoot = this.attachShadow({ mode: "open" });
107
+ styleManager.addRoot(shadowRoot);
108
+ this.root = new AppNode(shadowRoot, new ShadowRunner(document, styleManager));
109
+ }
110
+ connectedCallback() {
111
+ const result = renderer(new ShadowFragment(this.root), this.props);
112
+ /* istanbul ignore else */
113
+ if (result && typeof result === "object" && result.constructor === Object) {
114
+ // Object.assign does not copy getters and setters
115
+ Object.defineProperties(this, Object.getOwnPropertyDescriptors(result));
116
+ }
117
+ }
118
+ disconnectedCallback() {
119
+ this.root.destroy(this.root.sDeep);
120
+ }
121
+ attributeChangedCallback(name, oldValue, newValue) {
122
+ const propName = attributesNamesMap.get(name);
123
+ /* istanbul ignore else */
124
+ if (propName) {
125
+ const type = props[propName];
126
+ switch (type) {
127
+ case string: {
128
+ matchAndSet(this.props, propName, newValue);
129
+ break;
130
+ }
131
+ case number: {
132
+ matchAndSet(this.props, propName, newValue ? parseFloat(newValue) : 0);
133
+ break;
134
+ }
135
+ case boolean: {
136
+ matchAndSet(this.props, propName, newValue !== null);
137
+ break;
138
+ }
139
+ }
140
+ }
141
+ }
142
+ },
143
+ _a.observedAttributes = observableAttributes,
144
+ _a));
145
+ }
@@ -0,0 +1,31 @@
1
+ import { ClassItem, EventHandlers, prefixedObject, TagAttrs, TagEvents, TagProps } from "../web/jsx/jsx-runtime.js";
2
+ import { ElementStyleProps } from "../web/jsx/spec/css.js";
3
+ type Kebab<T extends string, A extends string = ""> = T extends `${infer F}${infer R}` ? Kebab<R, `${A}${F extends Lowercase<F> ? "" : "-"}${Lowercase<F>}`> : A;
4
+ export type WebComponentAttributes<T extends object> = {
5
+ [K in keyof T as K extends `$${infer R}` ? Kebab<R> : K extends `on${string}` ? never : K extends string ? Kebab<K> : K]?: string extends T[K] ? T[K] : number extends T[K] ? T[K] : boolean extends T[K] ? T[K] : never;
6
+ };
7
+ export type WebComponentEventHandler<T, Element> = T extends (arg: infer Arg, ...args: unknown[]) => unknown ? (ev: CustomEvent<Arg>, element: Element) => void : (ev: CustomEvent<never>, element: Element) => void;
8
+ export type WebComponentEvents<T extends object, Element> = {
9
+ [K in keyof T as K extends `on${infer R}` ? `on${Kebab<R>}` : never]?: ((...args: unknown[]) => any) extends T[K] ? WebComponentEventHandler<T[K], Element> : never;
10
+ };
11
+ export type WebComponentProps<T extends object> = {
12
+ [K in keyof T as K extends `$${infer R}` ? R : K]?: T[K];
13
+ };
14
+ export type EmptyObject = NonNullable<unknown>;
15
+ export type WebComponent<T extends (arg: object) => void, Props extends object = T extends (arg: infer Arg) => void ? Arg extends object ? Omit<Arg, "slot" | "callback"> : EmptyObject : EmptyObject, Return extends object = T extends (arg: {
16
+ callback: (arg: infer Arg) => void;
17
+ }) => void ? Arg extends object ? Arg : EmptyObject : EmptyObject> = {
18
+ class?: ClassItem[] | string;
19
+ style?: ElementStyleProps | string;
20
+ callback?: (element: WebComponentProps<Props> & Return & HTMLElement) => void;
21
+ slot?: unknown;
22
+ } & WebComponentEvents<Props, HTMLElement & Return & WebComponentProps<Props>> & prefixedObject<EventHandlers<TagEvents<HTMLElement & Return & WebComponentProps<Props>>>, "on"> & WebComponentAttributes<Props> & Partial<TagAttrs> & prefixedObject<WebComponentProps<Props> & TagProps<HTMLElement>, "property:">;
23
+ type EventHandlersAdapter<T, Element> = {
24
+ [K in keyof T]: T[K] extends (arg: infer Arg, ...args: unknown[]) => unknown ? (arg: Arg, element: Element) => void : (_: never, element: Element) => void;
25
+ };
26
+ export type WebComponentAdapter<Attributes extends object, Properties extends object, Methods extends object, Events extends object> = {
27
+ class?: ClassItem[] | string;
28
+ style?: ElementStyleProps | string;
29
+ callback?: (element: HTMLElement & Properties & Methods) => void;
30
+ } & Partial<Attributes> & Partial<TagAttrs> & prefixedObject<Properties, "property:"> & prefixedObject<EventHandlersAdapter<Events, HTMLElement & Properties & Methods>, "on-"> & prefixedObject<EventHandlers<TagEvents<HTMLElement & Properties & Methods>>, "on">;
31
+ export {};
@@ -0,0 +1,3 @@
1
+ import { IValue } from "vasille";
2
+ export declare function awaited<T>(target: () => Promise<T>): [IValue<unknown, unknown>, IValue<unknown, unknown>];
3
+ export declare function waitForAsyncData(): Promise<void>;
@@ -0,0 +1,24 @@
1
+ import { ref } from "vasille";
2
+ const promises = [];
3
+ export function awaited(target) {
4
+ const value = ref(undefined);
5
+ const err = ref(undefined);
6
+ let current;
7
+ try {
8
+ current = target();
9
+ }
10
+ catch (e) {
11
+ current = undefined;
12
+ err.V = e;
13
+ }
14
+ if (current instanceof Promise) {
15
+ promises.push(current.then(result => (value.V = result)).catch(e => (err.V = e)));
16
+ }
17
+ else {
18
+ value.V = current;
19
+ }
20
+ return [err, value];
21
+ }
22
+ export async function waitForAsyncData() {
23
+ await Promise.all(promises);
24
+ }