@e280/sly 0.2.0-8 → 0.2.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 (293) hide show
  1. package/README.md +400 -98
  2. package/package.json +14 -7
  3. package/s/base/element.ts +76 -0
  4. package/s/base/index.ts +6 -0
  5. package/s/{views → base}/use.ts +22 -14
  6. package/s/base/utils/attr-watcher.ts +22 -0
  7. package/s/base/utils/reactor.ts +32 -0
  8. package/s/base/utils/states.ts +49 -0
  9. package/s/base/utils/use-attrs.ts +36 -0
  10. package/s/demo/demo.bundle.ts +6 -7
  11. package/s/demo/views/counter.ts +21 -24
  12. package/s/demo/views/demo.ts +9 -6
  13. package/s/demo/views/{incredi.ts → fastcount.ts} +7 -6
  14. package/s/demo/views/loaders.ts +7 -7
  15. package/s/dom/attrs/attrs.ts +21 -0
  16. package/s/dom/attrs/parts/attr-fns.ts +68 -0
  17. package/s/dom/attrs/parts/attr-proxies.ts +35 -0
  18. package/s/dom/attrs/parts/attr-spec.ts +29 -0
  19. package/s/dom/attrs/parts/on-attrs.ts +8 -0
  20. package/s/dom/dom.ts +23 -60
  21. package/s/dom/index.ts +4 -0
  22. package/s/dom/parts/dom-scope.ts +46 -0
  23. package/s/dom/parts/el.ts +14 -0
  24. package/s/dom/parts/elmer.ts +38 -0
  25. package/s/dom/parts/eve.ts +24 -0
  26. package/s/dom/parts/mk.ts +9 -0
  27. package/s/dom/parts/queries.ts +26 -0
  28. package/s/dom/{register.ts → parts/register.ts} +2 -10
  29. package/s/dom/types.ts +50 -0
  30. package/s/index.html.ts +4 -3
  31. package/s/index.ts +7 -20
  32. package/s/loaders/index.barrel.ts +10 -0
  33. package/s/loaders/index.ts +4 -0
  34. package/s/loaders/make.ts +14 -0
  35. package/s/loaders/mock.ts +11 -0
  36. package/s/{ops/loaders → loaders}/parts/anims.ts +1 -1
  37. package/s/{ops/loaders → loaders}/parts/ascii-anim.ts +6 -5
  38. package/s/{ops/loaders → loaders}/parts/error-display.ts +2 -2
  39. package/s/loaders/types.ts +6 -0
  40. package/s/loot/index.barrel.ts +5 -0
  41. package/s/loot/index.ts +2 -3
  42. package/s/ops/index.ts +5 -0
  43. package/s/ops/op.ts +1 -0
  44. package/s/spa/index.barrel.ts +6 -0
  45. package/s/spa/index.ts +4 -0
  46. package/s/spa/plumbing/braces.ts +76 -0
  47. package/s/spa/plumbing/primitives.ts +85 -0
  48. package/s/spa/plumbing/router-core.ts +49 -0
  49. package/s/spa/plumbing/types.ts +45 -0
  50. package/s/spa/router.ts +49 -0
  51. package/s/spa/spa.test.ts +91 -0
  52. package/s/tests.test.ts +4 -1
  53. package/s/view/index.ts +7 -0
  54. package/s/view/types.ts +39 -0
  55. package/s/view/utils/contextualize.ts +45 -0
  56. package/s/view/utils/make-component.ts +34 -0
  57. package/s/view/utils/make-view.ts +48 -0
  58. package/s/view/utils/parts/capsule.ts +67 -0
  59. package/s/view/utils/parts/chain.ts +40 -0
  60. package/s/view/utils/parts/context.ts +11 -0
  61. package/s/view/utils/parts/directive.ts +29 -0
  62. package/s/view/utils/parts/sly-view.ts +15 -0
  63. package/s/view/view.ts +24 -0
  64. package/x/base/css-reset.js.map +1 -0
  65. package/x/base/element.d.ts +19 -0
  66. package/x/base/element.js +52 -0
  67. package/x/base/element.js.map +1 -0
  68. package/x/base/index.d.ts +4 -0
  69. package/x/base/index.js +5 -0
  70. package/x/base/index.js.map +1 -0
  71. package/x/{views → base}/use.d.ts +6 -2
  72. package/x/{views → base}/use.js +13 -8
  73. package/x/base/use.js.map +1 -0
  74. package/x/base/utils/apply-styles.js.map +1 -0
  75. package/x/base/utils/attr-watcher.d.ts +8 -0
  76. package/x/base/utils/attr-watcher.js +20 -0
  77. package/x/base/utils/attr-watcher.js.map +1 -0
  78. package/x/base/utils/mounts.js.map +1 -0
  79. package/x/base/utils/reactor.d.ts +5 -0
  80. package/x/base/utils/reactor.js +25 -0
  81. package/x/base/utils/reactor.js.map +1 -0
  82. package/x/base/utils/states.d.ts +13 -0
  83. package/x/base/utils/states.js +41 -0
  84. package/x/base/utils/states.js.map +1 -0
  85. package/x/base/utils/use-attrs.d.ts +11 -0
  86. package/x/base/utils/use-attrs.js +18 -0
  87. package/x/base/utils/use-attrs.js.map +1 -0
  88. package/x/demo/demo.bundle.js +6 -6
  89. package/x/demo/demo.bundle.js.map +1 -1
  90. package/x/demo/demo.bundle.min.js +17 -23
  91. package/x/demo/demo.bundle.min.js.map +4 -4
  92. package/x/demo/views/counter.d.ts +374 -1
  93. package/x/demo/views/counter.js +19 -22
  94. package/x/demo/views/counter.js.map +1 -1
  95. package/x/demo/views/demo.d.ts +4 -1
  96. package/x/demo/views/demo.js +9 -5
  97. package/x/demo/views/demo.js.map +1 -1
  98. package/x/demo/views/{incredi.d.ts → fastcount.d.ts} +3 -3
  99. package/x/demo/views/{incredi.js → fastcount.js} +6 -6
  100. package/x/demo/views/fastcount.js.map +1 -0
  101. package/x/demo/views/loaders.js +6 -6
  102. package/x/demo/views/loaders.js.map +1 -1
  103. package/x/dom/attrs/attrs.d.ts +23 -0
  104. package/x/dom/attrs/attrs.js +17 -0
  105. package/x/dom/attrs/attrs.js.map +1 -0
  106. package/x/dom/attrs/parts/attr-fns.d.ts +16 -0
  107. package/x/dom/attrs/parts/attr-fns.js +64 -0
  108. package/x/dom/attrs/parts/attr-fns.js.map +1 -0
  109. package/x/dom/attrs/parts/attr-proxies.d.ts +8 -0
  110. package/x/dom/attrs/parts/attr-proxies.js +21 -0
  111. package/x/dom/attrs/parts/attr-proxies.js.map +1 -0
  112. package/x/dom/attrs/parts/attr-spec.d.ts +3 -0
  113. package/x/dom/attrs/parts/attr-spec.js +21 -0
  114. package/x/dom/attrs/parts/attr-spec.js.map +1 -0
  115. package/x/dom/attrs/parts/on-attrs.d.ts +2 -0
  116. package/x/dom/attrs/parts/on-attrs.js +7 -0
  117. package/x/dom/attrs/parts/on-attrs.js.map +1 -0
  118. package/x/dom/dom.d.ts +16 -22
  119. package/x/dom/dom.js +21 -47
  120. package/x/dom/dom.js.map +1 -1
  121. package/x/dom/index.d.ts +2 -0
  122. package/x/dom/index.js +3 -0
  123. package/x/dom/index.js.map +1 -0
  124. package/x/dom/parts/dashify.js.map +1 -0
  125. package/x/dom/parts/dom-scope.d.ts +15 -0
  126. package/x/dom/parts/dom-scope.js +35 -0
  127. package/x/dom/parts/dom-scope.js.map +1 -0
  128. package/x/dom/parts/el.d.ts +2 -0
  129. package/x/dom/parts/el.js +7 -0
  130. package/x/dom/parts/el.js.map +1 -0
  131. package/x/dom/parts/elmer.d.ts +11 -0
  132. package/x/dom/parts/elmer.js +32 -0
  133. package/x/dom/parts/elmer.js.map +1 -0
  134. package/x/dom/parts/eve.d.ts +7 -0
  135. package/x/dom/parts/eve.js +16 -0
  136. package/x/dom/parts/eve.js.map +1 -0
  137. package/x/dom/parts/mk.d.ts +2 -0
  138. package/x/dom/parts/mk.js +7 -0
  139. package/x/dom/parts/mk.js.map +1 -0
  140. package/x/dom/parts/queries.d.ts +4 -0
  141. package/x/dom/parts/queries.js +13 -0
  142. package/x/dom/parts/queries.js.map +1 -0
  143. package/x/dom/{register.d.ts → parts/register.d.ts} +2 -10
  144. package/x/dom/parts/register.js.map +1 -0
  145. package/x/dom/types.d.ts +22 -0
  146. package/x/{views → dom}/types.js.map +1 -1
  147. package/x/index.d.ts +7 -17
  148. package/x/index.html +6 -5
  149. package/x/index.html.js +4 -3
  150. package/x/index.html.js.map +1 -1
  151. package/x/index.js +7 -17
  152. package/x/index.js.map +1 -1
  153. package/x/loaders/index.barrel.d.ts +7 -0
  154. package/x/loaders/index.barrel.js +7 -0
  155. package/x/loaders/index.barrel.js.map +1 -0
  156. package/x/loaders/index.d.ts +2 -0
  157. package/x/loaders/index.js +2 -0
  158. package/x/loaders/index.js.map +1 -0
  159. package/x/loaders/make.d.ts +3 -0
  160. package/x/loaders/make.js +6 -0
  161. package/x/loaders/make.js.map +1 -0
  162. package/x/loaders/mock.d.ts +2 -0
  163. package/x/loaders/mock.js +8 -0
  164. package/x/loaders/mock.js.map +1 -0
  165. package/x/{ops/loaders → loaders}/parts/anims.d.ts +1 -1
  166. package/x/loaders/parts/anims.js.map +1 -0
  167. package/x/{ops/loaders → loaders}/parts/ascii-anim.d.ts +2 -2
  168. package/x/{ops/loaders → loaders}/parts/ascii-anim.js +4 -4
  169. package/x/loaders/parts/ascii-anim.js.map +1 -0
  170. package/x/loaders/parts/error-display.d.ts +1 -0
  171. package/x/{ops/loaders → loaders}/parts/error-display.js +2 -2
  172. package/x/loaders/parts/error-display.js.map +1 -0
  173. package/x/loaders/types.d.ts +3 -0
  174. package/x/loaders/types.js +2 -0
  175. package/x/loaders/types.js.map +1 -0
  176. package/x/loot/index.barrel.d.ts +3 -0
  177. package/x/loot/index.barrel.js +4 -0
  178. package/x/loot/index.barrel.js.map +1 -0
  179. package/x/loot/index.d.ts +2 -3
  180. package/x/loot/index.js +1 -3
  181. package/x/loot/index.js.map +1 -1
  182. package/x/ops/index.d.ts +3 -0
  183. package/x/ops/index.js +4 -0
  184. package/x/ops/index.js.map +1 -0
  185. package/x/ops/op.js +1 -0
  186. package/x/ops/op.js.map +1 -1
  187. package/x/spa/index.barrel.d.ts +4 -0
  188. package/x/spa/index.barrel.js +3 -0
  189. package/x/spa/index.barrel.js.map +1 -0
  190. package/x/spa/index.d.ts +2 -0
  191. package/x/spa/index.js +2 -0
  192. package/x/spa/index.js.map +1 -0
  193. package/x/spa/plumbing/braces.d.ts +12 -0
  194. package/x/spa/plumbing/braces.js +55 -0
  195. package/x/spa/plumbing/braces.js.map +1 -0
  196. package/x/spa/plumbing/primitives.d.ts +22 -0
  197. package/x/spa/plumbing/primitives.js +65 -0
  198. package/x/spa/plumbing/primitives.js.map +1 -0
  199. package/x/spa/plumbing/router-core.d.ts +13 -0
  200. package/x/spa/plumbing/router-core.js +38 -0
  201. package/x/spa/plumbing/router-core.js.map +1 -0
  202. package/x/spa/plumbing/types.d.ts +35 -0
  203. package/x/spa/plumbing/types.js +2 -0
  204. package/x/spa/plumbing/types.js.map +1 -0
  205. package/x/spa/router.d.ts +13 -0
  206. package/x/spa/router.js +39 -0
  207. package/x/spa/router.js.map +1 -0
  208. package/x/spa/spa.test.d.ts +15 -0
  209. package/x/spa/spa.test.js +78 -0
  210. package/x/spa/spa.test.js.map +1 -0
  211. package/x/tests.test.js +4 -1
  212. package/x/tests.test.js.map +1 -1
  213. package/x/view/index.d.ts +5 -0
  214. package/x/view/index.js +6 -0
  215. package/x/view/index.js.map +1 -0
  216. package/x/view/types.d.ts +21 -0
  217. package/x/view/types.js +2 -0
  218. package/x/view/types.js.map +1 -0
  219. package/x/view/utils/contextualize.d.ts +13 -0
  220. package/x/view/utils/contextualize.js +18 -0
  221. package/x/view/utils/contextualize.js.map +1 -0
  222. package/x/view/utils/make-component.d.ts +5 -0
  223. package/x/view/utils/make-component.js +17 -0
  224. package/x/view/utils/make-component.js.map +1 -0
  225. package/x/view/utils/make-view.d.ts +2 -0
  226. package/x/view/utils/make-view.js +24 -0
  227. package/x/view/utils/make-view.js.map +1 -0
  228. package/x/view/utils/parts/capsule.d.ts +13 -0
  229. package/x/view/utils/parts/capsule.js +49 -0
  230. package/x/view/utils/parts/capsule.js.map +1 -0
  231. package/x/view/utils/parts/chain.d.ts +13 -0
  232. package/x/view/utils/parts/chain.js +26 -0
  233. package/x/view/utils/parts/chain.js.map +1 -0
  234. package/x/view/utils/parts/context.d.ts +9 -0
  235. package/x/view/utils/parts/context.js +10 -0
  236. package/x/view/utils/parts/context.js.map +1 -0
  237. package/x/view/utils/parts/directive.d.ts +5 -0
  238. package/x/view/utils/parts/directive.js +18 -0
  239. package/x/view/utils/parts/directive.js.map +1 -0
  240. package/x/view/utils/parts/sly-view.d.ts +5 -0
  241. package/x/view/utils/parts/sly-view.js +13 -0
  242. package/x/view/utils/parts/sly-view.js.map +1 -0
  243. package/x/view/view.d.ts +11 -0
  244. package/x/view/view.js +15 -0
  245. package/x/view/view.js.map +1 -0
  246. package/s/dom/attributes.ts +0 -89
  247. package/s/ops/loaders/make-loader.ts +0 -18
  248. package/s/views/base-element.ts +0 -84
  249. package/s/views/types.ts +0 -40
  250. package/s/views/utils/apply-attrs.ts +0 -33
  251. package/s/views/view.ts +0 -150
  252. package/x/demo/views/incredi.js.map +0 -1
  253. package/x/dom/attributes.d.ts +0 -10
  254. package/x/dom/attributes.js +0 -46
  255. package/x/dom/attributes.js.map +0 -1
  256. package/x/dom/dashify.js.map +0 -1
  257. package/x/dom/register.js.map +0 -1
  258. package/x/ops/loaders/make-loader.d.ts +0 -5
  259. package/x/ops/loaders/make-loader.js +0 -7
  260. package/x/ops/loaders/make-loader.js.map +0 -1
  261. package/x/ops/loaders/parts/anims.js.map +0 -1
  262. package/x/ops/loaders/parts/ascii-anim.js.map +0 -1
  263. package/x/ops/loaders/parts/error-display.d.ts +0 -1
  264. package/x/ops/loaders/parts/error-display.js.map +0 -1
  265. package/x/views/base-element.d.ts +0 -14
  266. package/x/views/base-element.js +0 -62
  267. package/x/views/base-element.js.map +0 -1
  268. package/x/views/css-reset.js.map +0 -1
  269. package/x/views/types.d.ts +0 -31
  270. package/x/views/use.js.map +0 -1
  271. package/x/views/utils/apply-attrs.d.ts +0 -2
  272. package/x/views/utils/apply-attrs.js +0 -21
  273. package/x/views/utils/apply-attrs.js.map +0 -1
  274. package/x/views/utils/apply-styles.js.map +0 -1
  275. package/x/views/utils/mounts.js.map +0 -1
  276. package/x/views/view.d.ts +0 -9
  277. package/x/views/view.js +0 -116
  278. package/x/views/view.js.map +0 -1
  279. /package/s/{views → base}/css-reset.ts +0 -0
  280. /package/s/{views → base}/utils/apply-styles.ts +0 -0
  281. /package/s/{views → base}/utils/mounts.ts +0 -0
  282. /package/s/dom/{dashify.ts → parts/dashify.ts} +0 -0
  283. /package/x/{views → base}/css-reset.d.ts +0 -0
  284. /package/x/{views → base}/css-reset.js +0 -0
  285. /package/x/{views → base}/utils/apply-styles.d.ts +0 -0
  286. /package/x/{views → base}/utils/apply-styles.js +0 -0
  287. /package/x/{views → base}/utils/mounts.d.ts +0 -0
  288. /package/x/{views → base}/utils/mounts.js +0 -0
  289. /package/x/dom/{dashify.d.ts → parts/dashify.d.ts} +0 -0
  290. /package/x/dom/{dashify.js → parts/dashify.js} +0 -0
  291. /package/x/dom/{register.js → parts/register.js} +0 -0
  292. /package/x/{views → dom}/types.js +0 -0
  293. /package/x/{ops/loaders → loaders}/parts/anims.js +0 -0
