rip-lang 3.15.4 → 3.16.1

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 (112) hide show
  1. package/README.md +6 -4
  2. package/bin/rip +167 -12
  3. package/docs/AGENTS.md +1 -1
  4. package/docs/RIP-APP.md +808 -0
  5. package/docs/RIP-DUCKDB.md +477 -0
  6. package/docs/RIP-INTRO.md +396 -0
  7. package/docs/RIP-LANG.md +59 -5
  8. package/docs/RIP-SCHEMA.md +191 -8
  9. package/docs/RIP-TYPES.md +74 -103
  10. package/docs/demo/README.md +4 -3
  11. package/docs/dist/rip.js +3627 -1470
  12. package/docs/dist/rip.min.js +671 -244
  13. package/docs/dist/rip.min.js.br +0 -0
  14. package/docs/example/index.json +7 -7
  15. package/docs/example/index.json.br +0 -0
  16. package/docs/extensions/duckdb/manifest.json +1 -1
  17. package/docs/extensions/duckdb/v1.5.2/linux_amd64/ripdb.duckdb_extension.gz +0 -0
  18. package/docs/extensions/duckdb/v1.5.2/osx_arm64/ripdb.duckdb_extension.gz +0 -0
  19. package/docs/extensions/vscode/print/index.html +2 -1
  20. package/docs/extensions/vscode/print/print-1.0.13.vsix +0 -0
  21. package/docs/extensions/vscode/print/print-1.0.14.vsix +0 -0
  22. package/docs/extensions/vscode/print/print-latest.vsix +0 -0
  23. package/docs/extensions/vscode/rip/rip-0.5.15.vsix +0 -0
  24. package/docs/extensions/vscode/rip/rip-latest.vsix +0 -0
  25. package/docs/ui/bundle.json +61 -0
  26. package/docs/ui/bundle.json.br +0 -0
  27. package/docs/ui/hljs-rip.js +0 -7
  28. package/docs/ui/index.css +66 -23
  29. package/docs/ui/index.html +6 -6
  30. package/package.json +9 -3
  31. package/rip-loader.js +64 -2
  32. package/src/AGENTS.md +63 -36
  33. package/src/browser.js +96 -14
  34. package/src/compiler.js +960 -143
  35. package/src/components.js +794 -88
  36. package/src/{types-emit.js → dts.js} +181 -71
  37. package/src/grammar/README.md +1 -1
  38. package/src/grammar/grammar.rip +111 -97
  39. package/src/lexer.js +132 -18
  40. package/src/parser.js +203 -205
  41. package/src/repl.js +74 -6
  42. package/src/schema/runtime-orm.js +168 -4
  43. package/src/schema/runtime-validate.js +146 -2
  44. package/src/schema/runtime.generated.js +314 -6
  45. package/src/schema/schema.js +5 -5
  46. package/src/sourcemaps.js +277 -1
  47. package/src/stdlib.js +253 -0
  48. package/src/typecheck.js +2023 -106
  49. package/src/types.js +127 -7
  50. package/docs/ui/accordion.rip +0 -103
  51. package/docs/ui/alert-dialog.rip +0 -53
  52. package/docs/ui/autocomplete.rip +0 -115
  53. package/docs/ui/avatar.rip +0 -37
  54. package/docs/ui/badge.rip +0 -15
  55. package/docs/ui/breadcrumb.rip +0 -47
  56. package/docs/ui/button-group.rip +0 -26
  57. package/docs/ui/button.rip +0 -23
  58. package/docs/ui/card.rip +0 -25
  59. package/docs/ui/carousel.rip +0 -110
  60. package/docs/ui/checkbox-group.rip +0 -61
  61. package/docs/ui/checkbox.rip +0 -33
  62. package/docs/ui/collapsible.rip +0 -50
  63. package/docs/ui/combobox.rip +0 -130
  64. package/docs/ui/context-menu.rip +0 -88
  65. package/docs/ui/date-picker.rip +0 -206
  66. package/docs/ui/dialog.rip +0 -60
  67. package/docs/ui/drawer.rip +0 -58
  68. package/docs/ui/editable-value.rip +0 -82
  69. package/docs/ui/field.rip +0 -53
  70. package/docs/ui/fieldset.rip +0 -22
  71. package/docs/ui/form.rip +0 -39
  72. package/docs/ui/grid.rip +0 -901
  73. package/docs/ui/input-group.rip +0 -28
  74. package/docs/ui/input.rip +0 -36
  75. package/docs/ui/label.rip +0 -16
  76. package/docs/ui/menu.rip +0 -134
  77. package/docs/ui/menubar.rip +0 -151
  78. package/docs/ui/meter.rip +0 -36
  79. package/docs/ui/multi-select.rip +0 -203
  80. package/docs/ui/native-select.rip +0 -33
  81. package/docs/ui/nav-menu.rip +0 -126
  82. package/docs/ui/number-field.rip +0 -162
  83. package/docs/ui/otp-field.rip +0 -89
  84. package/docs/ui/pagination.rip +0 -123
  85. package/docs/ui/popover.rip +0 -93
  86. package/docs/ui/preview-card.rip +0 -75
  87. package/docs/ui/progress.rip +0 -25
  88. package/docs/ui/radio-group.rip +0 -57
  89. package/docs/ui/resizable.rip +0 -123
  90. package/docs/ui/scroll-area.rip +0 -145
  91. package/docs/ui/select.rip +0 -151
  92. package/docs/ui/separator.rip +0 -17
  93. package/docs/ui/skeleton.rip +0 -22
  94. package/docs/ui/slider.rip +0 -165
  95. package/docs/ui/spinner.rip +0 -17
  96. package/docs/ui/table.rip +0 -27
  97. package/docs/ui/tabs.rip +0 -113
  98. package/docs/ui/textarea.rip +0 -48
  99. package/docs/ui/toast.rip +0 -87
  100. package/docs/ui/toggle-group.rip +0 -71
  101. package/docs/ui/toggle.rip +0 -24
  102. package/docs/ui/toolbar.rip +0 -38
  103. package/docs/ui/tooltip.rip +0 -85
  104. package/src/app.rip +0 -1571
  105. package/src/sourcemap-merge.js +0 -287
  106. /package/docs/demo/{components → routes}/_layout.rip +0 -0
  107. /package/docs/demo/{components → routes}/about.rip +0 -0
  108. /package/docs/demo/{components → routes}/card.rip +0 -0
  109. /package/docs/demo/{components → routes}/counter.rip +0 -0
  110. /package/docs/demo/{components → routes}/index.rip +0 -0
  111. /package/docs/demo/{components → routes}/todos.rip +0 -0
  112. /package/src/schema/{dts-emit.js → dts.js} +0 -0
