tosijs 1.0.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.
- package/LICENSE +29 -0
- package/README.md +385 -0
- package/dist/bind.d.ts +9 -0
- package/dist/bindings.d.ts +4 -0
- package/dist/blueprint-loader.d.ts +19 -0
- package/dist/by-path.d.ts +8 -0
- package/dist/color.d.ts +46 -0
- package/dist/component.d.ts +37 -0
- package/dist/css-colors.d.ts +3 -0
- package/dist/css-system-color.d.ts +1 -0
- package/dist/css-types.d.ts +250 -0
- package/dist/css.d.ts +22 -0
- package/dist/deep-clone.d.ts +5 -0
- package/dist/dom.d.ts +9 -0
- package/dist/elements.d.ts +142 -0
- package/dist/get-css-var.d.ts +1 -0
- package/dist/hot-reload.d.ts +2 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +33 -0
- package/dist/list-binding.d.ts +37 -0
- package/dist/main.js +13 -0
- package/dist/main.js.map +33 -0
- package/dist/make-component.d.ts +39 -0
- package/dist/make-error.d.ts +1 -0
- package/dist/metadata.d.ts +32 -0
- package/dist/module.js +13 -0
- package/dist/module.js.map +33 -0
- package/dist/more-math.d.ts +10 -0
- package/dist/object-property-list.d.ts +8 -0
- package/dist/path-listener.d.ts +13 -0
- package/dist/settings.d.ts +4 -0
- package/dist/string-case.d.ts +2 -0
- package/dist/throttle.d.ts +4 -0
- package/dist/version.d.ts +1 -0
- package/dist/xin-proxy.d.ts +4 -0
- package/dist/xin-types.d.ts +111 -0
- package/dist/xin.d.ts +16 -0
- package/package.json +71 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022, Tonio Loewald
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
ADDED
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
# tosijs
|
|
2
|
+
|
|
3
|
+
<!--{ "pin": "top" }-->
|
|
4
|
+
|
|
5
|
+
> `tosijs` is being renamed `tosijs`. This is a work-in-progress.
|
|
6
|
+
|
|
7
|
+
[tosijs.net](https://tosijs.net) | [tosijs-ui](https://ui.tosijs.net) | [github](https://github.com/tonioloewald/tosijs) | [npm](https://www.npmjs.com/package/tosijs) | [cdn](https://www.jsdelivr.com/package/npm/tosijs) | [react-tosijs](https://github.com/tonioloewald/react-tosijs#readme) | [discord](https://discord.gg/ramJ9rgky5)
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/tosijs)
|
|
10
|
+
[](https://bundlejs.com/?q=tosijs&badge=)
|
|
11
|
+
[](https://www.jsdelivr.com/package/npm/tosijs)
|
|
12
|
+
|
|
13
|
+
<div style="text-align: center; margin: 20px">
|
|
14
|
+
<img style="width: 250px; max-width: 80%" class="logo" alt="tosijs logo" src="https://tosijs.net/favicon.svg">
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
> For a pretty thorough overview of tosijs, you might like to start with [What is tosijs?](https://loewald.com/blog/2025/6/4/what-is-tosijs-).
|
|
18
|
+
> To understand the thinking behind tosijs, there's [What should a front-end framework do?](https://loewald.com/blog/2025/6/4/what-should-a-front-end-framework-do).
|
|
19
|
+
|
|
20
|
+
### Build UIs with less code
|
|
21
|
+
|
|
22
|
+
If you want to build a web-application that's performant, robust, and maintainable,
|
|
23
|
+
`tosijs` lets you:
|
|
24
|
+
|
|
25
|
+
- build user-interfaces with pure javascript/typescript—no JSX, complex tooling, or spooky action-at-a-distance
|
|
26
|
+
- manage application state almost effortlessly—eliminate most binding code
|
|
27
|
+
- written in Typescript, Javascript-friendly
|
|
28
|
+
- use web-components, build your own web-components quickly and easily
|
|
29
|
+
- manage CSS efficiently and flexibly using CSS variables and Color computations
|
|
30
|
+
- leverage existing business logic and libraries without complex wrappers
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
const { elements, tosi, touch } = tosijs
|
|
34
|
+
|
|
35
|
+
const todo = {
|
|
36
|
+
list: [],
|
|
37
|
+
addItem(reminder) {
|
|
38
|
+
if (reminder.trim()) {
|
|
39
|
+
todo.list.push(reminder)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const { readmeTodoDemo } = tosi({ readmeTodoDemo: todo })
|
|
45
|
+
|
|
46
|
+
const { h4, ul, template, li, label, input } = elements
|
|
47
|
+
preview.append(
|
|
48
|
+
h4('To Do List'),
|
|
49
|
+
ul(
|
|
50
|
+
{
|
|
51
|
+
bindList: {
|
|
52
|
+
value: readmeTodoDemo.list
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
template(li({ bindText: '^' }))
|
|
56
|
+
),
|
|
57
|
+
label(
|
|
58
|
+
'Reminder',
|
|
59
|
+
input({
|
|
60
|
+
placeholder: 'enter a reminder',
|
|
61
|
+
onKeydown(event) {
|
|
62
|
+
if (event.key === 'Enter') {
|
|
63
|
+
event.preventDefault()
|
|
64
|
+
readmeTodoDemo.addItem(event.target.value.trim())
|
|
65
|
+
event.target.value = ''
|
|
66
|
+
touch(readmeTodoDemo)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
)
|
|
71
|
+
)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
In general, `tosijs` is able to accomplish the same or better compactness, expressiveness,
|
|
75
|
+
and simplicity as you get with highly-refined React-centric toolchains, but without transpilation,
|
|
76
|
+
domain-specific-languages, or other tricks that provide "convenience" at the cost of becoming locked-in
|
|
77
|
+
to React, a specific state-management system (which permeates your business logic), and usually a specific UI framework.
|
|
78
|
+
|
|
79
|
+
`tosijs` lets you work with pure HTML and web-component as cleanly—more cleanly—and efficiently than
|
|
80
|
+
React toolchains let you work with JSX.
|
|
81
|
+
|
|
82
|
+
export default function App() {
|
|
83
|
+
return (
|
|
84
|
+
<div className="App">
|
|
85
|
+
<h1>Hello React</h1>
|
|
86
|
+
<h2>Start editing to see some magic happen!</h2>
|
|
87
|
+
</div>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
Becomes:
|
|
92
|
+
|
|
93
|
+
const { div, h1, h2 } = elements // exported from tosijs
|
|
94
|
+
export const App = () => div(
|
|
95
|
+
{ class: 'App' },
|
|
96
|
+
h1('Hello tosijs'),
|
|
97
|
+
h2('Start editing to see some magic happen!')
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
Except this reusable component outputs native DOM nodes. No transpilation, spooky magic at a distance,
|
|
101
|
+
or virtual DOM required. And it all works just as well with web-components. This is you get when
|
|
102
|
+
you run App() in the console:
|
|
103
|
+
|
|
104
|
+
▼ <div class="App">
|
|
105
|
+
<h1>Hello tosijs</h1>
|
|
106
|
+
<h2>Start editing to see some magic happen!</h2>
|
|
107
|
+
</div>
|
|
108
|
+
|
|
109
|
+
The ▼ is there to show that's **DOM nodes**, not HTML.
|
|
110
|
+
|
|
111
|
+
`tosijs` lets you lean into web-standards and native browser functionality while writing less code that's
|
|
112
|
+
easier to run, debug, deploy, and maintain. Bind data direct to standard input elements—without having
|
|
113
|
+
to fight their basic behavior—and now you're using _native_ functionality with _deep accessibility_ support
|
|
114
|
+
as opposed to whatever the folks who wrote the library you're using have gotten around to implementing.
|
|
115
|
+
|
|
116
|
+
> **Aside**: `tosijs` will also probably work perfectly well with `Angular`, `Vue`, et al, but I haven't
|
|
117
|
+
> bothered digging into it and don't want to deal with `ngZone` stuff unless someone is paying
|
|
118
|
+
> me.
|
|
119
|
+
|
|
120
|
+
If you want to build your own `web-components` versus use something off-the-rack like
|
|
121
|
+
[Shoelace](https://shoelace.style), `tosijs` offers a `Component` base class that, along with
|
|
122
|
+
its `elements` and `css` libraries allows you to implement component views in pure Javascript
|
|
123
|
+
more compactly than with `jsx` (and without a virtual DOM).
|
|
124
|
+
|
|
125
|
+
import { Component, elements, css } from 'tosijs'
|
|
126
|
+
|
|
127
|
+
const { style, h1, slot } = elements
|
|
128
|
+
export class MyComponent extends Component {
|
|
129
|
+
styleNode = style(css({
|
|
130
|
+
h1: {
|
|
131
|
+
color: 'blue'
|
|
132
|
+
}
|
|
133
|
+
}))
|
|
134
|
+
content = [ h1('hello world'), slot() ]
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
The difference is that `web-components` are drop-in replacements for standard HTML elements
|
|
138
|
+
and interoperate happily with one-another and other libraries, load asynchronously,
|
|
139
|
+
and are natively supported by all modern browsers.
|
|
140
|
+
|
|
141
|
+
## What `tosijs` does
|
|
142
|
+
|
|
143
|
+
### Observe Object State
|
|
144
|
+
|
|
145
|
+
`tosijs` tracks the state of objects you assign to it using `paths` allowing economical
|
|
146
|
+
and direct updates to application state.
|
|
147
|
+
|
|
148
|
+
import { xinProxy, observe } from 'tosijs'
|
|
149
|
+
|
|
150
|
+
const { app } = xinProxy({
|
|
151
|
+
app: {
|
|
152
|
+
prefs: {
|
|
153
|
+
darkmode: false
|
|
154
|
+
},
|
|
155
|
+
docs: [
|
|
156
|
+
{
|
|
157
|
+
id: 1234,
|
|
158
|
+
title: 'title',
|
|
159
|
+
body: 'markdown goes here'
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
observe('app.prefs.darkmode', () => {
|
|
166
|
+
document.body.classList.toggle('dark-mode', app.prefs.darkmode)
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
observe('app.docs', () => {
|
|
170
|
+
// render docs
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
> #### What does `xinProxy` do, and what is a `XinProxy`?
|
|
174
|
+
>
|
|
175
|
+
> `xinProxy` is syntax sugar for assigning something to `xin` (which is a `XinProxyObject`)
|
|
176
|
+
> and then getting it back out again.
|
|
177
|
+
>
|
|
178
|
+
> A `XinProxy` is an [ES Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy)
|
|
179
|
+
> wrapped around an `object` (which in Javascript means anything
|
|
180
|
+
> that has a `constructor` which in particular includes `Array`s, `class` instances, `function`s
|
|
181
|
+
> and so on, but not "scalars" like `number`s, `string`s, `boolean`s, `null`, and `undefined`)
|
|
182
|
+
>
|
|
183
|
+
> All you need to know about a `XinProxy` is that it's Proxy wrapped around your original
|
|
184
|
+
> object that allows you to interact with the object normally, but which allows `tosijs` to
|
|
185
|
+
> **observe** changes made to the wrapped object and tell interested parties about the changes.
|
|
186
|
+
>
|
|
187
|
+
> If you want to original object back you can just hold on to a reference or use `xinValue(someProxy)`
|
|
188
|
+
> to unwrap it.
|
|
189
|
+
|
|
190
|
+
### No Tax, No Packaging
|
|
191
|
+
|
|
192
|
+
`tosijs` does not modify the stuff you hand over to it… it just wraps objects
|
|
193
|
+
with a `Proxy` and then if you use `xin` to make changes to those objects,
|
|
194
|
+
`tosijs` will notify any interested observers.
|
|
195
|
+
|
|
196
|
+
**Note** `xinProxy({foo: {...}})` is syntax sugar for `xin.foo = {...}`.
|
|
197
|
+
|
|
198
|
+
import { xinProxy, observe } from 'tosijs'
|
|
199
|
+
const { foo } = xinProxy({
|
|
200
|
+
foo: {
|
|
201
|
+
bar: 17
|
|
202
|
+
}
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
observe('foo.bar', v => {
|
|
206
|
+
console.log('foo.bar was changed to', xin.foo.bar)
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
foo.bar = 17 // does not trigger the observer
|
|
210
|
+
foo.bar = Math.PI // triggers the observer
|
|
211
|
+
|
|
212
|
+
### Paths are like JavaScript
|
|
213
|
+
|
|
214
|
+
`xin` is designed to behave just like a JavaScript `Object`. What you put
|
|
215
|
+
into it is what you get out of it:
|
|
216
|
+
|
|
217
|
+
import { xin, xinValue } from 'tosijs'
|
|
218
|
+
|
|
219
|
+
const foo = {bar: 'baz'}
|
|
220
|
+
xin.foo = foo
|
|
221
|
+
|
|
222
|
+
// xin.foo returns a Proxy wrapped around foo (without touching foo)
|
|
223
|
+
xinValue(xin.foo) === foo
|
|
224
|
+
|
|
225
|
+
// really, it's just the original object
|
|
226
|
+
xin.foo.bar = 'lurman'
|
|
227
|
+
foo.bar === 'lurman' // true
|
|
228
|
+
|
|
229
|
+
// seriously, it's just the original object
|
|
230
|
+
foo.bar = 'luhrman'
|
|
231
|
+
xin.foo.bar === 'luhrman' // true
|
|
232
|
+
|
|
233
|
+
### …but better!
|
|
234
|
+
|
|
235
|
+
It's very common to deal with arrays of objects that have unique id values,
|
|
236
|
+
so `tosijs` supports the idea of id-paths
|
|
237
|
+
|
|
238
|
+
import { xinProxy, xin } from 'tosijs
|
|
239
|
+
|
|
240
|
+
const { app } = xinProxy ({
|
|
241
|
+
app: {
|
|
242
|
+
list: [
|
|
243
|
+
{
|
|
244
|
+
id: '1234abcd',
|
|
245
|
+
text: 'hello world'
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
id: '5678efgh',
|
|
249
|
+
text: 'so long, redux'
|
|
250
|
+
}
|
|
251
|
+
]
|
|
252
|
+
}
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
console.log(app.list[0].text) // hello world
|
|
256
|
+
console.log(app.list['id=5678efgh']) // so long, redux
|
|
257
|
+
console.log(xin['app.list[id=1234abcd']) // hello world
|
|
258
|
+
|
|
259
|
+
### Telling `xin` about changes using `touch()`
|
|
260
|
+
|
|
261
|
+
Sometimes you will modify an object behind `xin`'s back (e.g. for efficiency).
|
|
262
|
+
When you want to trigger updates, simply touch the path.
|
|
263
|
+
|
|
264
|
+
import { xin, observe, touch } from 'tosijs'
|
|
265
|
+
|
|
266
|
+
const foo = { bar: 17 }
|
|
267
|
+
xin.foo = foo
|
|
268
|
+
observe('foo.bar', path => console.log(path, '->', xin[path])
|
|
269
|
+
xin.foo.bar = -2 // console will show: foo.bar -> -2
|
|
270
|
+
|
|
271
|
+
foo.bar = 100 // nothing happens
|
|
272
|
+
touch('foo.bar') // console will show: foo.bar -> 100
|
|
273
|
+
|
|
274
|
+
### CSS
|
|
275
|
+
|
|
276
|
+
`tosijs` includes utilities for working with css.
|
|
277
|
+
|
|
278
|
+
import {css, vars, initVars, darkMode} from 'tosijs'
|
|
279
|
+
const cssVars = {
|
|
280
|
+
textFont: 'sans-serif'
|
|
281
|
+
color: '#111'
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
`initVars()` processes an object changing its keys from camelCase to --kabob-case:
|
|
285
|
+
|
|
286
|
+
initVars(cssVars) // emits { --text-font: "sans-serif", --color: "#111" }
|
|
287
|
+
|
|
288
|
+
`darkMode()` processes an object, taking only the color properties and inverting their luminance values:
|
|
289
|
+
darkMode(cssVars) // emits { color: '#ededed' }
|
|
290
|
+
|
|
291
|
+
The `vars` simply converts its camelCase properties into css variable references
|
|
292
|
+
|
|
293
|
+
vars.fooBar // emits 'var(--foo-bar)'
|
|
294
|
+
calc(`${vars.width} + 2 * ${vars.spacing}`) // emits 'calc(var(--width) + 2 * var(--spacing))'
|
|
295
|
+
|
|
296
|
+
`css()` processes an object, rendering it as CSS
|
|
297
|
+
|
|
298
|
+
css({
|
|
299
|
+
'.container': {
|
|
300
|
+
'position', 'relative'
|
|
301
|
+
}
|
|
302
|
+
}) // emits .container { position: relative; }
|
|
303
|
+
|
|
304
|
+
## Color
|
|
305
|
+
|
|
306
|
+
`tosijs` includes a powerful `Color` class for manipulating colors.
|
|
307
|
+
|
|
308
|
+
import {Color} from 'tosijs
|
|
309
|
+
const translucentBlue = new Color(0, 0, 255, 0.5) // r, g, b, a parameters
|
|
310
|
+
const postItBackground = Color.fromCss('#e7e79d')
|
|
311
|
+
const darkGrey = Color.fromHsl(0, 0, 0.2)
|
|
312
|
+
|
|
313
|
+
The color objects have computed properties for rendering the color in different ways,
|
|
314
|
+
making adjustments, blending colors, and so forth.
|
|
315
|
+
|
|
316
|
+
## Hot Reload
|
|
317
|
+
|
|
318
|
+
One of the nice things about working with the React toolchain is hot reloading.
|
|
319
|
+
`tosijs` supports hot reloading (and not just in development!) via the `hotReload()`
|
|
320
|
+
function:
|
|
321
|
+
|
|
322
|
+
import {xin, hotReload} from 'tosijs'
|
|
323
|
+
|
|
324
|
+
xin.app = {
|
|
325
|
+
...
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
hotReload()
|
|
329
|
+
|
|
330
|
+
`hotReload` stores serializable state managed by `xin` in localStorage and restores
|
|
331
|
+
it (by overlay) on reload. Because any functions (for example) won't be persisted,
|
|
332
|
+
simply call `hotReload` after initializing your app state and you're good to go.
|
|
333
|
+
|
|
334
|
+
`hotReload` accepts a test function (path => boolean) as a parameter.
|
|
335
|
+
Only top-level properties in `xin` that pass the test will be persisted.
|
|
336
|
+
|
|
337
|
+
To completely reset the app, run `localStorage.clear()` in the console.
|
|
338
|
+
|
|
339
|
+
### Types
|
|
340
|
+
|
|
341
|
+
`tosijs` [type-by-example](https://www.npmjs.com/package/type-by-example) has been
|
|
342
|
+
broken out into a separate standalone library. (Naturally it works very well with
|
|
343
|
+
tosijs but they are completely independent.)
|
|
344
|
+
|
|
345
|
+
## Development Notes
|
|
346
|
+
|
|
347
|
+
You'll need to install [bun](https://bun.sh/) and [nodejs](https://nodejs.org)),
|
|
348
|
+
and then run `npm install` and `bun install`. `bun` is used because it's
|
|
349
|
+
**fast** and is a really nice test-runner.
|
|
350
|
+
|
|
351
|
+
To work interactively on the demo code, use `bun start`. This runs the demo
|
|
352
|
+
site on localhost.
|
|
353
|
+
|
|
354
|
+
To build everything run `bun run make` which builds production versions of the
|
|
355
|
+
demo site (in `www`) and the `dist` and `cdn` directories.
|
|
356
|
+
|
|
357
|
+
To create a local package (for experimenting with a build) run `bun pack`.
|
|
358
|
+
|
|
359
|
+
### Parcel Occasionally Gets Screwed Up
|
|
360
|
+
|
|
361
|
+
- remove all the parcel transformer dependencies @parcel/\*
|
|
362
|
+
- rm -rf node_modules
|
|
363
|
+
- run the update script
|
|
364
|
+
- npx parcel build (which restores needed parcel transformers)
|
|
365
|
+
|
|
366
|
+
## Related Libraries
|
|
367
|
+
|
|
368
|
+
- react-tosijs [react-tosijs](https://github.com/tonioloewald/react-tosijs#readme)
|
|
369
|
+
allows you to use xin's path-observer model in React [ReactJS](https://reactjs.org) apps
|
|
370
|
+
- type-by-example [github](https://github.com/tonioloewald/type-by-example) | [npm](https://www.npmjs.com/package/type-by-example)
|
|
371
|
+
is a library for declaring types in pure javascript, allowing run-time type-checking.
|
|
372
|
+
- filter-shapes [github](https://github.com/tonioloewald/filter-shapes) | [npm](https://www.npmjs.com/package/filter-shapes)
|
|
373
|
+
is a library for filtering objects (and arrays of objects) to specific shapes (e.g. to reduce storage / bandwidth costs).
|
|
374
|
+
It is built on top of type-by-example.
|
|
375
|
+
|
|
376
|
+
## Credits
|
|
377
|
+
|
|
378
|
+
`tosijs` is in essence a highly incompatible update to `b8rjs` with the goal
|
|
379
|
+
of removing cruft, supporting more use-cases, and eliminating functionality
|
|
380
|
+
that has been made redundant by improvements to the JavaScript language and
|
|
381
|
+
DOM APIs.
|
|
382
|
+
|
|
383
|
+
`tosijs` is being developed using [bun](https://bun.sh/).
|
|
384
|
+
`bun` is crazy fast (based on Webkit's JS engine, vs. V8), does a lot of stuff
|
|
385
|
+
natively, and runs TypeScript (with import and require) directly.
|
package/dist/bind.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { XinEventHandler, XinTouchableType, XinBinding, XinBindingSpec, EventType } from './xin-types';
|
|
2
|
+
export declare const touchElement: (element: Element, changedPath?: string) => void;
|
|
3
|
+
interface BindingOptions {
|
|
4
|
+
[key: string]: any;
|
|
5
|
+
}
|
|
6
|
+
export declare function bind<T extends Element = Element>(element: T, what: XinTouchableType | XinBindingSpec, binding: XinBinding<T>, options?: BindingOptions): T;
|
|
7
|
+
type RemoveListener = VoidFunction;
|
|
8
|
+
export declare function on<E extends HTMLElement, K extends EventType>(element: E, eventType: K, eventHandler: XinEventHandler<HTMLElementEventMap[K], E>): RemoveListener;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Component } from './component';
|
|
2
|
+
import { XinPackagedComponent } from './make-component';
|
|
3
|
+
export declare class Blueprint extends Component {
|
|
4
|
+
tag: string;
|
|
5
|
+
src: string;
|
|
6
|
+
property: string;
|
|
7
|
+
loaded?: XinPackagedComponent;
|
|
8
|
+
blueprintLoaded: (_package: XinPackagedComponent) => void;
|
|
9
|
+
packaged(): Promise<XinPackagedComponent>;
|
|
10
|
+
constructor();
|
|
11
|
+
}
|
|
12
|
+
export declare const blueprint: import("./xin-types").ElementCreator<Component<import("./xin-types").PartsMap>>;
|
|
13
|
+
export declare class BlueprintLoader extends Component {
|
|
14
|
+
allLoaded: () => void;
|
|
15
|
+
constructor();
|
|
16
|
+
private load;
|
|
17
|
+
connectedCallback(): void;
|
|
18
|
+
}
|
|
19
|
+
export declare const blueprintLoader: import("./xin-types").ElementCreator<Component<import("./xin-types").PartsMap>>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { XinObject, XinArray } from './xin-types';
|
|
2
|
+
type Part = string | string[];
|
|
3
|
+
type PartArray = Part[];
|
|
4
|
+
declare function pathParts(path: string | PartArray): PartArray;
|
|
5
|
+
declare function getByPath(obj: XinObject | XinArray, path: string): any;
|
|
6
|
+
declare function setByPath(orig: XinObject | XinArray, path: string, val: any): boolean;
|
|
7
|
+
declare function deleteByPath(orig: XinObject, path: string): void;
|
|
8
|
+
export { getByPath, setByPath, deleteByPath, pathParts };
|
package/dist/color.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { CSSSystemColor } from './css-system-color';
|
|
2
|
+
declare class HslColor {
|
|
3
|
+
h: number;
|
|
4
|
+
s: number;
|
|
5
|
+
l: number;
|
|
6
|
+
constructor(r: number, g: number, b: number);
|
|
7
|
+
}
|
|
8
|
+
export declare class Color {
|
|
9
|
+
r: number;
|
|
10
|
+
g: number;
|
|
11
|
+
b: number;
|
|
12
|
+
a: number;
|
|
13
|
+
static fromVar(varName: string, element?: HTMLElement): Color;
|
|
14
|
+
static fromCss(spec: CSSSystemColor | string): Color;
|
|
15
|
+
static fromHsl(h: number, s: number, l: number, a?: number): Color;
|
|
16
|
+
static black: Color;
|
|
17
|
+
static white: Color;
|
|
18
|
+
constructor(r: number, g: number, b: number, a?: number);
|
|
19
|
+
get inverse(): Color;
|
|
20
|
+
get inverseLuminance(): Color;
|
|
21
|
+
contrasting(amount?: number): Color;
|
|
22
|
+
get rgb(): string;
|
|
23
|
+
get rgba(): string;
|
|
24
|
+
get RGBA(): number[];
|
|
25
|
+
get ARGB(): number[];
|
|
26
|
+
private hslCached?;
|
|
27
|
+
get _hsl(): HslColor;
|
|
28
|
+
get hsl(): string;
|
|
29
|
+
get hsla(): string;
|
|
30
|
+
get mono(): Color;
|
|
31
|
+
get brightness(): number;
|
|
32
|
+
get html(): string;
|
|
33
|
+
toString(): string;
|
|
34
|
+
brighten(amount: number): Color;
|
|
35
|
+
darken(amount: number): Color;
|
|
36
|
+
saturate(amount: number): Color;
|
|
37
|
+
desaturate(amount: number): Color;
|
|
38
|
+
rotate(amount: number): Color;
|
|
39
|
+
opacity(alpha: number): Color;
|
|
40
|
+
swatch(): Color;
|
|
41
|
+
blend(otherColor: Color, t: number): Color;
|
|
42
|
+
static blendHue(a: number, b: number, t: number): number;
|
|
43
|
+
mix(otherColor: Color, t: number): Color;
|
|
44
|
+
colorMix(otherColor: Color, t: number): Color;
|
|
45
|
+
}
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { XinStyleSheet } from './css-types';
|
|
2
|
+
import { ElementsProxy } from './elements';
|
|
3
|
+
import { ElementCreator, ContentType, PartsMap } from './xin-types';
|
|
4
|
+
interface ElementCreatorOptions extends ElementDefinitionOptions {
|
|
5
|
+
tag?: string;
|
|
6
|
+
styleSpec?: XinStyleSheet;
|
|
7
|
+
}
|
|
8
|
+
export declare abstract class Component<T = PartsMap> extends HTMLElement {
|
|
9
|
+
static elements: ElementsProxy;
|
|
10
|
+
private static _elementCreator?;
|
|
11
|
+
instanceId: string;
|
|
12
|
+
styleNode?: HTMLStyleElement;
|
|
13
|
+
static styleSpec?: XinStyleSheet;
|
|
14
|
+
static styleNode?: HTMLStyleElement;
|
|
15
|
+
content: ContentType | (() => ContentType) | null;
|
|
16
|
+
isSlotted?: boolean;
|
|
17
|
+
private static _tagName;
|
|
18
|
+
static get tagName(): null | string;
|
|
19
|
+
[key: string]: any;
|
|
20
|
+
static StyleNode(styleSpec: XinStyleSheet): HTMLStyleElement;
|
|
21
|
+
static elementCreator(options?: ElementCreatorOptions): ElementCreator<Component>;
|
|
22
|
+
initAttributes(...attributeNames: string[]): void;
|
|
23
|
+
private initValue;
|
|
24
|
+
private _parts?;
|
|
25
|
+
get parts(): T;
|
|
26
|
+
constructor();
|
|
27
|
+
connectedCallback(): void;
|
|
28
|
+
disconnectedCallback(): void;
|
|
29
|
+
private _changeQueued;
|
|
30
|
+
private _renderQueued;
|
|
31
|
+
queueRender(triggerChangeEvent?: boolean): void;
|
|
32
|
+
private _hydrated;
|
|
33
|
+
private hydrate;
|
|
34
|
+
render(): void;
|
|
35
|
+
}
|
|
36
|
+
export declare const xinSlot: ElementCreator<Component<PartsMap>>;
|
|
37
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type CSSSystemColor = 'aliceblue' | 'antiquewhite' | 'aqua' | 'aquamarine' | 'azure' | 'beige' | 'bisque' | 'black' | 'blanchedalmond' | 'blue' | 'blueviolet' | 'brown' | 'burlywood' | 'cadetblue' | 'chartreuse' | 'chocolate' | 'coral' | 'cornflowerblue' | 'cornsilk' | 'crimson' | 'cyan' | 'darkblue' | 'darkcyan' | 'darkgoldenrod' | 'darkgray' | 'darkgreen' | 'darkgrey' | 'darkkhaki' | 'darkmagenta' | 'darkolivegreen' | 'darkorange' | 'darkorchid' | 'darkred' | 'darksalmon' | 'darkseagreen' | 'darkslateblue' | 'darkslategray' | 'darkslategrey' | 'darkturquoise' | 'darkviolet' | 'deeppink' | 'deepskyblue' | 'dimgray' | 'dimgrey' | 'dodgerblue' | 'firebrick' | 'floralwhite' | 'forestgreen' | 'fuchsia' | 'gainsboro' | 'ghostwhite' | 'gold' | 'goldenrod' | 'gray' | 'green' | 'greenyellow' | 'grey' | 'honeydew' | 'hotpink' | 'indianred' | 'indigo' | 'ivory' | 'khaki' | 'lavender' | 'lavenderblush' | 'lawngreen' | 'lemonchiffon' | 'lightblue' | 'lightcoral' | 'lightcyan' | 'lightgoldenrodyellow' | 'lightgray' | 'lightgreen' | 'lightgrey' | 'lightpink' | 'lightsalmon' | 'lightseagreen' | 'lightskyblue' | 'lightslategray' | 'lightslategrey' | 'lightsteelblue' | 'lightyellow' | 'lime' | 'limegreen' | 'linen' | 'magenta' | 'maroon' | 'mediumaquamarine' | 'mediumblue' | 'mediumorchid' | 'mediumpurple' | 'mediumseagreen' | 'mediumslateblue' | 'mediumspringgreen' | 'mediumturquoise' | 'mediumvioletred' | 'midnightblue' | 'mintcream' | 'mistyrose' | 'moccasin' | 'navajowhite' | 'navy' | 'oldlace' | 'olive' | 'olivedrab' | 'orange' | 'orangered' | 'orchid' | 'palegoldenrod' | 'palegreen' | 'paleturquoise' | 'palevioletred' | 'papayawhip' | 'peachpuff' | 'peru' | 'pink' | 'plum' | 'powderblue' | 'purple' | 'red' | 'rosybrown' | 'royalblue' | 'saddlebrown' | 'salmon' | 'sandybrown' | 'seagreen' | 'seashell' | 'sienna' | 'silver' | 'skyblue' | 'slateblue' | 'slategray' | 'slategrey' | 'snow' | 'springgreen' | 'steelblue' | 'tan' | 'teal' | 'thistle' | 'tomato' | 'turquoise' | 'violet' | 'wheat' | 'white' | 'whitesmoke' | 'yellow' | 'yellowgreen';
|