@@ -0,0 +1,8 @@
1
+
2
+ /** respond when any attribute changes on the html element */
3
+ export function onAttrs(element: HTMLElement, fn: () => void) {
4
+ const observer = new MutationObserver(fn)
5
+ observer.observe(element, {attributes: true})
6
+ return () => observer.disconnect()
7
+ }
8
+
package/s/dom/dom.ts CHANGED
@@ -1,70 +1,33 @@
1
1
 
2
2
  import {render} from "lit"
3
- import {register} from "./register.js"
4
- import {Content} from "../views/types.js"
5
- import {attributes, AttrSpec, AttrTypes} from "./attributes.js"
6
-
7
- export type Renderable = HTMLElement | ShadowRoot | DocumentFragment
8
- export type Queryable = HTMLElement | ShadowRoot | Element | Document | DocumentFragment
9
-
10
- function require<E extends Element>(
11
- container: Queryable,
12
- selector: string,
13
- ) {
14
- const e = container.querySelector<E>(selector)
15
- if (!e) throw new Error(`element not found (${selector})`)
16
- return e
17
- }
18
-
19
- export class Dom<C extends Queryable> {
20
- constructor(public element: C) {}
21
-
22
- in<E extends HTMLElement>(selectorOrElement: string | E) {
23
- return new Dom<E>(
24
- (typeof selectorOrElement === "string")
25
- ? require(this.element, selectorOrElement) as E
26
- : selectorOrElement
27
- )
28
- }
29
-
30
- require<E extends Element = HTMLElement>(selector: string) {
31
- const e = this.element.querySelector<E>(selector)
32
- if (!e) throw new Error(`element not found (${selector})`)
33
- return e
34
- }
35
-
36
- maybe<E extends Element = HTMLElement>(selector: string) {
37
- return this.element.querySelector<E>(selector)
38
- }
39
-
40
- all<E extends Element = HTMLElement>(selector: string) {
41
- return Array.from(this.element.querySelectorAll<E>(selector))
42
- }
43
-
44
- render(...content: Content[]) {
45
- return render(content, this.element as Renderable)
46
- }
47
-
48
- attrs<A extends AttrSpec>(spec: A) {
49
- return attributes(this.element as HTMLElement, spec)
50
- }
3
+ import {el} from "./parts/el.js"
4
+ import {mk} from "./parts/mk.js"
5
+ import {eve} from "./parts/eve.js"
6
+ import {attrs} from "./attrs/attrs.js"
7
+ import {elmer} from "./parts/elmer.js"
8
+ import {Content} from "../view/types.js"
9
+ import {Dom} from "./parts/dom-scope.js"
10
+ import {register} from "./parts/register.js"
11
+ import {Queryable, Renderable} from "./types.js"
12
+ import {queryAll, queryMaybe, queryRequire} from "./parts/queries.js"
13
+
14
+ export function dom<E extends Element>(selector: string, container: Queryable = document): E {
15
+ return queryRequire<E>(selector, container)
51
16
  }
52
17
 
53
- export function dom<E extends Queryable>(selector: string): E
54
- export function dom<E extends Queryable>(element: E): Dom<E>
55
- export function dom<E extends Queryable>(selectorOrElement: string | E): E | Dom<E> {
56
- return (typeof selectorOrElement === "string")
57
- ? require(document, selectorOrElement) as E
58
- : new Dom(selectorOrElement)
18
+ dom.in = <E extends HTMLElement>(selectorOrElement: string | E, container: Queryable = document) => {
19
+ return new Dom(container).in(selectorOrElement)
59
20
  }
60
21
 
61
- const doc = new Dom(document)
62
- dom.in = doc.in.bind(doc)
63
- dom.require = doc.require.bind(doc)
64
- dom.maybe = doc.maybe.bind(doc)
65
- dom.all = doc.all.bind(doc)
22
+ dom.require = queryRequire
23
+ dom.maybe = queryMaybe
24
+ dom.all = queryAll
66
25
 
67
- dom.attrs = attributes
26
+ dom.el = el
27
+ dom.elmer = elmer
28
+ dom.mk = mk
29
+ dom.events = eve
30
+ dom.attrs = attrs
68
31
  dom.register = register
69
32
  dom.render = (container: Renderable, ...content: Content[]) => {
70
33
  return render(content, container)
package/s/dom/index.ts ADDED
@@ -0,0 +1,4 @@
1
+
2
+ export * from "./types.js"
3
+ export * from "./dom.js"
4
+
@@ -0,0 +1,46 @@
1
+
2
+ import {render} from "lit"
3
+ import {eve, EveSpec} from "./eve.js"
4
+ import {attrs} from "../attrs/attrs.js"
5
+ import {Content} from "../../view/types.js"
6
+ import {Attrs, Queryable, Renderable} from "../types.js"
7
+ import {queryAll, queryMaybe, queryRequire} from "./queries.js"
8
+
9
+ export class Dom<C extends Queryable> {
10
+ #attrs?: Attrs
11
+
12
+ constructor(public element: C) {}
13
+
14
+ in<E extends HTMLElement>(selectorOrElement: string | E) {
15
+ return new Dom<E>(
16
+ (typeof selectorOrElement === "string")
17
+ ? queryRequire(selectorOrElement, this.element) as E
18
+ : selectorOrElement
19
+ )
20
+ }
21
+
22
+ require<E extends Element = HTMLElement>(selector: string) {
23
+ return queryRequire<E>(selector, this.element)
24
+ }
25
+
26
+ maybe<E extends Element = HTMLElement>(selector: string) {
27
+ return queryMaybe<E>(selector, this.element)
28
+ }
29
+
30
+ all<E extends Element = HTMLElement>(selector: string) {
31
+ return queryAll<E>(selector, this.element)
32
+ }
33
+
34
+ render(...content: Content[]) {
35
+ return render(content, this.element as Renderable)
36
+ }
37
+
38
+ get attrs(): Attrs {
39
+ return this.#attrs ??= attrs(this.element as HTMLElement)
40
+ }
41
+
42
+ events(spec: EveSpec) {
43
+ return eve(this.element, spec)
44
+ }
45
+ }
46
+
@@ -0,0 +1,14 @@
1
+
2
+ import {AttrValue} from "../types.js"
3
+ import {attrSet} from "../attrs/parts/attr-fns.js"
4
+
5
+ export function el<E extends HTMLElement>(
6
+ tagName: string,
7
+ attrs: Record<string, AttrValue> = {},
8
+ ) {
9
+
10
+ const element = document.createElement(tagName) as E
11
+ attrSet.record(element, attrs)
12
+ return element
13
+ }
14
+
@@ -0,0 +1,38 @@
1
+
2
+ import {AttrValue} from "../types.js"
3
+ import {attrSet} from "../attrs/parts/attr-fns.js"
4
+
5
+ export function elmer<E extends HTMLElement = HTMLElement>(tagName: string) {
6
+ return new Elmer<E>(tagName)
7
+ }
8
+
9
+ export class Elmer<E extends HTMLElement = HTMLElement> {
10
+ #attrs = new Map<string, AttrValue>()
11
+ #children: (Node | string)[] = []
12
+
13
+ constructor(public tagName: string) {}
14
+
15
+ attr(key: string, value: AttrValue = true) {
16
+ this.#attrs.set(key, value)
17
+ return this
18
+ }
19
+
20
+ attrs(record: Record<string, AttrValue>) {
21
+ for (const [key, value] of Object.entries(record))
22
+ this.attr(key, value)
23
+ return this
24
+ }
25
+
26
+ children(...elements: (Node | string)[]) {
27
+ this.#children.push(...elements)
28
+ return this
29
+ }
30
+
31
+ done() {
32
+ const element = document.createElement(this.tagName)
33
+ attrSet.entries(element, this.#attrs)
34
+ element.append(...this.#children)
35
+ return element as E
36
+ }
37
+ }
38
+
@@ -0,0 +1,24 @@
1
+
2
+ export type EveFn = (event: any) => void
3
+ export type EveConfig = [options: AddEventListenerOptions, fn: EveFn]
4
+ export type EveHandler = EveFn | EveConfig
5
+ export type EveSpec = {[eventName: string]: EveHandler}
6
+
7
+ export function eve(target: EventTarget, events: EveSpec) {
8
+ let detachers: (() => void)[] = []
9
+
10
+ for (const [eventName, handler] of Object.entries(events)) {
11
+ if (typeof handler === "function") {
12
+ target.addEventListener(eventName, handler)
13
+ detachers.push(() => target.removeEventListener(eventName, handler))
14
+ }
15
+ else {
16
+ const [options, fn] = handler
17
+ target.addEventListener(eventName, fn, options)
18
+ detachers.push(() => target.removeEventListener(eventName, fn))
19
+ }
20
+ }
21
+
22
+ return () => detachers.forEach(d => d())
23
+ }
24
+
@@ -0,0 +1,9 @@
1
+
2
+ import {render, TemplateResult} from "lit"
3
+
4
+ export function mk<E extends Element = HTMLElement>(template: TemplateResult) {
5
+ const fragment = document.createDocumentFragment()
6
+ render(template, fragment)
7
+ return fragment.firstElementChild as E
8
+ }
9
+
@@ -0,0 +1,26 @@
1
+
2
+ import {Queryable} from "../types.js"
3
+
4
+ export function queryRequire<E extends Element>(
5
+ selector: string,
6
+ container: Queryable = document,
7
+ ) {
8
+ const e = container.querySelector<E>(selector)
9
+ if (!e) throw new Error(`element not found (${selector})`)
10
+ return e
11
+ }
12
+
13
+ export function queryMaybe<E extends Element>(
14
+ selector: string,
15
+ container: Queryable = document,
16
+ ) {
17
+ return container.querySelector<E>(selector)
18
+ }
19
+
20
+ export function queryAll<E extends Element>(
21
+ selector: string,
22
+ container: Queryable = document,
23
+ ) {
24
+ return Array.from(container.querySelectorAll<E>(selector))
25
+ }
26
+
@@ -1,14 +1,6 @@
1
1
 
2
2
  import {dashify} from "./dashify.js"
3
-
4
- export type HTMLElementClasses = {
5
- [key: string]: {new(...args: any[]): HTMLElement}
6
- }
7
-
8
- export type RegistrationOptions = {
9
- soft: boolean
10
- upgrade: boolean
11
- }
3
+ import {HTMLElementClasses, RegisterOptions} from "../types.js"
12
4
 
13
5
  /**
14
6
  * register custom elements (web components) to the dom
@@ -24,7 +16,7 @@ export type RegistrationOptions = {
24
16
  */
25
17
  export function register<E extends HTMLElementClasses>(
26
18
  elements: E,
27
- options: Partial<RegistrationOptions> = {},
19
+ options: Partial<RegisterOptions> = {},
28
20
  ) {
29
21
 
30
22
  const {
package/s/dom/types.ts ADDED
@@ -0,0 +1,50 @@
1
+
2
+ import {attrs} from "./attrs/attrs.js"
3
+
4
+ export type Renderable = HTMLElement | ShadowRoot | DocumentFragment
5
+ export type Queryable = HTMLElement | ShadowRoot | Element | Document | DocumentFragment
6
+
7
+ // attrs
8
+
9
+ export type AttrValue = string | boolean | number | undefined | null | void
10
+
11
+ export type AttrKind = (
12
+ | typeof String
13
+ | typeof Number
14
+ | typeof Boolean
15
+ )
16
+
17
+ export type AttrType<H extends AttrKind> = (
18
+ H extends typeof String
19
+ ? string | undefined
20
+
21
+ : H extends typeof Number
22
+ ? number | undefined
23
+
24
+ : H extends typeof Boolean
25
+ ? boolean
26
+
27
+ : never
28
+ )
29
+
30
+ export type AttrSpec = {
31
+ [key: string]: AttrKind
32
+ }
33
+
34
+ export type AttrTypes<A extends AttrSpec> = {
35
+ [P in keyof A]: AttrType<A[P]>
36
+ }
37
+
38
+ export type Attrs = ReturnType<typeof attrs>
39
+
40
+ // register
41
+
42
+ export type HTMLElementClasses = {
43
+ [key: string]: {new(...args: any[]): HTMLElement}
44
+ }
45
+
46
+ export type RegisterOptions = {
47
+ soft: boolean
48
+ upgrade: boolean
49
+ }
50
+
package/s/index.html.ts CHANGED
@@ -29,9 +29,10 @@ export default ssg.page(import.meta.url, async orb => ({
29
29
  <h1>sly testing page</h1>
30
30
  <p><a href="https://github.com/e280/sly">github.com/e280/sly</a></p>
31
31
  <p class=lil>v${orb.packageVersion()}</p>
32
- <incredi-element></incredi-element>
33
- <demo-counter>component</demo-counter>
34
- <div class=demo></div>
32
+
33
+ <fastcount-element></fastcount-element>
34
+ <counter-component start=280 step=2>component</counter-component>
35
+ <demo-component></demo-component>
35
36
  `,
36
37
  }))
37
38
 
package/s/index.ts CHANGED
@@ -1,22 +1,9 @@
1
1
 
2
- export * from "./dom/attributes.js"
3
- export * from "./dom/dashify.js"
4
- export * from "./dom/dom.js"
5
- export * from "./dom/register.js"
6
-
7
- export * from "./ops/loaders/make-loader.js"
8
- export * from "./ops/loaders/parts/ascii-anim.js"
9
- export * from "./ops/loaders/parts/error-display.js"
10
- export * from "./ops/op.js"
11
- export * from "./ops/podium.js"
12
- export * from "./ops/types.js"
13
-
14
- export * as loot from "./loot/index.js"
15
-
16
- export * from "./dom/attributes.js"
17
- export * from "./views/base-element.js"
18
- export * from "./views/css-reset.js"
19
- export * from "./views/types.js"
20
- export * from "./views/use.js"
21
- export * from "./views/view.js"
2
+ export * from "./base/index.js"
3
+ export * from "./dom/index.js"
4
+ export * from "./loaders/index.js"
5
+ export * from "./loot/index.js"
6
+ export * from "./ops/index.js"
7
+ export * from "./spa/index.js"
8
+ export * from "./view/index.js"
22
9
 
@@ -0,0 +1,10 @@
1
+
2
+ export * as anims from "./parts/anims.js"
3
+ export type * from "./parts/anims.js"
4
+ export * from "./parts/ascii-anim.js"
5
+ export * from "./parts/error-display.js"
6
+ export * from "./make.js"
7
+ export * from "./mock.js"
8
+ export * from "./types.js"
9
+
10
+
@@ -0,0 +1,4 @@
1
+
2
+ export * as loaders from "./index.barrel.js"
3
+ export type * from "./index.barrel.js"
4
+
@@ -0,0 +1,14 @@
1
+
2
+ import {Loader} from "./types.js"
3
+ import {earth} from "./parts/anims.js"
4
+ import type {Content} from "../view/types.js"
5
+ import {ErrorDisplay} from "./parts/error-display.js"
6
+
7
+ export function make(
8
+ loading: () => Content = earth,
9
+ error: (error: any) => Content = (error: any) => ErrorDisplay(error),
10
+ ): Loader {
11
+
12
+ return (op, ready) => op.select({loading, ready, error})
13
+ }
14
+
@@ -0,0 +1,11 @@
1
+
2
+ import {Loader} from "./types.js"
3
+
4
+ export function mock(): Loader {
5
+ return (op, ready) => op.select({
6
+ ready,
7
+ loading: () => `[loading]`,
8
+ error: () => `[error]`,
9
+ })
10
+ }
11
+
@@ -1,6 +1,6 @@
1
1
 
2
2
  import {makeAsciiAnim} from "./ascii-anim.js"
3
- import {Content} from "../../../views/types.js"
3
+ import type {Content} from "../../view/types.js"
4
4
 
5
5
  const fast = 20
6
6
  const mid = 10
@@ -1,10 +1,10 @@
1
1
 
2
2
  import {css} from "lit"
3
- import {nap, repeat} from "@e280/stz"
3
+ import {nap, cycle} from "@e280/stz"
4
4
 
5
- import {view} from "../../../views/view.js"
6
- import {Content} from "../../../views/types.js"
7
- import {cssReset} from "../../../views/css-reset.js"
5
+ import {view} from "../../view/view.js"
6
+ import {Content} from "../../view/types.js"
7
+ import {cssReset} from "../../base/css-reset.js"
8
8
 
9
9
  export function makeAsciiAnim(hz: number, frames: string[]): () => Content {
10
10
  return () => AsciiAnim({hz, frames})
@@ -17,9 +17,10 @@ export const AsciiAnim = view(use => ({hz, frames}: {
17
17
 
18
18
  use.name("loading")
19
19
  use.styles(cssReset, style)
20
+
20
21
  const frame = use.signal(0)
21
22
 
22
- use.mount(() => repeat(async() => {
23
+ use.mount(() => cycle(async() => {
23
24
  await nap(1000 / hz)
24
25
  const next = frame.get() + 1
25
26
  frame.set(next >= frames.length ? 0 : next)
@@ -1,7 +1,7 @@
1
1
 
2
2
  import {css, html} from "lit"
3
- import {view} from "../../../views/view.js"
4
- import {cssReset} from "../../../views/css-reset.js"
3
+ import {view} from "../../view/view.js"
4
+ import {cssReset} from "../../base/css-reset.js"
5
5
 
6
6
  export const ErrorDisplay = view(use => (error: any) => {
7
7
  use.name("error")
@@ -0,0 +1,6 @@
1
+
2
+ import type {Op} from "../ops/op.js"
3
+ import type {Content} from "../view/types.js"
4
+
5
+ export type Loader = <V>(op: Op<V>, ready: (value: V) => Content) => Content
6
+
@@ -0,0 +1,5 @@
1
+
2
+ export * from "./drag-and-drops.js"
3
+ export * from "./drops.js"
4
+ export * from "./helpers.js"
5
+
package/s/loot/index.ts CHANGED
@@ -1,5 +1,4 @@
1
1
 
2
- export * from "./drag-and-drops.js"
3
- export * from "./drops.js"
4
- export * from "./helpers.js"
2
+ export * as loot from "./index.barrel.js"
3
+ export type * from "./index.barrel.js"
5
4
 
package/s/ops/index.ts ADDED
@@ -0,0 +1,5 @@
1
+
2
+ export * from "./op.js"
3
+ export * from "./podium.js"
4
+ export * from "./types.js"
5
+
package/s/ops/op.ts CHANGED
@@ -69,6 +69,7 @@ export class Op<V> {
69
69
  return value
70
70
  }
71
71
  catch (error) {
72
+ console.error(error)
72
73
  if (count === this.#count)
73
74
  await this.setError(error)
74
75
  }
@@ -0,0 +1,6 @@
1
+
2
+ export {route} from "./plumbing/braces.js"
3
+ export type {Navigable} from "./plumbing/primitives.js"
4
+ export {RouterOptions, Hasher, Route, Routes, Navigables, Params} from "./plumbing/types.js"
5
+ export {Router} from "./router.js"
6
+
package/s/spa/index.ts ADDED
@@ -0,0 +1,4 @@
1
+
2
+ export * as spa from "./index.barrel.js"
3
+ export type * from "./index.barrel.js"
4
+
@@ -0,0 +1,76 @@
1
+
2
+ import {Hasher, Route} from "./types.js"
3
+ import type {Content} from "../../view/types.js"
4
+
5
+ type ParamKeys<S extends string> =
6
+ S extends `${string}{${infer P}}${infer R}` ? (string & P) | ParamKeys<R> : never
7
+
8
+ type ParamsOf<S extends string> =
9
+ [ParamKeys<S>] extends [never] ? {} : { [K in ParamKeys<S>]: string }
10
+
11
+ type ParamsTuple<S extends string> =
12
+ keyof ParamsOf<S> extends never ? [] : [ParamsOf<S>]
13
+
14
+ export function hasher<S extends string>(spec: S): Hasher<ParamsTuple<S>> {
15
+ if (!spec.startsWith("#/"))
16
+ throw new Error(`hash route spec must start with "#/"`)
17
+
18
+ const specparts = spec.split("/")
19
+ const braceregex = /\{([^\}\/]+)\}/
20
+
21
+ function parse(hash: string): ParamsTuple<S> | null {
22
+ if (!hash.startsWith("#/"))
23
+ throw new Error(`hash must start with "#/"`)
24
+
25
+ const hashparts = hash.split("/")
26
+ const params: Record<string, string> = {}
27
+
28
+ if (hashparts.length !== specparts.length)
29
+ return null
30
+
31
+ for (const [index, specpart] of specparts.entries()) {
32
+ const hashpart = hashparts.at(index)
33
+ if (hashpart === undefined) return null
34
+ const bracematch = specpart.match(braceregex)
35
+ try {
36
+ if (bracematch) params[bracematch[1]] = decodeURIComponent(hashpart)
37
+ else if (hashpart !== specpart) return null
38
+ }
39
+ catch {
40
+ return null
41
+ }
42
+ }
43
+
44
+ return (Object.keys(params).length === 0)
45
+ ? ([] as ParamsTuple<S>)
46
+ : ([params as ParamsOf<S>] as ParamsTuple<S>)
47
+ }
48
+
49
+ function make(...[braces]: any[]): string {
50
+ const get = (param: string) => {
51
+ const p = param as any
52
+ if (p in braces) return braces[p]
53
+ else throw new Error(`missing param "${p}"`)
54
+ }
55
+ return specparts.map(specpart => {
56
+ const bracematch = specpart.match(braceregex)
57
+ return bracematch
58
+ ? encodeURIComponent(get(bracematch[1]))
59
+ : specpart
60
+ }).join("/")
61
+ }
62
+
63
+ return {parse, make}
64
+ }
65
+
66
+ export function route<S extends string>(
67
+ spec: S,
68
+ fn: (...params: ParamsTuple<S>) => Promise<Content>,
69
+ ): Route<ParamsTuple<S>> {
70
+
71
+ return {
72
+ hasher: hasher(spec),
73
+ fn,
74
+ }
75
+ }
76
+