@jseeio/jsee 0.4.1 → 0.8.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 (60) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/LICENSE +21 -0
  3. package/README.md +583 -55
  4. package/dist/2b3e1faf89f94a483539.png +0 -0
  5. package/dist/416d91365b44e4b4f477.png +0 -0
  6. package/dist/8f2c4d11474275fbc161.png +0 -0
  7. package/dist/jsee.core.js +1 -0
  8. package/dist/jsee.full.js +1 -0
  9. package/dist/jsee.runtime.js +2 -1
  10. package/package.json +84 -18
  11. package/src/app.js +130 -33
  12. package/src/cli.js +474 -64
  13. package/src/extended-imports.js +11 -0
  14. package/src/main.js +264 -45
  15. package/src/overlay.js +26 -1
  16. package/src/utils.js +390 -12
  17. package/templates/common-inputs.js +88 -0
  18. package/templates/common-outputs.js +340 -4
  19. package/templates/minimal-app.vue +367 -0
  20. package/templates/minimal-input.vue +573 -0
  21. package/templates/minimal-output.vue +426 -0
  22. package/templates/virtual-table.vue +194 -0
  23. package/.claude/settings.local.json +0 -13
  24. package/.eslintrc.js +0 -38
  25. package/AGENTS.md +0 -65
  26. package/CLAUDE.md +0 -5
  27. package/CNAME +0 -1
  28. package/_config.yml +0 -26
  29. package/dist/jsee.js +0 -1
  30. package/jest-puppeteer.config.js +0 -14
  31. package/jest.config.js +0 -8
  32. package/jest.unit.config.js +0 -8
  33. package/load/index.html +0 -52
  34. package/templates/bulma-app.vue +0 -242
  35. package/templates/bulma-input.vue +0 -125
  36. package/templates/bulma-output.vue +0 -101
  37. package/test/class.html +0 -22
  38. package/test/code.html +0 -25
  39. package/test/codew.html +0 -25
  40. package/test/example-class.js +0 -8
  41. package/test/example-sum.js +0 -3
  42. package/test/fixtures/lodash-like.js +0 -15
  43. package/test/fixtures/upload-sample.csv +0 -3
  44. package/test/importw.html +0 -28
  45. package/test/minimal.html +0 -14
  46. package/test/minimal1.html +0 -13
  47. package/test/minimal2.html +0 -15
  48. package/test/minimal3.html +0 -10
  49. package/test/minimal4.html +0 -22
  50. package/test/pipeline.html +0 -52
  51. package/test/python.html +0 -41
  52. package/test/string.html +0 -26
  53. package/test/stringw.html +0 -29
  54. package/test/sum.schema.json +0 -17
  55. package/test/sumw.schema.json +0 -15
  56. package/test/test-basic.test.js +0 -603
  57. package/test/test-python.test.js +0 -23
  58. package/test/unit/cli-fetch.test.js +0 -229
  59. package/test/unit/utils.test.js +0 -888
  60. package/webpack.config.js +0 -101
