juxscript 1.1.393 → 1.1.395

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 (122) hide show
  1. package/bin/cli.js +9 -9
  2. package/dist/components/barChart.d.ts +103 -0
  3. package/dist/components/barChart.d.ts.map +1 -0
  4. package/dist/components/barChart.js +520 -0
  5. package/dist/components/barChart.js.map +1 -0
  6. package/dist/components/c.d.ts.map +1 -1
  7. package/dist/components/c.js +16 -12
  8. package/dist/components/c.js.map +1 -1
  9. package/dist/components/g.d.ts +21 -0
  10. package/dist/components/g.d.ts.map +1 -0
  11. package/dist/components/g.js +52 -0
  12. package/dist/components/g.js.map +1 -0
  13. package/dist/components/gateway.d.ts +97 -0
  14. package/dist/components/gateway.d.ts.map +1 -0
  15. package/dist/components/gateway.js +188 -0
  16. package/dist/components/gateway.js.map +1 -0
  17. package/dist/components/lineChart.d.ts +87 -0
  18. package/dist/components/lineChart.d.ts.map +1 -0
  19. package/dist/components/lineChart.js +330 -0
  20. package/dist/components/lineChart.js.map +1 -0
  21. package/dist/components/pieChart.d.ts +86 -0
  22. package/dist/components/pieChart.d.ts.map +1 -0
  23. package/dist/components/pieChart.js +300 -0
  24. package/dist/components/pieChart.js.map +1 -0
  25. package/dist/index.d.ts +15 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +16 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/primitives/button.d.ts +53 -0
  30. package/dist/primitives/button.d.ts.map +1 -0
  31. package/dist/primitives/button.js +170 -0
  32. package/dist/primitives/button.js.map +1 -0
  33. package/dist/primitives/c.d.ts +53 -0
  34. package/dist/primitives/c.d.ts.map +1 -0
  35. package/dist/primitives/c.js +127 -0
  36. package/dist/primitives/c.js.map +1 -0
  37. package/dist/primitives/checkbox.d.ts +92 -0
  38. package/dist/primitives/checkbox.d.ts.map +1 -0
  39. package/dist/primitives/checkbox.js +217 -0
  40. package/dist/primitives/checkbox.js.map +1 -0
  41. package/dist/primitives/data.d.ts +58 -0
  42. package/dist/primitives/data.d.ts.map +1 -0
  43. package/dist/primitives/data.js +131 -0
  44. package/dist/primitives/data.js.map +1 -0
  45. package/dist/primitives/grid.d.ts +58 -0
  46. package/dist/primitives/grid.d.ts.map +1 -0
  47. package/dist/primitives/grid.js +128 -0
  48. package/dist/primitives/grid.js.map +1 -0
  49. package/dist/primitives/include.d.ts +86 -0
  50. package/dist/primitives/include.d.ts.map +1 -0
  51. package/dist/primitives/include.js +239 -0
  52. package/dist/primitives/include.js.map +1 -0
  53. package/dist/primitives/indexDb.d.ts +80 -0
  54. package/dist/primitives/indexDb.d.ts.map +1 -0
  55. package/dist/primitives/indexDb.js +253 -0
  56. package/dist/primitives/indexDb.js.map +1 -0
  57. package/dist/primitives/input.d.ts +88 -0
  58. package/dist/primitives/input.d.ts.map +1 -0
  59. package/dist/primitives/input.js +216 -0
  60. package/dist/primitives/input.js.map +1 -0
  61. package/dist/primitives/link.d.ts +51 -0
  62. package/dist/primitives/link.d.ts.map +1 -0
  63. package/dist/primitives/link.js +178 -0
  64. package/dist/primitives/link.js.map +1 -0
  65. package/dist/primitives/list.d.ts +66 -0
  66. package/dist/primitives/list.d.ts.map +1 -0
  67. package/dist/primitives/list.js +233 -0
  68. package/dist/primitives/list.js.map +1 -0
  69. package/dist/primitives/nav.d.ts +64 -0
  70. package/dist/primitives/nav.d.ts.map +1 -0
  71. package/dist/primitives/nav.js +236 -0
  72. package/dist/primitives/nav.js.map +1 -0
  73. package/dist/primitives/radio.d.ts +58 -0
  74. package/dist/primitives/radio.d.ts.map +1 -0
  75. package/dist/primitives/radio.js +135 -0
  76. package/dist/primitives/radio.js.map +1 -0
  77. package/dist/primitives/routes.d.ts +15 -0
  78. package/dist/primitives/routes.d.ts.map +1 -0
  79. package/dist/primitives/routes.js +34 -0
  80. package/dist/primitives/routes.js.map +1 -0
  81. package/dist/primitives/select.d.ts +67 -0
  82. package/dist/primitives/select.d.ts.map +1 -0
  83. package/dist/primitives/select.js +160 -0
  84. package/dist/primitives/select.js.map +1 -0
  85. package/dist/primitives/style.d.ts +27 -0
  86. package/dist/primitives/style.d.ts.map +1 -0
  87. package/dist/primitives/style.js +53 -0
  88. package/dist/primitives/style.js.map +1 -0
  89. package/dist/primitives/table.d.ts +83 -0
  90. package/dist/primitives/table.d.ts.map +1 -0
  91. package/dist/primitives/table.js +264 -0
  92. package/dist/primitives/table.js.map +1 -0
  93. package/dist/primitives/tabs.d.ts +75 -0
  94. package/dist/primitives/tabs.d.ts.map +1 -0
  95. package/dist/primitives/tabs.js +263 -0
  96. package/dist/primitives/tabs.js.map +1 -0
  97. package/dist/primitives/tag.d.ts +92 -0
  98. package/dist/primitives/tag.d.ts.map +1 -0
  99. package/dist/primitives/tag.js +151 -0
  100. package/dist/primitives/tag.js.map +1 -0
  101. package/dist/services/db.d.ts +44 -0
  102. package/dist/services/db.d.ts.map +1 -0
  103. package/dist/services/db.js +59 -0
  104. package/dist/services/db.js.map +1 -0
  105. package/dist/services/email.d.ts +50 -0
  106. package/dist/services/email.d.ts.map +1 -0
  107. package/dist/services/email.js +60 -0
  108. package/dist/services/email.js.map +1 -0
  109. package/dist/services/s3.d.ts +61 -0
  110. package/dist/services/s3.d.ts.map +1 -0
  111. package/dist/services/s3.js +79 -0
  112. package/dist/services/s3.js.map +1 -0
  113. package/juxconfig.example.js +7 -0
  114. package/machinery/build3.js +2 -1
  115. package/machinery/compiler4.js +2 -0
  116. package/machinery/serve.js +6 -26
  117. package/machinery/validate-jux.js +4 -0
  118. package/package.json +2 -2
  119. /package/{presets → components}/calendar/calendar-usage.jux +0 -0
  120. /package/{presets → components}/calendar/calendar.jux +0 -0
  121. /package/{presets → components}/sidebar/index.jux +0 -0
  122. /package/{presets → components}/sidebar/usage.jux +0 -0
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Include - Simplified resource injection for bundled and external resources
3
+ * Supports page-specific scoping and cleanup
4
+ */
5
+ type ResourceType = 'css' | 'js' | 'module';
6
+ interface IncludeOptions {
7
+ type?: ResourceType;
8
+ target?: string;
9
+ async?: boolean;
10
+ defer?: boolean;
11
+ crossOrigin?: 'anonymous' | 'use-credentials';
12
+ integrity?: string;
13
+ pageScoped?: boolean;
14
+ }
15
+ export declare class Include {
16
+ private url;
17
+ private options;
18
+ private element;
19
+ private pageId;
20
+ constructor(url: string, options?: IncludeOptions);
21
+ css(): this;
22
+ js(): this;
23
+ module(): this;
24
+ async(): this;
25
+ defer(): this;
26
+ /**
27
+ * Inject into specific container instead of <head>
28
+ * Useful for page-specific styles
29
+ *
30
+ * @example
31
+ * jux.include('/css/page1.css').into('#page1-container');
32
+ */
33
+ into(selector: string): this;
34
+ /**
35
+ * Mark as page-scoped for automatic cleanup
36
+ *
37
+ * @example
38
+ * jux.include('/css/dashboard.css').forPage('dashboard');
39
+ * // Later: Include.cleanupPage('dashboard');
40
+ */
41
+ forPage(pageId: string): this;
42
+ render(): this;
43
+ private createStylesheet;
44
+ private createScript;
45
+ private getContainer;
46
+ private isAlreadyLoaded;
47
+ remove(): this;
48
+ /**
49
+ * Remove all resources for a specific page
50
+ *
51
+ * @example
52
+ * Include.cleanupPage('dashboard');
53
+ */
54
+ static cleanupPage(pageId: string): void;
55
+ /**
56
+ * Remove all page-scoped resources
57
+ */
58
+ static cleanupAll(): void;
59
+ }
60
+ /**
61
+ * Factory function - simplified usage
62
+ *
63
+ * Usage:
64
+ * // Basic (auto-detects from extension)
65
+ * jux.include('/css/styles.css');
66
+ * jux.include('/js/app.js');
67
+ *
68
+ * // Page-specific with cleanup
69
+ * jux.include('/css/dashboard.css').forPage('dashboard');
70
+ * jux.include('/js/dashboard.js').forPage('dashboard');
71
+ *
72
+ * // Later cleanup:
73
+ * Include.cleanupPage('dashboard');
74
+ *
75
+ * // Inject into specific container
76
+ * jux.include('/css/widget.css').into('#widget-container');
77
+ *
78
+ * // External CDN
79
+ * jux.include('https://cdn.tailwindcss.com').js();
80
+ *
81
+ * // Module
82
+ * jux.include('/js/app.mjs').module();
83
+ */
84
+ export declare function include(url: string, options?: IncludeOptions): Include;
85
+ export {};
86
+ //# sourceMappingURL=include.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"include.d.ts","sourceRoot":"","sources":["../../lib/primitives/include.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,KAAK,YAAY,GAAG,KAAK,GAAG,IAAI,GAAG,QAAQ,CAAC;AAE5C,UAAU,cAAc;IACpB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,WAAW,GAAG,iBAAiB,CAAC;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB;AAKD,qBAAa,OAAO;IAChB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,MAAM,CAAuB;gBAEzB,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB;IAoBrD,GAAG,IAAI,IAAI;IAKX,EAAE,IAAI,IAAI;IAKV,MAAM,IAAI,IAAI;IAKd,KAAK,IAAI,IAAI;IAKb,KAAK,IAAI,IAAI;IAKb;;;;;;OAMG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAK5B;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAU7B,MAAM,IAAI,IAAI;IAoDd,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,YAAY;IAuBpB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,eAAe;IAKvB,MAAM,IAAI,IAAI;IAYd;;;;;OAKG;IACH,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAYxC;;OAEG;IACH,MAAM,CAAC,UAAU,IAAI,IAAI;CAS5B;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAItE"}
@@ -0,0 +1,239 @@
1
+ /**
2
+ * Include - Simplified resource injection for bundled and external resources
3
+ * Supports page-specific scoping and cleanup
4
+ */
5
+ // Global registry for page-scoped resources
6
+ const scopedResources = new Map();
7
+ export class Include {
8
+ constructor(url, options = {}) {
9
+ this.element = null;
10
+ this.pageId = null;
11
+ this.url = url;
12
+ this.options = options;
13
+ // Auto-detect type from extension if not provided
14
+ if (!options.type) {
15
+ if (url.endsWith('.css')) {
16
+ this.options.type = 'css';
17
+ }
18
+ else if (url.endsWith('.mjs') || url.endsWith('.module.js')) {
19
+ this.options.type = 'module';
20
+ }
21
+ else {
22
+ this.options.type = 'js';
23
+ }
24
+ }
25
+ }
26
+ /* -------------------------
27
+ * Fluent API
28
+ * ------------------------- */
29
+ css() {
30
+ this.options.type = 'css';
31
+ return this;
32
+ }
33
+ js() {
34
+ this.options.type = 'js';
35
+ return this;
36
+ }
37
+ module() {
38
+ this.options.type = 'module';
39
+ return this;
40
+ }
41
+ async() {
42
+ this.options.async = true;
43
+ return this;
44
+ }
45
+ defer() {
46
+ this.options.defer = true;
47
+ return this;
48
+ }
49
+ /**
50
+ * Inject into specific container instead of <head>
51
+ * Useful for page-specific styles
52
+ *
53
+ * @example
54
+ * jux.include('/css/page1.css').into('#page1-container');
55
+ */
56
+ into(selector) {
57
+ this.options.target = selector;
58
+ return this;
59
+ }
60
+ /**
61
+ * Mark as page-scoped for automatic cleanup
62
+ *
63
+ * @example
64
+ * jux.include('/css/dashboard.css').forPage('dashboard');
65
+ * // Later: Include.cleanupPage('dashboard');
66
+ */
67
+ forPage(pageId) {
68
+ this.pageId = pageId;
69
+ this.options.pageScoped = true;
70
+ return this;
71
+ }
72
+ /* -------------------------
73
+ * Render
74
+ * ------------------------- */
75
+ render() {
76
+ if (typeof document === 'undefined')
77
+ return this;
78
+ try {
79
+ // Check if already loaded
80
+ if (this.isAlreadyLoaded()) {
81
+ console.log(`⚠️ Resource already loaded: ${this.url}`);
82
+ return this;
83
+ }
84
+ // Create element based on type
85
+ let element;
86
+ switch (this.options.type) {
87
+ case 'css':
88
+ element = this.createStylesheet();
89
+ break;
90
+ case 'js':
91
+ case 'module':
92
+ element = this.createScript();
93
+ break;
94
+ default:
95
+ throw new Error(`Unknown resource type: ${this.options.type}`);
96
+ }
97
+ // Get target container
98
+ const container = this.getContainer();
99
+ container.appendChild(element);
100
+ this.element = element;
101
+ // Register for page cleanup if needed
102
+ if (this.options.pageScoped && this.pageId) {
103
+ if (!scopedResources.has(this.pageId)) {
104
+ scopedResources.set(this.pageId, new Set());
105
+ }
106
+ scopedResources.get(this.pageId).add(element);
107
+ }
108
+ console.log(`✓ Loaded ${this.options.type}: ${this.url}`);
109
+ }
110
+ catch (error) {
111
+ console.error(`✗ Failed to load ${this.options.type}: ${this.url}`, error);
112
+ throw error;
113
+ }
114
+ return this;
115
+ }
116
+ /* -------------------------
117
+ * Element Creation
118
+ * ------------------------- */
119
+ createStylesheet() {
120
+ const link = document.createElement('link');
121
+ link.rel = 'stylesheet';
122
+ link.href = this.url;
123
+ link.dataset.juxInclude = this.url;
124
+ if (this.options.crossOrigin)
125
+ link.crossOrigin = this.options.crossOrigin;
126
+ if (this.options.integrity)
127
+ link.integrity = this.options.integrity;
128
+ link.onload = () => console.log(`✓ Stylesheet loaded: ${this.url}`);
129
+ link.onerror = () => {
130
+ throw new Error(`Failed to load stylesheet: ${this.url}`);
131
+ };
132
+ return link;
133
+ }
134
+ createScript() {
135
+ const script = document.createElement('script');
136
+ script.src = this.url;
137
+ script.dataset.juxInclude = this.url;
138
+ if (this.options.type === 'module')
139
+ script.type = 'module';
140
+ if (this.options.async)
141
+ script.async = true;
142
+ if (this.options.defer)
143
+ script.defer = true;
144
+ if (this.options.crossOrigin)
145
+ script.crossOrigin = this.options.crossOrigin;
146
+ if (this.options.integrity)
147
+ script.integrity = this.options.integrity;
148
+ script.onload = () => console.log(`✓ Script loaded: ${this.url}`);
149
+ script.onerror = () => {
150
+ throw new Error(`Failed to load script: ${this.url}`);
151
+ };
152
+ return script;
153
+ }
154
+ /* -------------------------
155
+ * Helpers
156
+ * ------------------------- */
157
+ getContainer() {
158
+ if (this.options.target) {
159
+ const container = document.querySelector(this.options.target);
160
+ if (!container) {
161
+ throw new Error(`Target container not found: ${this.options.target}`);
162
+ }
163
+ return container;
164
+ }
165
+ return document.head;
166
+ }
167
+ isAlreadyLoaded() {
168
+ const selector = `[data-jux-include="${this.url}"]`;
169
+ return document.querySelector(selector) !== null;
170
+ }
171
+ remove() {
172
+ if (this.element?.parentNode) {
173
+ this.element.parentNode.removeChild(this.element);
174
+ this.element = null;
175
+ }
176
+ return this;
177
+ }
178
+ /* -------------------------
179
+ * Static Page Cleanup
180
+ * ------------------------- */
181
+ /**
182
+ * Remove all resources for a specific page
183
+ *
184
+ * @example
185
+ * Include.cleanupPage('dashboard');
186
+ */
187
+ static cleanupPage(pageId) {
188
+ const resources = scopedResources.get(pageId);
189
+ if (!resources)
190
+ return;
191
+ resources.forEach(element => {
192
+ element.parentNode?.removeChild(element);
193
+ });
194
+ scopedResources.delete(pageId);
195
+ console.log(`✓ Cleaned up page resources: ${pageId}`);
196
+ }
197
+ /**
198
+ * Remove all page-scoped resources
199
+ */
200
+ static cleanupAll() {
201
+ scopedResources.forEach((resources, pageId) => {
202
+ resources.forEach(element => {
203
+ element.parentNode?.removeChild(element);
204
+ });
205
+ });
206
+ scopedResources.clear();
207
+ console.log('✓ Cleaned up all page-scoped resources');
208
+ }
209
+ }
210
+ /**
211
+ * Factory function - simplified usage
212
+ *
213
+ * Usage:
214
+ * // Basic (auto-detects from extension)
215
+ * jux.include('/css/styles.css');
216
+ * jux.include('/js/app.js');
217
+ *
218
+ * // Page-specific with cleanup
219
+ * jux.include('/css/dashboard.css').forPage('dashboard');
220
+ * jux.include('/js/dashboard.js').forPage('dashboard');
221
+ *
222
+ * // Later cleanup:
223
+ * Include.cleanupPage('dashboard');
224
+ *
225
+ * // Inject into specific container
226
+ * jux.include('/css/widget.css').into('#widget-container');
227
+ *
228
+ * // External CDN
229
+ * jux.include('https://cdn.tailwindcss.com').js();
230
+ *
231
+ * // Module
232
+ * jux.include('/js/app.mjs').module();
233
+ */
234
+ export function include(url, options) {
235
+ const inc = new Include(url, options);
236
+ inc.render();
237
+ return inc;
238
+ }
239
+ //# sourceMappingURL=include.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"include.js","sourceRoot":"","sources":["../../lib/primitives/include.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ interface IndexDbStoreOptions {
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 IndexDb {
15
+ id: string;
16
+ options: IndexDbStoreOptions;
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: IndexDbStoreOptions);
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
+ /** Returns the reactive pageState proxy for this component */
45
+ get state(): any;
46
+ }
47
+ /**
48
+ * Create a reactive IndexedDB store that integrates with pageState.
49
+ *
50
+ * @example
51
+ * // Basic usage
52
+ * const todos = await jux.indexDb('todos', { db: 'myapp', table: 'todos' });
53
+ * // pageState['todos'].value → [{ id: 1, text: 'Buy milk', done: false }, ...]
54
+ *
55
+ * // With indexes
56
+ * const users = await jux.indexDb('users', {
57
+ * db: 'myapp',
58
+ * table: 'users',
59
+ * indexes: [{ name: 'by_email', keyPath: 'email', unique: true }]
60
+ * });
61
+ *
62
+ * // Write
63
+ * await pageState['todos'].add({ text: 'New item', done: false });
64
+ * await pageState['todos'].put({ id: 1, text: 'Updated', done: true });
65
+ * await pageState['todos'].delete(1);
66
+ *
67
+ * // Query by index
68
+ * const results = await pageState['users'].query('by_email', 'alice@example.com');
69
+ *
70
+ * // React to changes
71
+ * pageState.__watch(() => {
72
+ * const items = pageState['todos'].value;
73
+ * if (items) {
74
+ * pageState['count'].content = `${items.length} items`;
75
+ * }
76
+ * });
77
+ */
78
+ export declare function indexDb(id: string, options: IndexDbStoreOptions): Promise<IndexDb>;
79
+ export { IndexDb, IndexDbStoreOptions };
80
+ //# sourceMappingURL=indexDb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexDb.d.ts","sourceRoot":"","sources":["../../lib/primitives/indexDb.ts"],"names":[],"mappings":"AAGA,UAAU,mBAAmB;IACzB,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,OAAO;IACT,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,mBAAmB,CAAC;IAC7B,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,mBAAmB;IA0BpD,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;IAG/B,8DAA8D;IAC9D,IAAI,KAAK,IAAI,GAAG,CAEf;CACJ;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CAUxF;AAED,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,253 @@
1
+ import generateId from '../utils/idgen.js';
2
+ import { pageState } from '../state/pageState.js';
3
+ class IndexDb {
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-indexdb', 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.indexDb('${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
+ /** Returns the reactive pageState proxy for this component */
208
+ get state() {
209
+ return pageState[this.id];
210
+ }
211
+ }
212
+ /**
213
+ * Create a reactive IndexedDB store that integrates with pageState.
214
+ *
215
+ * @example
216
+ * // Basic usage
217
+ * const todos = await jux.indexDb('todos', { db: 'myapp', table: 'todos' });
218
+ * // pageState['todos'].value → [{ id: 1, text: 'Buy milk', done: false }, ...]
219
+ *
220
+ * // With indexes
221
+ * const users = await jux.indexDb('users', {
222
+ * db: 'myapp',
223
+ * table: 'users',
224
+ * indexes: [{ name: 'by_email', keyPath: 'email', unique: true }]
225
+ * });
226
+ *
227
+ * // Write
228
+ * await pageState['todos'].add({ text: 'New item', done: false });
229
+ * await pageState['todos'].put({ id: 1, text: 'Updated', done: true });
230
+ * await pageState['todos'].delete(1);
231
+ *
232
+ * // Query by index
233
+ * const results = await pageState['users'].query('by_email', 'alice@example.com');
234
+ *
235
+ * // React to changes
236
+ * pageState.__watch(() => {
237
+ * const items = pageState['todos'].value;
238
+ * if (items) {
239
+ * pageState['count'].content = `${items.length} items`;
240
+ * }
241
+ * });
242
+ */
243
+ export async function indexDb(id, options) {
244
+ const s = new IndexDb(id, options);
245
+ pageState.__register(s);
246
+ if (options.auto !== false) {
247
+ await s.getAll();
248
+ pageState.__register(s);
249
+ }
250
+ return s;
251
+ }
252
+ export { IndexDb };
253
+ //# sourceMappingURL=indexDb.js.map