stipa 0.1.0 → 0.1.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.
- checksums.yaml +4 -4
- data/lib/js/stipa-vue.js +63 -83
- data/lib/stipa/generators/vue.rb +72 -53
- data/lib/stipa/template.rb +1 -1
- data/lib/stipa/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 387748a4e29d9918defffcbf6e020d826933bc96619f9579f27bbcc4bde3a8c8
|
|
4
|
+
data.tar.gz: e7a6122363efaeff5405b48bb5fe8b334af837b9269b8ad854fdc2aa020b8186
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b2787738c43370505fec1cecdf96ce6d5ff951abd4eb0c80dfd4328dad29e24c9c322c8f0d85faee29d918d40f904da6bc7cf59bfdca7383420c4644b2a897ba
|
|
7
|
+
data.tar.gz: d3bfdfcd68a3920214ab00547e9272d7d7ad2f721c4062793aa38bddaf0f256d9eeeafcc3d2ed0e49c9d5fd3df15c7cec50d917b6b0073f6667b6d642c3c9f81
|
data/lib/js/stipa-vue.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Stīpa Vue Bootstrapper
|
|
2
|
+
* Stīpa Vue Bootstrapper (ES Module)
|
|
3
3
|
*
|
|
4
4
|
* Automatically mounts Vue 3 components declared with the ERB helper:
|
|
5
5
|
* <%= vue_component("Counter", props: { initial: 5 }) %>
|
|
@@ -7,102 +7,82 @@
|
|
|
7
7
|
* Which renders on the page as:
|
|
8
8
|
* <div data-vue-component="Counter" data-props='{"initial":5}'></div>
|
|
9
9
|
*
|
|
10
|
-
* Usage in your layout
|
|
11
|
-
*
|
|
10
|
+
* Usage in your layout:
|
|
11
|
+
* <script type="importmap">{ "imports": { "vue": "/vendor/vue.esm-browser.prod.js" } }</script>
|
|
12
|
+
* <script type="module" src="/stipa-vue.js"></script>
|
|
13
|
+
* <script type="module" src="/app.js"></script>
|
|
12
14
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* <script type="module">
|
|
18
|
-
* import Counter from '/components/Counter.js'
|
|
19
|
-
* StipaVue.register('Counter', Counter)
|
|
20
|
-
* </script>
|
|
21
|
-
* <%= stipa_vue_bootstrap %>
|
|
15
|
+
* In app/main.ts, register components and call mount():
|
|
16
|
+
* const { StipaVue } = window
|
|
17
|
+
* StipaVue.register('Counter', Counter)
|
|
18
|
+
* StipaVue.mount()
|
|
22
19
|
*/
|
|
23
|
-
|
|
24
|
-
const COMPONENT_ATTR = "data-vue-component";
|
|
25
|
-
const PROPS_ATTR = "data-props";
|
|
26
|
-
const MOUNTED_ATTR = "data-stipa-vue-mounted";
|
|
20
|
+
import { createApp } from 'vue'
|
|
27
21
|
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
const COMPONENT_ATTR = 'data-vue-component'
|
|
23
|
+
const PROPS_ATTR = 'data-props'
|
|
24
|
+
const MOUNTED_ATTR = 'data-stipa-vue-mounted'
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
registry[name] = component;
|
|
34
|
-
},
|
|
26
|
+
const registry = {}
|
|
27
|
+
const mounted = []
|
|
35
28
|
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
const StipaVue = {
|
|
30
|
+
register(name, component) {
|
|
31
|
+
registry[name] = component
|
|
32
|
+
},
|
|
38
33
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"[StipaVue] Vue is not defined. Make sure vue_script() appears before stipa_vue_bootstrap() in your layout.",
|
|
42
|
-
);
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
34
|
+
mount(root) {
|
|
35
|
+
root = root || document
|
|
45
36
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
37
|
+
// Prune stale entries for elements no longer in the DOM
|
|
38
|
+
for (let i = mounted.length - 1; i >= 0; i--) {
|
|
39
|
+
if (!document.contains(mounted[i].el)) {
|
|
40
|
+
mounted.splice(i, 1)
|
|
51
41
|
}
|
|
42
|
+
}
|
|
52
43
|
|
|
53
|
-
|
|
54
|
-
|
|
44
|
+
const selector = `[${COMPONENT_ATTR}]:not([${MOUNTED_ATTR}])`
|
|
45
|
+
const elements = root.querySelectorAll(selector)
|
|
55
46
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
47
|
+
elements.forEach((el) => {
|
|
48
|
+
const name = el.getAttribute(COMPONENT_ATTR)
|
|
49
|
+
const component = registry[name]
|
|
59
50
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
'", YourComponent) before the DOM loads.',
|
|
68
|
-
);
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
51
|
+
if (!component) {
|
|
52
|
+
console.warn(
|
|
53
|
+
`[StipaVue] Component "${name}" is not registered. ` +
|
|
54
|
+
`Call StipaVue.register("${name}", YourComponent) before calling StipaVue.mount().`
|
|
55
|
+
)
|
|
56
|
+
return
|
|
57
|
+
}
|
|
71
58
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
59
|
+
let props = {}
|
|
60
|
+
const propsRaw = el.getAttribute(PROPS_ATTR)
|
|
61
|
+
if (propsRaw) {
|
|
62
|
+
try {
|
|
63
|
+
props = JSON.parse(propsRaw)
|
|
64
|
+
} catch (e) {
|
|
65
|
+
console.error(`[StipaVue] Failed to parse props for "${name}":`, e)
|
|
80
66
|
}
|
|
67
|
+
}
|
|
81
68
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
el.setAttribute(MOUNTED_ATTR, "1");
|
|
86
|
-
mounted.push({ app, el });
|
|
87
|
-
});
|
|
88
|
-
},
|
|
69
|
+
const app = createApp(component, props)
|
|
70
|
+
app.mount(el)
|
|
89
71
|
|
|
90
|
-
|
|
91
|
-
mounted.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
});
|
|
95
|
-
mounted.length = 0;
|
|
96
|
-
},
|
|
97
|
-
};
|
|
72
|
+
el.setAttribute(MOUNTED_ATTR, '1')
|
|
73
|
+
mounted.push({ app, el })
|
|
74
|
+
})
|
|
75
|
+
},
|
|
98
76
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
77
|
+
unmountAll() {
|
|
78
|
+
mounted.forEach((entry) => {
|
|
79
|
+
entry.app.unmount()
|
|
80
|
+
entry.el.removeAttribute(MOUNTED_ATTR)
|
|
81
|
+
})
|
|
82
|
+
mounted.length = 0
|
|
83
|
+
},
|
|
84
|
+
}
|
|
106
85
|
|
|
107
|
-
|
|
108
|
-
}
|
|
86
|
+
window.StipaVue = StipaVue
|
|
87
|
+
export { StipaVue }
|
|
88
|
+
export default StipaVue
|
data/lib/stipa/generators/vue.rb
CHANGED
|
@@ -9,13 +9,13 @@ module Stipa
|
|
|
9
9
|
|
|
10
10
|
def dirs
|
|
11
11
|
%w[
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
public/
|
|
12
|
+
app/config
|
|
13
|
+
app/controllers
|
|
14
|
+
app/models
|
|
15
|
+
app/views/layouts
|
|
16
|
+
app/views/home
|
|
17
|
+
app/components
|
|
18
|
+
public/vendor
|
|
19
19
|
]
|
|
20
20
|
end
|
|
21
21
|
|
|
@@ -42,8 +42,12 @@ module Stipa
|
|
|
42
42
|
cd #{name}
|
|
43
43
|
bundle install
|
|
44
44
|
npm install
|
|
45
|
-
npm run build #
|
|
45
|
+
npm run build # copies Vue from node_modules + compiles app bundle
|
|
46
46
|
bundle exec ruby server.rb
|
|
47
|
+
|
|
48
|
+
To upgrade Vue:
|
|
49
|
+
npm install vue@3.x.x
|
|
50
|
+
npm run build
|
|
47
51
|
DONE
|
|
48
52
|
end
|
|
49
53
|
|
|
@@ -54,18 +58,20 @@ module Stipa
|
|
|
54
58
|
'rollup.config.js' => t_rollup_config,
|
|
55
59
|
'tsconfig.json' => t_tsconfig,
|
|
56
60
|
'server.rb' => t_server,
|
|
57
|
-
'
|
|
61
|
+
'app/config/routes.rb' => t_routes(
|
|
58
62
|
extra_requires: ['../controllers/home_controller', '../controllers/health_controller'],
|
|
59
63
|
extra_routes: ["get '/', to: 'home#index'", "get '/api/health', to: 'health#show'"],
|
|
60
64
|
method_override: true,
|
|
61
65
|
),
|
|
62
|
-
'
|
|
63
|
-
'
|
|
64
|
-
'
|
|
65
|
-
'
|
|
66
|
-
'
|
|
66
|
+
'app/controllers/application_controller.rb' => t_application_controller,
|
|
67
|
+
'app/controllers/home_controller.rb' => t_home_controller,
|
|
68
|
+
'app/controllers/health_controller.rb' => t_health_controller,
|
|
69
|
+
'app/views/layouts/application.html.erb' => t_layout,
|
|
70
|
+
'app/views/home/index.html.erb' => t_home_index,
|
|
67
71
|
'public/app.css' => t_app_css,
|
|
68
|
-
'
|
|
72
|
+
'app/components/RequestCard.vue' => t_request_card_vue,
|
|
73
|
+
'app/main.ts' => t_main_ts,
|
|
74
|
+
'app/shims-vue.d.ts' => t_shims_vue,
|
|
69
75
|
}
|
|
70
76
|
end
|
|
71
77
|
|
|
@@ -75,9 +81,11 @@ module Stipa
|
|
|
75
81
|
private: true,
|
|
76
82
|
type: 'module',
|
|
77
83
|
scripts: {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
'copy:vue' => 'cp node_modules/vue/dist/vue.esm-browser.prod.js public/vendor/vue.esm-browser.prod.js',
|
|
85
|
+
build: 'npm run copy:vue && rollup -c',
|
|
86
|
+
watch: 'rollup -c --watch',
|
|
87
|
+
dev: 'npm run copy:vue && concurrently "bundle exec ruby server.rb" "rollup -c --watch"',
|
|
88
|
+
typecheck: 'vue-tsc --noEmit',
|
|
81
89
|
},
|
|
82
90
|
devDependencies: {
|
|
83
91
|
'concurrently' => '^8.0.0',
|
|
@@ -87,6 +95,7 @@ module Stipa
|
|
|
87
95
|
'@vue/compiler-sfc' => '^3.4.0',
|
|
88
96
|
'typescript' => '^5.0.0',
|
|
89
97
|
'vue' => '^3.4.0',
|
|
98
|
+
'vue-tsc' => '^2.0.0',
|
|
90
99
|
},
|
|
91
100
|
) + "\n"
|
|
92
101
|
end
|
|
@@ -95,30 +104,18 @@ module Stipa
|
|
|
95
104
|
<<~JS
|
|
96
105
|
import vue from 'rollup-plugin-vue'
|
|
97
106
|
import typescript from '@rollup/plugin-typescript'
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
output: {
|
|
111
|
-
file: `${out}/${name}.js`,
|
|
112
|
-
format: 'iife',
|
|
113
|
-
name,
|
|
114
|
-
globals: { vue: 'Vue' },
|
|
115
|
-
},
|
|
116
|
-
external: ['vue'],
|
|
117
|
-
// rollup-plugin-vue handles <script lang="ts"> internally;
|
|
118
|
-
// @rollup/plugin-typescript is only needed for plain .ts files.
|
|
119
|
-
plugins: [vue(), ...(isTs ? [typescript({ tsconfig: './tsconfig.json' })] : [])],
|
|
120
|
-
}
|
|
121
|
-
})
|
|
107
|
+
|
|
108
|
+
export default {
|
|
109
|
+
input: 'app/main.ts',
|
|
110
|
+
output: {
|
|
111
|
+
file: 'public/app.js',
|
|
112
|
+
format: 'es',
|
|
113
|
+
},
|
|
114
|
+
external: ['vue'],
|
|
115
|
+
// rollup-plugin-vue handles <script lang="ts"> in .vue SFCs;
|
|
116
|
+
// @rollup/plugin-typescript compiles app/main.ts and other plain .ts files.
|
|
117
|
+
plugins: [vue(), typescript({ tsconfig: './tsconfig.json' })],
|
|
118
|
+
}
|
|
122
119
|
JS
|
|
123
120
|
end
|
|
124
121
|
|
|
@@ -130,20 +127,21 @@ module Stipa
|
|
|
130
127
|
moduleResolution: 'bundler',
|
|
131
128
|
strict: true,
|
|
132
129
|
skipLibCheck: true,
|
|
130
|
+
allowJs: true,
|
|
133
131
|
},
|
|
134
|
-
include: ['
|
|
132
|
+
include: ['app/**/*'],
|
|
135
133
|
) + "\n"
|
|
136
134
|
end
|
|
137
135
|
|
|
138
136
|
def t_server
|
|
139
137
|
<<~RUBY
|
|
140
138
|
require 'stipa'
|
|
141
|
-
require_relative '
|
|
139
|
+
require_relative 'app/config/routes'
|
|
142
140
|
|
|
143
141
|
APP_DIR = __dir__
|
|
144
142
|
|
|
145
143
|
app = Stipa::App.new(
|
|
146
|
-
views: "\#{APP_DIR}/
|
|
144
|
+
views: "\#{APP_DIR}/app/views",
|
|
147
145
|
public: "\#{APP_DIR}/public",
|
|
148
146
|
)
|
|
149
147
|
|
|
@@ -261,17 +259,16 @@ module Stipa
|
|
|
261
259
|
<link rel="icon" href="/favicon.ico">
|
|
262
260
|
<%= stylesheet_tag '/app.css' %>
|
|
263
261
|
|
|
264
|
-
<%# Vue
|
|
265
|
-
<script
|
|
262
|
+
<%# Pin Vue version via importmap — upgrade by changing vue in package.json and rebuilding %>
|
|
263
|
+
<script type="importmap">
|
|
264
|
+
{ "imports": { "vue": "/vendor/vue.esm-browser.prod.js" } }
|
|
265
|
+
</script>
|
|
266
266
|
|
|
267
|
-
<%# Stipa Vue bootstrapper —
|
|
267
|
+
<%# Stipa Vue bootstrapper — exposes window.StipaVue %>
|
|
268
268
|
<%= stipa_vue_bootstrap %>
|
|
269
269
|
|
|
270
|
-
<%#
|
|
271
|
-
<script src="/
|
|
272
|
-
<script>
|
|
273
|
-
window.StipaVue.register('RequestCard', window.RequestCard)
|
|
274
|
-
</script>
|
|
270
|
+
<%# App bundle — registers components and mounts them %>
|
|
271
|
+
<script type="module" src="/app.js"></script>
|
|
275
272
|
|
|
276
273
|
<%# Measure time from first byte to DOMContentLoaded %>
|
|
277
274
|
<script>const _t0 = performance.now()</script>
|
|
@@ -396,6 +393,28 @@ module Stipa
|
|
|
396
393
|
|
|
397
394
|
|
|
398
395
|
|
|
396
|
+
def t_shims_vue
|
|
397
|
+
<<~TS
|
|
398
|
+
declare module '*.vue' {
|
|
399
|
+
import type { DefineComponent } from 'vue'
|
|
400
|
+
const component: DefineComponent
|
|
401
|
+
export default component
|
|
402
|
+
}
|
|
403
|
+
TS
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
def t_main_ts
|
|
407
|
+
<<~TS
|
|
408
|
+
import RequestCard from './components/RequestCard.vue'
|
|
409
|
+
|
|
410
|
+
// window.StipaVue is set by /stipa-vue.js, loaded as a module before this script.
|
|
411
|
+
const { StipaVue } = window as any
|
|
412
|
+
|
|
413
|
+
StipaVue.register('RequestCard', RequestCard)
|
|
414
|
+
StipaVue.mount()
|
|
415
|
+
TS
|
|
416
|
+
end
|
|
417
|
+
|
|
399
418
|
def t_request_card_vue
|
|
400
419
|
<<~VUE
|
|
401
420
|
<template>
|
data/lib/stipa/template.rb
CHANGED
data/lib/stipa/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: stipa
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Pedro Harbs
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-03-
|
|
11
|
+
date: 2026-03-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: minitest
|