jaxs 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 (67) hide show
  1. package/.env +1 -0
  2. package/.parcel-cache/6f14daf302269614-BundleGraph-0 +0 -0
  3. package/.parcel-cache/7d3d872b02d671a6-AssetGraph-0 +0 -0
  4. package/.parcel-cache/8e029bb14f8992df-RequestGraph-0 +0 -0
  5. package/.parcel-cache/a5394978e4ece10b-AssetGraph-0 +0 -0
  6. package/.parcel-cache/b5686051ae060930.txt +2 -0
  7. package/.parcel-cache/data.mdb +0 -0
  8. package/.parcel-cache/lock.mdb +0 -0
  9. package/README.md +15 -0
  10. package/bun.lockb +0 -0
  11. package/bundle.ts +5 -0
  12. package/bunfig.toml +0 -0
  13. package/cypress/e2e/add-remove-nested-children.cy.js +39 -0
  14. package/cypress/e2e/add-remove-root-children.cy.js +37 -0
  15. package/cypress/jaxs-apps/add-remove-nested-children.html +12 -0
  16. package/cypress/jaxs-apps/add-remove-nested-children.jsx +84 -0
  17. package/cypress/jaxs-apps/add-remove-root-children.html +15 -0
  18. package/cypress/jaxs-apps/add-remove-root-children.jsx +53 -0
  19. package/cypress/jaxs-apps/dist/add-remove-nested-children.afcab974.js +717 -0
  20. package/cypress/jaxs-apps/dist/add-remove-nested-children.afcab974.js.map +1 -0
  21. package/cypress/jaxs-apps/dist/add-remove-nested-children.html +12 -0
  22. package/cypress/jaxs-apps/dist/add-remove-root-children.3bb9b3f5.js +1682 -0
  23. package/cypress/jaxs-apps/dist/add-remove-root-children.3bb9b3f5.js.map +1 -0
  24. package/cypress/jaxs-apps/dist/add-remove-root-children.fbb4ec9b.js +706 -0
  25. package/cypress/jaxs-apps/dist/add-remove-root-children.fbb4ec9b.js.map +1 -0
  26. package/cypress/jaxs-apps/dist/add-remove-root-children.html +15 -0
  27. package/cypress/support/commands.js +25 -0
  28. package/cypress/support/e2e.js +20 -0
  29. package/cypress.config.js +10 -0
  30. package/dist/jaxs.js +1154 -0
  31. package/package.json +38 -0
  32. package/src/app.ts +64 -0
  33. package/src/debugging.js +5 -0
  34. package/src/jaxs.ts +8 -0
  35. package/src/jsx.js +27 -0
  36. package/src/messageBus.ts +70 -0
  37. package/src/navigation/findHref.js +10 -0
  38. package/src/navigation/routeState.js +15 -0
  39. package/src/navigation/setupHistory.js +38 -0
  40. package/src/navigation/setupNavigation.js +25 -0
  41. package/src/navigation.ts +2 -0
  42. package/src/rendering/change/compile.ts +1 -0
  43. package/src/rendering/change/instructions/attributes.ts +78 -0
  44. package/src/rendering/change/instructions/children.ts +128 -0
  45. package/src/rendering/change/instructions/element.ts +42 -0
  46. package/src/rendering/change/instructions/events.ts +51 -0
  47. package/src/rendering/change/instructions/generate.ts +122 -0
  48. package/src/rendering/change/instructions/idMap.js +55 -0
  49. package/src/rendering/change/instructions/node.ts +38 -0
  50. package/src/rendering/change/instructions/text.ts +10 -0
  51. package/src/rendering/change.ts +131 -0
  52. package/src/rendering/dom/attributesAndEvents.ts +33 -0
  53. package/src/rendering/dom/create.ts +68 -0
  54. package/src/rendering/templates/bound.js +55 -0
  55. package/src/rendering/templates/children.ts +91 -0
  56. package/src/rendering/templates/root.ts +55 -0
  57. package/src/rendering/templates/tag.ts +70 -0
  58. package/src/rendering/templates/text.ts +17 -0
  59. package/src/state/equality.js +36 -0
  60. package/src/state/stores.js +63 -0
  61. package/src/state/testingTypes.js +6 -0
  62. package/src/state.js +89 -0
  63. package/src/types.ts +149 -0
  64. package/src/views/conditionals.jsx +18 -0
  65. package/src/views/link.jsx +5 -0
  66. package/src/views.js +7 -0
  67. package/tsconfig.json +26 -0