@@ -1,60 +0,0 @@
1
- # Dialog — accessible headless modal dialog
2
- #
3
- # Native `<dialog>` variant that uses `showModal()` for top-layer modality.
4
- # Restores focus to the previously focused element on close.
5
- # Auto-wires aria-labelledby (first h1-h6) and aria-describedby (first p).
6
- #
7
- # Exposes $open on the backdrop. Ships zero CSS.
8
- #
9
- # Usage:
10
- # Dialog open <=> showDialog, @close: handleClose
11
- # h2 "Title"
12
- # p "Content"
13
- # button @click: (=> showDialog = false), "Close"
14
-
15
- export Dialog = component
16
- @open:: boolean := false
17
- @dismissable:: boolean := true
18
- @initialFocus:: any := null
19
-
20
- _id =! "dlg-#{Math.random().toString(36).slice(2, 8)}"
21
-
22
- ~>
23
- ARIA.bindDialog @open, (=> @_dialog), ((isOpen) =>
24
- if not isOpen and @open
25
- @open = false
26
- @emit 'close'
27
- ), @dismissable
28
-
29
- ~>
30
- if @open
31
- ARIA.lockScroll(this)
32
- requestAnimationFrame =>
33
- panel = @_dialog
34
- if panel
35
- ARIA.wireAria panel, _id
36
- if @initialFocus
37
- target = if typeof @initialFocus is 'string' then panel.querySelector(@initialFocus) else @initialFocus
38
- target?.focus()
39
- else
40
- panel.querySelectorAll('a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])')?[0]?.focus()
41
- return ->
42
- ARIA.unlockScroll(this)
43
-
44
- close: ->
45
- @open = false
46
- @emit 'close'
47
-
48
- onKeydown: (e) ->
49
- if e.key is 'Escape'
50
- e.preventDefault()
51
- @close() if @dismissable
52
-
53
- onBackdropClick: (e) ->
54
- if e.target is e.currentTarget and @dismissable
55
- @_dialog?.close()
56
-
57
- render
58
- dialog ref: "_dialog", @click: @onBackdropClick, @keydown: @onKeydown
59
- $open: @open?!
60
- slot
@@ -1,58 +0,0 @@
1
- # Drawer — accessible headless slide-out panel
2
- #
3
- # A Dialog variant that slides from an edge of the screen.
4
- # Supports dismiss on escape, click-outside, and optional swipe-to-close.
5
- # Ships zero CSS.
6
- #
7
- # Usage:
8
- # Drawer open <=> showDrawer, side: "right"
9
- # h2 "Settings"
10
- # p "Panel content here"
11
-
12
- export Drawer = component
13
- @open:: boolean := false
14
- @side:: "top" | "right" | "bottom" | "left" := "right"
15
- @dismissable:: boolean := true
16
-
17
- _prevFocus = null
18
- _id =! "drw-#{Math.random().toString(36).slice(2, 8)}"
19
-
20
- ~>
21
- ARIA.bindDialog @open, (=> @_dialog), ((isOpen) =>
22
- if not isOpen and @open
23
- @open = false
24
- @emit 'close'
25
- ), @dismissable
26
-
27
- ~>
28
- if @open
29
- _prevFocus = document.activeElement
30
- ARIA.lockScroll(this)
31
- requestAnimationFrame =>
32
- panel = @_dialog
33
- if panel
34
- ARIA.wireAria panel, _id
35
- panel.querySelectorAll('a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])')?[0]?.focus()
36
- return ->
37
- ARIA.unlockScroll(this)
38
- _prevFocus?.focus()
39
-
40
- close: ->
41
- @open = false
42
- @emit 'close'
43
-
44
- onKeydown: (e) ->
45
- if e.key is 'Escape' and @dismissable
46
- e.preventDefault()
47
- @close()
48
-
49
- onBackdropClick: (e) ->
50
- if e.target is e.currentTarget and @dismissable
51
- @_dialog?.close()
52
-
53
- render
54
- dialog ref: "_dialog", $open: @open?!, $side: @side
55
- @click: @onBackdropClick
56
- @keydown: @onKeydown
57
- $side: @side
58
- slot
@@ -1,82 +0,0 @@
1
- # EditableValue — accessible headless inline editable value
2
- #
3
- # Displays a value with an edit trigger. Clicking opens a popover form.
4
- # Emits 'save' on submit. Ships zero CSS.
5
- #
6
- # Usage:
7
- # EditableValue @save: handleSave
8
- # span $display: true
9
- # "John Doe"
10
- # div $editor: true
11
- # input type: "text", value: name, @input: (e) => name = e.target.value
12
-
13
- export EditableValue = component
14
- @disabled:: boolean := false
15
-
16
- editing := false
17
- saving := false
18
-
19
- _onEdit: ->
20
- return if @disabled
21
- editing = true
22
- requestAnimationFrame => @_position()
23
-
24
- _onSave: ->
25
- return if saving
26
- saving = true
27
- @emit 'save'
28
- @close()
29
-
30
- _onCancel: ->
31
- editing = false
32
- saving = false
33
-
34
- close: ->
35
- editing = false
36
- saving = false
37
-
38
- setSaving: (val) -> saving = val
39
-
40
- _position: ->
41
- display = @_root?.querySelector('[data-display]')
42
- editor = @_root?.querySelector('[data-editor]')
43
- return unless display and editor
44
- @_root.style.position = 'relative'
45
- dr = display.getBoundingClientRect()
46
- cr = @_root.getBoundingClientRect()
47
- editor.style.position = 'absolute'
48
- editor.style.left = "0px"
49
- editor.style.top = "#{dr.bottom - cr.top + 4}px"
50
- editor.style.zIndex = '50'
51
- editor.querySelector('input, textarea, select')?.focus()
52
-
53
- ~>
54
- _editing = editing # track before any early return
55
- display = @_root?.querySelector('[data-display]')
56
- editor = @_root?.querySelector('[data-editor]')
57
- return unless display and editor
58
- editor.hidden = not _editing
59
- if _editing
60
- editor.setAttribute 'data-open', ''
61
- onDown = (e) =>
62
- unless @_root?.contains(e.target)
63
- @_onCancel()
64
- document.addEventListener 'mousedown', onDown
65
- return -> document.removeEventListener 'mousedown', onDown
66
- else
67
- editor.removeAttribute 'data-open'
68
-
69
- onKeydown: (e) ->
70
- if e.key is 'Escape' and editing
71
- e.preventDefault()
72
- @_onCancel()
73
- if e.key is 'Enter' and editing
74
- e.preventDefault()
75
- @_onSave()
76
-
77
- render
78
- div ref: "_root", $editing: editing?!, $disabled: @disabled?!, $saving: saving?!
79
- slot
80
- unless editing
81
- button $edit-trigger: true, aria-label: "Edit", @click: @_onEdit
82
- "✎"
package/docs/ui/field.rip DELETED
@@ -1,53 +0,0 @@
1
- # Field — accessible headless form field wrapper
2
- #
3
- # Associates a label, description, and error message with a form control.
4
- # Generates linked IDs for aria-labelledby/describedby/errormessage.
5
- # Ships zero CSS.
6
- #
7
- # Usage:
8
- # Field label: "Email", error: errors.email
9
- # Input value <=> email, type: "email"
10
-
11
- export Field = component
12
- @label:: string := ""
13
- @description:: string := ""
14
- @error:: string := ""
15
- @disabled:: boolean := false
16
- @required:: boolean := false
17
-
18
- _id =! "fld-#{Math.random().toString(36).slice(2, 8)}"
19
-
20
- mounted: ->
21
- ctrl = @_root?.querySelector('input, select, textarea, button, [role]')
22
- if ctrl
23
- ctrl.setAttribute 'aria-labelledby', "#{_id}-label" if @label
24
- ctrl.setAttribute 'aria-describedby', "#{_id}-desc" if @description
25
- ctrl.setAttribute 'aria-errormessage', "#{_id}-err" if @error
26
- ctrl.setAttribute 'aria-invalid', true if @error
27
- ctrl.setAttribute 'aria-required', true if @required
28
-
29
- ~>
30
- ctrl = @_root?.querySelector('input, select, textarea, button, [role]')
31
- return unless ctrl
32
- if @error
33
- ctrl.setAttribute 'aria-invalid', true
34
- ctrl.setAttribute 'aria-errormessage', "#{_id}-err"
35
- else
36
- ctrl.removeAttribute 'aria-invalid'
37
- ctrl.removeAttribute 'aria-errormessage'
38
-
39
- render
40
- div $disabled: @disabled?!, $invalid: @error?!
41
- if @label
42
- label id: "#{_id}-label", $label: true
43
- @label
44
- if @required
45
- span $required: true, aria-hidden: "true"
46
- " *"
47
- slot
48
- if @description and not @error
49
- div id: "#{_id}-desc", $description: true
50
- @description
51
- if @error
52
- div id: "#{_id}-err", role: "alert", $error: true
53
- @error
@@ -1,22 +0,0 @@
1
- # Fieldset — accessible headless fieldset with legend
2
- #
3
- # Groups related fields with an optional legend. Disables all children
4
- # when @disabled is set. Ships zero CSS.
5
- #
6
- # Usage:
7
- # Fieldset legend: "Shipping Address"
8
- # Field label: "Street"
9
- # Input value <=> street
10
- # Field label: "City"
11
- # Input value <=> city
12
-
13
- export Fieldset = component
14
- @legend:: string := ""
15
- @disabled:: boolean := false
16
-
17
- render
18
- fieldset disabled: @disabled, $disabled: @disabled?!
19
- if @legend
20
- legend $legend: true
21
- @legend
22
- slot
package/docs/ui/form.rip DELETED
@@ -1,39 +0,0 @@
1
- # Form — accessible headless form with validation and submission
2
- #
3
- # Wraps native <form> with submit handling, validation state, and
4
- # loading indicator support. Prevents default submission and emits
5
- # a 'submit' event. Ships zero CSS.
6
- #
7
- # Usage:
8
- # Form @submit: handleSubmit
9
- # Field label: "Name"
10
- # Input value <=> name
11
- # Button
12
- # "Submit"
13
-
14
- export Form = component
15
- @disabled:: boolean := false
16
-
17
- submitting := false
18
- submitted := false
19
- errors := {}
20
-
21
- _onSubmit: (e) ->
22
- e.preventDefault()
23
- return if @disabled or submitting
24
- submitting = true
25
- submitted = true
26
- @emit 'submit', { form: e.target }
27
-
28
- setErrors: (errs) ->
29
- errors = errs or {}
30
-
31
- setSubmitting: (val) ->
32
- submitting = val
33
-
34
- render
35
- form @submit: @_onSubmit, novalidate: true
36
- $disabled: @disabled?!
37
- $submitting: submitting?!
38
- $submitted: submitted?!
39
- slot