@@ -0,0 +1,367 @@
1
+ <style scoped lang="scss">
2
+ .jsee-app {
3
+ /* Theme variables — light (default) */
4
+ --jsee-primary: #00d1b2;
5
+ --jsee-primary-dark: #016c5c;
6
+ --jsee-bg: #fff;
7
+ --jsee-bg-secondary: #f5f5f5;
8
+ --jsee-text: #333;
9
+ --jsee-text-secondary: #666;
10
+ --jsee-border: #e0e0e0;
11
+ --jsee-card-bg: #fff;
12
+ --jsee-input-bg: #fff;
13
+ --jsee-input-border: #ddd;
14
+ --jsee-label-bg: #f2f2f2;
15
+ --jsee-focus-ring: rgba(72, 139, 199, 0.2);
16
+ --jsee-focus-border: #7ab8e6;
17
+ --jsee-toggle-active: #00d1b2;
18
+ --jsee-gradient-start: #4395d0;
19
+ --jsee-gradient-end: #00d1b2;
20
+ --jsee-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
21
+ --jsee-radius: 6px;
22
+
23
+ font-family: var(--jsee-font);
24
+ font-size: 14px;
25
+ line-height: 1.5;
26
+ color: var(--jsee-text);
27
+ box-sizing: border-box;
28
+ *, *::before, *::after { box-sizing: border-box; }
29
+
30
+ .jsee-header {
31
+ margin-bottom: 16px;
32
+ }
33
+ .jsee-title {
34
+ font-size: 24px;
35
+ font-weight: 600;
36
+ margin: 0 0 4px;
37
+ }
38
+ .jsee-description {
39
+ margin: 0;
40
+ color: var(--jsee-text-secondary);
41
+ }
42
+
43
+ .jsee-grid {
44
+ display: grid;
45
+ grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
46
+ gap: 20px;
47
+ }
48
+ @media (max-width: 768px) {
49
+ .jsee-grid { grid-template-columns: 1fr; }
50
+ }
51
+
52
+ .jsee-grid[data-layout="sidebar"] {
53
+ grid-template-columns: 280px minmax(0, 1fr);
54
+ }
55
+ .jsee-grid > div {
56
+ min-width: 0;
57
+ }
58
+ .jsee-grid[data-layout="sidebar"] > div:first-child {
59
+ position: sticky;
60
+ top: 0;
61
+ max-height: 100vh;
62
+ overflow-y: auto;
63
+ }
64
+ @media (max-width: 768px) {
65
+ .jsee-grid[data-layout="sidebar"] {
66
+ grid-template-columns: 1fr;
67
+ }
68
+ .jsee-grid[data-layout="sidebar"] > div:first-child {
69
+ position: static;
70
+ max-height: none;
71
+ }
72
+ }
73
+
74
+ .jsee-12-grid {
75
+ display: grid;
76
+ grid-template-columns: repeat(12, minmax(0, 1fr));
77
+ gap: 8px;
78
+ }
79
+ .jsee-12-grid > * {
80
+ min-width: 0;
81
+ }
82
+ @media (max-width: 768px) {
83
+ .jsee-12-grid { grid-template-columns: 1fr; }
84
+ .jsee-12-grid > * { grid-column: span 1 !important; }
85
+ }
86
+
87
+ .jsee-card {
88
+ border: 1px solid var(--jsee-border);
89
+ border-radius: var(--jsee-radius);
90
+ background: var(--jsee-card-bg);
91
+ position: relative;
92
+ }
93
+
94
+ .jsee-card-body {
95
+ padding: 16px;
96
+ }
97
+ #inputs, #outputs {
98
+ position: relative;
99
+ }
100
+
101
+ #inputs .jsee-input-col {
102
+ padding: 0 4px;
103
+ margin-bottom: 2px;
104
+ }
105
+
106
+ #overlay {
107
+ display: none;
108
+ position: absolute;
109
+ inset: -1px;
110
+ background: var(--jsee-bg-secondary);
111
+ opacity: .6;
112
+ z-index: 1000;
113
+ align-items: center;
114
+ justify-content: center;
115
+ }
116
+
117
+ .jsee-card-footer {
118
+ display: flex;
119
+ border-top: 1px solid var(--jsee-border);
120
+ background: linear-gradient(90deg, var(--jsee-gradient-start) 0%, var(--jsee-gradient-end) 100%);
121
+ border-radius: 0 0 var(--jsee-radius) var(--jsee-radius);
122
+ }
123
+ .jsee-card-footer.reset {
124
+ background: linear-gradient(90deg, #ff577f 0%, var(--jsee-gradient-start) 50%, var(--jsee-gradient-end) 100%);
125
+ }
126
+ .jsee-card-footer button {
127
+ flex: 1;
128
+ padding: 10px 16px;
129
+ border: none;
130
+ background: none;
131
+ cursor: pointer;
132
+ font-size: 14px;
133
+ color: #fff;
134
+ }
135
+ .jsee-card-footer button:hover {
136
+ background: rgba(255,255,255,0.15);
137
+ }
138
+ .jsee-reset-btn {
139
+ text-align: left;
140
+ }
141
+ .jsee-reset-btn::before {
142
+ content: '\2715 ';
143
+ }
144
+ .jsee-run-btn {
145
+ text-align: right;
146
+ border-left: 1px dashed rgba(255,255,255,0.5);
147
+ }
148
+ .jsee-run-btn::after {
149
+ content: ' \25B8';
150
+ }
151
+ .jsee-stop-btn {
152
+ background: #e74c3c !important;
153
+ }
154
+ .jsee-stop-btn::after {
155
+ content: ' \25A0' !important;
156
+ }
157
+
158
+ .jsee-examples {
159
+ margin-top: 16px;
160
+ }
161
+ .jsee-examples p {
162
+ margin: 0 0 8px;
163
+ font-size: 13px;
164
+ color: var(--jsee-text-secondary);
165
+ }
166
+ .jsee-example-btn {
167
+ display: block;
168
+ width: 100%;
169
+ padding: 6px 10px;
170
+ margin-top: 4px;
171
+ border: 1px solid var(--jsee-border);
172
+ border-radius: 4px;
173
+ background: var(--jsee-bg-secondary);
174
+ cursor: pointer;
175
+ font-family: monospace;
176
+ font-size: 11px;
177
+ text-align: left;
178
+ white-space: normal;
179
+ color: var(--jsee-text);
180
+ }
181
+ .jsee-example-btn:hover {
182
+ background: var(--jsee-border);
183
+ }
184
+ }
185
+ /* Dark theme overrides */
186
+ .jsee-app[data-theme="dark"] {
187
+ --jsee-bg: #1a1a1a;
188
+ --jsee-bg-secondary: #222;
189
+ --jsee-text: #e0e0e0;
190
+ --jsee-text-secondary: #aaa;
191
+ --jsee-border: #333;
192
+ --jsee-card-bg: #252525;
193
+ --jsee-input-bg: #2a2a2a;
194
+ --jsee-input-border: #444;
195
+ --jsee-label-bg: #303030;
196
+ --jsee-focus-ring: rgba(72, 139, 199, 0.35);
197
+ --jsee-toggle-active: #00d1b2;
198
+ }
199
+ </style>
200
+
201
+ <template>
202
+ <section>
203
+ <div class="jsee-app" :data-theme="$parent.design && $parent.design.theme ? $parent.design.theme : undefined" :style="designStyle">
204
+ <div class="jsee-header" v-if="$parent.model">
205
+ <h2 class="jsee-title" v-if="$parent.model.title">{{ $parent.model.title }}</h2>
206
+ <p class="jsee-description" v-if="$parent.model.description">{{ $parent.model.description }}</p>
207
+ </div>
208
+ <div class="jsee-grid" :data-layout="$parent.design && $parent.design.layout ? $parent.design.layout : undefined" :style="gridStyle">
209
+ <div>
210
+ <!-- Inputs -->
211
+ <div class="jsee-card">
212
+ <div class="jsee-card-body" id="inputs" v-if="$parent.inputs && $parent.inputs.length > 0"
213
+ :class="{ 'jsee-12-grid': hasInputColumns }">
214
+ <div
215
+ v-for="(input, index) in $parent.inputs"
216
+ :key="index"
217
+ class="jsee-input-col"
218
+ :style="input.columns ? { gridColumn: 'span ' + input.columns } : undefined"
219
+ >
220
+ <vue-input
221
+ v-bind:input="input"
222
+ v-if="input.display !== false && $parent.display(index)"
223
+ v-on:inchange="$parent.run()"
224
+ ></vue-input>
225
+ </div>
226
+ <pre v-if="$parent.model.debug">{{ $parent.inputs }}</pre>
227
+ </div>
228
+ <div class="jsee-card-footer" v-bind:class="{ reset: $parent.dataChanged }">
229
+ <button
230
+ v-on:click="$parent.reset()"
231
+ v-if="$parent.inputs && $parent.inputs.length > 0 && $parent.dataChanged"
232
+ class="jsee-reset-btn"
233
+ >
234
+ Reset
235
+ </button>
236
+ <button
237
+ v-if="!$parent.running"
238
+ v-on:click="$parent.run('run')"
239
+ class="jsee-run-btn"
240
+ >
241
+ Run
242
+ </button>
243
+ <button
244
+ v-else
245
+ v-on:click="$parent.stop()"
246
+ class="jsee-run-btn jsee-stop-btn"
247
+ >
248
+ Stop
249
+ </button>
250
+ </div>
251
+ </div>
252
+ <!-- Examples -->
253
+ <div class="jsee-examples" v-if="$parent.examples">
254
+ <p>Examples</p>
255
+ <div v-for="(example, index) in $parent.examples">
256
+ <button
257
+ v-on:click="$parent.reset(example)"
258
+ class="jsee-example-btn"
259
+ >
260
+ {{ JSON.stringify(example, null, 2) }}
261
+ </button>
262
+ </div>
263
+ </div>
264
+ </div>
265
+ <div id="outputs">
266
+ <!-- Outputs -->
267
+ <div v-if="$parent.outputs" :class="{ 'jsee-12-grid': hasOutputColumns }">
268
+ <div
269
+ v-for="(output, index) in $parent.outputs"
270
+ :key="index"
271
+ :style="output.columns ? { gridColumn: 'span ' + output.columns } : undefined"
272
+ >
273
+ <vue-output
274
+ v-bind:output="output"
275
+ v-on:notification="$parent.notify($event)"
276
+ ></vue-output>
277
+ </div>
278
+ <pre v-if="$parent.debug">{{ $parent.outputs }}</pre>
279
+ </div>
280
+ </div>
281
+ </div>
282
+ </div>
283
+ </section>
284
+ </template>
285
+
286
+ <script>
287
+ function hexToRgb (hex) {
288
+ if (typeof hex !== 'string' || hex[0] !== '#') return null
289
+ const n = parseInt(hex.slice(1), 16)
290
+ if (hex.length === 4) {
291
+ return [(n >> 8 & 0xf) * 17, (n >> 4 & 0xf) * 17, (n & 0xf) * 17]
292
+ }
293
+ return [(n >> 16) & 255, (n >> 8) & 255, n & 255]
294
+ }
295
+
296
+ function mix (c, white, t) {
297
+ return c.map((v, i) => Math.round(v + (white[i] - v) * t))
298
+ }
299
+
300
+ function rgbHex (c) {
301
+ return '#' + c.map(v => v.toString(16).padStart(2, '0')).join('')
302
+ }
303
+
304
+ function lighter (hex, t) {
305
+ const c = hexToRgb(hex)
306
+ return c ? rgbHex(mix(c, [255, 255, 255], t)) : hex
307
+ }
308
+
309
+ function darker (hex, t) {
310
+ const c = hexToRgb(hex)
311
+ return c ? rgbHex(mix(c, [0, 0, 0], t)) : hex
312
+ }
313
+
314
+ export default {
315
+ computed: {
316
+ designStyle () {
317
+ const d = this.$parent.design
318
+ if (!d) return undefined
319
+ const s = {}
320
+ if (d.primary) {
321
+ s['--jsee-primary'] = d.primary
322
+ s['--jsee-primary-dark'] = darker(d.primary, 0.4)
323
+ s['--jsee-gradient-end'] = d.primary
324
+ s['--jsee-toggle-active'] = d.primary
325
+ }
326
+ if (d.secondary) {
327
+ s['--jsee-gradient-start'] = d.secondary
328
+ } else if (d.primary) {
329
+ s['--jsee-gradient-start'] = darker(d.primary, 0.25)
330
+ }
331
+ if (d.bg) {
332
+ s['--jsee-bg'] = d.bg
333
+ s['--jsee-bg-secondary'] = darker(d.bg, 0.04)
334
+ s['--jsee-card-bg'] = d.bg
335
+ s['--jsee-input-bg'] = d.bg
336
+ s['--jsee-label-bg'] = darker(d.bg, 0.05)
337
+ s['--jsee-border'] = darker(d.bg, 0.12)
338
+ s['--jsee-input-border'] = darker(d.bg, 0.13)
339
+ }
340
+ if (d.fg) {
341
+ s['--jsee-text'] = d.fg
342
+ s['--jsee-text-secondary'] = lighter(d.fg, 0.4)
343
+ }
344
+ if (d.font) {
345
+ s['--jsee-font'] = d.font
346
+ }
347
+ if (typeof d.radius !== 'undefined') {
348
+ s['--jsee-radius'] = typeof d.radius === 'number' ? d.radius + 'px' : d.radius
349
+ }
350
+ return Object.keys(s).length ? s : undefined
351
+ },
352
+ gridStyle () {
353
+ const d = this.$parent.design
354
+ if (!d || !d.grid || !Array.isArray(d.grid) || d.grid.length < 2) return undefined
355
+ return { gridTemplateColumns: d.grid.map(n => `minmax(0, ${n}fr)`).join(' ') }
356
+ },
357
+ hasInputColumns () {
358
+ const inputs = this.$parent.inputs
359
+ return inputs && inputs.some(i => i.columns)
360
+ },
361
+ hasOutputColumns () {
362
+ const outputs = this.$parent.outputs
363
+ return outputs && outputs.some(o => o.columns)
364
+ }
365
+ }
366
+ }
367
+ </script>