@e280/sly 0.0.0-3 → 0.0.0-5

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 (85) hide show
  1. package/README.md +108 -87
  2. package/package.json +3 -3
  3. package/s/demo/demo.bundle.ts +3 -47
  4. package/s/demo/demo.css +13 -6
  5. package/s/demo/views/counter.ts +42 -0
  6. package/s/demo/views/demo.ts +25 -0
  7. package/s/demo/views/loaders.ts +58 -0
  8. package/s/features/dom/dollar.ts +13 -9
  9. package/s/features/op/loaders/make-loader.ts +18 -0
  10. package/s/features/op/loaders/parts/anims.ts +277 -0
  11. package/s/features/op/loaders/parts/ascii-anim.ts +38 -0
  12. package/s/features/{loady → op/loaders}/parts/error-display.ts +10 -10
  13. package/s/features/op/op.ts +42 -20
  14. package/s/features/op/podium.ts +67 -0
  15. package/s/features/views/types.ts +9 -2
  16. package/s/features/views/use.ts +20 -9
  17. package/s/features/views/view.ts +15 -8
  18. package/s/index.html.ts +3 -3
  19. package/s/index.ts +4 -3
  20. package/x/demo/demo.bundle.js +2 -36
  21. package/x/demo/demo.bundle.js.map +1 -1
  22. package/x/demo/demo.bundle.min.js +61 -12
  23. package/x/demo/demo.bundle.min.js.map +4 -4
  24. package/x/demo/demo.css +13 -6
  25. package/x/demo/views/counter.d.ts +1 -0
  26. package/x/demo/views/counter.js +34 -0
  27. package/x/demo/views/counter.js.map +1 -0
  28. package/x/demo/views/demo.d.ts +1 -0
  29. package/x/demo/views/demo.js +21 -0
  30. package/x/demo/views/demo.js.map +1 -0
  31. package/x/demo/views/loaders.d.ts +1 -0
  32. package/x/demo/views/loaders.js +50 -0
  33. package/x/demo/views/loaders.js.map +1 -0
  34. package/x/features/dom/dollar.d.ts +6 -5
  35. package/x/features/dom/dollar.js +8 -7
  36. package/x/features/dom/dollar.js.map +1 -1
  37. package/x/features/op/loaders/make-loader.d.ts +5 -0
  38. package/x/features/op/loaders/make-loader.js +7 -0
  39. package/x/features/op/loaders/make-loader.js.map +1 -0
  40. package/x/features/op/loaders/parts/anims.d.ts +24 -0
  41. package/x/features/op/loaders/parts/anims.js +251 -0
  42. package/x/features/op/loaders/parts/anims.js.map +1 -0
  43. package/x/features/op/loaders/parts/ascii-anim.d.ts +6 -0
  44. package/x/features/op/loaders/parts/ascii-anim.js +26 -0
  45. package/x/features/op/loaders/parts/ascii-anim.js.map +1 -0
  46. package/x/features/op/loaders/parts/error-display.d.ts +1 -0
  47. package/x/features/{loady → op/loaders}/parts/error-display.js +9 -9
  48. package/x/features/op/loaders/parts/error-display.js.map +1 -0
  49. package/x/features/op/op.d.ts +12 -3
  50. package/x/features/op/op.js +33 -17
  51. package/x/features/op/op.js.map +1 -1
  52. package/x/features/op/podium.d.ts +9 -0
  53. package/x/features/op/podium.js +53 -0
  54. package/x/features/op/podium.js.map +1 -0
  55. package/x/features/views/types.d.ts +9 -2
  56. package/x/features/views/use.d.ts +8 -6
  57. package/x/features/views/use.js +21 -10
  58. package/x/features/views/use.js.map +1 -1
  59. package/x/features/views/view.d.ts +2 -10
  60. package/x/features/views/view.js +12 -6
  61. package/x/features/views/view.js.map +1 -1
  62. package/x/index.d.ts +4 -3
  63. package/x/index.html +18 -11
  64. package/x/index.html.js +3 -3
  65. package/x/index.html.js.map +1 -1
  66. package/x/index.js +4 -3
  67. package/x/index.js.map +1 -1
  68. package/s/features/loady/ascii-loader.ts +0 -38
  69. package/s/features/loady/parts/ascii-anim.ts +0 -27
  70. package/s/features/loady/parts/ascii-loader.ts +0 -14
  71. package/s/features/op/pod.ts +0 -19
  72. package/x/features/loady/ascii-loader.d.ts +0 -5
  73. package/x/features/loady/ascii-loader.js +0 -33
  74. package/x/features/loady/ascii-loader.js.map +0 -1
  75. package/x/features/loady/parts/ascii-anim.d.ts +0 -8
  76. package/x/features/loady/parts/ascii-anim.js +0 -21
  77. package/x/features/loady/parts/ascii-anim.js.map +0 -1
  78. package/x/features/loady/parts/ascii-loader.d.ts +0 -3
  79. package/x/features/loady/parts/ascii-loader.js +0 -10
  80. package/x/features/loady/parts/ascii-loader.js.map +0 -1
  81. package/x/features/loady/parts/error-display.d.ts +0 -8
  82. package/x/features/loady/parts/error-display.js.map +0 -1
  83. package/x/features/op/pod.d.ts +0 -5
  84. package/x/features/op/pod.js +0 -16
  85. package/x/features/op/pod.js.map +0 -1
