aberdeen 0.2.1 → 0.2.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 (51) hide show
  1. package/dist/aberdeen.d.ts +573 -0
  2. package/dist/aberdeen.js +1756 -0
  3. package/dist/aberdeen.js.map +1 -0
  4. package/dist/prediction.d.ts +29 -0
  5. package/dist/prediction.js +110 -0
  6. package/dist/prediction.js.map +1 -0
  7. package/dist/route.d.ts +16 -0
  8. package/dist/route.js +119 -0
  9. package/dist/route.js.map +1 -0
  10. package/dist/transitions.d.ts +18 -0
  11. package/dist/transitions.js +67 -0
  12. package/dist/transitions.js.map +1 -0
  13. package/package.json +5 -2
  14. package/.github/workflows/deploy.yml +0 -43
  15. package/.vscode/launch.json +0 -23
  16. package/examples/input/index.html +0 -8
  17. package/examples/input/input.css +0 -56
  18. package/examples/input/input.js +0 -66
  19. package/examples/list/index.html +0 -7
  20. package/examples/list/list.js +0 -47
  21. package/examples/router/index.html +0 -8
  22. package/examples/router/page-home.js +0 -12
  23. package/examples/router/page-list.js +0 -35
  24. package/examples/router/page-settings.js +0 -6
  25. package/examples/router/router.js +0 -76
  26. package/examples/router/style.css +0 -88
  27. package/examples/tic-tac-toe/index.html +0 -8
  28. package/examples/tic-tac-toe/tic-tac-toe.css +0 -50
  29. package/examples/tic-tac-toe/tic-tac-toe.js +0 -90
  30. package/tests/_fakedom.js +0 -255
  31. package/tests/_init.js +0 -81
  32. package/tests/array.js +0 -109
  33. package/tests/binding.js +0 -106
  34. package/tests/browsers.js +0 -22
  35. package/tests/clean.js +0 -26
  36. package/tests/count.js +0 -105
  37. package/tests/create.js +0 -92
  38. package/tests/destroy.js +0 -270
  39. package/tests/dom.js +0 -219
  40. package/tests/errors.js +0 -114
  41. package/tests/immediate.js +0 -87
  42. package/tests/map.js +0 -76
  43. package/tests/objmap.js +0 -40
  44. package/tests/onEach.js +0 -392
  45. package/tests/prediction.js +0 -97
  46. package/tests/props.js +0 -49
  47. package/tests/schedule.js +0 -44
  48. package/tests/scope.js +0 -277
  49. package/tests/sort.js +0 -105
  50. package/tests/store.js +0 -254
  51. package/tsconfig.json +0 -67