package/.env ADDED
@@ -0,0 +1 @@
1
+ DEBUG=false
@@ -0,0 +1,2 @@
1
+ 536441516
2
+ 1705626586315608000
Binary file
Binary file
package/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # jaxs
2
+
3
+ To install dependencies:
4
+
5
+ ```bash
6
+ bun install
7
+ ```
8
+
9
+ To run:
10
+
11
+ ```bash
12
+ bun run src/jaxs.ts
13
+ ```
14
+
15
+ This project was created using `bun init` in bun v1.0.22. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
package/bun.lockb ADDED
Binary file
package/bundle.ts ADDED
@@ -0,0 +1,5 @@
1
+ await Bun.build({
2
+ entrypoints: ["./src/jaxs.ts"],
3
+ outdir: "./dist",
4
+ minify: false,
5
+ })
package/bunfig.toml ADDED
File without changes
@@ -0,0 +1,39 @@
1
+ describe('Add and remove child nodes with state', () => {
2
+ beforeEach(() => {
3
+ cy.visit('http://localhost:1234/add-remove-nested-children.html')
4
+ })
5
+
6
+ it('it toggles conditional children correctly', () => {
7
+ cy.get('.validation-error').should('not.exist')
8
+
9
+ cy.get('input[name=email]').type('hello?')
10
+ cy.get('.validation-error').should('not.exist')
11
+
12
+ cy.get('input[name=email]').blur()
13
+ cy.get('.validation-error').contains('Email unknown')
14
+ /* change instructions for blur
15
+ {source: input#email, target: input#email, type: removeNode, data: {…}}
16
+ {target: p.validation-error, source: p.validation-error, type: addNode, data: {…}}
17
+ {target: input#email, source: input#email, type: addNode, data: {…}}
18
+ */
19
+
20
+ cy.get('input[name=email]').focus()
21
+ cy.get('input[name=email]').should('exist')
22
+ cy.get('.validation-error').should('not.exist')
23
+ /* On focus
24
+ {source: p.validation-error, target: p.validation-error, type: removeNode, data: {…}}
25
+ {target: input#email, source: input#email, type: addNode, data: {…}}
26
+ {source: input#email, target: input#email, type: removeNode, data: {…}} // trigger blur?
27
+ */
28
+ /*
29
+ change triggered on blur:
30
+ {source: input#email, target: input#email, type: removeNode, data: {…}}
31
+ {target: p.validation-error, source: p.validation-error, type: addNode, data: {…}}
32
+ */
33
+
34
+ cy.get('input[name=email]').clear()
35
+ cy.get('input[name=email]').type('kane@example.com')
36
+ cy.get('input[name=email]').blur()
37
+ cy.get('.validation-error').should('not.exist')
38
+ })
39
+ })
@@ -0,0 +1,37 @@
1
+ describe('Add and remove child nodes with state', () => {
2
+ beforeEach(() => {
3
+ cy.visit('http://localhost:1234/add-remove-root-children.html')
4
+ })
5
+
6
+ it('if/else conditional with nested children and toggling conditions', () => {
7
+ cy.get('.member-content').should('not.exist')
8
+ cy.get('.guest-content').contains('that is fine')
9
+ cy.get('form').should.exist
10
+ cy.get('input[type=submit]').should.exist
11
+
12
+ cy.get('a.exclusive-link').click()
13
+
14
+ cy.get('h1.member-content').contains('Oh great crickets!')
15
+ cy.get('p.member-content').contains('Sing me a tale')
16
+ cy.get('.guest-content').should('not.exist')
17
+
18
+ cy.go('back')
19
+
20
+ cy.get('.member-content').should('not.exist')
21
+ cy.get('.guest-content').contains('that is fine')
22
+ cy.get('form').should.exist
23
+ cy.get('input[type=submit]').should.exist
24
+ })
25
+
26
+ it('show/hide at the root level', () => {
27
+ cy.get('a.exclusive-link').contains('Go to')
28
+
29
+ cy.get('a.exclusive-link').click()
30
+
31
+ cy.get('a.exclusive-link').should('not.exist')
32
+
33
+ cy.go('back')
34
+
35
+ cy.get('a.exclusive-link').contains('Go to')
36
+ })
37
+ })
@@ -0,0 +1,12 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8"/>
5
+ <title>Jaxs integration test</title>
6
+ <script type="module" src="./add-remove-nested-children.jsx"></script>
7
+ </head>
8
+ <body>
9
+ <article id="app">
10
+ </article>
11
+ </body>
12
+ </html>
@@ -0,0 +1,84 @@
1
+ import { bind, createApp, jsx, views } from '../../dist/jaxs.js'
2
+ const { If } = views
3
+
4
+ const app = createApp()
5
+
6
+ app.state.create('form', {
7
+ email: '',
8
+ emailValidation: '',
9
+ emailInvalid: false
10
+ })
11
+
12
+ export const onInput = (event, { state }) => {
13
+ const { form } = state
14
+ const { name, value } = event.target
15
+ state.form.update({
16
+ ...form,
17
+ [name]: value
18
+ })
19
+ }
20
+
21
+ export const onFocus = (event, { state }) => {
22
+ const { form } = state
23
+ const { name } = event.target
24
+ state.form.update({
25
+ ...form,
26
+ [`${name}Validation`]: ''
27
+ })
28
+ }
29
+
30
+ export const onBlur = (event, { state }) => {
31
+ const { form } = state
32
+ const { name, value } = event.target
33
+
34
+ if (value !== 'kane@example.com') {
35
+ state.form.update({
36
+ ...form,
37
+ [`${name}Validation`]: 'Email unknown'
38
+ })
39
+ }
40
+ }
41
+
42
+ const FormTemplate = ({ email, emailValidation, emailInvalid }) => {
43
+ return (
44
+ <form>
45
+ <div>
46
+ <p>
47
+ <label for='email'>Email</label>
48
+ </p>
49
+ <If condition={emailInvalid}>
50
+ <p class='validation-error'>{emailValidation}</p>
51
+ </If>
52
+ <input
53
+ id='email'
54
+ name='email'
55
+ value={email}
56
+ onInput='onInput'
57
+ onBlur='onBlur'
58
+ onFocus='onFocus'
59
+ />
60
+ </div>
61
+
62
+ <input type='submit' value="Let's go!" class='button-primary mt-6' />
63
+ </form>
64
+ )
65
+ }
66
+
67
+ const viewModel = ({ form }) => {
68
+ return {
69
+ ...form,
70
+ emailInvalid: !!form.emailValidation
71
+ }
72
+ }
73
+
74
+ const Form = bind({
75
+ Template: FormTemplate,
76
+ viewModel,
77
+ subscriptions: ['form']
78
+ })
79
+
80
+ app.subscribe('onInput', onInput)
81
+ app.subscribe('onFocus', onFocus)
82
+ app.subscribe('onBlur', onBlur)
83
+
84
+ app.render(<Form />, '#app')
@@ -0,0 +1,15 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8"/>
5
+ <title>Jaxs integration test</title>
6
+ <script type="module" src="./add-remove-root-children.jsx"></script>
7
+ </head>
8
+ <body>
9
+ <header style="background-color: yellowgreen; border: 1px solid blue; padding: 10px;">
10
+ <div>Hello!</div>
11
+ <div id="profile-area" style="width: 25%"></div>
12
+ </header>
13
+ <article id="main-content"></article>
14
+ </body>
15
+ </html>
@@ -0,0 +1,53 @@
1
+ import { bind, createApp, jsx, views } from '../../dist/jaxs.js'
2
+ const { If, Unless } = views
3
+
4
+ const app = createApp()
5
+
6
+ export const MainContentTemplate = ({ inMembers }) => {
7
+ return (
8
+ <>
9
+ <Unless condition={inMembers}>
10
+ <form>
11
+ <p class='guest-content'>
12
+ You are a guest, and I guess that is fine.
13
+ </p>
14
+ <input type='submit' value='Agree! or something' />
15
+ </form>
16
+ </Unless>
17
+ <If condition={inMembers}>
18
+ <h1 class='member-content'>Oh great crickets!</h1>
19
+ <p class='member-content'>Sing me a tale of private content.</p>
20
+ </If>
21
+ </>
22
+ )
23
+ }
24
+ const ProfileAreaTemplate = ({ inMembers }) => {
25
+ return (
26
+ <Unless condition={inMembers}>
27
+ <a href='/members' onClick='goToHref' class='exclusive-link'>
28
+ Go to members area
29
+ </a>
30
+ </Unless>
31
+ )
32
+ }
33
+
34
+ const viewModel = ({ route }) => {
35
+ return {
36
+ inMembers: route && route.path && route.path.match(/members/)
37
+ }
38
+ }
39
+
40
+ const MainContent = bind({
41
+ Template: MainContentTemplate,
42
+ viewModel,
43
+ subscriptions: ['route']
44
+ })
45
+
46
+ const ProfileArea = bind({
47
+ Template: ProfileAreaTemplate,
48
+ viewModel,
49
+ subscriptions: ['route']
50
+ })
51
+
52
+ app.render(<MainContent />, '#main-content')
53
+ app.render(<ProfileArea />, '#profile-area')