package/x/demo/demo.css CHANGED
@@ -5,6 +5,7 @@
5
5
  :root {
6
6
  --prime: #1eff00;
7
7
  --accent: #387d42;
8
+ --pill: #12763959;
8
9
  --bg: #0e2316;
9
10
  --link: cyan;
10
11
  }
@@ -51,15 +52,12 @@
51
52
 
52
53
  @layer page {
53
54
  :root {
54
- color-scheme: dark;
55
-
56
- padding: 5vw 0.5em;
57
- min-height: 100%;
58
- scrollbar-gutter: stable;
59
-
60
55
  font-size: 21px;
61
56
  font-family: sans-serif;
62
57
 
58
+ color-scheme: dark;
59
+ scrollbar-gutter: stable;
60
+
63
61
  color: color-mix(in lch, var(--prime), #fff8 50%);
64
62
  background: radial-gradient(
65
63
  circle,
@@ -69,6 +67,11 @@
69
67
  }
70
68
 
71
69
  body {
70
+ width: 100%;
71
+ max-width: 32em;
72
+ margin: auto;
73
+ padding: 1em;
74
+
72
75
  display: flex;
73
76
  flex-direction: column;
74
77
  align-items: center;
@@ -88,6 +91,10 @@
88
91
  font-size: 0.8em;
89
92
  }
90
93
 
94
+ .demo {
95
+ width: 100%;
96
+ }
97
+
91
98
  :not(:defined) {
92
99
  display: none;
93
100
  }
@@ -0,0 +1 @@
1
+ export declare const CounterView: import("../../index.js").View<[]>;
@@ -0,0 +1,34 @@
1
+ import { css, html } from "lit";
2
+ import { repeat } from "@e280/stz";
3
+ import { view } from "../../features/views/view.js";
4
+ import { cssReset } from "../../features/views/css-reset.js";
5
+ export const CounterView = view(use => () => {
6
+ use.name("counter");
7
+ use.styles(cssReset, styles);
8
+ const start = use.once(() => Date.now());
9
+ const seconds = use.signal(0);
10
+ use.mount(() => repeat(async () => {
11
+ const since = Date.now() - start;
12
+ seconds(Math.floor(since / 1000));
13
+ }));
14
+ const count = use.signal(0);
15
+ const increment = () => count(count() + 1);
16
+ return html `
17
+ <div>
18
+ <span>${seconds()}</span>
19
+ </div>
20
+ <div>
21
+ <span>${count()}</span>
22
+ <button @click="${increment}">+</button>
23
+ </div>
24
+ `;
25
+ });
26
+ const styles = css `
27
+ :host {
28
+ display: flex;
29
+ flex-direction: column;
30
+ justify-content: center;
31
+ text-align: center;
32
+ }
33
+ `;
34
+ //# sourceMappingURL=counter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"counter.js","sourceRoot":"","sources":["../../../s/demo/views/counter.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,GAAG,EAAE,IAAI,EAAC,MAAM,KAAK,CAAA;AAC7B,OAAO,EAAC,MAAM,EAAC,MAAM,WAAW,CAAA;AAEhC,OAAO,EAAC,IAAI,EAAC,MAAM,8BAA8B,CAAA;AACjD,OAAO,EAAC,QAAQ,EAAC,MAAM,mCAAmC,CAAA;AAE1D,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE;IAC3C,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACnB,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IAE5B,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;IACxC,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IAE7B,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,IAAG,EAAE;QAChC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAA;QAChC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAA;IAClC,CAAC,CAAC,CAAC,CAAA;IAEH,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IAC3B,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAA;IAE1C,OAAO,IAAI,CAAA;;WAED,OAAO,EAAE;;;WAGT,KAAK,EAAE;qBACG,SAAS;;EAE5B,CAAA;AACF,CAAC,CAAC,CAAA;AAEF,MAAM,MAAM,GAAG,GAAG,CAAA;;;;;;;CAOjB,CAAA"}
@@ -0,0 +1 @@
1
+ export declare const DemoView: import("../../index.js").View<[]>;
@@ -0,0 +1,21 @@
1
+ import { css, html } from "lit";
2
+ import { CounterView } from "./counter.js";
3
+ import { LoadersView } from "./loaders.js";
4
+ import { view } from "../../features/views/view.js";
5
+ import { cssReset } from "../../features/views/css-reset.js";
6
+ export const DemoView = view(use => () => {
7
+ use.name("demo");
8
+ use.styles(cssReset, styles);
9
+ return html `
10
+ ${CounterView()}
11
+ ${LoadersView()}
12
+ `;
13
+ });
14
+ const styles = css `
15
+ :host {
16
+ display: flex;
17
+ flex-direction: column;
18
+ gap: 1em;
19
+ }
20
+ `;
21
+ //# sourceMappingURL=demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demo.js","sourceRoot":"","sources":["../../../s/demo/views/demo.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,GAAG,EAAE,IAAI,EAAC,MAAM,KAAK,CAAA;AAC7B,OAAO,EAAC,WAAW,EAAC,MAAM,cAAc,CAAA;AACxC,OAAO,EAAC,WAAW,EAAC,MAAM,cAAc,CAAA;AACxC,OAAO,EAAC,IAAI,EAAC,MAAM,8BAA8B,CAAA;AACjD,OAAO,EAAC,QAAQ,EAAC,MAAM,mCAAmC,CAAA;AAE1D,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE;IACxC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAChB,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IAE5B,OAAO,IAAI,CAAA;IACR,WAAW,EAAE;IACb,WAAW,EAAE;EACf,CAAA;AACF,CAAC,CAAC,CAAA;AAEF,MAAM,MAAM,GAAG,GAAG,CAAA;;;;;;CAMjB,CAAA"}
@@ -0,0 +1 @@
1
+ export declare const LoadersView: import("../../index.js").View<[]>;
@@ -0,0 +1,50 @@
1
+ import { css, html } from "lit";
2
+ import { Op } from "../../features/op/op.js";
3
+ import { view } from "../../features/views/view.js";
4
+ import { cssReset } from "../../features/views/css-reset.js";
5
+ import { anims, makeLoader } from "../../features/op/loaders/make-loader.js";
6
+ export const LoadersView = view(use => () => {
7
+ use.name("loaders");
8
+ use.styles(cssReset, styles);
9
+ const op = use.once(() => Op.loading());
10
+ const loaders = use.once(() => Object.entries(anims).map(([key, anim]) => ({
11
+ key,
12
+ loader: makeLoader(anim)
13
+ })));
14
+ return loaders.map(({ key, loader }) => html `
15
+ <div data-anim="${key}">
16
+ <span>${key}</span>
17
+ <span>${loader(op, () => null)}</span>
18
+ </div>
19
+ `);
20
+ });
21
+ const styles = css `
22
+ :host {
23
+ display: flex;
24
+ flex-direction: row;
25
+ justify-content: center;
26
+ flex-wrap: wrap;
27
+
28
+ gap: 0.2em;
29
+ padding: 1em;
30
+
31
+ width: 100%;
32
+ }
33
+
34
+ div {
35
+ font-family: monospace;
36
+
37
+ display: flex;
38
+ flex-direction: column;
39
+ align-items: center;
40
+ gap: 0.4em;
41
+
42
+ padding: 0.2em 0.5em;
43
+ background: var(--pill);
44
+ border-radius: 0.5em;
45
+
46
+ span:nth-child(1) { font-size: 0.6em; }
47
+ span:nth-child(2) { font-size: 1.2em; }
48
+ }
49
+ `;
50
+ //# sourceMappingURL=loaders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loaders.js","sourceRoot":"","sources":["../../../s/demo/views/loaders.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,GAAG,EAAE,IAAI,EAAC,MAAM,KAAK,CAAA;AAC7B,OAAO,EAAC,EAAE,EAAC,MAAM,yBAAyB,CAAA;AAC1C,OAAO,EAAC,IAAI,EAAC,MAAM,8BAA8B,CAAA;AACjD,OAAO,EAAC,QAAQ,EAAC,MAAM,mCAAmC,CAAA;AAC1D,OAAO,EAAC,KAAK,EAAE,UAAU,EAAC,MAAM,0CAA0C,CAAA;AAE1E,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE;IAC3C,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACnB,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IAE5B,MAAM,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;IAEvC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,CAC7B,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3C,GAAG;QACH,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC;KACxB,CAAC,CAAC,CACH,CAAA;IAED,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,EAAC,GAAG,EAAE,MAAM,EAAC,EAAE,EAAE,CAAC,IAAI,CAAA;oBACvB,GAAG;WACZ,GAAG;WACH,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC;;EAE/B,CAAC,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,MAAM,MAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BjB,CAAA"}
@@ -1,8 +1,9 @@
1
- export declare const $: typeof one;
2
- export type Queryable = HTMLElement | Document | ShadowRoot | Element;
3
- declare function one<E extends HTMLElement = HTMLElement>(selector: string, context?: Queryable): E;
4
- declare namespace one {
1
+ import { Content } from "../views/types.js";
2
+ export type Container = HTMLElement | ShadowRoot | DocumentFragment;
3
+ export type Queryable = HTMLElement | ShadowRoot | Element | Document | DocumentFragment;
4
+ export declare function $<E extends HTMLElement = HTMLElement>(selector: string, context?: Queryable): E;
5
+ export declare namespace $ {
5
6
  var maybe: <E extends HTMLElement = HTMLElement>(selector: string, context?: Queryable) => E | null;
6
7
  var all: <E extends HTMLElement = HTMLElement>(selector: string, context?: Queryable) => E[];
8
+ var render: (container: Container, ...content: Content[]) => import("lit-html").RootPart;
7
9
  }
8
- export {};
@@ -1,15 +1,16 @@
1
- export const $ = one;
2
- function all(selector, context = document) {
3
- return Array.from(context.querySelectorAll(selector));
4
- }
5
- function one(selector, context = document) {
1
+ import { render } from "lit";
2
+ export function $(selector, context = document) {
6
3
  const e = context.querySelector(selector);
7
4
  if (!e)
8
5
  throw new Error(`$1 ${selector} not found`);
9
6
  return e;
10
7
  }
11
- one.maybe = (selector, context = document) => {
8
+ function all(selector, context = document) {
9
+ return Array.from(context.querySelectorAll(selector));
10
+ }
11
+ $.maybe = (selector, context = document) => {
12
12
  return context.querySelector(selector);
13
13
  };
14
- one.all = all;
14
+ $.all = all;
15
+ $.render = (container, ...content) => render(content, container);
15
16
  //# sourceMappingURL=dollar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dollar.js","sourceRoot":"","sources":["../../../s/features/dom/dollar.ts"],"names":[],"mappings":"AACA,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,CAAA;AAIpB,SAAS,GAAG,CAAsC,QAAgB,EAAE,UAAqB,QAAQ;IAChG,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAI,QAAQ,CAAC,CAAC,CAAA;AACzD,CAAC;AAED,SAAS,GAAG,CAAsC,QAAgB,EAAE,UAAqB,QAAQ;IAChG,MAAM,CAAC,GAAG,OAAO,CAAC,aAAa,CAAI,QAAQ,CAAC,CAAA;IAC5C,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,MAAM,QAAQ,YAAY,CAAC,CAAA;IACnD,OAAO,CAAC,CAAA;AACT,CAAC;AAED,GAAG,CAAC,KAAK,GAAG,CAAsC,QAAgB,EAAE,UAAqB,QAAQ,EAAE,EAAE;IACpG,OAAO,OAAO,CAAC,aAAa,CAAI,QAAQ,CAAC,CAAA;AAC1C,CAAC,CAAA;AAED,GAAG,CAAC,GAAG,GAAG,GAAG,CAAA"}
1
+ {"version":3,"file":"dollar.js","sourceRoot":"","sources":["../../../s/features/dom/dollar.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,MAAM,EAAC,MAAM,KAAK,CAAA;AAM1B,MAAM,UAAU,CAAC,CAAsC,QAAgB,EAAE,UAAqB,QAAQ;IACrG,MAAM,CAAC,GAAG,OAAO,CAAC,aAAa,CAAI,QAAQ,CAAC,CAAA;IAC5C,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,MAAM,QAAQ,YAAY,CAAC,CAAA;IACnD,OAAO,CAAC,CAAA;AACT,CAAC;AAED,SAAS,GAAG,CAAsC,QAAgB,EAAE,UAAqB,QAAQ;IAChG,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAI,QAAQ,CAAC,CAAC,CAAA;AACzD,CAAC;AAED,CAAC,CAAC,KAAK,GAAG,CAAsC,QAAgB,EAAE,UAAqB,QAAQ,EAAE,EAAE;IAClG,OAAO,OAAO,CAAC,aAAa,CAAI,QAAQ,CAAC,CAAA;AAC1C,CAAC,CAAA;AAED,CAAC,CAAC,GAAG,GAAG,GAAG,CAAA;AAEX,CAAC,CAAC,MAAM,GAAG,CAAC,SAAoB,EAAE,GAAG,OAAkB,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { Op } from "../op.js";
2
+ import { Content } from "../../views/types.js";
3
+ export * as anims from "./parts/anims.js";
4
+ export type Loader = <V>(op: Op<V>, ready: (value: V) => Content) => Content;
5
+ export declare function makeLoader(loading?: () => Content, error?: (error: any) => Content): Loader;
@@ -0,0 +1,7 @@
1
+ import { braille } from "./parts/anims.js";
2
+ import { ErrorDisplay } from "./parts/error-display.js";
3
+ export * as anims from "./parts/anims.js";
4
+ export function makeLoader(loading = braille, error = (error) => ErrorDisplay(error)) {
5
+ return (op, ready) => op.select({ loading, ready, error });
6
+ }
7
+ //# sourceMappingURL=make-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"make-loader.js","sourceRoot":"","sources":["../../../../s/features/op/loaders/make-loader.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,OAAO,EAAC,MAAM,kBAAkB,CAAA;AAExC,OAAO,EAAC,YAAY,EAAC,MAAM,0BAA0B,CAAA;AAErD,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAA;AAIzC,MAAM,UAAU,UAAU,CACxB,UAAyB,OAAO,EAChC,QAAiC,CAAC,KAAU,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC;IAGrE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAC,CAAC,CAAA;AACzD,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { Content } from "../../../views/types.js";
2
+ export declare const spinner: () => Content;
3
+ export declare const braille: () => Content;
4
+ export declare const arrow: () => Content;
5
+ export declare const arrow2: () => Content;
6
+ export declare const bar: () => Content;
7
+ export declare const bar2: () => Content;
8
+ export declare const bar3: () => Content;
9
+ export declare const bar4: () => Content;
10
+ export declare const pie: () => Content;
11
+ export declare const cylon: () => Content;
12
+ export declare const slider: () => Content;
13
+ export declare const scrubber: () => Content;
14
+ export declare const pulse: () => Content;
15
+ export declare const bin: () => Content;
16
+ export declare const binary: () => Content;
17
+ export declare const binary2: () => Content;
18
+ export declare const clock: () => Content;
19
+ export declare const fistbump: () => Content;
20
+ export declare const earth: () => Content;
21
+ export declare const lock: () => Content;
22
+ export declare const bright: () => Content;
23
+ export declare const speaker: () => Content;
24
+ export declare const moon: () => Content;
@@ -0,0 +1,251 @@
1
+ import { makeAsciiAnim } from "./ascii-anim.js";
2
+ const hz = 20;
3
+ export const spinner = makeAsciiAnim(hz, [
4
+ "|",
5
+ "/",
6
+ "-",
7
+ "\\",
8
+ ]);
9
+ export const braille = makeAsciiAnim(hz, [
10
+ "⠈",
11
+ "⠐",
12
+ "⠠",
13
+ "⢀",
14
+ "⡀",
15
+ "⠄",
16
+ "⠂",
17
+ "⠁",
18
+ ]);
19
+ export const arrow = makeAsciiAnim(hz, [
20
+ "←",
21
+ "↖",
22
+ "↑",
23
+ "↗",
24
+ "→",
25
+ "↘",
26
+ "↓",
27
+ "↙",
28
+ ]);
29
+ export const arrow2 = makeAsciiAnim(hz, [
30
+ "⬆️",
31
+ "↗️",
32
+ "➡️",
33
+ "↘️",
34
+ "⬇️",
35
+ "↙️",
36
+ "⬅️",
37
+ "↖️",
38
+ ]);
39
+ export const bar = makeAsciiAnim(hz, [
40
+ "▰▱▱▱▱",
41
+ "▰▱▱▱▱",
42
+ "▱▰▱▱▱",
43
+ "▱▱▰▱▱",
44
+ "▱▱▱▰▱",
45
+ "▱▱▱▱▰",
46
+ "▱▱▱▱▰",
47
+ "▱▱▱▰▱",
48
+ "▱▱▰▱▱",
49
+ "▱▰▱▱▱",
50
+ ]);
51
+ export const bar2 = makeAsciiAnim(hz, [
52
+ "▱▱▰▱▱",
53
+ "▱▱▱▰▱",
54
+ "▱▱▱▰▰",
55
+ "▱▱▱▰▰",
56
+ "▱▱▱▱▰",
57
+ "▱▱▱▱▰",
58
+ "▱▱▱▱▰",
59
+ "▱▱▱▰▰",
60
+ "▱▱▱▰▰",
61
+ "▱▱▱▰▱",
62
+ "▱▱▰▱▱",
63
+ "▱▰▱▱▱",
64
+ "▰▰▱▱▱",
65
+ "▰▰▱▱▱",
66
+ "▰▱▱▱▱",
67
+ "▰▱▱▱▱",
68
+ "▰▱▱▱▱",
69
+ "▰▰▱▱▱",
70
+ "▰▰▱▱▱",
71
+ "▱▰▱▱▱",
72
+ ]);
73
+ export const bar3 = makeAsciiAnim(hz, [
74
+ "▰▱▱▱▱",
75
+ "▰▱▱▱▱",
76
+ "▰▰▱▱▱",
77
+ "▰▰▰▱▱",
78
+ "▱▰▰▰▱",
79
+ "▱▱▰▰▰",
80
+ "▱▱▱▰▰",
81
+ "▱▱▱▱▰",
82
+ "▱▱▱▱▰",
83
+ "▱▱▱▰▰",
84
+ "▱▱▰▰▰",
85
+ "▱▰▰▰▱",
86
+ "▰▰▰▱▱",
87
+ "▰▰▱▱▱",
88
+ ]);
89
+ export const bar4 = makeAsciiAnim(hz, [
90
+ "▱▱▱▱▱",
91
+ "▰▱▱▱▱",
92
+ "▰▰▱▱▱",
93
+ "▰▰▰▱▱",
94
+ "▰▰▰▰▱",
95
+ "▰▰▰▰▰",
96
+ "▰▰▰▰▰",
97
+ "▱▰▰▰▰",
98
+ "▱▱▰▰▰",
99
+ "▱▱▱▰▰",
100
+ "▱▱▱▱▰",
101
+ ]);
102
+ export const pie = makeAsciiAnim(hz, [
103
+ "◷",
104
+ "◶",
105
+ "◵",
106
+ "◴",
107
+ ]);
108
+ export const cylon = makeAsciiAnim(hz, [
109
+ "=----",
110
+ "-=---",
111
+ "--=--",
112
+ "---=-",
113
+ "----=",
114
+ "----=",
115
+ "---=-",
116
+ "--=--",
117
+ "-=---",
118
+ "=----",
119
+ ]);
120
+ export const slider = makeAsciiAnim(hz, [
121
+ "o----",
122
+ "-o---",
123
+ "--o--",
124
+ "---o-",
125
+ "----o",
126
+ "----o",
127
+ "---o-",
128
+ "--o--",
129
+ "-o---",
130
+ "o----",
131
+ ]);
132
+ export const scrubber = makeAsciiAnim(hz, [
133
+ ":....",
134
+ ":....",
135
+ "::...",
136
+ ".::..",
137
+ "..::.",
138
+ "...::",
139
+ "....:",
140
+ "....:",
141
+ "...::",
142
+ "..::.",
143
+ ".::..",
144
+ "::...",
145
+ ]);
146
+ export const pulse = makeAsciiAnim(hz, [
147
+ ".....",
148
+ ".....",
149
+ "..:..",
150
+ ".:::.",
151
+ ".:::.",
152
+ ":::::",
153
+ ":::::",
154
+ "::.::",
155
+ ":...:",
156
+ ]);
157
+ export const bin = makeAsciiAnim(hz, [
158
+ "000",
159
+ "100",
160
+ "110",
161
+ "111",
162
+ "011",
163
+ "001",
164
+ ]);
165
+ export const binary = makeAsciiAnim(hz, [
166
+ "11111",
167
+ "01111",
168
+ "00111",
169
+ "10011",
170
+ "11001",
171
+ "01100",
172
+ "00110",
173
+ "10011",
174
+ "11001",
175
+ "11100",
176
+ "11110",
177
+ ]);
178
+ export const binary2 = makeAsciiAnim(hz, [
179
+ "11111",
180
+ "01111",
181
+ "10111",
182
+ "11011",
183
+ "11101",
184
+ "11110",
185
+ "11111",
186
+ "11110",
187
+ "11101",
188
+ "11011",
189
+ "10111",
190
+ "01111",
191
+ ]);
192
+ export const clock = makeAsciiAnim(hz, [
193
+ "🕐",
194
+ "🕑",
195
+ "🕒",
196
+ "🕓",
197
+ "🕔",
198
+ "🕕",
199
+ "🕖",
200
+ "🕗",
201
+ "🕘",
202
+ "🕙",
203
+ "🕚",
204
+ "🕛",
205
+ ]);
206
+ export const fistbump = makeAsciiAnim(hz, [
207
+ "🤜 🤛",
208
+ "🤜 🤛",
209
+ "🤜 🤛",
210
+ " 🤜 🤛 ",
211
+ " 🤜🤛 ",
212
+ " 🤜🤛 ",
213
+ " 🤜💥🤛 ",
214
+ "🤜 💥 🤛",
215
+ "🤜 ✨ 🤛",
216
+ "🤜 ✨ 🤛",
217
+ ]);
218
+ export const earth = makeAsciiAnim(4, [
219
+ "🌎",
220
+ "🌏",
221
+ "🌍",
222
+ ]);
223
+ export const lock = makeAsciiAnim(4, [
224
+ "🔓",
225
+ "🔒",
226
+ ]);
227
+ export const bright = makeAsciiAnim(4, [
228
+ "🔅",
229
+ "🔆",
230
+ ]);
231
+ export const speaker = makeAsciiAnim(4, [
232
+ "🔈",
233
+ "🔈",
234
+ "🔉",
235
+ "🔊",
236
+ "🔊",
237
+ "🔉",
238
+ ]);
239
+ export const moon = makeAsciiAnim(10, [
240
+ "🌑",
241
+ "🌑",
242
+ "🌑",
243
+ "🌘",
244
+ "🌗",
245
+ "🌖",
246
+ "🌕",
247
+ "🌔",
248
+ "🌓",
249
+ "🌒",
250
+ ]);
251
+ //# sourceMappingURL=anims.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anims.js","sourceRoot":"","sources":["../../../../../s/features/op/loaders/parts/anims.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Content } from "../../../views/types.js";
2
+ export declare function makeAsciiAnim(hz: number, frames: string[]): () => Content;
3
+ export declare const AsciiAnim: import("../../../views/types.js").View<[{
4
+ hz: number;
5
+ frames: string[];
6
+ }]>;
@@ -0,0 +1,26 @@
1
+ import { css } from "lit";
2
+ import { nap, repeat } from "@e280/stz";
3
+ import { view } from "../../../views/view.js";
4
+ import { cssReset } from "../../../views/css-reset.js";
5
+ export function makeAsciiAnim(hz, frames) {
6
+ return () => AsciiAnim({ hz, frames });
7
+ }
8
+ export const AsciiAnim = view(use => ({ hz, frames }) => {
9
+ use.name("loading");
10
+ use.styles(cssReset, style);
11
+ const frame = use.signal(0);
12
+ use.mount(() => repeat(async () => {
13
+ await nap(1000 / hz);
14
+ const next = frame() + 1;
15
+ frame(next >= frames.length ? 0 : next);
16
+ }));
17
+ return frames.at(frame());
18
+ });
19
+ const style = css `
20
+ :host {
21
+ font-family: monospace;
22
+ white-space: pre;
23
+ user-select: none;
24
+ }
25
+ `;
26
+ //# sourceMappingURL=ascii-anim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ascii-anim.js","sourceRoot":"","sources":["../../../../../s/features/op/loaders/parts/ascii-anim.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,GAAG,EAAC,MAAM,KAAK,CAAA;AACvB,OAAO,EAAC,GAAG,EAAE,MAAM,EAAC,MAAM,WAAW,CAAA;AAErC,OAAO,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAA;AAE3C,OAAO,EAAC,QAAQ,EAAC,MAAM,6BAA6B,CAAA;AAEpD,MAAM,UAAU,aAAa,CAAC,EAAU,EAAE,MAAgB;IACzD,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,EAAC,EAAE,EAAE,MAAM,EAAC,CAAC,CAAA;AACrC,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAC,EAAE,EAAE,MAAM,EAG/C,EAAE,EAAE;IAEL,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACnB,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;IAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IAE3B,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,IAAG,EAAE;QAChC,MAAM,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAA;QACpB,MAAM,IAAI,GAAG,KAAK,EAAE,GAAG,CAAC,CAAA;QACxB,KAAK,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IACxC,CAAC,CAAC,CAAC,CAAA;IAEH,OAAO,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAA;AAC1B,CAAC,CAAC,CAAA;AAEF,MAAM,KAAK,GAAG,GAAG,CAAA;;;;;;CAMhB,CAAA"}
@@ -0,0 +1 @@
1
+ export declare const ErrorDisplay: import("../../../views/types.js").View<[error: any]>;
@@ -1,14 +1,8 @@
1
1
  import { css, html } from "lit";
2
- import { view } from "../../views/view.js";
3
- import { cssReset } from "../../views/css-reset.js";
4
- const style = css `
5
- :host {
6
- font-family: monospace;
7
- color: red;
8
- }
9
- `;
2
+ import { view } from "../../../views/view.js";
3
+ import { cssReset } from "../../../views/css-reset.js";
10
4
  export const ErrorDisplay = view(use => (error) => {
11
- use.name("loading");
5
+ use.name("error");
12
6
  use.styles(cssReset, style);
13
7
  if (typeof error === "string")
14
8
  return error;
@@ -17,4 +11,10 @@ export const ErrorDisplay = view(use => (error) => {
17
11
  else
18
12
  return `error`;
19
13
  });
14
+ const style = css `
15
+ :host {
16
+ font-family: monospace;
17
+ color: red;
18
+ }
19
+ `;
20
20
  //# sourceMappingURL=error-display.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-display.js","sourceRoot":"","sources":["../../../../../s/features/op/loaders/parts/error-display.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,GAAG,EAAE,IAAI,EAAC,MAAM,KAAK,CAAA;AAC7B,OAAO,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAA;AAC3C,OAAO,EAAC,QAAQ,EAAC,MAAM,6BAA6B,CAAA;AAEpD,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAU,EAAE,EAAE;IACtD,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACjB,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;IAE3B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAC5B,OAAO,KAAK,CAAA;SAER,IAAI,KAAK,YAAY,KAAK;QAC9B,OAAO,IAAI,CAAA,WAAW,KAAK,CAAC,IAAI,oBAAoB,KAAK,CAAC,OAAO,SAAS,CAAA;;QAG1E,OAAO,OAAO,CAAA;AAChB,CAAC,CAAC,CAAA;AAEF,MAAM,KAAK,GAAG,GAAG,CAAA;;;;;CAKhB,CAAA"}
@@ -1,12 +1,15 @@
1
+ import { Signal } from "@e280/strata/signals";
1
2
  import { Pod, PodSelect } from "./types.js";
2
3
  export declare class Op<V> {
3
4
  #private;
4
- static loading(): Op<unknown>;
5
+ static loading<V>(): Op<V>;
5
6
  static ready<V>(value: V): Op<V>;
6
- static error(error: any): Op<unknown>;
7
+ static error<V>(error: any): Op<V>;
7
8
  static promise<V>(promise: Promise<V>): Op<V>;
8
9
  static fn<V>(fn: () => Promise<V>): Op<V>;
9
- readonly signal: import("@e280/strata/signals").Signal<Pod<V>>;
10
+ static all<V>(...ops: Op<V>[]): Op<V[]>;
11
+ readonly signal: Signal<Pod<V>>;
12
+ constructor(pod?: Pod<V>);
10
13
  get wait(): Promise<unknown>;
11
14
  setLoading(): Promise<void>;
12
15
  setReady(value: V): Promise<void>;
@@ -14,8 +17,14 @@ export declare class Op<V> {
14
17
  promise(promise: Promise<V>): Promise<V | undefined>;
15
18
  fn(fn: () => Promise<V>): Promise<V | undefined>;
16
19
  get pod(): Pod<V>;
20
+ set pod(p: Pod<V>);
17
21
  get status(): "loading" | "ready" | "error";
18
22
  get value(): V | undefined;
23
+ get error(): any;
24
+ get isLoading(): boolean;
25
+ get isReady(): boolean;
26
+ get isError(): boolean;
19
27
  require(): V;
20
28
  select<R>(select: PodSelect<V, R>): R;
29
+ morph<V2>(fn: (value: V) => V2): Op<V2>;
21
30
  }