@@ -1,66 +0,0 @@
1
- import {node, Store, mount, text, observe} from '../../dist/aberdeen.js'
2
- import {grow, shrink} from '../../dist/transitions.js'
3
-
4
- const store = new Store({
5
- name: 'John Doe',
6
- age: 23,
7
- gender: 'w',
8
- active: false,
9
- vehicle: 'car',
10
- bio: 'John was born on an unknown date at an unknown location.\n\nHis main claim to fame is showing up out of nowhere.',
11
- color: '#00fa9a',
12
- })
13
-
14
- mount(document.body, () => {
15
- node('h2', () => {
16
- text((store.get('name') || "Nobody") + "'s biography")
17
- })
18
- node('input', store.ref('name'))
19
- node('input', {type: 'number', placeholder: 'Age'}, store.ref('age'))
20
- node('label', () => {
21
- node('input', {type: 'checkbox'}, store.ref('active'))
22
- text('Active member')
23
- })
24
- observe(() => {
25
- if (store.get('active')) node('input', {type: 'number', placeholder: 'Member id', create: grow, destroy: shrink}, store.ref('member_id'))
26
- else store.delete('member_id')
27
- })
28
- node('select', () => {
29
- node('option', {value: "m"}, "Man")
30
- node('option', {value: "w"}, "Woman")
31
- node('option', {value: "o"}, "Other..")
32
- }, store.ref('gender'))
33
-
34
- observe(() => {
35
- if (store.get('gender')==='o') node('input', {placeholder: 'Specify gender', create: grow, destroy: shrink}, store.ref('gender_other'))
36
- else store.delete('gender_other')
37
- })
38
-
39
- node('fieldset', () => {
40
- const vehicles = {plane: 'Plane', car: 'Car', bike: 'Bicycle', none: 'None'}
41
- for(let id in vehicles) {
42
- node('label', () => {
43
- node('input', {type: 'radio', name: 'vehicle', value: id}, store.ref('vehicle'))
44
- text(vehicles[id])
45
- })
46
- }
47
- })
48
-
49
- node('textarea', {placeholder: "Biography"}, store.ref('bio'))
50
-
51
- node('label', () => {
52
- node('input', {type: 'color'}, store.ref('color'))
53
- text('Favorite color')
54
- })
55
-
56
- node('input', {type: 'range', min: 50, max: 230}, store.ref('height'))
57
-
58
- node('input', {type: 'date'}, store.ref('first_day'))
59
-
60
- node('pre', () => {
61
- text(JSON.stringify(store.get(), undefined, 4))
62
- })
63
- })
64
-
65
-
66
-
@@ -1,7 +0,0 @@
1
- <!doctype html>
2
- <head>
3
- <meta charset="utf-8">
4
- </head>
5
- <body>
6
- <script type="module" src="list.js"></script>
7
- </body>
@@ -1,47 +0,0 @@
1
- import {node, mount, Store, text} from '../../dist/aberdeen.js';
2
-
3
- const items = new Store([])
4
- const orderIndex = new Store(0)
5
- const search = new Store("")
6
-
7
- const makeWord = () => Math.random().toString(36).substring(2, 12).replace(/[0-9]+/g, '').replace(/^\w/, c => c.toUpperCase());
8
-
9
- const COLUMN_NAMES= ["First name", "Last name", "Age", "Gender", "City"]
10
-
11
- const addItems = (count) => {
12
- for(let i=0; i<count; i++) {
13
- items.push([
14
- makeWord(),
15
- makeWord(),
16
- 0 | (Math.random() * 99),
17
- Math.random()<0.5 ? 'male' : 'female',
18
- makeWord()
19
- ])
20
- }
21
- }
22
-
23
- addItems(100)
24
-
25
- mount(document.body, () => {
26
- node('button', 'Add 10', {click: () => addItems(10)})
27
- node('button', 'Add 100', {click: () => addItems(100)})
28
- node('button', 'Add 1000', {click: () => addItems(1000)})
29
- node('input', {placeholder: 'Search first name', autofocus: true}, search)
30
- node('table.game', () => {
31
- node('tr', () => {
32
- for(let i=0; i<COLUMN_NAMES.length; i++) {
33
- node('th', COLUMN_NAMES[i], {click: () => orderIndex.set(i)})
34
- }
35
- })
36
- items.onEach(item => {
37
- node('tr', () => {
38
- item.onEach(field => {
39
- node('td', () => {
40
- text(field.get())
41
- })
42
- })
43
- node('td', '⌫', {click: () => item.set()})
44
- })
45
- }, item => item.get(0).toLowerCase().startsWith(search.get().toLowerCase()) ? item.get(orderIndex.get()) : undefined)
46
- })
47
- })
@@ -1,8 +0,0 @@
1
- <!doctype html>
2
- <head>
3
- <meta charset="utf-8">
4
- <link rel="stylesheet" type="text/css" href="style.css">
5
- </head>
6
- <body>
7
- <script type="module" src="router.js"></script>
8
- </body>
@@ -1,12 +0,0 @@
1
- // import {node, mount, Store, text, router} from 'https://cdn.jsdelivr.net/npm/aberdeen/+esm';
2
- import {node} from '../../dist/aberdeen.js';
3
-
4
- export default function() {
5
- node('h3', 'Welcome home!!')
6
- node('ul', () => {
7
- node('li', "Use the tabs to navigate between dynamically loaded pages. They will be pushed to the browser history.")
8
- node('li', "The List tab demos the use of subpages and a live updating search query parameter.")
9
- node('li', "Click 'Modal!' to open a modal. It can be closed using browser back. Closing it by clicking the background drop will also remove it from the stack.")
10
- node('li', "Click 'LOGO' to go home. The stack will be unwound (going back) until the last time this page was visited or the first page in our session.")
11
- })
12
- }
@@ -1,35 +0,0 @@
1
- // import {node, mount, Store, text, router} from 'https://cdn.jsdelivr.net/npm/aberdeen/+esm';
2
- import {node, prop} from '../../dist/aberdeen.js';
3
- import {route} from "../../dist/route.js";
4
-
5
- const words = ['butterfly', 'orchestra', 'whisper', 'mountain', 'zebra', 'chocolate', 'umbrella', 'lighthouse', 'rainbow', 'dragon', 'bicycle', 'galaxy', 'penguin', 'tornado', 'waterfall', 'cinnamon', 'compass', 'firefly', 'carousel', 'telescope'];
6
-
7
- export default function() {
8
- node('input', route.makeRef('search', 'filter'), {placeholder: 'Filter'})
9
-
10
- node('.columns', () => {
11
-
12
- // The list of words
13
- node('nav.vertical', () => {
14
- for(let word of words) {
15
- node('button', word, {click: () => route.set('p', 1, word)}, () => {
16
- prop('class', {active: route.get('p', 1) === word})
17
- prop('style', {display: word.indexOf(route.get('search', 'filter') || '') >= 0 ? '' : 'none' })
18
- })
19
- }
20
- })
21
-
22
- // The detail view for the selected word
23
- node('section', () => {
24
- const word = route.get('p', 1)
25
- if (!word) return
26
- if (words.indexOf(word) < 0) {
27
- // Word specified in URL is not in our list. Go back to list without selection.
28
- route.merge({mode: 'back', p: {1: undefined}})
29
- return
30
- }
31
- node('h2', word)
32
- node('p', `This word has ${word.length} letters.`)
33
- })
34
- })
35
- }
@@ -1,6 +0,0 @@
1
- // import {node, mount, Store, text, router} from 'https://cdn.jsdelivr.net/npm/aberdeen/+esm';
2
- import {node} from '../../dist/aberdeen.js';
3
-
4
- export default function() {
5
- node('p', 'Yeah, settings!')
6
- }
@@ -1,76 +0,0 @@
1
- // import {node, mount, Store, text, router} from 'https://cdn.jsdelivr.net/npm/aberdeen/+esm';
2
- import {node, mount, Store, text, observe, prop} from '../../dist/aberdeen.js';
3
- import {route} from "../../dist/route.js";
4
- import {grow, shrink} from "../../dist/transitions.js"
5
-
6
- // This is not something you'd normally do: when opening this example from a file
7
- // (instead of serving it from a well-configured backend), fake the initial path
8
- // as if it were `/`.
9
- if (route.get('p').indexOf('router') >= 0) route.set({path: '/'})
10
-
11
- // Load modules on-demand
12
- const modules = new Store({})
13
- function loadModule(name) {
14
- const module = modules.get(name)
15
- if (module==null) backgroundLoadModule(name)
16
- return module
17
- }
18
- async function backgroundLoadModule(name) {
19
- let module
20
- try {
21
- module = await import(`./page-${name||'home'}.js`)
22
- } catch(e) {
23
- console.error(e)
24
- module = false
25
- }
26
- modules.set(name, module)
27
- }
28
-
29
- // Are main page component
30
- function drawTemplate() {
31
- node('header', () => {
32
- node('nav', () => {
33
- node('button.no-line.logo', 'LOGO', {click: () => route.set({path: '/'})})
34
- // Draw the top navigation bar
35
- const menu = {"": 'Home', settings: 'Settings', list: 'List'}
36
- for(const [id, label] of Object.entries(menu)) {
37
- node('button', label, {click: () => route.set({p: [id]})}, () => {
38
- prop('class', {active: route.get('p', 0) === id})
39
- })
40
- }
41
- node('div', {style: {flex: 1}})
42
- node('button.no-line', 'Modal!', {click: () => route.set('state', 'modal', 'home')})
43
- })
44
- })
45
-
46
- node('main', () => {
47
- let module = loadModule(route.get('p', 0))
48
- if (module) module.default()
49
- else if (module===false) node('p', 'No such page!')
50
- else node('p', 'Loading...')
51
- })
52
-
53
- node("footer", () => {
54
- route.dump()
55
- })
56
-
57
- observe(() => {
58
- let modal = route.get('state', 'modal');
59
- if (!modal) return
60
- node('.modal-bg', () => {
61
- node('.modal', () => {
62
- let module = loadModule(modal);
63
- if (module) module.default()
64
- else if (module===false) node('p', 'No such modal!')
65
- else node('p', 'Loading...')
66
- })
67
- }, {
68
- click: function(e) {if (e.target===this) route.merge({mode: 'back', state: {modal: undefined}})},
69
- create: grow,
70
- destroy: shrink,
71
- })
72
-
73
- })
74
- }
75
-
76
- mount(document.body, drawTemplate)
@@ -1,88 +0,0 @@
1
- body, html {
2
- padding: 0;
3
- margin: 0;
4
- }
5
- * {
6
- box-sizing: border-box;
7
- }
8
- main {
9
- padding: 20px;
10
- }
11
- .columns {
12
- display: flex;
13
- gap: 20px;
14
- }
15
- nav {
16
- display: flex;
17
- gap: 10px;
18
- }
19
- nav.vertical {
20
- flex-direction: column;
21
- gap: 5px;
22
- }
23
- button {
24
- margin-top: 10px;
25
- border: 0;
26
- background-color: transparent;
27
- border-bottom: 2px solid #ccc;
28
- cursor: pointer;
29
- }
30
- button.no-line {
31
- border: 0;
32
- }
33
- nav.vertical button {
34
- border-right: 2px solid #ccc;
35
- border-bottom: 0;
36
- }
37
- button.active {
38
- border-color: #2150ac !important;
39
- }
40
- header {
41
- display: fixed;
42
- top: 0;
43
- left: 0;
44
- right: 0;
45
- padding: 10px 20px;
46
- box-shadow: 0 0 10px black;
47
- }
48
- .modal-bg {
49
- position: fixed;
50
- top: 0;
51
- left: 0;
52
- width: 100%;
53
- height: 100%;
54
- background-color: rgba(0, 0, 0, 0.5);
55
- display: flex;
56
- justify-content: center;
57
- align-items: center;
58
- z-index: 1000;
59
- }
60
-
61
- .modal {
62
- background-color: white;
63
- padding: 20px;
64
- border-radius: 8px;
65
- max-width: 500px;
66
- width: 90%;
67
- position: relative;
68
- z-index: 1001;
69
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
70
- }
71
-
72
- .logo {
73
- font-weight: bold;
74
- text-shadow: 0 0 4px #2150ac;
75
- }
76
-
77
- footer {
78
- color: #888;
79
- display: fixed;
80
- left: 0;
81
- bottom: 0;
82
- right: 0;
83
- padding: 10px 20px;
84
- }
85
-
86
- footer ul {
87
- margin: 0;
88
- }
@@ -1,8 +0,0 @@
1
- <!doctype html>
2
- <head>
3
- <meta charset="utf-8">
4
- <link rel="stylesheet" href="tic-tac-toe.css">
5
- </head>
6
- <body>
7
- <script type="module" src="tic-tac-toe.js"></script>
8
- </body>
@@ -1,50 +0,0 @@
1
- body {
2
- font: 14px "Century Gothic", Futura, sans-serif;
3
- margin: 20px;
4
- }
5
-
6
- ol, ul {
7
- padding-left: 30px;
8
- }
9
-
10
- .board-row:after {
11
- clear: both;
12
- content: "";
13
- display: table;
14
- }
15
-
16
- .status {
17
- margin-bottom: 10px;
18
- }
19
-
20
- .square {
21
- background: #fff;
22
- border: 1px solid #999;
23
- float: left;
24
- font-size: 24px;
25
- font-weight: bold;
26
- line-height: 34px;
27
- height: 34px;
28
- margin-right: -1px;
29
- margin-top: -1px;
30
- padding: 0;
31
- text-align: center;
32
- width: 34px;
33
- }
34
-
35
- .square:focus {
36
- outline: none;
37
- }
38
-
39
- .kbd-navigation .square:focus {
40
- background: #ddd;
41
- }
42
-
43
- .game {
44
- display: flex;
45
- flex-direction: row;
46
- }
47
-
48
- .game-info {
49
- margin-left: 20px;
50
- }
@@ -1,90 +0,0 @@
1
- import {node, prop, mount, Store, text} from '../../dist/aberdeen.js';
2
-
3
- const store = new Store({
4
- squares: [],
5
- turn: 'X',
6
- history: [{}],
7
- })
8
-
9
- const drawSquare = (position) => {
10
- node('button.square', () => {
11
- let value = store.get('squares', position)
12
- if (value) text(value)
13
- else prop('click', () => fillSquare(position))
14
- })
15
- }
16
-
17
- const drawBoard = () => {
18
- for(let y=0; y<3; y++) {
19
- node('div.board-row', () => {
20
- for(let x=0; x<3; x++) {
21
- drawSquare(y*3 + x)
22
- }
23
- })
24
- }
25
- }
26
-
27
- const drawInfo = () => {
28
- node('div', () => {
29
- let winner = calculateWinner(store.get('squares'))
30
- if (winner) {
31
- text(`Winner: ${winner}`)
32
- } else {
33
- text(`Next player: ${store.get('turn')}`)
34
- }
35
- })
36
- node('ol', () => {
37
- store.onEach('history', item => {
38
- node('li', () => {
39
- node('button', () => {
40
- text(item.index() ? `Go to move ${item.index()}` : `Go to game start`)
41
- prop('click', () => {
42
- store.set('historyPos', item.index())
43
- store.set('squares', item.get())
44
- })
45
- })
46
- })
47
- })
48
- })
49
- }
50
-
51
- const fillSquare = (position) => {
52
- // If there's already a winner, don't allow a new square to be filled
53
- if (calculateWinner(store.get('squares'))) return
54
-
55
- // Fill the square
56
- store.set('squares', position, store.get('turn'))
57
-
58
- // Next player's turn
59
- store.set('turn', store.get('turn')==='X' ? 'O' : 'X')
60
-
61
- if (store.get('historyPos') != null) {
62
- // Truncate everything after history pos
63
- store.set('history', store.get('history').slice(0,store.get('historyPos')+1))
64
- // Stop 'time traveling'
65
- store.delete('historyPos')
66
- }
67
-
68
- // Append the current squares-state to the history array
69
- store.push('history', store.get('squares'))
70
- }
71
-
72
- const calculateWinner = (squares) => {
73
- const lines = [
74
- [0, 1, 2], [3, 4, 5], [6, 7, 8], // horizontal
75
- [0, 3, 6], [1, 4, 7], [2, 5, 8], // vertical
76
- [0, 4, 8], [2, 4, 6] // diagonal
77
- ];
78
- for (const [a, b, c] of lines) {
79
- if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
80
- return squares[a];
81
- }
82
- }
83
- }
84
-
85
- mount(document.body, () => {
86
- node('div.game', () => {
87
- node('div.game-board', drawBoard)
88
- node('div.game-info', drawInfo)
89
- })
90
- })