@wrnrlr/prelude 0.0.1 → 0.1.3

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 (40) hide show
  1. package/.github/workflows/publish.yml +46 -5
  2. package/deno.json +18 -9
  3. package/package.json +4 -6
  4. package/readme.md +163 -41
  5. package/src/constants.ts +2 -1
  6. package/src/{controlflow.js → controlflow.ts} +63 -50
  7. package/src/hyperscript.ts +7 -6
  8. package/src/mod.ts +19 -17
  9. package/src/reactive.ts +42 -14
  10. package/src/resource.js +184 -0
  11. package/src/router.js +65 -0
  12. package/src/runtime.ts +9 -8
  13. package/test/hyperscript.js +2 -2
  14. package/test/reactive.js +12 -4
  15. package/www/assets/css/presets.css +504 -0
  16. package/www/assets/css/style.css +90 -0
  17. package/www/demo.html +15 -0
  18. package/www/index.html +211 -0
  19. package/www/playground.html +183 -0
  20. package/www/public/example/admin.html +88 -0
  21. package/{example → www/public/example}/counter.html +1 -1
  22. package/{example → www/public/example}/greeting.html +1 -1
  23. package/{example → www/public/example}/show.html +1 -1
  24. package/{example → www/public/example}/todo.html +1 -1
  25. package/www/public/fonts/fab.ttf +0 -0
  26. package/www/public/fonts/fab.woff2 +0 -0
  27. package/www/public/fonts/far.ttf +0 -0
  28. package/www/public/fonts/far.woff2 +0 -0
  29. package/www/public/fonts/fas.ttf +0 -0
  30. package/www/public/fonts/fas.woff2 +0 -0
  31. package/www/public/logo.svg +16 -0
  32. package/www/typedoc.json +13 -0
  33. package/www/vite.config.js +106 -0
  34. package/example/paint.html +0 -22
  35. package/index.html +0 -230
  36. package/presets.css +0 -284
  37. package/public/logo.svg +0 -5
  38. package/test/runtime.js +0 -7
  39. package/typedoc.jsonc +0 -31
  40. /package/{public → www/public}/banner.svg +0 -0
@@ -5,12 +5,53 @@ on:
5
5
  branches:
6
6
  - main
7
7
 
8
+ permissions:
9
+ contents: read
10
+ pages: write
11
+ id-token: write
12
+
8
13
  jobs:
9
14
  publish:
10
15
  runs-on: ubuntu-latest
11
- permissions:
12
- contents: read
13
- id-token: write # The OIDC ID token is used for authentication with JSR.
16
+ environment:
17
+ name: github-pages
18
+ url: ${{ steps.deployment.outputs.page_url }}
14
19
  steps:
