juxscript 1.1.362 → 1.1.363

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 (85) hide show
  1. package/package.json +1 -1
  2. package/dist/lib/components/blocks/menu.d.ts +0 -40
  3. package/dist/lib/components/blocks/menu.d.ts.map +0 -1
  4. package/dist/lib/components/blocks/menu.js +0 -136
  5. package/dist/lib/components/button.d.ts +0 -33
  6. package/dist/lib/components/button.d.ts.map +0 -1
  7. package/dist/lib/components/button.js +0 -107
  8. package/dist/lib/components/checkbox.d.ts +0 -62
  9. package/dist/lib/components/checkbox.d.ts.map +0 -1
  10. package/dist/lib/components/checkbox.js +0 -178
  11. package/dist/lib/components/container.d.ts +0 -58
  12. package/dist/lib/components/container.d.ts.map +0 -1
  13. package/dist/lib/components/container.js +0 -151
  14. package/dist/lib/components/data.d.ts +0 -58
  15. package/dist/lib/components/data.d.ts.map +0 -1
  16. package/dist/lib/components/data.js +0 -130
  17. package/dist/lib/components/grid.d.ts +0 -58
  18. package/dist/lib/components/grid.d.ts.map +0 -1
  19. package/dist/lib/components/grid.js +0 -127
  20. package/dist/lib/components/include.d.ts +0 -86
  21. package/dist/lib/components/include.d.ts.map +0 -1
  22. package/dist/lib/components/include.js +0 -238
  23. package/dist/lib/components/input.d.ts +0 -58
  24. package/dist/lib/components/input.d.ts.map +0 -1
  25. package/dist/lib/components/input.js +0 -161
  26. package/dist/lib/components/link.d.ts +0 -35
  27. package/dist/lib/components/link.d.ts.map +0 -1
  28. package/dist/lib/components/link.js +0 -135
  29. package/dist/lib/components/list.d.ts +0 -48
  30. package/dist/lib/components/list.d.ts.map +0 -1
  31. package/dist/lib/components/list.js +0 -178
  32. package/dist/lib/components/nav.d.ts +0 -46
  33. package/dist/lib/components/nav.d.ts.map +0 -1
  34. package/dist/lib/components/nav.js +0 -189
  35. package/dist/lib/components/radio.d.ts +0 -40
  36. package/dist/lib/components/radio.d.ts.map +0 -1
  37. package/dist/lib/components/radio.js +0 -112
  38. package/dist/lib/components/select.d.ts +0 -41
  39. package/dist/lib/components/select.d.ts.map +0 -1
  40. package/dist/lib/components/select.js +0 -111
  41. package/dist/lib/components/sidebar.d.ts +0 -40
  42. package/dist/lib/components/sidebar.d.ts.map +0 -1
  43. package/dist/lib/components/sidebar.js +0 -141
  44. package/dist/lib/components/store.d.ts +0 -78
  45. package/dist/lib/components/store.d.ts.map +0 -1
  46. package/dist/lib/components/store.js +0 -248
  47. package/dist/lib/components/style.d.ts +0 -27
  48. package/dist/lib/components/style.d.ts.map +0 -1
  49. package/dist/lib/components/style.js +0 -52
  50. package/dist/lib/components/table.d.ts +0 -56
  51. package/dist/lib/components/table.d.ts.map +0 -1
  52. package/dist/lib/components/table.js +0 -199
  53. package/dist/lib/components/tabs.d.ts +0 -52
  54. package/dist/lib/components/tabs.d.ts.map +0 -1
  55. package/dist/lib/components/tabs.js +0 -206
  56. package/dist/lib/components/tag.d.ts +0 -41
  57. package/dist/lib/components/tag.d.ts.map +0 -1
  58. package/dist/lib/components/tag.js +0 -103
  59. package/dist/lib/devtools/devtools.d.ts +0 -3
  60. package/dist/lib/devtools/devtools.d.ts.map +0 -1
  61. package/dist/lib/devtools/devtools.js +0 -181
  62. package/dist/lib/index.d.ts +0 -68
  63. package/dist/lib/index.d.ts.map +0 -1
  64. package/dist/lib/index.js +0 -63
  65. package/dist/lib/state/pageState.d.ts +0 -19
  66. package/dist/lib/state/pageState.d.ts.map +0 -1
  67. package/dist/lib/state/pageState.js +0 -360
  68. package/dist/lib/utils/codeHighlight.d.ts +0 -7
  69. package/dist/lib/utils/codeHighlight.d.ts.map +0 -1
  70. package/dist/lib/utils/codeHighlight.js +0 -105
  71. package/dist/lib/utils/codeparser.d.ts +0 -29
  72. package/dist/lib/utils/codeparser.d.ts.map +0 -1
  73. package/dist/lib/utils/codeparser.js +0 -384
  74. package/dist/lib/utils/fetch.d.ts +0 -176
  75. package/dist/lib/utils/fetch.d.ts.map +0 -1
  76. package/dist/lib/utils/fetch.js +0 -427
  77. package/dist/lib/utils/formatId.d.ts +0 -16
  78. package/dist/lib/utils/formatId.d.ts.map +0 -1
  79. package/dist/lib/utils/formatId.js +0 -27
  80. package/dist/lib/utils/idgen.d.ts +0 -2
  81. package/dist/lib/utils/idgen.d.ts.map +0 -1
  82. package/dist/lib/utils/idgen.js +0 -4
  83. package/dist/lib/utils/niceName.d.ts +0 -14
  84. package/dist/lib/utils/niceName.d.ts.map +0 -1
  85. package/dist/lib/utils/niceName.js +0 -22
@@ -1,111 +0,0 @@
1
- import generateId from '../utils/idgen.js';
2
- import { pageState } from '../state/pageState.js';
3
- class Select {
4
- constructor(id, options = {}) {
5
- this._element = null;
6
- this._wrapper = null;
7
- this._onChange = null;
8
- this.id = id || generateId();
9
- this.opts = { options: [], ...options };
10
- }
11
- // Fluent API
12
- label(value) { this.opts.label = value; return this; }
13
- placeholder(value) { this.opts.placeholder = value; return this; }
14
- required(value = true) { this.opts.required = value; return this; }
15
- disabled(value = true) { this.opts.disabled = value; return this; }
16
- multiple(value = true) { this.opts.multiple = value; return this; }
17
- style(value) { this.opts.style = value; return this; }
18
- class(value) { this.opts.class = value; return this; }
19
- options(opts) {
20
- this.opts.options = opts;
21
- if (this._element)
22
- this._rebuildOptions();
23
- return this;
24
- }
25
- value(val) {
26
- this.opts.value = val;
27
- if (this._element)
28
- this._element.value = val;
29
- return this;
30
- }
31
- onChange(fn) {
32
- this._onChange = fn;
33
- return this;
34
- }
35
- getValue() {
36
- return this._element?.value ?? this.opts.value ?? '';
37
- }
38
- getSelectedValues() {
39
- if (!this._element)
40
- return [];
41
- return Array.from(this._element.selectedOptions).map(o => o.value);
42
- }
43
- _rebuildOptions() {
44
- if (!this._element)
45
- return;
46
- this._element.innerHTML = '';
47
- if (this.opts.placeholder) {
48
- const ph = document.createElement('option');
49
- ph.value = '';
50
- ph.textContent = this.opts.placeholder;
51
- ph.disabled = true;
52
- ph.selected = !this.opts.value;
53
- this._element.appendChild(ph);
54
- }
55
- for (const opt of this.opts.options || []) {
56
- const o = document.createElement('option');
57
- o.value = opt.value;
58
- o.textContent = opt.label;
59
- if (opt.disabled)
60
- o.disabled = true;
61
- if (opt.value === this.opts.value)
62
- o.selected = true;
63
- this._element.appendChild(o);
64
- }
65
- }
66
- render(target) {
67
- const wrapper = document.createElement('div');
68
- wrapper.className = 'jux-select';
69
- wrapper.id = `${this.id}-wrapper`;
70
- if (this.opts.class)
71
- wrapper.className += ` ${this.opts.class}`;
72
- if (this.opts.style)
73
- wrapper.setAttribute('style', this.opts.style);
74
- if (this.opts.label) {
75
- const labelEl = document.createElement('label');
76
- labelEl.htmlFor = this.id;
77
- labelEl.textContent = this.opts.label;
78
- labelEl.className = 'jux-select-label';
79
- wrapper.appendChild(labelEl);
80
- }
81
- const sel = document.createElement('select');
82
- sel.id = this.id;
83
- sel.className = 'jux-select-element';
84
- if (this.opts.required)
85
- sel.required = true;
86
- if (this.opts.disabled)
87
- sel.disabled = true;
88
- if (this.opts.multiple)
89
- sel.multiple = true;
90
- this._element = sel;
91
- this._rebuildOptions();
92
- sel.addEventListener('change', (e) => {
93
- if (this._onChange)
94
- this._onChange(sel.value, e);
95
- });
96
- wrapper.appendChild(sel);
97
- this._wrapper = wrapper;
98
- const container = target
99
- ? (typeof target === 'string' ? document.getElementById(target) || document.querySelector(target) : target)
100
- : document.getElementById('app');
101
- container?.appendChild(wrapper);
102
- return this;
103
- }
104
- }
105
- export function select(id, options = {}) {
106
- const s = new Select(id, options);
107
- s.render();
108
- pageState.__register(s);
109
- return s;
110
- }
111
- export { Select };
@@ -1,40 +0,0 @@
1
- interface MenuItem {
2
- id: string;
3
- label: string;
4
- path: string;
5
- icon?: string;
6
- }
7
- interface MenuOptions {
8
- title?: string;
9
- logo?: string;
10
- footer?: string;
11
- width?: string;
12
- target?: string;
13
- density?: 'dense' | 'normal' | 'inflated';
14
- }
15
- interface MenuApi {
16
- id: string;
17
- title: (val: string) => MenuApi;
18
- logo: (val: string) => MenuApi;
19
- footer: (val: string) => MenuApi;
20
- width: (val: string) => MenuApi;
21
- target: (val: string) => MenuApi;
22
- density: (val: 'dense' | 'normal' | 'inflated') => MenuApi;
23
- section: (label: string, items: (string | MenuItem)[]) => MenuApi;
24
- items: (items: (string | MenuItem)[]) => MenuApi;
25
- render: () => MenuApi;
26
- addSection: (label: string, items: (string | MenuItem)[]) => MenuApi;
27
- setTitle: (val: string) => MenuApi;
28
- setFooter: (val: string) => MenuApi;
29
- show: () => MenuApi;
30
- hide: () => MenuApi;
31
- toggle: () => MenuApi;
32
- getElement: () => HTMLElement | null;
33
- }
34
- type SectionInput = string | {
35
- label?: string;
36
- items?: (string | MenuItem)[];
37
- };
38
- export declare function menu(id: string, sections?: SectionInput[], options?: MenuOptions): MenuApi;
39
- export {};
40
- //# sourceMappingURL=sidebar.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sidebar.d.ts","sourceRoot":"","sources":["../../../lib/components/sidebar.ts"],"names":[],"mappings":"AAEA,UAAU,QAAQ;IACd,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAOD,UAAU,WAAW;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAC;CAC7C;AAYD,UAAU,OAAO;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAChC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAC/B,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACjC,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAChC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACjC,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,KAAK,OAAO,CAAC;IAC3D,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,MAAM,GAAG,QAAQ,CAAC,EAAE,KAAK,OAAO,CAAC;IAClE,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,MAAM,GAAG,QAAQ,CAAC,EAAE,KAAK,OAAO,CAAC;IACjD,MAAM,EAAE,MAAM,OAAO,CAAC;IACtB,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,MAAM,GAAG,QAAQ,CAAC,EAAE,KAAK,OAAO,CAAC;IACrE,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACnC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACpC,IAAI,EAAE,MAAM,OAAO,CAAC;IACpB,IAAI,EAAE,MAAM,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,OAAO,CAAC;IACtB,UAAU,EAAE,MAAM,WAAW,GAAG,IAAI,CAAC;CACxC;AAED,KAAK,YAAY,GAAG,MAAM,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,CAAC,MAAM,GAAG,QAAQ,CAAC,EAAE,CAAA;CAAE,CAAC;AAE/E,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,YAAY,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAgJ1F"}
@@ -1,141 +0,0 @@
1
- import { div, span, nav, pageState } from './tag';
2
- export function menu(id, sections, options) {
3
- const opts = options || {};
4
- let _title = opts.title || 'App';
5
- let _logo = opts.logo || _title.charAt(0).toUpperCase();
6
- let _footer = opts.footer || '';
7
- let _width = opts.width || '260px';
8
- let _target = opts.target;
9
- let _density = opts.density || 'normal';
10
- let _sectionCount = 0;
11
- let _rendered = false;
12
- let _footerRendered = false;
13
- const DENSITY = {
14
- dense: { headerPad: '10px', itemPad: '4px 10px', labelPad: '6px 10px 2px', footerPad: '8px 12px', gap: '0px', fontSize: '12px', iconSize: '13px' },
15
- normal: { headerPad: '16px', itemPad: '8px 12px', labelPad: '8px 12px 4px', footerPad: '12px 16px', gap: '1px', fontSize: '13px', iconSize: '15px' },
16
- inflated: { headerPad: '20px', itemPad: '12px 16px', labelPad: '12px 16px 6px', footerPad: '16px 20px', gap: '4px', fontSize: '14px', iconSize: '17px' }
17
- };
18
- function normalizeItem(item) {
19
- if (typeof item === 'string') {
20
- const path = item.startsWith('/') ? item : '/' + item;
21
- const seg = path.split('/').filter(Boolean).pop() || 'Home';
22
- return { id: id + '-' + seg.toLowerCase().replace(/[^a-z0-9]/g, '-'), label: seg.charAt(0).toUpperCase() + seg.slice(1), path: path };
23
- }
24
- return item;
25
- }
26
- function normalizeSections(input) {
27
- if (!input || !Array.isArray(input) || input.length === 0)
28
- return [];
29
- const isFlat = input.every((i) => typeof i === 'string' || (typeof i === 'object' && !('items' in i)));
30
- if (isFlat)
31
- return [{ items: input.map(normalizeItem) }];
32
- return input.map((s) => {
33
- if (typeof s === 'string')
34
- return { items: [normalizeItem(s)] };
35
- return { label: s.label, items: (s.items || []).map(normalizeItem) };
36
- });
37
- }
38
- function ensureShell() {
39
- if (_rendered)
40
- return;
41
- _rendered = true;
42
- injectStyles();
43
- div(id, { class: 'jux-sidebar jux-sidebar--' + _density, style: 'width:' + _width, target: _target });
44
- div(id + '-header', { class: 'jux-sidebar-header', target: id });
45
- div(id + '-logo', { class: 'jux-sidebar-logo', content: _logo, target: id + '-header' });
46
- span(id + '-title', { content: _title, target: id + '-header' });
47
- }
48
- function renderSection(section) {
49
- ensureShell();
50
- const i = _sectionCount++;
51
- if (i > 0)
52
- div(id + '-divider-' + i, { class: 'jux-sidebar-divider', target: id });
53
- if (section.label)
54
- div(id + '-label-' + i, { class: 'jux-sidebar-label', content: section.label, target: id });
55
- nav(id + '-nav-' + i, { target: id, items: section.items });
56
- }
57
- function renderFooter() {
58
- if (_footerRendered || !_footer)
59
- return;
60
- _footerRendered = true;
61
- div(id + '-footer', { class: 'jux-sidebar-footer', content: _footer, target: id });
62
- }
63
- function injectStyles() {
64
- if (document.getElementById('menu-styles'))
65
- return;
66
- const el = document.createElement('style');
67
- el.id = 'menu-styles';
68
- el.textContent = '\
69
- body { margin: 0; }\
70
- .jux-sidebar { display:flex; flex-direction:column; min-height:100vh; background:hsl(var(--card)); color:hsl(var(--card-foreground)); border-right:1px solid hsl(var(--border)); font-family:var(--font-sans,system-ui,sans-serif); }\
71
- .jux-sidebar-header { display:flex; align-items:center; gap:8px; font-size:14px; font-weight:600; border-bottom:1px solid hsl(var(--border)); }\
72
- .jux-sidebar-logo { width:20px; height:20px; border-radius:6px; background:hsl(var(--primary)); display:flex; align-items:center; justify-content:center; color:hsl(var(--primary-foreground)); font-size:11px; font-weight:700; }\
73
- .jux-sidebar-label { font-size:11px; font-weight:500; color:hsl(var(--muted-foreground)); text-transform:uppercase; letter-spacing:0.05em; }\
74
- .jux-sidebar-footer { margin-top:auto; border-top:1px solid hsl(var(--border)); font-size:11px; color:hsl(var(--muted-foreground)); }\
75
- .jux-sidebar-divider { height:1px; background:hsl(var(--border)); margin:4px 8px; }\
76
- .jux-nav-item { display:flex; align-items:center; border-radius:var(--radius,6px); font-weight:500; color:hsl(var(--foreground)); cursor:pointer; transition:background 0.15s; user-select:none; text-decoration:none; }\
77
- .jux-nav-item:hover { background:hsl(var(--accent)); color:hsl(var(--accent-foreground)); }\
78
- .jux-nav-item--active { background:hsl(var(--accent)); color:hsl(var(--accent-foreground)); font-weight:600; }\
79
- .jux-nav-item-icon { text-align:center; flex-shrink:0; }\
80
- \
81
- .jux-sidebar--dense .jux-sidebar-header { padding:' + DENSITY.dense.headerPad + '; }\
82
- .jux-sidebar--dense .jux-sidebar-label { padding:' + DENSITY.dense.labelPad + '; }\
83
- .jux-sidebar--dense .jux-sidebar-footer { padding:' + DENSITY.dense.footerPad + '; }\
84
- .jux-sidebar--dense .jux-nav-item { padding:' + DENSITY.dense.itemPad + '; margin:' + DENSITY.dense.gap + ' 0; font-size:' + DENSITY.dense.fontSize + '; gap:8px; }\
85
- .jux-sidebar--dense .jux-nav-item-icon { width:16px; font-size:' + DENSITY.dense.iconSize + '; }\
86
- \
87
- .jux-sidebar--normal .jux-sidebar-header { padding:' + DENSITY.normal.headerPad + '; }\
88
- .jux-sidebar--normal .jux-sidebar-label { padding:' + DENSITY.normal.labelPad + '; }\
89
- .jux-sidebar--normal .jux-sidebar-footer { padding:' + DENSITY.normal.footerPad + '; }\
90
- .jux-sidebar--normal .jux-nav-item { padding:' + DENSITY.normal.itemPad + '; margin:' + DENSITY.normal.gap + ' 0; font-size:' + DENSITY.normal.fontSize + '; gap:10px; }\
91
- .jux-sidebar--normal .jux-nav-item-icon { width:18px; font-size:' + DENSITY.normal.iconSize + '; }\
92
- \
93
- .jux-sidebar--inflated .jux-sidebar-header { padding:' + DENSITY.inflated.headerPad + '; }\
94
- .jux-sidebar--inflated .jux-sidebar-label { padding:' + DENSITY.inflated.labelPad + '; }\
95
- .jux-sidebar--inflated .jux-sidebar-footer { padding:' + DENSITY.inflated.footerPad + '; }\
96
- .jux-sidebar--inflated .jux-nav-item { padding:' + DENSITY.inflated.itemPad + '; margin:' + DENSITY.inflated.gap + ' 0; font-size:' + DENSITY.inflated.fontSize + '; gap:12px; }\
97
- .jux-sidebar--inflated .jux-nav-item-icon { width:20px; font-size:' + DENSITY.inflated.iconSize + '; }\
98
- ';
99
- document.head.appendChild(el);
100
- }
101
- const api = {
102
- id: id,
103
- title: function (val) { _title = val; return api; },
104
- logo: function (val) { _logo = val; return api; },
105
- footer: function (val) {
106
- _footer = val;
107
- if (_rendered)
108
- renderFooter();
109
- return api;
110
- },
111
- width: function (val) { _width = val; return api; },
112
- target: function (val) { _target = val; return api; },
113
- density: function (val) { _density = val; return api; },
114
- section: function (label, items) {
115
- renderSection({ label: label, items: (items || []).map(normalizeItem) });
116
- return api;
117
- },
118
- items: function (items) {
119
- renderSection({ items: (items || []).map(normalizeItem) });
120
- return api;
121
- },
122
- render: function () {
123
- ensureShell();
124
- renderFooter();
125
- return api;
126
- },
127
- addSection: function (label, items) { return api.section(label, items); },
128
- setTitle: function (val) { pageState[id + '-title'].content = val; return api; },
129
- setFooter: function (val) { pageState[id + '-footer'].content = val; return api; },
130
- show: function () { pageState[id].visible = true; return api; },
131
- hide: function () { pageState[id].visible = false; return api; },
132
- toggle: function () { pageState[id].visible = !pageState[id].visible; return api; },
133
- getElement: function () { return document.getElementById(id); }
134
- };
135
- if (sections && Array.isArray(sections) && sections.length > 0) {
136
- const normalized = normalizeSections(sections);
137
- normalized.forEach(renderSection);
138
- renderFooter();
139
- }
140
- return api;
141
- }
@@ -1,78 +0,0 @@
1
- interface StoreOptions {
2
- db: string;
3
- table: string;
4
- version?: number;
5
- keyPath?: string;
6
- autoIncrement?: boolean;
7
- indexes?: Array<{
8
- name: string;
9
- keyPath: string | string[];
10
- unique?: boolean;
11
- }>;
12
- auto?: boolean;
13
- }
14
- declare class Store {
15
- id: string;
16
- options: StoreOptions;
17
- _element: HTMLElement;
18
- private _db;
19
- private _value;
20
- private _loading;
21
- private _error;
22
- private _onChange;
23
- private _ready;
24
- constructor(id: string, options: StoreOptions);
25
- private _open;
26
- private _tx;
27
- private _notifyChange;
28
- onChange(fn: (value: any[]) => void): this;
29
- getElement(): HTMLElement;
30
- getValue(): any[];
31
- getLoading(): boolean;
32
- getError(): string | null;
33
- getCount(): number;
34
- setValue(val: any[]): this;
35
- getAll(): Promise<any[]>;
36
- get(key: IDBValidKey): Promise<any>;
37
- query(indexName: string, value: IDBValidKey): Promise<any[]>;
38
- put(record: any): Promise<IDBValidKey>;
39
- add(record: any): Promise<IDBValidKey>;
40
- putMany(records: any[]): Promise<void>;
41
- delete(key: IDBValidKey): Promise<void>;
42
- clear(): Promise<void>;
43
- refresh(): Promise<any[]>;
44
- }
45
- /**
46
- * Create a reactive IndexedDB store that integrates with pageState.
47
- *
48
- * @example
49
- * // Basic usage
50
- * const todos = await jux.store('todos', { db: 'myapp', table: 'todos' });
51
- * // pageState['todos'].value → [{ id: 1, text: 'Buy milk', done: false }, ...]
52
- *
53
- * // With indexes
54
- * const users = await jux.store('users', {
55
- * db: 'myapp',
56
- * table: 'users',
57
- * indexes: [{ name: 'by_email', keyPath: 'email', unique: true }]
58
- * });
59
- *
60
- * // Write
61
- * await pageState['todos'].add({ text: 'New item', done: false });
62
- * await pageState['todos'].put({ id: 1, text: 'Updated', done: true });
63
- * await pageState['todos'].delete(1);
64
- *
65
- * // Query by index
66
- * const results = await pageState['users'].query('by_email', 'alice@example.com');
67
- *
68
- * // React to changes
69
- * pageState.__watch(() => {
70
- * const items = pageState['todos'].value;
71
- * if (items) {
72
- * pageState['count'].content = `${items.length} items`;
73
- * }
74
- * });
75
- */
76
- export declare function store(id: string, options: StoreOptions): Promise<Store>;
77
- export { Store, StoreOptions };
78
- //# sourceMappingURL=store.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../lib/components/store.ts"],"names":[],"mappings":"AAGA,UAAU,YAAY;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAChF,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,cAAM,KAAK;IACP,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,WAAW,CAAC;IACtB,OAAO,CAAC,GAAG,CAA4B;IACvC,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,MAAM,CAAgB;gBAElB,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY;IA0B7C,OAAO,CAAC,KAAK;IAgCb,OAAO,CAAC,GAAG;IAOX,OAAO,CAAC,aAAa;IAoBrB,QAAQ,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI;IAK1C,UAAU,IAAI,WAAW;IACzB,QAAQ,IAAI,GAAG,EAAE;IACjB,UAAU,IAAI,OAAO;IACrB,QAAQ,IAAI,MAAM,GAAG,IAAI;IACzB,QAAQ,IAAI,MAAM;IAElB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;IAUpB,MAAM,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAwBxB,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC;IAWnC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAiB5D,GAAG,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC;IActC,GAAG,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC;IActC,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBtC,MAAM,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAcvC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBtB,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;CAGlC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,CAU7E;AAED,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC"}
@@ -1,248 +0,0 @@
1
- import generateId from '../utils/idgen.js';
2
- import { pageState } from '../state/pageState.js';
3
- class Store {
4
- constructor(id, options) {
5
- this._db = null;
6
- this._value = [];
7
- this._loading = false;
8
- this._error = null;
9
- this._onChange = null;
10
- this.id = id || generateId();
11
- this.options = {
12
- version: 1,
13
- keyPath: 'id',
14
- autoIncrement: true,
15
- auto: true,
16
- ...options
17
- };
18
- // Create a hidden DOM element so pageState can wire events
19
- this._element = document.createElement('div');
20
- this._element.id = this.id;
21
- this._element.setAttribute('data-jux-store', this.options.table);
22
- this._element.setAttribute('data-count', '0');
23
- this._element.setAttribute('data-loading', 'false');
24
- this._element.style.display = 'none';
25
- (document.getElementById('app') || document.body).appendChild(this._element);
26
- this._ready = this._open();
27
- }
28
- // ═══════════════════════════════════════════════════════════
29
- // INTERNAL: Open / ensure DB
30
- // ═══════════════════════════════════════════════════════════
31
- _open() {
32
- return new Promise((resolve, reject) => {
33
- const req = indexedDB.open(this.options.db, this.options.version);
34
- req.onupgradeneeded = (e) => {
35
- const db = e.target.result;
36
- if (!db.objectStoreNames.contains(this.options.table)) {
37
- const store = db.createObjectStore(this.options.table, {
38
- keyPath: this.options.keyPath,
39
- autoIncrement: this.options.autoIncrement
40
- });
41
- if (this.options.indexes) {
42
- for (const idx of this.options.indexes) {
43
- store.createIndex(idx.name, idx.keyPath, { unique: idx.unique ?? false });
44
- }
45
- }
46
- }
47
- };
48
- req.onsuccess = (e) => {
49
- this._db = e.target.result;
50
- resolve();
51
- };
52
- req.onerror = (e) => {
53
- this._error = `IndexedDB open failed: ${e.target.error?.message}`;
54
- console.error(`❌ jux.store('${this.id}'):`, this._error);
55
- reject(new Error(this._error));
56
- };
57
- });
58
- }
59
- _tx(mode) {
60
- if (!this._db)
61
- throw new Error('Database not open');
62
- return this._db
63
- .transaction(this.options.table, mode)
64
- .objectStore(this.options.table);
65
- }
66
- _notifyChange() {
67
- // Update DOM element metadata
68
- this._element.setAttribute('data-count', String(this._value.length));
69
- this._element.setAttribute('data-loading', String(this._loading));
70
- if (this._error) {
71
- this._element.setAttribute('data-error', this._error);
72
- }
73
- else {
74
- this._element.removeAttribute('data-error');
75
- }
76
- if (this._onChange)
77
- this._onChange(this._value);
78
- // Dispatch a real DOM change event — pageState._wireEvent picks this up
79
- this._element.dispatchEvent(new Event('change', { bubbles: false }));
80
- }
81
- // ═══════════════════════════════════════════════════════════
82
- // PAGESTATE INTEGRATION
83
- // ═══════════════════════════════════════════════════════════
84
- onChange(fn) {
85
- this._onChange = fn;
86
- return this;
87
- }
88
- getElement() { return this._element; }
89
- getValue() { return this._value; }
90
- getLoading() { return this._loading; }
91
- getError() { return this._error; }
92
- getCount() { return this._value.length; }
93
- setValue(val) {
94
- this._value = val;
95
- this._notifyChange();
96
- return this;
97
- }
98
- // ═══════════════════════════════════════════════════════════
99
- // READ
100
- // ═══════════════════════════════════════════════════════════
101
- async getAll() {
102
- await this._ready;
103
- this._loading = true;
104
- this._error = null;
105
- return new Promise((resolve, reject) => {
106
- const req = this._tx('readonly').getAll();
107
- req.onsuccess = () => {
108
- this._value = req.result;
109
- this._loading = false;
110
- this._notifyChange();
111
- resolve(this._value);
112
- };
113
- req.onerror = () => {
114
- this._loading = false;
115
- this._error = req.error?.message ?? 'getAll failed';
116
- this._notifyChange();
117
- reject(new Error(this._error));
118
- };
119
- });
120
- }
121
- async get(key) {
122
- await this._ready;
123
- return new Promise((resolve, reject) => {
124
- const req = this._tx('readonly').get(key);
125
- req.onsuccess = () => resolve(req.result ?? null);
126
- req.onerror = () => reject(new Error(req.error?.message ?? 'get failed'));
127
- });
128
- }
129
- async query(indexName, value) {
130
- await this._ready;
131
- return new Promise((resolve, reject) => {
132
- const store = this._tx('readonly');
133
- const index = store.index(indexName);
134
- const req = index.getAll(value);
135
- req.onsuccess = () => resolve(req.result);
136
- req.onerror = () => reject(new Error(req.error?.message ?? 'query failed'));
137
- });
138
- }
139
- // ═══════════════════════════════════════════════════════════
140
- // WRITE
141
- // ═══════════════════════════════════════════════════════════
142
- async put(record) {
143
- await this._ready;
144
- return new Promise((resolve, reject) => {
145
- const req = this._tx('readwrite').put(record);
146
- req.onsuccess = () => {
147
- this.getAll().then(() => resolve(req.result));
148
- };
149
- req.onerror = () => reject(new Error(req.error?.message ?? 'put failed'));
150
- });
151
- }
152
- async add(record) {
153
- await this._ready;
154
- return new Promise((resolve, reject) => {
155
- const req = this._tx('readwrite').add(record);
156
- req.onsuccess = () => {
157
- this.getAll().then(() => resolve(req.result));
158
- };
159
- req.onerror = () => reject(new Error(req.error?.message ?? 'add failed'));
160
- });
161
- }
162
- async putMany(records) {
163
- await this._ready;
164
- return new Promise((resolve, reject) => {
165
- const tx = this._db.transaction(this.options.table, 'readwrite');
166
- const store = tx.objectStore(this.options.table);
167
- for (const record of records) {
168
- store.put(record);
169
- }
170
- tx.oncomplete = () => {
171
- this.getAll().then(() => resolve());
172
- };
173
- tx.onerror = () => reject(new Error(tx.error?.message ?? 'putMany failed'));
174
- });
175
- }
176
- // ═══════════════════════════════════════════════════════════
177
- // DELETE
178
- // ═══════════════════════════════════════════════════════════
179
- async delete(key) {
180
- await this._ready;
181
- return new Promise((resolve, reject) => {
182
- const req = this._tx('readwrite').delete(key);
183
- req.onsuccess = () => {
184
- this.getAll().then(() => resolve());
185
- };
186
- req.onerror = () => reject(new Error(req.error?.message ?? 'delete failed'));
187
- });
188
- }
189
- async clear() {
190
- await this._ready;
191
- return new Promise((resolve, reject) => {
192
- const req = this._tx('readwrite').clear();
193
- req.onsuccess = () => {
194
- this._value = [];
195
- this._notifyChange();
196
- resolve();
197
- };
198
- req.onerror = () => reject(new Error(req.error?.message ?? 'clear failed'));
199
- });
200
- }
201
- // ═══════════════════════════════════════════════════════════
202
- // REFRESH (alias for getAll, matches data.ts pattern)
203
- // ═══════════════════════════════════════════════════════════
204
- async refresh() {
205
- return this.getAll();
206
- }
207
- }
208
- /**
209
- * Create a reactive IndexedDB store that integrates with pageState.
210
- *
211
- * @example
212
- * // Basic usage
213
- * const todos = await jux.store('todos', { db: 'myapp', table: 'todos' });
214
- * // pageState['todos'].value → [{ id: 1, text: 'Buy milk', done: false }, ...]
215
- *
216
- * // With indexes
217
- * const users = await jux.store('users', {
218
- * db: 'myapp',
219
- * table: 'users',
220
- * indexes: [{ name: 'by_email', keyPath: 'email', unique: true }]
221
- * });
222
- *
223
- * // Write
224
- * await pageState['todos'].add({ text: 'New item', done: false });
225
- * await pageState['todos'].put({ id: 1, text: 'Updated', done: true });
226
- * await pageState['todos'].delete(1);
227
- *
228
- * // Query by index
229
- * const results = await pageState['users'].query('by_email', 'alice@example.com');
230
- *
231
- * // React to changes
232
- * pageState.__watch(() => {
233
- * const items = pageState['todos'].value;
234
- * if (items) {
235
- * pageState['count'].content = `${items.length} items`;
236
- * }
237
- * });
238
- */
239
- export async function store(id, options) {
240
- const s = new Store(id, options);
241
- pageState.__register(s);
242
- if (options.auto !== false) {
243
- await s.getAll();
244
- pageState.__register(s);
245
- }
246
- return s;
247
- }
248
- export { Store };
@@ -1,27 +0,0 @@
1
- declare class Style {
2
- id: string;
3
- private _element;
4
- constructor(id: string, css: string);
5
- /** Replace the entire stylesheet content */
6
- setContent(css: string): this;
7
- /** Append additional CSS rules */
8
- append(css: string): this;
9
- /** Get current CSS content */
10
- getContent(): string;
11
- /** Remove the style tag from the document */
12
- remove(): void;
13
- getElement(): HTMLStyleElement;
14
- }
15
- /**
16
- * Inject a CSS string into the document head.
17
- *
18
- * @example
19
- * jux.style('my-styles', `
20
- * .sidebar { background: hsl(var(--card)); }
21
- * .nav-item:hover { background: hsl(var(--accent)); }
22
- * `);
23
- */
24
- export declare function style(id: string, css: string): Style;
25
- export { Style };
26
- export default style;
27
- //# sourceMappingURL=style.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../../lib/components/style.ts"],"names":[],"mappings":"AAEA,cAAM,KAAK;IACP,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,QAAQ,CAAmB;gBAEvB,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;IASnC,4CAA4C;IAC5C,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAK7B,kCAAkC;IAClC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKzB,8BAA8B;IAC9B,UAAU,IAAI,MAAM;IAIpB,6CAA6C;IAC7C,MAAM,IAAI,IAAI;IAId,UAAU,IAAI,gBAAgB;CAGjC;AAED;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,CAQpD;AAED,OAAO,EAAE,KAAK,EAAE,CAAC;AACjB,eAAe,KAAK,CAAC"}