15
- - uses: actions/checkout@v4
16
- - run: npx jsr publish
20
+ - name: Check out the repository to the runner
21
+ uses: actions/checkout@v4
22
+
23
+ - name: Setup Deno
24
+ uses: denoland/setup-deno@v2
25
+ with:
26
+ deno-version: v2.x
27
+
28
+ - name: Deno install
29
+ run: deno install
30
+
31
+ # - name: Lint
32
+ # run: deno lint
33
+
34
+ - name: Run tests
35
+ run: deno task test
36
+
37
+ - name: Build
38
+ run: deno task build
39
+
40
+ - name: Setup Pages
41
+ uses: actions/configure-pages@v5
42
+
43
+ - name: Upload artifact
44
+ uses: actions/upload-pages-artifact@v3
45
+ with:
46
+ path: './www/dist'
47
+
48
+ - name: Deploy to GitHub Pages
49
+ id: deployment
50
+ uses: actions/deploy-pages@v4
51
+
52
+ # - name: Setup NPM
53
+ # run: echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > /home/runner/.npmrc
54
+ # env:
55
+ # NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
56
+ # - name: Run release script
57
+ # run: /home/runner/.deno/bin/deno task release
package/deno.json CHANGED
@@ -1,23 +1,32 @@
1
1
  {
2
2
  "name": "@wrnrlr/prelude",
3
- "version": "0.1.0",
3
+ "version": "0.1.3",
4
4
  "exports": "./src/mod.ts",
5
5
  "compilerOptions": {
6
- "strict": true,
6
+ "strict": false,
7
7
  "checkJs": false,
8
8
  "noImplicitThis": false,
9
- "lib": ["dom","dom.iterable","dom.asynciterable","deno.ns"]
9
+ "lib": ["dom", "dom.iterable", "dom.asynciterable", "deno.ns"]
10
10
  },
11
11
  "imports": {
12
12
  "@std/assert": "jsr:@std/assert@^1.0.0",
13
+ "@std/fs": "jsr:@std/fs@^1.0.5",
14
+ "@std/path": "jsr:@std/path@^1.0.6",
13
15
  "@std/testing": "jsr:@std/testing@^0.225.3",
14
- "typedoc": "npm:typedoc",
15
- "vite": "npm:vite@^5.4.2",
16
- "typedoc-plugin-markdown": "npm:typedoc-plugin-markdown"
16
+ "jsdom": "npm:jsdom",
17
+ "typedoc": "npm:typedoc@^0.26.6",
18
+ "vite": "npm:vite@^5.4.9",
19
+ "esbuild": "npm:esbuild@^0.24.0"
17
20
  },
18
21
  "tasks": {
19
- "dev": "deno run -A npm:vite@^5.4.2",
20
- "test": "deno test -A --unstable-sloppy-imports ./test/*.[jt]s",
21
- "docs": "deno run -A npm:typedoc "
22
+ "dev": "deno run -A npm:vite --config www/vite.config.js",
23
+ "test": "deno test -A ./test/*.[jt]s",
24
+ "docs": "deno run -A npm:typedoc --options www/typedoc.json",
25
+ "build": "deno run -A npm:vite build --mode production --config www/vite.config.js",
26
+ "release": "deno publish --allow-slow-types --allow-dirty && npm publish --access public",
27
+ "clean": "rm -rf dist/ www/dist www/docs"
28
+ },
29
+ "lint": {
30
+ "include": ["src"]
22
31
  }
23
32
  }
package/package.json CHANGED
@@ -1,12 +1,10 @@
1
1
  {
2
2
  "name": "@wrnrlr/prelude",
3
- "version": "0.0.1",
3
+ "type": "module",
4
+ "version": "0.1.3",
4
5
  "author": "Werner Laurensse",
5
6
  "description": "A signal based frontend library with fine-grained reactivity",
6
7
  "main": "./src/mod.ts",
7
- "directories": {
8
- "example": "example",
9
- "test": "test"
10
- },
11
- "scripts": {}
8
+ "scripts": {},
9
+ "dependencies": { "@codemirror/lang-html": "^6.4.9", "codemirror": "^6.0.1" }
12
10
  }
package/readme.md CHANGED
@@ -1,86 +1,208 @@
1
- # PreludeJS
1
+ # Prelude
2
+ [Home](https://wrnrlr.github.io/prelude/) [NPM](https://www.npmjs.com/package/@wrnrlr/prelude) [JSR](https://jsr.io/@wrnrlr/prelude)
3
+
4
+ Prelude lets you develop web applications in a familiar component-based functional style.
5
+ It is build with the desire to have a lightweight frontend framework that works
6
+ using just JavaScript but that nontheless can handle complex web applications without
7
+ sacrificing on developer expierence.
2
8
 
3
9
  ## Get Started
4
10
 
5
- Run directly in the browser using ESM
6
- ```js
11
+ Prelude works with most popular JavaScript runtimes: Node, Deno, Bun or the borwser.
12
+ It is available on NPM and JSR under the package named `@wrnrlr/prelude`.
13
+
14
+ The quickest way to get started with Prelude is uing the [Playground](https://wrnrlr.github.io/prelude/playground) app on the homepage.
15
+ It offers a IDE complete with a code editor, live preview and a number of examples.
16
+ Aternativaly you can develop on your local machine using `vite`.
17
+
18
+ Some Prelude APIs can also be used in the REPL to expore their behaviour interactively.
19
+
20
+ ## Basic Example
21
+
22
+ This is a example of a button that increments a counter when it is clicked.
23
+
24
+ ```html
25
+ <!DOCTYPE html>
26
+ <title>Counter</title>
27
+
28
+ <script type="module">
7
29
  import {h, signal, render} from 'https://esm.sh/@wrnrlr/prelude'
8
- ```
9
30
 
10
- Install from NPM to run with Node or Bun
11
- ```js
12
- import {h, signal, render} from 'wrnrlr/prelude'
13
- ```
31
+ function Counter() {
32
+ const n = signal(1)
33
+ return h('button', {onClick: e => n(n=>n+1)}, n)
34
+ }
35
+
36
+ render(Counter, document.body)
37
+ </script>
38
+ ```
39
+
40
+ ## Hyperscript
14
41
 
15
- Use Deno's JSR
16
- ```js
17
- import {h, signal, render} from 'jsr:wrnrlr/prelude'
18
- ```
42
+ Prelude does not use JSX or a templating language to descript html instead we use a DSL called HyperScript.
19
43
 
20
- A simple js frontend library
44
+ The `h` function is used in either of two ways based on the type of the first argument,
45
+ when it is a string it will create a html element like ,
46
+ and when it is a function it will create a reactive component.
21
47
 
22
48
  ```js
23
- import {h,signal,render} from 'https://jsr.org/wrnrlr/prelude.ts'
49
+ h('div',{},[
50
+ h('label','Name'),h('input',{})
51
+ ])
52
+ ```
24
53
 
25
- function Counter() {
26
- const n = signal(1)
27
- return [n,h('button',{onclick(e){n(n=>n+1)}},'+')]
28
- }
54
+ ### Event Handler
55
+
56
+ Prelude tries to integrate with the existing web APIs as much as possible, handeling user events is no different,
57
+ use a function to the event callback.
29
58
 
30
- render(Counter, document.body)
59
+ In the following example we listen for `onclick` events for a button, and increment the value of the `n` signal.
60
+
61
+ ```js
62
+ h('button', {onClick:e => n(i => i + 1)}, n)
31
63
  ```
32
64
 
33
- ## Signals
65
+ Be adviced, the event handler MUST always have one argument even if this is not being used, lest HyperScript confuses it for a signal
66
+ and ignores the events.
34
67
 
35
68
  ```js
36
- const a = signal(1)
37
- const b = signal(2)
69
+ // Ok
70
+ h('button', {onClick: e => console.log('Ok')})
71
+ h('button', {onClick: _ => console.log('Ok')})
72
+ // This event handler will be ignored
73
+ h('button', {onClick: () => console.log('Wrong')})
74
+ ```
75
+
76
+ ## Reactivity
77
+
78
+ ### Signals
79
+
80
+ A signal is an object that holds a value with a setter to update this value and a getter that returns this value whenever it is updated.
81
+
82
+ Create signal.
83
+ ```js
84
+ // Create a signal with value one
85
+ const n = signal(1)
86
+
87
+ // Get value from signal
88
+ n()
89
+
90
+ // Set value for signal
91
+ n(2)
92
+
93
+ // Set value with an update function
94
+ n(i=>i+1)
95
+
96
+ // Derived signal
97
+ const n2 = () => n() * 2
98
+ ```
99
+
100
+ ### Effects
101
+
102
+ The `effect` function lets you subscribe to signals and perform side-effects whenever the signal chages.
103
+
104
+ ```js
105
+ const a = signal(1), b = signal(2)
38
106
  effect(() => console.log('a+b', a()+b()))
39
107
  const c = () => a()+b()
40
108
  effect(() => console.log('c', c()))
41
109
  a(i => i+1)
42
110
  ```
43
111
 
44
- ## Hyperscript
112
+ ### Memo
45
113
 
46
- The `h` function allows one to write html in javascript with a DSL specifically designed
114
+ The `memo` function caches the result of the function passed to it.
47
115
 
48
116
  ```js
49
- h('div',{},[
50
- h('label','Name'),h('input',{})
51
- ])
117
+ const n2 = memo(() => n() * 2)
52
118
  ```
53
119
 
54
- ## Event Handler
120
+ ### Untrack
55
121
 
56
- An event handler MUST have an argument even if this is not being used,
57
- otherwise hyperscript will confuse it for a signal.
122
+ ## Conditional Rendering
58
123
 
59
124
  ```js
60
- // Ok
61
- h('button', {onClick: e => console.log('Ok')}, 'Hi')
62
- h('button', {onClick: _ => console.log('Ok')}, 'Hi')
63
- // This event handler will be ignored
64
- h('button', {onClick: () => console.log('Wrong')}, '')
125
+ h(Show, {when:() => n()%2 === 0, fallback:'odd'}, 'even')
65
126
  ```
66
127
 
67
- ## Conditional Rendering
128
+ It is also possible to conditionally render a component by prefixing it with a JavaScript *and-expression*, like in the example below,
129
+ but using `Show` is going to be faster.
68
130
 
69
131
  ```js
70
- h(Show, {when:show}, 'Hi')
132
+ h('',show&&'Hi')
71
133
  ```
72
134
 
73
135
  ## Rendering Lists
74
136
 
75
137
  ```js
76
- h(List, {each:show}, 'Hi')
138
+ h(List, {each:['a','b','c']}, (v,i)=>`${i()}:${v()}`)
139
+ ```
140
+
141
+ ## Fetching Resources
142
+
143
+ The `resource()` function lets you define a asynchronous signal.
144
+
145
+
146
+ ```js
147
+ resource(async ()=>getPosts())
77
148
  ```
78
149
 
79
- ## Inversion of Control
150
+ ## Dependency Injection
80
151
  Prelude supports dependency injection with the `contect` and `useContext` APIs.
81
152
 
82
- ## Advanced DataTable
153
+ ```js
154
+ const CounterCtx = context()
155
+ const useCounter = () => useContext(CounterCtx)
156
+
157
+ function CounterProvider(props) {
158
+ const count = signal(0)
159
+ const increment = () => count(i=>i+1)
160
+ return h(CounterCtx.Provider, {value:[count,increment]}, props.children)
161
+ }
162
+
163
+ function Counter() {
164
+ const [n, increment] = useCounter()
165
+ return h('button', {onClick:e=>increment()}, n)
166
+ }
167
+
168
+ function
169
+
170
+ function App() {
171
+ h(CounterProvider, h(Counter))
172
+ }
173
+ ```
174
+
175
+ ## Router
83
176
 
84
177
  ```js
85
- h(Table)
178
+ h(Router,[
179
+ {path:'/', component:Posts},
180
+ {path:'/user', component:Users}
181
+ ])
86
182
  ```
183
+
184
+ ## Learn More
185
+
186
+ * [API Reference]()
187
+ * [SolidJS Docs]():
188
+ The documentation of SolidJS also a good place for background information because Prelude is lacking extensive documentation at this time.
189
+ Prelude started as a SolidJS clone, but with better HyperScript support. A lot of the concepts are the same but naming conventions can vary.
190
+
191
+ ## TODO
192
+
193
+ * [ ] tailwind styling
194
+ * SSR
195
+ * Hydration
196
+ * Components
197
+ * [ ] Select
198
+ * [ ] Multiselect
199
+ * [ ] DataTable
200
+ * [ ] Dropdown
201
+ * [ ] Dialog
202
+ * [ ] Dynamic
203
+
204
+ ## Links
205
+
206
+ * [Homepage](https://wrnrlr.github.io/prelude)
207
+ * [NPM](https://www.npmjs.com/package/@wrnrlr/prelude)
208
+ * [JSR](https://jsr.io/@wrnrlr/prelude)
package/src/constants.ts CHANGED
@@ -1,3 +1,4 @@
1
+ // @ts-nocheck:
1
2
  /**
2
3
  * Non-breakable space in Unicode
3
4
  * @group Utils
@@ -13,7 +14,7 @@ declare type DocumentFragment = any
13
14
  export declare type Node = any
14
15
 
15
16
  export type Mountable = Elem | Document | ShadowRoot | DocumentFragment | Node;
16
- type ExpandableNode = Node & { [key: string]: any };
17
+ type ExpandableNode = Node & { [key: string]: unknown };
17
18
 
18
19
  // type Expect<T extends true> = T;
19
20
  // type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
@@ -1,81 +1,94 @@
1
- import {signal,sample,batch,memo,root,Signal} from './reactive.ts'
1
+ // @ts-nocheck:
2
+ import type { Child } from './hyperscript.ts'
3
+ import {signal,untrack,batch,memo,root,type Signal} from './reactive.ts'
4
+
5
+ export type ShowProps<T> = {
6
+ when: T,
7
+ children: Child | ((a:()=>T)=>void),
8
+ fallback: unknown
9
+ }
2
10
 
3
11
  /**
4
12
  Show children if `when` prop is true, otherwise show `fallback`.
5
13
  @group Components
6
14
  */
7
- export function Show(props) {
15
+ export function Show<T>(props:ShowProps<T>) {
8
16
  const condition = memo(()=>props.when)
9
17
  return memo(()=>{
10
18
  const c = condition()
11
19
  if (c) {
12
20
  const child = props.children
13
21
  const fn = typeof child === "function" && child.length > 0
14
- return fn ? sample(() => child(() => props.when)) : child
22
+ return fn ? untrack(() => child(() => props.when)) : child
15
23
  } else return props.fallback
16
24
  })
17
25
  }
18
26
 
19
- export function wrap(s,k) {
20
- const t = typeof k
21
- if (t === 'number') return (...a) => {
22
- const b = s()
23
- return (a.length) ? s(b.toSpliced(k, 1, a[0])).at(k) : b.at(k)
24
- }; else if (t === 'string') return (...a) => {
25
- const b = s()
26
- return a.length ? s(({ ...b, [k]: a[0] }))[k] : b[k]
27
- }; else if (t === 'function') return (...a) => {
28
- const i = k(), c = typeof i
29
- if (c==='number') return a.length ? s(old => old.toSpliced(i, 1, a[0]))[i] : s()[i]
30
- else if (c === 'string') return a => a.length ? s(b => ({...b, [i]:a[0]}))[i] : s()[i]
31
- throw new Error('Cannot wrap signal')
32
- }
33
- throw new Error('Cannot wrap signal')
27
+ type ItemHolder = {
28
+ index:number,
29
+ indexSetter?:any,
30
+ value:unknown,
31
+ valueSetter:any,
32
+ disposer: any
33
+ }
34
+
35
+ export type ListProps<T> = {
36
+ when: T,
37
+ each: any,
38
+ children: Child | ((a:()=>T)=>void),
39
+ fallback: unknown
34
40
  }
35
41
 
36
42
  /**
37
43
  List
38
44
  @group Components
39
45
  */
40
- export function List(props) {
46
+ export function List<T>(props:ListProps<T>) {
41
47
  const fallback = "fallback" in props && { fallback: () => props.fallback }
42
48
  const list = props.each
43
- const cb = props.children.call ? props.children : (v)=>v
44
- let items = [], item, unusedItems, i, j, newValue, mapped, oldIndex, oldValue,
45
- indexes = cb.length > 1 ? [] : null;
46
- function newValueGetter(_) { return newValue }
49
+ const cb:any = (props.children as any)?.call ? props.children : (v:any)=>v
50
+ let items:ItemHolder[] = [],
51
+ item: undefined|ItemHolder,
52
+ // unusedItems,
53
+ i: undefined|number,
54
+ newValue: undefined|number,
55
+ mapped: number[],
56
+ oldIndex: number,
57
+ oldValue: unknown
58
+ const indexes = cb.length > 1 ? [] : null;
59
+ function newValueGetter(_:unknown) { return newValue }
47
60
  function changeBoth() {
48
- item.index = i
49
- item.indexSetter?.(i)
50
- item.value = newValue
51
- item.valueSetter?.(newValueGetter)
61
+ item!.index = i!
62
+ item!.indexSetter?.(i)
63
+ item!.value = newValue!
64
+ item!.valueSetter?.(newValueGetter)
52
65
  }
53
- function mapperWithIndexes(disposer) {
66
+ function mapperWithIndexes(disposer:any) {
54
67
  const V = newValue, I = i, Is = signal(I), Vs = signal(V)
55
- items.push({value: newValue, index: I, disposer, indexSetter: Is, valueSetter: Vs})
68
+ items.push({value: newValue, index: I!, disposer, indexSetter: Is, valueSetter: Vs})
56
69
  return cb(
57
- (...a) => a.length ?
58
- sample(()=>list(list=>list.toSpliced(I,1,a[0])))
70
+ (...a:any[]) => a.length ?
71
+ untrack(()=>list((list:any)=>list.toSpliced(I,1,a[0])))
59
72
  : Vs(),
60
73
  ()=>Is())
61
74
  }
62
- function mapperWithoutIndexes(disposer) {
75
+ function mapperWithoutIndexes(disposer:any) {
63
76
  const V = newValue, I = i, Vs = signal(V)
64
- items.push({value: V, index: i, disposer, valueSetter: Vs})
65
- return cb((...a) => a.length ?
66
- sample(()=>list(list=>list.toSpliced(I,1,a[0])))
77
+ items.push({value: V, index: i!, disposer, valueSetter: Vs})
78
+ return cb((...a:unknown[]) => a.length ?
79
+ untrack(()=>list((list:any)=>list.toSpliced(I,1,a[0])))
67
80
  : Vs())
68
81
  }
69
82
  const mapper = indexes ? mapperWithIndexes : mapperWithoutIndexes
70
83
  return memo(() => {
71
- const newItems = list() || []
84
+ const newItems = list.call ? list() : list
72
85
  // (newItems)[$TRACK]; // top level tracking
73
- return sample(() => {
86
+ return untrack(() => {
74
87
  const temp = new Array(newItems.length) // new mapped array
75
- unusedItems = items.length
88
+ let unusedItems = items.length
76
89
 
77
90
  // 1) no change when values & indexes match
78
- for (j = unusedItems - 1; j >= 0; --j) {
91
+ for (let j = unusedItems - 1; j >= 0; --j) {
79
92
  item = items[j]
80
93
  oldIndex = item.index
81
94
  if (oldIndex < newItems.length && newItems[oldIndex] === item.value) {
@@ -90,7 +103,7 @@ export function List(props) {
90
103
  // #2 prepare values matcher
91
104
  const matcher = new Map()
92
105
  const matchedItems = new Uint8Array(unusedItems)
93
- for (j = unusedItems - 1; j >= 0; --j) {
106
+ for (let j = unusedItems - 1; j >= 0; --j) {
94
107
  oldValue = items[j].value
95
108
  matcher.get(oldValue)?.push(j) ?? matcher.set(oldValue, [j])
96
109
  }
@@ -99,19 +112,19 @@ export function List(props) {
99
112
  for (i = 0; i < newItems.length; ++i) {
100
113
  if (i in temp) continue
101
114
  newValue = newItems[i]
102
- j = matcher.get(newValue)?.pop() ?? -1
115
+ const j = matcher.get(newValue)?.pop() ?? -1
103
116
  if (j >= 0) {
104
- item = items[j]
105
- oldIndex = item.index
117
+ item = items[j as number]
118
+ oldIndex = item!.index
106
119
  temp[i] = mapped[oldIndex]
107
- item.index = i
108
- item.indexSetter?.(i)
109
- matchedItems[j] = 1
120
+ item!.index = i
121
+ item!.indexSetter?.(i)
122
+ matchedItems[j as number] = 1
110
123
  }
111
124
  }
112
125
 
113
126
  // 3) reduce unusedItems for matched items
114
- for (j = matchedItems.length - 1; j >= 0; --j) {
127
+ for (let j = matchedItems.length - 1; j >= 0; --j) {
115
128
  if (matchedItems[j] && --unusedItems !== j) {
116
129
  item = items[j]
117
130
  items[j] = items[unusedItems]
@@ -120,9 +133,9 @@ export function List(props) {
120
133
  }
121
134
 
122
135
  // 4) change values when indexes match
123
- for (j = unusedItems - 1; j >= 0; --j) {
136
+ for (let j = unusedItems - 1; j >= 0; --j) {
124
137
  item = items[j];
125
- oldIndex = item.index;
138
+ oldIndex = item!.index;
126
139
  if (!(oldIndex in temp) && oldIndex < newItems.length) {
127
140
  temp[oldIndex] = mapped[oldIndex]
128
141
  newValue = newItems[oldIndex]
@@ -156,7 +169,7 @@ export function List(props) {
156
169
  })
157
170
  }
158
171
 
159
- function disposeList(list) {
172
+ function disposeList(list:any[]) {
160
173
  for (let i = 0; i < list.length; i++) {
161
174
  list[i]?.disposer()
162
175
  }
@@ -1,5 +1,6 @@
1
- import {sample} from './reactive.ts'
2
- import {Properties,BooleanAttributes,DelegatedEvents,DOMElements, type Mountable} from './constants.ts'
1
+ // @ts-nocheck:
2
+ import {untrack} from './reactive.ts'
3
+ import type {Properties,BooleanAttributes,DelegatedEvents,DOMElements, Mountable} from './constants.ts'
3
4
  import type {Runtime,$RUNTIME} from './runtime.ts'
4
5
 
5
6
  const ELEMENT: unique symbol = Symbol(), {isArray} = Array
@@ -89,7 +90,7 @@ export function hyperscript(r:Runtime, patch?:any):HyperScript {
89
90
  let children: Child
90
91
 
91
92
  if (typeof second === 'object' && !isArray(second)) {
92
- children = third || [];
93
+ children = (third as Child) || [];
93
94
  props = ((second ?? {}) as T&{children:K})
94
95
  } else {
95
96
  children = (second as Child) || []
@@ -115,7 +116,7 @@ export function hyperscript(r:Runtime, patch?:any):HyperScript {
115
116
  dynamicProperty(props as any, k)
116
117
  }
117
118
  }
118
- e = sample(()=>(element as Component<T&{children:K}>)(props as T&{children:K}))
119
+ e = untrack(()=>(element as Component<T&{children:K}>)(props as T&{children:K}))
119
120
  ret = () => e
120
121
  } else {
121
122
  const tag = parseTag(element as Tag)
@@ -160,12 +161,12 @@ function detectMultiExpression(list:any):boolean {
160
161
  // ^([a-zA-Z]\w*)?(#[a-zA-Z][-\w]*)?(.[a-zA-Z][-\w]*)*
161
162
  function parseTag(s:string):{name:string,id?:string,classes:string[]} {
162
163
  const classes:string[] = [];
163
- let name:string, id = undefined, i:number
164
+ let id:string|undefined = undefined, i:number
164
165
 
165
166
  i = s.indexOf('#')
166
167
  if (i===-1) i = s.indexOf('.')
167
168
  if (i===-1) i = s.length
168
- name = s.slice(0, i) || 'div'
169
+ const name = s.slice(0, i) || 'div'
169
170
  s = s.slice(i)
170
171
 
171
172
  if (s[0]==='#') {
package/src/mod.ts CHANGED
@@ -1,15 +1,18 @@
1
+ // @ts-nocheck:
1
2
  export type {Getter,Setter,Fn,EqualsFn,ErrorFn,RootFn,UpdateFn} from './reactive.ts'
2
- export {signal,effect,sample,batch,memo,root,onMount} from './reactive.ts'
3
+ export {signal,effect,untrack,batch,memo,root,wrap,onMount} from './reactive.ts'
3
4
  export {nbsp} from './constants.ts'
4
- export {wrap,Show,List} from './controlflow.js'
5
+ export {Show,List} from './controlflow.ts'
5
6
  export {runtime, type Runtime} from './runtime.ts'
6
7
  import {runtime, type Runtime} from './runtime.ts'
7
8
  export {hyperscript,type HyperScript,type Child,type Props,type Tag,type View,type Component} from './hyperscript.ts'
8
9
  import {type HyperScript, hyperscript} from './hyperscript.ts'
9
- export {Input,Table} from './components.js'
10
- export * from './canvas.js'
10
+ export {Router} from './router.js'
11
+ export {resource,makeAbortable,abortable} from './resource.js'
12
+ // export {Input,Table} from './components.js'
13
+ // export * from './canvas.js'
11
14
 
12
- const r:Runtime = runtime(window as any)
15
+ const r:Runtime|undefined = /*#__PURE__*/ (typeof window === 'object') ? runtime(window as any) : undefined
13
16
 
14
17
  /** h
15
18
  @example Element with a single child
@@ -26,20 +29,19 @@ h(Input,{onInput:e => {}})
26
29
  ```
27
30
  @group Hyperscript
28
31
  */
29
- const h:HyperScript = hyperscript(r)
32
+ const h:HyperScript|undefined = /*#__PURE__*/ r ? hyperscript(r) : undefined
30
33
 
31
- const render = r.render
34
+ const render = /*#__PURE__*/ r?.render
32
35
 
33
- import {signal} from './reactive.ts'
34
- import {wrap} from './controlflow.js'
36
+ // import {signal,wrap} from './reactive.ts'
35
37
 
36
- /**
37
- @group Utils
38
- */
39
- export function $(a:any,b:any):any {
40
- const t = typeof a
41
- if (t==='function') return wrap(a,b)
42
- else return signal(a,b)
43
- }
38
+ // /**
39
+ // @group Utils
40
+ // */
41
+ // export function $(a:any,b:any):any {
42
+ // const t = typeof a
43
+ // if (t==='function') return wrap(a,b)
44
+ // else return signal(a,b)
45
+ // }
44
46
 
45
47
  export {h,render}